[Intel-gfx] [PATCH 46/66] drm/i915: Move hsw_fdi_link_train into intel_crt.c

Paulo Zanoni przanoni at gmail.com
Thu May 22 22:28:05 CEST 2014


2014-04-24 18:55 GMT-03:00 Daniel Vetter <daniel.vetter at ffwll.ch>:
> The pch encoder case really isn't anything generic on hsw:
> - It's for the vga port only and
> - the vga port does only exist on some hsw platforms.
>
> Imo it helps the generic code flow a lot if we shovel all this into
> hsw specific enable/disable hooks. A bonus is that some of our largest
> files (intel_ddi.c and intel_display.c) will lose a pile of really big
> functions.
>
> Step one is to move the fdi link training code.

I don't think that helps much, since the other fdi link train code is
still at intel_display.c, and even if the only thing that needs fdi
link training on HSW is CRT, fdi link training is really _not_ a CRT
thing. So IMHO we're breaking an abstraction here by putting fdi link
training in CRT code. Also, the fact that HSW+ won't be using
dev_priv->display.fdi_link_train will makes things even more confusing
for people reading our code.

I'd really prefer if we merge
http://patchwork.freedesktop.org/patch/24019/ instead. Or something
based on that.


>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_crt.c     | 136 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_ddi.c     | 134 +---------------------------------
>  drivers/gpu/drm/i915/intel_display.c |   4 --
>  drivers/gpu/drm/i915/intel_drv.h     |   3 +-
>  4 files changed, 140 insertions(+), 137 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index f34d1df88918..2d8f4fe1b450 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -143,6 +143,141 @@ static bool hsw_crt_get_hw_state(struct intel_encoder *encoder,
>         return intel_ddi_get_port_state(encoder, pipe, PORT_E);
>  }
>
> +static const long hsw_ddi_buf_ctl_values[] = {
> +       DDI_BUF_EMP_400MV_0DB_HSW,
> +       DDI_BUF_EMP_400MV_3_5DB_HSW,
> +       DDI_BUF_EMP_400MV_6DB_HSW,
> +       DDI_BUF_EMP_400MV_9_5DB_HSW,
> +       DDI_BUF_EMP_600MV_0DB_HSW,
> +       DDI_BUF_EMP_600MV_3_5DB_HSW,
> +       DDI_BUF_EMP_600MV_6DB_HSW,
> +       DDI_BUF_EMP_800MV_0DB_HSW,
> +       DDI_BUF_EMP_800MV_3_5DB_HSW
> +};
> +
> +static void hsw_fdi_link_train(struct drm_crtc *crtc)
> +{
> +       struct drm_device *dev = crtc->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       u32 temp, i, rx_ctl_val;
> +
> +       /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> +        * mode set "sequence for CRT port" document:
> +        * - TP1 to TP2 time with the default value
> +        * - FDI delay to 90h
> +        *
> +        * WaFDIAutoLinkSetTimingOverrride:hsw
> +        */
> +       I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
> +                                 FDI_RX_PWRDN_LANE0_VAL(2) |
> +                                 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
> +
> +       /* Enable the PCH Receiver FDI PLL */
> +       rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
> +                    FDI_RX_PLL_ENABLE |
> +                    FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
> +       I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> +       POSTING_READ(_FDI_RXA_CTL);
> +       udelay(220);
> +
> +       /* Switch from Rawclk to PCDclk */
> +       rx_ctl_val |= FDI_PCDCLK;
> +       I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> +
> +       /* Configure Port Clock Select */
> +       I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel);
> +
> +       /* Start the training iterating through available voltages and emphasis,
> +        * testing each value twice. */
> +       for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) {
> +               /* Configure DP_TP_CTL with auto-training */
> +               I915_WRITE(DP_TP_CTL(PORT_E),
> +                                       DP_TP_CTL_FDI_AUTOTRAIN |
> +                                       DP_TP_CTL_ENHANCED_FRAME_ENABLE |
> +                                       DP_TP_CTL_LINK_TRAIN_PAT1 |
> +                                       DP_TP_CTL_ENABLE);
> +
> +               /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
> +                * DDI E does not support port reversal, the functionality is
> +                * achieved on the PCH side in FDI_RX_CTL, so no need to set the
> +                * port reversal bit */
> +               I915_WRITE(DDI_BUF_CTL(PORT_E),
> +                          DDI_BUF_CTL_ENABLE |
> +                          ((intel_crtc->config.fdi_lanes - 1) << 1) |
> +                          hsw_ddi_buf_ctl_values[i / 2]);
> +               POSTING_READ(DDI_BUF_CTL(PORT_E));
> +
> +               udelay(600);
> +
> +               /* Program PCH FDI Receiver TU */
> +               I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
> +
> +               /* Enable PCH FDI Receiver with auto-training */
> +               rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
> +               I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> +               POSTING_READ(_FDI_RXA_CTL);
> +
> +               /* Wait for FDI receiver lane calibration */
> +               udelay(30);
> +
> +               /* Unset FDI_RX_MISC pwrdn lanes */
> +               temp = I915_READ(_FDI_RXA_MISC);
> +               temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
> +               I915_WRITE(_FDI_RXA_MISC, temp);
> +               POSTING_READ(_FDI_RXA_MISC);
> +
> +               /* Wait for FDI auto training time */
> +               udelay(5);
> +
> +               temp = I915_READ(DP_TP_STATUS(PORT_E));
> +               if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
> +                       DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
> +
> +                       /* Enable normal pixel sending for FDI */
> +                       I915_WRITE(DP_TP_CTL(PORT_E),
> +                                  DP_TP_CTL_FDI_AUTOTRAIN |
> +                                  DP_TP_CTL_LINK_TRAIN_NORMAL |
> +                                  DP_TP_CTL_ENHANCED_FRAME_ENABLE |
> +                                  DP_TP_CTL_ENABLE);
> +
> +                       return;
> +               }
> +
> +               temp = I915_READ(DDI_BUF_CTL(PORT_E));
> +               temp &= ~DDI_BUF_CTL_ENABLE;
> +               I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
> +               POSTING_READ(DDI_BUF_CTL(PORT_E));
> +
> +               /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
> +               temp = I915_READ(DP_TP_CTL(PORT_E));
> +               temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
> +               temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
> +               I915_WRITE(DP_TP_CTL(PORT_E), temp);
> +               POSTING_READ(DP_TP_CTL(PORT_E));
> +
> +               intel_wait_ddi_buf_idle(dev_priv, PORT_E);
> +
> +               rx_ctl_val &= ~FDI_RX_ENABLE;
> +               I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> +               POSTING_READ(_FDI_RXA_CTL);
> +
> +               /* Reset FDI_RX_MISC pwrdn lanes */
> +               temp = I915_READ(_FDI_RXA_MISC);
> +               temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
> +               temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
> +               I915_WRITE(_FDI_RXA_MISC, temp);
> +               POSTING_READ(_FDI_RXA_MISC);
> +       }
> +
> +       DRM_ERROR("FDI link training failed!\n");
> +}
> +
> +static void hsw_crt_pre_enable(struct intel_encoder *encoder)
> +{
> +       hsw_fdi_link_train(encoder->base.crtc);
> +}
> +
>  /* Note: The caller is required to filter out dpms modes not supported by the
>   * platform. */
>  static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
> @@ -865,6 +1000,7 @@ void intel_crt_init(struct drm_device *dev)
>         if (HAS_DDI(dev)) {
>                 crt->base.get_config = hsw_crt_get_config;
>                 crt->base.get_hw_state = hsw_crt_get_hw_state;
> +               crt->base.pre_enable = hsw_crt_pre_enable;
>         } else {
>                 crt->base.get_config = intel_crt_get_config;
>                 crt->base.get_hw_state = intel_crt_get_hw_state;
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index afa1e87c54cc..13abde3e848f 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -211,20 +211,8 @@ void intel_prepare_ddi(struct drm_device *dev)
>                 intel_prepare_ddi_buffers(dev, port);
>  }
>
> -static const long hsw_ddi_buf_ctl_values[] = {
> -       DDI_BUF_EMP_400MV_0DB_HSW,
> -       DDI_BUF_EMP_400MV_3_5DB_HSW,
> -       DDI_BUF_EMP_400MV_6DB_HSW,
> -       DDI_BUF_EMP_400MV_9_5DB_HSW,
> -       DDI_BUF_EMP_600MV_0DB_HSW,
> -       DDI_BUF_EMP_600MV_3_5DB_HSW,
> -       DDI_BUF_EMP_600MV_6DB_HSW,
> -       DDI_BUF_EMP_800MV_0DB_HSW,
> -       DDI_BUF_EMP_800MV_3_5DB_HSW
> -};
> -
> -static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
> -                                   enum port port)
> +void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
> +                            enum port port)
>  {
>         uint32_t reg = DDI_BUF_CTL(port);
>         int i;
> @@ -246,124 +234,6 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
>   * DDI A (which is used for eDP)
>   */
>
> -void hsw_fdi_link_train(struct drm_crtc *crtc)
> -{
> -       struct drm_device *dev = crtc->dev;
> -       struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -       u32 temp, i, rx_ctl_val;
> -
> -       /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> -        * mode set "sequence for CRT port" document:
> -        * - TP1 to TP2 time with the default value
> -        * - FDI delay to 90h
> -        *
> -        * WaFDIAutoLinkSetTimingOverrride:hsw
> -        */
> -       I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
> -                                 FDI_RX_PWRDN_LANE0_VAL(2) |
> -                                 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
> -
> -       /* Enable the PCH Receiver FDI PLL */
> -       rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
> -                    FDI_RX_PLL_ENABLE |
> -                    FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
> -       I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> -       POSTING_READ(_FDI_RXA_CTL);
> -       udelay(220);
> -
> -       /* Switch from Rawclk to PCDclk */
> -       rx_ctl_val |= FDI_PCDCLK;
> -       I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> -
> -       /* Configure Port Clock Select */
> -       I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel);
> -
> -       /* Start the training iterating through available voltages and emphasis,
> -        * testing each value twice. */
> -       for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) {
> -               /* Configure DP_TP_CTL with auto-training */
> -               I915_WRITE(DP_TP_CTL(PORT_E),
> -                                       DP_TP_CTL_FDI_AUTOTRAIN |
> -                                       DP_TP_CTL_ENHANCED_FRAME_ENABLE |
> -                                       DP_TP_CTL_LINK_TRAIN_PAT1 |
> -                                       DP_TP_CTL_ENABLE);
> -
> -               /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
> -                * DDI E does not support port reversal, the functionality is
> -                * achieved on the PCH side in FDI_RX_CTL, so no need to set the
> -                * port reversal bit */
> -               I915_WRITE(DDI_BUF_CTL(PORT_E),
> -                          DDI_BUF_CTL_ENABLE |
> -                          ((intel_crtc->config.fdi_lanes - 1) << 1) |
> -                          hsw_ddi_buf_ctl_values[i / 2]);
> -               POSTING_READ(DDI_BUF_CTL(PORT_E));
> -
> -               udelay(600);
> -
> -               /* Program PCH FDI Receiver TU */
> -               I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
> -
> -               /* Enable PCH FDI Receiver with auto-training */
> -               rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
> -               I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> -               POSTING_READ(_FDI_RXA_CTL);
> -
> -               /* Wait for FDI receiver lane calibration */
> -               udelay(30);
> -
> -               /* Unset FDI_RX_MISC pwrdn lanes */
> -               temp = I915_READ(_FDI_RXA_MISC);
> -               temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
> -               I915_WRITE(_FDI_RXA_MISC, temp);
> -               POSTING_READ(_FDI_RXA_MISC);
> -
> -               /* Wait for FDI auto training time */
> -               udelay(5);
> -
> -               temp = I915_READ(DP_TP_STATUS(PORT_E));
> -               if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
> -                       DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
> -
> -                       /* Enable normal pixel sending for FDI */
> -                       I915_WRITE(DP_TP_CTL(PORT_E),
> -                                  DP_TP_CTL_FDI_AUTOTRAIN |
> -                                  DP_TP_CTL_LINK_TRAIN_NORMAL |
> -                                  DP_TP_CTL_ENHANCED_FRAME_ENABLE |
> -                                  DP_TP_CTL_ENABLE);
> -
> -                       return;
> -               }
> -
> -               temp = I915_READ(DDI_BUF_CTL(PORT_E));
> -               temp &= ~DDI_BUF_CTL_ENABLE;
> -               I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
> -               POSTING_READ(DDI_BUF_CTL(PORT_E));
> -
> -               /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
> -               temp = I915_READ(DP_TP_CTL(PORT_E));
> -               temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
> -               temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
> -               I915_WRITE(DP_TP_CTL(PORT_E), temp);
> -               POSTING_READ(DP_TP_CTL(PORT_E));
> -
> -               intel_wait_ddi_buf_idle(dev_priv, PORT_E);
> -
> -               rx_ctl_val &= ~FDI_RX_ENABLE;
> -               I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
> -               POSTING_READ(_FDI_RXA_CTL);
> -
> -               /* Reset FDI_RX_MISC pwrdn lanes */
> -               temp = I915_READ(_FDI_RXA_MISC);
> -               temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
> -               temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
> -               I915_WRITE(_FDI_RXA_MISC, temp);
> -               POSTING_READ(_FDI_RXA_MISC);
> -       }
> -
> -       DRM_ERROR("FDI link training failed!\n");
> -}
> -
>  static struct intel_encoder *
>  intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 82ad84eefc8d..80b34ac31d0a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3858,9 +3858,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         if (intel_crtc->config.has_pch_encoder)
>                 intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
>
> -       if (intel_crtc->config.has_pch_encoder)
> -               dev_priv->display.fdi_link_train(crtc);
> -
>         for_each_encoder_on_crtc(dev, crtc, encoder)
>                 if (encoder->pre_enable)
>                         encoder->pre_enable(encoder);
> @@ -11120,7 +11117,6 @@ static void intel_init_display(struct drm_device *dev)
>                         dev_priv->display.modeset_global_resources =
>                                 ivb_modeset_global_resources;
>                 } else if (IS_HASWELL(dev) || IS_GEN8(dev)) {
> -                       dev_priv->display.fdi_link_train = hsw_fdi_link_train;
>                         dev_priv->display.write_eld = haswell_write_eld;
>                         dev_priv->display.modeset_global_resources =
>                                 haswell_modeset_global_resources;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1c093e71db7d..7f1d7f675953 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -668,11 +668,12 @@ void intel_crt_init(struct drm_device *dev);
>
>  /* intel_ddi.c */
>  void intel_prepare_ddi(struct drm_device *dev);
> -void hsw_fdi_link_train(struct drm_crtc *crtc);
>  void intel_ddi_init(struct drm_device *dev, enum port port);
>  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
>  bool intel_ddi_get_port_state(struct intel_encoder *encoder, enum pipe *pipe,
>                               enum port port);
> +void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
> +                            enum port port);
>  int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv);
>  void intel_ddi_pll_init(struct drm_device *dev);
>  void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
> --
> 1.8.1.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni



More information about the Intel-gfx mailing list