aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-26 19:44:58 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-27 20:09:33 -0400
commit4e53c2e010e531b4a014692199e978482d471c7e (patch)
treeb9862b7c05165f2cea63fdd3a56afdd74f02bb3d /drivers/gpu/drm
parent965e0c489f360df1beeb567e4540777a09b8896e (diff)
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps: 1. Compute the bpp that the plane will output, this is done in pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also, this function clamps the pipe_bpp to whatever limit the EDID of any connected output specifies. 2. Adjust the pipe_bpp in the encoder and crtc functions, according to whatever constraints there are. 3. Decide whether to use dither by comparing the stored plane bpp with computed pipe_bpp. There are a few slight functional changes in this patch: - LVDS connector are now also going through the EDID clamping. But in a 2nd change we now unconditionally force the lvds bpc value - this shouldn't matter in reality when the panel setup is consistent, but better safe than sorry. - HDMI now forces the pipe_bpp to the selected value - I think that's what we actually want, since otherwise at least the pixelclock computations are wrong (I'm not sure whether the port would accept e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick the next higher bpc value, since otherwise there's no way to make use of the 12 bpc mode (since the next patch will remove the 12bpc plane format, it doesn't exist). Both of these changes are due to the removal of the pipe_bpp = min(display_bpp, plane_bpp); statement. Another slight change is the reworking of the dp bpc code: - For the mode_valid callback it's sufficient to only check whether the mode would fit at the lowest bpc. - The bandwidth computation code is a bit restructured: It now walks all available bpp values in an outer loop and the codeblock that computes derived values (once a good configuration is found) has been moved out of the for loop maze. This is prep work to allow us to successively fall back on bpc values, and also correctly support bpc values != 8 or 6. v2: Rebased on top of Paulo Zanoni's little refactoring to use more drm dp helper functions. v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color range work. v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed. v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked in a later patch though again. v6: Fix spelling in a comment. v7: Debug output improvements for the bpp computation. v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different things! v9: Reinstate the fix to properly ignore the firmware edp bpp ... this was lost in a rebase. v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have that. Still unsure whether this is the way to go, but at least 6bpc for a 8bpc hdmi output seems to work. v11: And g4x/vlv also lack 12bpc hdmi support, so only support high depth on DP. Adjust the code. v12: Rebased. v13: Split out the introduction of pipe_config->dither|pipe_bpp, as requested from Jesse Barnes. v14: Split out the special 6BPC handling for DP, as requested by Jesse Barnes. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c7
-rw-r--r--drivers/gpu/drm/i915/intel_display.c224
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c13
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c12
4 files changed, 100 insertions, 156 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 3d09df0d4b9d..6c6b0124f17d 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -945,9 +945,7 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
945 temp |= TRANS_MSA_12_BPC; 945 temp |= TRANS_MSA_12_BPC;
946 break; 946 break;
947 default: 947 default:
948 temp |= TRANS_MSA_8_BPC; 948 BUG();
949 WARN(1, "%d bpp unsupported by DDI function\n",
950 intel_crtc->config.pipe_bpp);
951 } 949 }
952 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); 950 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
953 } 951 }
@@ -983,8 +981,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
983 temp |= TRANS_DDI_BPC_12; 981 temp |= TRANS_DDI_BPC_12;
984 break; 982 break;
985 default: 983 default:
986 WARN(1, "%d bpp unsupported by transcoder DDI function\n", 984 BUG();
987 intel_crtc->config.pipe_bpp);
988 } 985 }
989 986
990 if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) 987 if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4cc46ef9ca9f..14397726d3ac 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4076,142 +4076,6 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
4076 && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); 4076 && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
4077} 4077}
4078 4078
4079/**
4080 * intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send
4081 * @crtc: CRTC structure
4082 * @mode: requested mode
4083 *
4084 * A pipe may be connected to one or more outputs. Based on the depth of the
4085 * attached framebuffer, choose a good color depth to use on the pipe.
4086 *
4087 * If possible, match the pipe depth to the fb depth. In some cases, this
4088 * isn't ideal, because the connected output supports a lesser or restricted
4089 * set of depths. Resolve that here:
4090 * LVDS typically supports only 6bpc, so clamp down in that case
4091 * HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc
4092 * Displays may support a restricted set as well, check EDID and clamp as
4093 * appropriate.
4094 * DP may want to dither down to 6bpc to fit larger modes
4095 *
4096 * RETURNS:
4097 * Dithering requirement (i.e. false if display bpc and pipe bpc match,
4098 * true if they don't match).
4099 */
4100static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
4101 struct drm_framebuffer *fb,
4102 unsigned int *pipe_bpp,
4103 struct drm_display_mode *mode)
4104{
4105 struct drm_device *dev = crtc->dev;
4106 struct drm_i915_private *dev_priv = dev->dev_private;
4107 struct drm_connector *connector;
4108 struct intel_encoder *intel_encoder;
4109 unsigned int display_bpc = UINT_MAX, bpc;
4110
4111 /* Walk the encoders & connectors on this crtc, get min bpc */
4112 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
4113
4114 if (intel_encoder->type == INTEL_OUTPUT_LVDS) {
4115 unsigned int lvds_bpc;
4116
4117 if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) ==
4118 LVDS_A3_POWER_UP)
4119 lvds_bpc = 8;
4120 else
4121 lvds_bpc = 6;
4122
4123 if (lvds_bpc < display_bpc) {
4124 DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
4125 display_bpc = lvds_bpc;
4126 }
4127 continue;
4128 }
4129
4130 /* Not one of the known troublemakers, check the EDID */
4131 list_for_each_entry(connector, &dev->mode_config.connector_list,
4132 head) {
4133 if (connector->encoder != &intel_encoder->base)
4134 continue;
4135
4136 /* Don't use an invalid EDID bpc value */
4137 if (connector->display_info.bpc &&
4138 connector->display_info.bpc < display_bpc) {
4139 DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
4140 display_bpc = connector->display_info.bpc;
4141 }
4142 }
4143
4144 if (intel_encoder->type == INTEL_OUTPUT_EDP) {
4145 /* Use VBT settings if we have an eDP panel */
4146 unsigned int edp_bpc = dev_priv->edp.bpp / 3;
4147
4148 if (edp_bpc && edp_bpc < display_bpc) {
4149 DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
4150 display_bpc = edp_bpc;
4151 }
4152 continue;
4153 }
4154
4155 /*
4156 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
4157 * through, clamp it down. (Note: >12bpc will be caught below.)
4158 */
4159 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
4160 if (display_bpc > 8 && display_bpc < 12) {
4161 DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
4162 display_bpc = 12;
4163 } else {
4164 DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
4165 display_bpc = 8;
4166 }
4167 }
4168 }
4169
4170 if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
4171 DRM_DEBUG_KMS("Dithering DP to 6bpc\n");
4172 display_bpc = 6;
4173 }
4174
4175 /*
4176 * We could just drive the pipe at the highest bpc all the time and
4177 * enable dithering as needed, but that costs bandwidth. So choose
4178 * the minimum value that expresses the full color range of the fb but
4179 * also stays within the max display bpc discovered above.
4180 */
4181
4182 switch (fb->depth) {
4183 case 8:
4184 bpc = 8; /* since we go through a colormap */
4185 break;
4186 case 15:
4187 case 16:
4188 bpc = 6; /* min is 18bpp */
4189 break;
4190 case 24:
4191 bpc = 8;
4192 break;
4193 case 30:
4194 bpc = 10;
4195 break;
4196 case 48:
4197 bpc = 12;
4198 break;
4199 default:
4200 DRM_DEBUG("unsupported depth, assuming 24 bits\n");
4201 bpc = min((unsigned int)8, display_bpc);
4202 break;
4203 }
4204
4205 display_bpc = min(display_bpc, bpc);
4206
4207 DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
4208 bpc, display_bpc);
4209
4210 *pipe_bpp = display_bpc * 3;
4211
4212 return display_bpc != bpc;
4213}
4214
4215static int vlv_get_refclk(struct drm_crtc *crtc) 4079static int vlv_get_refclk(struct drm_crtc *crtc)
4216{ 4080{
4217 struct drm_device *dev = crtc->dev; 4081 struct drm_device *dev = crtc->dev;
@@ -4665,10 +4529,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4665 const intel_limit_t *limit; 4529 const intel_limit_t *limit;
4666 int ret; 4530 int ret;
4667 4531
4668 /* temporary hack */
4669 intel_crtc->config.dither =
4670 adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC;
4671
4672 for_each_encoder_on_crtc(dev, crtc, encoder) { 4532 for_each_encoder_on_crtc(dev, crtc, encoder) {
4673 switch (encoder->type) { 4533 switch (encoder->type) {
4674 case INTEL_OUTPUT_LVDS: 4534 case INTEL_OUTPUT_LVDS:
@@ -5673,10 +5533,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5673 intel_crtc_update_cursor(crtc, true); 5533 intel_crtc_update_cursor(crtc, true);
5674 5534
5675 /* determine panel color depth */ 5535 /* determine panel color depth */
5676 dither = intel_choose_pipe_bpp_dither(crtc, fb, 5536 dither = intel_crtc->config.dither;
5677 &intel_crtc->config.pipe_bpp,
5678 adjusted_mode);
5679 intel_crtc->config.dither = dither;
5680 if (is_lvds && dev_priv->lvds_dither) 5537 if (is_lvds && dev_priv->lvds_dither)
5681 dither = true; 5538 dither = true;
5682 5539
@@ -5841,10 +5698,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
5841 intel_crtc_update_cursor(crtc, true); 5698 intel_crtc_update_cursor(crtc, true);
5842 5699
5843 /* determine panel color depth */ 5700 /* determine panel color depth */
5844 dither = intel_choose_pipe_bpp_dither(crtc, fb, 5701 dither = intel_crtc->config.dither;
5845 &intel_crtc->config.pipe_bpp,
5846 adjusted_mode);
5847 intel_crtc->config.dither = dither;
5848 5702
5849 DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); 5703 DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
5850 drm_mode_debug_printmodeline(mode); 5704 drm_mode_debug_printmodeline(mode);
@@ -7525,14 +7379,72 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
7525 } 7379 }
7526} 7380}
7527 7381
7382static int
7383pipe_config_set_bpp(struct drm_crtc *crtc,
7384 struct drm_framebuffer *fb,
7385 struct intel_crtc_config *pipe_config)
7386{
7387 struct drm_device *dev = crtc->dev;
7388 struct drm_connector *connector;
7389 int bpp;
7390
7391 switch (fb->depth) {
7392 case 8:
7393 bpp = 8*3; /* since we go through a colormap */
7394 break;
7395 case 15:
7396 case 16:
7397 bpp = 6*3; /* min is 18bpp */
7398 break;
7399 case 24:
7400 bpp = 8*3;
7401 break;
7402 case 30:
7403 bpp = 10*3;
7404 break;
7405 case 48:
7406 bpp = 12*3;
7407 break;
7408 default:
7409 DRM_DEBUG_KMS("unsupported depth\n");
7410 return -EINVAL;
7411 }
7412
7413 if (fb->depth > 24 && !HAS_PCH_SPLIT(dev)) {
7414 DRM_DEBUG_KMS("high depth not supported on gmch platforms\n");
7415 return -EINVAL;
7416 }
7417
7418 pipe_config->pipe_bpp = bpp;
7419
7420 /* Clamp display bpp to EDID value */
7421 list_for_each_entry(connector, &dev->mode_config.connector_list,
7422 head) {
7423 if (connector->encoder && connector->encoder->crtc != crtc)
7424 continue;
7425
7426 /* Don't use an invalid EDID bpc value */
7427 if (connector->display_info.bpc &&
7428 connector->display_info.bpc * 3 < bpp) {
7429 DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n",
7430 bpp, connector->display_info.bpc*3);
7431 pipe_config->pipe_bpp = connector->display_info.bpc*3;
7432 }
7433 }
7434
7435 return bpp;
7436}
7437
7528static struct intel_crtc_config * 7438static struct intel_crtc_config *
7529intel_modeset_pipe_config(struct drm_crtc *crtc, 7439intel_modeset_pipe_config(struct drm_crtc *crtc,
7440 struct drm_framebuffer *fb,
7530 struct drm_display_mode *mode) 7441 struct drm_display_mode *mode)
7531{ 7442{
7532 struct drm_device *dev = crtc->dev; 7443 struct drm_device *dev = crtc->dev;
7533 struct drm_encoder_helper_funcs *encoder_funcs; 7444 struct drm_encoder_helper_funcs *encoder_funcs;
7534 struct intel_encoder *encoder; 7445 struct intel_encoder *encoder;
7535 struct intel_crtc_config *pipe_config; 7446 struct intel_crtc_config *pipe_config;
7447 int plane_bpp;
7536 7448
7537 pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); 7449 pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
7538 if (!pipe_config) 7450 if (!pipe_config)
@@ -7541,6 +7453,10 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
7541 drm_mode_copy(&pipe_config->adjusted_mode, mode); 7453 drm_mode_copy(&pipe_config->adjusted_mode, mode);
7542 drm_mode_copy(&pipe_config->requested_mode, mode); 7454 drm_mode_copy(&pipe_config->requested_mode, mode);
7543 7455
7456 plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config);
7457 if (plane_bpp < 0)
7458 goto fail;
7459
7544 /* Pass our mode to the connectors and the CRTC to give them a chance to 7460 /* Pass our mode to the connectors and the CRTC to give them a chance to
7545 * adjust it according to limitations or connector properties, and also 7461 * adjust it according to limitations or connector properties, and also
7546 * a chance to reject the mode entirely. 7462 * a chance to reject the mode entirely.
@@ -7569,12 +7485,20 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
7569 } 7485 }
7570 } 7486 }
7571 7487
7488 /* temporary hack until the DP code doesn't use the 6BPC flag any more */
7489 if (pipe_config->adjusted_mode.private_flags & INTEL_MODE_DP_FORCE_6BPC)
7490 pipe_config->pipe_bpp = 6*8;
7491
7572 if (!(intel_crtc_compute_config(crtc, pipe_config))) { 7492 if (!(intel_crtc_compute_config(crtc, pipe_config))) {
7573 DRM_DEBUG_KMS("CRTC fixup failed\n"); 7493 DRM_DEBUG_KMS("CRTC fixup failed\n");
7574 goto fail; 7494 goto fail;
7575 } 7495 }
7576 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 7496 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
7577 7497
7498 pipe_config->dither = pipe_config->pipe_bpp != plane_bpp;
7499 DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
7500 plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
7501
7578 return pipe_config; 7502 return pipe_config;
7579fail: 7503fail:
7580 kfree(pipe_config); 7504 kfree(pipe_config);
@@ -7866,7 +7790,7 @@ int intel_set_mode(struct drm_crtc *crtc,
7866 * pieces of code that are not yet converted to deal with mutliple crtcs 7790 * pieces of code that are not yet converted to deal with mutliple crtcs
7867 * changing their mode at the same time. */ 7791 * changing their mode at the same time. */
7868 if (modeset_pipes) { 7792 if (modeset_pipes) {
7869 pipe_config = intel_modeset_pipe_config(crtc, mode); 7793 pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
7870 if (IS_ERR(pipe_config)) { 7794 if (IS_ERR(pipe_config)) {
7871 ret = PTR_ERR(pipe_config); 7795 ret = PTR_ERR(pipe_config);
7872 pipe_config = NULL; 7796 pipe_config = NULL;
@@ -8305,8 +8229,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
8305 dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; 8229 dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
8306 dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; 8230 dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
8307 8231
8308 intel_crtc->config.pipe_bpp = 24; /* default for pre-Ironlake */
8309
8310 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); 8232 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
8311} 8233}
8312 8234
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 0731ba660aac..b206a0db7716 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -791,6 +791,19 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
791 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev)) 791 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev))
792 pipe_config->has_pch_encoder = true; 792 pipe_config->has_pch_encoder = true;
793 793
794 /*
795 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
796 * through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi
797 * outputs.
798 */
799 if (pipe_config->pipe_bpp > 8*3 && HAS_PCH_SPLIT(dev)) {
800 DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
801 pipe_config->pipe_bpp = 12*3;
802 } else {
803 DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
804 pipe_config->pipe_bpp = 8*3;
805 }
806
794 return true; 807 return true;
795} 808}
796 809
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 9d6ed91b443d..7b6d07b6a02d 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -310,6 +310,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
310 struct drm_display_mode *mode = &pipe_config->requested_mode; 310 struct drm_display_mode *mode = &pipe_config->requested_mode;
311 struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; 311 struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
312 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; 312 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
313 unsigned int lvds_bpp;
313 int pipe; 314 int pipe;
314 315
315 /* Should never happen!! */ 316 /* Should never happen!! */
@@ -321,6 +322,17 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
321 if (intel_encoder_check_is_cloned(&lvds_encoder->base)) 322 if (intel_encoder_check_is_cloned(&lvds_encoder->base))
322 return false; 323 return false;
323 324
325 if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) ==
326 LVDS_A3_POWER_UP)
327 lvds_bpp = 8*3;
328 else
329 lvds_bpp = 6*3;
330
331 if (lvds_bpp != pipe_config->pipe_bpp) {
332 DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
333 pipe_config->pipe_bpp, lvds_bpp);
334 pipe_config->pipe_bpp = lvds_bpp;
335 }
324 /* 336 /*
325 * We have timings from the BIOS for the panel, put them in 337 * We have timings from the BIOS for the panel, put them in
326 * to the adjusted mode. The CRTC will be set up for this mode, 338 * to the adjusted mode. The CRTC will be set up for this mode,