mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
drm/i915/display: Add drm_panic support for Y-tiling with DPT
On Alder Lake and later, it's not possible to disable tiling when DPT is enabled. So this commit implements Y-Tiling support, to still be able to draw the panic screen. Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://lore.kernel.org/r/20250624091501.257661-10-jfalempe@redhat.com Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
This commit is contained in:
committed by
Maarten Lankhorst
parent
31d886b674
commit
116d86dd69
@@ -1272,6 +1272,32 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
|
||||
intel_plane_unpin_fb(old_plane_state);
|
||||
}
|
||||
|
||||
/* Handle Y-tiling, only if DPT is enabled (otherwise disabling tiling is easier)
|
||||
* All DPT hardware have 128-bytes width tiling, so Y-tile dimension is 32x32
|
||||
* pixels for 32bits pixels.
|
||||
*/
|
||||
#define YTILE_WIDTH 32
|
||||
#define YTILE_HEIGHT 32
|
||||
#define YTILE_SIZE (YTILE_WIDTH * YTILE_HEIGHT * 4)
|
||||
|
||||
static unsigned int intel_ytile_get_offset(unsigned int width, unsigned int x, unsigned int y)
|
||||
{
|
||||
u32 offset;
|
||||
unsigned int swizzle;
|
||||
unsigned int width_in_blocks = DIV_ROUND_UP(width, 32);
|
||||
|
||||
/* Block offset */
|
||||
offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE;
|
||||
|
||||
x = x % YTILE_WIDTH;
|
||||
y = y % YTILE_HEIGHT;
|
||||
|
||||
/* bit order inside a block is x4 x3 x2 y4 y3 y2 y1 y0 x1 x0 */
|
||||
swizzle = (x & 3) | ((y & 0x1f) << 2) | ((x & 0x1c) << 5);
|
||||
offset += swizzle * 4;
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void intel_panic_flush(struct drm_plane *plane)
|
||||
{
|
||||
struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
|
||||
@@ -1295,6 +1321,35 @@ static void intel_panic_flush(struct drm_plane *plane)
|
||||
iplane->disable_tiling(iplane);
|
||||
}
|
||||
|
||||
static unsigned int (*intel_get_tiling_func(u64 fb_modifier))(unsigned int width,
|
||||
unsigned int x,
|
||||
unsigned int y)
|
||||
{
|
||||
switch (fb_modifier) {
|
||||
case I915_FORMAT_MOD_Y_TILED:
|
||||
case I915_FORMAT_MOD_Y_TILED_CCS:
|
||||
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
|
||||
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
|
||||
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
|
||||
return intel_ytile_get_offset;
|
||||
case I915_FORMAT_MOD_4_TILED:
|
||||
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
|
||||
case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
|
||||
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
|
||||
case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
|
||||
case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
|
||||
case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
|
||||
case I915_FORMAT_MOD_4_TILED_BMG_CCS:
|
||||
case I915_FORMAT_MOD_4_TILED_LNL_CCS:
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
case I915_FORMAT_MOD_Yf_TILED:
|
||||
case I915_FORMAT_MOD_Yf_TILED_CCS:
|
||||
default:
|
||||
/* Not supported yet */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_get_scanout_buffer(struct drm_plane *plane,
|
||||
struct drm_scanout_buffer *sb)
|
||||
{
|
||||
@@ -1320,8 +1375,13 @@ static int intel_get_scanout_buffer(struct drm_plane *plane,
|
||||
} else {
|
||||
int ret;
|
||||
/* Can't disable tiling if DPT is in use */
|
||||
if (intel_fb_uses_dpt(fb))
|
||||
return -EOPNOTSUPP;
|
||||
if (intel_fb_uses_dpt(fb)) {
|
||||
if (fb->format->cpp[0] != 4)
|
||||
return -EOPNOTSUPP;
|
||||
intel_fb->panic_tiling = intel_get_tiling_func(fb->modifier);
|
||||
if (!intel_fb->panic_tiling)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
sb->private = intel_fb;
|
||||
ret = intel_bo_panic_setup(sb);
|
||||
if (ret)
|
||||
|
||||
Reference in New Issue
Block a user