summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorMahesh Kumar <mahesh1.kumar@intel.com>2017-05-26 20:45:46 +0530
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-06-01 09:48:19 +0200
commit73b0ca8ec76d593d8ebb9d3a5e4021da852310e7 (patch)
tree0fe84553e98ca82c257254b67b1839786a592b25 /drivers/gpu/drm/i915/intel_pm.c
parentbb9d85f6e9de8fef5236c076530eab67a2f2431b (diff)
downloadop-kernel-dev-73b0ca8ec76d593d8ebb9d3a5e4021da852310e7.zip
op-kernel-dev-73b0ca8ec76d593d8ebb9d3a5e4021da852310e7.tar.gz
drm/i915/skl+: consider max supported plane pixel rate while scaling
A display resolution is only supported if it meets all the restrictions below for Maximum Pipe Pixel Rate. The display resolution must fit within the maximum pixel rate output from the pipe. Make sure that the display pipe is able to feed pixels at a rate required to support the desired resolution. For each enabled plane on the pipe { If plane scaling enabled { Horizontal down scale amount = Maximum[1, plane horizontal size / scaler horizontal window size] Vertical down scale amount = Maximum[1, plane vertical size / scaler vertical window size] Plane down scale amount = Horizontal down scale amount * Vertical down scale amount Plane Ratio = 1 / Plane down scale amount } Else { Plane Ratio = 1 } If plane source pixel format is 64 bits per pixel { Plane Ratio = Plane Ratio * 8/9 } } Pipe Ratio = Minimum Plane Ratio of all enabled planes on the pipe If pipe scaling is enabled { Horizontal down scale amount = Maximum[1, pipe horizontal source size / scaler horizontal window size] Vertical down scale amount = Maximum[1, pipe vertical source size / scaler vertical window size] Note: The progressive fetch - interlace display mode is equivalent to a 2.0 vertical down scale Pipe down scale amount = Horizontal down scale amount * Vertical down scale amount Pipe Ratio = Pipe Ratio / Pipe down scale amount } Pipe maximum pixel rate = CDCLK frequency * Pipe Ratio In this patch our calculation is based on pipe downscale amount (plane max downscale amount * pipe downscale amount) instead of Pipe Ratio. So, max supported crtc clock with given scaling = CDCLK / pipe downscale. Flip will fail if, current crtc clock > max supported crct clock with given scaling. Changes since V1: - separate out fixed_16_16 wrapper API definition Changes since V2: - Fix buggy crtc !active condition (Maarten) - use intel_wm_plane_visible wrapper as per Maarten's suggestion Changes since V3: - Change failure return from ERANGE to EINVAL Changes since V4: - Rebase based on previous patch changes Changes since V5: - return EINVAL instead of continue (Maarten) Changes since V6: - Improve commit message - Address review comment Changes since V7: - use !enable instead of !active - rename config variable for consistency (Maarten) Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170526151546.25025-4-mahesh1.kumar@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1f9fee3..f9c5f61 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3863,6 +3863,93 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
return mul_fixed16(downscale_w, downscale_h);
}
+static uint_fixed_16_16_t
+skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
+{
+ uint_fixed_16_16_t pipe_downscale = u32_to_fixed_16_16(1);
+
+ if (!crtc_state->base.enable)
+ return pipe_downscale;
+
+ if (crtc_state->pch_pfit.enabled) {
+ uint32_t src_w, src_h, dst_w, dst_h;
+ uint32_t pfit_size = crtc_state->pch_pfit.size;
+ uint_fixed_16_16_t fp_w_ratio, fp_h_ratio;
+ uint_fixed_16_16_t downscale_h, downscale_w;
+
+ src_w = crtc_state->pipe_src_w;
+ src_h = crtc_state->pipe_src_h;
+ dst_w = pfit_size >> 16;
+ dst_h = pfit_size & 0xffff;
+
+ if (!dst_w || !dst_h)
+ return pipe_downscale;
+
+ fp_w_ratio = fixed_16_16_div(src_w, dst_w);
+ fp_h_ratio = fixed_16_16_div(src_h, dst_h);
+ downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
+ downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
+
+ pipe_downscale = mul_fixed16(downscale_w, downscale_h);
+ }
+
+ return pipe_downscale;
+}
+
+int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *cstate)
+{
+ struct drm_crtc_state *crtc_state = &cstate->base;
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_plane *plane;
+ const struct drm_plane_state *pstate;
+ struct intel_plane_state *intel_pstate;
+ int crtc_clock, cdclk;
+ uint32_t pipe_max_pixel_rate;
+ uint_fixed_16_16_t pipe_downscale;
+ uint_fixed_16_16_t max_downscale = u32_to_fixed_16_16(1);
+
+ if (!cstate->base.enable)
+ return 0;
+
+ drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
+ uint_fixed_16_16_t plane_downscale;
+ uint_fixed_16_16_t fp_9_div_8 = fixed_16_16_div(9, 8);
+ int bpp;
+
+ if (!intel_wm_plane_visible(cstate,
+ to_intel_plane_state(pstate)))
+ continue;
+
+ if (WARN_ON(!pstate->fb))
+ return -EINVAL;
+
+ intel_pstate = to_intel_plane_state(pstate);
+ plane_downscale = skl_plane_downscale_amount(cstate,
+ intel_pstate);
+ bpp = pstate->fb->format->cpp[0] * 8;
+ if (bpp == 64)
+ plane_downscale = mul_fixed16(plane_downscale,
+ fp_9_div_8);
+
+ max_downscale = max_fixed_16_16(plane_downscale, max_downscale);
+ }
+ pipe_downscale = skl_pipe_downscale_amount(cstate);
+
+ pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
+
+ crtc_clock = crtc_state->adjusted_mode.crtc_clock;
+ cdclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
+ pipe_max_pixel_rate = div_round_up_u32_fixed16(cdclk, pipe_downscale);
+
+ if (pipe_max_pixel_rate < crtc_clock) {
+ DRM_ERROR("Max supported pixel clock with scaling exceeded\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static unsigned int
skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
const struct drm_plane_state *pstate,
OpenPOWER on IntegriCloud