Em Qui, 2018-06-28 às 15:35 -0700, Manasi Navare escreveu:
> This sequence is used to setup voltage swing before enabling MG PHY
> DDI
> as well as for changing the voltage during DisplayPort Link training.
> 
> For ICL, there are two types of DDIs. This sequence needs to be used
> for MG PHY DDI which is ports C-F.

And our spec is still incomplete...

Reviewed-by: Paulo Zanoni <paulo.r.zan...@intel.com>

> 
> v6 (From Manasi):
> * Add programming for MG_CLKHUB and MG_TX_DCC as per the
> spec updates
> 
> v5 (from Paulo):
> * Checkpatch.
> v4 (from Paulo):
> * Fix bogus error message
> * Fix copy+paste bugs (missing s/TX1/TX2/ after copy+paste)
> * Use the new mask names
> * Stay under 80 columns
> * Add some blank lines
> v3:
> * Clear the regs before writing (Paulo)
> v2:
> * Rename to MG PHY in the function def (Jani Nikula)
> * Rebase on top of new revision of other patches in series
> 
> Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
> Cc: Jani Nikula <jani.nik...@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.nav...@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 135
> +++++++++++++++++++++++++++++++++++++--
>  1 file changed, 129 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 0319825..c91e96e 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2459,7 +2459,128 @@ static void
> icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
>       I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
>  }
>  
> -static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> u32 level,
> +static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder
> *encoder,
> +                                        int link_clock,
> +                                        u32 level)
> +{
> +     struct drm_i915_private *dev_priv = to_i915(encoder-
> >base.dev);
> +     enum port port = encoder->port;
> +     const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
> +     u32 n_entries, val;
> +     int ln;
> +
> +     n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
> +     ddi_translations = icl_mg_phy_ddi_translations;
> +     /* The table does not have values for level 3 and level 9.
> */
> +     if (level >= n_entries || level == 3 || level == 9) {
> +             DRM_DEBUG_KMS("DDI translation not found for level
> %d. Using %d instead.",
> +                           level, n_entries - 2);
> +             level = n_entries - 2;
> +     }
> +
> +     /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_TX1_LINK_PARAMS(port, ln));
> +             val &= ~CRI_USE_FS32;
> +             I915_WRITE(MG_TX1_LINK_PARAMS(port, ln), val);
> +
> +             val = I915_READ(MG_TX2_LINK_PARAMS(port, ln));
> +             val &= ~CRI_USE_FS32;
> +             I915_WRITE(MG_TX2_LINK_PARAMS(port, ln), val);
> +     }
> +
> +     /* Program MG_TX_SWINGCTRL with values from vswing table */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_TX1_SWINGCTRL(port, ln));
> +             val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
> +             val |= CRI_TXDEEMPH_OVERRIDE_17_12(
> +                     ddi_translations[level].cri_txdeemph_overrid
> e_17_12);
> +             I915_WRITE(MG_TX1_SWINGCTRL(port, ln), val);
> +
> +             val = I915_READ(MG_TX2_SWINGCTRL(port, ln));
> +             val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
> +             val |= CRI_TXDEEMPH_OVERRIDE_17_12(
> +                     ddi_translations[level].cri_txdeemph_overrid
> e_17_12);
> +             I915_WRITE(MG_TX2_SWINGCTRL(port, ln), val);
> +     }
> +
> +     /* Program MG_TX_DRVCTRL with values from vswing table */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_TX1_DRVCTRL(port, ln));
> +             val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
> +                      CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
> +             val |= CRI_TXDEEMPH_OVERRIDE_5_0(
> +                     ddi_translations[level].cri_txdeemph_overrid
> e_5_0) |
> +                     CRI_TXDEEMPH_OVERRIDE_11_6(
> +                             ddi_translations[level].cri_txdeemph
> _override_11_6) |
> +                     CRI_TXDEEMPH_OVERRIDE_EN;
> +             I915_WRITE(MG_TX1_DRVCTRL(port, ln), val);
> +
> +             val = I915_READ(MG_TX2_DRVCTRL(port, ln));
> +             val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
> +                      CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
> +             val |= CRI_TXDEEMPH_OVERRIDE_5_0(
> +                     ddi_translations[level].cri_txdeemph_overrid
> e_5_0) |
> +                     CRI_TXDEEMPH_OVERRIDE_11_6(
> +                             ddi_translations[level].cri_txdeemph
> _override_11_6) |
> +                     CRI_TXDEEMPH_OVERRIDE_EN;
> +             I915_WRITE(MG_TX2_DRVCTRL(port, ln), val);
> +
> +             /* FIXME: Program CRI_LOADGEN_SEL after the spec is
> updated */
> +     }
> +
> +     /*
> +      * Program MG_CLKHUB<LN, port being used> with value from
> frequency table
> +      * In case of Legacy mode on MG PHY, both TX1 and TX2
> enabled so use the
> +      * values from table for which TX1 and TX2 enabled.
> +      */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_CLKHUB(port, ln));
> +             if (link_clock < 300000)
> +                     val |= CFG_LOW_RATE_LKREN_EN;
> +             else
> +                     val &= ~CFG_LOW_RATE_LKREN_EN;
> +             I915_WRITE(MG_CLKHUB(port, ln), val);
> +     }
> +
> +     /* Program the MG_TX_DCC<LN, port being used> based on the
> link frequency */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_TX1_DCC(port, ln));
> +             val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
> +             if (link_clock <= 500000) {
> +                     val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
> +             } else {
> +                     val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
> +                             CFG_AMI_CK_DIV_OVERRIDE_VAL(1);
> +             }
> +             I915_WRITE(MG_TX1_DCC(port, ln), val);
> +
> +             val = I915_READ(MG_TX2_DCC(port, ln));
> +             val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
> +             if (link_clock <= 500000) {
> +                     val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
> +             } else {
> +                     val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
> +                             CFG_AMI_CK_DIV_OVERRIDE_VAL(1);
> +             }
> +             I915_WRITE(MG_TX2_DCC(port, ln), val);
> +     }
> +
> +     /* Program MG_TX_PISO_READLOAD with values from vswing table
> */
> +     for (ln = 0; ln < 2; ln++) {
> +             val = I915_READ(MG_TX1_PISO_READLOAD(port, ln));
> +             val |= CRI_CALCINIT;
> +             I915_WRITE(MG_TX1_PISO_READLOAD(port, ln), val);
> +
> +             val = I915_READ(MG_TX2_PISO_READLOAD(port, ln));
> +             val |= CRI_CALCINIT;
> +             I915_WRITE(MG_TX2_PISO_READLOAD(port, ln), val);
> +     }
> +}
> +
> +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> +                                 int link_clock,
> +                                 u32 level,
>                                   enum intel_output_type type)
>  {
>       enum port port = encoder->port;
> @@ -2467,8 +2588,7 @@ static void icl_ddi_vswing_sequence(struct
> intel_encoder *encoder, u32 level,
>       if (port == PORT_A || port == PORT_B)
>               icl_combo_phy_ddi_vswing_sequence(encoder, level,
> type);
>       else
> -             /* Not Implemented Yet */
> -             WARN_ON(1);
> +             icl_mg_phy_ddi_vswing_sequence(encoder, link_clock,
> level);
>  }
>  
>  static uint32_t translate_signal_level(int signal_levels)
> @@ -2503,7 +2623,8 @@ u32 bxt_signal_levels(struct intel_dp
> *intel_dp)
>       int level = intel_ddi_dp_level(intel_dp);
>  
>       if (IS_ICELAKE(dev_priv))
> -             icl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
> +             icl_ddi_vswing_sequence(encoder, intel_dp-
> >link_rate,
> +                                     level, encoder->type);
>       else if (IS_CANNONLAKE(dev_priv))
>               cnl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
>       else
> @@ -2684,7 +2805,8 @@ static void intel_ddi_pre_enable_dp(struct
> intel_encoder *encoder,
>       intel_display_power_get(dev_priv, dig_port-
> >ddi_io_power_domain);
>  
>       if (IS_ICELAKE(dev_priv))
> -             icl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
> +             icl_ddi_vswing_sequence(encoder, crtc_state-
> >port_clock,
> +                                     level, encoder->type);
>       else if (IS_CANNONLAKE(dev_priv))
>               cnl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
>       else if (IS_GEN9_LP(dev_priv))
> @@ -2719,7 +2841,8 @@ static void intel_ddi_pre_enable_hdmi(struct
> intel_encoder *encoder,
>       intel_display_power_get(dev_priv, dig_port-
> >ddi_io_power_domain);
>  
>       if (IS_ICELAKE(dev_priv))
> -             icl_ddi_vswing_sequence(encoder, level,
> INTEL_OUTPUT_HDMI);
> +             icl_ddi_vswing_sequence(encoder, crtc_state-
> >port_clock,
> +                                     level, INTEL_OUTPUT_HDMI);
>       else if (IS_CANNONLAKE(dev_priv))
>               cnl_ddi_vswing_sequence(encoder, level,
> INTEL_OUTPUT_HDMI);
>       else if (IS_GEN9_LP(dev_priv))
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to