diff mbox

[5/7] drm/i915: store adjusted dotclock in adjusted_mode->clock

Message ID 1370099783-20328-6-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter June 1, 2013, 3:16 p.m. UTC
... 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)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_ddi.c     |  3 ++-
 drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_dp.c      | 18 +++++++-----------
 drivers/gpu/drm/i915/intel_drv.h     | 13 +++++++------
 drivers/gpu/drm/i915/intel_hdmi.c    |  4 +---
 drivers/gpu/drm/i915/intel_pm.c      |  5 +----
 6 files changed, 35 insertions(+), 40 deletions(-)

Comments

Paulo Zanoni June 3, 2013, 4:54 p.m. UTC | #1
2013/6/1 Daniel Vetter <daniel.vetter@ffwll.ch>:
> ... 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)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Due to my comments on patch 3, there's a possibility you may need to
rebase this patch.

My only optional bikeshed is to print port_clock inside
intel_dump_pipe_config. If you rebase, you may consider doing it :)

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6)

> ---
>  drivers/gpu/drm/i915/intel_ddi.c     |  3 ++-
>  drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_dp.c      | 18 +++++++-----------
>  drivers/gpu/drm/i915/intel_drv.h     | 13 +++++++------
>  drivers/gpu/drm/i915/intel_hdmi.c    |  4 +---
>  drivers/gpu/drm/i915/intel_pm.c      |  5 +----
>  6 files changed, 35 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 9649df8..486c46b 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -624,7 +624,7 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
>                       clock, *p_out, *n2_out, *r2_out);
>  }
>
> -bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
> +bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
>  {
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>         struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
> @@ -634,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
>         int type = intel_encoder->type;
>         enum pipe pipe = intel_crtc->pipe;
>         uint32_t reg, val;
> +       int clock = intel_crtc->config.port_clock;
>
>         /* TODO: reuse PLLs when possible (compare values) */
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 761254d..103f4e9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3992,7 +3992,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  {
>         struct drm_device *dev = intel_crtc->base.dev;
>         struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> -       int target_clock, lane, link_bw, fdi_dotclock;
> +       int lane, link_bw, fdi_dotclock;
>         bool setup_ok, needs_recompute = false;
>
>  retry:
> @@ -4005,12 +4005,7 @@ retry:
>          */
>         link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
>
> -       if (pipe_config->pixel_target_clock)
> -               target_clock = pipe_config->pixel_target_clock;
> -       else
> -               target_clock = adjusted_mode->clock;
> -
> -       fdi_dotclock = target_clock;
> +       fdi_dotclock = adjusted_mode->clock;

In the patch you sent Friday, you used adjusted_mode->clock instead of
fdi_dotclock as the parameter to ironlake_get_lanes_required, you only
initialized fdi_dotclock before calling intel_link_compute_m_n. This
doesn't change the code behavior, I'm just pointing in case you
changed without noticing and prefer the older version.


>         if (pipe_config->pixel_multiplier > 1)
>                 fdi_dotclock /= pipe_config->pixel_multiplier;
>
> @@ -4360,8 +4355,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->base.dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct drm_display_mode *adjusted_mode =
> -               &crtc->config.adjusted_mode;
>         struct intel_encoder *encoder;
>         int pipe = crtc->pipe;
>         u32 dpll, mdiv;
> @@ -4414,7 +4407,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
>         vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
>
>         /* Set HBR and RBR LPF coefficients */
> -       if (adjusted_mode->clock == 162000 ||
> +       if (crtc->config.port_clock == 162000 ||
>             intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
>                 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
>                                  0x005f0021);
> @@ -4859,7 +4852,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
>          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
>          */
>         limit = intel_limit(crtc, refclk);
> -       ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
> +       ok = dev_priv->display.find_dpll(limit, crtc,
> +                                        intel_crtc->config.port_clock,
>                                          refclk, NULL, &clock);
>         if (!ok) {
>                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
> @@ -5467,7 +5461,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
>  }
>
>  static bool ironlake_compute_clocks(struct drm_crtc *crtc,
> -                                   struct drm_display_mode *adjusted_mode,
>                                     intel_clock_t *clock,
>                                     bool *has_reduced_clock,
>                                     intel_clock_t *reduced_clock)
> @@ -5495,7 +5488,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
>          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
>          */
>         limit = intel_limit(crtc, refclk);
> -       ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
> +       ret = dev_priv->display.find_dpll(limit, crtc,
> +                                         to_intel_crtc(crtc)->config.port_clock,
>                                           refclk, NULL, clock);
>         if (!ret)
>                 return false;
> @@ -5695,7 +5689,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>         WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
>              "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
>
> -       ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
> +       ok = ironlake_compute_clocks(crtc, &clock,
>                                      &has_reduced_clock, &reduced_clock);
>         if (!ok) {
>                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
> @@ -5898,7 +5892,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>         WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
>              num_connectors, pipe_name(pipe));
>
> -       if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock))
> +       if (!intel_ddi_pll_mode_set(crtc))
>                 return -EINVAL;
>
>         /* Ensure that the cursor is valid for the new mode before changing... */
> @@ -7789,6 +7783,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>                 goto fail;
>
>  encoder_retry:
> +       /* Ensure the port clock default is reset when retrying. */
> +       pipe_config->port_clock = 0;
> +
>         /* Pass our mode to the connectors and the CRTC to give them a chance to
>          * adjust it according to limitations or connector properties, and also
>          * a chance to reject the mode entirely.
> @@ -7817,6 +7814,11 @@ encoder_retry:
>                 }
>         }
>
> +       /* Set default port clock if not overwritten by the encoder. Needs to be
> +        * done afterwards in case the encoder adjusts the mode. */
> +       if (!pipe_config->port_clock)
> +               pipe_config->port_clock = pipe_config->adjusted_mode.clock;
> +
>         ret = intel_crtc_compute_config(crtc, pipe_config);
>         if (ret < 0) {
>                 DRM_DEBUG_KMS("CRTC fixup failed\n");
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 647cc2b..c92eeeb 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -677,7 +677,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>         int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
>         int bpp, mode_rate;
>         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
> -       int target_clock, link_avail, link_clock;
> +       int link_avail, link_clock;
>
>         if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
>                 pipe_config->has_pch_encoder = true;
> @@ -694,8 +694,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>                         intel_pch_panel_fitting(intel_crtc, pipe_config,
>                                                 intel_connector->panel.fitting_mode);
>         }
> -       /* We need to take the panel's fixed mode into account. */
> -       target_clock = adjusted_mode->clock;
>
>         if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
>                 return false;
> @@ -711,7 +709,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>                 bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
>
>         for (; bpp >= 6*3; bpp -= 2*3) {
> -               mode_rate = intel_dp_link_required(target_clock, bpp);
> +               mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
>
>                 for (clock = 0; clock <= max_clock; clock++) {
>                         for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
> @@ -746,18 +744,17 @@ found:
>
>         intel_dp->link_bw = bws[clock];
>         intel_dp->lane_count = lane_count;
> -       adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
>         pipe_config->pipe_bpp = bpp;
> -       pipe_config->pixel_target_clock = target_clock;
> +       pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
>
>         DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
>                       intel_dp->link_bw, intel_dp->lane_count,
> -                     adjusted_mode->clock, bpp);
> +                     pipe_config->port_clock, bpp);
>         DRM_DEBUG_KMS("DP link bw required %i available %i\n",
>                       mode_rate, link_avail);
>
>         intel_link_compute_m_n(bpp, lane_count,
> -                              target_clock, adjusted_mode->clock,
> +                              adjusted_mode->clock, pipe_config->port_clock,
>                                &pipe_config->dp_m_n);
>
>         intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
> @@ -788,12 +785,11 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         u32 dpa_ctl;
>
> -       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
> -                     crtc->config.adjusted_mode.clock);
> +       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
>         dpa_ctl = I915_READ(DP_A);
>         dpa_ctl &= ~DP_PLL_FREQ_MASK;
>
> -       if (crtc->config.adjusted_mode.clock == 162000) {
> +       if (crtc->config.port_clock == 162000) {
>                 /* For a long time we've carried around a ILK-DevA w/a for the
>                  * 160MHz clock. If we're really unlucky, it's still required.
>                  */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index fdf6303..afda71f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -243,12 +243,13 @@ struct intel_crtc_config {
>
>         int pipe_bpp;
>         struct intel_link_m_n dp_m_n;
> -       /**
> -        * This is currently used by DP and HDMI encoders since those can have a
> -        * target pixel clock != the port link clock (which is currently stored
> -        * in adjusted_mode->clock).
> +
> +       /*
> +        * Frequence the dpll for the port should run at. Differs from the
> +        * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
>          */
> -       int pixel_target_clock;
> +       int port_clock;
> +
>         /* Used by SDVO (and if we ever fix it, HDMI). */
>         unsigned pixel_multiplier;
>
> @@ -786,7 +787,7 @@ extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
>  extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
>  extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
>  extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
> -extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
> +extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
>  extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
>  extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
>  extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 8062a92..bc12518 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -835,9 +835,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>                 desired_bpp = 12*3;
>
>                 /* Need to adjust the port link by 1.5x for 12bpc. */
> -               adjusted_mode->clock = clock_12bpc;
> -               pipe_config->pixel_target_clock =
> -                       pipe_config->requested_mode.clock;
> +               pipe_config->port_clock = clock_12bpc;
>         } else {
>                 DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
>                 desired_bpp = 8*3;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 49a1887..4126fb1 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2078,10 +2078,7 @@ static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>         uint32_t pixel_rate, pfit_size;
>
> -       if (intel_crtc->config.pixel_target_clock)
> -               pixel_rate = intel_crtc->config.pixel_target_clock;
> -       else
> -               pixel_rate = intel_crtc->config.adjusted_mode.clock;
> +       pixel_rate = intel_crtc->config.adjusted_mode.clock;
>
>         /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
>          * adjust the pixel_rate here. */
> --
> 1.7.11.7
>
Paulo Zanoni June 3, 2013, 4:56 p.m. UTC | #2
2013/6/3 Paulo Zanoni <przanoni@gmail.com>:
> 2013/6/1 Daniel Vetter <daniel.vetter@ffwll.ch>:
>> ... 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)
>> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> Due to my comments on patch 3, there's a possibility you may need to
> rebase this patch.
>
> My only optional bikeshed is to print port_clock inside
> intel_dump_pipe_config. If you rebase, you may consider doing it :)
>
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6)
>
>> ---
>>  drivers/gpu/drm/i915/intel_ddi.c     |  3 ++-
>>  drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++++---------------
>>  drivers/gpu/drm/i915/intel_dp.c      | 18 +++++++-----------
>>  drivers/gpu/drm/i915/intel_drv.h     | 13 +++++++------
>>  drivers/gpu/drm/i915/intel_hdmi.c    |  4 +---
>>  drivers/gpu/drm/i915/intel_pm.c      |  5 +----
>>  6 files changed, 35 insertions(+), 40 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index 9649df8..486c46b 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -624,7 +624,7 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
>>                       clock, *p_out, *n2_out, *r2_out);
>>  }
>>
>> -bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
>> +bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
>>  {
>>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>         struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>> @@ -634,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
>>         int type = intel_encoder->type;
>>         enum pipe pipe = intel_crtc->pipe;
>>         uint32_t reg, val;
>> +       int clock = intel_crtc->config.port_clock;
>>
>>         /* TODO: reuse PLLs when possible (compare values) */
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 761254d..103f4e9 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -3992,7 +3992,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>>  {
>>         struct drm_device *dev = intel_crtc->base.dev;
>>         struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>> -       int target_clock, lane, link_bw, fdi_dotclock;
>> +       int lane, link_bw, fdi_dotclock;
>>         bool setup_ok, needs_recompute = false;
>>
>>  retry:
>> @@ -4005,12 +4005,7 @@ retry:
>>          */
>>         link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
>>
>> -       if (pipe_config->pixel_target_clock)
>> -               target_clock = pipe_config->pixel_target_clock;
>> -       else
>> -               target_clock = adjusted_mode->clock;
>> -
>> -       fdi_dotclock = target_clock;
>> +       fdi_dotclock = adjusted_mode->clock;
>
> In the patch you sent Friday, you used adjusted_mode->clock instead of
> fdi_dotclock as the parameter to ironlake_get_lanes_required, you only
> initialized fdi_dotclock before calling intel_link_compute_m_n. This
> doesn't change the code behavior, I'm just pointing in case you
> changed without noticing and prefer the older version.

Completely ignore this paragraph and read the comment inside patch 3.
I forgot to remove the paragraph before sending the email. Sorry.

>
>
>>         if (pipe_config->pixel_multiplier > 1)
>>                 fdi_dotclock /= pipe_config->pixel_multiplier;
>>
>> @@ -4360,8 +4355,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
>>  {
>>         struct drm_device *dev = crtc->base.dev;
>>         struct drm_i915_private *dev_priv = dev->dev_private;
>> -       struct drm_display_mode *adjusted_mode =
>> -               &crtc->config.adjusted_mode;
>>         struct intel_encoder *encoder;
>>         int pipe = crtc->pipe;
>>         u32 dpll, mdiv;
>> @@ -4414,7 +4407,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
>>         vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
>>
>>         /* Set HBR and RBR LPF coefficients */
>> -       if (adjusted_mode->clock == 162000 ||
>> +       if (crtc->config.port_clock == 162000 ||
>>             intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
>>                 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
>>                                  0x005f0021);
>> @@ -4859,7 +4852,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
>>          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
>>          */
>>         limit = intel_limit(crtc, refclk);
>> -       ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
>> +       ok = dev_priv->display.find_dpll(limit, crtc,
>> +                                        intel_crtc->config.port_clock,
>>                                          refclk, NULL, &clock);
>>         if (!ok) {
>>                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
>> @@ -5467,7 +5461,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
>>  }
>>
>>  static bool ironlake_compute_clocks(struct drm_crtc *crtc,
>> -                                   struct drm_display_mode *adjusted_mode,
>>                                     intel_clock_t *clock,
>>                                     bool *has_reduced_clock,
>>                                     intel_clock_t *reduced_clock)
>> @@ -5495,7 +5488,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
>>          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
>>          */
>>         limit = intel_limit(crtc, refclk);
>> -       ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
>> +       ret = dev_priv->display.find_dpll(limit, crtc,
>> +                                         to_intel_crtc(crtc)->config.port_clock,
>>                                           refclk, NULL, clock);
>>         if (!ret)
>>                 return false;
>> @@ -5695,7 +5689,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>>         WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
>>              "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
>>
>> -       ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
>> +       ok = ironlake_compute_clocks(crtc, &clock,
>>                                      &has_reduced_clock, &reduced_clock);
>>         if (!ok) {
>>                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
>> @@ -5898,7 +5892,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>>         WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
>>              num_connectors, pipe_name(pipe));
>>
>> -       if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock))
>> +       if (!intel_ddi_pll_mode_set(crtc))
>>                 return -EINVAL;
>>
>>         /* Ensure that the cursor is valid for the new mode before changing... */
>> @@ -7789,6 +7783,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>>                 goto fail;
>>
>>  encoder_retry:
>> +       /* Ensure the port clock default is reset when retrying. */
>> +       pipe_config->port_clock = 0;
>> +
>>         /* Pass our mode to the connectors and the CRTC to give them a chance to
>>          * adjust it according to limitations or connector properties, and also
>>          * a chance to reject the mode entirely.
>> @@ -7817,6 +7814,11 @@ encoder_retry:
>>                 }
>>         }
>>
>> +       /* Set default port clock if not overwritten by the encoder. Needs to be
>> +        * done afterwards in case the encoder adjusts the mode. */
>> +       if (!pipe_config->port_clock)
>> +               pipe_config->port_clock = pipe_config->adjusted_mode.clock;
>> +
>>         ret = intel_crtc_compute_config(crtc, pipe_config);
>>         if (ret < 0) {
>>                 DRM_DEBUG_KMS("CRTC fixup failed\n");
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index 647cc2b..c92eeeb 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -677,7 +677,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>>         int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
>>         int bpp, mode_rate;
>>         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
>> -       int target_clock, link_avail, link_clock;
>> +       int link_avail, link_clock;
>>
>>         if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
>>                 pipe_config->has_pch_encoder = true;
>> @@ -694,8 +694,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>>                         intel_pch_panel_fitting(intel_crtc, pipe_config,
>>                                                 intel_connector->panel.fitting_mode);
>>         }
>> -       /* We need to take the panel's fixed mode into account. */
>> -       target_clock = adjusted_mode->clock;
>>
>>         if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
>>                 return false;
>> @@ -711,7 +709,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>>                 bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
>>
>>         for (; bpp >= 6*3; bpp -= 2*3) {
>> -               mode_rate = intel_dp_link_required(target_clock, bpp);
>> +               mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
>>
>>                 for (clock = 0; clock <= max_clock; clock++) {
>>                         for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
>> @@ -746,18 +744,17 @@ found:
>>
>>         intel_dp->link_bw = bws[clock];
>>         intel_dp->lane_count = lane_count;
>> -       adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
>>         pipe_config->pipe_bpp = bpp;
>> -       pipe_config->pixel_target_clock = target_clock;
>> +       pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
>>
>>         DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
>>                       intel_dp->link_bw, intel_dp->lane_count,
>> -                     adjusted_mode->clock, bpp);
>> +                     pipe_config->port_clock, bpp);
>>         DRM_DEBUG_KMS("DP link bw required %i available %i\n",
>>                       mode_rate, link_avail);
>>
>>         intel_link_compute_m_n(bpp, lane_count,
>> -                              target_clock, adjusted_mode->clock,
>> +                              adjusted_mode->clock, pipe_config->port_clock,
>>                                &pipe_config->dp_m_n);
>>
>>         intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
>> @@ -788,12 +785,11 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
>>         struct drm_i915_private *dev_priv = dev->dev_private;
>>         u32 dpa_ctl;
>>
>> -       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
>> -                     crtc->config.adjusted_mode.clock);
>> +       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
>>         dpa_ctl = I915_READ(DP_A);
>>         dpa_ctl &= ~DP_PLL_FREQ_MASK;
>>
>> -       if (crtc->config.adjusted_mode.clock == 162000) {
>> +       if (crtc->config.port_clock == 162000) {
>>                 /* For a long time we've carried around a ILK-DevA w/a for the
>>                  * 160MHz clock. If we're really unlucky, it's still required.
>>                  */
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index fdf6303..afda71f 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -243,12 +243,13 @@ struct intel_crtc_config {
>>
>>         int pipe_bpp;
>>         struct intel_link_m_n dp_m_n;
>> -       /**
>> -        * This is currently used by DP and HDMI encoders since those can have a
>> -        * target pixel clock != the port link clock (which is currently stored
>> -        * in adjusted_mode->clock).
>> +
>> +       /*
>> +        * Frequence the dpll for the port should run at. Differs from the
>> +        * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
>>          */
>> -       int pixel_target_clock;
>> +       int port_clock;
>> +
>>         /* Used by SDVO (and if we ever fix it, HDMI). */
>>         unsigned pixel_multiplier;
>>
>> @@ -786,7 +787,7 @@ extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
>>  extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
>>  extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
>>  extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
>> -extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
>> +extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
>>  extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
>>  extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
>>  extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
>> index 8062a92..bc12518 100644
>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>> @@ -835,9 +835,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>>                 desired_bpp = 12*3;
>>
>>                 /* Need to adjust the port link by 1.5x for 12bpc. */
>> -               adjusted_mode->clock = clock_12bpc;
>> -               pipe_config->pixel_target_clock =
>> -                       pipe_config->requested_mode.clock;
>> +               pipe_config->port_clock = clock_12bpc;
>>         } else {
>>                 DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
>>                 desired_bpp = 8*3;
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 49a1887..4126fb1 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -2078,10 +2078,7 @@ static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
>>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>         uint32_t pixel_rate, pfit_size;
>>
>> -       if (intel_crtc->config.pixel_target_clock)
>> -               pixel_rate = intel_crtc->config.pixel_target_clock;
>> -       else
>> -               pixel_rate = intel_crtc->config.adjusted_mode.clock;
>> +       pixel_rate = intel_crtc->config.adjusted_mode.clock;
>>
>>         /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
>>          * adjust the pixel_rate here. */
>> --
>> 1.7.11.7
>>
>
>
>
> --
> Paulo Zanoni
Daniel Vetter June 4, 2013, 12:01 p.m. UTC | #3
On Mon, Jun 03, 2013 at 01:54:40PM -0300, Paulo Zanoni wrote:
> 2013/6/1 Daniel Vetter <daniel.vetter@ffwll.ch>:
> > ... 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)
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Due to my comments on patch 3, there's a possibility you may need to
> rebase this patch.
> 
> My only optional bikeshed is to print port_clock inside
> intel_dump_pipe_config. If you rebase, you may consider doing it :)

Yeah, I think I'll follow up with another pipe config dump patch to add
lots more stuff. Already screamed around because it wasn't as complete as
I've wished for ;-)
-Daniel

> 
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6)
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c     |  3 ++-
> >  drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++++---------------
> >  drivers/gpu/drm/i915/intel_dp.c      | 18 +++++++-----------
> >  drivers/gpu/drm/i915/intel_drv.h     | 13 +++++++------
> >  drivers/gpu/drm/i915/intel_hdmi.c    |  4 +---
> >  drivers/gpu/drm/i915/intel_pm.c      |  5 +----
> >  6 files changed, 35 insertions(+), 40 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 9649df8..486c46b 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -624,7 +624,7 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
> >                       clock, *p_out, *n2_out, *r2_out);
> >  }
> >
> > -bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
> > +bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
> >  {
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >         struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
> > @@ -634,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
> >         int type = intel_encoder->type;
> >         enum pipe pipe = intel_crtc->pipe;
> >         uint32_t reg, val;
> > +       int clock = intel_crtc->config.port_clock;
> >
> >         /* TODO: reuse PLLs when possible (compare values) */
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 761254d..103f4e9 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3992,7 +3992,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> >  {
> >         struct drm_device *dev = intel_crtc->base.dev;
> >         struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> > -       int target_clock, lane, link_bw, fdi_dotclock;
> > +       int lane, link_bw, fdi_dotclock;
> >         bool setup_ok, needs_recompute = false;
> >
> >  retry:
> > @@ -4005,12 +4005,7 @@ retry:
> >          */
> >         link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
> >
> > -       if (pipe_config->pixel_target_clock)
> > -               target_clock = pipe_config->pixel_target_clock;
> > -       else
> > -               target_clock = adjusted_mode->clock;
> > -
> > -       fdi_dotclock = target_clock;
> > +       fdi_dotclock = adjusted_mode->clock;
> 
> In the patch you sent Friday, you used adjusted_mode->clock instead of
> fdi_dotclock as the parameter to ironlake_get_lanes_required, you only
> initialized fdi_dotclock before calling intel_link_compute_m_n. This
> doesn't change the code behavior, I'm just pointing in case you
> changed without noticing and prefer the older version.
> 
> 
> >         if (pipe_config->pixel_multiplier > 1)
> >                 fdi_dotclock /= pipe_config->pixel_multiplier;
> >
> > @@ -4360,8 +4355,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct drm_display_mode *adjusted_mode =
> > -               &crtc->config.adjusted_mode;
> >         struct intel_encoder *encoder;
> >         int pipe = crtc->pipe;
> >         u32 dpll, mdiv;
> > @@ -4414,7 +4407,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
> >         vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
> >
> >         /* Set HBR and RBR LPF coefficients */
> > -       if (adjusted_mode->clock == 162000 ||
> > +       if (crtc->config.port_clock == 162000 ||
> >             intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
> >                 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
> >                                  0x005f0021);
> > @@ -4859,7 +4852,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> >          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> >          */
> >         limit = intel_limit(crtc, refclk);
> > -       ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
> > +       ok = dev_priv->display.find_dpll(limit, crtc,
> > +                                        intel_crtc->config.port_clock,
> >                                          refclk, NULL, &clock);
> >         if (!ok) {
> >                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
> > @@ -5467,7 +5461,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
> >  }
> >
> >  static bool ironlake_compute_clocks(struct drm_crtc *crtc,
> > -                                   struct drm_display_mode *adjusted_mode,
> >                                     intel_clock_t *clock,
> >                                     bool *has_reduced_clock,
> >                                     intel_clock_t *reduced_clock)
> > @@ -5495,7 +5488,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
> >          * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> >          */
> >         limit = intel_limit(crtc, refclk);
> > -       ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
> > +       ret = dev_priv->display.find_dpll(limit, crtc,
> > +                                         to_intel_crtc(crtc)->config.port_clock,
> >                                           refclk, NULL, clock);
> >         if (!ret)
> >                 return false;
> > @@ -5695,7 +5689,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> >         WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
> >              "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
> >
> > -       ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
> > +       ok = ironlake_compute_clocks(crtc, &clock,
> >                                      &has_reduced_clock, &reduced_clock);
> >         if (!ok) {
> >                 DRM_ERROR("Couldn't find PLL settings for mode!\n");
> > @@ -5898,7 +5892,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> >         WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
> >              num_connectors, pipe_name(pipe));
> >
> > -       if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock))
> > +       if (!intel_ddi_pll_mode_set(crtc))
> >                 return -EINVAL;
> >
> >         /* Ensure that the cursor is valid for the new mode before changing... */
> > @@ -7789,6 +7783,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> >                 goto fail;
> >
> >  encoder_retry:
> > +       /* Ensure the port clock default is reset when retrying. */
> > +       pipe_config->port_clock = 0;
> > +
> >         /* Pass our mode to the connectors and the CRTC to give them a chance to
> >          * adjust it according to limitations or connector properties, and also
> >          * a chance to reject the mode entirely.
> > @@ -7817,6 +7814,11 @@ encoder_retry:
> >                 }
> >         }
> >
> > +       /* Set default port clock if not overwritten by the encoder. Needs to be
> > +        * done afterwards in case the encoder adjusts the mode. */
> > +       if (!pipe_config->port_clock)
> > +               pipe_config->port_clock = pipe_config->adjusted_mode.clock;
> > +
> >         ret = intel_crtc_compute_config(crtc, pipe_config);
> >         if (ret < 0) {
> >                 DRM_DEBUG_KMS("CRTC fixup failed\n");
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 647cc2b..c92eeeb 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -677,7 +677,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >         int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
> >         int bpp, mode_rate;
> >         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
> > -       int target_clock, link_avail, link_clock;
> > +       int link_avail, link_clock;
> >
> >         if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
> >                 pipe_config->has_pch_encoder = true;
> > @@ -694,8 +694,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >                         intel_pch_panel_fitting(intel_crtc, pipe_config,
> >                                                 intel_connector->panel.fitting_mode);
> >         }
> > -       /* We need to take the panel's fixed mode into account. */
> > -       target_clock = adjusted_mode->clock;
> >
> >         if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
> >                 return false;
> > @@ -711,7 +709,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >                 bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
> >
> >         for (; bpp >= 6*3; bpp -= 2*3) {
> > -               mode_rate = intel_dp_link_required(target_clock, bpp);
> > +               mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
> >
> >                 for (clock = 0; clock <= max_clock; clock++) {
> >                         for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
> > @@ -746,18 +744,17 @@ found:
> >
> >         intel_dp->link_bw = bws[clock];
> >         intel_dp->lane_count = lane_count;
> > -       adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
> >         pipe_config->pipe_bpp = bpp;
> > -       pipe_config->pixel_target_clock = target_clock;
> > +       pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
> >
> >         DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
> >                       intel_dp->link_bw, intel_dp->lane_count,
> > -                     adjusted_mode->clock, bpp);
> > +                     pipe_config->port_clock, bpp);
> >         DRM_DEBUG_KMS("DP link bw required %i available %i\n",
> >                       mode_rate, link_avail);
> >
> >         intel_link_compute_m_n(bpp, lane_count,
> > -                              target_clock, adjusted_mode->clock,
> > +                              adjusted_mode->clock, pipe_config->port_clock,
> >                                &pipe_config->dp_m_n);
> >
> >         intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
> > @@ -788,12 +785,11 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         u32 dpa_ctl;
> >
> > -       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
> > -                     crtc->config.adjusted_mode.clock);
> > +       DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
> >         dpa_ctl = I915_READ(DP_A);
> >         dpa_ctl &= ~DP_PLL_FREQ_MASK;
> >
> > -       if (crtc->config.adjusted_mode.clock == 162000) {
> > +       if (crtc->config.port_clock == 162000) {
> >                 /* For a long time we've carried around a ILK-DevA w/a for the
> >                  * 160MHz clock. If we're really unlucky, it's still required.
> >                  */
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index fdf6303..afda71f 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -243,12 +243,13 @@ struct intel_crtc_config {
> >
> >         int pipe_bpp;
> >         struct intel_link_m_n dp_m_n;
> > -       /**
> > -        * This is currently used by DP and HDMI encoders since those can have a
> > -        * target pixel clock != the port link clock (which is currently stored
> > -        * in adjusted_mode->clock).
> > +
> > +       /*
> > +        * Frequence the dpll for the port should run at. Differs from the
> > +        * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
> >          */
> > -       int pixel_target_clock;
> > +       int port_clock;
> > +
> >         /* Used by SDVO (and if we ever fix it, HDMI). */
> >         unsigned pixel_multiplier;
> >
> > @@ -786,7 +787,7 @@ extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
> >  extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
> >  extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
> >  extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
> > -extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
> > +extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
> >  extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
> >  extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
> >  extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 8062a92..bc12518 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -835,9 +835,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> >                 desired_bpp = 12*3;
> >
> >                 /* Need to adjust the port link by 1.5x for 12bpc. */
> > -               adjusted_mode->clock = clock_12bpc;
> > -               pipe_config->pixel_target_clock =
> > -                       pipe_config->requested_mode.clock;
> > +               pipe_config->port_clock = clock_12bpc;
> >         } else {
> >                 DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
> >                 desired_bpp = 8*3;
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 49a1887..4126fb1 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2078,10 +2078,7 @@ static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >         uint32_t pixel_rate, pfit_size;
> >
> > -       if (intel_crtc->config.pixel_target_clock)
> > -               pixel_rate = intel_crtc->config.pixel_target_clock;
> > -       else
> > -               pixel_rate = intel_crtc->config.adjusted_mode.clock;
> > +       pixel_rate = intel_crtc->config.adjusted_mode.clock;
> >
> >         /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
> >          * adjust the pixel_rate here. */
> > --
> > 1.7.11.7
> >
> 
> 
> 
> -- 
> Paulo Zanoni
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9649df8..486c46b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -624,7 +624,7 @@  intel_ddi_calculate_wrpll(int clock /* in Hz */,
 		      clock, *p_out, *n2_out, *r2_out);
 }
 
-bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
+bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
@@ -634,6 +634,7 @@  bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
 	int type = intel_encoder->type;
 	enum pipe pipe = intel_crtc->pipe;
 	uint32_t reg, val;
+	int clock = intel_crtc->config.port_clock;
 
 	/* TODO: reuse PLLs when possible (compare values) */
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 761254d..103f4e9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3992,7 +3992,7 @@  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
-	int target_clock, lane, link_bw, fdi_dotclock;
+	int lane, link_bw, fdi_dotclock;
 	bool setup_ok, needs_recompute = false;
 
 retry:
@@ -4005,12 +4005,7 @@  retry:
 	 */
 	link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
 
-	if (pipe_config->pixel_target_clock)
-		target_clock = pipe_config->pixel_target_clock;
-	else
-		target_clock = adjusted_mode->clock;
-
-	fdi_dotclock = target_clock;
+	fdi_dotclock = adjusted_mode->clock;
 	if (pipe_config->pixel_multiplier > 1)
 		fdi_dotclock /= pipe_config->pixel_multiplier;
 
@@ -4360,8 +4355,6 @@  static void vlv_update_pll(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_display_mode *adjusted_mode =
-		&crtc->config.adjusted_mode;
 	struct intel_encoder *encoder;
 	int pipe = crtc->pipe;
 	u32 dpll, mdiv;
@@ -4414,7 +4407,7 @@  static void vlv_update_pll(struct intel_crtc *crtc)
 	vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
 
 	/* Set HBR and RBR LPF coefficients */
-	if (adjusted_mode->clock == 162000 ||
+	if (crtc->config.port_clock == 162000 ||
 	    intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
 		vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
 				 0x005f0021);
@@ -4859,7 +4852,8 @@  static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
+	ok = dev_priv->display.find_dpll(limit, crtc,
+					 intel_crtc->config.port_clock,
 					 refclk, NULL, &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5467,7 +5461,6 @@  static void haswell_set_pipeconf(struct drm_crtc *crtc)
 }
 
 static bool ironlake_compute_clocks(struct drm_crtc *crtc,
-				    struct drm_display_mode *adjusted_mode,
 				    intel_clock_t *clock,
 				    bool *has_reduced_clock,
 				    intel_clock_t *reduced_clock)
@@ -5495,7 +5488,8 @@  static bool ironlake_compute_clocks(struct drm_crtc *crtc,
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock,
+	ret = dev_priv->display.find_dpll(limit, crtc,
+					  to_intel_crtc(crtc)->config.port_clock,
 					  refclk, NULL, clock);
 	if (!ret)
 		return false;
@@ -5695,7 +5689,7 @@  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 	WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
 	     "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
 
-	ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
+	ok = ironlake_compute_clocks(crtc, &clock,
 				     &has_reduced_clock, &reduced_clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5898,7 +5892,7 @@  static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 	WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
 	     num_connectors, pipe_name(pipe));
 
-	if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock))
+	if (!intel_ddi_pll_mode_set(crtc))
 		return -EINVAL;
 
 	/* Ensure that the cursor is valid for the new mode before changing... */
@@ -7789,6 +7783,9 @@  intel_modeset_pipe_config(struct drm_crtc *crtc,
 		goto fail;
 
 encoder_retry:
+	/* Ensure the port clock default is reset when retrying. */
+	pipe_config->port_clock = 0;
+
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -7817,6 +7814,11 @@  encoder_retry:
 		}
 	}
 
+	/* Set default port clock if not overwritten by the encoder. Needs to be
+	 * done afterwards in case the encoder adjusts the mode. */
+	if (!pipe_config->port_clock)
+		pipe_config->port_clock = pipe_config->adjusted_mode.clock;
+
 	ret = intel_crtc_compute_config(crtc, pipe_config);
 	if (ret < 0) {
 		DRM_DEBUG_KMS("CRTC fixup failed\n");
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 647cc2b..c92eeeb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -677,7 +677,7 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
-	int target_clock, link_avail, link_clock;
+	int link_avail, link_clock;
 
 	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
 		pipe_config->has_pch_encoder = true;
@@ -694,8 +694,6 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 			intel_pch_panel_fitting(intel_crtc, pipe_config,
 						intel_connector->panel.fitting_mode);
 	}
-	/* We need to take the panel's fixed mode into account. */
-	target_clock = adjusted_mode->clock;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return false;
@@ -711,7 +709,7 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 		bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
 
 	for (; bpp >= 6*3; bpp -= 2*3) {
-		mode_rate = intel_dp_link_required(target_clock, bpp);
+		mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
 
 		for (clock = 0; clock <= max_clock; clock++) {
 			for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
@@ -746,18 +744,17 @@  found:
 
 	intel_dp->link_bw = bws[clock];
 	intel_dp->lane_count = lane_count;
-	adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
 	pipe_config->pipe_bpp = bpp;
-	pipe_config->pixel_target_clock = target_clock;
+	pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
 
 	DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
 		      intel_dp->link_bw, intel_dp->lane_count,
-		      adjusted_mode->clock, bpp);
+		      pipe_config->port_clock, bpp);
 	DRM_DEBUG_KMS("DP link bw required %i available %i\n",
 		      mode_rate, link_avail);
 
 	intel_link_compute_m_n(bpp, lane_count,
-			       target_clock, adjusted_mode->clock,
+			       adjusted_mode->clock, pipe_config->port_clock,
 			       &pipe_config->dp_m_n);
 
 	intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
@@ -788,12 +785,11 @@  static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
-		      crtc->config.adjusted_mode.clock);
+	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_FREQ_MASK;
 
-	if (crtc->config.adjusted_mode.clock == 162000) {
+	if (crtc->config.port_clock == 162000) {
 		/* For a long time we've carried around a ILK-DevA w/a for the
 		 * 160MHz clock. If we're really unlucky, it's still required.
 		 */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fdf6303..afda71f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -243,12 +243,13 @@  struct intel_crtc_config {
 
 	int pipe_bpp;
 	struct intel_link_m_n dp_m_n;
-	/**
-	 * This is currently used by DP and HDMI encoders since those can have a
-	 * target pixel clock != the port link clock (which is currently stored
-	 * in adjusted_mode->clock).
+
+	/*
+	 * Frequence the dpll for the port should run at. Differs from the
+	 * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
 	 */
-	int pixel_target_clock;
+	int port_clock;
+
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 
@@ -786,7 +787,7 @@  extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
-extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
+extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
 extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
 extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 8062a92..bc12518 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -835,9 +835,7 @@  bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 		desired_bpp = 12*3;
 
 		/* Need to adjust the port link by 1.5x for 12bpc. */
-		adjusted_mode->clock = clock_12bpc;
-		pipe_config->pixel_target_clock =
-			pipe_config->requested_mode.clock;
+		pipe_config->port_clock = clock_12bpc;
 	} else {
 		DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
 		desired_bpp = 8*3;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 49a1887..4126fb1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2078,10 +2078,7 @@  static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	uint32_t pixel_rate, pfit_size;
 
-	if (intel_crtc->config.pixel_target_clock)
-		pixel_rate = intel_crtc->config.pixel_target_clock;
-	else
-		pixel_rate = intel_crtc->config.adjusted_mode.clock;
+	pixel_rate = intel_crtc->config.adjusted_mode.clock;
 
 	/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
 	 * adjust the pixel_rate here. */