Commit 6bfdb06d authored by Ville Syrjälä's avatar Ville Syrjälä

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: default avatarAndrzej Hajda <andrzej.hajda@intel.com>
Tested-by: default avatarPaz Zcharya <pazz@chromium.org>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240202224340.30647-12-ville.syrjala@linux.intel.com
parent 27fbcaf7
......@@ -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;
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment