summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fb.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c378
1 files changed, 222 insertions, 156 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 0c0144eaa8fa..223c4218c019 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -3,13 +3,16 @@
* Copyright © 2021 Intel Corporation
*/
-#include <drm/drm_blend.h>
-#include <drm/drm_modeset_helper.h>
-
#include <linux/dma-fence.h>
#include <linux/dma-resv.h>
+#include <drm/drm_blend.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_modeset_helper.h>
+
#include "i915_drv.h"
+#include "intel_atomic_plane.h"
+#include "intel_bo.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
@@ -42,6 +45,14 @@ static const struct drm_format_info skl_ccs_formats[] = {
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
};
/*
@@ -64,6 +75,30 @@ static const struct drm_format_info gen12_ccs_formats[] = {
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
.char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
.hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_YUYV, .num_planes = 2,
.char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
.hsub = 2, .vsub = 1, .is_yuv = true },
@@ -99,31 +134,79 @@ static const struct drm_format_info gen12_ccs_formats[] = {
*/
static const struct drm_format_info gen12_ccs_cc_formats[] = {
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
};
static const struct drm_format_info gen12_flat_ccs_cc_formats[] = {
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
};
@@ -161,6 +244,14 @@ struct intel_modifier_desc {
static const struct intel_modifier_desc intel_modifiers[] = {
{
+ .modifier = I915_FORMAT_MOD_4_TILED_LNL_CCS,
+ .display_ver = { 20, -1 },
+ .plane_caps = INTEL_PLANE_CAP_TILING_4,
+ }, {
+ .modifier = I915_FORMAT_MOD_4_TILED_BMG_CCS,
+ .display_ver = { 14, -1 },
+ .plane_caps = INTEL_PLANE_CAP_TILING_4 | INTEL_PLANE_CAP_NEED64K_PHYS,
+ }, {
.modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS,
.display_ver = { 14, 14 },
.plane_caps = INTEL_PLANE_CAP_TILING_4 | INTEL_PLANE_CAP_CCS_MC,
@@ -258,7 +349,7 @@ static const struct intel_modifier_desc intel_modifiers[] = {
.plane_caps = INTEL_PLANE_CAP_TILING_Y,
}, {
.modifier = I915_FORMAT_MOD_X_TILED,
- .display_ver = DISPLAY_VER_ALL,
+ .display_ver = { 0, 29 },
.plane_caps = INTEL_PLANE_CAP_TILING_X,
}, {
.modifier = DRM_FORMAT_MOD_LINEAR,
@@ -410,6 +501,37 @@ bool intel_fb_is_mc_ccs_modifier(u64 modifier)
INTEL_PLANE_CAP_CCS_MC);
}
+/**
+ * intel_fb_needs_64k_phys: Check if modifier requires 64k physical placement.
+ * @modifier: Modifier to check
+ *
+ * Returns:
+ * Returns %true if @modifier requires 64k aligned physical pages.
+ */
+bool intel_fb_needs_64k_phys(u64 modifier)
+{
+ const struct intel_modifier_desc *md = lookup_modifier_or_null(modifier);
+
+ if (!md)
+ return false;
+
+ return plane_caps_contain_any(md->plane_caps,
+ INTEL_PLANE_CAP_NEED64K_PHYS);
+}
+
+/**
+ * intel_fb_is_tile4_modifier: Check if a modifier is a tile4 modifier type
+ * @modifier: Modifier to check
+ *
+ * Returns:
+ * Returns %true if @modifier is a tile4 modifier.
+ */
+bool intel_fb_is_tile4_modifier(u64 modifier)
+{
+ return plane_caps_contain_any(lookup_modifier(modifier)->plane_caps,
+ INTEL_PLANE_CAP_TILING_4);
+}
+
static bool check_modifier_display_ver_range(const struct intel_modifier_desc *md,
u8 display_ver_from, u8 display_ver_until)
{
@@ -435,6 +557,14 @@ static bool plane_has_modifier(struct drm_i915_private *i915,
HAS_FLAT_CCS(i915) != !md->ccs.packed_aux_planes)
return false;
+ if (md->modifier == I915_FORMAT_MOD_4_TILED_BMG_CCS &&
+ (GRAPHICS_VER(i915) < 20 || !IS_DGFX(i915)))
+ return false;
+
+ if (md->modifier == I915_FORMAT_MOD_4_TILED_LNL_CCS &&
+ (GRAPHICS_VER(i915) < 20 || IS_DGFX(i915)))
+ return false;
+
return true;
}
@@ -583,12 +713,6 @@ static bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int color_pl
return intel_fb_rc_ccs_cc_plane(fb) == color_plane;
}
-static bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane)
-{
- return intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
- color_plane == 1;
-}
-
bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane)
{
return fb->modifier == DRM_FORMAT_MOD_LINEAR ||
@@ -657,6 +781,8 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
return 128;
else
return 512;
+ case I915_FORMAT_MOD_4_TILED_BMG_CCS:
+ case I915_FORMAT_MOD_4_TILED_LNL_CCS:
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
@@ -775,90 +901,6 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
}
-unsigned int intel_cursor_alignment(const struct drm_i915_private *i915)
-{
- if (IS_I830(i915))
- return 16 * 1024;
- else if (IS_I85X(i915))
- return 256;
- else if (IS_I845G(i915) || IS_I865G(i915))
- return 32;
- else
- return 4 * 1024;
-}
-
-static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv)
-{
- if (DISPLAY_VER(dev_priv) >= 9)
- return 256 * 1024;
- else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) ||
- IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- return 128 * 1024;
- else if (DISPLAY_VER(dev_priv) >= 4)
- return 4 * 1024;
- else
- return 0;
-}
-
-unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
- int color_plane)
-{
- struct drm_i915_private *dev_priv = to_i915(fb->dev);
-
- if (intel_fb_uses_dpt(fb))
- return 512 * 4096;
-
- /* AUX_DIST needs only 4K alignment */
- if (intel_fb_is_ccs_aux_plane(fb, color_plane))
- return 4096;
-
- if (is_semiplanar_uv_plane(fb, color_plane)) {
- /*
- * TODO: cross-check wrt. the bspec stride in bytes * 64 bytes
- * alignment for linear UV planes on all platforms.
- */
- if (DISPLAY_VER(dev_priv) >= 12) {
- if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
- return intel_linear_alignment(dev_priv);
-
- return intel_tile_row_size(fb, color_plane);
- }
-
- return 4096;
- }
-
- drm_WARN_ON(&dev_priv->drm, color_plane != 0);
-
- switch (fb->modifier) {
- case DRM_FORMAT_MOD_LINEAR:
- return intel_linear_alignment(dev_priv);
- case I915_FORMAT_MOD_X_TILED:
- if (HAS_ASYNC_FLIPS(dev_priv))
- return 256 * 1024;
- return 0;
- case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
- case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
- case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
- case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
- case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
- case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
- return 16 * 1024;
- case I915_FORMAT_MOD_Y_TILED_CCS:
- case I915_FORMAT_MOD_Yf_TILED_CCS:
- case I915_FORMAT_MOD_Y_TILED:
- case I915_FORMAT_MOD_4_TILED:
- case I915_FORMAT_MOD_Yf_TILED:
- return 1 * 1024 * 1024;
- case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
- case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
- case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
- return 16 * 1024;
- default:
- MISSING_CASE(fb->modifier);
- return 0;
- }
-}
-
void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
const struct drm_framebuffer *fb,
int color_plane)
@@ -1030,7 +1072,7 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
int color_plane,
unsigned int pitch,
unsigned int rotation,
- u32 alignment)
+ unsigned int alignment)
{
unsigned int cpp = fb->format->cpp[color_plane];
u32 offset, offset_aligned;
@@ -1083,17 +1125,12 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
const struct intel_plane_state *state,
int color_plane)
{
- struct intel_plane *intel_plane = to_intel_plane(state->uapi.plane);
- struct drm_i915_private *i915 = to_i915(intel_plane->base.dev);
+ struct intel_plane *plane = to_intel_plane(state->uapi.plane);
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = state->hw.fb;
unsigned int rotation = state->hw.rotation;
- int pitch = state->view.color_plane[color_plane].mapping_stride;
- u32 alignment;
-
- if (intel_plane->id == PLANE_CURSOR)
- alignment = intel_cursor_alignment(i915);
- else
- alignment = intel_surf_alignment(fb, color_plane);
+ unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
+ unsigned int alignment = plane->min_alignment(plane, fb, color_plane);
return intel_compute_aligned_offset(i915, x, y, fb, color_plane,
pitch, rotation, alignment);
@@ -1105,14 +1142,9 @@ static int intel_fb_offset_to_xy(int *x, int *y,
int color_plane)
{
struct drm_i915_private *i915 = to_i915(fb->dev);
- unsigned int height;
- u32 alignment;
-
- if (DISPLAY_VER(i915) >= 12 &&
- !intel_fb_needs_pot_stride_remap(to_intel_framebuffer(fb)) &&
- is_semiplanar_uv_plane(fb, color_plane))
- alignment = intel_tile_row_size(fb, color_plane);
- else if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
+ unsigned int height, alignment, unused;
+
+ if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
alignment = intel_tile_size(i915);
else
alignment = 0;
@@ -1128,8 +1160,8 @@ static int intel_fb_offset_to_xy(int *x, int *y,
height = ALIGN(height, intel_tile_height(fb, color_plane));
/* Catch potential overflows early */
- if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]),
- fb->offsets[color_plane])) {
+ if (check_add_overflow(mul_u32_u32(height, fb->pitches[color_plane]),
+ fb->offsets[color_plane], &unused)) {
drm_dbg_kms(&i915->drm,
"Bad offset 0x%08x or pitch %d for color plane %d\n",
fb->offsets[color_plane], fb->pitches[color_plane],
@@ -1286,7 +1318,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int color_plane,
int plane_width, int *x, int *y)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
int ret;
ret = intel_fb_offset_to_xy(x, y, &fb->base, color_plane);
@@ -1310,7 +1342,7 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co
* fb layout agrees with the fence layout. We already check that the
* fb stride matches the fence stride elsewhere.
*/
- if (color_plane == 0 && i915_gem_object_is_tiled(obj) &&
+ if (color_plane == 0 && intel_bo_is_tiled(obj) &&
(*x + plane_width) * fb->base.format->cpp[color_plane] > fb->base.pitches[color_plane]) {
drm_dbg_kms(fb->base.dev,
"bad fb plane %d offset: 0x%x\n",
@@ -1493,8 +1525,8 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
check_array_bounds(i915, view->gtt.remapped.plane, color_plane);
if (view->gtt.remapped.plane_alignment) {
- unsigned int aligned_offset = ALIGN(gtt_offset,
- view->gtt.remapped.plane_alignment);
+ u32 aligned_offset = ALIGN(gtt_offset,
+ view->gtt.remapped.plane_alignment);
size += aligned_offset - gtt_offset;
gtt_offset = aligned_offset;
@@ -1602,9 +1634,35 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
fb->base.modifier == I915_FORMAT_MOD_Yf_TILED;
}
+static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
+{
+ struct drm_i915_private *i915 = to_i915(fb->dev);
+ struct intel_plane *plane;
+ unsigned int min_alignment = 0;
+
+ for_each_intel_plane(&i915->drm, plane) {
+ unsigned int plane_min_alignment;
+
+ if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
+ continue;
+
+ plane_min_alignment = plane->min_alignment(plane, fb, 0);
+
+ drm_WARN_ON(&i915->drm, plane_min_alignment &&
+ !is_power_of_2(plane_min_alignment));
+
+ if (intel_plane_needs_physical(plane))
+ continue;
+
+ min_alignment = max(min_alignment, plane_min_alignment);
+ }
+
+ return min_alignment;
+}
+
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
u32 gtt_offset_rotated = 0;
u32 gtt_offset_remapped = 0;
unsigned int max_size = 0;
@@ -1636,7 +1694,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
* arithmetic related to alignment and offset calculation.
*/
if (is_gen12_ccs_cc_plane(&fb->base, i)) {
- if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE))
+ if (IS_ALIGNED(fb->base.offsets[i], 64))
continue;
else
return -EINVAL;
@@ -1677,13 +1735,15 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
max_size = max(max_size, offset + size);
}
- if (mul_u32_u32(max_size, tile_size) > intel_bo_to_drm_bo(obj)->size) {
+ if (mul_u32_u32(max_size, tile_size) > obj->size) {
drm_dbg_kms(&i915->drm,
"fb too big for bo (need %llu bytes, have %zu bytes)\n",
- mul_u32_u32(max_size, tile_size), intel_bo_to_drm_bo(obj)->size);
+ mul_u32_u32(max_size, tile_size), obj->size);
return -EINVAL;
}
+ fb->min_alignment = intel_fb_min_alignment(&fb->base);
+
return 0;
}
@@ -1780,16 +1840,16 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
return 128 * 1024;
}
-static u32
+static unsigned int
intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
{
struct drm_i915_private *dev_priv = to_i915(fb->dev);
- u32 tile_width;
+ unsigned int tile_width;
if (is_surface_linear(fb, color_plane)) {
- u32 max_stride = intel_plane_fb_max_stride(dev_priv,
- fb->format->format,
- fb->modifier);
+ unsigned int max_stride = intel_plane_fb_max_stride(dev_priv,
+ fb->format->format,
+ fb->modifier);
/*
* To make remapping with linear generally feasible
@@ -1849,9 +1909,10 @@ static int intel_plane_check_stride(const struct intel_plane_state *plane_state)
fb->modifier, rotation);
if (stride > max_stride) {
- DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
- fb->base.id, stride,
- plane->base.base.id, plane->base.name, max_stride);
+ drm_dbg_kms(plane->base.dev,
+ "[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
+ fb->base.id, stride,
+ plane->base.base.id, plane->base.name, max_stride);
return -EINVAL;
}
@@ -1901,7 +1962,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
intel_frontbuffer_put(intel_fb->frontbuffer);
- intel_fb_bo_framebuffer_fini(intel_fb_obj(fb));
+ intel_fb_bo_framebuffer_fini(intel_fb_bo(fb));
kfree(intel_fb);
}
@@ -1910,16 +1971,16 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file,
unsigned int *handle)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_private *i915 = to_i915(intel_bo_to_drm_bo(obj)->dev);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
+ struct intel_display *display = to_intel_display(obj->dev);
- if (i915_gem_object_is_userptr(obj)) {
- drm_dbg(&i915->drm,
+ if (intel_bo_is_userptr(obj)) {
+ drm_dbg(display->drm,
"attempting to use a userptr for a framebuffer, denied\n");
return -EINVAL;
}
- return drm_gem_handle_create(file, intel_bo_to_drm_bo(obj), handle);
+ return drm_gem_handle_create(file, obj, handle);
}
struct frontbuffer_fence_cb {
@@ -1943,7 +2004,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_clip_rect *clips,
unsigned int num_clips)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
struct intel_frontbuffer *front = to_intel_frontbuffer(fb);
struct dma_fence *fence;
struct frontbuffer_fence_cb *cb;
@@ -1952,10 +2013,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
if (!atomic_read(&front->bits))
return 0;
- if (dma_resv_test_signaled(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false)))
+ if (dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(false)))
goto flush;
- ret = dma_resv_get_singleton(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false),
+ ret = dma_resv_get_singleton(obj->resv, dma_resv_usage_rw(false),
&fence);
if (ret || !fence)
goto flush;
@@ -1982,7 +2043,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
return ret;
flush:
- i915_gem_object_flush_if_display(obj);
+ intel_bo_flush_if_display(obj);
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
return ret;
}
@@ -1994,10 +2055,10 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
};
int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
- struct drm_i915_private *dev_priv = to_i915(intel_bo_to_drm_bo(obj)->dev);
+ struct drm_i915_private *dev_priv = to_i915(obj->dev);
struct drm_framebuffer *fb = &intel_fb->base;
u32 max_stride;
int ret = -EINVAL;
@@ -2045,7 +2106,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
for (i = 0; i < fb->format->num_planes; i++) {
- u32 stride_alignment;
+ unsigned int stride_alignment;
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n",
@@ -2062,7 +2123,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
}
if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
- int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
+ unsigned int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
if (fb->pitches[i] != ccs_aux_stride) {
drm_dbg_kms(&dev_priv->drm,
@@ -2073,7 +2134,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
}
}
- fb->obj[i] = intel_bo_to_drm_bo(obj);
+ fb->obj[i] = obj;
}
ret = intel_fill_fb_info(dev_priv, intel_fb);
@@ -2117,7 +2178,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
const struct drm_mode_fb_cmd2 *user_mode_cmd)
{
struct drm_framebuffer *fb;
- struct drm_i915_gem_object *obj;
+ struct drm_gem_object *obj;
struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
struct drm_i915_private *i915 = to_i915(dev);
@@ -2126,13 +2187,13 @@ intel_user_framebuffer_create(struct drm_device *dev,
return ERR_CAST(obj);
fb = intel_framebuffer_create(obj, &mode_cmd);
- drm_gem_object_put(intel_bo_to_drm_bo(obj));
+ drm_gem_object_put(obj);
return fb;
}
struct drm_framebuffer *
-intel_framebuffer_create(struct drm_i915_gem_object *obj,
+intel_framebuffer_create(struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct intel_framebuffer *intel_fb;
@@ -2152,3 +2213,8 @@ err:
kfree(intel_fb);
return ERR_PTR(ret);
}
+
+struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb)
+{
+ return fb ? fb->obj[0] : NULL;
+}