summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2024-09-16 19:24:11 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2024-09-24 10:45:21 +0300
commit7572d3f72ed3ad83d302d4fa0ff67706ce68994a (patch)
tree8ee8370aa862e9893afe0942ea40b0b3ab068d17
parent69aebe7a61ce49895e0352a1d5b5534e07094a46 (diff)
downloadlwn-7572d3f72ed3ad83d302d4fa0ff67706ce68994a.tar.gz
lwn-7572d3f72ed3ad83d302d4fa0ff67706ce68994a.zip
drm/i915: Move the dodgy pre-g4x wm stuff into i9xx_wm
As with other watermark calculations, the dodgy pre-g4x update_wm_{pre,post} flag calcultion would like to know if a modeset is about to happen or not, and technically later stages in the atomic_check() may still flag one. In practice that shouldn't happen as we don't have dynamic CDCLK implemented for these old platforms. Regardless it'll be nice to move this old cruft out from the supposedly platform agnostic plane code. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-6-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.c74
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c36
2 files changed, 74 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c
index 15052a822cc4..999fc085af28 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.c
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.c
@@ -706,6 +706,76 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
}
}
+static bool i9xx_wm_need_update(const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ /* Update watermarks on tiling or size changes. */
+ if (old_plane_state->uapi.visible != new_plane_state->uapi.visible)
+ return true;
+
+ if (!old_plane_state->hw.fb || !new_plane_state->hw.fb)
+ return false;
+
+ if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier ||
+ old_plane_state->hw.rotation != new_plane_state->hw.rotation ||
+ drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) ||
+ drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) ||
+ drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) ||
+ drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->uapi.dst))
+ return true;
+
+ return false;
+}
+
+static void i9xx_wm_compute(struct intel_crtc_state *new_crtc_state,
+ const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ bool turn_off, turn_on, visible, was_visible, mode_changed;
+
+ mode_changed = intel_crtc_needs_modeset(new_crtc_state);
+ was_visible = old_plane_state->uapi.visible;
+ visible = new_plane_state->uapi.visible;
+
+ if (!was_visible && !visible)
+ return;
+
+ turn_off = was_visible && (!visible || mode_changed);
+ turn_on = visible && (!was_visible || mode_changed);
+
+ /* FIXME nuke when all wm code is atomic */
+ if (turn_on) {
+ new_crtc_state->update_wm_pre = true;
+ } else if (turn_off) {
+ new_crtc_state->update_wm_post = true;
+ } else if (i9xx_wm_need_update(old_plane_state, new_plane_state)) {
+ /* FIXME bollocks */
+ new_crtc_state->update_wm_pre = true;
+ new_crtc_state->update_wm_post = true;
+ }
+}
+
+static int i9xx_compute_watermarks(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+ const struct intel_plane_state *old_plane_state;
+ const struct intel_plane_state *new_plane_state;
+ struct intel_plane *plane;
+ int i;
+
+ for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+ new_plane_state, i) {
+ if (plane->pipe != crtc->pipe)
+ continue;
+
+ i9xx_wm_compute(new_crtc_state, old_plane_state, new_plane_state);
+ }
+
+ return 0;
+}
+
/*
* Documentation says:
* "If the line size is small, the TLB fetches can get in the way of the
@@ -4057,18 +4127,22 @@ static const struct intel_wm_funcs g4x_wm_funcs = {
};
static const struct intel_wm_funcs pnv_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = pnv_update_wm,
};
static const struct intel_wm_funcs i965_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i965_update_wm,
};
static const struct intel_wm_funcs i9xx_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i9xx_update_wm,
};
static const struct intel_wm_funcs i845_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i845_update_wm,
};
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 49b5b2c4f2f2..b2cc7f1dee0c 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -392,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 *old_plane_state,
- const struct intel_plane_state *new_plane_state)
-{
- /* Update watermarks on tiling or size changes. */
- if (old_plane_state->uapi.visible != new_plane_state->uapi.visible)
- return true;
-
- if (!old_plane_state->hw.fb || !new_plane_state->hw.fb)
- return false;
-
- if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier ||
- old_plane_state->hw.rotation != new_plane_state->hw.rotation ||
- drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) ||
- drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) ||
- drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) ||
- drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->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;
@@ -602,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;