Merge tag 'drm-intel-next-2021-05-19-1' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_cdclk.c
index f95896f..4656a6e 100644 (file)
@@ -724,12 +724,28 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
                bdw_calc_voltage_level(cdclk_config->cdclk);
 }
 
+static u32 bdw_cdclk_freq_sel(int cdclk)
+{
+       switch (cdclk) {
+       default:
+               MISSING_CASE(cdclk);
+               fallthrough;
+       case 337500:
+               return LCPLL_CLK_FREQ_337_5_BDW;
+       case 450000:
+               return LCPLL_CLK_FREQ_450;
+       case 540000:
+               return LCPLL_CLK_FREQ_54O_BDW;
+       case 675000:
+               return LCPLL_CLK_FREQ_675_BDW;
+       }
+}
+
 static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
 {
        int cdclk = cdclk_config->cdclk;
-       u32 val;
        int ret;
 
        if (drm_WARN(&dev_priv->drm,
@@ -749,9 +765,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       val = intel_de_read(dev_priv, LCPLL_CTL);
-       val |= LCPLL_CD_SOURCE_FCLK;
-       intel_de_write(dev_priv, LCPLL_CTL, val);
+       intel_de_rmw(dev_priv, LCPLL_CTL,
+                    0, LCPLL_CD_SOURCE_FCLK);
 
        /*
         * According to the spec, it should be enough to poll for this 1 us.
@@ -761,32 +776,11 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
                        LCPLL_CD_SOURCE_FCLK_DONE, 100))
                drm_err(&dev_priv->drm, "Switching to FCLK failed\n");
 
-       val = intel_de_read(dev_priv, LCPLL_CTL);
-       val &= ~LCPLL_CLK_FREQ_MASK;
-
-       switch (cdclk) {
-       default:
-               MISSING_CASE(cdclk);
-               fallthrough;
-       case 337500:
-               val |= LCPLL_CLK_FREQ_337_5_BDW;
-               break;
-       case 450000:
-               val |= LCPLL_CLK_FREQ_450;
-               break;
-       case 540000:
-               val |= LCPLL_CLK_FREQ_54O_BDW;
-               break;
-       case 675000:
-               val |= LCPLL_CLK_FREQ_675_BDW;
-               break;
-       }
-
-       intel_de_write(dev_priv, LCPLL_CTL, val);
+       intel_de_rmw(dev_priv, LCPLL_CTL,
+                    LCPLL_CLK_FREQ_MASK, bdw_cdclk_freq_sel(cdclk));
 
-       val = intel_de_read(dev_priv, LCPLL_CTL);
-       val &= ~LCPLL_CD_SOURCE_FCLK;
-       intel_de_write(dev_priv, LCPLL_CTL, val);
+       intel_de_rmw(dev_priv, LCPLL_CTL,
+                    LCPLL_CD_SOURCE_FCLK, 0);
 
        if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) &
                         LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
@@ -955,10 +949,8 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
                intel_update_max_cdclk(dev_priv);
 }
 
-static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
+static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)
 {
-       u32 val;
-
        drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
 
        /*
@@ -970,23 +962,24 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
         * rate later on, with the constraint of choosing a frequency that
         * works with vco.
         */
-       val = intel_de_read(dev_priv, DPLL_CTRL1);
-
-       val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
-                DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
-       val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
        if (vco == 8640000)
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
-                                           SKL_DPLL0);
+               return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0);
        else
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
-                                           SKL_DPLL0);
+               return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0);
+}
 
-       intel_de_write(dev_priv, DPLL_CTRL1, val);
+static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
+{
+       intel_de_rmw(dev_priv, DPLL_CTRL1,
+                    DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
+                    DPLL_CTRL1_SSC(SKL_DPLL0) |
+                    DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0),
+                    DPLL_CTRL1_OVERRIDE(SKL_DPLL0) |
+                    skl_dpll0_link_rate(dev_priv, vco));
        intel_de_posting_read(dev_priv, DPLL_CTRL1);
 
-       intel_de_write(dev_priv, LCPLL1_CTL,
-                      intel_de_read(dev_priv, LCPLL1_CTL) | LCPLL_PLL_ENABLE);
+       intel_de_rmw(dev_priv, LCPLL1_CTL,
+                    0, LCPLL_PLL_ENABLE);
 
        if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
                drm_err(&dev_priv->drm, "DPLL0 not locked\n");
