|
|
0903551 |
From 0206aec944641c69815562407b73b6f9df22f041 Mon Sep 17 00:00:00 2001
|
|
|
0903551 |
From: Fedora Kernel Team <kernel-team@fedoraproject.org>
|
|
|
0903551 |
Date: Mon, 20 Jun 2016 11:13:09 +0200
|
|
|
0903551 |
Subject: [PATCH 03/17] drm/i915/gen9: Cache plane data rates in CRTC state
|
|
|
0903551 |
|
|
|
0903551 |
Upstream: since drm-intel-next-2016-05-22
|
|
|
0903551 |
commit a1de91e5f3039dfc32ac2b77ffb280a68646cbc7
|
|
|
0903551 |
|
|
|
0903551 |
Author: Matt Roper <matthew.d.roper@intel.com>
|
|
|
0903551 |
AuthorDate: Thu May 12 07:05:57 2016 -0700
|
|
|
0903551 |
Commit: Matt Roper <matthew.d.roper@intel.com>
|
|
|
0903551 |
CommitDate: Fri May 13 07:32:35 2016 -0700
|
|
|
0903551 |
|
|
|
0903551 |
drm/i915/gen9: Cache plane data rates in CRTC state
|
|
|
0903551 |
|
|
|
0903551 |
This will be important when we start calculating CRTC data rates for
|
|
|
0903551 |
in-flight CRTC states since it will allow us to calculate the total data
|
|
|
0903551 |
rate without needing to grab the plane state for any planes that aren't
|
|
|
0903551 |
updated by the transaction.
|
|
|
0903551 |
|
|
|
0903551 |
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
|
|
|
0903551 |
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
|
|
|
0903551 |
Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-4-git-send-email-matthew.d.roper@intel.com
|
|
|
0903551 |
---
|
|
|
0903551 |
drivers/gpu/drm/i915/intel_drv.h | 4 ++
|
|
|
0903551 |
drivers/gpu/drm/i915/intel_pm.c | 92 ++++++++++++++++++++++++++--------------
|
|
|
0903551 |
2 files changed, 63 insertions(+), 33 deletions(-)
|
|
|
0903551 |
|
|
|
0903551 |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
|
|
|
0903551 |
index 7d19baf..7c00ab6 100644
|
|
|
0903551 |
--- a/drivers/gpu/drm/i915/intel_drv.h
|
|
|
0903551 |
+++ b/drivers/gpu/drm/i915/intel_drv.h
|
|
|
0903551 |
@@ -385,6 +385,10 @@ struct intel_crtc_wm_state {
|
|
|
0903551 |
struct {
|
|
|
0903551 |
/* gen9+ only needs 1-step wm programming */
|
|
|
0903551 |
struct skl_pipe_wm optimal;
|
|
|
0903551 |
+
|
|
|
0903551 |
+ /* cached plane data rate */
|
|
|
0903551 |
+ unsigned plane_data_rate[I915_MAX_PLANES];
|
|
|
0903551 |
+ unsigned plane_y_data_rate[I915_MAX_PLANES];
|
|
|
0903551 |
} skl;
|
|
|
0903551 |
};
|
|
|
0903551 |
|
|
|
0903551 |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
|
|
0903551 |
index 8f081b2..854f0a4 100644
|
|
|
0903551 |
--- a/drivers/gpu/drm/i915/intel_pm.c
|
|
|
0903551 |
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
|
|
0903551 |
@@ -2879,6 +2879,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
|
|
|
0903551 |
struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
|
|
|
0903551 |
struct drm_framebuffer *fb = pstate->fb;
|
|
|
0903551 |
uint32_t width = 0, height = 0;
|
|
|
0903551 |
+ unsigned format = fb ? fb->pixel_format : DRM_FORMAT_XRGB8888;
|
|
|
0903551 |
+
|
|
|
0903551 |
+ if (!intel_pstate->visible)
|
|
|
0903551 |
+ return 0;
|
|
|
0903551 |
+ if (pstate->plane->type == DRM_PLANE_TYPE_CURSOR)
|
|
|
0903551 |
+ return 0;
|
|
|
0903551 |
+ if (y && format != DRM_FORMAT_NV12)
|
|
|
0903551 |
+ return 0;
|
|
|
0903551 |
|
|
|
0903551 |
width = drm_rect_width(&intel_pstate->src) >> 16;
|
|
|
0903551 |
height = drm_rect_height(&intel_pstate->src) >> 16;
|
|
|
0903551 |
@@ -2887,17 +2895,17 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
|
|
|
0903551 |
swap(width, height);
|
|
|
0903551 |
|
|
|
0903551 |
/* for planar format */
|
|
|
0903551 |
- if (fb->pixel_format == DRM_FORMAT_NV12) {
|
|
|
0903551 |
+ if (format == DRM_FORMAT_NV12) {
|
|
|
0903551 |
if (y) /* y-plane data rate */
|
|
|
0903551 |
return width * height *
|
|
|
0903551 |
- drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
0903551 |
+ drm_format_plane_cpp(format, 0);
|
|
|
0903551 |
else /* uv-plane data rate */
|
|
|
0903551 |
return (width / 2) * (height / 2) *
|
|
|
0903551 |
- drm_format_plane_cpp(fb->pixel_format, 1);
|
|
|
0903551 |
+ drm_format_plane_cpp(format, 1);
|
|
|
0903551 |
}
|
|
|
0903551 |
|
|
|
0903551 |
/* for packed formats */
|
|
|
0903551 |
- return width * height * drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
0903551 |
+ return width * height * drm_format_plane_cpp(format, 0);
|
|
|
0903551 |
}
|
|
|
0903551 |
|
|
|
0903551 |
/*
|
|
|
0903551 |
@@ -2906,32 +2914,34 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
|
|
|
0903551 |
* 3 * 4096 * 8192 * 4 < 2^32
|
|
|
0903551 |
*/
|
|
|
0903551 |
static unsigned int
|
|
|
0903551 |
-skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
|
|
|
0903551 |
+skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
|
|
|
0903551 |
{
|
|
|
0903551 |
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
|
|
|
0903551 |
struct drm_device *dev = intel_crtc->base.dev;
|
|
|
0903551 |
const struct intel_plane *intel_plane;
|
|
|
0903551 |
- unsigned int total_data_rate = 0;
|
|
|
0903551 |
+ unsigned int rate, total_data_rate = 0;
|
|
|
0903551 |
|
|
|
0903551 |
+ /* Calculate and cache data rate for each plane */
|
|
|
0903551 |
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
0903551 |
const struct drm_plane_state *pstate = intel_plane->base.state;
|
|
|
0903551 |
+ int id = skl_wm_plane_id(intel_plane);
|
|
|
0903551 |
|
|
|
0903551 |
- if (pstate->fb == NULL)
|
|
|
0903551 |
- continue;
|
|
|
0903551 |
+ /* packed/uv */
|
|
|
0903551 |
+ rate = skl_plane_relative_data_rate(cstate, pstate, 0);
|
|
|
0903551 |
+ cstate->wm.skl.plane_data_rate[id] = rate;
|
|
|
0903551 |
|
|
|
0903551 |
- if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
|
|
|
0903551 |
- continue;
|
|
|
0903551 |
+ /* y-plane */
|
|
|
0903551 |
+ rate = skl_plane_relative_data_rate(cstate, pstate, 1);
|
|
|
0903551 |
+ cstate->wm.skl.plane_y_data_rate[id] = rate;
|
|
|
0903551 |
+ }
|
|
|
0903551 |
|
|
|
0903551 |
- /* packed/uv */
|
|
|
0903551 |
- total_data_rate += skl_plane_relative_data_rate(cstate,
|
|
|
0903551 |
- pstate,
|
|
|
0903551 |
- 0);
|
|
|
0903551 |
+ /* Calculate CRTC's total data rate from cached values */
|
|
|
0903551 |
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
0903551 |
+ int id = skl_wm_plane_id(intel_plane);
|
|
|
0903551 |
|
|
|
0903551 |
- if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
|
|
|
0903551 |
- /* y-plane */
|
|
|
0903551 |
- total_data_rate += skl_plane_relative_data_rate(cstate,
|
|
|
0903551 |
- pstate,
|
|
|
0903551 |
- 1);
|
|
|
0903551 |
+ /* packed/uv */
|
|
|
0903551 |
+ total_data_rate += cstate->wm.skl.plane_data_rate[id];
|
|
|
0903551 |
+ total_data_rate += cstate->wm.skl.plane_y_data_rate[id];
|
|
|
0903551 |
}
|
|
|
0903551 |
|
|
|
0903551 |
return total_data_rate;
|
|
|
0903551 |
@@ -2995,6 +3005,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
|
|
|
0903551 |
* FIXME: we may not allocate every single block here.
|
|
|
0903551 |
*/
|
|
|
0903551 |
total_data_rate = skl_get_total_relative_data_rate(cstate);
|
|
|
0903551 |
+ if (total_data_rate == 0)
|
|
|
0903551 |
+ return;
|
|
|
0903551 |
|
|
|
0903551 |
start = alloc->start;
|
|
|
0903551 |
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
0903551 |
@@ -3009,7 +3021,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
|
|
|
0903551 |
if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
|
|
0903551 |
continue;
|
|
|
0903551 |
|
|
|
0903551 |
- data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);
|
|
|
0903551 |
+ data_rate = cstate->wm.skl.plane_data_rate[id];
|
|
|
0903551 |
|
|
|
0903551 |
/*
|
|
|
0903551 |
* allocation for (packed formats) or (uv-plane part of planar format):
|
|
|
0903551 |
@@ -3028,20 +3040,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
|
|
|
0903551 |
/*
|
|
|
0903551 |
* allocation for y_plane part of planar format:
|
|
|
0903551 |
*/
|
|
|
0903551 |
- if (pstate->fb->pixel_format == DRM_FORMAT_NV12) {
|
|
|
0903551 |
- y_data_rate = skl_plane_relative_data_rate(cstate,
|
|
|
0903551 |
- pstate,
|
|
|
0903551 |
- 1);
|
|
|
0903551 |
- y_plane_blocks = y_minimum[id];
|
|
|
0903551 |
- y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
|
|
|
0903551 |
- total_data_rate);
|
|
|
0903551 |
-
|
|
|
0903551 |
- ddb->y_plane[pipe][id].start = start;
|
|
|
0903551 |
- ddb->y_plane[pipe][id].end = start + y_plane_blocks;
|
|
|
0903551 |
-
|
|
|
0903551 |
- start += y_plane_blocks;
|
|
|
0903551 |
- }
|
|
|
0903551 |
+ y_data_rate = cstate->wm.skl.plane_y_data_rate[id];
|
|
|
0903551 |
+
|
|
|
0903551 |
+ y_plane_blocks = y_minimum[id];
|
|
|
0903551 |
+ y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
|
|
|
0903551 |
+ total_data_rate);
|
|
|
0903551 |
|
|
|
0903551 |
+ ddb->y_plane[pipe][id].start = start;
|
|
|
0903551 |
+ ddb->y_plane[pipe][id].end = start + y_plane_blocks;
|
|
|
0903551 |
+
|
|
|
0903551 |
+ start += y_plane_blocks;
|
|
|
0903551 |
}
|
|
|
0903551 |
|
|
|
0903551 |
}
|
|
|
0903551 |
@@ -3820,10 +3828,28 @@ void skl_wm_get_hw_state(struct drm_device *dev)
|
|
|
0903551 |
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
0903551 |
struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
|
|
|
0903551 |
struct drm_crtc *crtc;
|
|
|
0903551 |
+ struct intel_crtc *intel_crtc;
|
|
|
0903551 |
|
|
|
0903551 |
skl_ddb_get_hw_state(dev_priv, ddb);
|
|
|
0903551 |
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
|
|
0903551 |
skl_pipe_wm_get_hw_state(crtc);
|
|
|
0903551 |
+
|
|
|
0903551 |
+ /* Calculate plane data rates */
|
|
|
0903551 |
+ for_each_intel_crtc(dev, intel_crtc) {
|
|
|
0903551 |
+ struct intel_crtc_state *cstate = intel_crtc->config;
|
|
|
0903551 |
+ struct intel_plane *intel_plane;
|
|
|
0903551 |
+
|
|
|
0903551 |
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
0903551 |
+ const struct drm_plane_state *pstate =
|
|
|
0903551 |
+ intel_plane->base.state;
|
|
|
0903551 |
+ int id = skl_wm_plane_id(intel_plane);
|
|
|
0903551 |
+
|
|
|
0903551 |
+ cstate->wm.skl.plane_data_rate[id] =
|
|
|
0903551 |
+ skl_plane_relative_data_rate(cstate, pstate, 0);
|
|
|
0903551 |
+ cstate->wm.skl.plane_y_data_rate[id] =
|
|
|
0903551 |
+ skl_plane_relative_data_rate(cstate, pstate, 1);
|
|
|
0903551 |
+ }
|
|
|
0903551 |
+ }
|
|
|
0903551 |
}
|
|
|
0903551 |
|
|
|
0903551 |
static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|
|
0903551 |
--
|
|
|
0903551 |
2.7.4
|
|
|
0903551 |
|