drm/i915/bxt: Additional MIPI clock divider form B0 stepping onwards
authorDeepak M <m.deepak@intel.com>
Mon, 15 Feb 2016 17:13:57 +0000 (22:43 +0530)
committerJani Nikula <jani.nikula@intel.com>
Thu, 3 Mar 2016 13:05:52 +0000 (15:05 +0200)
The MIPI clock calculations for the addtional clock
are revised from B0 stepping onwards, the bit definitions
have changed compared to old stepping.

v2: Fixing compilation warning.
v3: Retained the old Macros (Jani)

Signed-off-by: Deepak M <m.deepak@intel.com>
Tested-by: Ramalingam C <ramalingam.c@intel.com> # BXT-T with Tianma panel
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1455556437-29267-1-git-send-email-m.deepak@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_dsi_pll.c

index 71abf57..65f9bb9 100644 (file)
@@ -7669,58 +7669,62 @@ enum skl_disp_power_wells {
 #define  BXT_MIPI_DIV_SHIFT(port)              \
                        _MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \
                                        BXT_MIPI2_DIV_SHIFT)
-/* Var clock divider to generate TX source. Result must be < 39.5 M */
-#define  BXT_MIPI1_ESCLK_VAR_DIV_MASK          (0x3F << 26)
-#define  BXT_MIPI2_ESCLK_VAR_DIV_MASK          (0x3F << 10)
-#define  BXT_MIPI_ESCLK_VAR_DIV_MASK(port)     \
-                       _MIPI_PORT(port, BXT_MIPI1_ESCLK_VAR_DIV_MASK, \
-                                               BXT_MIPI2_ESCLK_VAR_DIV_MASK)
-
-#define  BXT_MIPI_ESCLK_VAR_DIV(port, val)     \
-                       (val << BXT_MIPI_DIV_SHIFT(port))
+
 /* TX control divider to select actual TX clock output from (8x/var) */
-#define  BXT_MIPI1_TX_ESCLK_SHIFT              21
-#define  BXT_MIPI2_TX_ESCLK_SHIFT              5
+#define  BXT_MIPI1_TX_ESCLK_SHIFT              26
+#define  BXT_MIPI2_TX_ESCLK_SHIFT              10
 #define  BXT_MIPI_TX_ESCLK_SHIFT(port)         \
                        _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \
                                        BXT_MIPI2_TX_ESCLK_SHIFT)
-#define  BXT_MIPI1_TX_ESCLK_FIXDIV_MASK                (3 << 21)
-#define  BXT_MIPI2_TX_ESCLK_FIXDIV_MASK                (3 << 5)
+#define  BXT_MIPI1_TX_ESCLK_FIXDIV_MASK                (0x3F << 26)
+#define  BXT_MIPI2_TX_ESCLK_FIXDIV_MASK                (0x3F << 10)
 #define  BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)   \
                        _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \
-                                               BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
-#define  BXT_MIPI_TX_ESCLK_8XDIV_BY2(port)     \
-               (0x0 << BXT_MIPI_TX_ESCLK_SHIFT(port))
-#define  BXT_MIPI_TX_ESCLK_8XDIV_BY4(port)     \
-               (0x1 << BXT_MIPI_TX_ESCLK_SHIFT(port))
-#define  BXT_MIPI_TX_ESCLK_8XDIV_BY8(port)     \
-               (0x2 << BXT_MIPI_TX_ESCLK_SHIFT(port))
-/* RX control divider to select actual RX clock output from 8x*/
-#define  BXT_MIPI1_RX_ESCLK_SHIFT              19
-#define  BXT_MIPI2_RX_ESCLK_SHIFT              3
-#define  BXT_MIPI_RX_ESCLK_SHIFT(port)         \
-                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_SHIFT, \
-                                       BXT_MIPI2_RX_ESCLK_SHIFT)
-#define  BXT_MIPI1_RX_ESCLK_FIXDIV_MASK                (3 << 19)
-#define  BXT_MIPI2_RX_ESCLK_FIXDIV_MASK                (3 << 3)
-#define  BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)   \
-               (3 << BXT_MIPI_RX_ESCLK_SHIFT(port))
-#define  BXT_MIPI_RX_ESCLK_8X_BY2(port)        \
-               (1 << BXT_MIPI_RX_ESCLK_SHIFT(port))
-#define  BXT_MIPI_RX_ESCLK_8X_BY3(port)        \
-               (2 << BXT_MIPI_RX_ESCLK_SHIFT(port))
-#define  BXT_MIPI_RX_ESCLK_8X_BY4(port)        \
-               (3 << BXT_MIPI_RX_ESCLK_SHIFT(port))
-/* BXT-A WA: Always prog DPHY dividers to 00 */
-#define  BXT_MIPI1_DPHY_DIV_SHIFT              16
-#define  BXT_MIPI2_DPHY_DIV_SHIFT              0
-#define  BXT_MIPI_DPHY_DIV_SHIFT(port)         \
-                       _MIPI_PORT(port, BXT_MIPI1_DPHY_DIV_SHIFT, \
-                                       BXT_MIPI2_DPHY_DIV_SHIFT)
-#define  BXT_MIPI_1_DPHY_DIVIDER_MASK          (3 << 16)
-#define  BXT_MIPI_2_DPHY_DIVIDER_MASK          (3 << 0)
-#define  BXT_MIPI_DPHY_DIVIDER_MASK(port)      \
-               (3 << BXT_MIPI_DPHY_DIV_SHIFT(port))
+                                       BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
+#define  BXT_MIPI_TX_ESCLK_DIVIDER(port, val)  \
+               ((val & 0x3F) << BXT_MIPI_TX_ESCLK_SHIFT(port))
+/* RX upper control divider to select actual RX clock output from 8x */
+#define  BXT_MIPI1_RX_ESCLK_UPPER_SHIFT                21
+#define  BXT_MIPI2_RX_ESCLK_UPPER_SHIFT                5
+#define  BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port)           \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_SHIFT, \
+                                       BXT_MIPI2_RX_ESCLK_UPPER_SHIFT)
+#define  BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK          (3 << 21)
+#define  BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK          (3 << 5)
+#define  BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)     \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK, \
+                                       BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK)
+#define  BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, val)    \
+               ((val & 3) << BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port))
+/* 8/3X divider to select the actual 8/3X clock output from 8x */
+#define  BXT_MIPI1_8X_BY3_SHIFT                19
+#define  BXT_MIPI2_8X_BY3_SHIFT                3
+#define  BXT_MIPI_8X_BY3_SHIFT(port)          \
+                       _MIPI_PORT(port, BXT_MIPI1_8X_BY3_SHIFT, \
+                                       BXT_MIPI2_8X_BY3_SHIFT)
+#define  BXT_MIPI1_8X_BY3_DIVIDER_MASK         (3 << 19)
+#define  BXT_MIPI2_8X_BY3_DIVIDER_MASK         (3 << 3)
+#define  BXT_MIPI_8X_BY3_DIVIDER_MASK(port)    \
+                       _MIPI_PORT(port, BXT_MIPI1_8X_BY3_DIVIDER_MASK, \
+                                               BXT_MIPI2_8X_BY3_DIVIDER_MASK)
+#define  BXT_MIPI_8X_BY3_DIVIDER(port, val)    \
+                       ((val & 3) << BXT_MIPI_8X_BY3_SHIFT(port))
+/* RX lower control divider to select actual RX clock output from 8x */
+#define  BXT_MIPI1_RX_ESCLK_LOWER_SHIFT                16
+#define  BXT_MIPI2_RX_ESCLK_LOWER_SHIFT                0
+#define  BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port)           \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_SHIFT, \
+                                       BXT_MIPI2_RX_ESCLK_LOWER_SHIFT)
+#define  BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK          (3 << 16)
+#define  BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK          (3 << 0)
+#define  BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port)     \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK, \
+                                       BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK)
+#define  BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, val)    \
+               ((val & 3) << BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port))
+
+#define RX_DIVIDER_BIT_1_2                     0x3
+#define RX_DIVIDER_BIT_3_4                     0xC
 
 /* BXT MIPI mode configure */
 #define  _BXT_MIPIA_TRANS_HACTIVE                      0x6B0F8
