From f07d43d2da1cbf4f335359a5fe39f773133c2be4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 2 Mar 2017 19:14:52 +0200 Subject: [PATCH] drm/i915: Track plane fifo sizes under intel_crtc MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Track the plane fifo sizes under intel_crtc instead of under each intel_plane. Avoids looping over the planes in a bunch of places, and later we'll move this tracking into the crtc state properly. v2: Nuke intel_plane_wm_parameters (Maarten) Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/20170302171508.1666-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_drv.h | 32 ++------- drivers/gpu/drm/i915/intel_pm.c | 115 +++++++++++++------------------ 2 files changed, 54 insertions(+), 93 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 708311837faf..0ffe527e1099 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -709,6 +709,10 @@ struct vlv_wm_state { bool cxsr; }; +struct vlv_fifo_state { + uint16_t plane[I915_MAX_PLANES]; +}; + struct intel_crtc { struct drm_crtc base; enum pipe pipe; @@ -758,6 +762,8 @@ struct intel_crtc { /* allow CxSR on this pipe */ bool cxsr_allowed; + + struct vlv_fifo_state fifo_state; } wm; int scanline_offset; @@ -775,25 +781,6 @@ struct intel_crtc { struct vlv_wm_state wm_state; }; -struct intel_plane_wm_parameters { - uint32_t horiz_pixels; - uint32_t vert_pixels; - /* - * For packed pixel formats: - * bytes_per_pixel - holds bytes per pixel - * For planar pixel formats: - * bytes_per_pixel - holds bytes per pixel for uv-plane - * y_bytes_per_pixel - holds bytes per pixel for y-plane - */ - uint8_t bytes_per_pixel; - uint8_t y_bytes_per_pixel; - bool enabled; - bool scaled; - u64 tiling; - unsigned int rotation; - uint16_t fifo_size; -}; - struct intel_plane { struct drm_plane base; u8 plane; @@ -803,13 +790,6 @@ struct intel_plane { int max_downscale; uint32_t frontbuffer_bit; - /* Since we need to change the watermarks before/after - * enabling/disabling the planes, we need to store the parameters here - * as the other pieces of the struct may not reflect the values we want - * for the watermark calculations. Currently only Haswell uses this. - */ - struct intel_plane_wm_parameters wm; - /* * NOTE: Do not place new plane state fields here (e.g., when adding * new plane properties). New runtime state should now be placed in diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 50e672f84276..7047b35d0e1d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -415,15 +415,14 @@ static const int pessimal_latency_ns = 5000; #define VLV_FIFO_START(dsparb, dsparb2, lo_shift, hi_shift) \ ((((dsparb) >> (lo_shift)) & 0xff) | ((((dsparb2) >> (hi_shift)) & 0x1) << 8)) -static int vlv_get_fifo_size(struct intel_plane *plane) +static void vlv_get_fifo_size(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - int sprite0_start, sprite1_start, size; - - if (plane->id == PLANE_CURSOR) - return 63; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct vlv_fifo_state *fifo_state = &crtc->wm.fifo_state; + enum pipe pipe = crtc->pipe; + int sprite0_start, sprite1_start; - switch (plane->pipe) { + switch (pipe) { uint32_t dsparb, dsparb2, dsparb3; case PIPE_A: dsparb = I915_READ(DSPARB); @@ -444,26 +443,21 @@ static int vlv_get_fifo_size(struct intel_plane *plane) sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20); break; default: - return 0; - } - - switch (plane->id) { - case PLANE_PRIMARY: - size = sprite0_start; - break; - case PLANE_SPRITE0: - size = sprite1_start - sprite0_start; - break; - case PLANE_SPRITE1: - size = 512 - 1 - sprite1_start; - break; - default: - return 0; + MISSING_CASE(pipe); + return; } - DRM_DEBUG_KMS("%s FIFO size: %d\n", plane->base.name, size); + fifo_state->plane[PLANE_PRIMARY] = sprite0_start; + fifo_state->plane[PLANE_SPRITE0] = sprite1_start - sprite0_start; + fifo_state->plane[PLANE_SPRITE1] = 511 - sprite1_start; + fifo_state->plane[PLANE_CURSOR] = 63; - return size; + DRM_DEBUG_KMS("Pipe %c FIFO size: %d/%d/%d/%d\n", + pipe_name(pipe), + fifo_state->plane[PLANE_PRIMARY], + fifo_state->plane[PLANE_SPRITE0], + fifo_state->plane[PLANE_SPRITE1], + fifo_state->plane[PLANE_CURSOR]); } static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, int plane) @@ -1041,8 +1035,9 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, static void vlv_compute_fifo(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; struct vlv_wm_state *wm_state = &crtc->wm_state; + struct vlv_fifo_state *fifo_state = &crtc->wm.fifo_state; + struct drm_device *dev = crtc->base.dev; struct intel_plane *plane; unsigned int total_rate = 0; const int fifo_size = 512 - 1; @@ -1052,7 +1047,7 @@ static void vlv_compute_fifo(struct intel_crtc *crtc) struct intel_plane_state *state = to_intel_plane_state(plane->base.state); - if (plane->base.type == DRM_PLANE_TYPE_CURSOR) + if (plane->id == PLANE_CURSOR) continue; if (state->base.visible) { @@ -1066,19 +1061,19 @@ static void vlv_compute_fifo(struct intel_crtc *crtc) to_intel_plane_state(plane->base.state); unsigned int rate; - if (plane->base.type == DRM_PLANE_TYPE_CURSOR) { - plane->wm.fifo_size = 63; + if (plane->id == PLANE_CURSOR) { + fifo_state->plane[plane->id] = 63; continue; } if (!state->base.visible) { - plane->wm.fifo_size = 0; + fifo_state->plane[plane->id] = 0; continue; } rate = state->base.fb->format->cpp[0]; - plane->wm.fifo_size = fifo_size * rate / total_rate; - fifo_left -= plane->wm.fifo_size; + fifo_state->plane[plane->id] = fifo_size * rate / total_rate; + fifo_left -= fifo_state->plane[plane->id]; } fifo_extra = DIV_ROUND_UP(fifo_left, wm_state->num_active_planes ?: 1); @@ -1090,16 +1085,16 @@ static void vlv_compute_fifo(struct intel_crtc *crtc) if (fifo_left == 0) break; - if (plane->base.type == DRM_PLANE_TYPE_CURSOR) + if (plane->id == PLANE_CURSOR) continue; /* give it all to the first plane if none are active */ - if (plane->wm.fifo_size == 0 && + if (fifo_state->plane[plane->id] == 0 && wm_state->num_active_planes) continue; plane_extra = min(fifo_extra, fifo_left); - plane->wm.fifo_size += plane_extra; + fifo_state->plane[plane->id] += plane_extra; fifo_left -= plane_extra; } @@ -1121,9 +1116,10 @@ static void vlv_invert_wms(struct intel_crtc *crtc) for (level = 0; level < wm_state->num_levels; level++) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct vlv_fifo_state *fifo_state = &crtc->wm.fifo_state; const int sr_fifo_size = INTEL_INFO(dev_priv)->num_pipes * 512 - 1; - struct intel_plane *plane; + enum plane_id plane_id; wm_state->sr[level].plane = vlv_invert_wm_value(wm_state->sr[level].plane, @@ -1132,10 +1128,10 @@ static void vlv_invert_wms(struct intel_crtc *crtc) vlv_invert_wm_value(wm_state->sr[level].cursor, 63); - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { - wm_state->wm[level].plane[plane->id] = - vlv_invert_wm_value(wm_state->wm[level].plane[plane->id], - plane->wm.fifo_size); + for_each_plane_id_on_crtc(crtc, plane_id) { + wm_state->wm[level].plane[plane_id] = + vlv_invert_wm_value(wm_state->wm[level].plane[plane_id], + fifo_state->plane[plane_id]); } } } @@ -1144,6 +1140,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct vlv_wm_state *wm_state = &crtc->wm_state; + const struct vlv_fifo_state *fifo_state = &crtc->wm.fifo_state; struct intel_plane *plane; int level; @@ -1170,7 +1167,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc) /* normal watermarks */ for (level = 0; level < wm_state->num_levels; level++) { int wm = vlv_compute_wm_level(crtc->config, state, level); - int max_wm = plane->wm.fifo_size; + int max_wm = fifo_state->plane[plane->id]; /* hack */ if (WARN_ON(level == 0 && wm > max_wm)) @@ -1214,32 +1211,16 @@ static void vlv_compute_wm(struct intel_crtc *crtc) static void vlv_pipe_set_fifo_size(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_plane *plane; - int sprite0_start = 0, sprite1_start = 0, fifo_size = 0; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct vlv_fifo_state *fifo_state = &crtc->wm.fifo_state; + int sprite0_start, sprite1_start, fifo_size; - for_each_intel_plane_on_crtc(dev, crtc, plane) { - switch (plane->id) { - case PLANE_PRIMARY: - sprite0_start = plane->wm.fifo_size; - break; - case PLANE_SPRITE0: - sprite1_start = sprite0_start + plane->wm.fifo_size; - break; - case PLANE_SPRITE1: - fifo_size = sprite1_start + plane->wm.fifo_size; - break; - case PLANE_CURSOR: - WARN_ON(plane->wm.fifo_size != 63); - break; - default: - MISSING_CASE(plane->id); - break; - } - } + sprite0_start = fifo_state->plane[PLANE_PRIMARY]; + sprite1_start = fifo_state->plane[PLANE_SPRITE0] + sprite0_start; + fifo_size = fifo_state->plane[PLANE_SPRITE1] + sprite1_start; - WARN_ON(fifo_size != 512 - 1); + WARN_ON(fifo_state->plane[PLANE_CURSOR] != 63); + WARN_ON(fifo_size != 511); DRM_DEBUG_KMS("Pipe %c FIFO split %d / %d / %d\n", pipe_name(crtc->pipe), sprite0_start, @@ -4531,14 +4512,14 @@ void vlv_wm_get_hw_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); struct vlv_wm_values *wm = &dev_priv->wm.vlv; - struct intel_plane *plane; + struct intel_crtc *crtc; enum pipe pipe; u32 val; vlv_read_wm_values(dev_priv, wm); - for_each_intel_plane(dev, plane) - plane->wm.fifo_size = vlv_get_fifo_size(plane); + for_each_intel_crtc(dev, crtc) + vlv_get_fifo_size(crtc); wm->cxsr = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; wm->level = VLV_WM_LEVEL_PM2; -- 2.20.1