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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
if (!initial_plane_phys(i915, plane_config))
|
||||
return NULL;
|
||||
|
||||
phys_base = plane_config->phys_base;
|
||||
mem = plane_config->mem;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
size = round_up(plane_config->base + plane_config->size,
|
||||
mem->min_page_size);
|
||||
size -= base;
|
||||
|
||||
Reference in New Issue
Block a user