[PATCH v3 6/9] drm/bridge: ti-sn65dsi86: Use 18-bit DP if we can

Bjorn Andersson bjorn.andersson at linaro.org
Mon Feb 3 23:37:11 UTC 2020


On Wed 18 Dec 14:35 PST 2019, Douglas Anderson wrote:

> The current bridge driver always forced us to use 24 bits per pixel
> over the DP link.  This is a waste if you are hooked up to a panel
> that only supports 6 bits per color or fewer, since in that case you
> ran run at 18 bits per pixel and thus end up at a lower DP clock rate.

s/ran/can/

> 
> Let's support this.
> 
> While at it, let's clean up the math in the function to avoid rounding
> errors (and round in the correct direction when we have to round).
> Numbers are sufficiently small (because mode->clock is in kHz) that we
> don't need to worry about integer overflow.
> 
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> Tested-by: Rob Clark <robdclark at gmail.com>
> Reviewed-by: Rob Clark <robdclark at gmail.com>

Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 27 ++++++++++++++++++---------
>  1 file changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index 0fc9e97b2d98..d5990a0947b9 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -51,6 +51,7 @@
>  #define SN_ENH_FRAME_REG			0x5A
>  #define  VSTREAM_ENABLE				BIT(3)
>  #define SN_DATA_FORMAT_REG			0x5B
> +#define  BPP_18_RGB				BIT(0)
>  #define SN_HPD_DISABLE_REG			0x5C
>  #define  HPD_DISABLE				BIT(0)
>  #define SN_AUX_WDATA_REG(x)			(0x64 + (x))
> @@ -436,6 +437,14 @@ static void ti_sn_bridge_set_dsi_rate(struct ti_sn_bridge *pdata)
>  	regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val);
>  }
>  
> +static unsigned int ti_sn_bridge_get_bpp(struct ti_sn_bridge *pdata)
> +{
> +	if (pdata->connector.display_info.bpc <= 6)
> +		return 18;
> +	else
> +		return 24;
> +}
> +
>  /**
>   * LUT index corresponds to register value and
>   * LUT values corresponds to dp data rate supported
> @@ -447,21 +456,17 @@ static const unsigned int ti_sn_bridge_dp_rate_lut[] = {
>  
>  static void ti_sn_bridge_set_dp_rate(struct ti_sn_bridge *pdata)
>  {
> -	unsigned int bit_rate_mhz, dp_rate_mhz;
> +	unsigned int bit_rate_khz, dp_rate_mhz;
>  	unsigned int i;
>  	struct drm_display_mode *mode =
>  		&pdata->bridge.encoder->crtc->state->adjusted_mode;
>  
> -	/*
> -	 * Calculate minimum bit rate based on our pixel clock.  At
> -	 * the moment this driver never sets the DP_18BPP_EN bit in
> -	 * register 0x5b so we hardcode 24bpp.
> -	 */
> -	bit_rate_mhz = (mode->clock / 1000) * 24;
> +	/* Calculate minimum bit rate based on our pixel clock. */
> +	bit_rate_khz = mode->clock * ti_sn_bridge_get_bpp(pdata);
>  
>  	/* Calculate minimum DP data rate, taking 80% as per DP spec */
> -	dp_rate_mhz = ((bit_rate_mhz / pdata->dp_lanes) * DP_CLK_FUDGE_NUM) /
> -							DP_CLK_FUDGE_DEN;
> +	dp_rate_mhz = DIV_ROUND_UP(bit_rate_khz * DP_CLK_FUDGE_NUM,
> +				   1000 * pdata->dp_lanes * DP_CLK_FUDGE_DEN);
>  
>  	for (i = 1; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++)
>  		if (ti_sn_bridge_dp_rate_lut[i] > dp_rate_mhz)
> @@ -550,6 +555,10 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
>  	regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
>  			   CHA_DSI_LANES_MASK, val);
>  
> +	/* Set the DP output format (18 bpp or 24 bpp) */
> +	val = (ti_sn_bridge_get_bpp(pdata) == 18) ? BPP_18_RGB : 0;
> +	regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val);
> +
>  	/* DP lane config */
>  	val = DP_NUM_LANES(min(pdata->dp_lanes, 3));
>  	regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK,
> -- 
> 2.24.1.735.g03f4e72817-goog
> 


More information about the dri-devel mailing list