drm/xe: fix pat[2] programming with 2M/1G pages
authorMatthew Auld <matthew.auld@intel.com>
Wed, 18 Oct 2023 12:34:24 +0000 (13:34 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:43:19 +0000 (11:43 -0500)
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 <matthew.auld@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_bo.h
drivers/gpu/drm/xe/xe_vm.c

index ba6ffd359ff70f6d91095f4a1d2a4d0ca7f1168e..3f4e2818f92c59f099229e368d1f1d3139e34e55 100644 (file)
@@ -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)
index 4c8d77c4c7c0d06d506cc27f4207c68643a15b4e..05f8c691f5fb23240f799599f7a07355b325f88f 100644 (file)
@@ -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)