summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_atomic_plane.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 14:56:17 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 14:56:17 -0800
commit28eb75e178d389d325f1666e422bc13bbbb9804c (patch)
tree20417b4e798f98fc5687e80c1e0126afcf437c70 /drivers/gpu/drm/i915/display/intel_atomic_plane.c
parent071b34dcf71523a559b6c39f5d21a268a9531b50 (diff)
parenta163b895077861598be48c1cf7f4a88413c28b22 (diff)
Merge tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel
Pull drm updates from Dave Airlie: "There's a lot of rework, the panic helper support is being added to more drivers, v3d gets support for HW superpages, scheduler documentation, drm client and video aperture reworks, some new MAINTAINERS added, amdgpu has the usual lots of IP refactors, Intel has some Pantherlake enablement and xe is getting some SRIOV bits, but just lots of stuff everywhere. core: - split DSC helpers from DP helpers - clang build fixes for drm/mm test - drop simple pipeline support for gem vram - document submission error signaling - move drm_rect to drm core module from kms helper - add default client setup to most drivers - move to video aperture helpers instead of drm ones tests: - new framebuffer tests ttm: - remove swapped and pinned BOs from TTM lru panic: - fix uninit spinlock - add ABGR2101010 support bridge: - add TI TDP158 support - use standard PM OPS dma-fence: - use read_trylock instead of read_lock to help lockdep scheduler: - add errno to sched start to report different errors - add locking to drm_sched_entity_modify_sched - improve documentation xe: - add drm_line_printer - lots of refactoring - Enable Xe2 + PES disaggregation - add new ARL PCI ID - SRIOV development work - fix exec unnecessary implicit fence - define and parse OA sync props - forcewake refactoring i915: - Enable BMG/LNL ultra joiner - Enable 10bpx + CCS scanout on ICL+, fp16/CCS on TGL+ - use DSB for plane/color mgmt - Arrow lake PCI IDs - lots of i915/xe display refactoring - enable PXP GuC autoteardown - Pantherlake (PTL) Xe3 LPD display enablement - Allow fastset HDR infoframe changes - write DP source OUI for non-eDP sinks - share PCI IDs between i915 and xe amdgpu: - SDMA queue reset support - SMU 13.0.6, JPEG 4.0.3 updates - Initial runtime repartitioning support - rework IP structs for multiple IP instances - Fetch EDID from _DDC if available - SMU13 zero rpm user control - lots of fixes/cleanups amdkfd: - Increase event FIFO size - add topology cap flag for per queue reset msm: - DPU: - SA8775P support - (disabled by default) MSM8917, MSM8937, MSM8953 and MSM8996 support - Enable large framebuffer support - Drop MSM8998 and SDM845 - DP: - SA8775P support - GPU: - a7xx preemption support - Adreno A663 support ast: - warn about unsupported TX chips ivpu: - add coredump - add pantherlake support rockchip: - 4K@60Hz display enablement - generate pll programming tables panthor: - add timestamp query API - add realtime group priority - add fdinfo support etnaviv: - improve handling of DMA address limits - improve GPU hangcheck exynos: - Decon Exynos7870 support mediatek: - add OF graph support omap: - locking fixes bochs: - convert to gem/shmem from simpledrm v3d: - support big/super pages - add gemfs vc4: - BCM2712 support refactoring - add YUV444 format support udmabuf: - folio related fixes nouveau: - add panic support on nv50+" * tag 'drm-next-2024-11-21' of https://gitlab.freedesktop.org/drm/kernel: (1583 commits) drm/xe/guc: Fix dereference before NULL check drm/amd: Fix initialization mistake for NBIO 7.7.0 Revert "drm/amd/display: parse umc_info or vram_info based on ASIC" drm/amd/display: Fix failure to read vram info due to static BP_RESULT drm/amdgpu: enable GTT fallback handling for dGPUs only drm/amd/amdgpu: limit single process inside MES drm/fourcc: add AMD_FMT_MOD_TILE_GFX9_4K_D_X drm/amdgpu/mes12: correct kiq unmap latency drm/amdgpu: Support vcn and jpeg error info parsing drm/amd : Update MES API header file for v11 & v12 drm/amd/amdkfd: add/remove kfd queues on start/stop KFD scheduling drm/amdkfd: change kfd process kref count at creation drm/amdgpu: Cleanup shift coding style drm/amd/amdgpu: Increase MES log buffer to dump mes scratch data drm/amdgpu: Implement virt req_ras_err_count drm/amdgpu: VF Query RAS Caps from Host if supported drm/amdgpu: Add msg handlers for SRIOV RAS Telemetry drm/amdgpu: Update SRIOV Exchange Headers for RAS Telemetry Support drm/amd/display: 3.2.309 drm/amd/display: Adjust VSDB parser for replay feature ...
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_atomic_plane.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c203
1 files changed, 101 insertions, 102 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index e979786aa5cf..d89630b2d5c1 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -35,9 +35,10 @@
#include <linux/dma-resv.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_gem_atomic_helper.h>
#include "i915_config.h"
#include "i9xx_plane_regs.h"
@@ -391,28 +392,6 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
plane_state->uapi.visible = false;
}
-/* FIXME nuke when all wm code is atomic */
-static bool intel_wm_need_update(const struct intel_plane_state *cur,
- struct intel_plane_state *new)
-{
- /* Update watermarks on tiling or size changes. */
- if (new->uapi.visible != cur->uapi.visible)
- return true;
-
- if (!cur->hw.fb || !new->hw.fb)
- return false;
-
- if (cur->hw.fb->modifier != new->hw.fb->modifier ||
- cur->hw.rotation != new->hw.rotation ||
- drm_rect_width(&new->uapi.src) != drm_rect_width(&cur->uapi.src) ||
- drm_rect_height(&new->uapi.src) != drm_rect_height(&cur->uapi.src) ||
- drm_rect_width(&new->uapi.dst) != drm_rect_width(&cur->uapi.dst) ||
- drm_rect_height(&new->uapi.dst) != drm_rect_height(&cur->uapi.dst))
- return true;
-
- return false;
-}
-
static bool intel_plane_is_scaled(const struct intel_plane_state *plane_state)
{
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
@@ -492,6 +471,61 @@ static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state
return old_ctl != new_ctl;
}
+static bool ilk_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
+ const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+ bool old_visible = old_plane_state->uapi.visible;
+ bool new_visible = new_plane_state->uapi.visible;
+ bool modeset, turn_on;
+
+ if (plane->id == PLANE_CURSOR)
+ return false;
+
+ modeset = intel_crtc_needs_modeset(new_crtc_state);
+ turn_on = new_visible && (!old_visible || modeset);
+
+ /*
+ * ILK/SNB DVSACNTR/Sprite Enable
+ * IVB SPR_CTL/Sprite Enable
+ * "When in Self Refresh Big FIFO mode, a write to enable the
+ * plane will be internally buffered and delayed while Big FIFO
+ * mode is exiting."
+ *
+ * Which means that enabling the sprite can take an extra frame
+ * when we start in big FIFO mode (LP1+). Thus we need to drop
+ * down to LP0 and wait for vblank in order to make sure the
+ * sprite gets enabled on the next vblank after the register write.
+ * Doing otherwise would risk enabling the sprite one frame after
+ * we've already signalled flip completion. We can resume LP1+
+ * once the sprite has been enabled.
+ *
+ * With experimental results seems this is needed also for primary
+ * plane, not only sprite plane.
+ */
+ if (turn_on)
+ return true;
+
+ /*
+ * WaCxSRDisabledForSpriteScaling:ivb
+ * IVB SPR_SCALE/Scaling Enable
+ * "Low Power watermarks must be disabled for at least one
+ * frame before enabling sprite scaling, and kept disabled
+ * until sprite scaling is disabled."
+ *
+ * ILK/SNB DVSASCALE/Scaling Enable
+ * "When in Self Refresh Big FIFO mode, scaling enable will be
+ * masked off while Big FIFO mode is exiting."
+ *
+ * Despite the w/a only being listed for IVB we assume that
+ * the ILK/SNB note has similar ramifications, hence we apply
+ * the w/a on all three platforms.
+ */
+ return !intel_plane_is_scaled(old_plane_state) &&
+ intel_plane_is_scaled(new_plane_state);
+}
+
static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state,
const struct intel_plane_state *old_plane_state,
@@ -546,20 +580,6 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
was_visible, visible,
turn_off, turn_on, mode_changed);
- if (turn_on) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- new_crtc_state->update_wm_pre = true;
- } else if (turn_off) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- new_crtc_state->update_wm_post = true;
- } else if (intel_wm_need_update(old_plane_state, new_plane_state)) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
- /* FIXME bollocks */
- new_crtc_state->update_wm_pre = true;
- new_crtc_state->update_wm_post = true;
- }
- }
-
if (visible || was_visible)
new_crtc_state->fb_bits |= plane->frontbuffer_bit;
@@ -567,45 +587,9 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
new_crtc_state->disable_cxsr = true;
- /*
- * ILK/SNB DVSACNTR/Sprite Enable
- * IVB SPR_CTL/Sprite Enable
- * "When in Self Refresh Big FIFO mode, a write to enable the
- * plane will be internally buffered and delayed while Big FIFO
- * mode is exiting."
- *
- * Which means that enabling the sprite can take an extra frame
- * when we start in big FIFO mode (LP1+). Thus we need to drop
- * down to LP0 and wait for vblank in order to make sure the
- * sprite gets enabled on the next vblank after the register write.
- * Doing otherwise would risk enabling the sprite one frame after
- * we've already signalled flip completion. We can resume LP1+
- * once the sprite has been enabled.
- *
- *
- * WaCxSRDisabledForSpriteScaling:ivb
- * IVB SPR_SCALE/Scaling Enable
- * "Low Power watermarks must be disabled for at least one
- * frame before enabling sprite scaling, and kept disabled
- * until sprite scaling is disabled."
- *
- * ILK/SNB DVSASCALE/Scaling Enable
- * "When in Self Refresh Big FIFO mode, scaling enable will be
- * masked off while Big FIFO mode is exiting."
- *
- * Despite the w/a only being listed for IVB we assume that
- * the ILK/SNB note has similar ramifications, hence we apply
- * the w/a on all three platforms.
- *
- * With experimental results seems this is needed also for primary
- * plane, not only sprite plane.
- */
- if (plane->id != PLANE_CURSOR &&
- (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)) &&
- (turn_on || (!intel_plane_is_scaled(old_plane_state) &&
- intel_plane_is_scaled(new_plane_state))))
- new_crtc_state->disable_lp_wm = true;
+ if ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) &&
+ ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
+ new_crtc_state->disable_cxsr = true;
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
@@ -710,13 +694,13 @@ intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
int intel_plane_atomic_check(struct intel_atomic_state *state,
struct intel_plane *plane)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_plane_state *new_plane_state =
intel_atomic_get_new_plane_state(state, plane);
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
const struct intel_plane_state *new_primary_crtc_plane_state;
- struct intel_crtc *crtc = intel_crtc_for_pipe(i915, plane->pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc_state *new_crtc_state =
@@ -790,7 +774,8 @@ skl_next_plane_to_commit(struct intel_atomic_state *state,
return NULL;
}
-void intel_plane_update_noarm(struct intel_plane *plane,
+void intel_plane_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -799,10 +784,11 @@ void intel_plane_update_noarm(struct intel_plane *plane,
trace_intel_plane_update_noarm(plane, crtc);
if (plane->update_noarm)
- plane->update_noarm(plane, crtc_state, plane_state);
+ plane->update_noarm(dsb, plane, crtc_state, plane_state);
}
-void intel_plane_async_flip(struct intel_plane *plane,
+void intel_plane_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
@@ -810,34 +796,37 @@ void intel_plane_async_flip(struct intel_plane *plane,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_plane_async_flip(plane, crtc, async_flip);
- plane->async_flip(plane, crtc_state, plane_state, async_flip);
+ plane->async_flip(dsb, plane, crtc_state, plane_state, async_flip);
}
-void intel_plane_update_arm(struct intel_plane *plane,
+void intel_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (crtc_state->do_async_flip && plane->async_flip) {
- intel_plane_async_flip(plane, crtc_state, plane_state, true);
+ intel_plane_async_flip(dsb, plane, crtc_state, plane_state, true);
return;
}
trace_intel_plane_update_arm(plane, crtc);
- plane->update_arm(plane, crtc_state, plane_state);
+ plane->update_arm(dsb, plane, crtc_state, plane_state);
}
-void intel_plane_disable_arm(struct intel_plane *plane,
+void intel_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_plane_disable_arm(plane, crtc);
- plane->disable_arm(plane, crtc_state);
+ plane->disable_arm(dsb, plane, crtc_state);
}
-void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_noarm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
@@ -862,11 +851,13 @@ void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
/* TODO: for mailbox updates this should be skipped */
if (new_plane_state->uapi.visible ||
new_plane_state->planar_slave)
- intel_plane_update_noarm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_noarm(dsb, plane,
+ new_crtc_state, new_plane_state);
}
}
-static void skl_crtc_planes_update_arm(struct intel_atomic_state *state,
+static void skl_crtc_planes_update_arm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *old_crtc_state =
@@ -893,13 +884,14 @@ static void skl_crtc_planes_update_arm(struct intel_atomic_state *state,
*/
if (new_plane_state->uapi.visible ||
new_plane_state->planar_slave)
- intel_plane_update_arm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
else
- intel_plane_disable_arm(plane, new_crtc_state);
+ intel_plane_disable_arm(dsb, plane, new_crtc_state);
}
}
-static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state,
+static void i9xx_crtc_planes_update_arm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
@@ -919,21 +911,22 @@ static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state,
* would have to be called here as well.
*/
if (new_plane_state->uapi.visible)
- intel_plane_update_arm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
else
- intel_plane_disable_arm(plane, new_crtc_state);
+ intel_plane_disable_arm(dsb, plane, new_crtc_state);
}
}
-void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_arm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
if (DISPLAY_VER(i915) >= 9)
- skl_crtc_planes_update_arm(state, crtc);
+ skl_crtc_planes_update_arm(dsb, state, crtc);
else
- i9xx_crtc_planes_update_arm(state, crtc);
+ i9xx_crtc_planes_update_arm(dsb, state, crtc);
}
int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
@@ -1031,6 +1024,12 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
*/
hsub = 1;
vsub = 1;
+
+ /* Wa_16023981245 */
+ if ((DISPLAY_VERx100(i915) == 2000 ||
+ DISPLAY_VERx100(i915) == 3000) &&
+ src_x % 2 != 0)
+ hsub = 2;
} else {
hsub = fb->format->hsub;
vsub = fb->format->vsub;
@@ -1114,8 +1113,8 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
- struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb);
- struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb);
+ struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb);
+ struct drm_gem_object *old_obj = intel_fb_bo(old_plane_state->hw.fb);
int ret;
if (old_obj) {
@@ -1135,7 +1134,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
* can safely continue.
*/
if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) {
- ret = add_dma_resv_fences(intel_bo_to_drm_bo(old_obj)->resv,
+ ret = add_dma_resv_fences(old_obj->resv,
&new_plane_state->uapi);
if (ret < 0)
return ret;
@@ -1195,7 +1194,7 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
struct intel_atomic_state *state =
to_intel_atomic_state(old_plane_state->uapi.state);
struct drm_i915_private *dev_priv = to_i915(plane->dev);
- struct drm_i915_gem_object *obj = intel_fb_obj(old_plane_state->hw.fb);
+ struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb);
if (!obj)
return;