drm/i915/glk: Program txesc clock divider for GLK
authorDeepak M <m.deepak@intel.com>
Fri, 17 Feb 2017 12:43:34 +0000 (18:13 +0530)
committerJani Nikula <jani.nikula@intel.com>
Tue, 28 Feb 2017 09:53:35 +0000 (11:53 +0200)
v2: Addressed Jani's Review comments(renamed bit field macros)

Txesc clock divider is calculated and programmed
for geminilake platform.

Signed-off-by: Deepak M <m.deepak@intel.com>
Signed-off-by: Madhav Chauhan <madhav.chauhan@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1487335415-14766-7-git-send-email-madhav.chauhan@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_dsi_pll.c

index 89093efc9b4202ac6b1f86a93ce8a235a7140eea..1343170d8f5c3fc5b366e94943d9c906249c07b2 100644 (file)
@@ -8251,6 +8251,11 @@ enum {
 #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c)   /* ports A and C only */
 #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c))
 
+#define MIPIO_TXESC_CLK_DIV1                   _MMIO(0x160004)
+#define  GLK_TX_ESC_CLK_DIV1_MASK                      0x3FF
+#define MIPIO_TXESC_CLK_DIV2                   _MMIO(0x160008)
+#define  GLK_TX_ESC_CLK_DIV2_MASK                      0x3FF
+
 /* BXT MIPI clock controls */
 #define BXT_MAX_VAR_OUTPUT_KHZ                 39500
 
index 0a9a5c431a048314e7134d38b30c4bf942ffcc7a..7a7617b24cb280cbc6d7c5909a0dae79109f5f84 100644 (file)
@@ -372,6 +372,53 @@ static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
                        ESCAPE_CLOCK_DIVIDER_SHIFT);
 }
 
+static void glk_dsi_program_esc_clock(struct drm_device *dev,
+                                  const struct intel_crtc_state *config)
+{
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       u32 dsi_rate = 0;
+       u32 pll_ratio = 0;
+       u32 ddr_clk = 0;
+       u32 div1_value = 0;
+       u32 div2_value = 0;
+       u32 txesc1_div = 0;
+       u32 txesc2_div = 0;
+
+       pll_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
+
+       dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
+
+       ddr_clk = dsi_rate / 2;
+
+       /* Variable divider value */
+       div1_value = DIV_ROUND_CLOSEST(ddr_clk, 20000);
+
+       /* Calculate TXESC1 divider */
+       if (div1_value <= 10)
+               txesc1_div = div1_value;
+       else if ((div1_value > 10) && (div1_value <= 20))
+               txesc1_div = DIV_ROUND_UP(div1_value, 2);
+       else if ((div1_value > 20) && (div1_value <= 30))
+               txesc1_div = DIV_ROUND_UP(div1_value, 4);
+       else if ((div1_value > 30) && (div1_value <= 40))
+               txesc1_div = DIV_ROUND_UP(div1_value, 6);
+       else if ((div1_value > 40) && (div1_value <= 50))
+               txesc1_div = DIV_ROUND_UP(div1_value, 8);
+       else
+               txesc1_div = 10;
+
+       /* Calculate TXESC2 divider */
+       div2_value = DIV_ROUND_UP(div1_value, txesc1_div);
+
+       if (div2_value < 10)
+               txesc2_div = div2_value;
+       else
+               txesc2_div = 10;
+
+       I915_WRITE(MIPIO_TXESC_CLK_DIV1, txesc1_div & GLK_TX_ESC_CLK_DIV1_MASK);
+       I915_WRITE(MIPIO_TXESC_CLK_DIV2, txesc2_div & GLK_TX_ESC_CLK_DIV2_MASK);
+}
+
 /* Program BXT Mipi clocks and dividers */
 static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port,
                                   const struct intel_crtc_state *config)
@@ -474,7 +521,7 @@ static int gen9lp_compute_dsi_pll(struct intel_encoder *encoder,
        return 0;
 }
 
-static void bxt_enable_dsi_pll(struct intel_encoder *encoder,
+static void gen9lp_enable_dsi_pll(struct intel_encoder *encoder,
                               const struct intel_crtc_state *config)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -492,6 +539,8 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder,
        if (IS_BROXTON(dev_priv)) {
                for_each_dsi_port(port, intel_dsi->ports)
                        bxt_dsi_program_clocks(encoder->base.dev, port, config);
+       } else {
+               glk_dsi_program_esc_clock(encoder->base.dev, config);
        }
 
        /* Enable DSI PLL */
@@ -543,7 +592,7 @@ void intel_enable_dsi_pll(struct intel_encoder *encoder,
        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                vlv_enable_dsi_pll(encoder, config);
        else if (IS_GEN9_LP(dev_priv))
-               bxt_enable_dsi_pll(encoder, config);
+               gen9lp_enable_dsi_pll(encoder, config);
 }
 
 void intel_disable_dsi_pll(struct intel_encoder *encoder)
@@ -571,6 +620,14 @@ static void gen9lp_dsi_reset_clocks(struct intel_encoder *encoder,
                tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
                tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
                I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
+       } else {
+               tmp = I915_READ(MIPIO_TXESC_CLK_DIV1);
+               tmp &= ~GLK_TX_ESC_CLK_DIV1_MASK;
+               I915_WRITE(MIPIO_TXESC_CLK_DIV1, tmp);
+
+               tmp = I915_READ(MIPIO_TXESC_CLK_DIV2);
+               tmp &= ~GLK_TX_ESC_CLK_DIV2_MASK;
+               I915_WRITE(MIPIO_TXESC_CLK_DIV2, tmp);
        }
        I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
 }