LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/display - intel_dpll_mgr.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 1464 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 93 0.0 %
Branches: 0 584 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2006-2016 Intel Corporation
       3                 :            :  *
       4                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
       5                 :            :  * copy of this software and associated documentation files (the "Software"),
       6                 :            :  * to deal in the Software without restriction, including without limitation
       7                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
       9                 :            :  * Software is furnished to do so, subject to the following conditions:
      10                 :            :  *
      11                 :            :  * The above copyright notice and this permission notice (including the next
      12                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      13                 :            :  * Software.
      14                 :            :  *
      15                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18                 :            :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20                 :            :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      21                 :            :  * DEALINGS IN THE SOFTWARE.
      22                 :            :  */
      23                 :            : 
      24                 :            : #include "intel_display_types.h"
      25                 :            : #include "intel_dpio_phy.h"
      26                 :            : #include "intel_dpll_mgr.h"
      27                 :            : 
      28                 :            : /**
      29                 :            :  * DOC: Display PLLs
      30                 :            :  *
      31                 :            :  * Display PLLs used for driving outputs vary by platform. While some have
      32                 :            :  * per-pipe or per-encoder dedicated PLLs, others allow the use of any PLL
      33                 :            :  * from a pool. In the latter scenario, it is possible that multiple pipes
      34                 :            :  * share a PLL if their configurations match.
      35                 :            :  *
      36                 :            :  * This file provides an abstraction over display PLLs. The function
      37                 :            :  * intel_shared_dpll_init() initializes the PLLs for the given platform.  The
      38                 :            :  * users of a PLL are tracked and that tracking is integrated with the atomic
      39                 :            :  * modset interface. During an atomic operation, required PLLs can be reserved
      40                 :            :  * for a given CRTC and encoder configuration by calling
      41                 :            :  * intel_reserve_shared_dplls() and previously reserved PLLs can be released
      42                 :            :  * with intel_release_shared_dplls().
      43                 :            :  * Changes to the users are first staged in the atomic state, and then made
      44                 :            :  * effective by calling intel_shared_dpll_swap_state() during the atomic
      45                 :            :  * commit phase.
      46                 :            :  */
      47                 :            : 
      48                 :            : static void
      49                 :          0 : intel_atomic_duplicate_dpll_state(struct drm_i915_private *dev_priv,
      50                 :            :                                   struct intel_shared_dpll_state *shared_dpll)
      51                 :            : {
      52                 :            :         enum intel_dpll_id i;
      53                 :            : 
      54                 :            :         /* Copy shared dpll state */
      55         [ #  # ]:          0 :         for (i = 0; i < dev_priv->num_shared_dpll; i++) {
      56                 :          0 :                 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
      57                 :            : 
      58                 :          0 :                 shared_dpll[i] = pll->state;
      59                 :            :         }
      60                 :            : }
      61                 :            : 
      62                 :            : static struct intel_shared_dpll_state *
      63                 :          0 : intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
      64                 :            : {
      65                 :          0 :         struct intel_atomic_state *state = to_intel_atomic_state(s);
      66                 :            : 
      67         [ #  # ]:          0 :         WARN_ON(!drm_modeset_is_locked(&s->dev->mode_config.connection_mutex));
      68                 :            : 
      69         [ #  # ]:          0 :         if (!state->dpll_set) {
      70                 :          0 :                 state->dpll_set = true;
      71                 :            : 
      72                 :          0 :                 intel_atomic_duplicate_dpll_state(to_i915(s->dev),
      73                 :          0 :                                                   state->shared_dpll);
      74                 :            :         }
      75                 :            : 
      76                 :          0 :         return state->shared_dpll;
      77                 :            : }
      78                 :            : 
      79                 :            : /**
      80                 :            :  * intel_get_shared_dpll_by_id - get a DPLL given its id
      81                 :            :  * @dev_priv: i915 device instance
      82                 :            :  * @id: pll id
      83                 :            :  *
      84                 :            :  * Returns:
      85                 :            :  * A pointer to the DPLL with @id
      86                 :            :  */
      87                 :            : struct intel_shared_dpll *
      88                 :          0 : intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
      89                 :            :                             enum intel_dpll_id id)
      90                 :            : {
      91                 :          0 :         return &dev_priv->shared_dplls[id];
      92                 :            : }
      93                 :            : 
      94                 :            : /**
      95                 :            :  * intel_get_shared_dpll_id - get the id of a DPLL
      96                 :            :  * @dev_priv: i915 device instance
      97                 :            :  * @pll: the DPLL
      98                 :            :  *
      99                 :            :  * Returns:
     100                 :            :  * The id of @pll
     101                 :            :  */
     102                 :            : enum intel_dpll_id
     103                 :          0 : intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
     104                 :            :                          struct intel_shared_dpll *pll)
     105                 :            : {
     106   [ #  #  #  #  :          0 :         if (WARN_ON(pll < dev_priv->shared_dplls||
             #  #  #  # ]
     107                 :            :                     pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll]))
     108                 :            :                 return -1;
     109                 :            : 
     110                 :          0 :         return (enum intel_dpll_id) (pll - dev_priv->shared_dplls);
     111                 :            : }
     112                 :            : 
     113                 :            : /* For ILK+ */
     114                 :          0 : void assert_shared_dpll(struct drm_i915_private *dev_priv,
     115                 :            :                         struct intel_shared_dpll *pll,
     116                 :            :                         bool state)
     117                 :            : {
     118                 :          0 :         bool cur_state;
     119                 :          0 :         struct intel_dpll_hw_state hw_state;
     120                 :            : 
     121   [ #  #  #  #  :          0 :         if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
                   #  # ]
     122                 :          0 :                 return;
     123                 :            : 
     124                 :          0 :         cur_state = pll->info->funcs->get_hw_state(dev_priv, pll, &hw_state);
     125   [ #  #  #  #  :          0 :         I915_STATE_WARN(cur_state != state,
          #  #  #  #  #  
                      # ]
     126                 :            :              "%s assertion failure (expected %s, current %s)\n",
     127                 :            :                         pll->info->name, onoff(state), onoff(cur_state));
     128                 :            : }
     129                 :            : 
     130                 :            : /**
     131                 :            :  * intel_prepare_shared_dpll - call a dpll's prepare hook
     132                 :            :  * @crtc_state: CRTC, and its state, which has a shared dpll
     133                 :            :  *
     134                 :            :  * This calls the PLL's prepare hook if it has one and if the PLL is not
     135                 :            :  * already enabled. The prepare hook is platform specific.
     136                 :            :  */
     137                 :          0 : void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
     138                 :            : {
     139                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
     140         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     141                 :          0 :         struct intel_shared_dpll *pll = crtc_state->shared_dpll;
     142                 :            : 
     143   [ #  #  #  # ]:          0 :         if (WARN_ON(pll == NULL))
     144                 :            :                 return;
     145                 :            : 
     146                 :          0 :         mutex_lock(&dev_priv->dpll_lock);
     147         [ #  # ]:          0 :         WARN_ON(!pll->state.crtc_mask);
     148         [ #  # ]:          0 :         if (!pll->active_mask) {
     149                 :          0 :                 DRM_DEBUG_DRIVER("setting up %s\n", pll->info->name);
     150         [ #  # ]:          0 :                 WARN_ON(pll->on);
     151                 :          0 :                 assert_shared_dpll_disabled(dev_priv, pll);
     152                 :            : 
     153                 :          0 :                 pll->info->funcs->prepare(dev_priv, pll);
     154                 :            :         }
     155                 :          0 :         mutex_unlock(&dev_priv->dpll_lock);
     156                 :            : }
     157                 :            : 
     158                 :            : /**
     159                 :            :  * intel_enable_shared_dpll - enable a CRTC's shared DPLL
     160                 :            :  * @crtc_state: CRTC, and its state, which has a shared DPLL
     161                 :            :  *
     162                 :            :  * Enable the shared DPLL used by @crtc.
     163                 :            :  */
     164                 :          0 : void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
     165                 :            : {
     166                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
     167         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     168                 :          0 :         struct intel_shared_dpll *pll = crtc_state->shared_dpll;
     169         [ #  # ]:          0 :         unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
     170                 :          0 :         unsigned int old_mask;
     171                 :            : 
     172   [ #  #  #  # ]:          0 :         if (WARN_ON(pll == NULL))
     173                 :            :                 return;
     174                 :            : 
     175                 :          0 :         mutex_lock(&dev_priv->dpll_lock);
     176                 :          0 :         old_mask = pll->active_mask;
     177                 :            : 
     178   [ #  #  #  # ]:          0 :         if (WARN_ON(!(pll->state.crtc_mask & crtc_mask)) ||
     179   [ #  #  #  # ]:          0 :             WARN_ON(pll->active_mask & crtc_mask))
     180                 :          0 :                 goto out;
     181                 :            : 
     182                 :          0 :         pll->active_mask |= crtc_mask;
     183                 :            : 
     184                 :          0 :         DRM_DEBUG_KMS("enable %s (active %x, on? %d) for crtc %d\n",
     185                 :            :                       pll->info->name, pll->active_mask, pll->on,
     186                 :            :                       crtc->base.base.id);
     187                 :            : 
     188         [ #  # ]:          0 :         if (old_mask) {
     189         [ #  # ]:          0 :                 WARN_ON(!pll->on);
     190                 :          0 :                 assert_shared_dpll_enabled(dev_priv, pll);
     191                 :          0 :                 goto out;
     192                 :            :         }
     193         [ #  # ]:          0 :         WARN_ON(pll->on);
     194                 :            : 
     195                 :          0 :         DRM_DEBUG_KMS("enabling %s\n", pll->info->name);
     196                 :          0 :         pll->info->funcs->enable(dev_priv, pll);
     197                 :          0 :         pll->on = true;
     198                 :            : 
     199                 :          0 : out:
     200                 :          0 :         mutex_unlock(&dev_priv->dpll_lock);
     201                 :            : }
     202                 :            : 
     203                 :            : /**
     204                 :            :  * intel_disable_shared_dpll - disable a CRTC's shared DPLL
     205                 :            :  * @crtc_state: CRTC, and its state, which has a shared DPLL
     206                 :            :  *
     207                 :            :  * Disable the shared DPLL used by @crtc.
     208                 :            :  */
     209                 :          0 : void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state)
     210                 :            : {
     211                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
     212         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     213                 :          0 :         struct intel_shared_dpll *pll = crtc_state->shared_dpll;
     214         [ #  # ]:          0 :         unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
     215                 :            : 
     216                 :            :         /* PCH only available on ILK+ */
     217         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 5)
     218                 :            :                 return;
     219                 :            : 
     220         [ #  # ]:          0 :         if (pll == NULL)
     221                 :            :                 return;
     222                 :            : 
     223                 :          0 :         mutex_lock(&dev_priv->dpll_lock);
     224   [ #  #  #  # ]:          0 :         if (WARN_ON(!(pll->active_mask & crtc_mask)))
     225                 :          0 :                 goto out;
     226                 :            : 
     227                 :          0 :         DRM_DEBUG_KMS("disable %s (active %x, on? %d) for crtc %d\n",
     228                 :            :                       pll->info->name, pll->active_mask, pll->on,
     229                 :            :                       crtc->base.base.id);
     230                 :            : 
     231                 :          0 :         assert_shared_dpll_enabled(dev_priv, pll);
     232         [ #  # ]:          0 :         WARN_ON(!pll->on);
     233                 :            : 
     234                 :          0 :         pll->active_mask &= ~crtc_mask;
     235         [ #  # ]:          0 :         if (pll->active_mask)
     236                 :          0 :                 goto out;
     237                 :            : 
     238                 :          0 :         DRM_DEBUG_KMS("disabling %s\n", pll->info->name);
     239                 :          0 :         pll->info->funcs->disable(dev_priv, pll);
     240                 :          0 :         pll->on = false;
     241                 :            : 
     242                 :          0 : out:
     243                 :          0 :         mutex_unlock(&dev_priv->dpll_lock);
     244                 :            : }
     245                 :            : 
     246                 :            : static struct intel_shared_dpll *
     247                 :          0 : intel_find_shared_dpll(struct intel_atomic_state *state,
     248                 :            :                        const struct intel_crtc *crtc,
     249                 :            :                        const struct intel_dpll_hw_state *pll_state,
     250                 :            :                        unsigned long dpll_mask)
     251                 :            : {
     252                 :          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     253                 :          0 :         struct intel_shared_dpll *pll, *unused_pll = NULL;
     254                 :          0 :         struct intel_shared_dpll_state *shared_dpll;
     255                 :          0 :         enum intel_dpll_id i;
     256                 :            : 
     257                 :          0 :         shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
     258                 :            : 
     259         [ #  # ]:          0 :         WARN_ON(dpll_mask & ~(BIT(I915_NUM_PLLS) - 1));
     260                 :            : 
     261         [ #  # ]:          0 :         for_each_set_bit(i, &dpll_mask, I915_NUM_PLLS) {
     262                 :          0 :                 pll = &dev_priv->shared_dplls[i];
     263                 :            : 
     264                 :            :                 /* Only want to check enabled timings first */
     265         [ #  # ]:          0 :                 if (shared_dpll[i].crtc_mask == 0) {
     266         [ #  # ]:          0 :                         if (!unused_pll)
     267                 :          0 :                                 unused_pll = pll;
     268                 :          0 :                         continue;
     269                 :            :                 }
     270                 :            : 
     271                 :          0 :                 if (memcmp(pll_state,
     272         [ #  # ]:          0 :                            &shared_dpll[i].hw_state,
     273                 :            :                            sizeof(*pll_state)) == 0) {
     274                 :          0 :                         DRM_DEBUG_KMS("[CRTC:%d:%s] sharing existing %s (crtc mask 0x%08x, active %x)\n",
     275                 :            :                                       crtc->base.base.id, crtc->base.name,
     276                 :            :                                       pll->info->name,
     277                 :            :                                       shared_dpll[i].crtc_mask,
     278                 :            :                                       pll->active_mask);
     279                 :          0 :                         return pll;
     280                 :            :                 }
     281                 :            :         }
     282                 :            : 
     283                 :            :         /* Ok no matching timings, maybe there's a free one? */
     284         [ #  # ]:          0 :         if (unused_pll) {
     285                 :          0 :                 DRM_DEBUG_KMS("[CRTC:%d:%s] allocated %s\n",
     286                 :            :                               crtc->base.base.id, crtc->base.name,
     287                 :            :                               unused_pll->info->name);
     288                 :          0 :                 return unused_pll;
     289                 :            :         }
     290                 :            : 
     291                 :            :         return NULL;
     292                 :            : }
     293                 :            : 
     294                 :            : static void
     295                 :            : intel_reference_shared_dpll(struct intel_atomic_state *state,
     296                 :            :                             const struct intel_crtc *crtc,
     297                 :            :                             const struct intel_shared_dpll *pll,
     298                 :            :                             const struct intel_dpll_hw_state *pll_state)
     299                 :            : {
     300                 :            :         struct intel_shared_dpll_state *shared_dpll;
     301                 :            :         const enum intel_dpll_id id = pll->info->id;
     302                 :            : 
     303                 :            :         shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
     304                 :            : 
     305                 :            :         if (shared_dpll[id].crtc_mask == 0)
     306                 :            :                 shared_dpll[id].hw_state = *pll_state;
     307                 :            : 
     308                 :            :         DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->info->name,
     309                 :            :                          pipe_name(crtc->pipe));
     310                 :            : 
     311                 :            :         shared_dpll[id].crtc_mask |= 1 << crtc->pipe;
     312                 :            : }
     313                 :            : 
     314                 :            : static void intel_unreference_shared_dpll(struct intel_atomic_state *state,
     315                 :            :                                           const struct intel_crtc *crtc,
     316                 :            :                                           const struct intel_shared_dpll *pll)
     317                 :            : {
     318                 :            :         struct intel_shared_dpll_state *shared_dpll;
     319                 :            : 
     320                 :            :         shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
     321                 :            :         shared_dpll[pll->info->id].crtc_mask &= ~(1 << crtc->pipe);
     322                 :            : }
     323                 :            : 
     324                 :          0 : static void intel_put_dpll(struct intel_atomic_state *state,
     325                 :            :                            struct intel_crtc *crtc)
     326                 :            : {
     327         [ #  # ]:          0 :         const struct intel_crtc_state *old_crtc_state =
     328                 :            :                 intel_atomic_get_old_crtc_state(state, crtc);
     329         [ #  # ]:          0 :         struct intel_crtc_state *new_crtc_state =
     330                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
     331                 :            : 
     332                 :          0 :         new_crtc_state->shared_dpll = NULL;
     333                 :            : 
     334         [ #  # ]:          0 :         if (!old_crtc_state->shared_dpll)
     335                 :            :                 return;
     336                 :            : 
     337                 :          0 :         intel_unreference_shared_dpll(state, crtc, old_crtc_state->shared_dpll);
     338                 :            : }
     339                 :            : 
     340                 :            : /**
     341                 :            :  * intel_shared_dpll_swap_state - make atomic DPLL configuration effective
     342                 :            :  * @state: atomic state
     343                 :            :  *
     344                 :            :  * This is the dpll version of drm_atomic_helper_swap_state() since the
     345                 :            :  * helper does not handle driver-specific global state.
     346                 :            :  *
     347                 :            :  * For consistency with atomic helpers this function does a complete swap,
     348                 :            :  * i.e. it also puts the current state into @state, even though there is no
     349                 :            :  * need for that at this moment.
     350                 :            :  */
     351                 :          0 : void intel_shared_dpll_swap_state(struct intel_atomic_state *state)
     352                 :            : {
     353         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
     354                 :          0 :         struct intel_shared_dpll_state *shared_dpll = state->shared_dpll;
     355                 :          0 :         enum intel_dpll_id i;
     356                 :            : 
     357         [ #  # ]:          0 :         if (!state->dpll_set)
     358                 :            :                 return;
     359                 :            : 
     360         [ #  # ]:          0 :         for (i = 0; i < dev_priv->num_shared_dpll; i++) {
     361                 :          0 :                 struct intel_shared_dpll *pll =
     362                 :            :                         &dev_priv->shared_dplls[i];
     363                 :            : 
     364                 :          0 :                 swap(pll->state, shared_dpll[i]);
     365                 :            :         }
     366                 :            : }
     367                 :            : 
     368                 :          0 : static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
     369                 :            :                                       struct intel_shared_dpll *pll,
     370                 :            :                                       struct intel_dpll_hw_state *hw_state)
     371                 :            : {
     372                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     373                 :          0 :         intel_wakeref_t wakeref;
     374                 :          0 :         u32 val;
     375                 :            : 
     376                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
     377                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
     378         [ #  # ]:          0 :         if (!wakeref)
     379                 :            :                 return false;
     380                 :            : 
     381         [ #  # ]:          0 :         val = I915_READ(PCH_DPLL(id));
     382                 :          0 :         hw_state->dpll = val;
     383         [ #  # ]:          0 :         hw_state->fp0 = I915_READ(PCH_FP0(id));
     384         [ #  # ]:          0 :         hw_state->fp1 = I915_READ(PCH_FP1(id));
     385                 :            : 
     386                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
     387                 :            : 
     388                 :          0 :         return val & DPLL_VCO_ENABLE;
     389                 :            : }
     390                 :            : 
     391                 :          0 : static void ibx_pch_dpll_prepare(struct drm_i915_private *dev_priv,
     392                 :            :                                  struct intel_shared_dpll *pll)
     393                 :            : {
     394                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     395                 :            : 
     396         [ #  # ]:          0 :         I915_WRITE(PCH_FP0(id), pll->state.hw_state.fp0);
     397         [ #  # ]:          0 :         I915_WRITE(PCH_FP1(id), pll->state.hw_state.fp1);
     398                 :          0 : }
     399                 :            : 
     400                 :          0 : static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
     401                 :            : {
     402                 :          0 :         u32 val;
     403                 :          0 :         bool enabled;
     404                 :            : 
     405   [ #  #  #  #  :          0 :         I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
                   #  # ]
     406                 :            : 
     407                 :          0 :         val = I915_READ(PCH_DREF_CONTROL);
     408                 :          0 :         enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
     409                 :            :                             DREF_SUPERSPREAD_SOURCE_MASK));
     410   [ #  #  #  #  :          0 :         I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
                   #  # ]
     411                 :          0 : }
     412                 :            : 
     413                 :          0 : static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
     414                 :            :                                 struct intel_shared_dpll *pll)
     415                 :            : {
     416                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     417                 :            : 
     418                 :            :         /* PCH refclock must be enabled first */
     419                 :          0 :         ibx_assert_pch_refclk_enabled(dev_priv);
     420                 :            : 
     421         [ #  # ]:          0 :         I915_WRITE(PCH_DPLL(id), pll->state.hw_state.dpll);
     422                 :            : 
     423                 :            :         /* Wait for the clocks to stabilize. */
     424                 :          0 :         POSTING_READ(PCH_DPLL(id));
     425                 :          0 :         udelay(150);
     426                 :            : 
     427                 :            :         /* The pixel multiplier can only be updated once the
     428                 :            :          * DPLL is enabled and the clocks are stable.
     429                 :            :          *
     430                 :            :          * So write it again.
     431                 :            :          */
     432                 :          0 :         I915_WRITE(PCH_DPLL(id), pll->state.hw_state.dpll);
     433                 :          0 :         POSTING_READ(PCH_DPLL(id));
     434                 :          0 :         udelay(200);
     435                 :          0 : }
     436                 :            : 
     437                 :          0 : static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
     438                 :            :                                  struct intel_shared_dpll *pll)
     439                 :            : {
     440                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     441                 :            : 
     442         [ #  # ]:          0 :         I915_WRITE(PCH_DPLL(id), 0);
     443                 :          0 :         POSTING_READ(PCH_DPLL(id));
     444                 :          0 :         udelay(200);
     445                 :          0 : }
     446                 :            : 
     447                 :          0 : static bool ibx_get_dpll(struct intel_atomic_state *state,
     448                 :            :                          struct intel_crtc *crtc,
     449                 :            :                          struct intel_encoder *encoder)
     450                 :            : {
     451         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
     452                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
     453         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     454                 :          0 :         struct intel_shared_dpll *pll;
     455                 :          0 :         enum intel_dpll_id i;
     456                 :            : 
     457         [ #  # ]:          0 :         if (HAS_PCH_IBX(dev_priv)) {
     458                 :            :                 /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
     459                 :          0 :                 i = (enum intel_dpll_id) crtc->pipe;
     460                 :          0 :                 pll = &dev_priv->shared_dplls[i];
     461                 :            : 
     462                 :          0 :                 DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n",
     463                 :            :                               crtc->base.base.id, crtc->base.name,
     464                 :            :                               pll->info->name);
     465                 :            :         } else {
     466                 :          0 :                 pll = intel_find_shared_dpll(state, crtc,
     467                 :          0 :                                              &crtc_state->dpll_hw_state,
     468                 :            :                                              BIT(DPLL_ID_PCH_PLL_B) |
     469                 :            :                                              BIT(DPLL_ID_PCH_PLL_A));
     470                 :            :         }
     471                 :            : 
     472         [ #  # ]:          0 :         if (!pll)
     473                 :            :                 return false;
     474                 :            : 
     475                 :            :         /* reference the pll */
     476                 :          0 :         intel_reference_shared_dpll(state, crtc,
     477                 :          0 :                                     pll, &crtc_state->dpll_hw_state);
     478                 :            : 
     479                 :          0 :         crtc_state->shared_dpll = pll;
     480                 :            : 
     481                 :          0 :         return true;
     482                 :            : }
     483                 :            : 
     484                 :          0 : static void ibx_dump_hw_state(struct drm_i915_private *dev_priv,
     485                 :            :                               const struct intel_dpll_hw_state *hw_state)
     486                 :            : {
     487                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
     488                 :            :                       "fp0: 0x%x, fp1: 0x%x\n",
     489                 :            :                       hw_state->dpll,
     490                 :            :                       hw_state->dpll_md,
     491                 :            :                       hw_state->fp0,
     492                 :            :                       hw_state->fp1);
     493                 :          0 : }
     494                 :            : 
     495                 :            : static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
     496                 :            :         .prepare = ibx_pch_dpll_prepare,
     497                 :            :         .enable = ibx_pch_dpll_enable,
     498                 :            :         .disable = ibx_pch_dpll_disable,
     499                 :            :         .get_hw_state = ibx_pch_dpll_get_hw_state,
     500                 :            : };
     501                 :            : 
     502                 :          0 : static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
     503                 :            :                                struct intel_shared_dpll *pll)
     504                 :            : {
     505                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     506                 :            : 
     507                 :          0 :         I915_WRITE(WRPLL_CTL(id), pll->state.hw_state.wrpll);
     508                 :          0 :         POSTING_READ(WRPLL_CTL(id));
     509                 :          0 :         udelay(20);
     510                 :          0 : }
     511                 :            : 
     512                 :          0 : static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
     513                 :            :                                 struct intel_shared_dpll *pll)
     514                 :            : {
     515                 :          0 :         I915_WRITE(SPLL_CTL, pll->state.hw_state.spll);
     516                 :          0 :         POSTING_READ(SPLL_CTL);
     517                 :          0 :         udelay(20);
     518                 :          0 : }
     519                 :            : 
     520                 :          0 : static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
     521                 :            :                                   struct intel_shared_dpll *pll)
     522                 :            : {
     523                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     524                 :          0 :         u32 val;
     525                 :            : 
     526                 :          0 :         val = I915_READ(WRPLL_CTL(id));
     527                 :          0 :         I915_WRITE(WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE);
     528                 :          0 :         POSTING_READ(WRPLL_CTL(id));
     529                 :            : 
     530                 :            :         /*
     531                 :            :          * Try to set up the PCH reference clock once all DPLLs
     532                 :            :          * that depend on it have been shut down.
     533                 :            :          */
     534         [ #  # ]:          0 :         if (dev_priv->pch_ssc_use & BIT(id))
     535                 :          0 :                 intel_init_pch_refclk(dev_priv);
     536                 :          0 : }
     537                 :            : 
     538                 :          0 : static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
     539                 :            :                                  struct intel_shared_dpll *pll)
     540                 :            : {
     541                 :          0 :         enum intel_dpll_id id = pll->info->id;
     542                 :          0 :         u32 val;
     543                 :            : 
     544                 :          0 :         val = I915_READ(SPLL_CTL);
     545                 :          0 :         I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
     546                 :          0 :         POSTING_READ(SPLL_CTL);
     547                 :            : 
     548                 :            :         /*
     549                 :            :          * Try to set up the PCH reference clock once all DPLLs
     550                 :            :          * that depend on it have been shut down.
     551                 :            :          */
     552         [ #  # ]:          0 :         if (dev_priv->pch_ssc_use & BIT(id))
     553                 :          0 :                 intel_init_pch_refclk(dev_priv);
     554                 :          0 : }
     555                 :            : 
     556                 :          0 : static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
     557                 :            :                                        struct intel_shared_dpll *pll,
     558                 :            :                                        struct intel_dpll_hw_state *hw_state)
     559                 :            : {
     560                 :          0 :         const enum intel_dpll_id id = pll->info->id;
     561                 :          0 :         intel_wakeref_t wakeref;
     562                 :          0 :         u32 val;
     563                 :            : 
     564                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
     565                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
     566         [ #  # ]:          0 :         if (!wakeref)
     567                 :            :                 return false;
     568                 :            : 
     569                 :          0 :         val = I915_READ(WRPLL_CTL(id));
     570                 :          0 :         hw_state->wrpll = val;
     571                 :            : 
     572                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
     573                 :            : 
     574                 :          0 :         return val & WRPLL_PLL_ENABLE;
     575                 :            : }
     576                 :            : 
     577                 :          0 : static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
     578                 :            :                                       struct intel_shared_dpll *pll,
     579                 :            :                                       struct intel_dpll_hw_state *hw_state)
     580                 :            : {
     581                 :          0 :         intel_wakeref_t wakeref;
     582                 :          0 :         u32 val;
     583                 :            : 
     584                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
     585                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
     586         [ #  # ]:          0 :         if (!wakeref)
     587                 :            :                 return false;
     588                 :            : 
     589                 :          0 :         val = I915_READ(SPLL_CTL);
     590                 :          0 :         hw_state->spll = val;
     591                 :            : 
     592                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
     593                 :            : 
     594                 :          0 :         return val & SPLL_PLL_ENABLE;
     595                 :            : }
     596                 :            : 
     597                 :            : #define LC_FREQ 2700
     598                 :            : #define LC_FREQ_2K U64_C(LC_FREQ * 2000)
     599                 :            : 
     600                 :            : #define P_MIN 2
     601                 :            : #define P_MAX 64
     602                 :            : #define P_INC 2
     603                 :            : 
     604                 :            : /* Constraints for PLL good behavior */
     605                 :            : #define REF_MIN 48
     606                 :            : #define REF_MAX 400
     607                 :            : #define VCO_MIN 2400
     608                 :            : #define VCO_MAX 4800
     609                 :            : 
     610                 :            : struct hsw_wrpll_rnp {
     611                 :            :         unsigned p, n2, r2;
     612                 :            : };
     613                 :            : 
     614                 :          0 : static unsigned hsw_wrpll_get_budget_for_freq(int clock)
     615                 :            : {
     616                 :          0 :         unsigned budget;
     617                 :            : 
     618   [ #  #  #  #  :          0 :         switch (clock) {
                   #  # ]
     619                 :            :         case 25175000:
     620                 :            :         case 25200000:
     621                 :            :         case 27000000:
     622                 :            :         case 27027000:
     623                 :            :         case 37762500:
     624                 :            :         case 37800000:
     625                 :            :         case 40500000:
     626                 :            :         case 40541000:
     627                 :            :         case 54000000:
     628                 :            :         case 54054000:
     629                 :            :         case 59341000:
     630                 :            :         case 59400000:
     631                 :            :         case 72000000:
     632                 :            :         case 74176000:
     633                 :            :         case 74250000:
     634                 :            :         case 81000000:
     635                 :            :         case 81081000:
     636                 :            :         case 89012000:
     637                 :            :         case 89100000:
     638                 :            :         case 108000000:
     639                 :            :         case 108108000:
     640                 :            :         case 111264000:
     641                 :            :         case 111375000:
     642                 :            :         case 148352000:
     643                 :            :         case 148500000:
     644                 :            :         case 162000000:
     645                 :            :         case 162162000:
     646                 :            :         case 222525000:
     647                 :            :         case 222750000:
     648                 :            :         case 296703000:
     649                 :            :         case 297000000:
     650                 :            :                 budget = 0;
     651                 :            :                 break;
     652                 :          0 :         case 233500000:
     653                 :            :         case 245250000:
     654                 :            :         case 247750000:
     655                 :            :         case 253250000:
     656                 :            :         case 298000000:
     657                 :          0 :                 budget = 1500;
     658                 :          0 :                 break;
     659                 :          0 :         case 169128000:
     660                 :            :         case 169500000:
     661                 :            :         case 179500000:
     662                 :            :         case 202000000:
     663                 :          0 :                 budget = 2000;
     664                 :          0 :                 break;
     665                 :          0 :         case 256250000:
     666                 :            :         case 262500000:
     667                 :            :         case 270000000:
     668                 :            :         case 272500000:
     669                 :            :         case 273750000:
     670                 :            :         case 280750000:
     671                 :            :         case 281250000:
     672                 :            :         case 286000000:
     673                 :            :         case 291750000:
     674                 :          0 :                 budget = 4000;
     675                 :          0 :                 break;
     676                 :          0 :         case 267250000:
     677                 :            :         case 268500000:
     678                 :          0 :                 budget = 5000;
     679                 :          0 :                 break;
     680                 :          0 :         default:
     681                 :          0 :                 budget = 1000;
     682                 :          0 :                 break;
     683                 :            :         }
     684                 :            : 
     685                 :          0 :         return budget;
     686                 :            : }
     687                 :            : 
     688                 :          0 : static void hsw_wrpll_update_rnp(u64 freq2k, unsigned int budget,
     689                 :            :                                  unsigned int r2, unsigned int n2,
     690                 :            :                                  unsigned int p,
     691                 :            :                                  struct hsw_wrpll_rnp *best)
     692                 :            : {
     693                 :          0 :         u64 a, b, c, d, diff, diff_best;
     694                 :            : 
     695                 :            :         /* No best (r,n,p) yet */
     696         [ #  # ]:          0 :         if (best->p == 0) {
     697                 :          0 :                 best->p = p;
     698                 :          0 :                 best->n2 = n2;
     699                 :          0 :                 best->r2 = r2;
     700                 :          0 :                 return;
     701                 :            :         }
     702                 :            : 
     703                 :            :         /*
     704                 :            :          * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
     705                 :            :          * freq2k.
     706                 :            :          *
     707                 :            :          * delta = 1e6 *
     708                 :            :          *         abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
     709                 :            :          *         freq2k;
     710                 :            :          *
     711                 :            :          * and we would like delta <= budget.
     712                 :            :          *
     713                 :            :          * If the discrepancy is above the PPM-based budget, always prefer to
     714                 :            :          * improve upon the previous solution.  However, if you're within the
     715                 :            :          * budget, try to maximize Ref * VCO, that is N / (P * R^2).
     716                 :            :          */
     717                 :          0 :         a = freq2k * budget * p * r2;
     718                 :          0 :         b = freq2k * budget * best->p * best->r2;
     719         [ #  # ]:          0 :         diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
     720         [ #  # ]:          0 :         diff_best = abs_diff(freq2k * best->p * best->r2,
     721                 :            :                              LC_FREQ_2K * best->n2);
     722                 :          0 :         c = 1000000 * diff;
     723                 :          0 :         d = 1000000 * diff_best;
     724                 :            : 
     725         [ #  # ]:          0 :         if (a < c && b < d) {
     726                 :            :                 /* If both are above the budget, pick the closer */
     727         [ #  # ]:          0 :                 if (best->p * best->r2 * diff < p * r2 * diff_best) {
     728                 :          0 :                         best->p = p;
     729                 :          0 :                         best->n2 = n2;
     730                 :          0 :                         best->r2 = r2;
     731                 :            :                 }
     732         [ #  # ]:          0 :         } else if (a >= c && b < d) {
     733                 :            :                 /* If A is below the threshold but B is above it?  Update. */
     734                 :          0 :                 best->p = p;
     735                 :          0 :                 best->n2 = n2;
     736                 :          0 :                 best->r2 = r2;
     737         [ #  # ]:          0 :         } else if (a >= c && b >= d) {
     738                 :            :                 /* Both are below the limit, so pick the higher n2/(r2*r2) */
     739         [ #  # ]:          0 :                 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
     740                 :          0 :                         best->p = p;
     741                 :          0 :                         best->n2 = n2;
     742                 :          0 :                         best->r2 = r2;
     743                 :            :                 }
     744                 :            :         }
     745                 :            :         /* Otherwise a < c && b >= d, do nothing */
     746                 :            : }
     747                 :            : 
     748                 :            : static void
     749                 :          0 : hsw_ddi_calculate_wrpll(int clock /* in Hz */,
     750                 :            :                         unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
     751                 :            : {
     752                 :          0 :         u64 freq2k;
     753                 :          0 :         unsigned p, n2, r2;
     754                 :          0 :         struct hsw_wrpll_rnp best = { 0, 0, 0 };
     755                 :          0 :         unsigned budget;
     756                 :            : 
     757                 :          0 :         freq2k = clock / 100;
     758                 :            : 
     759                 :          0 :         budget = hsw_wrpll_get_budget_for_freq(clock);
     760                 :            : 
     761                 :            :         /* Special case handling for 540 pixel clock: bypass WR PLL entirely
     762                 :            :          * and directly pass the LC PLL to it. */
     763         [ #  # ]:          0 :         if (freq2k == 5400000) {
     764                 :          0 :                 *n2_out = 2;
     765                 :          0 :                 *p_out = 1;
     766                 :          0 :                 *r2_out = 2;
     767                 :          0 :                 return;
     768                 :            :         }
     769                 :            : 
     770                 :            :         /*
     771                 :            :          * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
     772                 :            :          * the WR PLL.
     773                 :            :          *
     774                 :            :          * We want R so that REF_MIN <= Ref <= REF_MAX.
     775                 :            :          * Injecting R2 = 2 * R gives:
     776                 :            :          *   REF_MAX * r2 > LC_FREQ * 2 and
     777                 :            :          *   REF_MIN * r2 < LC_FREQ * 2
     778                 :            :          *
     779                 :            :          * Which means the desired boundaries for r2 are:
     780                 :            :          *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
     781                 :            :          *
     782                 :            :          */
     783                 :          0 :         for (r2 = LC_FREQ * 2 / REF_MAX + 1;
     784         [ #  # ]:          0 :              r2 <= LC_FREQ * 2 / REF_MIN;
     785                 :          0 :              r2++) {
     786                 :            : 
     787                 :            :                 /*
     788                 :            :                  * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
     789                 :            :                  *
     790                 :            :                  * Once again we want VCO_MIN <= VCO <= VCO_MAX.
     791                 :            :                  * Injecting R2 = 2 * R and N2 = 2 * N, we get:
     792                 :            :                  *   VCO_MAX * r2 > n2 * LC_FREQ and
     793                 :            :                  *   VCO_MIN * r2 < n2 * LC_FREQ)
     794                 :            :                  *
     795                 :            :                  * Which means the desired boundaries for n2 are:
     796                 :            :                  * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
     797                 :            :                  */
     798                 :          0 :                 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
     799         [ #  # ]:          0 :                      n2 <= VCO_MAX * r2 / LC_FREQ;
     800                 :          0 :                      n2++) {
     801                 :            : 
     802         [ #  # ]:          0 :                         for (p = P_MIN; p <= P_MAX; p += P_INC)
     803                 :          0 :                                 hsw_wrpll_update_rnp(freq2k, budget,
     804                 :            :                                                      r2, n2, p, &best);
     805                 :            :                 }
     806                 :            :         }
     807                 :            : 
     808                 :          0 :         *n2_out = best.n2;
     809                 :          0 :         *p_out = best.p;
     810                 :          0 :         *r2_out = best.r2;
     811                 :            : }
     812                 :            : 
     813                 :            : static struct intel_shared_dpll *
     814                 :          0 : hsw_ddi_hdmi_get_dpll(struct intel_atomic_state *state,
     815                 :            :                       struct intel_crtc *crtc)
     816                 :            : {
     817                 :          0 :         struct intel_crtc_state *crtc_state =
     818                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
     819                 :          0 :         struct intel_shared_dpll *pll;
     820                 :          0 :         u32 val;
     821                 :          0 :         unsigned int p, n2, r2;
     822                 :            : 
     823                 :          0 :         hsw_ddi_calculate_wrpll(crtc_state->port_clock * 1000, &r2, &n2, &p);
     824                 :            : 
     825                 :          0 :         val = WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
     826                 :          0 :               WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
     827                 :          0 :               WRPLL_DIVIDER_POST(p);
     828                 :            : 
     829                 :          0 :         crtc_state->dpll_hw_state.wrpll = val;
     830                 :            : 
     831                 :          0 :         pll = intel_find_shared_dpll(state, crtc,
     832                 :          0 :                                      &crtc_state->dpll_hw_state,
     833                 :            :                                      BIT(DPLL_ID_WRPLL2) |
     834                 :            :                                      BIT(DPLL_ID_WRPLL1));
     835                 :            : 
     836         [ #  # ]:          0 :         if (!pll)
     837                 :          0 :                 return NULL;
     838                 :            : 
     839                 :            :         return pll;
     840                 :            : }
     841                 :            : 
     842                 :            : static struct intel_shared_dpll *
     843                 :            : hsw_ddi_dp_get_dpll(struct intel_crtc_state *crtc_state)
     844                 :            : {
     845                 :            :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
     846                 :            :         struct intel_shared_dpll *pll;
     847                 :            :         enum intel_dpll_id pll_id;
     848                 :            :         int clock = crtc_state->port_clock;
     849                 :            : 
     850                 :            :         switch (clock / 2) {
     851                 :            :         case 81000:
     852                 :            :                 pll_id = DPLL_ID_LCPLL_810;
     853                 :            :                 break;
     854                 :            :         case 135000:
     855                 :            :                 pll_id = DPLL_ID_LCPLL_1350;
     856                 :            :                 break;
     857                 :            :         case 270000:
     858                 :            :                 pll_id = DPLL_ID_LCPLL_2700;
     859                 :            :                 break;
     860                 :            :         default:
     861                 :            :                 DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
     862                 :            :                 return NULL;
     863                 :            :         }
     864                 :            : 
     865                 :            :         pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
     866                 :            : 
     867                 :            :         if (!pll)
     868                 :            :                 return NULL;
     869                 :            : 
     870                 :            :         return pll;
     871                 :            : }
     872                 :            : 
     873                 :          0 : static bool hsw_get_dpll(struct intel_atomic_state *state,
     874                 :            :                          struct intel_crtc *crtc,
     875                 :            :                          struct intel_encoder *encoder)
     876                 :            : {
     877         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
     878                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
     879                 :          0 :         struct intel_shared_dpll *pll;
     880                 :            : 
     881                 :          0 :         memset(&crtc_state->dpll_hw_state, 0,
     882                 :            :                sizeof(crtc_state->dpll_hw_state));
     883                 :            : 
     884         [ #  # ]:          0 :         if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
     885                 :          0 :                 pll = hsw_ddi_hdmi_get_dpll(state, crtc);
     886         [ #  # ]:          0 :         } else if (intel_crtc_has_dp_encoder(crtc_state)) {
     887                 :          0 :                 pll = hsw_ddi_dp_get_dpll(crtc_state);
     888         [ #  # ]:          0 :         } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
     889   [ #  #  #  # ]:          0 :                 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
     890                 :            :                         return false;
     891                 :            : 
     892                 :          0 :                 crtc_state->dpll_hw_state.spll =
     893                 :            :                         SPLL_PLL_ENABLE | SPLL_FREQ_1350MHz | SPLL_REF_MUXED_SSC;
     894                 :            : 
     895                 :          0 :                 pll = intel_find_shared_dpll(state, crtc,
     896                 :            :                                              &crtc_state->dpll_hw_state,
     897                 :            :                                              BIT(DPLL_ID_SPLL));
     898                 :            :         } else {
     899                 :            :                 return false;
     900                 :            :         }
     901                 :            : 
     902         [ #  # ]:          0 :         if (!pll)
     903                 :            :                 return false;
     904                 :            : 
     905                 :          0 :         intel_reference_shared_dpll(state, crtc,
     906                 :            :                                     pll, &crtc_state->dpll_hw_state);
     907                 :            : 
     908                 :          0 :         crtc_state->shared_dpll = pll;
     909                 :            : 
     910                 :          0 :         return true;
     911                 :            : }
     912                 :            : 
     913                 :          0 : static void hsw_dump_hw_state(struct drm_i915_private *dev_priv,
     914                 :            :                               const struct intel_dpll_hw_state *hw_state)
     915                 :            : {
     916                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
     917                 :            :                       hw_state->wrpll, hw_state->spll);
     918                 :          0 : }
     919                 :            : 
     920                 :            : static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
     921                 :            :         .enable = hsw_ddi_wrpll_enable,
     922                 :            :         .disable = hsw_ddi_wrpll_disable,
     923                 :            :         .get_hw_state = hsw_ddi_wrpll_get_hw_state,
     924                 :            : };
     925                 :            : 
     926                 :            : static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
     927                 :            :         .enable = hsw_ddi_spll_enable,
     928                 :            :         .disable = hsw_ddi_spll_disable,
     929                 :            :         .get_hw_state = hsw_ddi_spll_get_hw_state,
     930                 :            : };
     931                 :            : 
     932                 :          0 : static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
     933                 :            :                                  struct intel_shared_dpll *pll)
     934                 :            : {
     935                 :          0 : }
     936                 :            : 
     937                 :          0 : static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
     938                 :            :                                   struct intel_shared_dpll *pll)
     939                 :            : {
     940                 :          0 : }
     941                 :            : 
     942                 :          0 : static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
     943                 :            :                                        struct intel_shared_dpll *pll,
     944                 :            :                                        struct intel_dpll_hw_state *hw_state)
     945                 :            : {
     946                 :          0 :         return true;
     947                 :            : }
     948                 :            : 
     949                 :            : static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
     950                 :            :         .enable = hsw_ddi_lcpll_enable,
     951                 :            :         .disable = hsw_ddi_lcpll_disable,
     952                 :            :         .get_hw_state = hsw_ddi_lcpll_get_hw_state,
     953                 :            : };
     954                 :            : 
     955                 :            : struct skl_dpll_regs {
     956                 :            :         i915_reg_t ctl, cfgcr1, cfgcr2;
     957                 :            : };
     958                 :            : 
     959                 :            : /* this array is indexed by the *shared* pll id */
     960                 :            : static const struct skl_dpll_regs skl_dpll_regs[4] = {
     961                 :            :         {
     962                 :            :                 /* DPLL 0 */
     963                 :            :                 .ctl = LCPLL1_CTL,
     964                 :            :                 /* DPLL 0 doesn't support HDMI mode */
     965                 :            :         },
     966                 :            :         {
     967                 :            :                 /* DPLL 1 */
     968                 :            :                 .ctl = LCPLL2_CTL,
     969                 :            :                 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
     970                 :            :                 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
     971                 :            :         },
     972                 :            :         {
     973                 :            :                 /* DPLL 2 */
     974                 :            :                 .ctl = WRPLL_CTL(0),
     975                 :            :                 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
     976                 :            :                 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
     977                 :            :         },
     978                 :            :         {
     979                 :            :                 /* DPLL 3 */
     980                 :            :                 .ctl = WRPLL_CTL(1),
     981                 :            :                 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
     982                 :            :                 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
     983                 :            :         },
     984                 :            : };
     985                 :            : 
     986                 :            : static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
     987                 :            :                                     struct intel_shared_dpll *pll)
     988                 :            : {
     989                 :            :         const enum intel_dpll_id id = pll->info->id;
     990                 :            :         u32 val;
     991                 :            : 
     992                 :            :         val = I915_READ(DPLL_CTRL1);
     993                 :            : 
     994                 :            :         val &= ~(DPLL_CTRL1_HDMI_MODE(id) |
     995                 :            :                  DPLL_CTRL1_SSC(id) |
     996                 :            :                  DPLL_CTRL1_LINK_RATE_MASK(id));
     997                 :            :         val |= pll->state.hw_state.ctrl1 << (id * 6);
     998                 :            : 
     999                 :            :         I915_WRITE(DPLL_CTRL1, val);
    1000                 :            :         POSTING_READ(DPLL_CTRL1);
    1001                 :            : }
    1002                 :            : 
    1003                 :          0 : static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
    1004                 :            :                                struct intel_shared_dpll *pll)
    1005                 :            : {
    1006                 :          0 :         const struct skl_dpll_regs *regs = skl_dpll_regs;
    1007                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    1008                 :            : 
    1009                 :          0 :         skl_ddi_pll_write_ctrl1(dev_priv, pll);
    1010                 :            : 
    1011                 :          0 :         I915_WRITE(regs[id].cfgcr1, pll->state.hw_state.cfgcr1);
    1012                 :          0 :         I915_WRITE(regs[id].cfgcr2, pll->state.hw_state.cfgcr2);
    1013                 :          0 :         POSTING_READ(regs[id].cfgcr1);
    1014                 :          0 :         POSTING_READ(regs[id].cfgcr2);
    1015                 :            : 
    1016                 :            :         /* the enable bit is always bit 31 */
    1017                 :          0 :         I915_WRITE(regs[id].ctl,
    1018                 :            :                    I915_READ(regs[id].ctl) | LCPLL_PLL_ENABLE);
    1019                 :            : 
    1020         [ #  # ]:          0 :         if (intel_de_wait_for_set(dev_priv, DPLL_STATUS, DPLL_LOCK(id), 5))
    1021                 :          0 :                 DRM_ERROR("DPLL %d not locked\n", id);
    1022                 :          0 : }
    1023                 :            : 
    1024                 :          0 : static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
    1025                 :            :                                  struct intel_shared_dpll *pll)
    1026                 :            : {
    1027                 :          0 :         skl_ddi_pll_write_ctrl1(dev_priv, pll);
    1028                 :          0 : }
    1029                 :            : 
    1030                 :          0 : static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
    1031                 :            :                                 struct intel_shared_dpll *pll)
    1032                 :            : {
    1033                 :          0 :         const struct skl_dpll_regs *regs = skl_dpll_regs;
    1034                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    1035                 :            : 
    1036                 :            :         /* the enable bit is always bit 31 */
    1037                 :          0 :         I915_WRITE(regs[id].ctl,
    1038                 :            :                    I915_READ(regs[id].ctl) & ~LCPLL_PLL_ENABLE);
    1039                 :          0 :         POSTING_READ(regs[id].ctl);
    1040                 :          0 : }
    1041                 :            : 
    1042                 :          0 : static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
    1043                 :            :                                   struct intel_shared_dpll *pll)
    1044                 :            : {
    1045                 :          0 : }
    1046                 :            : 
    1047                 :          0 : static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
    1048                 :            :                                      struct intel_shared_dpll *pll,
    1049                 :            :                                      struct intel_dpll_hw_state *hw_state)
    1050                 :            : {
    1051                 :          0 :         u32 val;
    1052                 :          0 :         const struct skl_dpll_regs *regs = skl_dpll_regs;
    1053                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    1054                 :          0 :         intel_wakeref_t wakeref;
    1055                 :          0 :         bool ret;
    1056                 :            : 
    1057                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    1058                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    1059         [ #  # ]:          0 :         if (!wakeref)
    1060                 :            :                 return false;
    1061                 :            : 
    1062                 :          0 :         ret = false;
    1063                 :            : 
    1064                 :          0 :         val = I915_READ(regs[id].ctl);
    1065         [ #  # ]:          0 :         if (!(val & LCPLL_PLL_ENABLE))
    1066                 :          0 :                 goto out;
    1067                 :            : 
    1068                 :          0 :         val = I915_READ(DPLL_CTRL1);
    1069                 :          0 :         hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
    1070                 :            : 
    1071                 :            :         /* avoid reading back stale values if HDMI mode is not enabled */
    1072         [ #  # ]:          0 :         if (val & DPLL_CTRL1_HDMI_MODE(id)) {
    1073                 :          0 :                 hw_state->cfgcr1 = I915_READ(regs[id].cfgcr1);
    1074                 :          0 :                 hw_state->cfgcr2 = I915_READ(regs[id].cfgcr2);
    1075                 :            :         }
    1076                 :            :         ret = true;
    1077                 :            : 
    1078                 :          0 : out:
    1079                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    1080                 :            : 
    1081                 :          0 :         return ret;
    1082                 :            : }
    1083                 :            : 
    1084                 :          0 : static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
    1085                 :            :                                        struct intel_shared_dpll *pll,
    1086                 :            :                                        struct intel_dpll_hw_state *hw_state)
    1087                 :            : {
    1088                 :          0 :         const struct skl_dpll_regs *regs = skl_dpll_regs;
    1089                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    1090                 :          0 :         intel_wakeref_t wakeref;
    1091                 :          0 :         u32 val;
    1092                 :          0 :         bool ret;
    1093                 :            : 
    1094                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    1095                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    1096         [ #  # ]:          0 :         if (!wakeref)
    1097                 :            :                 return false;
    1098                 :            : 
    1099                 :          0 :         ret = false;
    1100                 :            : 
    1101                 :            :         /* DPLL0 is always enabled since it drives CDCLK */
    1102                 :          0 :         val = I915_READ(regs[id].ctl);
    1103   [ #  #  #  # ]:          0 :         if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
    1104                 :          0 :                 goto out;
    1105                 :            : 
    1106                 :          0 :         val = I915_READ(DPLL_CTRL1);
    1107                 :          0 :         hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
    1108                 :            : 
    1109                 :          0 :         ret = true;
    1110                 :            : 
    1111                 :          0 : out:
    1112                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    1113                 :            : 
    1114                 :          0 :         return ret;
    1115                 :            : }
    1116                 :            : 
    1117                 :            : struct skl_wrpll_context {
    1118                 :            :         u64 min_deviation;              /* current minimal deviation */
    1119                 :            :         u64 central_freq;               /* chosen central freq */
    1120                 :            :         u64 dco_freq;                   /* chosen dco freq */
    1121                 :            :         unsigned int p;                 /* chosen divider */
    1122                 :            : };
    1123                 :            : 
    1124                 :          0 : static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
    1125                 :            : {
    1126                 :          0 :         memset(ctx, 0, sizeof(*ctx));
    1127                 :            : 
    1128                 :          0 :         ctx->min_deviation = U64_MAX;
    1129                 :            : }
    1130                 :            : 
    1131                 :            : /* DCO freq must be within +1%/-6%  of the DCO central freq */
    1132                 :            : #define SKL_DCO_MAX_PDEVIATION  100
    1133                 :            : #define SKL_DCO_MAX_NDEVIATION  600
    1134                 :            : 
    1135                 :          0 : static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
    1136                 :            :                                   u64 central_freq,
    1137                 :            :                                   u64 dco_freq,
    1138                 :            :                                   unsigned int divider)
    1139                 :            : {
    1140                 :          0 :         u64 deviation;
    1141                 :            : 
    1142   [ #  #  #  # ]:          0 :         deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
    1143                 :            :                               central_freq);
    1144                 :            : 
    1145                 :            :         /* positive deviation */
    1146         [ #  # ]:          0 :         if (dco_freq >= central_freq) {
    1147         [ #  # ]:          0 :                 if (deviation < SKL_DCO_MAX_PDEVIATION &&
    1148         [ #  # ]:          0 :                     deviation < ctx->min_deviation) {
    1149                 :          0 :                         ctx->min_deviation = deviation;
    1150                 :          0 :                         ctx->central_freq = central_freq;
    1151                 :          0 :                         ctx->dco_freq = dco_freq;
    1152                 :          0 :                         ctx->p = divider;
    1153                 :            :                 }
    1154                 :            :         /* negative deviation */
    1155         [ #  # ]:          0 :         } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
    1156         [ #  # ]:          0 :                    deviation < ctx->min_deviation) {
    1157                 :          0 :                 ctx->min_deviation = deviation;
    1158                 :          0 :                 ctx->central_freq = central_freq;
    1159                 :          0 :                 ctx->dco_freq = dco_freq;
    1160                 :          0 :                 ctx->p = divider;
    1161                 :            :         }
    1162                 :          0 : }
    1163                 :            : 
    1164                 :          0 : static void skl_wrpll_get_multipliers(unsigned int p,
    1165                 :            :                                       unsigned int *p0 /* out */,
    1166                 :            :                                       unsigned int *p1 /* out */,
    1167                 :            :                                       unsigned int *p2 /* out */)
    1168                 :            : {
    1169                 :            :         /* even dividers */
    1170         [ #  # ]:          0 :         if (p % 2 == 0) {
    1171                 :          0 :                 unsigned int half = p / 2;
    1172                 :            : 
    1173         [ #  # ]:          0 :                 if (half == 1 || half == 2 || half == 3 || half == 5) {
    1174                 :          0 :                         *p0 = 2;
    1175                 :          0 :                         *p1 = 1;
    1176                 :          0 :                         *p2 = half;
    1177         [ #  # ]:          0 :                 } else if (half % 2 == 0) {
    1178                 :          0 :                         *p0 = 2;
    1179                 :          0 :                         *p1 = half / 2;
    1180                 :          0 :                         *p2 = 2;
    1181         [ #  # ]:          0 :                 } else if (half % 3 == 0) {
    1182                 :          0 :                         *p0 = 3;
    1183                 :          0 :                         *p1 = half / 3;
    1184                 :          0 :                         *p2 = 2;
    1185         [ #  # ]:          0 :                 } else if (half % 7 == 0) {
    1186                 :          0 :                         *p0 = 7;
    1187                 :          0 :                         *p1 = half / 7;
    1188                 :          0 :                         *p2 = 2;
    1189                 :            :                 }
    1190         [ #  # ]:          0 :         } else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
    1191                 :          0 :                 *p0 = 3;
    1192                 :          0 :                 *p1 = 1;
    1193                 :          0 :                 *p2 = p / 3;
    1194         [ #  # ]:          0 :         } else if (p == 5 || p == 7) {
    1195                 :          0 :                 *p0 = p;
    1196                 :          0 :                 *p1 = 1;
    1197                 :          0 :                 *p2 = 1;
    1198         [ #  # ]:          0 :         } else if (p == 15) {
    1199                 :          0 :                 *p0 = 3;
    1200                 :          0 :                 *p1 = 1;
    1201                 :          0 :                 *p2 = 5;
    1202         [ #  # ]:          0 :         } else if (p == 21) {
    1203                 :          0 :                 *p0 = 7;
    1204                 :          0 :                 *p1 = 1;
    1205                 :          0 :                 *p2 = 3;
    1206         [ #  # ]:          0 :         } else if (p == 35) {
    1207                 :          0 :                 *p0 = 7;
    1208                 :          0 :                 *p1 = 1;
    1209                 :          0 :                 *p2 = 5;
    1210                 :            :         }
    1211                 :          0 : }
    1212                 :            : 
    1213                 :            : struct skl_wrpll_params {
    1214                 :            :         u32 dco_fraction;
    1215                 :            :         u32 dco_integer;
    1216                 :            :         u32 qdiv_ratio;
    1217                 :            :         u32 qdiv_mode;
    1218                 :            :         u32 kdiv;
    1219                 :            :         u32 pdiv;
    1220                 :            :         u32 central_freq;
    1221                 :            : };
    1222                 :            : 
    1223                 :          0 : static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
    1224                 :            :                                       u64 afe_clock,
    1225                 :            :                                       u64 central_freq,
    1226                 :            :                                       u32 p0, u32 p1, u32 p2)
    1227                 :            : {
    1228                 :          0 :         u64 dco_freq;
    1229                 :            : 
    1230   [ #  #  #  # ]:          0 :         switch (central_freq) {
    1231                 :          0 :         case 9600000000ULL:
    1232                 :          0 :                 params->central_freq = 0;
    1233                 :          0 :                 break;
    1234                 :          0 :         case 9000000000ULL:
    1235                 :          0 :                 params->central_freq = 1;
    1236                 :          0 :                 break;
    1237                 :          0 :         case 8400000000ULL:
    1238                 :          0 :                 params->central_freq = 3;
    1239                 :            :         }
    1240                 :            : 
    1241   [ #  #  #  #  :          0 :         switch (p0) {
                      # ]
    1242                 :          0 :         case 1:
    1243                 :          0 :                 params->pdiv = 0;
    1244                 :          0 :                 break;
    1245                 :          0 :         case 2:
    1246                 :          0 :                 params->pdiv = 1;
    1247                 :          0 :                 break;
    1248                 :          0 :         case 3:
    1249                 :          0 :                 params->pdiv = 2;
    1250                 :          0 :                 break;
    1251                 :          0 :         case 7:
    1252                 :          0 :                 params->pdiv = 4;
    1253                 :          0 :                 break;
    1254                 :            :         default:
    1255                 :          0 :                 WARN(1, "Incorrect PDiv\n");
    1256                 :            :         }
    1257                 :            : 
    1258   [ #  #  #  #  :          0 :         switch (p2) {
                      # ]
    1259                 :          0 :         case 5:
    1260                 :          0 :                 params->kdiv = 0;
    1261                 :          0 :                 break;
    1262                 :          0 :         case 2:
    1263                 :          0 :                 params->kdiv = 1;
    1264                 :          0 :                 break;
    1265                 :          0 :         case 3:
    1266                 :          0 :                 params->kdiv = 2;
    1267                 :          0 :                 break;
    1268                 :          0 :         case 1:
    1269                 :          0 :                 params->kdiv = 3;
    1270                 :          0 :                 break;
    1271                 :            :         default:
    1272                 :          0 :                 WARN(1, "Incorrect KDiv\n");
    1273                 :            :         }
    1274                 :            : 
    1275                 :          0 :         params->qdiv_ratio = p1;
    1276                 :          0 :         params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
    1277                 :            : 
    1278                 :          0 :         dco_freq = p0 * p1 * p2 * afe_clock;
    1279                 :            : 
    1280                 :            :         /*
    1281                 :            :          * Intermediate values are in Hz.
    1282                 :            :          * Divide by MHz to match bsepc
    1283                 :            :          */
    1284                 :          0 :         params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
    1285                 :          0 :         params->dco_fraction =
    1286                 :          0 :                 div_u64((div_u64(dco_freq, 24) -
    1287                 :          0 :                          params->dco_integer * MHz(1)) * 0x8000, MHz(1));
    1288                 :          0 : }
    1289                 :            : 
    1290                 :            : static bool
    1291                 :          0 : skl_ddi_calculate_wrpll(int clock /* in Hz */,
    1292                 :            :                         struct skl_wrpll_params *wrpll_params)
    1293                 :            : {
    1294                 :          0 :         u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
    1295                 :          0 :         u64 dco_central_freq[3] = { 8400000000ULL,
    1296                 :            :                                     9000000000ULL,
    1297                 :            :                                     9600000000ULL };
    1298                 :          0 :         static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
    1299                 :            :                                              24, 28, 30, 32, 36, 40, 42, 44,
    1300                 :            :                                              48, 52, 54, 56, 60, 64, 66, 68,
    1301                 :            :                                              70, 72, 76, 78, 80, 84, 88, 90,
    1302                 :            :                                              92, 96, 98 };
    1303                 :          0 :         static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
    1304                 :          0 :         static const struct {
    1305                 :            :                 const int *list;
    1306                 :            :                 int n_dividers;
    1307                 :            :         } dividers[] = {
    1308                 :            :                 { even_dividers, ARRAY_SIZE(even_dividers) },
    1309                 :            :                 { odd_dividers, ARRAY_SIZE(odd_dividers) },
    1310                 :            :         };
    1311                 :          0 :         struct skl_wrpll_context ctx;
    1312                 :          0 :         unsigned int dco, d, i;
    1313                 :          0 :         unsigned int p0, p1, p2;
    1314                 :            : 
    1315                 :          0 :         skl_wrpll_context_init(&ctx);
    1316                 :            : 
    1317         [ #  # ]:          0 :         for (d = 0; d < ARRAY_SIZE(dividers); d++) {
    1318         [ #  # ]:          0 :                 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
    1319         [ #  # ]:          0 :                         for (i = 0; i < dividers[d].n_dividers; i++) {
    1320                 :          0 :                                 unsigned int p = dividers[d].list[i];
    1321                 :          0 :                                 u64 dco_freq = p * afe_clock;
    1322                 :            : 
    1323                 :          0 :                                 skl_wrpll_try_divider(&ctx,
    1324                 :            :                                                       dco_central_freq[dco],
    1325                 :            :                                                       dco_freq,
    1326                 :            :                                                       p);
    1327                 :            :                                 /*
    1328                 :            :                                  * Skip the remaining dividers if we're sure to
    1329                 :            :                                  * have found the definitive divider, we can't
    1330                 :            :                                  * improve a 0 deviation.
    1331                 :            :                                  */
    1332         [ #  # ]:          0 :                                 if (ctx.min_deviation == 0)
    1333                 :          0 :                                         goto skip_remaining_dividers;
    1334                 :            :                         }
    1335                 :            :                 }
    1336                 :            : 
    1337                 :          0 : skip_remaining_dividers:
    1338                 :            :                 /*
    1339                 :            :                  * If a solution is found with an even divider, prefer
    1340                 :            :                  * this one.
    1341                 :            :                  */
    1342   [ #  #  #  # ]:          0 :                 if (d == 0 && ctx.p)
    1343                 :            :                         break;
    1344                 :            :         }
    1345                 :            : 
    1346         [ #  # ]:          0 :         if (!ctx.p) {
    1347                 :          0 :                 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
    1348                 :          0 :                 return false;
    1349                 :            :         }
    1350                 :            : 
    1351                 :            :         /*
    1352                 :            :          * gcc incorrectly analyses that these can be used without being
    1353                 :            :          * initialized. To be fair, it's hard to guess.
    1354                 :            :          */
    1355                 :          0 :         p0 = p1 = p2 = 0;
    1356                 :          0 :         skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
    1357                 :          0 :         skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
    1358                 :            :                                   p0, p1, p2);
    1359                 :            : 
    1360                 :          0 :         return true;
    1361                 :            : }
    1362                 :            : 
    1363                 :          0 : static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
    1364                 :            : {
    1365                 :          0 :         u32 ctrl1, cfgcr1, cfgcr2;
    1366                 :          0 :         struct skl_wrpll_params wrpll_params = { 0, };
    1367                 :            : 
    1368                 :            :         /*
    1369                 :            :          * See comment in intel_dpll_hw_state to understand why we always use 0
    1370                 :            :          * as the DPLL id in this function.
    1371                 :            :          */
    1372                 :          0 :         ctrl1 = DPLL_CTRL1_OVERRIDE(0);
    1373                 :            : 
    1374                 :          0 :         ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
    1375                 :            : 
    1376         [ #  # ]:          0 :         if (!skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
    1377                 :            :                                      &wrpll_params))
    1378                 :            :                 return false;
    1379                 :            : 
    1380                 :          0 :         cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
    1381                 :          0 :                 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
    1382                 :          0 :                 wrpll_params.dco_integer;
    1383                 :            : 
    1384                 :          0 :         cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
    1385                 :          0 :                 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
    1386                 :          0 :                 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
    1387                 :          0 :                 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
    1388                 :          0 :                 wrpll_params.central_freq;
    1389                 :            : 
    1390                 :          0 :         memset(&crtc_state->dpll_hw_state, 0,
    1391                 :            :                sizeof(crtc_state->dpll_hw_state));
    1392                 :            : 
    1393                 :          0 :         crtc_state->dpll_hw_state.ctrl1 = ctrl1;
    1394                 :          0 :         crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
    1395                 :          0 :         crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
    1396                 :          0 :         return true;
    1397                 :            : }
    1398                 :            : 
    1399                 :            : static bool
    1400                 :          0 : skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
    1401                 :            : {
    1402                 :          0 :         u32 ctrl1;
    1403                 :            : 
    1404                 :            :         /*
    1405                 :            :          * See comment in intel_dpll_hw_state to understand why we always use 0
    1406                 :            :          * as the DPLL id in this function.
    1407                 :            :          */
    1408                 :          0 :         ctrl1 = DPLL_CTRL1_OVERRIDE(0);
    1409   [ #  #  #  #  :          0 :         switch (crtc_state->port_clock / 2) {
                   #  # ]
    1410                 :          0 :         case 81000:
    1411                 :          0 :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
    1412                 :          0 :                 break;
    1413                 :          0 :         case 135000:
    1414                 :          0 :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
    1415                 :          0 :                 break;
    1416                 :            :         case 270000:
    1417                 :            :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
    1418                 :            :                 break;
    1419                 :            :                 /* eDP 1.4 rates */
    1420                 :          0 :         case 162000:
    1421                 :          0 :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
    1422                 :          0 :                 break;
    1423                 :          0 :         case 108000:
    1424                 :          0 :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
    1425                 :          0 :                 break;
    1426                 :          0 :         case 216000:
    1427                 :          0 :                 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
    1428                 :          0 :                 break;
    1429                 :            :         }
    1430                 :            : 
    1431                 :          0 :         memset(&crtc_state->dpll_hw_state, 0,
    1432                 :            :                sizeof(crtc_state->dpll_hw_state));
    1433                 :            : 
    1434                 :          0 :         crtc_state->dpll_hw_state.ctrl1 = ctrl1;
    1435                 :            : 
    1436                 :          0 :         return true;
    1437                 :            : }
    1438                 :            : 
    1439                 :          0 : static bool skl_get_dpll(struct intel_atomic_state *state,
    1440                 :            :                          struct intel_crtc *crtc,
    1441                 :            :                          struct intel_encoder *encoder)
    1442                 :            : {
    1443         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
    1444                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    1445                 :          0 :         struct intel_shared_dpll *pll;
    1446                 :          0 :         bool bret;
    1447                 :            : 
    1448         [ #  # ]:          0 :         if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
    1449                 :          0 :                 bret = skl_ddi_hdmi_pll_dividers(crtc_state);
    1450         [ #  # ]:          0 :                 if (!bret) {
    1451                 :          0 :                         DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
    1452                 :          0 :                         return false;
    1453                 :            :                 }
    1454         [ #  # ]:          0 :         } else if (intel_crtc_has_dp_encoder(crtc_state)) {
    1455                 :          0 :                 bret = skl_ddi_dp_set_dpll_hw_state(crtc_state);
    1456         [ #  # ]:          0 :                 if (!bret) {
    1457                 :          0 :                         DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
    1458                 :          0 :                         return false;
    1459                 :            :                 }
    1460                 :            :         } else {
    1461                 :            :                 return false;
    1462                 :            :         }
    1463                 :            : 
    1464         [ #  # ]:          0 :         if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
    1465                 :          0 :                 pll = intel_find_shared_dpll(state, crtc,
    1466                 :          0 :                                              &crtc_state->dpll_hw_state,
    1467                 :            :                                              BIT(DPLL_ID_SKL_DPLL0));
    1468                 :            :         else
    1469                 :          0 :                 pll = intel_find_shared_dpll(state, crtc,
    1470                 :          0 :                                              &crtc_state->dpll_hw_state,
    1471                 :            :                                              BIT(DPLL_ID_SKL_DPLL3) |
    1472                 :            :                                              BIT(DPLL_ID_SKL_DPLL2) |
    1473                 :            :                                              BIT(DPLL_ID_SKL_DPLL1));
    1474         [ #  # ]:          0 :         if (!pll)
    1475                 :            :                 return false;
    1476                 :            : 
    1477                 :          0 :         intel_reference_shared_dpll(state, crtc,
    1478                 :          0 :                                     pll, &crtc_state->dpll_hw_state);
    1479                 :            : 
    1480                 :          0 :         crtc_state->shared_dpll = pll;
    1481                 :            : 
    1482                 :          0 :         return true;
    1483                 :            : }
    1484                 :            : 
    1485                 :          0 : static void skl_dump_hw_state(struct drm_i915_private *dev_priv,
    1486                 :            :                               const struct intel_dpll_hw_state *hw_state)
    1487                 :            : {
    1488                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: "
    1489                 :            :                       "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
    1490                 :            :                       hw_state->ctrl1,
    1491                 :            :                       hw_state->cfgcr1,
    1492                 :            :                       hw_state->cfgcr2);
    1493                 :          0 : }
    1494                 :            : 
    1495                 :            : static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
    1496                 :            :         .enable = skl_ddi_pll_enable,
    1497                 :            :         .disable = skl_ddi_pll_disable,
    1498                 :            :         .get_hw_state = skl_ddi_pll_get_hw_state,
    1499                 :            : };
    1500                 :            : 
    1501                 :            : static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
    1502                 :            :         .enable = skl_ddi_dpll0_enable,
    1503                 :            :         .disable = skl_ddi_dpll0_disable,
    1504                 :            :         .get_hw_state = skl_ddi_dpll0_get_hw_state,
    1505                 :            : };
    1506                 :            : 
    1507                 :          0 : static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
    1508                 :            :                                 struct intel_shared_dpll *pll)
    1509                 :            : {
    1510                 :          0 :         u32 temp;
    1511                 :          0 :         enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
    1512                 :          0 :         enum dpio_phy phy;
    1513                 :          0 :         enum dpio_channel ch;
    1514                 :            : 
    1515                 :          0 :         bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
    1516                 :            : 
    1517                 :            :         /* Non-SSC reference */
    1518                 :          0 :         temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1519                 :          0 :         temp |= PORT_PLL_REF_SEL;
    1520                 :          0 :         I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
    1521                 :            : 
    1522         [ #  # ]:          0 :         if (IS_GEMINILAKE(dev_priv)) {
    1523                 :          0 :                 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1524                 :          0 :                 temp |= PORT_PLL_POWER_ENABLE;
    1525                 :          0 :                 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
    1526                 :            : 
    1527   [ #  #  #  #  :          0 :                 if (wait_for_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
                   #  # ]
    1528                 :            :                                  PORT_PLL_POWER_STATE), 200))
    1529                 :          0 :                         DRM_ERROR("Power state not set for PLL:%d\n", port);
    1530                 :            :         }
    1531                 :            : 
    1532                 :            :         /* Disable 10 bit clock */
    1533                 :          0 :         temp = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch));
    1534                 :          0 :         temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
    1535                 :          0 :         I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp);
    1536                 :            : 
    1537                 :            :         /* Write P1 & P2 */
    1538                 :          0 :         temp = I915_READ(BXT_PORT_PLL_EBB_0(phy, ch));
    1539                 :          0 :         temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
    1540                 :          0 :         temp |= pll->state.hw_state.ebb0;
    1541                 :          0 :         I915_WRITE(BXT_PORT_PLL_EBB_0(phy, ch), temp);
    1542                 :            : 
    1543                 :            :         /* Write M2 integer */
    1544                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 0));
    1545                 :          0 :         temp &= ~PORT_PLL_M2_MASK;
    1546                 :          0 :         temp |= pll->state.hw_state.pll0;
    1547                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 0), temp);
    1548                 :            : 
    1549                 :            :         /* Write N */
    1550                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 1));
    1551                 :          0 :         temp &= ~PORT_PLL_N_MASK;
    1552                 :          0 :         temp |= pll->state.hw_state.pll1;
    1553                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 1), temp);
    1554                 :            : 
    1555                 :            :         /* Write M2 fraction */
    1556                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 2));
    1557                 :          0 :         temp &= ~PORT_PLL_M2_FRAC_MASK;
    1558                 :          0 :         temp |= pll->state.hw_state.pll2;
    1559                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 2), temp);
    1560                 :            : 
    1561                 :            :         /* Write M2 fraction enable */
    1562                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 3));
    1563                 :          0 :         temp &= ~PORT_PLL_M2_FRAC_ENABLE;
    1564                 :          0 :         temp |= pll->state.hw_state.pll3;
    1565                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 3), temp);
    1566                 :            : 
    1567                 :            :         /* Write coeff */
    1568                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 6));
    1569                 :          0 :         temp &= ~PORT_PLL_PROP_COEFF_MASK;
    1570                 :          0 :         temp &= ~PORT_PLL_INT_COEFF_MASK;
    1571                 :          0 :         temp &= ~PORT_PLL_GAIN_CTL_MASK;
    1572                 :          0 :         temp |= pll->state.hw_state.pll6;
    1573                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 6), temp);
    1574                 :            : 
    1575                 :            :         /* Write calibration val */
    1576                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 8));
    1577                 :          0 :         temp &= ~PORT_PLL_TARGET_CNT_MASK;
    1578                 :          0 :         temp |= pll->state.hw_state.pll8;
    1579                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 8), temp);
    1580                 :            : 
    1581                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 9));
    1582                 :          0 :         temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
    1583                 :          0 :         temp |= pll->state.hw_state.pll9;
    1584                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 9), temp);
    1585                 :            : 
    1586                 :          0 :         temp = I915_READ(BXT_PORT_PLL(phy, ch, 10));
    1587                 :          0 :         temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
    1588                 :          0 :         temp &= ~PORT_PLL_DCO_AMP_MASK;
    1589                 :          0 :         temp |= pll->state.hw_state.pll10;
    1590                 :          0 :         I915_WRITE(BXT_PORT_PLL(phy, ch, 10), temp);
    1591                 :            : 
    1592                 :            :         /* Recalibrate with new settings */
    1593                 :          0 :         temp = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch));
    1594                 :          0 :         temp |= PORT_PLL_RECALIBRATE;
    1595                 :          0 :         I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp);
    1596                 :          0 :         temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
    1597                 :          0 :         temp |= pll->state.hw_state.ebb4;
    1598                 :          0 :         I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp);
    1599                 :            : 
    1600                 :            :         /* Enable PLL */
    1601                 :          0 :         temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1602                 :          0 :         temp |= PORT_PLL_ENABLE;
    1603                 :          0 :         I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
    1604                 :          0 :         POSTING_READ(BXT_PORT_PLL_ENABLE(port));
    1605                 :            : 
    1606   [ #  #  #  #  :          0 :         if (wait_for_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK),
                   #  # ]
    1607                 :            :                         200))
    1608                 :          0 :                 DRM_ERROR("PLL %d not locked\n", port);
    1609                 :            : 
    1610         [ #  # ]:          0 :         if (IS_GEMINILAKE(dev_priv)) {
    1611                 :          0 :                 temp = I915_READ(BXT_PORT_TX_DW5_LN0(phy, ch));
    1612                 :          0 :                 temp |= DCC_DELAY_RANGE_2;
    1613                 :          0 :                 I915_WRITE(BXT_PORT_TX_DW5_GRP(phy, ch), temp);
    1614                 :            :         }
    1615                 :            : 
    1616                 :            :         /*
    1617                 :            :          * While we write to the group register to program all lanes at once we
    1618                 :            :          * can read only lane registers and we pick lanes 0/1 for that.
    1619                 :            :          */
    1620                 :          0 :         temp = I915_READ(BXT_PORT_PCS_DW12_LN01(phy, ch));
    1621                 :          0 :         temp &= ~LANE_STAGGER_MASK;
    1622                 :          0 :         temp &= ~LANESTAGGER_STRAP_OVRD;
    1623                 :          0 :         temp |= pll->state.hw_state.pcsdw12;
    1624                 :          0 :         I915_WRITE(BXT_PORT_PCS_DW12_GRP(phy, ch), temp);
    1625                 :          0 : }
    1626                 :            : 
    1627                 :          0 : static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
    1628                 :            :                                         struct intel_shared_dpll *pll)
    1629                 :            : {
    1630                 :          0 :         enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
    1631                 :          0 :         u32 temp;
    1632                 :            : 
    1633                 :          0 :         temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1634                 :          0 :         temp &= ~PORT_PLL_ENABLE;
    1635                 :          0 :         I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
    1636                 :          0 :         POSTING_READ(BXT_PORT_PLL_ENABLE(port));
    1637                 :            : 
    1638         [ #  # ]:          0 :         if (IS_GEMINILAKE(dev_priv)) {
    1639                 :          0 :                 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1640                 :          0 :                 temp &= ~PORT_PLL_POWER_ENABLE;
    1641                 :          0 :                 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
    1642                 :            : 
    1643   [ #  #  #  #  :          0 :                 if (wait_for_us(!(I915_READ(BXT_PORT_PLL_ENABLE(port)) &
                   #  # ]
    1644                 :            :                                 PORT_PLL_POWER_STATE), 200))
    1645                 :          0 :                         DRM_ERROR("Power state not reset for PLL:%d\n", port);
    1646                 :            :         }
    1647                 :          0 : }
    1648                 :            : 
    1649                 :          0 : static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
    1650                 :            :                                         struct intel_shared_dpll *pll,
    1651                 :            :                                         struct intel_dpll_hw_state *hw_state)
    1652                 :            : {
    1653                 :          0 :         enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
    1654                 :          0 :         intel_wakeref_t wakeref;
    1655                 :          0 :         enum dpio_phy phy;
    1656                 :          0 :         enum dpio_channel ch;
    1657                 :          0 :         u32 val;
    1658                 :          0 :         bool ret;
    1659                 :            : 
    1660                 :          0 :         bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
    1661                 :            : 
    1662                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    1663                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    1664         [ #  # ]:          0 :         if (!wakeref)
    1665                 :            :                 return false;
    1666                 :            : 
    1667                 :          0 :         ret = false;
    1668                 :            : 
    1669                 :          0 :         val = I915_READ(BXT_PORT_PLL_ENABLE(port));
    1670         [ #  # ]:          0 :         if (!(val & PORT_PLL_ENABLE))
    1671                 :          0 :                 goto out;
    1672                 :            : 
    1673                 :          0 :         hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(phy, ch));
    1674                 :          0 :         hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
    1675                 :            : 
    1676                 :          0 :         hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch));
    1677                 :          0 :         hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
    1678                 :            : 
    1679                 :          0 :         hw_state->pll0 = I915_READ(BXT_PORT_PLL(phy, ch, 0));
    1680                 :          0 :         hw_state->pll0 &= PORT_PLL_M2_MASK;
    1681                 :            : 
    1682                 :          0 :         hw_state->pll1 = I915_READ(BXT_PORT_PLL(phy, ch, 1));
    1683                 :          0 :         hw_state->pll1 &= PORT_PLL_N_MASK;
    1684                 :            : 
    1685                 :          0 :         hw_state->pll2 = I915_READ(BXT_PORT_PLL(phy, ch, 2));
    1686                 :          0 :         hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
    1687                 :            : 
    1688                 :          0 :         hw_state->pll3 = I915_READ(BXT_PORT_PLL(phy, ch, 3));
    1689                 :          0 :         hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
    1690                 :            : 
    1691                 :          0 :         hw_state->pll6 = I915_READ(BXT_PORT_PLL(phy, ch, 6));
    1692                 :          0 :         hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
    1693                 :            :                           PORT_PLL_INT_COEFF_MASK |
    1694                 :            :                           PORT_PLL_GAIN_CTL_MASK;
    1695                 :            : 
    1696                 :          0 :         hw_state->pll8 = I915_READ(BXT_PORT_PLL(phy, ch, 8));
    1697                 :          0 :         hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
    1698                 :            : 
    1699                 :          0 :         hw_state->pll9 = I915_READ(BXT_PORT_PLL(phy, ch, 9));
    1700                 :          0 :         hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
    1701                 :            : 
    1702                 :          0 :         hw_state->pll10 = I915_READ(BXT_PORT_PLL(phy, ch, 10));
    1703                 :          0 :         hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
    1704                 :            :                            PORT_PLL_DCO_AMP_MASK;
    1705                 :            : 
    1706                 :            :         /*
    1707                 :            :          * While we write to the group register to program all lanes at once we
    1708                 :            :          * can read only lane registers. We configure all lanes the same way, so
    1709                 :            :          * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
    1710                 :            :          */
    1711                 :          0 :         hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(phy, ch));
    1712         [ #  # ]:          0 :         if (I915_READ(BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12)
    1713                 :          0 :                 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
    1714                 :            :                                  hw_state->pcsdw12,
    1715                 :            :                                  I915_READ(BXT_PORT_PCS_DW12_LN23(phy, ch)));
    1716                 :          0 :         hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
    1717                 :            : 
    1718                 :          0 :         ret = true;
    1719                 :            : 
    1720                 :          0 : out:
    1721                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    1722                 :            : 
    1723                 :          0 :         return ret;
    1724                 :            : }
    1725                 :            : 
    1726                 :            : /* bxt clock parameters */
    1727                 :            : struct bxt_clk_div {
    1728                 :            :         int clock;
    1729                 :            :         u32 p1;
    1730                 :            :         u32 p2;
    1731                 :            :         u32 m2_int;
    1732                 :            :         u32 m2_frac;
    1733                 :            :         bool m2_frac_en;
    1734                 :            :         u32 n;
    1735                 :            : 
    1736                 :            :         int vco;
    1737                 :            : };
    1738                 :            : 
    1739                 :            : /* pre-calculated values for DP linkrates */
    1740                 :            : static const struct bxt_clk_div bxt_dp_clk_val[] = {
    1741                 :            :         {162000, 4, 2, 32, 1677722, 1, 1},
    1742                 :            :         {270000, 4, 1, 27,       0, 0, 1},
    1743                 :            :         {540000, 2, 1, 27,       0, 0, 1},
    1744                 :            :         {216000, 3, 2, 32, 1677722, 1, 1},
    1745                 :            :         {243000, 4, 1, 24, 1258291, 1, 1},
    1746                 :            :         {324000, 4, 1, 32, 1677722, 1, 1},
    1747                 :            :         {432000, 3, 1, 32, 1677722, 1, 1}
    1748                 :            : };
    1749                 :            : 
    1750                 :            : static bool
    1751                 :          0 : bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
    1752                 :            :                           struct bxt_clk_div *clk_div)
    1753                 :            : {
    1754                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    1755                 :          0 :         struct dpll best_clock;
    1756                 :            : 
    1757                 :            :         /* Calculate HDMI div */
    1758                 :            :         /*
    1759                 :            :          * FIXME: tie the following calculation into
    1760                 :            :          * i9xx_crtc_compute_clock
    1761                 :            :          */
    1762         [ #  # ]:          0 :         if (!bxt_find_best_dpll(crtc_state, &best_clock)) {
    1763                 :          0 :                 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
    1764                 :            :                                  crtc_state->port_clock,
    1765                 :            :                                  pipe_name(crtc->pipe));
    1766                 :          0 :                 return false;
    1767                 :            :         }
    1768                 :            : 
    1769                 :          0 :         clk_div->p1 = best_clock.p1;
    1770                 :          0 :         clk_div->p2 = best_clock.p2;
    1771         [ #  # ]:          0 :         WARN_ON(best_clock.m1 != 2);
    1772                 :          0 :         clk_div->n = best_clock.n;
    1773                 :          0 :         clk_div->m2_int = best_clock.m2 >> 22;
    1774                 :          0 :         clk_div->m2_frac = best_clock.m2 & ((1 << 22) - 1);
    1775                 :          0 :         clk_div->m2_frac_en = clk_div->m2_frac != 0;
    1776                 :            : 
    1777                 :          0 :         clk_div->vco = best_clock.vco;
    1778                 :            : 
    1779                 :          0 :         return true;
    1780                 :            : }
    1781                 :            : 
    1782                 :            : static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state,
    1783                 :            :                                     struct bxt_clk_div *clk_div)
    1784                 :            : {
    1785                 :            :         int clock = crtc_state->port_clock;
    1786                 :            :         int i;
    1787                 :            : 
    1788                 :            :         *clk_div = bxt_dp_clk_val[0];
    1789                 :            :         for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
    1790                 :            :                 if (bxt_dp_clk_val[i].clock == clock) {
    1791                 :            :                         *clk_div = bxt_dp_clk_val[i];
    1792                 :            :                         break;
    1793                 :            :                 }
    1794                 :            :         }
    1795                 :            : 
    1796                 :            :         clk_div->vco = clock * 10 / 2 * clk_div->p1 * clk_div->p2;
    1797                 :            : }
    1798                 :            : 
    1799                 :          0 : static bool bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
    1800                 :            :                                       const struct bxt_clk_div *clk_div)
    1801                 :            : {
    1802                 :          0 :         struct intel_dpll_hw_state *dpll_hw_state = &crtc_state->dpll_hw_state;
    1803                 :          0 :         int clock = crtc_state->port_clock;
    1804                 :          0 :         int vco = clk_div->vco;
    1805                 :          0 :         u32 prop_coef, int_coef, gain_ctl, targ_cnt;
    1806                 :          0 :         u32 lanestagger;
    1807                 :            : 
    1808                 :          0 :         memset(dpll_hw_state, 0, sizeof(*dpll_hw_state));
    1809                 :            : 
    1810         [ #  # ]:          0 :         if (vco >= 6200000 && vco <= 6700000) {
    1811                 :            :                 prop_coef = 4;
    1812                 :            :                 int_coef = 9;
    1813                 :            :                 gain_ctl = 3;
    1814                 :            :                 targ_cnt = 8;
    1815                 :          0 :         } else if ((vco > 5400000 && vco < 6200000) ||
    1816         [ #  # ]:          0 :                         (vco >= 4800000 && vco < 5400000)) {
    1817                 :            :                 prop_coef = 5;
    1818                 :            :                 int_coef = 11;
    1819                 :            :                 gain_ctl = 3;
    1820                 :            :                 targ_cnt = 9;
    1821         [ #  # ]:          0 :         } else if (vco == 5400000) {
    1822                 :            :                 prop_coef = 3;
    1823                 :            :                 int_coef = 8;
    1824                 :            :                 gain_ctl = 1;
    1825                 :            :                 targ_cnt = 9;
    1826                 :            :         } else {
    1827                 :          0 :                 DRM_ERROR("Invalid VCO\n");
    1828                 :          0 :                 return false;
    1829                 :            :         }
    1830                 :            : 
    1831         [ #  # ]:          0 :         if (clock > 270000)
    1832                 :            :                 lanestagger = 0x18;
    1833         [ #  # ]:          0 :         else if (clock > 135000)
    1834                 :            :                 lanestagger = 0x0d;
    1835         [ #  # ]:          0 :         else if (clock > 67000)
    1836                 :            :                 lanestagger = 0x07;
    1837         [ #  # ]:          0 :         else if (clock > 33000)
    1838                 :            :                 lanestagger = 0x04;
    1839                 :            :         else
    1840                 :          0 :                 lanestagger = 0x02;
    1841                 :            : 
    1842                 :          0 :         dpll_hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
    1843                 :          0 :         dpll_hw_state->pll0 = clk_div->m2_int;
    1844                 :          0 :         dpll_hw_state->pll1 = PORT_PLL_N(clk_div->n);
    1845                 :          0 :         dpll_hw_state->pll2 = clk_div->m2_frac;
    1846                 :            : 
    1847         [ #  # ]:          0 :         if (clk_div->m2_frac_en)
    1848                 :          0 :                 dpll_hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
    1849                 :            : 
    1850                 :          0 :         dpll_hw_state->pll6 = prop_coef | PORT_PLL_INT_COEFF(int_coef);
    1851                 :          0 :         dpll_hw_state->pll6 |= PORT_PLL_GAIN_CTL(gain_ctl);
    1852                 :            : 
    1853                 :          0 :         dpll_hw_state->pll8 = targ_cnt;
    1854                 :            : 
    1855                 :          0 :         dpll_hw_state->pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
    1856                 :            : 
    1857                 :          0 :         dpll_hw_state->pll10 =
    1858                 :            :                 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
    1859                 :            :                 | PORT_PLL_DCO_AMP_OVR_EN_H;
    1860                 :            : 
    1861                 :          0 :         dpll_hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
    1862                 :            : 
    1863                 :          0 :         dpll_hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
    1864                 :            : 
    1865                 :          0 :         return true;
    1866                 :            : }
    1867                 :            : 
    1868                 :            : static bool
    1869                 :          0 : bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
    1870                 :            : {
    1871                 :          0 :         struct bxt_clk_div clk_div = {};
    1872                 :            : 
    1873                 :          0 :         bxt_ddi_dp_pll_dividers(crtc_state, &clk_div);
    1874                 :            : 
    1875                 :          0 :         return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
    1876                 :            : }
    1877                 :            : 
    1878                 :            : static bool
    1879                 :          0 : bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
    1880                 :            : {
    1881                 :          0 :         struct bxt_clk_div clk_div = {};
    1882                 :            : 
    1883                 :          0 :         bxt_ddi_hdmi_pll_dividers(crtc_state, &clk_div);
    1884                 :            : 
    1885                 :          0 :         return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
    1886                 :            : }
    1887                 :            : 
    1888                 :          0 : static bool bxt_get_dpll(struct intel_atomic_state *state,
    1889                 :            :                          struct intel_crtc *crtc,
    1890                 :            :                          struct intel_encoder *encoder)
    1891                 :            : {
    1892         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
    1893                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    1894         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    1895                 :          0 :         struct intel_shared_dpll *pll;
    1896                 :          0 :         enum intel_dpll_id id;
    1897                 :            : 
    1898   [ #  #  #  # ]:          0 :         if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
    1899                 :          0 :             !bxt_ddi_hdmi_set_dpll_hw_state(crtc_state))
    1900                 :            :                 return false;
    1901                 :            : 
    1902   [ #  #  #  # ]:          0 :         if (intel_crtc_has_dp_encoder(crtc_state) &&
    1903                 :          0 :             !bxt_ddi_dp_set_dpll_hw_state(crtc_state))
    1904                 :            :                 return false;
    1905                 :            : 
    1906                 :            :         /* 1:1 mapping between ports and PLLs */
    1907                 :          0 :         id = (enum intel_dpll_id) encoder->port;
    1908                 :          0 :         pll = intel_get_shared_dpll_by_id(dev_priv, id);
    1909                 :            : 
    1910                 :          0 :         DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n",
    1911                 :            :                       crtc->base.base.id, crtc->base.name, pll->info->name);
    1912                 :            : 
    1913                 :          0 :         intel_reference_shared_dpll(state, crtc,
    1914                 :          0 :                                     pll, &crtc_state->dpll_hw_state);
    1915                 :            : 
    1916                 :          0 :         crtc_state->shared_dpll = pll;
    1917                 :            : 
    1918                 :          0 :         return true;
    1919                 :            : }
    1920                 :            : 
    1921                 :          0 : static void bxt_dump_hw_state(struct drm_i915_private *dev_priv,
    1922                 :            :                               const struct intel_dpll_hw_state *hw_state)
    1923                 :            : {
    1924                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
    1925                 :            :                       "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
    1926                 :            :                       "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
    1927                 :            :                       hw_state->ebb0,
    1928                 :            :                       hw_state->ebb4,
    1929                 :            :                       hw_state->pll0,
    1930                 :            :                       hw_state->pll1,
    1931                 :            :                       hw_state->pll2,
    1932                 :            :                       hw_state->pll3,
    1933                 :            :                       hw_state->pll6,
    1934                 :            :                       hw_state->pll8,
    1935                 :            :                       hw_state->pll9,
    1936                 :            :                       hw_state->pll10,
    1937                 :            :                       hw_state->pcsdw12);
    1938                 :          0 : }
    1939                 :            : 
    1940                 :            : static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
    1941                 :            :         .enable = bxt_ddi_pll_enable,
    1942                 :            :         .disable = bxt_ddi_pll_disable,
    1943                 :            :         .get_hw_state = bxt_ddi_pll_get_hw_state,
    1944                 :            : };
    1945                 :            : 
    1946                 :            : struct intel_dpll_mgr {
    1947                 :            :         const struct dpll_info *dpll_info;
    1948                 :            : 
    1949                 :            :         bool (*get_dplls)(struct intel_atomic_state *state,
    1950                 :            :                           struct intel_crtc *crtc,
    1951                 :            :                           struct intel_encoder *encoder);
    1952                 :            :         void (*put_dplls)(struct intel_atomic_state *state,
    1953                 :            :                           struct intel_crtc *crtc);
    1954                 :            :         void (*update_active_dpll)(struct intel_atomic_state *state,
    1955                 :            :                                    struct intel_crtc *crtc,
    1956                 :            :                                    struct intel_encoder *encoder);
    1957                 :            :         void (*dump_hw_state)(struct drm_i915_private *dev_priv,
    1958                 :            :                               const struct intel_dpll_hw_state *hw_state);
    1959                 :            : };
    1960                 :            : 
    1961                 :            : static const struct dpll_info pch_plls[] = {
    1962                 :            :         { "PCH DPLL A", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_A, 0 },
    1963                 :            :         { "PCH DPLL B", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_B, 0 },
    1964                 :            :         { },
    1965                 :            : };
    1966                 :            : 
    1967                 :            : static const struct intel_dpll_mgr pch_pll_mgr = {
    1968                 :            :         .dpll_info = pch_plls,
    1969                 :            :         .get_dplls = ibx_get_dpll,
    1970                 :            :         .put_dplls = intel_put_dpll,
    1971                 :            :         .dump_hw_state = ibx_dump_hw_state,
    1972                 :            : };
    1973                 :            : 
    1974                 :            : static const struct dpll_info hsw_plls[] = {
    1975                 :            :         { "WRPLL 1",    &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL1,     0 },
    1976                 :            :         { "WRPLL 2",    &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL2,     0 },
    1977                 :            :         { "SPLL",       &hsw_ddi_spll_funcs,  DPLL_ID_SPLL,       0 },
    1978                 :            :         { "LCPLL 810",  &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_810,  INTEL_DPLL_ALWAYS_ON },
    1979                 :            :         { "LCPLL 1350", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_1350, INTEL_DPLL_ALWAYS_ON },
    1980                 :            :         { "LCPLL 2700", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_2700, INTEL_DPLL_ALWAYS_ON },
    1981                 :            :         { },
    1982                 :            : };
    1983                 :            : 
    1984                 :            : static const struct intel_dpll_mgr hsw_pll_mgr = {
    1985                 :            :         .dpll_info = hsw_plls,
    1986                 :            :         .get_dplls = hsw_get_dpll,
    1987                 :            :         .put_dplls = intel_put_dpll,
    1988                 :            :         .dump_hw_state = hsw_dump_hw_state,
    1989                 :            : };
    1990                 :            : 
    1991                 :            : static const struct dpll_info skl_plls[] = {
    1992                 :            :         { "DPLL 0", &skl_ddi_dpll0_funcs, DPLL_ID_SKL_DPLL0, INTEL_DPLL_ALWAYS_ON },
    1993                 :            :         { "DPLL 1", &skl_ddi_pll_funcs,   DPLL_ID_SKL_DPLL1, 0 },
    1994                 :            :         { "DPLL 2", &skl_ddi_pll_funcs,   DPLL_ID_SKL_DPLL2, 0 },
    1995                 :            :         { "DPLL 3", &skl_ddi_pll_funcs,   DPLL_ID_SKL_DPLL3, 0 },
    1996                 :            :         { },
    1997                 :            : };
    1998                 :            : 
    1999                 :            : static const struct intel_dpll_mgr skl_pll_mgr = {
    2000                 :            :         .dpll_info = skl_plls,
    2001                 :            :         .get_dplls = skl_get_dpll,
    2002                 :            :         .put_dplls = intel_put_dpll,
    2003                 :            :         .dump_hw_state = skl_dump_hw_state,
    2004                 :            : };
    2005                 :            : 
    2006                 :            : static const struct dpll_info bxt_plls[] = {
    2007                 :            :         { "PORT PLL A", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
    2008                 :            :         { "PORT PLL B", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
    2009                 :            :         { "PORT PLL C", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
    2010                 :            :         { },
    2011                 :            : };
    2012                 :            : 
    2013                 :            : static const struct intel_dpll_mgr bxt_pll_mgr = {
    2014                 :            :         .dpll_info = bxt_plls,
    2015                 :            :         .get_dplls = bxt_get_dpll,
    2016                 :            :         .put_dplls = intel_put_dpll,
    2017                 :            :         .dump_hw_state = bxt_dump_hw_state,
    2018                 :            : };
    2019                 :            : 
    2020                 :          0 : static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
    2021                 :            :                                struct intel_shared_dpll *pll)
    2022                 :            : {
    2023                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    2024                 :          0 :         u32 val;
    2025                 :            : 
    2026                 :            :         /* 1. Enable DPLL power in DPLL_ENABLE. */
    2027                 :          0 :         val = I915_READ(CNL_DPLL_ENABLE(id));
    2028                 :          0 :         val |= PLL_POWER_ENABLE;
    2029                 :          0 :         I915_WRITE(CNL_DPLL_ENABLE(id), val);
    2030                 :            : 
    2031                 :            :         /* 2. Wait for DPLL power state enabled in DPLL_ENABLE. */
    2032         [ #  # ]:          0 :         if (intel_de_wait_for_set(dev_priv, CNL_DPLL_ENABLE(id),
    2033                 :            :                                   PLL_POWER_STATE, 5))
    2034                 :          0 :                 DRM_ERROR("PLL %d Power not enabled\n", id);
    2035                 :            : 
    2036                 :            :         /*
    2037                 :            :          * 3. Configure DPLL_CFGCR0 to set SSC enable/disable,
    2038                 :            :          * select DP mode, and set DP link rate.
    2039                 :            :          */
    2040                 :          0 :         val = pll->state.hw_state.cfgcr0;
    2041                 :          0 :         I915_WRITE(CNL_DPLL_CFGCR0(id), val);
    2042                 :            : 
    2043                 :            :         /* 4. Reab back to ensure writes completed */
    2044                 :          0 :         POSTING_READ(CNL_DPLL_CFGCR0(id));
    2045                 :            : 
    2046                 :            :         /* 3. Configure DPLL_CFGCR0 */
    2047                 :            :         /* Avoid touch CFGCR1 if HDMI mode is not enabled */
    2048         [ #  # ]:          0 :         if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
    2049                 :          0 :                 val = pll->state.hw_state.cfgcr1;
    2050                 :          0 :                 I915_WRITE(CNL_DPLL_CFGCR1(id), val);
    2051                 :            :                 /* 4. Reab back to ensure writes completed */
    2052                 :          0 :                 POSTING_READ(CNL_DPLL_CFGCR1(id));
    2053                 :            :         }
    2054                 :            : 
    2055                 :            :         /*
    2056                 :            :          * 5. If the frequency will result in a change to the voltage
    2057                 :            :          * requirement, follow the Display Voltage Frequency Switching
    2058                 :            :          * Sequence Before Frequency Change
    2059                 :            :          *
    2060                 :            :          * Note: DVFS is actually handled via the cdclk code paths,
    2061                 :            :          * hence we do nothing here.
    2062                 :            :          */
    2063                 :            : 
    2064                 :            :         /* 6. Enable DPLL in DPLL_ENABLE. */
    2065                 :          0 :         val = I915_READ(CNL_DPLL_ENABLE(id));
    2066                 :          0 :         val |= PLL_ENABLE;
    2067                 :          0 :         I915_WRITE(CNL_DPLL_ENABLE(id), val);
    2068                 :            : 
    2069                 :            :         /* 7. Wait for PLL lock status in DPLL_ENABLE. */
    2070         [ #  # ]:          0 :         if (intel_de_wait_for_set(dev_priv, CNL_DPLL_ENABLE(id), PLL_LOCK, 5))
    2071                 :          0 :                 DRM_ERROR("PLL %d not locked\n", id);
    2072                 :            : 
    2073                 :            :         /*
    2074                 :            :          * 8. If the frequency will result in a change to the voltage
    2075                 :            :          * requirement, follow the Display Voltage Frequency Switching
    2076                 :            :          * Sequence After Frequency Change
    2077                 :            :          *
    2078                 :            :          * Note: DVFS is actually handled via the cdclk code paths,
    2079                 :            :          * hence we do nothing here.
    2080                 :            :          */
    2081                 :            : 
    2082                 :            :         /*
    2083                 :            :          * 9. turn on the clock for the DDI and map the DPLL to the DDI
    2084                 :            :          * Done at intel_ddi_clk_select
    2085                 :            :          */
    2086                 :          0 : }
    2087                 :            : 
    2088                 :          0 : static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
    2089                 :            :                                 struct intel_shared_dpll *pll)
    2090                 :            : {
    2091                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    2092                 :          0 :         u32 val;
    2093                 :            : 
    2094                 :            :         /*
    2095                 :            :          * 1. Configure DPCLKA_CFGCR0 to turn off the clock for the DDI.
    2096                 :            :          * Done at intel_ddi_post_disable
    2097                 :            :          */
    2098                 :            : 
    2099                 :            :         /*
    2100                 :            :          * 2. If the frequency will result in a change to the voltage
    2101                 :            :          * requirement, follow the Display Voltage Frequency Switching
    2102                 :            :          * Sequence Before Frequency Change
    2103                 :            :          *
    2104                 :            :          * Note: DVFS is actually handled via the cdclk code paths,
    2105                 :            :          * hence we do nothing here.
    2106                 :            :          */
    2107                 :            : 
    2108                 :            :         /* 3. Disable DPLL through DPLL_ENABLE. */
    2109                 :          0 :         val = I915_READ(CNL_DPLL_ENABLE(id));
    2110                 :          0 :         val &= ~PLL_ENABLE;
    2111                 :          0 :         I915_WRITE(CNL_DPLL_ENABLE(id), val);
    2112                 :            : 
    2113                 :            :         /* 4. Wait for PLL not locked status in DPLL_ENABLE. */
    2114         [ #  # ]:          0 :         if (intel_de_wait_for_clear(dev_priv, CNL_DPLL_ENABLE(id), PLL_LOCK, 5))
    2115                 :          0 :                 DRM_ERROR("PLL %d locked\n", id);
    2116                 :            : 
    2117                 :            :         /*
    2118                 :            :          * 5. If the frequency will result in a change to the voltage
    2119                 :            :          * requirement, follow the Display Voltage Frequency Switching
    2120                 :            :          * Sequence After Frequency Change
    2121                 :            :          *
    2122                 :            :          * Note: DVFS is actually handled via the cdclk code paths,
    2123                 :            :          * hence we do nothing here.
    2124                 :            :          */
    2125                 :            : 
    2126                 :            :         /* 6. Disable DPLL power in DPLL_ENABLE. */
    2127                 :          0 :         val = I915_READ(CNL_DPLL_ENABLE(id));
    2128                 :          0 :         val &= ~PLL_POWER_ENABLE;
    2129                 :          0 :         I915_WRITE(CNL_DPLL_ENABLE(id), val);
    2130                 :            : 
    2131                 :            :         /* 7. Wait for DPLL power state disabled in DPLL_ENABLE. */
    2132         [ #  # ]:          0 :         if (intel_de_wait_for_clear(dev_priv, CNL_DPLL_ENABLE(id),
    2133                 :            :                                     PLL_POWER_STATE, 5))
    2134                 :          0 :                 DRM_ERROR("PLL %d Power not disabled\n", id);
    2135                 :          0 : }
    2136                 :            : 
    2137                 :          0 : static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
    2138                 :            :                                      struct intel_shared_dpll *pll,
    2139                 :            :                                      struct intel_dpll_hw_state *hw_state)
    2140                 :            : {
    2141                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    2142                 :          0 :         intel_wakeref_t wakeref;
    2143                 :          0 :         u32 val;
    2144                 :          0 :         bool ret;
    2145                 :            : 
    2146                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    2147                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    2148         [ #  # ]:          0 :         if (!wakeref)
    2149                 :            :                 return false;
    2150                 :            : 
    2151                 :          0 :         ret = false;
    2152                 :            : 
    2153                 :          0 :         val = I915_READ(CNL_DPLL_ENABLE(id));
    2154         [ #  # ]:          0 :         if (!(val & PLL_ENABLE))
    2155                 :          0 :                 goto out;
    2156                 :            : 
    2157                 :          0 :         val = I915_READ(CNL_DPLL_CFGCR0(id));
    2158                 :          0 :         hw_state->cfgcr0 = val;
    2159                 :            : 
    2160                 :            :         /* avoid reading back stale values if HDMI mode is not enabled */
    2161         [ #  # ]:          0 :         if (val & DPLL_CFGCR0_HDMI_MODE) {
    2162                 :          0 :                 hw_state->cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(id));
    2163                 :            :         }
    2164                 :            :         ret = true;
    2165                 :            : 
    2166                 :          0 : out:
    2167                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    2168                 :            : 
    2169                 :          0 :         return ret;
    2170                 :            : }
    2171                 :            : 
    2172                 :          0 : static void cnl_wrpll_get_multipliers(int bestdiv, int *pdiv,
    2173                 :            :                                       int *qdiv, int *kdiv)
    2174                 :            : {
    2175                 :            :         /* even dividers */
    2176         [ #  # ]:          0 :         if (bestdiv % 2 == 0) {
    2177         [ #  # ]:          0 :                 if (bestdiv == 2) {
    2178                 :          0 :                         *pdiv = 2;
    2179                 :          0 :                         *qdiv = 1;
    2180                 :          0 :                         *kdiv = 1;
    2181         [ #  # ]:          0 :                 } else if (bestdiv % 4 == 0) {
    2182                 :          0 :                         *pdiv = 2;
    2183                 :          0 :                         *qdiv = bestdiv / 4;
    2184                 :          0 :                         *kdiv = 2;
    2185         [ #  # ]:          0 :                 } else if (bestdiv % 6 == 0) {
    2186                 :          0 :                         *pdiv = 3;
    2187                 :          0 :                         *qdiv = bestdiv / 6;
    2188                 :          0 :                         *kdiv = 2;
    2189         [ #  # ]:          0 :                 } else if (bestdiv % 5 == 0) {
    2190                 :          0 :                         *pdiv = 5;
    2191                 :          0 :                         *qdiv = bestdiv / 10;
    2192                 :          0 :                         *kdiv = 2;
    2193         [ #  # ]:          0 :                 } else if (bestdiv % 14 == 0) {
    2194                 :          0 :                         *pdiv = 7;
    2195                 :          0 :                         *qdiv = bestdiv / 14;
    2196                 :          0 :                         *kdiv = 2;
    2197                 :            :                 }
    2198                 :            :         } else {
    2199   [ #  #  #  # ]:          0 :                 if (bestdiv == 3 || bestdiv == 5 || bestdiv == 7) {
    2200                 :          0 :                         *pdiv = bestdiv;
    2201                 :          0 :                         *qdiv = 1;
    2202                 :          0 :                         *kdiv = 1;
    2203                 :            :                 } else { /* 9, 15, 21 */
    2204                 :          0 :                         *pdiv = bestdiv / 3;
    2205                 :          0 :                         *qdiv = 1;
    2206                 :          0 :                         *kdiv = 3;
    2207                 :            :                 }
    2208                 :            :         }
    2209                 :          0 : }
    2210                 :            : 
    2211                 :          0 : static void cnl_wrpll_params_populate(struct skl_wrpll_params *params,
    2212                 :            :                                       u32 dco_freq, u32 ref_freq,
    2213                 :            :                                       int pdiv, int qdiv, int kdiv)
    2214                 :            : {
    2215                 :          0 :         u32 dco;
    2216                 :            : 
    2217   [ #  #  #  # ]:          0 :         switch (kdiv) {
    2218                 :          0 :         case 1:
    2219                 :          0 :                 params->kdiv = 1;
    2220                 :          0 :                 break;
    2221                 :          0 :         case 2:
    2222                 :          0 :                 params->kdiv = 2;
    2223                 :          0 :                 break;
    2224                 :          0 :         case 3:
    2225                 :          0 :                 params->kdiv = 4;
    2226                 :          0 :                 break;
    2227                 :            :         default:
    2228                 :          0 :                 WARN(1, "Incorrect KDiv\n");
    2229                 :            :         }
    2230                 :            : 
    2231   [ #  #  #  #  :          0 :         switch (pdiv) {
                      # ]
    2232                 :          0 :         case 2:
    2233                 :          0 :                 params->pdiv = 1;
    2234                 :          0 :                 break;
    2235                 :          0 :         case 3:
    2236                 :          0 :                 params->pdiv = 2;
    2237                 :          0 :                 break;
    2238                 :          0 :         case 5:
    2239                 :          0 :                 params->pdiv = 4;
    2240                 :          0 :                 break;
    2241                 :          0 :         case 7:
    2242                 :          0 :                 params->pdiv = 8;
    2243                 :          0 :                 break;
    2244                 :            :         default:
    2245                 :          0 :                 WARN(1, "Incorrect PDiv\n");
    2246                 :            :         }
    2247                 :            : 
    2248         [ #  # ]:          0 :         WARN_ON(kdiv != 2 && qdiv != 1);
    2249                 :            : 
    2250                 :          0 :         params->qdiv_ratio = qdiv;
    2251                 :          0 :         params->qdiv_mode = (qdiv == 1) ? 0 : 1;
    2252                 :            : 
    2253                 :          0 :         dco = div_u64((u64)dco_freq << 15, ref_freq);
    2254                 :            : 
    2255                 :          0 :         params->dco_integer = dco >> 15;
    2256                 :          0 :         params->dco_fraction = dco & 0x7fff;
    2257                 :          0 : }
    2258                 :            : 
    2259                 :          0 : int cnl_hdmi_pll_ref_clock(struct drm_i915_private *dev_priv)
    2260                 :            : {
    2261                 :          0 :         int ref_clock = dev_priv->cdclk.hw.ref;
    2262                 :            : 
    2263                 :            :         /*
    2264                 :            :          * For ICL+, the spec states: if reference frequency is 38.4,
    2265                 :            :          * use 19.2 because the DPLL automatically divides that by 2.
    2266                 :            :          */
    2267   [ #  #  #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 11 && ref_clock == 38400)
    2268                 :          0 :                 ref_clock = 19200;
    2269                 :            : 
    2270                 :          0 :         return ref_clock;
    2271                 :            : }
    2272                 :            : 
    2273                 :            : static bool
    2274                 :            : cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
    2275                 :            :                         struct skl_wrpll_params *wrpll_params)
    2276                 :            : {
    2277                 :            :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    2278                 :            :         u32 afe_clock = crtc_state->port_clock * 5;
    2279                 :            :         u32 ref_clock;
    2280                 :            :         u32 dco_min = 7998000;
    2281                 :            :         u32 dco_max = 10000000;
    2282                 :            :         u32 dco_mid = (dco_min + dco_max) / 2;
    2283                 :            :         static const int dividers[] = {  2,  4,  6,  8, 10, 12,  14,  16,
    2284                 :            :                                          18, 20, 24, 28, 30, 32,  36,  40,
    2285                 :            :                                          42, 44, 48, 50, 52, 54,  56,  60,
    2286                 :            :                                          64, 66, 68, 70, 72, 76,  78,  80,
    2287                 :            :                                          84, 88, 90, 92, 96, 98, 100, 102,
    2288                 :            :                                           3,  5,  7,  9, 15, 21 };
    2289                 :            :         u32 dco, best_dco = 0, dco_centrality = 0;
    2290                 :            :         u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
    2291                 :            :         int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
    2292                 :            : 
    2293                 :            :         for (d = 0; d < ARRAY_SIZE(dividers); d++) {
    2294                 :            :                 dco = afe_clock * dividers[d];
    2295                 :            : 
    2296                 :            :                 if ((dco <= dco_max) && (dco >= dco_min)) {
    2297                 :            :                         dco_centrality = abs(dco - dco_mid);
    2298                 :            : 
    2299                 :            :                         if (dco_centrality < best_dco_centrality) {
    2300                 :            :                                 best_dco_centrality = dco_centrality;
    2301                 :            :                                 best_div = dividers[d];
    2302                 :            :                                 best_dco = dco;
    2303                 :            :                         }
    2304                 :            :                 }
    2305                 :            :         }
    2306                 :            : 
    2307                 :            :         if (best_div == 0)
    2308                 :            :                 return false;
    2309                 :            : 
    2310                 :            :         cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
    2311                 :            : 
    2312                 :            :         ref_clock = cnl_hdmi_pll_ref_clock(dev_priv);
    2313                 :            : 
    2314                 :            :         cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock,
    2315                 :            :                                   pdiv, qdiv, kdiv);
    2316                 :            : 
    2317                 :            :         return true;
    2318                 :            : }
    2319                 :            : 
    2320                 :          0 : static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
    2321                 :            : {
    2322                 :          0 :         u32 cfgcr0, cfgcr1;
    2323                 :          0 :         struct skl_wrpll_params wrpll_params = { 0, };
    2324                 :            : 
    2325                 :          0 :         cfgcr0 = DPLL_CFGCR0_HDMI_MODE;
    2326                 :            : 
    2327         [ #  # ]:          0 :         if (!cnl_ddi_calculate_wrpll(crtc_state, &wrpll_params))
    2328                 :            :                 return false;
    2329                 :            : 
    2330                 :          0 :         cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) |
    2331                 :          0 :                 wrpll_params.dco_integer;
    2332                 :            : 
    2333                 :          0 :         cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(wrpll_params.qdiv_ratio) |
    2334                 :          0 :                 DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) |
    2335                 :          0 :                 DPLL_CFGCR1_KDIV(wrpll_params.kdiv) |
    2336                 :          0 :                 DPLL_CFGCR1_PDIV(wrpll_params.pdiv) |
    2337                 :            :                 DPLL_CFGCR1_CENTRAL_FREQ;
    2338                 :            : 
    2339                 :          0 :         memset(&crtc_state->dpll_hw_state, 0,
    2340                 :            :                sizeof(crtc_state->dpll_hw_state));
    2341                 :            : 
    2342                 :          0 :         crtc_state->dpll_hw_state.cfgcr0 = cfgcr0;
    2343                 :          0 :         crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
    2344                 :          0 :         return true;
    2345                 :            : }
    2346                 :            : 
    2347                 :            : static bool
    2348                 :          0 : cnl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
    2349                 :            : {
    2350                 :          0 :         u32 cfgcr0;
    2351                 :            : 
    2352                 :          0 :         cfgcr0 = DPLL_CFGCR0_SSC_ENABLE;
    2353                 :            : 
    2354   [ #  #  #  #  :          0 :         switch (crtc_state->port_clock / 2) {
             #  #  #  # ]
    2355                 :          0 :         case 81000:
    2356                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_810;
    2357                 :          0 :                 break;
    2358                 :          0 :         case 135000:
    2359                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1350;
    2360                 :          0 :                 break;
    2361                 :            :         case 270000:
    2362                 :            :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2700;
    2363                 :            :                 break;
    2364                 :            :                 /* eDP 1.4 rates */
    2365                 :          0 :         case 162000:
    2366                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1620;
    2367                 :          0 :                 break;
    2368                 :          0 :         case 108000:
    2369                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1080;
    2370                 :          0 :                 break;
    2371                 :          0 :         case 216000:
    2372                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2160;
    2373                 :          0 :                 break;
    2374                 :          0 :         case 324000:
    2375                 :            :                 /* Some SKUs may require elevated I/O voltage to support this */
    2376                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_3240;
    2377                 :          0 :                 break;
    2378                 :          0 :         case 405000:
    2379                 :            :                 /* Some SKUs may require elevated I/O voltage to support this */
    2380                 :          0 :                 cfgcr0 |= DPLL_CFGCR0_LINK_RATE_4050;
    2381                 :          0 :                 break;
    2382                 :            :         }
    2383                 :            : 
    2384                 :          0 :         memset(&crtc_state->dpll_hw_state, 0,
    2385                 :            :                sizeof(crtc_state->dpll_hw_state));
    2386                 :            : 
    2387                 :          0 :         crtc_state->dpll_hw_state.cfgcr0 = cfgcr0;
    2388                 :            : 
    2389                 :          0 :         return true;
    2390                 :            : }
    2391                 :            : 
    2392                 :          0 : static bool cnl_get_dpll(struct intel_atomic_state *state,
    2393                 :            :                          struct intel_crtc *crtc,
    2394                 :            :                          struct intel_encoder *encoder)
    2395                 :            : {
    2396         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
    2397                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    2398                 :          0 :         struct intel_shared_dpll *pll;
    2399                 :          0 :         bool bret;
    2400                 :            : 
    2401         [ #  # ]:          0 :         if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
    2402                 :          0 :                 bret = cnl_ddi_hdmi_pll_dividers(crtc_state);
    2403         [ #  # ]:          0 :                 if (!bret) {
    2404                 :          0 :                         DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
    2405                 :          0 :                         return false;
    2406                 :            :                 }
    2407         [ #  # ]:          0 :         } else if (intel_crtc_has_dp_encoder(crtc_state)) {
    2408                 :          0 :                 bret = cnl_ddi_dp_set_dpll_hw_state(crtc_state);
    2409         [ #  # ]:          0 :                 if (!bret) {
    2410                 :          0 :                         DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
    2411                 :          0 :                         return false;
    2412                 :            :                 }
    2413                 :            :         } else {
    2414                 :          0 :                 DRM_DEBUG_KMS("Skip DPLL setup for output_types 0x%x\n",
    2415                 :            :                               crtc_state->output_types);
    2416                 :          0 :                 return false;
    2417                 :            :         }
    2418                 :            : 
    2419                 :          0 :         pll = intel_find_shared_dpll(state, crtc,
    2420                 :          0 :                                      &crtc_state->dpll_hw_state,
    2421                 :            :                                      BIT(DPLL_ID_SKL_DPLL2) |
    2422                 :            :                                      BIT(DPLL_ID_SKL_DPLL1) |
    2423                 :            :                                      BIT(DPLL_ID_SKL_DPLL0));
    2424         [ #  # ]:          0 :         if (!pll) {
    2425                 :          0 :                 DRM_DEBUG_KMS("No PLL selected\n");
    2426                 :          0 :                 return false;
    2427                 :            :         }
    2428                 :            : 
    2429                 :          0 :         intel_reference_shared_dpll(state, crtc,
    2430                 :            :                                     pll, &crtc_state->dpll_hw_state);
    2431                 :            : 
    2432                 :          0 :         crtc_state->shared_dpll = pll;
    2433                 :            : 
    2434                 :          0 :         return true;
    2435                 :            : }
    2436                 :            : 
    2437                 :          0 : static void cnl_dump_hw_state(struct drm_i915_private *dev_priv,
    2438                 :            :                               const struct intel_dpll_hw_state *hw_state)
    2439                 :            : {
    2440                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: "
    2441                 :            :                       "cfgcr0: 0x%x, cfgcr1: 0x%x\n",
    2442                 :            :                       hw_state->cfgcr0,
    2443                 :            :                       hw_state->cfgcr1);
    2444                 :          0 : }
    2445                 :            : 
    2446                 :            : static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = {
    2447                 :            :         .enable = cnl_ddi_pll_enable,
    2448                 :            :         .disable = cnl_ddi_pll_disable,
    2449                 :            :         .get_hw_state = cnl_ddi_pll_get_hw_state,
    2450                 :            : };
    2451                 :            : 
    2452                 :            : static const struct dpll_info cnl_plls[] = {
    2453                 :            :         { "DPLL 0", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
    2454                 :            :         { "DPLL 1", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
    2455                 :            :         { "DPLL 2", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
    2456                 :            :         { },
    2457                 :            : };
    2458                 :            : 
    2459                 :            : static const struct intel_dpll_mgr cnl_pll_mgr = {
    2460                 :            :         .dpll_info = cnl_plls,
    2461                 :            :         .get_dplls = cnl_get_dpll,
    2462                 :            :         .put_dplls = intel_put_dpll,
    2463                 :            :         .dump_hw_state = cnl_dump_hw_state,
    2464                 :            : };
    2465                 :            : 
    2466                 :            : struct icl_combo_pll_params {
    2467                 :            :         int clock;
    2468                 :            :         struct skl_wrpll_params wrpll;
    2469                 :            : };
    2470                 :            : 
    2471                 :            : /*
    2472                 :            :  * These values alrea already adjusted: they're the bits we write to the
    2473                 :            :  * registers, not the logical values.
    2474                 :            :  */
    2475                 :            : static const struct icl_combo_pll_params icl_dp_combo_pll_24MHz_values[] = {
    2476                 :            :         { 540000,
    2477                 :            :           { .dco_integer = 0x151, .dco_fraction = 0x4000,               /* [0]: 5.4 */
    2478                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2479                 :            :         { 270000,
    2480                 :            :           { .dco_integer = 0x151, .dco_fraction = 0x4000,               /* [1]: 2.7 */
    2481                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2482                 :            :         { 162000,
    2483                 :            :           { .dco_integer = 0x151, .dco_fraction = 0x4000,               /* [2]: 1.62 */
    2484                 :            :             .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2485                 :            :         { 324000,
    2486                 :            :           { .dco_integer = 0x151, .dco_fraction = 0x4000,               /* [3]: 3.24 */
    2487                 :            :             .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2488                 :            :         { 216000,
    2489                 :            :           { .dco_integer = 0x168, .dco_fraction = 0x0000,               /* [4]: 2.16 */
    2490                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2, }, },
    2491                 :            :         { 432000,
    2492                 :            :           { .dco_integer = 0x168, .dco_fraction = 0x0000,               /* [5]: 4.32 */
    2493                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2494                 :            :         { 648000,
    2495                 :            :           { .dco_integer = 0x195, .dco_fraction = 0x0000,               /* [6]: 6.48 */
    2496                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2497                 :            :         { 810000,
    2498                 :            :           { .dco_integer = 0x151, .dco_fraction = 0x4000,               /* [7]: 8.1 */
    2499                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2500                 :            : };
    2501                 :            : 
    2502                 :            : 
    2503                 :            : /* Also used for 38.4 MHz values. */
    2504                 :            : static const struct icl_combo_pll_params icl_dp_combo_pll_19_2MHz_values[] = {
    2505                 :            :         { 540000,
    2506                 :            :           { .dco_integer = 0x1A5, .dco_fraction = 0x7000,               /* [0]: 5.4 */
    2507                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2508                 :            :         { 270000,
    2509                 :            :           { .dco_integer = 0x1A5, .dco_fraction = 0x7000,               /* [1]: 2.7 */
    2510                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2511                 :            :         { 162000,
    2512                 :            :           { .dco_integer = 0x1A5, .dco_fraction = 0x7000,               /* [2]: 1.62 */
    2513                 :            :             .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2514                 :            :         { 324000,
    2515                 :            :           { .dco_integer = 0x1A5, .dco_fraction = 0x7000,               /* [3]: 3.24 */
    2516                 :            :             .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2517                 :            :         { 216000,
    2518                 :            :           { .dco_integer = 0x1C2, .dco_fraction = 0x0000,               /* [4]: 2.16 */
    2519                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2, }, },
    2520                 :            :         { 432000,
    2521                 :            :           { .dco_integer = 0x1C2, .dco_fraction = 0x0000,               /* [5]: 4.32 */
    2522                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2523                 :            :         { 648000,
    2524                 :            :           { .dco_integer = 0x1FA, .dco_fraction = 0x2000,               /* [6]: 6.48 */
    2525                 :            :             .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2526                 :            :         { 810000,
    2527                 :            :           { .dco_integer = 0x1A5, .dco_fraction = 0x7000,               /* [7]: 8.1 */
    2528                 :            :             .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, }, },
    2529                 :            : };
    2530                 :            : 
    2531                 :            : static const struct skl_wrpll_params icl_tbt_pll_24MHz_values = {
    2532                 :            :         .dco_integer = 0x151, .dco_fraction = 0x4000,
    2533                 :            :         .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0,
    2534                 :            : };
    2535                 :            : 
    2536                 :            : static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = {
    2537                 :            :         .dco_integer = 0x1A5, .dco_fraction = 0x7000,
    2538                 :            :         .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0,
    2539                 :            : };
    2540                 :            : 
    2541                 :            : static const struct skl_wrpll_params tgl_tbt_pll_19_2MHz_values = {
    2542                 :            :         .dco_integer = 0x54, .dco_fraction = 0x3000,
    2543                 :            :         /* the following params are unused */
    2544                 :            :         .pdiv = 0, .kdiv = 0, .qdiv_mode = 0, .qdiv_ratio = 0,
    2545                 :            : };
    2546                 :            : 
    2547                 :            : static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = {
    2548                 :            :         .dco_integer = 0x43, .dco_fraction = 0x4000,
    2549                 :            :         /* the following params are unused */
    2550                 :            :         .pdiv = 0, .kdiv = 0, .qdiv_mode = 0, .qdiv_ratio = 0,
    2551                 :            : };
    2552                 :            : 
    2553                 :            : static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
    2554                 :            :                                   struct skl_wrpll_params *pll_params)
    2555                 :            : {
    2556                 :            :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    2557                 :            :         const struct icl_combo_pll_params *params =
    2558                 :            :                 dev_priv->cdclk.hw.ref == 24000 ?
    2559                 :            :                 icl_dp_combo_pll_24MHz_values :
    2560                 :            :                 icl_dp_combo_pll_19_2MHz_values;
    2561                 :            :         int clock = crtc_state->port_clock;
    2562                 :            :         int i;
    2563                 :            : 
    2564                 :            :         for (i = 0; i < ARRAY_SIZE(icl_dp_combo_pll_24MHz_values); i++) {
    2565                 :            :                 if (clock == params[i].clock) {
    2566                 :            :                         *pll_params = params[i].wrpll;
    2567                 :            :                         return true;
    2568                 :            :                 }
    2569                 :            :         }
    2570                 :            : 
    2571                 :            :         MISSING_CASE(clock);
    2572                 :            :         return false;
    2573                 :            : }
    2574                 :            : 
    2575                 :            : static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
    2576                 :            :                              struct skl_wrpll_params *pll_params)
    2577                 :            : {
    2578                 :            :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    2579                 :            : 
    2580                 :            :         if (INTEL_GEN(dev_priv) >= 12) {
    2581                 :            :                 switch (dev_priv->cdclk.hw.ref) {
    2582                 :            :                 default:
    2583                 :            :                         MISSING_CASE(dev_priv->cdclk.hw.ref);
    2584                 :            :                         /* fall-through */
    2585                 :            :                 case 19200:
    2586                 :            :                 case 38400:
    2587                 :            :                         *pll_params = tgl_tbt_pll_19_2MHz_values;
    2588                 :            :                         break;
    2589                 :            :                 case 24000:
    2590                 :            :                         *pll_params = tgl_tbt_pll_24MHz_values;
    2591                 :            :                         break;
    2592                 :            :                 }
    2593                 :            :         } else {
    2594                 :            :                 switch (dev_priv->cdclk.hw.ref) {
    2595                 :            :                 default:
    2596                 :            :                         MISSING_CASE(dev_priv->cdclk.hw.ref);
    2597                 :            :                         /* fall-through */
    2598                 :            :                 case 19200:
    2599                 :            :                 case 38400:
    2600                 :            :                         *pll_params = icl_tbt_pll_19_2MHz_values;
    2601                 :            :                         break;
    2602                 :            :                 case 24000:
    2603                 :            :                         *pll_params = icl_tbt_pll_24MHz_values;
    2604                 :            :                         break;
    2605                 :            :                 }
    2606                 :            :         }
    2607                 :            : 
    2608                 :            :         return true;
    2609                 :            : }
    2610                 :            : 
    2611                 :            : static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
    2612                 :            :                                 struct intel_encoder *encoder,
    2613                 :            :                                 struct intel_dpll_hw_state *pll_state)
    2614                 :            : {
    2615                 :            :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    2616                 :            :         u32 cfgcr0, cfgcr1;
    2617                 :            :         struct skl_wrpll_params pll_params = { 0 };
    2618                 :            :         bool ret;
    2619                 :            : 
    2620                 :            :         if (intel_phy_is_tc(dev_priv, intel_port_to_phy(dev_priv,
    2621                 :            :                                                         encoder->port)))
    2622                 :            :                 ret = icl_calc_tbt_pll(crtc_state, &pll_params);
    2623                 :            :         else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
    2624                 :            :                  intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
    2625                 :            :                 ret = cnl_ddi_calculate_wrpll(crtc_state, &pll_params);
    2626                 :            :         else
    2627                 :            :                 ret = icl_calc_dp_combo_pll(crtc_state, &pll_params);
    2628                 :            : 
    2629                 :            :         if (!ret)
    2630                 :            :                 return false;
    2631                 :            : 
    2632                 :            :         cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(pll_params.dco_fraction) |
    2633                 :            :                  pll_params.dco_integer;
    2634                 :            : 
    2635                 :            :         cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params.qdiv_ratio) |
    2636                 :            :                  DPLL_CFGCR1_QDIV_MODE(pll_params.qdiv_mode) |
    2637                 :            :                  DPLL_CFGCR1_KDIV(pll_params.kdiv) |
    2638                 :            :                  DPLL_CFGCR1_PDIV(pll_params.pdiv);
    2639                 :            : 
    2640                 :            :         if (INTEL_GEN(dev_priv) >= 12)
    2641                 :            :                 cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL;
    2642                 :            :         else
    2643                 :            :                 cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
    2644                 :            : 
    2645                 :            :         memset(pll_state, 0, sizeof(*pll_state));
    2646                 :            : 
    2647                 :            :         pll_state->cfgcr0 = cfgcr0;
    2648                 :            :         pll_state->cfgcr1 = cfgcr1;
    2649                 :            : 
    2650                 :            :         return true;
    2651                 :            : }
    2652                 :            : 
    2653                 :            : 
    2654                 :          0 : static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
    2655                 :            : {
    2656                 :          0 :         return id - DPLL_ID_ICL_MGPLL1;
    2657                 :            : }
    2658                 :            : 
    2659                 :          0 : enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
    2660                 :            : {
    2661                 :          0 :         return tc_port + DPLL_ID_ICL_MGPLL1;
    2662                 :            : }
    2663                 :            : 
    2664                 :          0 : static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
    2665                 :            :                                      u32 *target_dco_khz,
    2666                 :            :                                      struct intel_dpll_hw_state *state,
    2667                 :            :                                      bool is_dkl)
    2668                 :            : {
    2669                 :          0 :         u32 dco_min_freq, dco_max_freq;
    2670                 :          0 :         int div1_vals[] = {7, 5, 3, 2};
    2671                 :          0 :         unsigned int i;
    2672                 :          0 :         int div2;
    2673                 :            : 
    2674   [ #  #  #  # ]:          0 :         dco_min_freq = is_dp ? 8100000 : use_ssc ? 8000000 : 7992000;
    2675         [ #  # ]:          0 :         dco_max_freq = is_dp ? 8100000 : 10000000;
    2676                 :            : 
    2677         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
    2678                 :          0 :                 int div1 = div1_vals[i];
    2679                 :            : 
    2680         [ #  # ]:          0 :                 for (div2 = 10; div2 > 0; div2--) {
    2681                 :          0 :                         int dco = div1 * div2 * clock_khz * 5;
    2682                 :          0 :                         int a_divratio, tlinedrv, inputsel;
    2683                 :          0 :                         u32 hsdiv;
    2684                 :            : 
    2685         [ #  # ]:          0 :                         if (dco < dco_min_freq || dco > dco_max_freq)
    2686                 :          0 :                                 continue;
    2687                 :            : 
    2688         [ #  # ]:          0 :                         if (div2 >= 2) {
    2689                 :            :                                 /*
    2690                 :            :                                  * Note: a_divratio not matching TGL BSpec
    2691                 :            :                                  * algorithm but matching hardcoded values and
    2692                 :            :                                  * working on HW for DP alt-mode at least
    2693                 :            :                                  */
    2694         [ #  # ]:          0 :                                 a_divratio = is_dp ? 10 : 5;
    2695         [ #  # ]:          0 :                                 tlinedrv = is_dkl ? 1 : 2;
    2696                 :            :                         } else {
    2697                 :            :                                 a_divratio = 5;
    2698                 :            :                                 tlinedrv = 0;
    2699                 :            :                         }
    2700                 :          0 :                         inputsel = is_dp ? 0 : 1;
    2701                 :            : 
    2702   [ #  #  #  #  :          0 :                         switch (div1) {
                      # ]
    2703                 :            :                         default:
    2704                 :          0 :                                 MISSING_CASE(div1);
    2705                 :            :                                 /* fall through */
    2706                 :            :                         case 2:
    2707                 :            :                                 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;
    2708                 :            :                                 break;
    2709                 :            :                         case 3:
    2710                 :            :                                 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3;
    2711                 :            :                                 break;
    2712                 :          0 :                         case 5:
    2713                 :          0 :                                 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5;
    2714                 :          0 :                                 break;
    2715                 :          0 :                         case 7:
    2716                 :          0 :                                 hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7;
    2717                 :          0 :                                 break;
    2718                 :            :                         }
    2719                 :            : 
    2720                 :          0 :                         *target_dco_khz = dco;
    2721                 :            : 
    2722                 :          0 :                         state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
    2723                 :            : 
    2724                 :          0 :                         state->mg_clktop2_coreclkctl1 =
    2725                 :          0 :                                 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
    2726                 :            : 
    2727                 :          0 :                         state->mg_clktop2_hsclkctl =
    2728                 :          0 :                                 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
    2729                 :          0 :                                 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
    2730                 :          0 :                                 hsdiv |
    2731                 :          0 :                                 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
    2732                 :            : 
    2733                 :          0 :                         return true;
    2734                 :            :                 }
    2735                 :            :         }
    2736                 :            : 
    2737                 :            :         return false;
    2738                 :            : }
    2739                 :            : 
    2740                 :            : /*
    2741                 :            :  * The specification for this function uses real numbers, so the math had to be
    2742                 :            :  * adapted to integer-only calculation, that's why it looks so different.
    2743                 :            :  */
    2744                 :          0 : static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
    2745                 :            :                                   struct intel_dpll_hw_state *pll_state)
    2746                 :            : {
    2747                 :          0 :         struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    2748                 :          0 :         int refclk_khz = dev_priv->cdclk.hw.ref;
    2749                 :          0 :         int clock = crtc_state->port_clock;
    2750                 :          0 :         u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
    2751                 :          0 :         u32 iref_ndiv, iref_trim, iref_pulse_w;
    2752                 :          0 :         u32 prop_coeff, int_coeff;
    2753                 :          0 :         u32 tdc_targetcnt, feedfwgain;
    2754                 :          0 :         u64 ssc_stepsize, ssc_steplen, ssc_steplog;
    2755                 :          0 :         u64 tmp;
    2756                 :          0 :         bool use_ssc = false;
    2757                 :          0 :         bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
    2758                 :          0 :         bool is_dkl = INTEL_GEN(dev_priv) >= 12;
    2759                 :            : 
    2760                 :          0 :         memset(pll_state, 0, sizeof(*pll_state));
    2761                 :            : 
    2762         [ #  # ]:          0 :         if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
    2763                 :            :                                       pll_state, is_dkl)) {
    2764                 :          0 :                 DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock);
    2765                 :          0 :                 return false;
    2766                 :            :         }
    2767                 :            : 
    2768                 :          0 :         m1div = 2;
    2769                 :          0 :         m2div_int = dco_khz / (refclk_khz * m1div);
    2770         [ #  # ]:          0 :         if (m2div_int > 255) {
    2771         [ #  # ]:          0 :                 if (!is_dkl) {
    2772                 :          0 :                         m1div = 4;
    2773                 :          0 :                         m2div_int = dco_khz / (refclk_khz * m1div);
    2774                 :            :                 }
    2775                 :            : 
    2776         [ #  # ]:          0 :                 if (m2div_int > 255) {
    2777                 :          0 :                         DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n",
    2778                 :            :                                       clock);
    2779                 :          0 :                         return false;
    2780                 :            :                 }
    2781                 :            :         }
    2782                 :          0 :         m2div_rem = dco_khz % (refclk_khz * m1div);
    2783                 :            : 
    2784                 :          0 :         tmp = (u64)m2div_rem * (1 << 22);
    2785                 :          0 :         do_div(tmp, refclk_khz * m1div);
    2786                 :          0 :         m2div_frac = tmp;
    2787                 :            : 
    2788   [ #  #  #  # ]:          0 :         switch (refclk_khz) {
    2789                 :            :         case 19200:
    2790                 :            :                 iref_ndiv = 1;
    2791                 :            :                 iref_trim = 28;
    2792                 :            :                 iref_pulse_w = 1;
    2793                 :            :                 break;
    2794                 :          0 :         case 24000:
    2795                 :          0 :                 iref_ndiv = 1;
    2796                 :          0 :                 iref_trim = 25;
    2797                 :          0 :                 iref_pulse_w = 2;
    2798                 :          0 :                 break;
    2799                 :          0 :         case 38400:
    2800                 :          0 :                 iref_ndiv = 2;
    2801                 :          0 :                 iref_trim = 28;
    2802                 :          0 :                 iref_pulse_w = 1;
    2803                 :          0 :                 break;
    2804                 :            :         default:
    2805                 :          0 :                 MISSING_CASE(refclk_khz);
    2806                 :          0 :                 return false;
    2807                 :            :         }
    2808                 :            : 
    2809                 :            :         /*
    2810                 :            :          * tdc_res = 0.000003
    2811                 :            :          * tdc_targetcnt = int(2 / (tdc_res * 8 * 50 * 1.1) / refclk_mhz + 0.5)
    2812                 :            :          *
    2813                 :            :          * The multiplication by 1000 is due to refclk MHz to KHz conversion. It
    2814                 :            :          * was supposed to be a division, but we rearranged the operations of
    2815                 :            :          * the formula to avoid early divisions so we don't multiply the
    2816                 :            :          * rounding errors.
    2817                 :            :          *
    2818                 :            :          * 0.000003 * 8 * 50 * 1.1 = 0.00132, also known as 132 / 100000, which
    2819                 :            :          * we also rearrange to work with integers.
    2820                 :            :          *
    2821                 :            :          * The 0.5 transformed to 5 results in a multiplication by 10 and the
    2822                 :            :          * last division by 10.
    2823                 :            :          */
    2824                 :          0 :         tdc_targetcnt = (2 * 1000 * 100000 * 10 / (132 * refclk_khz) + 5) / 10;
    2825                 :            : 
    2826                 :            :         /*
    2827                 :            :          * Here we divide dco_khz by 10 in order to allow the dividend to fit in
    2828                 :            :          * 32 bits. That's not a problem since we round the division down
    2829                 :            :          * anyway.
    2830                 :            :          */
    2831                 :          0 :         feedfwgain = (use_ssc || m2div_rem > 0) ?
    2832         [ #  # ]:          0 :                 m1div * 1000000 * 100 / (dco_khz * 3 / 10) : 0;
    2833                 :            : 
    2834         [ #  # ]:          0 :         if (dco_khz >= 9000000) {
    2835                 :            :                 prop_coeff = 5;
    2836                 :            :                 int_coeff = 10;
    2837                 :            :         } else {
    2838                 :          0 :                 prop_coeff = 4;
    2839                 :          0 :                 int_coeff = 8;
    2840                 :            :         }
    2841                 :            : 
    2842                 :          0 :         if (use_ssc) {
    2843                 :            :                 tmp = mul_u32_u32(dco_khz, 47 * 32);
    2844                 :            :                 do_div(tmp, refclk_khz * m1div * 10000);
    2845                 :            :                 ssc_stepsize = tmp;
    2846                 :            : 
    2847                 :            :                 tmp = mul_u32_u32(dco_khz, 1000);
    2848                 :            :                 ssc_steplen = DIV_ROUND_UP_ULL(tmp, 32 * 2 * 32);
    2849                 :            :         } else {
    2850                 :          0 :                 ssc_stepsize = 0;
    2851                 :          0 :                 ssc_steplen = 0;
    2852                 :            :         }
    2853                 :          0 :         ssc_steplog = 4;
    2854                 :            : 
    2855                 :            :         /* write pll_state calculations */
    2856         [ #  # ]:          0 :         if (is_dkl) {
    2857                 :          0 :                 pll_state->mg_pll_div0 = DKL_PLL_DIV0_INTEG_COEFF(int_coeff) |
    2858                 :          0 :                                          DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
    2859                 :          0 :                                          DKL_PLL_DIV0_FBPREDIV(m1div) |
    2860                 :            :                                          DKL_PLL_DIV0_FBDIV_INT(m2div_int);
    2861                 :            : 
    2862                 :          0 :                 pll_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
    2863                 :            :                                          DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt);
    2864                 :            : 
    2865                 :          0 :                 pll_state->mg_pll_ssc = DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) |
    2866                 :          0 :                                         DKL_PLL_SSC_STEP_LEN(ssc_steplen) |
    2867                 :            :                                         DKL_PLL_SSC_STEP_NUM(ssc_steplog) |
    2868                 :            :                                         (use_ssc ? DKL_PLL_SSC_EN : 0);
    2869                 :            : 
    2870         [ #  # ]:          0 :                 pll_state->mg_pll_bias = (m2div_frac ? DKL_PLL_BIAS_FRAC_EN_H : 0) |
    2871                 :          0 :                                           DKL_PLL_BIAS_FBDIV_FRAC(m2div_frac);
    2872                 :            : 
    2873                 :          0 :                 pll_state->mg_pll_tdc_coldst_bias =
    2874                 :            :                                 DKL_PLL_TDC_SSC_STEP_SIZE(ssc_stepsize) |
    2875                 :            :                                 DKL_PLL_TDC_FEED_FWD_GAIN(feedfwgain);
    2876                 :            : 
    2877                 :            :         } else {
    2878                 :          0 :                 pll_state->mg_pll_div0 =
    2879         [ #  # ]:          0 :                         (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
    2880                 :          0 :                         MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
    2881                 :            :                         MG_PLL_DIV0_FBDIV_INT(m2div_int);
    2882                 :            : 
    2883                 :          0 :                 pll_state->mg_pll_div1 =
    2884                 :          0 :                         MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
    2885                 :            :                         MG_PLL_DIV1_DITHER_DIV_2 |
    2886                 :          0 :                         MG_PLL_DIV1_NDIVRATIO(1) |
    2887                 :            :                         MG_PLL_DIV1_FBPREDIV(m1div);
    2888                 :            : 
    2889                 :          0 :                 pll_state->mg_pll_lf =
    2890                 :          0 :                         MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
    2891                 :            :                         MG_PLL_LF_AFCCNTSEL_512 |
    2892                 :          0 :                         MG_PLL_LF_GAINCTRL(1) |
    2893                 :          0 :                         MG_PLL_LF_INT_COEFF(int_coeff) |
    2894                 :            :                         MG_PLL_LF_PROP_COEFF(prop_coeff);
    2895                 :            : 
    2896                 :          0 :                 pll_state->mg_pll_frac_lock =
    2897                 :            :                         MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
    2898                 :            :                         MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
    2899                 :            :                         MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
    2900                 :          0 :                         MG_PLL_FRAC_LOCK_DCODITHEREN |
    2901                 :            :                         MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
    2902         [ #  # ]:          0 :                 if (use_ssc || m2div_rem > 0)
    2903                 :          0 :                         pll_state->mg_pll_frac_lock |=
    2904                 :            :                                 MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
    2905                 :            : 
    2906                 :          0 :                 pll_state->mg_pll_ssc =
    2907                 :            :                         (use_ssc ? MG_PLL_SSC_EN : 0) |
    2908                 :            :                         MG_PLL_SSC_TYPE(2) |
    2909                 :            :                         MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
    2910                 :            :                         MG_PLL_SSC_STEPNUM(ssc_steplog) |
    2911                 :            :                         MG_PLL_SSC_FLLEN |
    2912                 :            :                         MG_PLL_SSC_STEPSIZE(ssc_stepsize);
    2913                 :            : 
    2914                 :          0 :                 pll_state->mg_pll_tdc_coldst_bias =
    2915                 :            :                         MG_PLL_TDC_COLDST_COLDSTART |
    2916                 :            :                         MG_PLL_TDC_COLDST_IREFINT_EN |
    2917                 :          0 :                         MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
    2918                 :          0 :                         MG_PLL_TDC_TDCOVCCORR_EN |
    2919                 :            :                         MG_PLL_TDC_TDCSEL(3);
    2920                 :            : 
    2921                 :          0 :                 pll_state->mg_pll_bias =
    2922                 :            :                         MG_PLL_BIAS_BIAS_GB_SEL(3) |
    2923                 :            :                         MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
    2924                 :            :                         MG_PLL_BIAS_BIAS_BONUS(10) |
    2925                 :            :                         MG_PLL_BIAS_BIASCAL_EN |
    2926                 :            :                         MG_PLL_BIAS_CTRIM(12) |
    2927                 :          0 :                         MG_PLL_BIAS_VREF_RDAC(4) |
    2928                 :            :                         MG_PLL_BIAS_IREFTRIM(iref_trim);
    2929                 :            : 
    2930         [ #  # ]:          0 :                 if (refclk_khz == 38400) {
    2931                 :          0 :                         pll_state->mg_pll_tdc_coldst_bias_mask =
    2932                 :            :                                 MG_PLL_TDC_COLDST_COLDSTART;
    2933                 :          0 :                         pll_state->mg_pll_bias_mask = 0;
    2934                 :            :                 } else {
    2935                 :          0 :                         pll_state->mg_pll_tdc_coldst_bias_mask = -1U;
    2936                 :          0 :                         pll_state->mg_pll_bias_mask = -1U;
    2937                 :            :                 }
    2938                 :            : 
    2939                 :          0 :                 pll_state->mg_pll_tdc_coldst_bias &=
    2940                 :          0 :                         pll_state->mg_pll_tdc_coldst_bias_mask;
    2941                 :          0 :                 pll_state->mg_pll_bias &= pll_state->mg_pll_bias_mask;
    2942                 :            :         }
    2943                 :            : 
    2944                 :            :         return true;
    2945                 :            : }
    2946                 :            : 
    2947                 :            : /**
    2948                 :            :  * icl_set_active_port_dpll - select the active port DPLL for a given CRTC
    2949                 :            :  * @crtc_state: state for the CRTC to select the DPLL for
    2950                 :            :  * @port_dpll_id: the active @port_dpll_id to select
    2951                 :            :  *
    2952                 :            :  * Select the given @port_dpll_id instance from the DPLLs reserved for the
    2953                 :            :  * CRTC.
    2954                 :            :  */
    2955                 :          0 : void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
    2956                 :            :                               enum icl_port_dpll_id port_dpll_id)
    2957                 :            : {
    2958                 :          0 :         struct icl_port_dpll *port_dpll =
    2959                 :            :                 &crtc_state->icl_port_dplls[port_dpll_id];
    2960                 :            : 
    2961                 :          0 :         crtc_state->shared_dpll = port_dpll->pll;
    2962                 :          0 :         crtc_state->dpll_hw_state = port_dpll->hw_state;
    2963                 :          0 : }
    2964                 :            : 
    2965                 :          0 : static void icl_update_active_dpll(struct intel_atomic_state *state,
    2966                 :            :                                    struct intel_crtc *crtc,
    2967                 :            :                                    struct intel_encoder *encoder)
    2968                 :            : {
    2969         [ #  # ]:          0 :         struct intel_crtc_state *crtc_state =
    2970                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    2971                 :          0 :         struct intel_digital_port *primary_port;
    2972                 :          0 :         enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT;
    2973                 :            : 
    2974                 :          0 :         primary_port = encoder->type == INTEL_OUTPUT_DP_MST ?
    2975         [ #  # ]:          0 :                 enc_to_mst(encoder)->primary :
    2976                 :            :                 enc_to_dig_port(encoder);
    2977                 :            : 
    2978         [ #  # ]:          0 :         if (primary_port &&
    2979         [ #  # ]:          0 :             (primary_port->tc_mode == TC_PORT_DP_ALT ||
    2980                 :            :              primary_port->tc_mode == TC_PORT_LEGACY))
    2981                 :          0 :                 port_dpll_id = ICL_PORT_DPLL_MG_PHY;
    2982                 :            : 
    2983                 :          0 :         icl_set_active_port_dpll(crtc_state, port_dpll_id);
    2984                 :          0 : }
    2985                 :            : 
    2986                 :          0 : static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
    2987                 :            :                                    struct intel_crtc *crtc,
    2988                 :            :                                    struct intel_encoder *encoder)
    2989                 :            : {
    2990                 :          0 :         struct intel_crtc_state *crtc_state =
    2991                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    2992                 :          0 :         struct icl_port_dpll *port_dpll =
    2993                 :            :                 &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
    2994                 :          0 :         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    2995                 :          0 :         enum port port = encoder->port;
    2996                 :          0 :         unsigned long dpll_mask;
    2997                 :            : 
    2998         [ #  # ]:          0 :         if (!icl_calc_dpll_state(crtc_state, encoder, &port_dpll->hw_state)) {
    2999                 :          0 :                 DRM_DEBUG_KMS("Could not calculate combo PHY PLL state.\n");
    3000                 :            : 
    3001                 :          0 :                 return false;
    3002                 :            :         }
    3003                 :            : 
    3004   [ #  #  #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv) && port != PORT_A)
    3005                 :            :                 dpll_mask =
    3006                 :            :                         BIT(DPLL_ID_EHL_DPLL4) |
    3007                 :            :                         BIT(DPLL_ID_ICL_DPLL1) |
    3008                 :            :                         BIT(DPLL_ID_ICL_DPLL0);
    3009                 :            :         else
    3010                 :          0 :                 dpll_mask = BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0);
    3011                 :            : 
    3012                 :          0 :         port_dpll->pll = intel_find_shared_dpll(state, crtc,
    3013                 :            :                                                 &port_dpll->hw_state,
    3014                 :            :                                                 dpll_mask);
    3015         [ #  # ]:          0 :         if (!port_dpll->pll) {
    3016                 :          0 :                 DRM_DEBUG_KMS("No combo PHY PLL found for [ENCODER:%d:%s]\n",
    3017                 :            :                               encoder->base.base.id, encoder->base.name);
    3018                 :          0 :                 return false;
    3019                 :            :         }
    3020                 :            : 
    3021                 :          0 :         intel_reference_shared_dpll(state, crtc,
    3022                 :            :                                     port_dpll->pll, &port_dpll->hw_state);
    3023                 :            : 
    3024                 :          0 :         icl_update_active_dpll(state, crtc, encoder);
    3025                 :            : 
    3026                 :          0 :         return true;
    3027                 :            : }
    3028                 :            : 
    3029                 :          0 : static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
    3030                 :            :                                  struct intel_crtc *crtc,
    3031                 :            :                                  struct intel_encoder *encoder)
    3032                 :            : {
    3033                 :          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
    3034                 :          0 :         struct intel_crtc_state *crtc_state =
    3035                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    3036                 :          0 :         struct icl_port_dpll *port_dpll;
    3037                 :          0 :         enum intel_dpll_id dpll_id;
    3038                 :            : 
    3039                 :          0 :         port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
    3040         [ #  # ]:          0 :         if (!icl_calc_dpll_state(crtc_state, encoder, &port_dpll->hw_state)) {
    3041                 :          0 :                 DRM_DEBUG_KMS("Could not calculate TBT PLL state.\n");
    3042                 :          0 :                 return false;
    3043                 :            :         }
    3044                 :            : 
    3045                 :          0 :         port_dpll->pll = intel_find_shared_dpll(state, crtc,
    3046                 :            :                                                 &port_dpll->hw_state,
    3047                 :            :                                                 BIT(DPLL_ID_ICL_TBTPLL));
    3048         [ #  # ]:          0 :         if (!port_dpll->pll) {
    3049                 :          0 :                 DRM_DEBUG_KMS("No TBT-ALT PLL found\n");
    3050                 :          0 :                 return false;
    3051                 :            :         }
    3052                 :          0 :         intel_reference_shared_dpll(state, crtc,
    3053                 :            :                                     port_dpll->pll, &port_dpll->hw_state);
    3054                 :            : 
    3055                 :            : 
    3056                 :          0 :         port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
    3057         [ #  # ]:          0 :         if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state)) {
    3058                 :          0 :                 DRM_DEBUG_KMS("Could not calculate MG PHY PLL state.\n");
    3059                 :          0 :                 goto err_unreference_tbt_pll;
    3060                 :            :         }
    3061                 :            : 
    3062                 :          0 :         dpll_id = icl_tc_port_to_pll_id(intel_port_to_tc(dev_priv,
    3063                 :            :                                                          encoder->port));
    3064                 :          0 :         port_dpll->pll = intel_find_shared_dpll(state, crtc,
    3065                 :            :                                                 &port_dpll->hw_state,
    3066                 :            :                                                 BIT(dpll_id));
    3067         [ #  # ]:          0 :         if (!port_dpll->pll) {
    3068                 :          0 :                 DRM_DEBUG_KMS("No MG PHY PLL found\n");
    3069                 :          0 :                 goto err_unreference_tbt_pll;
    3070                 :            :         }
    3071                 :          0 :         intel_reference_shared_dpll(state, crtc,
    3072                 :            :                                     port_dpll->pll, &port_dpll->hw_state);
    3073                 :            : 
    3074                 :          0 :         icl_update_active_dpll(state, crtc, encoder);
    3075                 :            : 
    3076                 :          0 :         return true;
    3077                 :            : 
    3078                 :          0 : err_unreference_tbt_pll:
    3079                 :          0 :         port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
    3080                 :          0 :         intel_unreference_shared_dpll(state, crtc, port_dpll->pll);
    3081                 :            : 
    3082                 :          0 :         return false;
    3083                 :            : }
    3084                 :            : 
    3085                 :          0 : static bool icl_get_dplls(struct intel_atomic_state *state,
    3086                 :            :                           struct intel_crtc *crtc,
    3087                 :            :                           struct intel_encoder *encoder)
    3088                 :            : {
    3089                 :          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
    3090                 :          0 :         enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
    3091                 :            : 
    3092         [ #  # ]:          0 :         if (intel_phy_is_combo(dev_priv, phy))
    3093                 :          0 :                 return icl_get_combo_phy_dpll(state, crtc, encoder);
    3094         [ #  # ]:          0 :         else if (intel_phy_is_tc(dev_priv, phy))
    3095                 :          0 :                 return icl_get_tc_phy_dplls(state, crtc, encoder);
    3096                 :            : 
    3097                 :          0 :         MISSING_CASE(phy);
    3098                 :            : 
    3099                 :          0 :         return false;
    3100                 :            : }
    3101                 :            : 
    3102                 :          0 : static void icl_put_dplls(struct intel_atomic_state *state,
    3103                 :            :                           struct intel_crtc *crtc)
    3104                 :            : {
    3105                 :          0 :         const struct intel_crtc_state *old_crtc_state =
    3106                 :            :                 intel_atomic_get_old_crtc_state(state, crtc);
    3107                 :          0 :         struct intel_crtc_state *new_crtc_state =
    3108                 :            :                 intel_atomic_get_new_crtc_state(state, crtc);
    3109                 :          0 :         enum icl_port_dpll_id id;
    3110                 :            : 
    3111                 :          0 :         new_crtc_state->shared_dpll = NULL;
    3112                 :            : 
    3113         [ #  # ]:          0 :         for (id = ICL_PORT_DPLL_DEFAULT; id < ICL_PORT_DPLL_COUNT; id++) {
    3114                 :          0 :                 const struct icl_port_dpll *old_port_dpll =
    3115                 :            :                         &old_crtc_state->icl_port_dplls[id];
    3116                 :          0 :                 struct icl_port_dpll *new_port_dpll =
    3117                 :            :                         &new_crtc_state->icl_port_dplls[id];
    3118                 :            : 
    3119                 :          0 :                 new_port_dpll->pll = NULL;
    3120                 :            : 
    3121         [ #  # ]:          0 :                 if (!old_port_dpll->pll)
    3122                 :          0 :                         continue;
    3123                 :            : 
    3124                 :          0 :                 intel_unreference_shared_dpll(state, crtc, old_port_dpll->pll);
    3125                 :            :         }
    3126                 :          0 : }
    3127                 :            : 
    3128                 :          0 : static bool mg_pll_get_hw_state(struct drm_i915_private *dev_priv,
    3129                 :            :                                 struct intel_shared_dpll *pll,
    3130                 :            :                                 struct intel_dpll_hw_state *hw_state)
    3131                 :            : {
    3132                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    3133                 :          0 :         enum tc_port tc_port = icl_pll_id_to_tc_port(id);
    3134                 :          0 :         intel_wakeref_t wakeref;
    3135                 :          0 :         bool ret = false;
    3136                 :          0 :         u32 val;
    3137                 :            : 
    3138                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    3139                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    3140         [ #  # ]:          0 :         if (!wakeref)
    3141                 :            :                 return false;
    3142                 :            : 
    3143                 :          0 :         val = I915_READ(MG_PLL_ENABLE(tc_port));
    3144         [ #  # ]:          0 :         if (!(val & PLL_ENABLE))
    3145                 :          0 :                 goto out;
    3146                 :            : 
    3147                 :          0 :         hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(tc_port));
    3148                 :          0 :         hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
    3149                 :            : 
    3150                 :          0 :         hw_state->mg_clktop2_coreclkctl1 =
    3151                 :          0 :                 I915_READ(MG_CLKTOP2_CORECLKCTL1(tc_port));
    3152                 :          0 :         hw_state->mg_clktop2_coreclkctl1 &=
    3153                 :            :                 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
    3154                 :            : 
    3155                 :          0 :         hw_state->mg_clktop2_hsclkctl =
    3156                 :          0 :                 I915_READ(MG_CLKTOP2_HSCLKCTL(tc_port));
    3157                 :          0 :         hw_state->mg_clktop2_hsclkctl &=
    3158                 :            :                 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
    3159                 :            :                 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
    3160                 :            :                 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
    3161                 :            :                 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
    3162                 :            : 
    3163                 :          0 :         hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(tc_port));
    3164                 :          0 :         hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(tc_port));
    3165                 :          0 :         hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(tc_port));
    3166                 :          0 :         hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(tc_port));
    3167                 :          0 :         hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(tc_port));
    3168                 :            : 
    3169                 :          0 :         hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(tc_port));
    3170                 :          0 :         hw_state->mg_pll_tdc_coldst_bias =
    3171                 :          0 :                 I915_READ(MG_PLL_TDC_COLDST_BIAS(tc_port));
    3172                 :            : 
    3173         [ #  # ]:          0 :         if (dev_priv->cdclk.hw.ref == 38400) {
    3174                 :          0 :                 hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
    3175                 :          0 :                 hw_state->mg_pll_bias_mask = 0;
    3176                 :            :         } else {
    3177                 :          0 :                 hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
    3178                 :          0 :                 hw_state->mg_pll_bias_mask = -1U;
    3179                 :            :         }
    3180                 :            : 
    3181                 :          0 :         hw_state->mg_pll_tdc_coldst_bias &= hw_state->mg_pll_tdc_coldst_bias_mask;
    3182                 :          0 :         hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
    3183                 :            : 
    3184                 :          0 :         ret = true;
    3185                 :          0 : out:
    3186                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    3187                 :          0 :         return ret;
    3188                 :            : }
    3189                 :            : 
    3190                 :          0 : static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
    3191                 :            :                                  struct intel_shared_dpll *pll,
    3192                 :            :                                  struct intel_dpll_hw_state *hw_state)
    3193                 :            : {
    3194                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    3195                 :          0 :         enum tc_port tc_port = icl_pll_id_to_tc_port(id);
    3196                 :          0 :         intel_wakeref_t wakeref;
    3197                 :          0 :         bool ret = false;
    3198                 :          0 :         u32 val;
    3199                 :            : 
    3200                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    3201                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    3202         [ #  # ]:          0 :         if (!wakeref)
    3203                 :            :                 return false;
    3204                 :            : 
    3205                 :          0 :         val = I915_READ(MG_PLL_ENABLE(tc_port));
    3206         [ #  # ]:          0 :         if (!(val & PLL_ENABLE))
    3207                 :          0 :                 goto out;
    3208                 :            : 
    3209                 :            :         /*
    3210                 :            :          * All registers read here have the same HIP_INDEX_REG even though
    3211                 :            :          * they are on different building blocks
    3212                 :            :          */
    3213         [ #  # ]:          0 :         I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x2));
    3214                 :            : 
    3215                 :          0 :         hw_state->mg_refclkin_ctl = I915_READ(DKL_REFCLKIN_CTL(tc_port));
    3216                 :          0 :         hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
    3217                 :            : 
    3218                 :          0 :         hw_state->mg_clktop2_hsclkctl =
    3219                 :          0 :                 I915_READ(DKL_CLKTOP2_HSCLKCTL(tc_port));
    3220                 :          0 :         hw_state->mg_clktop2_hsclkctl &=
    3221                 :            :                 MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
    3222                 :            :                 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
    3223                 :            :                 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
    3224                 :            :                 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
    3225                 :            : 
    3226                 :          0 :         hw_state->mg_clktop2_coreclkctl1 =
    3227                 :          0 :                 I915_READ(DKL_CLKTOP2_CORECLKCTL1(tc_port));
    3228                 :          0 :         hw_state->mg_clktop2_coreclkctl1 &=
    3229                 :            :                 MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
    3230                 :            : 
    3231                 :          0 :         hw_state->mg_pll_div0 = I915_READ(DKL_PLL_DIV0(tc_port));
    3232                 :          0 :         hw_state->mg_pll_div0 &= (DKL_PLL_DIV0_INTEG_COEFF_MASK |
    3233                 :            :                                   DKL_PLL_DIV0_PROP_COEFF_MASK |
    3234                 :            :                                   DKL_PLL_DIV0_FBPREDIV_MASK |
    3235                 :            :                                   DKL_PLL_DIV0_FBDIV_INT_MASK);
    3236                 :            : 
    3237                 :          0 :         hw_state->mg_pll_div1 = I915_READ(DKL_PLL_DIV1(tc_port));
    3238                 :          0 :         hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
    3239                 :            :                                   DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
    3240                 :            : 
    3241                 :          0 :         hw_state->mg_pll_ssc = I915_READ(DKL_PLL_SSC(tc_port));
    3242                 :          0 :         hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
    3243                 :            :                                  DKL_PLL_SSC_STEP_LEN_MASK |
    3244                 :            :                                  DKL_PLL_SSC_STEP_NUM_MASK |
    3245                 :            :                                  DKL_PLL_SSC_EN);
    3246                 :            : 
    3247                 :          0 :         hw_state->mg_pll_bias = I915_READ(DKL_PLL_BIAS(tc_port));
    3248                 :          0 :         hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H |
    3249                 :            :                                   DKL_PLL_BIAS_FBDIV_FRAC_MASK);
    3250                 :            : 
    3251                 :          0 :         hw_state->mg_pll_tdc_coldst_bias =
    3252                 :          0 :                 I915_READ(DKL_PLL_TDC_COLDST_BIAS(tc_port));
    3253                 :          0 :         hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
    3254                 :            :                                              DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
    3255                 :            : 
    3256                 :          0 :         ret = true;
    3257                 :          0 : out:
    3258                 :          0 :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    3259                 :          0 :         return ret;
    3260                 :            : }
    3261                 :            : 
    3262                 :            : static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
    3263                 :            :                                  struct intel_shared_dpll *pll,
    3264                 :            :                                  struct intel_dpll_hw_state *hw_state,
    3265                 :            :                                  i915_reg_t enable_reg)
    3266                 :            : {
    3267                 :            :         const enum intel_dpll_id id = pll->info->id;
    3268                 :            :         intel_wakeref_t wakeref;
    3269                 :            :         bool ret = false;
    3270                 :            :         u32 val;
    3271                 :            : 
    3272                 :            :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    3273                 :            :                                                      POWER_DOMAIN_DISPLAY_CORE);
    3274                 :            :         if (!wakeref)
    3275                 :            :                 return false;
    3276                 :            : 
    3277                 :            :         val = I915_READ(enable_reg);
    3278                 :            :         if (!(val & PLL_ENABLE))
    3279                 :            :                 goto out;
    3280                 :            : 
    3281                 :            :         if (INTEL_GEN(dev_priv) >= 12) {
    3282                 :            :                 hw_state->cfgcr0 = I915_READ(TGL_DPLL_CFGCR0(id));
    3283                 :            :                 hw_state->cfgcr1 = I915_READ(TGL_DPLL_CFGCR1(id));
    3284                 :            :         } else {
    3285                 :            :                 if (IS_ELKHARTLAKE(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
    3286                 :            :                         hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(4));
    3287                 :            :                         hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(4));
    3288                 :            :                 } else {
    3289                 :            :                         hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(id));
    3290                 :            :                         hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(id));
    3291                 :            :                 }
    3292                 :            :         }
    3293                 :            : 
    3294                 :            :         ret = true;
    3295                 :            : out:
    3296                 :            :         intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
    3297                 :            :         return ret;
    3298                 :            : }
    3299                 :            : 
    3300                 :          0 : static bool combo_pll_get_hw_state(struct drm_i915_private *dev_priv,
    3301                 :            :                                    struct intel_shared_dpll *pll,
    3302                 :            :                                    struct intel_dpll_hw_state *hw_state)
    3303                 :            : {
    3304                 :          0 :         i915_reg_t enable_reg = CNL_DPLL_ENABLE(pll->info->id);
    3305                 :            : 
    3306   [ #  #  #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv) &&
    3307                 :            :             pll->info->id == DPLL_ID_EHL_DPLL4) {
    3308                 :          0 :                 enable_reg = MG_PLL_ENABLE(0);
    3309                 :            :         }
    3310                 :            : 
    3311                 :          0 :         return icl_pll_get_hw_state(dev_priv, pll, hw_state, enable_reg);
    3312                 :            : }
    3313                 :            : 
    3314                 :          0 : static bool tbt_pll_get_hw_state(struct drm_i915_private *dev_priv,
    3315                 :            :                                  struct intel_shared_dpll *pll,
    3316                 :            :                                  struct intel_dpll_hw_state *hw_state)
    3317                 :            : {
    3318                 :          0 :         return icl_pll_get_hw_state(dev_priv, pll, hw_state, TBT_PLL_ENABLE);
    3319                 :            : }
    3320                 :            : 
    3321                 :          0 : static void icl_dpll_write(struct drm_i915_private *dev_priv,
    3322                 :            :                            struct intel_shared_dpll *pll)
    3323                 :            : {
    3324                 :          0 :         struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
    3325                 :          0 :         const enum intel_dpll_id id = pll->info->id;
    3326                 :          0 :         i915_reg_t cfgcr0_reg, cfgcr1_reg;
    3327                 :            : 
    3328         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 12) {
    3329                 :          0 :                 cfgcr0_reg = TGL_DPLL_CFGCR0(id);
    3330                 :          0 :                 cfgcr1_reg = TGL_DPLL_CFGCR1(id);
    3331                 :            :         } else {
    3332   [ #  #  #  # ]:          0 :                 if (IS_ELKHARTLAKE(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
    3333                 :            :                         cfgcr0_reg = ICL_DPLL_CFGCR0(4);
    3334                 :            :                         cfgcr1_reg = ICL_DPLL_CFGCR1(4);
    3335                 :            :                 } else {
    3336                 :          0 :                         cfgcr0_reg = ICL_DPLL_CFGCR0(id);
    3337                 :          0 :                         cfgcr1_reg = ICL_DPLL_CFGCR1(id);
    3338                 :            :                 }
    3339                 :            :         }
    3340                 :            : 
    3341                 :          0 :         I915_WRITE(cfgcr0_reg, hw_state->cfgcr0);
    3342                 :          0 :         I915_WRITE(cfgcr1_reg, hw_state->cfgcr1);
    3343                 :          0 :         POSTING_READ(cfgcr1_reg);
    3344                 :          0 : }
    3345                 :            : 
    3346                 :          0 : static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
    3347                 :            :                              struct intel_shared_dpll *pll)
    3348                 :            : {
    3349                 :          0 :         struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
    3350                 :          0 :         enum tc_port tc_port = icl_pll_id_to_tc_port(pll->info->id);
    3351                 :          0 :         u32 val;
    3352                 :            : 
    3353                 :            :         /*
    3354                 :            :          * Some of the following registers have reserved fields, so program
    3355                 :            :          * these with RMW based on a mask. The mask can be fixed or generated
    3356                 :            :          * during the calc/readout phase if the mask depends on some other HW
    3357                 :            :          * state like refclk, see icl_calc_mg_pll_state().
    3358                 :            :          */
    3359                 :          0 :         val = I915_READ(MG_REFCLKIN_CTL(tc_port));
    3360                 :          0 :         val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
    3361                 :          0 :         val |= hw_state->mg_refclkin_ctl;
    3362                 :          0 :         I915_WRITE(MG_REFCLKIN_CTL(tc_port), val);
    3363                 :            : 
    3364                 :          0 :         val = I915_READ(MG_CLKTOP2_CORECLKCTL1(tc_port));
    3365                 :          0 :         val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
    3366                 :          0 :         val |= hw_state->mg_clktop2_coreclkctl1;
    3367                 :          0 :         I915_WRITE(MG_CLKTOP2_CORECLKCTL1(tc_port), val);
    3368                 :            : 
    3369                 :          0 :         val = I915_READ(MG_CLKTOP2_HSCLKCTL(tc_port));
    3370                 :          0 :         val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
    3371                 :            :                  MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
    3372                 :            :                  MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
    3373                 :            :                  MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
    3374                 :          0 :         val |= hw_state->mg_clktop2_hsclkctl;
    3375                 :          0 :         I915_WRITE(MG_CLKTOP2_HSCLKCTL(tc_port), val);
    3376                 :            : 
    3377                 :          0 :         I915_WRITE(MG_PLL_DIV0(tc_port), hw_state->mg_pll_div0);
    3378                 :          0 :         I915_WRITE(MG_PLL_DIV1(tc_port), hw_state->mg_pll_div1);
    3379                 :          0 :         I915_WRITE(MG_PLL_LF(tc_port), hw_state->mg_pll_lf);
    3380                 :          0 :         I915_WRITE(MG_PLL_FRAC_LOCK(tc_port), hw_state->mg_pll_frac_lock);
    3381                 :          0 :         I915_WRITE(MG_PLL_SSC(tc_port), hw_state->mg_pll_ssc);
    3382                 :            : 
    3383                 :          0 :         val = I915_READ(MG_PLL_BIAS(tc_port));
    3384                 :          0 :         val &= ~hw_state->mg_pll_bias_mask;
    3385                 :          0 :         val |= hw_state->mg_pll_bias;
    3386                 :          0 :         I915_WRITE(MG_PLL_BIAS(tc_port), val);
    3387                 :            : 
    3388                 :          0 :         val = I915_READ(MG_PLL_TDC_COLDST_BIAS(tc_port));
    3389                 :          0 :         val &= ~hw_state->mg_pll_tdc_coldst_bias_mask;
    3390                 :          0 :         val |= hw_state->mg_pll_tdc_coldst_bias;
    3391                 :          0 :         I915_WRITE(MG_PLL_TDC_COLDST_BIAS(tc_port), val);
    3392                 :            : 
    3393                 :          0 :         POSTING_READ(MG_PLL_TDC_COLDST_BIAS(tc_port));
    3394                 :          0 : }
    3395                 :            : 
    3396                 :          0 : static void dkl_pll_write(struct drm_i915_private *dev_priv,
    3397                 :            :                           struct intel_shared_dpll *pll)
    3398                 :            : {
    3399                 :          0 :         struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
    3400                 :          0 :         enum tc_port tc_port = icl_pll_id_to_tc_port(pll->info->id);
    3401                 :          0 :         u32 val;
    3402                 :            : 
    3403                 :            :         /*
    3404                 :            :          * All registers programmed here have the same HIP_INDEX_REG even
    3405                 :            :          * though on different building block
    3406                 :            :          */
    3407         [ #  # ]:          0 :         I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x2));
    3408                 :            : 
    3409                 :            :         /* All the registers are RMW */
    3410                 :          0 :         val = I915_READ(DKL_REFCLKIN_CTL(tc_port));
    3411                 :          0 :         val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
    3412                 :          0 :         val |= hw_state->mg_refclkin_ctl;
    3413                 :          0 :         I915_WRITE(DKL_REFCLKIN_CTL(tc_port), val);
    3414                 :            : 
    3415                 :          0 :         val = I915_READ(DKL_CLKTOP2_CORECLKCTL1(tc_port));
    3416                 :          0 :         val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
    3417                 :          0 :         val |= hw_state->mg_clktop2_coreclkctl1;
    3418                 :          0 :         I915_WRITE(DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
    3419                 :            : 
    3420                 :          0 :         val = I915_READ(DKL_CLKTOP2_HSCLKCTL(tc_port));
    3421                 :          0 :         val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
    3422                 :            :                  MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
    3423                 :            :                  MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
    3424                 :            :                  MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
    3425                 :          0 :         val |= hw_state->mg_clktop2_hsclkctl;
    3426                 :          0 :         I915_WRITE(DKL_CLKTOP2_HSCLKCTL(tc_port), val);
    3427                 :            : 
    3428                 :          0 :         val = I915_READ(DKL_PLL_DIV0(tc_port));
    3429                 :          0 :         val &= ~(DKL_PLL_DIV0_INTEG_COEFF_MASK |
    3430                 :            :                  DKL_PLL_DIV0_PROP_COEFF_MASK |
    3431                 :            :                  DKL_PLL_DIV0_FBPREDIV_MASK |
    3432                 :            :                  DKL_PLL_DIV0_FBDIV_INT_MASK);
    3433                 :          0 :         val |= hw_state->mg_pll_div0;
    3434                 :          0 :         I915_WRITE(DKL_PLL_DIV0(tc_port), val);
    3435                 :            : 
    3436                 :          0 :         val = I915_READ(DKL_PLL_DIV1(tc_port));
    3437                 :          0 :         val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
    3438                 :            :                  DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
    3439                 :          0 :         val |= hw_state->mg_pll_div1;
    3440                 :          0 :         I915_WRITE(DKL_PLL_DIV1(tc_port), val);
    3441                 :            : 
    3442                 :          0 :         val = I915_READ(DKL_PLL_SSC(tc_port));
    3443                 :          0 :         val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
    3444                 :            :                  DKL_PLL_SSC_STEP_LEN_MASK |
    3445                 :            :                  DKL_PLL_SSC_STEP_NUM_MASK |
    3446                 :            :                  DKL_PLL_SSC_EN);
    3447                 :          0 :         val |= hw_state->mg_pll_ssc;
    3448                 :          0 :         I915_WRITE(DKL_PLL_SSC(tc_port), val);
    3449                 :            : 
    3450                 :          0 :         val = I915_READ(DKL_PLL_BIAS(tc_port));
    3451                 :          0 :         val &= ~(DKL_PLL_BIAS_FRAC_EN_H |
    3452                 :            :                  DKL_PLL_BIAS_FBDIV_FRAC_MASK);
    3453                 :          0 :         val |= hw_state->mg_pll_bias;
    3454                 :          0 :         I915_WRITE(DKL_PLL_BIAS(tc_port), val);
    3455                 :            : 
    3456                 :          0 :         val = I915_READ(DKL_PLL_TDC_COLDST_BIAS(tc_port));
    3457                 :          0 :         val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
    3458                 :            :                  DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
    3459                 :          0 :         val |= hw_state->mg_pll_tdc_coldst_bias;
    3460                 :          0 :         I915_WRITE(DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
    3461                 :            : 
    3462                 :          0 :         POSTING_READ(DKL_PLL_TDC_COLDST_BIAS(tc_port));
    3463                 :          0 : }
    3464                 :            : 
    3465                 :            : static void icl_pll_power_enable(struct drm_i915_private *dev_priv,
    3466                 :            :                                  struct intel_shared_dpll *pll,
    3467                 :            :                                  i915_reg_t enable_reg)
    3468                 :            : {
    3469                 :            :         u32 val;
    3470                 :            : 
    3471                 :            :         val = I915_READ(enable_reg);
    3472                 :            :         val |= PLL_POWER_ENABLE;
    3473                 :            :         I915_WRITE(enable_reg, val);
    3474                 :            : 
    3475                 :            :         /*
    3476                 :            :          * The spec says we need to "wait" but it also says it should be
    3477                 :            :          * immediate.
    3478                 :            :          */
    3479                 :            :         if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_POWER_STATE, 1))
    3480                 :            :                 DRM_ERROR("PLL %d Power not enabled\n", pll->info->id);
    3481                 :            : }
    3482                 :            : 
    3483                 :            : static void icl_pll_enable(struct drm_i915_private *dev_priv,
    3484                 :            :                            struct intel_shared_dpll *pll,
    3485                 :            :                            i915_reg_t enable_reg)
    3486                 :            : {
    3487                 :            :         u32 val;
    3488                 :            : 
    3489                 :            :         val = I915_READ(enable_reg);
    3490                 :            :         val |= PLL_ENABLE;
    3491                 :            :         I915_WRITE(enable_reg, val);
    3492                 :            : 
    3493                 :            :         /* Timeout is actually 600us. */
    3494                 :            :         if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 1))
    3495                 :            :                 DRM_ERROR("PLL %d not locked\n", pll->info->id);
    3496                 :            : }
    3497                 :            : 
    3498                 :          0 : static void combo_pll_enable(struct drm_i915_private *dev_priv,
    3499                 :            :                              struct intel_shared_dpll *pll)
    3500                 :            : {
    3501                 :          0 :         i915_reg_t enable_reg = CNL_DPLL_ENABLE(pll->info->id);
    3502                 :            : 
    3503   [ #  #  #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv) &&
    3504                 :            :             pll->info->id == DPLL_ID_EHL_DPLL4) {
    3505                 :          0 :                 enable_reg = MG_PLL_ENABLE(0);
    3506                 :            : 
    3507                 :            :                 /*
    3508                 :            :                  * We need to disable DC states when this DPLL is enabled.
    3509                 :            :                  * This can be done by taking a reference on DPLL4 power
    3510                 :            :                  * domain.
    3511                 :            :                  */
    3512                 :          0 :                 pll->wakeref = intel_display_power_get(dev_priv,
    3513                 :            :                                                        POWER_DOMAIN_DPLL_DC_OFF);
    3514                 :            :         }
    3515                 :            : 
    3516                 :          0 :         icl_pll_power_enable(dev_priv, pll, enable_reg);
    3517                 :            : 
    3518                 :          0 :         icl_dpll_write(dev_priv, pll);
    3519                 :            : 
    3520                 :            :         /*
    3521                 :            :          * DVFS pre sequence would be here, but in our driver the cdclk code
    3522                 :            :          * paths should already be setting the appropriate voltage, hence we do
    3523                 :            :          * nothing here.
    3524                 :            :          */
    3525                 :            : 
    3526                 :          0 :         icl_pll_enable(dev_priv, pll, enable_reg);
    3527                 :            : 
    3528                 :            :         /* DVFS post sequence would be here. See the comment above. */
    3529                 :          0 : }
    3530                 :            : 
    3531                 :          0 : static void tbt_pll_enable(struct drm_i915_private *dev_priv,
    3532                 :            :                            struct intel_shared_dpll *pll)
    3533                 :            : {
    3534                 :          0 :         icl_pll_power_enable(dev_priv, pll, TBT_PLL_ENABLE);
    3535                 :            : 
    3536                 :          0 :         icl_dpll_write(dev_priv, pll);
    3537                 :            : 
    3538                 :            :         /*
    3539                 :            :          * DVFS pre sequence would be here, but in our driver the cdclk code
    3540                 :            :          * paths should already be setting the appropriate voltage, hence we do
    3541                 :            :          * nothing here.
    3542                 :            :          */
    3543                 :            : 
    3544                 :          0 :         icl_pll_enable(dev_priv, pll, TBT_PLL_ENABLE);
    3545                 :            : 
    3546                 :            :         /* DVFS post sequence would be here. See the comment above. */
    3547                 :          0 : }
    3548                 :            : 
    3549                 :          0 : static void mg_pll_enable(struct drm_i915_private *dev_priv,
    3550                 :            :                           struct intel_shared_dpll *pll)
    3551                 :            : {
    3552                 :          0 :         i915_reg_t enable_reg =
    3553                 :          0 :                 MG_PLL_ENABLE(icl_pll_id_to_tc_port(pll->info->id));
    3554                 :            : 
    3555                 :          0 :         icl_pll_power_enable(dev_priv, pll, enable_reg);
    3556                 :            : 
    3557         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 12)
    3558                 :          0 :                 dkl_pll_write(dev_priv, pll);
    3559                 :            :         else
    3560                 :          0 :                 icl_mg_pll_write(dev_priv, pll);
    3561                 :            : 
    3562                 :            :         /*
    3563                 :            :          * DVFS pre sequence would be here, but in our driver the cdclk code
    3564                 :            :          * paths should already be setting the appropriate voltage, hence we do
    3565                 :            :          * nothing here.
    3566                 :            :          */
    3567                 :            : 
    3568                 :          0 :         icl_pll_enable(dev_priv, pll, enable_reg);
    3569                 :            : 
    3570                 :            :         /* DVFS post sequence would be here. See the comment above. */
    3571                 :          0 : }
    3572                 :            : 
    3573                 :            : static void icl_pll_disable(struct drm_i915_private *dev_priv,
    3574                 :            :                             struct intel_shared_dpll *pll,
    3575                 :            :                             i915_reg_t enable_reg)
    3576                 :            : {
    3577                 :            :         u32 val;
    3578                 :            : 
    3579                 :            :         /* The first steps are done by intel_ddi_post_disable(). */
    3580                 :            : 
    3581                 :            :         /*
    3582                 :            :          * DVFS pre sequence would be here, but in our driver the cdclk code
    3583                 :            :          * paths should already be setting the appropriate voltage, hence we do
    3584                 :            :          * nothign here.
    3585                 :            :          */
    3586                 :            : 
    3587                 :            :         val = I915_READ(enable_reg);
    3588                 :            :         val &= ~PLL_ENABLE;
    3589                 :            :         I915_WRITE(enable_reg, val);
    3590                 :            : 
    3591                 :            :         /* Timeout is actually 1us. */
    3592                 :            :         if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 1))
    3593                 :            :                 DRM_ERROR("PLL %d locked\n", pll->info->id);
    3594                 :            : 
    3595                 :            :         /* DVFS post sequence would be here. See the comment above. */
    3596                 :            : 
    3597                 :            :         val = I915_READ(enable_reg);
    3598                 :            :         val &= ~PLL_POWER_ENABLE;
    3599                 :            :         I915_WRITE(enable_reg, val);
    3600                 :            : 
    3601                 :            :         /*
    3602                 :            :          * The spec says we need to "wait" but it also says it should be
    3603                 :            :          * immediate.
    3604                 :            :          */
    3605                 :            :         if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_POWER_STATE, 1))
    3606                 :            :                 DRM_ERROR("PLL %d Power not disabled\n", pll->info->id);
    3607                 :            : }
    3608                 :            : 
    3609                 :          0 : static void combo_pll_disable(struct drm_i915_private *dev_priv,
    3610                 :            :                               struct intel_shared_dpll *pll)
    3611                 :            : {
    3612                 :          0 :         i915_reg_t enable_reg = CNL_DPLL_ENABLE(pll->info->id);
    3613                 :            : 
    3614   [ #  #  #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv) &&
    3615                 :            :             pll->info->id == DPLL_ID_EHL_DPLL4) {
    3616                 :          0 :                 enable_reg = MG_PLL_ENABLE(0);
    3617                 :          0 :                 icl_pll_disable(dev_priv, pll, enable_reg);
    3618                 :            : 
    3619                 :          0 :                 intel_display_power_put(dev_priv, POWER_DOMAIN_DPLL_DC_OFF,
    3620                 :            :                                         pll->wakeref);
    3621                 :          0 :                 return;
    3622                 :            :         }
    3623                 :            : 
    3624                 :          0 :         icl_pll_disable(dev_priv, pll, enable_reg);
    3625                 :            : }
    3626                 :            : 
    3627                 :          0 : static void tbt_pll_disable(struct drm_i915_private *dev_priv,
    3628                 :            :                             struct intel_shared_dpll *pll)
    3629                 :            : {
    3630                 :          0 :         icl_pll_disable(dev_priv, pll, TBT_PLL_ENABLE);
    3631                 :          0 : }
    3632                 :            : 
    3633                 :          0 : static void mg_pll_disable(struct drm_i915_private *dev_priv,
    3634                 :            :                            struct intel_shared_dpll *pll)
    3635                 :            : {
    3636                 :          0 :         i915_reg_t enable_reg =
    3637                 :          0 :                 MG_PLL_ENABLE(icl_pll_id_to_tc_port(pll->info->id));
    3638                 :            : 
    3639                 :          0 :         icl_pll_disable(dev_priv, pll, enable_reg);
    3640                 :          0 : }
    3641                 :            : 
    3642                 :          0 : static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
    3643                 :            :                               const struct intel_dpll_hw_state *hw_state)
    3644                 :            : {
    3645                 :          0 :         DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
    3646                 :            :                       "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
    3647                 :            :                       "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
    3648                 :            :                       "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
    3649                 :            :                       "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
    3650                 :            :                       "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
    3651                 :            :                       hw_state->cfgcr0, hw_state->cfgcr1,
    3652                 :            :                       hw_state->mg_refclkin_ctl,
    3653                 :            :                       hw_state->mg_clktop2_coreclkctl1,
    3654                 :            :                       hw_state->mg_clktop2_hsclkctl,
    3655                 :            :                       hw_state->mg_pll_div0,
    3656                 :            :                       hw_state->mg_pll_div1,
    3657                 :            :                       hw_state->mg_pll_lf,
    3658                 :            :                       hw_state->mg_pll_frac_lock,
    3659                 :            :                       hw_state->mg_pll_ssc,
    3660                 :            :                       hw_state->mg_pll_bias,
    3661                 :            :                       hw_state->mg_pll_tdc_coldst_bias);
    3662                 :          0 : }
    3663                 :            : 
    3664                 :            : static const struct intel_shared_dpll_funcs combo_pll_funcs = {
    3665                 :            :         .enable = combo_pll_enable,
    3666                 :            :         .disable = combo_pll_disable,
    3667                 :            :         .get_hw_state = combo_pll_get_hw_state,
    3668                 :            : };
    3669                 :            : 
    3670                 :            : static const struct intel_shared_dpll_funcs tbt_pll_funcs = {
    3671                 :            :         .enable = tbt_pll_enable,
    3672                 :            :         .disable = tbt_pll_disable,
    3673                 :            :         .get_hw_state = tbt_pll_get_hw_state,
    3674                 :            : };
    3675                 :            : 
    3676                 :            : static const struct intel_shared_dpll_funcs mg_pll_funcs = {
    3677                 :            :         .enable = mg_pll_enable,
    3678                 :            :         .disable = mg_pll_disable,
    3679                 :            :         .get_hw_state = mg_pll_get_hw_state,
    3680                 :            : };
    3681                 :            : 
    3682                 :            : static const struct dpll_info icl_plls[] = {
    3683                 :            :         { "DPLL 0",   &combo_pll_funcs, DPLL_ID_ICL_DPLL0,  0 },
    3684                 :            :         { "DPLL 1",   &combo_pll_funcs, DPLL_ID_ICL_DPLL1,  0 },
    3685                 :            :         { "TBT PLL",  &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
    3686                 :            :         { "MG PLL 1", &mg_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
    3687                 :            :         { "MG PLL 2", &mg_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
    3688                 :            :         { "MG PLL 3", &mg_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
    3689                 :            :         { "MG PLL 4", &mg_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
    3690                 :            :         { },
    3691                 :            : };
    3692                 :            : 
    3693                 :            : static const struct intel_dpll_mgr icl_pll_mgr = {
    3694                 :            :         .dpll_info = icl_plls,
    3695                 :            :         .get_dplls = icl_get_dplls,
    3696                 :            :         .put_dplls = icl_put_dplls,
    3697                 :            :         .update_active_dpll = icl_update_active_dpll,
    3698                 :            :         .dump_hw_state = icl_dump_hw_state,
    3699                 :            : };
    3700                 :            : 
    3701                 :            : static const struct dpll_info ehl_plls[] = {
    3702                 :            :         { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
    3703                 :            :         { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
    3704                 :            :         { "DPLL 4", &combo_pll_funcs, DPLL_ID_EHL_DPLL4, 0 },
    3705                 :            :         { },
    3706                 :            : };
    3707                 :            : 
    3708                 :            : static const struct intel_dpll_mgr ehl_pll_mgr = {
    3709                 :            :         .dpll_info = ehl_plls,
    3710                 :            :         .get_dplls = icl_get_dplls,
    3711                 :            :         .put_dplls = icl_put_dplls,
    3712                 :            :         .dump_hw_state = icl_dump_hw_state,
    3713                 :            : };
    3714                 :            : 
    3715                 :            : static const struct intel_shared_dpll_funcs dkl_pll_funcs = {
    3716                 :            :         .enable = mg_pll_enable,
    3717                 :            :         .disable = mg_pll_disable,
    3718                 :            :         .get_hw_state = dkl_pll_get_hw_state,
    3719                 :            : };
    3720                 :            : 
    3721                 :            : static const struct dpll_info tgl_plls[] = {
    3722                 :            :         { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0,  0 },
    3723                 :            :         { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1,  0 },
    3724                 :            :         { "TBT PLL",  &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
    3725                 :            :         { "TC PLL 1", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
    3726                 :            :         { "TC PLL 2", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
    3727                 :            :         { "TC PLL 3", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
    3728                 :            :         { "TC PLL 4", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
    3729                 :            :         { "TC PLL 5", &dkl_pll_funcs, DPLL_ID_TGL_MGPLL5, 0 },
    3730                 :            :         { "TC PLL 6", &dkl_pll_funcs, DPLL_ID_TGL_MGPLL6, 0 },
    3731                 :            :         { },
    3732                 :            : };
    3733                 :            : 
    3734                 :            : static const struct intel_dpll_mgr tgl_pll_mgr = {
    3735                 :            :         .dpll_info = tgl_plls,
    3736                 :            :         .get_dplls = icl_get_dplls,
    3737                 :            :         .put_dplls = icl_put_dplls,
    3738                 :            :         .update_active_dpll = icl_update_active_dpll,
    3739                 :            :         .dump_hw_state = icl_dump_hw_state,
    3740                 :            : };
    3741                 :            : 
    3742                 :            : /**
    3743                 :            :  * intel_shared_dpll_init - Initialize shared DPLLs
    3744                 :            :  * @dev: drm device
    3745                 :            :  *
    3746                 :            :  * Initialize shared DPLLs for @dev.
    3747                 :            :  */
    3748                 :          0 : void intel_shared_dpll_init(struct drm_device *dev)
    3749                 :            : {
    3750         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(dev);
    3751                 :          0 :         const struct intel_dpll_mgr *dpll_mgr = NULL;
    3752                 :          0 :         const struct dpll_info *dpll_info;
    3753                 :          0 :         int i;
    3754                 :            : 
    3755         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 12)
    3756                 :            :                 dpll_mgr = &tgl_pll_mgr;
    3757         [ #  # ]:          0 :         else if (IS_ELKHARTLAKE(dev_priv))
    3758                 :            :                 dpll_mgr = &ehl_pll_mgr;
    3759         [ #  # ]:          0 :         else if (INTEL_GEN(dev_priv) >= 11)
    3760                 :            :                 dpll_mgr = &icl_pll_mgr;
    3761         [ #  # ]:          0 :         else if (IS_CANNONLAKE(dev_priv))
    3762                 :            :                 dpll_mgr = &cnl_pll_mgr;
    3763   [ #  #  #  # ]:          0 :         else if (IS_GEN9_BC(dev_priv))
    3764                 :            :                 dpll_mgr = &skl_pll_mgr;
    3765   [ #  #  #  # ]:          0 :         else if (IS_GEN9_LP(dev_priv))
    3766                 :            :                 dpll_mgr = &bxt_pll_mgr;
    3767         [ #  # ]:          0 :         else if (HAS_DDI(dev_priv))
    3768                 :            :                 dpll_mgr = &hsw_pll_mgr;
    3769         [ #  # ]:          0 :         else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
    3770                 :            :                 dpll_mgr = &pch_pll_mgr;
    3771                 :            : 
    3772                 :          0 :         if (!dpll_mgr) {
    3773                 :          0 :                 dev_priv->num_shared_dpll = 0;
    3774                 :          0 :                 return;
    3775                 :            :         }
    3776                 :            : 
    3777                 :          0 :         dpll_info = dpll_mgr->dpll_info;
    3778                 :            : 
    3779         [ #  # ]:          0 :         for (i = 0; dpll_info[i].name; i++) {
    3780         [ #  # ]:          0 :                 WARN_ON(i != dpll_info[i].id);
    3781                 :          0 :                 dev_priv->shared_dplls[i].info = &dpll_info[i];
    3782                 :            :         }
    3783                 :            : 
    3784                 :          0 :         dev_priv->dpll_mgr = dpll_mgr;
    3785                 :          0 :         dev_priv->num_shared_dpll = i;
    3786                 :          0 :         mutex_init(&dev_priv->dpll_lock);
    3787                 :            : 
    3788         [ #  # ]:          0 :         BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
    3789                 :            : }
    3790                 :            : 
    3791                 :            : /**
    3792                 :            :  * intel_reserve_shared_dplls - reserve DPLLs for CRTC and encoder combination
    3793                 :            :  * @state: atomic state
    3794                 :            :  * @crtc: CRTC to reserve DPLLs for
    3795                 :            :  * @encoder: encoder
    3796                 :            :  *
    3797                 :            :  * This function reserves all required DPLLs for the given CRTC and encoder
    3798                 :            :  * combination in the current atomic commit @state and the new @crtc atomic
    3799                 :            :  * state.
    3800                 :            :  *
    3801                 :            :  * The new configuration in the atomic commit @state is made effective by
    3802                 :            :  * calling intel_shared_dpll_swap_state().
    3803                 :            :  *
    3804                 :            :  * The reserved DPLLs should be released by calling
    3805                 :            :  * intel_release_shared_dplls().
    3806                 :            :  *
    3807                 :            :  * Returns:
    3808                 :            :  * True if all required DPLLs were successfully reserved.
    3809                 :            :  */
    3810                 :          0 : bool intel_reserve_shared_dplls(struct intel_atomic_state *state,
    3811                 :            :                                 struct intel_crtc *crtc,
    3812                 :            :                                 struct intel_encoder *encoder)
    3813                 :            : {
    3814         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
    3815                 :          0 :         const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
    3816                 :            : 
    3817   [ #  #  #  # ]:          0 :         if (WARN_ON(!dpll_mgr))
    3818                 :            :                 return false;
    3819                 :            : 
    3820                 :          0 :         return dpll_mgr->get_dplls(state, crtc, encoder);
    3821                 :            : }
    3822                 :            : 
    3823                 :            : /**
    3824                 :            :  * intel_release_shared_dplls - end use of DPLLs by CRTC in atomic state
    3825                 :            :  * @state: atomic state
    3826                 :            :  * @crtc: crtc from which the DPLLs are to be released
    3827                 :            :  *
    3828                 :            :  * This function releases all DPLLs reserved by intel_reserve_shared_dplls()
    3829                 :            :  * from the current atomic commit @state and the old @crtc atomic state.
    3830                 :            :  *
    3831                 :            :  * The new configuration in the atomic commit @state is made effective by
    3832                 :            :  * calling intel_shared_dpll_swap_state().
    3833                 :            :  */
    3834                 :          0 : void intel_release_shared_dplls(struct intel_atomic_state *state,
    3835                 :            :                                 struct intel_crtc *crtc)
    3836                 :            : {
    3837         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
    3838                 :          0 :         const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
    3839                 :            : 
    3840                 :            :         /*
    3841                 :            :          * FIXME: this function is called for every platform having a
    3842                 :            :          * compute_clock hook, even though the platform doesn't yet support
    3843                 :            :          * the shared DPLL framework and intel_reserve_shared_dplls() is not
    3844                 :            :          * called on those.
    3845                 :            :          */
    3846         [ #  # ]:          0 :         if (!dpll_mgr)
    3847                 :            :                 return;
    3848                 :            : 
    3849                 :          0 :         dpll_mgr->put_dplls(state, crtc);
    3850                 :            : }
    3851                 :            : 
    3852                 :            : /**
    3853                 :            :  * intel_update_active_dpll - update the active DPLL for a CRTC/encoder
    3854                 :            :  * @state: atomic state
    3855                 :            :  * @crtc: the CRTC for which to update the active DPLL
    3856                 :            :  * @encoder: encoder determining the type of port DPLL
    3857                 :            :  *
    3858                 :            :  * Update the active DPLL for the given @crtc/@encoder in @crtc's atomic state,
    3859                 :            :  * from the port DPLLs reserved previously by intel_reserve_shared_dplls(). The
    3860                 :            :  * DPLL selected will be based on the current mode of the encoder's port.
    3861                 :            :  */
    3862                 :          0 : void intel_update_active_dpll(struct intel_atomic_state *state,
    3863                 :            :                               struct intel_crtc *crtc,
    3864                 :            :                               struct intel_encoder *encoder)
    3865                 :            : {
    3866         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    3867                 :          0 :         const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
    3868                 :            : 
    3869   [ #  #  #  # ]:          0 :         if (WARN_ON(!dpll_mgr))
    3870                 :            :                 return;
    3871                 :            : 
    3872                 :          0 :         dpll_mgr->update_active_dpll(state, crtc, encoder);
    3873                 :            : }
    3874                 :            : 
    3875                 :            : /**
    3876                 :            :  * intel_shared_dpll_dump_hw_state - write hw_state to dmesg
    3877                 :            :  * @dev_priv: i915 drm device
    3878                 :            :  * @hw_state: hw state to be written to the log
    3879                 :            :  *
    3880                 :            :  * Write the relevant values in @hw_state to dmesg using DRM_DEBUG_KMS.
    3881                 :            :  */
    3882                 :          0 : void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv,
    3883                 :            :                               const struct intel_dpll_hw_state *hw_state)
    3884                 :            : {
    3885         [ #  # ]:          0 :         if (dev_priv->dpll_mgr) {
    3886                 :          0 :                 dev_priv->dpll_mgr->dump_hw_state(dev_priv, hw_state);
    3887                 :            :         } else {
    3888                 :            :                 /* fallback for platforms that don't use the shared dpll
    3889                 :            :                  * infrastructure
    3890                 :            :                  */
    3891                 :          0 :                 DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
    3892                 :            :                               "fp0: 0x%x, fp1: 0x%x\n",
    3893                 :            :                               hw_state->dpll,
    3894                 :            :                               hw_state->dpll_md,
    3895                 :            :                               hw_state->fp0,
    3896                 :            :                               hw_state->fp1);
    3897                 :            :         }
    3898                 :          0 : }

Generated by: LCOV version 1.14