@@ -999,14 +992,38 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
 
 static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
 {
-       intel_de_write(dev_priv, LCPLL1_CTL,
-                      intel_de_read(dev_priv, LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
+       intel_de_rmw(dev_priv, LCPLL1_CTL,
+                    LCPLL_PLL_ENABLE, 0);
+
        if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
                drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");
 
        dev_priv->cdclk.hw.vco = 0;
 }
 
+static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
+                             int cdclk, int vco)
+{
+       switch (cdclk) {
+       default:
+               drm_WARN_ON(&dev_priv->drm,
+                           cdclk != dev_priv->cdclk.hw.bypass);
+               drm_WARN_ON(&dev_priv->drm, vco != 0);
+               fallthrough;
+       case 308571:
+       case 337500:
+               return CDCLK_FREQ_337_308;
+       case 450000:
+       case 432000:
+               return CDCLK_FREQ_450_432;
+       case 540000:
+               return CDCLK_FREQ_540;
+       case 617143:
+       case 675000:
+               return CDCLK_FREQ_675_617;
+       }
+}
+
 static void skl_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
@@ -1037,29 +1054,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       /* Choose frequency for this cdclk */
-       switch (cdclk) {
-       default:
-               drm_WARN_ON(&dev_priv->drm,
-                           cdclk != dev_priv->cdclk.hw.bypass);
-               drm_WARN_ON(&dev_priv->drm, vco != 0);
-               fallthrough;
-       case 308571:
-       case 337500:
-               freq_select = CDCLK_FREQ_337_308;
-               break;
-       case 450000:
-       case 432000:
-               freq_select = CDCLK_FREQ_450_432;
-               break;
-       case 540000:
-               freq_select = CDCLK_FREQ_540;
-               break;
-       case 617143:
-       case 675000:
-               freq_select = CDCLK_FREQ_675_617;
-               break;
-       }
+       freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);
 
        if (dev_priv->cdclk.hw.vco != 0 &&
            dev_priv->cdclk.hw.vco != vco)
@@ -1258,6 +1253,42 @@ static const struct intel_cdclk_vals rkl_cdclk_table[] = {
        {}
 };
 
