diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-06-01 11:16:21 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-06-04 08:01:48 -0400 |
commit | ff9a6750aca3553c78385a9aa89b678b2b9be7df (patch) | |
tree | c27e3b057e5e99957fb950a28f2dbcb749ba7511 /drivers/gpu/drm/i915/intel_display.c | |
parent | 7c62a164faea430c6e4c411eb0870640cf51a6e5 (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.c | 32 |
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 | ||
3995 | retry: | 3995 | retry: |
@@ -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 | ||
5466 | static bool ironlake_compute_clocks(struct drm_crtc *crtc, | 5460 | static 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 | ||
7807 | encoder_retry: | 7801 | encoder_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"); |