From: Matthew Auld Date: Wed, 18 Oct 2023 12:34:24 +0000 (+0100) Subject: drm/xe: fix pat[2] programming with 2M/1G pages X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=bf6d941c06c9681d0f3d8380e7093d7f79d3eef6;p=linux.git drm/xe: fix pat[2] programming with 2M/1G pages Bit 7 in the leaf node is normally programmed with pat[2], however with 2M/1G pages that same bit in the PDE/PDPE also toggles 2M/1G pages. For 2M/1G entries the pat[2] is rather moved to bit 12, which is now free given that the address must be aligned to 2M or 1G, leaving bit 7 for toggling 2M/1G pages. Bspec: 59510, 45038 Signed-off-by: Matthew Auld Cc: Lucas De Marchi Cc: Matt Roper Reviewed-by: Matthew Brost Reviewed-by: Lucas De Marchi Signed-off-by: Rodrigo Vivi --- diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h index ba6ffd359ff70..3f4e2818f92c5 100644 --- a/drivers/gpu/drm/xe/xe_bo.h +++ b/drivers/gpu/drm/xe/xe_bo.h @@ -50,6 +50,7 @@ #define XELPG_PPGTT_PTE_PAT3 BIT_ULL(62) #define XE2_PPGTT_PTE_PAT4 BIT_ULL(61) +#define XE_PPGTT_PDE_PDPE_PAT2 BIT_ULL(12) #define XE_PPGTT_PTE_PAT2 BIT_ULL(7) #define XE_PPGTT_PTE_PAT1 BIT_ULL(4) #define XE_PPGTT_PTE_PAT0 BIT_ULL(3) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 4c8d77c4c7c0d..05f8c691f5fb2 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1229,7 +1229,8 @@ static u64 pde_encode_pat_index(struct xe_device *xe, u16 pat_index) return pte; } -static u64 pte_encode_pat_index(struct xe_device *xe, u16 pat_index) +static u64 pte_encode_pat_index(struct xe_device *xe, u16 pat_index, + u32 pt_level) { u64 pte = 0; @@ -1239,8 +1240,12 @@ static u64 pte_encode_pat_index(struct xe_device *xe, u16 pat_index) if (pat_index & BIT(1)) pte |= XE_PPGTT_PTE_PAT1; - if (pat_index & BIT(2)) - pte |= XE_PPGTT_PTE_PAT2; + if (pat_index & BIT(2)) { + if (pt_level) + pte |= XE_PPGTT_PDE_PDPE_PAT2; + else + pte |= XE_PPGTT_PTE_PAT2; + } if (pat_index & BIT(3)) pte |= XELPG_PPGTT_PTE_PAT3; @@ -1284,7 +1289,7 @@ static u64 xelp_pte_encode_bo(struct xe_bo *bo, u64 bo_offset, pte = xe_bo_addr(bo, bo_offset, XE_PAGE_SIZE); pte |= XE_PAGE_PRESENT | XE_PAGE_RW; - pte |= pte_encode_pat_index(xe, pat_index); + pte |= pte_encode_pat_index(xe, pat_index, pt_level); pte |= pte_encode_ps(pt_level); if (xe_bo_is_vram(bo) || xe_bo_is_stolen_devmem(bo)) @@ -1303,7 +1308,7 @@ static u64 xelp_pte_encode_vma(u64 pte, struct xe_vma *vma, if (likely(!xe_vma_read_only(vma))) pte |= XE_PAGE_RW; - pte |= pte_encode_pat_index(xe, pat_index); + pte |= pte_encode_pat_index(xe, pat_index, pt_level); pte |= pte_encode_ps(pt_level); if (unlikely(xe_vma_is_null(vma))) @@ -1323,7 +1328,7 @@ static u64 xelp_pte_encode_addr(struct xe_device *xe, u64 addr, pte = addr; pte |= XE_PAGE_PRESENT | XE_PAGE_RW; - pte |= pte_encode_pat_index(xe, pat_index); + pte |= pte_encode_pat_index(xe, pat_index, pt_level); pte |= pte_encode_ps(pt_level); if (devmem)