diff mbox

drm/i915/bxt: Additional MIPI clock divider form B0 stepping onwards

Message ID 1455556437-29267-1-git-send-email-m.deepak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Deepak M Feb. 15, 2016, 5:13 p.m. UTC
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>
---
 drivers/gpu/drm/i915/i915_reg.h      | 96 +++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++-------
 2 files changed, 89 insertions(+), 63 deletions(-)

Comments

Jani Nikula Feb. 17, 2016, 8:30 p.m. UTC | #1
On Mon, 15 Feb 2016, Deepak M <m.deepak@intel.com> wrote:
> 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>

Reviewed-by: Jani Nikula <jani.nikula@intel.com>


> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 96 +++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++-------
>  2 files changed, 89 insertions(+), 63 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 144586e..4e61b06 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7663,58 +7663,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
> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
> index bb5e95a..02aeae5 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
> @@ -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);
>  }
Jani Nikula Feb. 19, 2016, 9:18 a.m. UTC | #2
On Wed, 17 Feb 2016, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Mon, 15 Feb 2016, Deepak M <m.deepak@intel.com> wrote:
>> 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>
>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>

The problem here is that we have no Tested-by on B0+ hardware for this.

>
>
>> ---
>>  drivers/gpu/drm/i915/i915_reg.h      | 96 +++++++++++++++++++-----------------
>>  drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++-------
>>  2 files changed, 89 insertions(+), 63 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 144586e..4e61b06 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -7663,58 +7663,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
>> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
>> index bb5e95a..02aeae5 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
>> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
>> @@ -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);
>>  }
Ramalingam C Feb. 26, 2016, 4:49 p.m. UTC | #3
On Thursday 18 February 2016 02:00 AM, Jani Nikula wrote:
> On Mon, 15 Feb 2016, Deepak M <m.deepak@intel.com> wrote:
>> 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>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Tested-by: Ramalingam C <ramalingam.c@intel.com>

Tested it on BXT-T with Tianma panel.
>
>
>> ---
>>   drivers/gpu/drm/i915/i915_reg.h      | 96 +++++++++++++++++++-----------------
>>   drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++-------
>>   2 files changed, 89 insertions(+), 63 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 144586e..4e61b06 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -7663,58 +7663,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
>> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
>> index bb5e95a..02aeae5 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
>> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
>> @@ -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);
>>   }
Jani Nikula March 3, 2016, 1:06 p.m. UTC | #4
On Fri, 26 Feb 2016, Ramalingam C <ramalingam.c@intel.com> wrote:
> On Thursday 18 February 2016 02:00 AM, Jani Nikula wrote:
>> On Mon, 15 Feb 2016, Deepak M <m.deepak@intel.com> wrote:
>>> 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>
>> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> Tested-by: Ramalingam C <ramalingam.c@intel.com>
>
> Tested it on BXT-T with Tianma panel.

Pushed to drm-intel-next-queued, thanks for the patch and testing.

BR,
Jani.


>>
>>
>>> ---
>>>   drivers/gpu/drm/i915/i915_reg.h      | 96 +++++++++++++++++++-----------------
>>>   drivers/gpu/drm/i915/intel_dsi_pll.c | 56 ++++++++++++++-------
>>>   2 files changed, 89 insertions(+), 63 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>>> index 144586e..4e61b06 100644
>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>> @@ -7663,58 +7663,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
>>> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
>>> index bb5e95a..02aeae5 100644
>>> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
>>> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
>>> @@ -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);
>>>   }
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 144586e..4e61b06 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7663,58 +7663,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
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index bb5e95a..02aeae5 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -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);
 }