+static const struct intel_cdclk_vals adlp_a_step_cdclk_table[] = {
+       { .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
+       { .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
+       { .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
+
+       { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
+       { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
+       { .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 },
+
+       { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
+       { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
+       { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
+       {}
+};
+
+static const struct intel_cdclk_vals adlp_cdclk_table[] = {
+       { .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
+       { .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
+       { .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
+       { .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
+       { .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
+
+       { .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
+       { .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
+       { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
+       { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
+       { .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 },
+
+       { .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
+       { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
+       { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
+       { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
+       { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
+       {}
+};
+
 static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
 {
        const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
@@ -1433,18 +1464,12 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
                div = 2;
                break;
        case BXT_CDCLK_CD2X_DIV_SEL_1_5:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 10,
-                        "Unsupported divider\n");
                div = 3;
                break;
        case BXT_CDCLK_CD2X_DIV_SEL_2:
                div = 4;
                break;
        case BXT_CDCLK_CD2X_DIV_SEL_4:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
-                        "Unsupported divider\n");
                div = 8;
                break;
        default:
@@ -1478,12 +1503,9 @@ static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
 static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
 {
        int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
-       u32 val;
 
-       val = intel_de_read(dev_priv, BXT_DE_PLL_CTL);
-       val &= ~BXT_DE_PLL_RATIO_MASK;
-       val |= BXT_DE_PLL_RATIO(ratio);
-       intel_de_write(dev_priv, BXT_DE_PLL_CTL, val);
+       intel_de_rmw(dev_priv, BXT_DE_PLL_CTL,
+                    BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio));
 
        intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
 
@@ -1497,16 +1519,12 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
 
 static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
 {
-       u32 val;
-
-       val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);
-       val &= ~BXT_DE_PLL_PLL_ENABLE;
-       intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
+       intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE,
+                    BXT_DE_PLL_PLL_ENABLE, 0);
 
        /* Timeout 200us */
-       if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1))
-               drm_err(&dev_priv->drm,
-                       "timeout waiting for CDCLK PLL unlock\n");
+       if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
+               drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n");
 
        dev_priv->cdclk.hw.vco = 0;
 }
@@ -1523,9 +1541,8 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
        intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
 
        /* Timeout 200us */
-       if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1))
-               drm_err(&dev_priv->drm,
-                       "timeout waiting for CDCLK PLL lock\n");
+       if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
+               drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n");
 
        dev_priv->cdclk.hw.vco = vco;
 }
@@ -1550,13 +1567,34 @@ static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe
        }
 }
 
+static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
+                                 int cdclk, int vco)
+{
+       /* cdclk = vco / 2 / div{1,1.5,2,4} */
+       switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
+       default:
+               drm_WARN_ON(&dev_priv->drm,
+                           cdclk != dev_priv->cdclk.hw.bypass);
+               drm_WARN_ON(&dev_priv->drm, vco != 0);
+               fallthrough;
+       case 2:
+               return BXT_CDCLK_CD2X_DIV_SEL_1;
+       case 3:
+               return BXT_CDCLK_CD2X_DIV_SEL_1_5;
+       case 4:
+               return BXT_CDCLK_CD2X_DIV_SEL_2;
+       case 8:
+               return BXT_CDCLK_CD2X_DIV_SEL_4;
+       }
+}
+
 static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
 {
        int cdclk = cdclk_config->cdclk;
        int vco = cdclk_config->vco;
-       u32 val, divider;
+       u32 val;
        int ret;
 
        /* Inform power controller of upcoming frequency change. */
@@ -1581,33 +1619,6 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       /* cdclk = vco / 2 / div{1,1.5,2,4} */
-       switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
-       default:
-               drm_WARN_ON(&dev_priv->drm,
-                           cdclk != dev_priv->cdclk.hw.bypass);
-               drm_WARN_ON(&dev_priv->drm, vco != 0);
-               fallthrough;
-       case 2:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       case 3:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 10,
-                        "Unsupported divider\n");
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
-               break;
-       case 4:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_2;
-               break;
-       case 8:
-               drm_WARN(&dev_priv->drm,
-                        DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
-                        "Unsupported divider\n");
-               divider = BXT_CDCLK_CD2X_DIV_SEL_4;
-               break;
-       }
-
        if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
                if (dev_priv->cdclk.hw.vco != 0 &&
                    dev_priv->cdclk.hw.vco != vco)
@@ -1625,8 +1636,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                        bxt_de_pll_enable(dev_priv, vco);
        }
 
-       val = divider | skl_cdclk_decimal(cdclk) |
-               bxt_cdclk_cd2x_pipe(dev_priv, pipe);
+       val = bxt_cdclk_cd2x_div_sel(dev_priv, cdclk, vco) |
+               bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
+               skl_cdclk_decimal(cdclk);
 
        /*
         * Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -1712,23 +1724,9 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
        expected = skl_cdclk_decimal(cdclk);
 
        /* Figure out what CD2X divider we should be using for this cdclk */
-       switch (DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.vco,
-                                 dev_priv->cdclk.hw.cdclk)) {
-       case 2:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       case 3:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_1_5;
-               break;
-       case 4:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_2;
-               break;
-       case 8:
-               expected |= BXT_CDCLK_CD2X_DIV_SEL_4;
-               break;
-       default:
-               goto sanitize;
-       }
+       expected |= bxt_cdclk_cd2x_div_sel(dev_priv,
+                                          dev_priv->cdclk.hw.cdclk,
+                                          dev_priv->cdclk.hw.vco);
 
        /*
         * Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -2392,44 +2390,6 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
        return 0;
 }
 
-static int intel_modeset_all_pipes(struct intel_atomic_state *state)
-{
-       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-       struct intel_crtc *crtc;
-
-       /*
-        * Add all pipes to the state, and force
-        * a modeset on all the active ones.
-        */
-       for_each_intel_crtc(&dev_priv->drm, crtc) {
-               struct intel_crtc_state *crtc_state;
-               int ret;
-
-               crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
-               if (IS_ERR(crtc_state))
-                       return PTR_ERR(crtc_state);
-
-               if (!crtc_state->hw.active ||
-                   drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
-                       continue;
-
-               crtc_state->uapi.mode_changed = true;
-
-               ret = drm_atomic_add_affected_connectors(&state->base,
-                                                        &crtc->base);
-               if (ret)
-                       return ret;
-
-               ret = intel_atomic_add_affected_planes(state, crtc);
-               if (ret)
-                       return ret;
-
-               crtc_state->update_planes |= crtc_state->active_planes;
-       }
-
-       return 0;
-}
-
 static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
 {
        int min_cdclk;
@@ -2851,7 +2811,17 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
  */
 void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
 {
-       if (IS_ROCKETLAKE(dev_priv)) {
+       if (IS_ALDERLAKE_P(dev_priv)) {
+               dev_priv->display.set_cdclk = bxt_set_cdclk;
+               dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
+               dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
+               dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
+               /* Wa_22011320316:adlp[a0] */
+               if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
+                       dev_priv->cdclk.table = adlp_a_step_cdclk_table;
+               else
+                       dev_priv->cdclk.table = adlp_cdclk_table;
+       } else if (IS_ROCKETLAKE(dev_priv)) {
                dev_priv->display.set_cdclk = bxt_set_cdclk;
                dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
                dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;