Op 03-03-16 om 14:40 schreef Ander Conselvan De Oliveira:
> On Thu, 2016-03-03 at 14:33 +0100, Maarten Lankhorst wrote:
>> Op 29-02-16 om 10:08 schreef Ander Conselvan de Oliveira:
>>> Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
>>> enabled because of it driving CDCLK, it is better to special case that
>>> inside the DPLL code than in the higher level.
>>>
>>> v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander)
>>>
>>> Signed-off-by: Ander Conselvan de Oliveira <
>>> ander.conselvan.de.olive...@intel.com>
>>>
>>> ---
>>> I wasn't able to test this patch. Would really appreciate a tested by
>>> from someone.
>> Unfortunately no skl with eDP here either. :(
>>>  drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
>>>  drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++++++++----
>>> ---
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
>>>  4 files changed, 109 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
>>> b/drivers/gpu/drm/i915/intel_ddi.c
>>> index 3cb9f36..8ef4d2e 100644
>>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>>> @@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
>>>  {
>>>     struct intel_shared_dpll *pll;
>>>  
>>> -   if (intel_encoder->type == INTEL_OUTPUT_EDP)
>>> -           return true;
>>> -
>>>     pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
>>>     if (pll == NULL) {
>>>             DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
>>> @@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder
>>> *encoder,
>>>             uint32_t dpll = pipe_config->ddi_pll_sel;
>>>             uint32_t val;
>>>  
>>> -           /*
>>> -            * DPLL0 is used for eDP and is the only "private" DPLL (as
>>> -            * opposed to shared) on SKL
>>> -            */
>>> -           if (encoder->type == INTEL_OUTPUT_EDP) {
>>> -                   WARN_ON(dpll != SKL_DPLL0);
>>> -
>>> -                   val = I915_READ(DPLL_CTRL1);
>>> -
>>> -                   val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
>>> -                            DPLL_CTRL1_SSC(dpll) |
>>> -                            DPLL_CTRL1_LINK_RATE_MASK(dpll));
>>> -                   val |= pipe_config->dpll_hw_state.ctrl1 << (dpll *
>>> 6);
>>> -
>>> -                   I915_WRITE(DPLL_CTRL1, val);
>>> -                   POSTING_READ(DPLL_CTRL1);
>>> -           }
>>> -
>>>             /* DDI -> PLL mapping  */
>>>             val = I915_READ(DPLL_CTRL2);
>>>  
>>> diff --git a/drivers/gpu/drm/i915/intel_dp.c
>>> b/drivers/gpu/drm/i915/intel_dp.c
>>> index 5be6892..9fef877 100644
>>> --- a/drivers/gpu/drm/i915/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>>> @@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector
>>> *intel_connector)
>>>     intel_connector_unregister(intel_connector);
>>>  }
>>>  
>>> -static void
>>> -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
>>> -{
>>> -   u32 ctrl1;
>>> -
>>> -   memset(&pipe_config->dpll_hw_state, 0,
>>> -          sizeof(pipe_config->dpll_hw_state));
>>> -
>>> -   pipe_config->ddi_pll_sel = SKL_DPLL0;
>>> -   pipe_config->dpll_hw_state.cfgcr1 = 0;
>>> -   pipe_config->dpll_hw_state.cfgcr2 = 0;
>>> -
>>> -   ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
>>> -   switch (pipe_config->port_clock / 2) {
>>> -   case 81000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -   case 135000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -   case 270000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -   case 162000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -   /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
>>> -   results in CDCLK change. Need to handle the change of CDCLK by
>>> -   disabling pipes and re-enabling them */
>>> -   case 108000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -   case 216000:
>>> -           ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
>>> -                                         SKL_DPLL0);
>>> -           break;
>>> -
>>> -   }
>>> -   pipe_config->dpll_hw_state.ctrl1 = ctrl1;
>>> -}
>>> -
>>>  static int
>>>  intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
>>>  {
>>> @@ -1632,11 +1586,7 @@ found:
>>>                             &pipe_config->dp_m2_n2);
>>>     }
>>>  
>>> -   if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
>>> -           skl_edp_set_pll_config(pipe_config);
>>> -   else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
>>> -           /* handled in ddi */;
>>> -   else
>>> +   if (!HAS_DDI(dev))
>>>             intel_dp_set_clock(encoder, pipe_config);
>>>  
>>>     return true;
>>> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> index d371680..6ec7836 100644
>>> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> @@ -785,7 +785,12 @@ struct skl_dpll_regs {
>>>  };
>>>  
>>>  /* this array is indexed by the *shared* pll id */
>>> -static const struct skl_dpll_regs skl_dpll_regs[3] = {
>>> +static const struct skl_dpll_regs skl_dpll_regs[4] = {
>>> +   {
>>> +           /* DPLL 0 */
>>> +           .ctl = LCPLL1_CTL,
>>> +           /* DPLL 0 doesn't support HDMI mode */
>>> +   },
>>>     {
>>>             /* DPLL 1 */
>>>             .ctl = LCPLL2_CTL,
>>> @@ -806,24 +811,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
>>>     },
>>>  };
>>>  
>>> -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>>> -                          struct intel_shared_dpll *pll)
>>> +static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
>>> +                               struct intel_shared_dpll *pll)
>>>  {
>>>     uint32_t val;
>>> -   unsigned int dpll;
>>> -   const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> -
>>> -   /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
>>> */
>>> -   dpll = pll->id + 1;
>>>  
>>>     val = I915_READ(DPLL_CTRL1);
>>>  
>>> -   val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
>>> -            DPLL_CTRL1_LINK_RATE_MASK(dpll));
>>> -   val |= pll->config.hw_state.ctrl1 << (dpll * 6);
>>> +   val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
>>> +            DPLL_CTRL1_LINK_RATE_MASK(pll->id));
>>> +   val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
>>>  
>>>     I915_WRITE(DPLL_CTRL1, val);
>>>     POSTING_READ(DPLL_CTRL1);
>>> +}
>>> +
>>> +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>>> +                          struct intel_shared_dpll *pll)
>>> +{
>>> +   const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> +
>>> +   WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
>>> +
>>> +   skl_ddi_pll_write_ctrl1(dev_priv, pll);
>>>  
>>>     I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
>>>     I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
>>> @@ -834,8 +844,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private
>>> *dev_priv,
>>>     I915_WRITE(regs[pll->id].ctl,
>>>                I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
>>>  
>>> -   if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
>>> -           DRM_ERROR("DPLL %d not locked\n", dpll);
>>> +   if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
>>> +           DRM_ERROR("DPLL %d not locked\n", pll->id);
>>> +}
>>> +
>>> +static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
>>> +                            struct intel_shared_dpll *pll)
>>> +{
>>> +   WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
>>> +   skl_ddi_pll_write_ctrl1(dev_priv, pll);
>>>  }
>>>  
>>>  static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
>>> @@ -849,32 +866,35 @@ static void skl_ddi_pll_disable(struct
>>> drm_i915_private *dev_priv,
>>>     POSTING_READ(regs[pll->id].ctl);
>>>  }
>>>  
>>> +static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
>>> +                             struct intel_shared_dpll *pll)
>>> +{
>>> +}
>>> +
>>>  static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
>>>                                  struct intel_shared_dpll *pll,
>>>                                  struct intel_dpll_hw_state *hw_state)
>>>  {
>>>     uint32_t val;
>>> -   unsigned int dpll;
>>>     const struct skl_dpll_regs *regs = skl_dpll_regs;
>>>     bool ret;
>>>  
>>> +   WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
>>> +
>>>     if (!intel_display_power_get_if_enabled(dev_priv,
>>> POWER_DOMAIN_PLLS))
>>>             return false;
>>>  
>>>     ret = false;
>>>  
>>> -   /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
>>> */
>>> -   dpll = pll->id + 1;
>>> -
>>>     val = I915_READ(regs[pll->id].ctl);
>>>     if (!(val & LCPLL_PLL_ENABLE))
>>>             goto out;
>>>  
>>>     val = I915_READ(DPLL_CTRL1);
>>> -   hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
>>> +   hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
>>>  
>>>     /* avoid reading back stale values if HDMI mode is not enabled */
>>> -   if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
>>> +   if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
>>>             hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
>>>             hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
>>>     }
>>> @@ -886,6 +906,37 @@ out:
>>>     return ret;
>>>  }
>>>  
>>> +static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
>>> +                                  struct intel_shared_dpll *pll,
>>> +                                  struct intel_dpll_hw_state
>>> *hw_state)
>>> +{
>>> +   uint32_t val;
>>> +   const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> +   bool ret;
>>> +
>>> +   WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
>> I'm all for paranoia, but how can this ever happen?
>>
>> Seems pll0 has its own function pointers, so you'd have to do something like
>> pll1->funcs->get_hw_state(pll0);
>>
>> I don't think this will ever happen, so all the paranoia from these functions
>> that are called from the function pointer can be removed.
> I went a bit overboard. Will respin.
>
>>> +   if (!intel_display_power_get_if_enabled(dev_priv,
>>> POWER_DOMAIN_PLLS))
>>> +           return false;
>>> +
>>> +   ret = false;
>>> +
>>> +   /* DPLL0 is always enabled since it drives CDCLK */
>>> +   val = I915_READ(regs[pll->id].ctl);
>>> +   if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
>>> +           goto out;
>>> +
>>> +   val = I915_READ(DPLL_CTRL1);
>>> +   hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
>>> +
>>> +   ret = true;
>>> +
>>> +out:
>>> +   intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
>>> +
>>> +   return ret;
>>> +}
>>> +
>>>  struct skl_wrpll_context {
>>>     uint64_t min_deviation;         /* current minimal deviation
>>> */
>>>     uint64_t central_freq;          /* chosen central freq */
>>> @@ -1165,7 +1216,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct
>>> intel_crtc_state *crtc_state,
>>>                      DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
>>>                      wrpll_params.central_freq;
>>>     } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
>>> -              encoder->type == INTEL_OUTPUT_DP_MST) {
>>> +              encoder->type == INTEL_OUTPUT_DP_MST ||
>>> +              encoder->type == INTEL_OUTPUT_EDP) {
>>>             switch (crtc_state->port_clock / 2) {
>>>             case 81000:
>>>                     ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
>>> @@ -1176,6 +1228,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct
>>> intel_crtc_state *crtc_state,
>>>             case 270000:
>>>                     ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
>>>                     break;
>>> +           /* eDP 1.4 rates */
>>> +           case 162000:
>>> +                   ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
>>> +                   break;
>>> +           /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is
>>> 8640 which
>>> +           results in CDCLK change. Need to handle the change of CDCLK
>>> by
>>> +           disabling pipes and re-enabling them */
>> Sounds like we really need to start supporting cdclk changes on SKL, if it's
>> based on this pll?
>> modeset_calc_cdclk and modeset_commit_cdclk.
> Clint Taylor has been working on it:
>
> https://lists.freedesktop.org/archives/intel-gfx/2016-February/087796.html
>
Ah indeed, that would definitely help with this TBD!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to