OSDN Git Service

drm/i915/skl+: refactor WM calculation for NV12
authorMahesh Kumar <mahesh1.kumar@intel.com>
Mon, 9 Apr 2018 03:41:01 +0000 (09:11 +0530)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Mon, 9 Apr 2018 11:36:42 +0000 (13:36 +0200)
Current code calculates DDB for planar formats in such a way that we
store DDB of plane-0 in plane 1 & vice-versa.
In order to make this clean this patch refactors WM/DDB calculation for
NV12 planar formats.

v2: Addressed review comments by Maarten

v3: Rebased and addressed review comments by Maarten

v4: Fixed a compilation issue of string replacement is_nv12 to
is_planar

v5: Added reviewed by from Juha-Pekka Heikkila

v6: Rebased the series

Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com>
Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1523245273-30264-3-git-send-email-vidya.srinivas@intel.com
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index c1b89e9..28fd200 100644 (file)
@@ -1182,8 +1182,9 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
 }
 
 struct skl_ddb_allocation {
-       struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */
-       struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
+       /* packed/y */
+       struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
+       struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
 };
 
 struct skl_ddb_values {
index d9a44cc..626a46c 100644 (file)
@@ -603,6 +603,7 @@ struct intel_pipe_wm {
 struct skl_plane_wm {
        struct skl_wm_level wm[8];
        struct skl_wm_level trans_wm;
+       bool is_planar;
 };
 
 struct skl_pipe_wm {
index b7f6d8b..fda22b1 100644 (file)
@@ -4009,9 +4009,9 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 static unsigned int
 skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
                             const struct drm_plane_state *pstate,
-                            int y)
+                            const int plane)
 {
-       struct intel_plane *plane = to_intel_plane(pstate->plane);
+       struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
        struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
        uint32_t data_rate;
        uint32_t width = 0, height = 0;
@@ -4025,9 +4025,9 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
        fb = pstate->fb;
        format = fb->format->format;
 
-       if (plane->id == PLANE_CURSOR)
+       if (intel_plane->id == PLANE_CURSOR)
                return 0;
-       if (y && format != DRM_FORMAT_NV12)
+       if (plane == 1 && format != DRM_FORMAT_NV12)
                return 0;
 
        /*
@@ -4038,19 +4038,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
        width = drm_rect_width(&intel_pstate->base.src) >> 16;
        height = drm_rect_height(&intel_pstate->base.src) >> 16;
 
-       /* for planar format */
-       if (format == DRM_FORMAT_NV12) {
-               if (y)  /* y-plane data rate */
-                       data_rate = width * height *
-                               fb->format->cpp[0];
-               else    /* uv-plane data rate */
-                       data_rate = (width / 2) * (height / 2) *
-                               fb->format->cpp[1];
-       } else {
-               /* for packed formats */
-               data_rate = width * height * fb->format->cpp[0];
+       /* UV plane does 1/2 pixel sub-sampling */
+       if (plane == 1 && format == DRM_FORMAT_NV12) {
+               width /= 2;
+               height /= 2;
        }
 
+       data_rate = width * height * fb->format->cpp[plane];
+
        down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
 
        return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
@@ -4063,8 +4058,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
  */
 static unsigned int
 skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
-                                unsigned *plane_data_rate,
-                                unsigned *plane_y_data_rate)
+                                unsigned int *plane_data_rate,
+                                unsigned int *uv_plane_data_rate)
 {
        struct drm_crtc_state *cstate = &intel_cstate->base;
        struct drm_atomic_state *state = cstate->state;
@@ -4080,17 +4075,17 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
                enum plane_id plane_id = to_intel_plane(plane)->id;
                unsigned int rate;
 
-               /* packed/uv */
+               /* packed/y */
                rate = skl_plane_relative_data_rate(intel_cstate,
                                                    pstate, 0);
                plane_data_rate[plane_id] = rate;
 
                total_data_rate += rate;
 
-               /* y-plane */
+               /* uv-plane */
                rate = skl_plane_relative_data_rate(intel_cstate,
                                                    pstate, 1);
-               plane_y_data_rate[plane_id] = rate;
+               uv_plane_data_rate[plane_id] = rate;
 
                total_data_rate += rate;
        }
@@ -4099,8 +4094,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
 }
 
 static uint16_t
