| From c525c512775142555ddd579122afdfd7e4316e6f Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> |
| Date: Wed, 4 Sep 2013 18:25:28 +0300 |
| Subject: drm/i915: Add explicit pipe src size to pipe config |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| Rather that mess about with hdisplay/vdisplay from requested_mode, add |
| explicit pipe src size information to pipe config. |
| |
| Now requested_mode is only really relevant for dvo/sdvo output timings. |
| For everything else either adjusted_mode or pipe src size should be |
| used. |
| |
| In many places where we end up using pipe source size, we should |
| actually use the primary plane size, but we don't currently store |
| that information explicitly. As long as we treat primaries as full |
| screen only, we can get away with this. Eventually when we move |
| primaries over to drm_plane, we need to fix it all up. |
| |
| v2: Add a comment to explain what pipe_src_{w,h} are |
| Add a note about primary planes to commit message |
| |
| Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 37327abdfbb4e2d7c9033f450de5e36e401d6efc) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++------ |
| drivers/gpu/drm/i915/intel_drv.h | 6 ++++ |
| drivers/gpu/drm/i915/intel_panel.c | 56 +++++++++++++++++------------------- |
| drivers/gpu/drm/i915/intel_pm.c | 33 ++++++++++----------- |
| drivers/gpu/drm/i915/intel_sprite.c | 4 +-- |
| 5 files changed, 67 insertions(+), 58 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
| index aa3b9c6f7a98..6a0242a143dc 100644 |
| --- a/drivers/gpu/drm/i915/intel_display.c |
| +++ b/drivers/gpu/drm/i915/intel_display.c |
| @@ -4692,7 +4692,6 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) |
| enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
| struct drm_display_mode *adjusted_mode = |
| &intel_crtc->config.adjusted_mode; |
| - struct drm_display_mode *mode = &intel_crtc->config.requested_mode; |
| uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end; |
| |
| /* We need to be careful not to changed the adjusted mode, for otherwise |
| @@ -4745,7 +4744,8 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) |
| * always be the user's requested size. |
| */ |
| I915_WRITE(PIPESRC(pipe), |
| - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); |
| + ((intel_crtc->config.pipe_src_w - 1) << 16) | |
| + (intel_crtc->config.pipe_src_h - 1)); |
| } |
| |
| static void intel_get_pipe_timings(struct intel_crtc *crtc, |
| @@ -4783,8 +4783,11 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, |
| } |
| |
| tmp = I915_READ(PIPESRC(crtc->pipe)); |
| - pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1; |
| - pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1; |
| + pipe_config->pipe_src_h = (tmp & 0xffff) + 1; |
| + pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1; |
| + |
| + pipe_config->requested_mode.vdisplay = pipe_config->pipe_src_h; |
| + pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w; |
| } |
| |
| static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc, |
| @@ -4884,7 +4887,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
| struct drm_device *dev = crtc->dev; |
| struct drm_i915_private *dev_priv = dev->dev_private; |
| struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| - struct drm_display_mode *mode = &intel_crtc->config.requested_mode; |
| int pipe = intel_crtc->pipe; |
| int plane = intel_crtc->plane; |
| int refclk, num_connectors = 0; |
| @@ -4983,8 +4985,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
| * which should always be the user's requested size. |
| */ |
| I915_WRITE(DSPSIZE(plane), |
| - ((mode->vdisplay - 1) << 16) | |
| - (mode->hdisplay - 1)); |
| + ((intel_crtc->config.pipe_src_h - 1) << 16) | |
| + (intel_crtc->config.pipe_src_w - 1)); |
| I915_WRITE(DSPPOS(plane), 0); |
| |
| i9xx_set_pipeconf(intel_crtc); |
| @@ -8354,6 +8356,8 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, |
| DRM_DEBUG_KMS("adjusted mode:\n"); |
| drm_mode_debug_printmodeline(&pipe_config->adjusted_mode); |
| DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock); |
| + DRM_DEBUG_KMS("pipe src size: %dx%d\n", |
| + pipe_config->pipe_src_w, pipe_config->pipe_src_h); |
| DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", |
| pipe_config->gmch_pfit.control, |
| pipe_config->gmch_pfit.pgm_ratios, |
| @@ -8406,6 +8410,10 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, |
| |
| drm_mode_copy(&pipe_config->adjusted_mode, mode); |
| drm_mode_copy(&pipe_config->requested_mode, mode); |
| + |
| + pipe_config->pipe_src_w = mode->hdisplay; |
| + pipe_config->pipe_src_h = mode->vdisplay; |
| + |
| pipe_config->cpu_transcoder = |
| (enum transcoder) to_intel_crtc(crtc)->pipe; |
| pipe_config->shared_dpll = DPLL_ID_PRIVATE; |
| @@ -8762,8 +8770,8 @@ intel_pipe_config_compare(struct drm_device *dev, |
| DRM_MODE_FLAG_NVSYNC); |
| } |
| |
| - PIPE_CONF_CHECK_I(requested_mode.hdisplay); |
| - PIPE_CONF_CHECK_I(requested_mode.vdisplay); |
| + PIPE_CONF_CHECK_I(pipe_src_w); |
| + PIPE_CONF_CHECK_I(pipe_src_h); |
| |
| PIPE_CONF_CHECK_I(gmch_pfit.control); |
| /* pfit ratios are autocomputed by the hw on gen4+ */ |
| diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h |
| index cd7ed03094ee..9a23b988046f 100644 |
| --- a/drivers/gpu/drm/i915/intel_drv.h |
| +++ b/drivers/gpu/drm/i915/intel_drv.h |
| @@ -215,6 +215,12 @@ struct intel_crtc_config { |
| /* Actual pipe timings ie. what we program into the pipe timing |
| * registers. adjusted_mode.clock is the pipe pixel clock. */ |
| struct drm_display_mode adjusted_mode; |
| + |
| + /* Pipe source size (ie. panel fitter input size) |
| + * All planes will be positioned inside this space, |
| + * and get clipped at the edges. */ |
| + int pipe_src_w, pipe_src_h; |
| + |
| /* Whether to set up the PCH/FDI. Note that we never allow sharing |
| * between pch encoders and cpu encoders. */ |
| bool has_pch_encoder; |
| diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c |
| index 293564a2896a..90b87c750695 100644 |
| --- a/drivers/gpu/drm/i915/intel_panel.c |
| +++ b/drivers/gpu/drm/i915/intel_panel.c |
| @@ -50,23 +50,22 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, |
| struct intel_crtc_config *pipe_config, |
| int fitting_mode) |
| { |
| - struct drm_display_mode *mode, *adjusted_mode; |
| + struct drm_display_mode *adjusted_mode; |
| int x, y, width, height; |
| |
| - mode = &pipe_config->requested_mode; |
| adjusted_mode = &pipe_config->adjusted_mode; |
| |
| x = y = width = height = 0; |
| |
| /* Native modes don't need fitting */ |
| - if (adjusted_mode->hdisplay == mode->hdisplay && |
| - adjusted_mode->vdisplay == mode->vdisplay) |
| + if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && |
| + adjusted_mode->vdisplay == pipe_config->pipe_src_h) |
| goto done; |
| |
| switch (fitting_mode) { |
| case DRM_MODE_SCALE_CENTER: |
| - width = mode->hdisplay; |
| - height = mode->vdisplay; |
| + width = pipe_config->pipe_src_w; |
| + height = pipe_config->pipe_src_h; |
| x = (adjusted_mode->hdisplay - width + 1)/2; |
| y = (adjusted_mode->vdisplay - height + 1)/2; |
| break; |
| @@ -74,17 +73,17 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, |
| case DRM_MODE_SCALE_ASPECT: |
| /* Scale but preserve the aspect ratio */ |
| { |
| - u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; |
| - u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; |
| + u32 scaled_width = adjusted_mode->hdisplay * pipe_config->pipe_src_h; |
| + u32 scaled_height = pipe_config->pipe_src_w * adjusted_mode->vdisplay; |
| if (scaled_width > scaled_height) { /* pillar */ |
| - width = scaled_height / mode->vdisplay; |
| + width = scaled_height / pipe_config->pipe_src_h; |
| if (width & 1) |
| width++; |
| x = (adjusted_mode->hdisplay - width + 1) / 2; |
| y = 0; |
| height = adjusted_mode->vdisplay; |
| } else if (scaled_width < scaled_height) { /* letter */ |
| - height = scaled_width / mode->hdisplay; |
| + height = scaled_width / pipe_config->pipe_src_w; |
| if (height & 1) |
| height++; |
| y = (adjusted_mode->vdisplay - height + 1) / 2; |
| @@ -177,14 +176,13 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| { |
| struct drm_device *dev = intel_crtc->base.dev; |
| u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
| - struct drm_display_mode *mode, *adjusted_mode; |
| + struct drm_display_mode *adjusted_mode; |
| |
| - mode = &pipe_config->requested_mode; |
| adjusted_mode = &pipe_config->adjusted_mode; |
| |
| /* Native modes don't need fitting */ |
| - if (adjusted_mode->hdisplay == mode->hdisplay && |
| - adjusted_mode->vdisplay == mode->vdisplay) |
| + if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && |
| + adjusted_mode->vdisplay == pipe_config->pipe_src_h) |
| goto out; |
| |
| switch (fitting_mode) { |
| @@ -193,16 +191,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| * For centered modes, we have to calculate border widths & |
| * heights and modify the values programmed into the CRTC. |
| */ |
| - centre_horizontally(adjusted_mode, mode->hdisplay); |
| - centre_vertically(adjusted_mode, mode->vdisplay); |
| + centre_horizontally(adjusted_mode, pipe_config->pipe_src_w); |
| + centre_vertically(adjusted_mode, pipe_config->pipe_src_h); |
| border = LVDS_BORDER_ENABLE; |
| break; |
| case DRM_MODE_SCALE_ASPECT: |
| /* Scale but preserve the aspect ratio */ |
| if (INTEL_INFO(dev)->gen >= 4) { |
| u32 scaled_width = adjusted_mode->hdisplay * |
| - mode->vdisplay; |
| - u32 scaled_height = mode->hdisplay * |
| + pipe_config->pipe_src_h; |
| + u32 scaled_height = pipe_config->pipe_src_w * |
| adjusted_mode->vdisplay; |
| |
| /* 965+ is easy, it does everything in hw */ |
| @@ -212,12 +210,12 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| else if (scaled_width < scaled_height) |
| pfit_control |= PFIT_ENABLE | |
| PFIT_SCALING_LETTER; |
| - else if (adjusted_mode->hdisplay != mode->hdisplay) |
| + else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) |
| pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; |
| } else { |
| u32 scaled_width = adjusted_mode->hdisplay * |
| - mode->vdisplay; |
| - u32 scaled_height = mode->hdisplay * |
| + pipe_config->pipe_src_h; |
| + u32 scaled_height = pipe_config->pipe_src_w * |
| adjusted_mode->vdisplay; |
| /* |
| * For earlier chips we have to calculate the scaling |
| @@ -227,11 +225,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| if (scaled_width > scaled_height) { /* pillar */ |
| centre_horizontally(adjusted_mode, |
| scaled_height / |
| - mode->vdisplay); |
| + pipe_config->pipe_src_h); |
| |
| border = LVDS_BORDER_ENABLE; |
| - if (mode->vdisplay != adjusted_mode->vdisplay) { |
| - u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); |
| + if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { |
| + u32 bits = panel_fitter_scaling(pipe_config->pipe_src_h, adjusted_mode->vdisplay); |
| pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
| bits << PFIT_VERT_SCALE_SHIFT); |
| pfit_control |= (PFIT_ENABLE | |
| @@ -241,11 +239,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| } else if (scaled_width < scaled_height) { /* letter */ |
| centre_vertically(adjusted_mode, |
| scaled_width / |
| - mode->hdisplay); |
| + pipe_config->pipe_src_w); |
| |
| border = LVDS_BORDER_ENABLE; |
| - if (mode->hdisplay != adjusted_mode->hdisplay) { |
| - u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); |
| + if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { |
| + u32 bits = panel_fitter_scaling(pipe_config->pipe_src_w, adjusted_mode->hdisplay); |
| pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
| bits << PFIT_VERT_SCALE_SHIFT); |
| pfit_control |= (PFIT_ENABLE | |
| @@ -266,8 +264,8 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, |
| * Full scaling, even if it changes the aspect ratio. |
| * Fortunately this is all done for us in hw. |
| */ |
| - if (mode->vdisplay != adjusted_mode->vdisplay || |
| - mode->hdisplay != adjusted_mode->hdisplay) { |
| + if (pipe_config->pipe_src_h != adjusted_mode->vdisplay || |
| + pipe_config->pipe_src_w != adjusted_mode->hdisplay) { |
| pfit_control |= PFIT_ENABLE; |
| if (INTEL_INFO(dev)->gen >= 4) |
| pfit_control |= PFIT_SCALING_AUTO; |
| diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c |
| index 3ecdfef3b619..db12c18e8040 100644 |
| --- a/drivers/gpu/drm/i915/intel_pm.c |
| +++ b/drivers/gpu/drm/i915/intel_pm.c |
| @@ -450,9 +450,8 @@ void intel_update_fbc(struct drm_device *dev) |
| struct drm_framebuffer *fb; |
| struct intel_framebuffer *intel_fb; |
| struct drm_i915_gem_object *obj; |
| - const struct drm_display_mode *mode; |
| const struct drm_display_mode *adjusted_mode; |
| - unsigned int max_hdisplay, max_vdisplay; |
| + unsigned int max_width, max_height; |
| |
| if (!I915_HAS_FBC(dev)) { |
| set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); |
| @@ -496,7 +495,6 @@ void intel_update_fbc(struct drm_device *dev) |
| fb = crtc->fb; |
| intel_fb = to_intel_framebuffer(fb); |
| obj = intel_fb->obj; |
| - mode = &intel_crtc->config.requested_mode; |
| adjusted_mode = &intel_crtc->config.adjusted_mode; |
| |
| if (i915_enable_fbc < 0 && |
| @@ -519,14 +517,14 @@ void intel_update_fbc(struct drm_device *dev) |
| } |
| |
| if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
| - max_hdisplay = 4096; |
| - max_vdisplay = 2048; |
| + max_width = 4096; |
| + max_height = 2048; |
| } else { |
| - max_hdisplay = 2048; |
| - max_vdisplay = 1536; |
| + max_width = 2048; |
| + max_height = 1536; |
| } |
| - if ((mode->hdisplay > max_hdisplay) || |
| - (mode->vdisplay > max_vdisplay)) { |
| + if (intel_crtc->config.pipe_src_w > max_width || |
| + intel_crtc->config.pipe_src_h > max_height) { |
| if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE)) |
| DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
| goto out_disable; |
| @@ -1178,7 +1176,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, |
| adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| clock = adjusted_mode->clock; |
| htotal = adjusted_mode->htotal; |
| - hdisplay = to_intel_crtc(crtc)->config.requested_mode.hdisplay; |
| + hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
| pixel_size = crtc->fb->bits_per_pixel / 8; |
| |
| /* Use the small buffer method to calculate plane watermark */ |
| @@ -1265,7 +1263,7 @@ static bool g4x_compute_srwm(struct drm_device *dev, |
| adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| clock = adjusted_mode->clock; |
| htotal = adjusted_mode->htotal; |
| - hdisplay = to_intel_crtc(crtc)->config.requested_mode.hdisplay; |
| + hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
| pixel_size = crtc->fb->bits_per_pixel / 8; |
| |
| line_time_us = (htotal * 1000) / clock; |
| @@ -1496,7 +1494,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) |
| &to_intel_crtc(crtc)->config.adjusted_mode; |
| int clock = adjusted_mode->clock; |
| int htotal = adjusted_mode->htotal; |
| - int hdisplay = to_intel_crtc(crtc)->config.requested_mode.hdisplay; |
| + int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
| int pixel_size = crtc->fb->bits_per_pixel / 8; |
| unsigned long line_time_us; |
| int entries; |
| @@ -1618,7 +1616,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) |
| &to_intel_crtc(enabled)->config.adjusted_mode; |
| int clock = adjusted_mode->clock; |
| int htotal = adjusted_mode->htotal; |
| - int hdisplay = to_intel_crtc(crtc)->config.requested_mode.hdisplay; |
| + int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
| int pixel_size = enabled->fb->bits_per_pixel / 8; |
| unsigned long line_time_us; |
| int entries; |
| @@ -1768,7 +1766,7 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, |
| adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| clock = adjusted_mode->clock; |
| htotal = adjusted_mode->htotal; |
| - hdisplay = to_intel_crtc(crtc)->config.requested_mode.hdisplay; |
| + hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
| pixel_size = crtc->fb->bits_per_pixel / 8; |
| |
| line_time_us = (htotal * 1000) / clock; |
| @@ -2123,8 +2121,8 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, |
| uint64_t pipe_w, pipe_h, pfit_w, pfit_h; |
| uint32_t pfit_size = intel_crtc->config.pch_pfit.size; |
| |
| - pipe_w = intel_crtc->config.requested_mode.hdisplay; |
| - pipe_h = intel_crtc->config.requested_mode.vdisplay; |
| + pipe_w = intel_crtc->config.pipe_src_w; |
| + pipe_h = intel_crtc->config.pipe_src_h; |
| pfit_w = (pfit_size >> 16) & 0xFFFF; |
| pfit_h = pfit_size & 0xFFFF; |
| if (pipe_w < pfit_w) |
| @@ -2650,8 +2648,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, |
| p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); |
| p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; |
| p->cur.bytes_per_pixel = 4; |
| - p->pri.horiz_pixels = |
| - intel_crtc->config.requested_mode.hdisplay; |
| + p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; |
| p->cur.horiz_pixels = 64; |
| /* TODO: for now, assume primary and cursor planes are always enabled. */ |
| p->pri.enabled = true; |
| diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c |
| index ae0e686e6e55..231b289e8e57 100644 |
| --- a/drivers/gpu/drm/i915/intel_sprite.c |
| +++ b/drivers/gpu/drm/i915/intel_sprite.c |
| @@ -652,8 +652,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
| .y2 = crtc_y + crtc_h, |
| }; |
| const struct drm_rect clip = { |
| - .x2 = intel_crtc->config.requested_mode.hdisplay, |
| - .y2 = intel_crtc->config.requested_mode.vdisplay, |
| + .x2 = intel_crtc->config.pipe_src_w, |
| + .y2 = intel_crtc->config.pipe_src_h, |
| }; |
| |
| intel_fb = to_intel_framebuffer(fb); |
| -- |
| 1.8.5.rc3 |
| |