[Intel-gfx] [PATCH 4/7] drm/i915/skl+: calculate plane pixel rate.
Shobhit Kumar
shobhit.kumar at intel.com
Thu Jan 14 04:02:45 PST 2016
From: "Kumar, Mahesh" <mahesh1.kumar at intel.com>
Don't use pipe pixel rate for plane pixel rate.
Calculate plane pixel according to formula
adjusted plane_pixel_rate = adjusted pipe_pixel_rate * downscale ammount
downscale amount = max[1, src_h/dst_h] * max[1, src_w/dst_w]
if 90/270 rotation use rotated width & height
Signed-off-by: Kumar, Mahesh <mahesh1.kumar at intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 95 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 059b46e..49f237e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -661,6 +661,8 @@ struct intel_plane_wm_parameters {
u64 tiling;
unsigned int rotation;
uint16_t fifo_size;
+ /* Stores the adjusted plane pixel rate for WM calculation */
+ uint32_t plane_pixel_rate;
};
struct intel_plane {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 64b39ec..ffcc56a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2841,6 +2841,54 @@ skl_wm_plane_id(const struct intel_plane *plane)
}
}
+/*
+ * This function takes drm_plane_state as input
+ * and decides the downscale amount according to the formula
+ *
+ * downscale amount = Max[1, Horizontal source size / Horizontal dest size]
+ *
+ * Return value is multiplied by 1000 to retain fractional part
+ * Caller should take care of dividing & Rounding off the value
+ */
+static uint32_t
+skl_plane_downscale_amount(const struct intel_plane *intel_plane)
+{
+ struct drm_plane_state *pstate = intel_plane->base.state;
+ struct intel_crtc *crtc = to_intel_crtc(pstate->crtc);
+ struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+ uint32_t downscale_h, downscale_w;
+ uint32_t src_w, src_h, dst_w, dst_h, tmp;
+
+ if (drm_rect_width(&intel_pstate->src)) {
+ src_w = drm_rect_width(&intel_pstate->src) >> 16;
+ src_h = drm_rect_height(&intel_pstate->src) >> 16;
+ } else {
+ src_w = crtc->config->pipe_src_w;
+ src_h = crtc->config->pipe_src_h;
+ }
+
+ dst_w = drm_rect_width(&intel_pstate->dst);
+ dst_h = drm_rect_height(&intel_pstate->dst);
+
+ if (intel_rotation_90_or_270(pstate->rotation))
+ swap(dst_w, dst_h);
+
+ /* If destination height & wight are zero return amount as unity */
+ if (dst_w == 0 || dst_h == 0)
+ return 1000;
+
+ /* Multiply by 1000 for precision */
+ tmp = (1000 * src_h) / dst_h;
+ downscale_h = max_t(uint32_t, 1000, tmp);
+
+ tmp = (1000 * src_w) / dst_w;
+ downscale_w = max_t(uint32_t, 1000, tmp);
+
+ /* Reducing precision to 3 decimal places */
+ return DIV_ROUND_UP(downscale_h * downscale_w, 1000);
+}
+
+
static void
skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
const struct intel_crtc_state *cstate,
@@ -3265,10 +3313,10 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(fb->pixel_format, 1) :
drm_format_plane_cpp(fb->pixel_format, 0);
- method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
+ method1 = skl_wm_method1(intel_plane->wm.plane_pixel_rate,
bytes_per_pixel,
latency);
- method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
+ method2 = skl_wm_method2(intel_plane->wm.plane_pixel_rate,
cstate->base.adjusted_mode.crtc_htotal,
width,
bytes_per_pixel,
@@ -3709,6 +3757,46 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
}
}
+static uint32_t
+skl_plane_pixel_rate(struct intel_crtc_state *cstate, struct intel_plane *plane)
+{
+ uint32_t adjusted_pixel_rate;
+ uint32_t downscale_amount;
+
+ /*
+ * adjusted plane pixel rate = adjusted pipe pixel rate
+ * Plane pixel rate = adjusted plane pixel rate * plane down scale
+ * amount
+ */
+ adjusted_pixel_rate = skl_pipe_pixel_rate(cstate);
+ downscale_amount = skl_plane_downscale_amount(plane);
+
+ return DIV_ROUND_UP(adjusted_pixel_rate * downscale_amount,
+ 1000);
+}
+
+static void skl_set_plane_pixel_rate(struct drm_crtc *crtc)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct intel_plane *intel_plane = NULL;
+ struct drm_device *dev = crtc->dev;
+
+ if (!intel_crtc->active)
+ return;
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
+ struct drm_plane *plane = &intel_plane->base;
+ struct drm_framebuffer *fb = plane->state->fb;
+
+ if (fb == NULL)
+ continue;
+
+ intel_plane->wm.plane_pixel_rate = skl_plane_pixel_rate(cstate,
+ intel_plane);
+ }
+
+}
+
static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
{
watermarks->wm_linetime[pipe] = 0;
@@ -3744,6 +3832,9 @@ static void skl_update_wm(struct drm_crtc *crtc)
skl_clear_wm(results, intel_crtc->pipe);
+ /* Calculate plane pixel rate for each plane in advance */
+ skl_set_plane_pixel_rate(crtc);
+
if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
return;
--
2.4.3
More information about the Intel-gfx
mailing list