aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-01 11:16:21 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-04 08:01:48 -0400
commitff9a6750aca3553c78385a9aa89b678b2b9be7df (patch)
treec27e3b057e5e99957fb950a28f2dbcb749ba7511 /drivers/gpu/drm/i915/intel_display.c
parent7c62a164faea430c6e4c411eb0870640cf51a6e5 (diff)
drm/i915: store adjusted dotclock in adjusted_mode->clock
... not the port clock. This allows us to kill the funny semantics around pixel_target_clock. Since the dpll code still needs the real port clock, add a new port_clock field to the pipe configuration. Handling the default case for that one is a bit tricky, since encoders might not consistently overwrite it when retrying the crtc/encoder bw arbitrage step in the compute config stage. Hence we need to always clear port_clock and update it again if the encoder hasn't put in something more specific. This can't be done in one step since the encoder might want to adjust the mode first. I was a bit on the fence whether I should subsume the pixel multiplier handling into the port_clock, too. But then I decided against this since it's on an abstract level still the dotclock of the adjusted mode, and only our hw makes it a bit special due to the separate pixel mulitplier setting (which requires that the dpll runs at the non-multiplied dotclock). So after this patch the adjusted_mode accurately describes the mode we feed into the port, after the panel fitter and pixel multiplier (or line doubling, if we ever bother with that) have done their job. Since the fdi link is between the pfit and the pixel multiplier steps we need to be careful with calculating the fdi link config. v2: Fix up ilk cpu pll handling. v3: Introduce an fdi_dotclock variable in ironlake_fdi_compute_config to make it clearer that we transmit the adjusted_mode without the pixel multiplier taken into account. The old code multiplied the the available link bw with the pixel multiplier, which results in the same fdi configuration, but is much more confusing. v4: Rebase on top of Imre's is_cpu_edp removal. v5: Rebase on top of Paulo's haswell watermark fixes, which introduce a new place which looked at the pixel_clock and so needed conversion. v6: Split out prep patches as requested by Paulo Zanoni. Also rebase on top of the fdi dotclock handling fix in the fdi lanes/bw computation code. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 711ec3314893..60d4bfd40107 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3989,7 +3989,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
3989{ 3989{
3990 struct drm_device *dev = intel_crtc->base.dev; 3990 struct drm_device *dev = intel_crtc->base.dev;
3991 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; 3991 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
3992 int target_clock, lane, link_bw, fdi_dotclock; 3992 int lane, link_bw, fdi_dotclock;
3993 bool setup_ok, needs_recompute = false; 3993 bool setup_ok, needs_recompute = false;
3994 3994
3995retry: 3995retry:
@@ -4002,12 +4002,7 @@ retry:
4002 */ 4002 */
4003 link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; 4003 link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
4004 4004
4005 if (pipe_config->pixel_target_clock) 4005 fdi_dotclock = adjusted_mode->clock;
4006 target_clock = pipe_config->pixel_target_clock;
4007 else
4008 target_clock = adjusted_mode->clock;
4009
4010 fdi_dotclock = target_clock;
4011 if (pipe_config->pixel_multiplier > 1) 4006 if (pipe_config->pixel_multiplier > 1)
4012 fdi_dotclock /= pipe_config->pixel_multiplier; 4007 fdi_dotclock /= pipe_config->pixel_multiplier;
4013 4008
@@ -4357,8 +4352,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
4357{ 4352{
4358 struct drm_device *dev = crtc->base.dev; 4353 struct drm_device *dev = crtc->base.dev;
4359 struct drm_i915_private *dev_priv = dev->dev_private; 4354 struct drm_i915_private *dev_priv = dev->dev_private;
4360 struct drm_display_mode *adjusted_mode =
4361 &crtc->config.adjusted_mode;
4362 struct intel_encoder *encoder; 4355 struct intel_encoder *encoder;
4363 int pipe = crtc->pipe; 4356 int pipe = crtc->pipe;
4364 u32 dpll, mdiv; 4357 u32 dpll, mdiv;
@@ -4411,7 +4404,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
4411 vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); 4404 vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
4412 4405
4413 /* Set HBR and RBR LPF coefficients */ 4406 /* Set HBR and RBR LPF coefficients */
4414 if (adjusted_mode->clock == 162000 || 4407 if (crtc->config.port_clock == 162000 ||
4415 intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) 4408 intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
4416 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 4409 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
4417 0x005f0021); 4410 0x005f0021);
@@ -4856,7 +4849,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4856 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. 4849 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
4857 */ 4850 */
4858 limit = intel_limit(crtc, refclk); 4851 limit = intel_limit(crtc, refclk);
4859 ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, 4852 ok = dev_priv->display.find_dpll(limit, crtc,
4853 intel_crtc->config.port_clock,
4860 refclk, NULL, &clock); 4854 refclk, NULL, &clock);
4861 if (!ok && !intel_crtc->config.clock_set) { 4855 if (!ok && !intel_crtc->config.clock_set) {
4862 DRM_ERROR("Couldn't find PLL settings for mode!\n"); 4856 DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5464,7 +5458,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
5464} 5458}
5465 5459
5466static bool ironlake_compute_clocks(struct drm_crtc *crtc, 5460static bool ironlake_compute_clocks(struct drm_crtc *crtc,
5467 struct drm_display_mode *adjusted_mode,
5468 intel_clock_t *clock, 5461 intel_clock_t *clock,
5469 bool *has_reduced_clock, 5462 bool *has_reduced_clock,
5470 intel_clock_t *reduced_clock) 5463 intel_clock_t *reduced_clock)
@@ -5492,7 +5485,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
5492 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. 5485 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
5493 */ 5486 */
5494 limit = intel_limit(crtc, refclk); 5487 limit = intel_limit(crtc, refclk);
5495 ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, 5488 ret = dev_priv->display.find_dpll(limit, crtc,
5489 to_intel_crtc(crtc)->config.port_clock,
5496 refclk, NULL, clock); 5490 refclk, NULL, clock);
5497 if (!ret) 5491 if (!ret)
5498 return false; 5492 return false;
@@ -5692,7 +5686,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5692 WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), 5686 WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
5693 "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); 5687 "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
5694 5688
5695 ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, 5689 ok = ironlake_compute_clocks(crtc, &clock,
5696 &has_reduced_clock, &reduced_clock); 5690 &has_reduced_clock, &reduced_clock);
5697 if (!ok && !intel_crtc->config.clock_set) { 5691 if (!ok && !intel_crtc->config.clock_set) {
5698 DRM_ERROR("Couldn't find PLL settings for mode!\n"); 5692 DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5895,7 +5889,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
5895 WARN(num_connectors != 1, "%d connectors attached to pipe %c\n", 5889 WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
5896 num_connectors, pipe_name(pipe)); 5890 num_connectors, pipe_name(pipe));
5897 5891
5898 if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock)) 5892 if (!intel_ddi_pll_mode_set(crtc))
5899 return -EINVAL; 5893 return -EINVAL;
5900 5894
5901 /* Ensure that the cursor is valid for the new mode before changing... */ 5895 /* Ensure that the cursor is valid for the new mode before changing... */
@@ -7805,6 +7799,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
7805 goto fail; 7799 goto fail;
7806 7800
7807encoder_retry: 7801encoder_retry:
7802 /* Ensure the port clock default is reset when retrying. */
7803 pipe_config->port_clock = 0;
7804
7808 /* Pass our mode to the connectors and the CRTC to give them a chance to 7805 /* Pass our mode to the connectors and the CRTC to give them a chance to
7809 * adjust it according to limitations or connector properties, and also 7806 * adjust it according to limitations or connector properties, and also
7810 * a chance to reject the mode entirely. 7807 * a chance to reject the mode entirely.
@@ -7833,6 +7830,11 @@ encoder_retry:
7833 } 7830 }
7834 } 7831 }
7835 7832
7833 /* Set default port clock if not overwritten by the encoder. Needs to be
7834 * done afterwards in case the encoder adjusts the mode. */
7835 if (!pipe_config->port_clock)
7836 pipe_config->port_clock = pipe_config->adjusted_mode.clock;
7837
7836 ret = intel_crtc_compute_config(crtc, pipe_config); 7838 ret = intel_crtc_compute_config(crtc, pipe_config);
7837 if (ret < 0) { 7839 if (ret < 0) {
7838 DRM_DEBUG_KMS("CRTC fixup failed\n"); 7840 DRM_DEBUG_KMS("CRTC fixup failed\n");