-skl_ddb_min_alloc(const struct drm_plane_state *pstate,
-                 const int y)
+skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane)
 {
        struct drm_framebuffer *fb = pstate->fb;
        struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
@@ -4111,8 +4105,8 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
        if (WARN_ON(!fb))
                return 0;
 
-       /* For packed formats, no y-plane, return 0 */
-       if (y && fb->format->format != DRM_FORMAT_NV12)
+       /* For packed formats, and uv-plane, return 0 */
+       if (plane == 1 && fb->format->format != DRM_FORMAT_NV12)
                return 0;
 
        /* For Non Y-tile return 8-blocks */
@@ -4131,15 +4125,12 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
        src_h = drm_rect_height(&intel_pstate->base.src) >> 16;
 
        /* Halve UV plane width and height for NV12 */
-       if (fb->format->format == DRM_FORMAT_NV12 && !y) {
+       if (plane == 1) {
                src_w /= 2;
                src_h /= 2;
        }
 
-       if (fb->format->format == DRM_FORMAT_NV12 && !y)
-               plane_bpp = fb->format->cpp[1];
-       else
-               plane_bpp = fb->format->cpp[0];
+       plane_bpp = fb->format->cpp[plane];
 
        if (drm_rotation_90_or_270(pstate->rotation)) {
                switch (plane_bpp) {
@@ -4167,7 +4158,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static void
 skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
-                uint16_t *minimum, uint16_t *y_minimum)
+                uint16_t *minimum, uint16_t *uv_minimum)
 {
        const struct drm_plane_state *pstate;
        struct drm_plane *plane;
@@ -4182,7 +4173,7 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
                        continue;
 
                minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
-               y_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
+               uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
        }
 
        minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
@@ -4200,17 +4191,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
        struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
        uint16_t alloc_size, start;
        uint16_t minimum[I915_MAX_PLANES] = {};
-       uint16_t y_minimum[I915_MAX_PLANES] = {};
+       uint16_t uv_minimum[I915_MAX_PLANES] = {};
        unsigned int total_data_rate;
        enum plane_id plane_id;
        int num_active;
-       unsigned plane_data_rate[I915_MAX_PLANES] = {};
-       unsigned plane_y_data_rate[I915_MAX_PLANES] = {};
+       unsigned int plane_data_rate[I915_MAX_PLANES] = {};
+       unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
        uint16_t total_min_blocks = 0;
 
        /* Clear the partitioning for disabled planes. */
        memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
-       memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
+       memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
 
        if (WARN_ON(!state))
                return 0;
@@ -4225,7 +4216,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
        if (alloc_size == 0)
                return 0;
 
-       skl_ddb_calc_min(cstate, num_active, minimum, y_minimum);
+       skl_ddb_calc_min(cstate, num_active, minimum, uv_minimum);
 
        /*
         * 1. Allocate the mininum required blocks for each active plane
@@ -4235,7 +4226,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
        for_each_plane_id_on_crtc(intel_crtc, plane_id) {
                total_min_blocks += minimum[plane_id];
-               total_min_blocks += y_minimum[plane_id];
+               total_min_blocks += uv_minimum[plane_id];
        }
 
        if (total_min_blocks > alloc_size) {
@@ -4257,14 +4248,14 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
         */
        total_data_rate = skl_get_total_relative_data_rate(cstate,
                                                           plane_data_rate,
-                                                          plane_y_data_rate);
+                                                          uv_plane_data_rate);
        if (total_data_rate == 0)
                return 0;
 
        start = alloc->start;
        for_each_plane_id_on_crtc(intel_crtc, plane_id) {
-               unsigned int data_rate, y_data_rate;
-               uint16_t plane_blocks, y_plane_blocks = 0;
+               unsigned int data_rate, uv_data_rate;
+               uint16_t plane_blocks, uv_plane_blocks;
 
                if (plane_id == PLANE_CURSOR)
                        continue;
@@ -4288,21 +4279,20 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
                start += plane_blocks;
 
-               /*
-                * allocation for y_plane part of planar format:
-                */
-               y_data_rate = plane_y_data_rate[plane_id];
+               /* Allocate DDB for UV plane for planar format/NV12 */
+               uv_data_rate = uv_plane_data_rate[plane_id];
 
-               y_plane_blocks = y_minimum[plane_id];
-               y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
-                                       total_data_rate);
+               uv_plane_blocks = uv_minimum[plane_id];
+               uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
+                                          total_data_rate);
 
-               if (y_data_rate) {
-                       ddb->y_plane[pipe][plane_id].start = start;
-                       ddb->y_plane[pipe][plane_id].end = start + y_plane_blocks;
+               if (uv_data_rate) {
+                       ddb->uv_plane[pipe][plane_id].start = start;
+                       ddb->uv_plane[pipe][plane_id].end =
+                               start + uv_plane_blocks;
                }
 
-               start += y_plane_blocks;
+               start += uv_plane_blocks;
        }
 
        return 0;
@@ -4430,8 +4420,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
                wp->width = drm_rect_width(&intel_pstate->base.src) >> 16;
        }
 
-       wp->cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] :
-                                                           fb->format->cpp[0];
+       wp->cpp = fb->format->cpp[0];
        wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate,
                                                             intel_pstate);
 
@@ -4660,6 +4649,9 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
                        return ret;
        }
 
+       if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
+               wm->is_planar = true;
+
        return 0;
 }
 
@@ -4833,10 +4825,21 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 
        skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
                            &ddb->plane[pipe][plane_id]);
-       if (INTEL_GEN(dev_priv) < 11)
+       if (INTEL_GEN(dev_priv) >= 11)
+               return skl_ddb_entry_write(dev_priv,
+                                          PLANE_BUF_CFG(pipe, plane_id),
+                                          &ddb->plane[pipe][plane_id]);
+       if (wm->is_planar) {
+               skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
+                                   &ddb->uv_plane[pipe][plane_id]);
                skl_ddb_entry_write(dev_priv,
                                    PLANE_NV12_BUF_CFG(pipe, plane_id),
-                                   &ddb->y_plane[pipe][plane_id]);
+                                   &ddb->plane[pipe][plane_id]);
+       } else {
+               skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
+                                   &ddb->plane[pipe][plane_id]);
+               I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
+       }
 }
 
 static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
@@ -4951,8 +4954,8 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
 
                if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
                                        &new_ddb->plane[pipe][plane_id]) &&
-                   skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][plane_id],
-                                       &new_ddb->y_plane[pipe][plane_id]))
+                   skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
+                                       &new_ddb->uv_plane[pipe][plane_id]))
                        continue;
 
                plane_state = drm_atomic_get_plane_state(state, plane);
@@ -5046,8 +5049,8 @@ skl_copy_ddb_for_pipe(struct skl_ddb_values *dst,
                      struct skl_ddb_values *src,
                      enum pipe pipe)
 {
-       memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe],
-              sizeof(dst->ddb.y_plane[pipe]));
+       memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe],
+              sizeof(dst->ddb.uv_plane[pipe]));
        memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
               sizeof(dst->ddb.plane[pipe]));
 }