diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2024-02-03 00:43:35 +0200 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2024-02-07 01:59:15 +0200 |
commit | 6bfdb06d1efafaa289f16ff5e5dfb4b02327525e (patch) | |
tree | 29cf4c261eaad24ba55cd896424fd25575028ee5 | |
parent | 27fbcaf7ca2470dbc112a5ea2759ad6408581c79 (diff) | |
download | linux-6bfdb06d1efafaa289f16ff5e5dfb4b02327525e.tar.gz linux-6bfdb06d1efafaa289f16ff5e5dfb4b02327525e.tar.bz2 linux-6bfdb06d1efafaa289f16ff5e5dfb4b02327525e.zip |
drm/i915: Split the smem and lmem plane readout apart
Declutter initial_plane_vma() a bit by pulling the lmem and smem
readout paths into their own functions.
TODO: the smem path should still be fixed to get and validate
the dma address from the pte as well
Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
Tested-by: Paz Zcharya <pazz@chromium.org>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240202224340.30647-12-ville.syrjala@linux.intel.com
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display_types.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_plane_initial.c | 143 |
2 files changed, 94 insertions, 51 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ae2e8cff9d69..319ba7aed4fa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -780,6 +780,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/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index 48b74319f45c..78bff6181ceb 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -44,6 +44,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) @@ -58,59 +145,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; |