index 70883c5..2451c84 100644 (file)
@@ -362,35 +362,57 @@ static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
 /* Program BXT Mipi clocks and dividers */
 static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port)
 {
-       u32 tmp;
-       u32 divider;
-       u32 dsi_rate;
-       u32 pll_ratio;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 tmp;
+       u32 dsi_rate = 0;
+       u32 pll_ratio = 0;
+       u32 rx_div;
+       u32 tx_div;
+       u32 rx_div_upper;
+       u32 rx_div_lower;
+       u32 mipi_8by3_divider;
 
        /* Clear old configurations */
        tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
        tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
-       tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+       tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
 
        /* Get the current DSI rate(actual) */
        pll_ratio = I915_READ(BXT_DSI_PLL_CTL) &
                                BXT_DSI_PLL_RATIO_MASK;
        dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
 
-       /* Max possible output of clock is 39.5 MHz, program value -1 */
-       divider = (dsi_rate / BXT_MAX_VAR_OUTPUT_KHZ) - 1;
-       tmp |= BXT_MIPI_ESCLK_VAR_DIV(port, divider);
+       /*
+        * tx clock should be <= 20MHz and the div value must be
+        * subtracted by 1 as per bspec
+        */
+       tx_div = DIV_ROUND_UP(dsi_rate, 20000) - 1;
+       /*
+        * rx clock should be <= 150MHz and the div value must be
+        * subtracted by 1 as per bspec
+        */
+       rx_div = DIV_ROUND_UP(dsi_rate, 150000) - 1;
 
        /*
-        * Tx escape clock must be as close to 20MHz possible, but should
-        * not exceed it. Hence select divide by 2
+        * rx divider value needs to be updated in the
+        * two differnt bit fields in the register hence splitting the
+        * rx divider value accordingly
         */
-       tmp |= BXT_MIPI_TX_ESCLK_8XDIV_BY2(port);
+       rx_div_lower = rx_div & RX_DIVIDER_BIT_1_2;
+       rx_div_upper = (rx_div & RX_DIVIDER_BIT_3_4) >> 2;
+
+       /* As per bpsec program the 8/3X clock divider to the below value */
+       if (dev_priv->vbt.dsi.config->is_cmd_mode)
+               mipi_8by3_divider = 0x2;
+       else
+               mipi_8by3_divider = 0x3;
 
-       tmp |= BXT_MIPI_RX_ESCLK_8X_BY3(port);
+       tmp |= BXT_MIPI_8X_BY3_DIVIDER(port, mipi_8by3_divider);
+       tmp |= BXT_MIPI_TX_ESCLK_DIVIDER(port, tx_div);
+       tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower);
+       tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper);
 
        I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
 }
@@ -513,9 +535,9 @@ static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
        /* Clear old configurations */
        tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
        tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
-       tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
-       tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port));
+       tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port));
+       tmp &= ~(BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port));
        I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
        I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
 }