diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2024-08-13 00:18:25 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2024-08-13 00:18:25 +0000 |
commit | b850026f4d955368ac595112b8fdefdecf1943fa (patch) | |
tree | 5bb2f4b426e3abada1e56b65d80de27dacdffb20 /sys/dev | |
parent | df8a9411eabc174c6f93246b315ddf5ccfbc9692 (diff) |
drm/i915: Split the smem and lmem plane readout apart
From Ville Syrjala
6bfdb06d1efafaa289f16ff5e5dfb4b02327525e in mainline linux
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/drm/i915/display/intel_display_types.h | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/display/intel_plane_initial.c | 143 |
2 files changed, 94 insertions, 51 deletions
diff --git a/sys/dev/pci/drm/i915/display/intel_display_types.h b/sys/dev/pci/drm/i915/display/intel_display_types.h index dfc7d628fd6..2d1c5bed6e1 100644 --- a/sys/dev/pci/drm/i915/display/intel_display_types.h +++ b/sys/dev/pci/drm/i915/display/intel_display_types.h @@ -770,6 +770,8 @@ struct intel_plane_state { struct intel_initial_plane_config { struct intel_framebuffer *fb; + struct intel_memory_region *mem; + resource_size_t phys_base; struct i915_vma *vma; unsigned int tiling; int size; diff --git a/sys/dev/pci/drm/i915/display/intel_plane_initial.c b/sys/dev/pci/drm/i915/display/intel_plane_initial.c index 07ae3e0d5a8..300aa8bc83f 100644 --- a/sys/dev/pci/drm/i915/display/intel_plane_initial.c +++ b/sys/dev/pci/drm/i915/display/intel_plane_initial.c @@ -43,6 +43,93 @@ intel_reuse_initial_plane_obj(struct drm_i915_private *i915, return false; } +static bool +initial_plane_phys_lmem(struct drm_i915_private *i915, + struct intel_initial_plane_config *plane_config) +{ + gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm; + struct intel_memory_region *mem; + dma_addr_t dma_addr; + gen8_pte_t pte; + u32 base; + + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); + + gte += base / I915_GTT_PAGE_SIZE; + + pte = ioread64(gte); + if (!(pte & GEN12_GGTT_PTE_LM)) { + drm_err(&i915->drm, + "Initial plane programming missing PTE_LM bit\n"); + return false; + } + + dma_addr = pte & GEN12_GGTT_PTE_ADDR_MASK; + + if (IS_DGFX(i915)) + mem = i915->mm.regions[INTEL_REGION_LMEM_0]; + else + mem = i915->mm.stolen_region; + if (!mem) { + drm_dbg_kms(&i915->drm, + "Initial plane memory region not initialized\n"); + return false; + } + + /* + * On lmem we don't currently expect this to + * ever be placed in the stolen portion. + */ + if (dma_addr < mem->region.start || dma_addr > mem->region.end) { + drm_err(&i915->drm, + "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", + &dma_addr, mem->region.name, &mem->region.start, &mem->region.end); + return false; + } + + drm_dbg(&i915->drm, + "Using dma_addr=%pa, based on initial plane programming\n", + &dma_addr); + + plane_config->phys_base = dma_addr - mem->region.start; + plane_config->mem = mem; + + return true; +} + +static bool +initial_plane_phys_smem(struct drm_i915_private *i915, + struct intel_initial_plane_config *plane_config) +{ + struct intel_memory_region *mem; + u32 base; + + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); + + mem = i915->mm.stolen_region; + if (!mem) { + drm_dbg_kms(&i915->drm, + "Initial plane memory region not initialized\n"); + return false; + } + + /* FIXME get and validate the dma_addr from the PTE */ + plane_config->phys_base = base; + plane_config->mem = mem; + + return true; +} + +static bool +initial_plane_phys(struct drm_i915_private *i915, + struct intel_initial_plane_config *plane_config) +{ + if (IS_DGFX(i915) || HAS_LMEMBAR_SMEM_STOLEN(i915)) + return initial_plane_phys_lmem(i915, plane_config); + else + return initial_plane_phys_smem(i915, plane_config); +} + static struct i915_vma * initial_plane_vma(struct drm_i915_private *i915, struct intel_initial_plane_config *plane_config) @@ -57,59 +144,13 @@ initial_plane_vma(struct drm_i915_private *i915, if (plane_config->size == 0) return NULL; - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); - if (IS_DGFX(i915) || HAS_LMEMBAR_SMEM_STOLEN(i915)) { - gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm; - dma_addr_t dma_addr; - gen8_pte_t pte; - - gte += base / I915_GTT_PAGE_SIZE; - - pte = ioread64(gte); - if (!(pte & GEN12_GGTT_PTE_LM)) { - drm_err(&i915->drm, - "Initial plane programming missing PTE_LM bit\n"); - return NULL; - } - - dma_addr = pte & GEN12_GGTT_PTE_ADDR_MASK; - - if (IS_DGFX(i915)) - mem = i915->mm.regions[INTEL_REGION_LMEM_0]; - else - mem = i915->mm.stolen_region; - if (!mem) { - drm_dbg_kms(&i915->drm, - "Initial plane memory region not initialized\n"); - return NULL; - } - - /* - * On lmem we don't currently expect this to - * ever be placed in the stolen portion. - */ - if (dma_addr < mem->region.start || dma_addr > mem->region.end) { - drm_err(&i915->drm, - "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", - &dma_addr, mem->region.name, &mem->region.start, &mem->region.end); - return NULL; - } + if (!initial_plane_phys(i915, plane_config)) + return NULL; - drm_dbg(&i915->drm, - "Using dma_addr=%pa, based on initial plane programming\n", - &dma_addr); - - phys_base = dma_addr - mem->region.start; - } else { - phys_base = base; - mem = i915->mm.stolen_region; - if (!mem) { - drm_dbg_kms(&i915->drm, - "Initial plane memory region not initialized\n"); - return NULL; - } - } + phys_base = plane_config->phys_base; + mem = plane_config->mem; + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); size = round_up(plane_config->base + plane_config->size, mem->min_page_size); size -= base; |