diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-03-03 22:12:01 +0300 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-03-21 18:48:39 +0300 |
commit | c034363ca898ea0f809efb113e232dfd0b3e59f2 (patch) | |
tree | f6ef8e155f5e7772c8db1553b7c0ef88cd933e41 /drivers/gpu/drm/i915/display/intel_atomic_plane.c | |
parent | 943ed3cc02191b220eb430dc855509ccc2c1a28e (diff) | |
download | linux-c034363ca898ea0f809efb113e232dfd0b3e59f2.tar.xz |
drm/i915: Pre-calculate plane relative data rate
Handle the plane relative data rate in exactly the same
way as we already handle the real data rate. Ie. pre-calculate
it during intel_plane_atomic_check_with_state(), and assign/clear
it for the Y plane as needed. This should guarantee that the
tracking is 100% consistent, and makes me have to think less
when the same apporach is used by both types of data rate.
We might even want to consider replacing the relative
data rate with the real data rate entirely, but it's not
clear if that will produce less optimal plane ddb
allocations. So for now lets keep using the current approach.
v2: Rebase due to async flip wm optimization
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220303191207.27931-4-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_atomic_plane.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_atomic_plane.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b6c80824aea1..3d87da283cfa 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -193,6 +193,57 @@ unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state, fb->format->cpp[color_plane]; } +static bool +use_min_ddb(const struct intel_crtc_state *crtc_state, + struct intel_plane *plane) +{ + struct drm_i915_private *i915 = to_i915(plane->base.dev); + + return DISPLAY_VER(i915) >= 13 && + crtc_state->uapi.async_flip && + plane->async_flip; +} + +static unsigned int +intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state, + int color_plane) +{ + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + const struct drm_framebuffer *fb = plane_state->hw.fb; + int width, height; + + if (plane->id == PLANE_CURSOR) + return 0; + + if (!plane_state->uapi.visible) + return 0; + + /* + * We calculate extra ddb based on ratio plane rate/total data rate + * in case, in some cases we should not allocate extra ddb for the plane, + * so do not count its data rate, if this is the case. + */ + if (use_min_ddb(crtc_state, plane)) + return 0; + + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ + width = drm_rect_width(&plane_state->uapi.src) >> 16; + height = drm_rect_height(&plane_state->uapi.src) >> 16; + + /* UV plane does 1/2 pixel sub-sampling */ + if (color_plane == 1) { + width /= 2; + height /= 2; + } + + return width * height * fb->format->cpp[color_plane]; +} + int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, struct intel_plane *plane, bool *need_cdclk_calc) @@ -314,6 +365,8 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, crtc_state->c8_planes &= ~BIT(plane->id); crtc_state->data_rate[plane->id] = 0; crtc_state->data_rate_y[plane->id] = 0; + crtc_state->rel_data_rate[plane->id] = 0; + crtc_state->rel_data_rate_y[plane->id] = 0; crtc_state->min_cdclk[plane->id] = 0; plane_state->uapi.visible = false; @@ -545,9 +598,20 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ intel_plane_data_rate(new_crtc_state, new_plane_state, 0); new_crtc_state->data_rate[plane->id] = intel_plane_data_rate(new_crtc_state, new_plane_state, 1); + + new_crtc_state->rel_data_rate_y[plane->id] = + intel_plane_relative_data_rate(new_crtc_state, + new_plane_state, 0); + new_crtc_state->rel_data_rate[plane->id] = + intel_plane_relative_data_rate(new_crtc_state, + new_plane_state, 1); } else if (new_plane_state->uapi.visible) { new_crtc_state->data_rate[plane->id] = intel_plane_data_rate(new_crtc_state, new_plane_state, 0); + + new_crtc_state->rel_data_rate[plane->id] = + intel_plane_relative_data_rate(new_crtc_state, + new_plane_state, 0); } return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state, |