Re: [PATCH 1/3] drm: rcar-du: Rework clock configuration based on hardware limits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Laurent,

On Mon, Jul 30, 2018 at 07:20:12PM +0200, Jacopo Mondi wrote:
> From: Laurent Pinchart <laurent.pinchart+renesas@xxxxxxxxxxxxxxxx>
>
> The DU channels that have a display PLL (DPLL) can only use external
> clock sources, and don't have an internal clock divider (with the
> exception of H3 ES1.x where the post-divider is present and needs to be
> used as a workaround for a DPLL silicon issue).
>
> Rework the clock configuration to take this into account, avoiding
> selection of non-existing clock sources or usage of a missing
> post-divider.
>

I have based my work on non-DPLL channel selection on this patch, but
always forgot to add my:
Reviewed-by: Jacopo Mondi <jacopo+renesas@xxxxxxxxxx>

Thanks
   j

> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@xxxxxxxxxxxxxxxx>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 122 ++++++++++++++++++---------------
>  1 file changed, 67 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index b52b3e8..6d55cec 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -208,78 +208,90 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>  	const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
>  	struct rcar_du_device *rcdu = rcrtc->group->dev;
>  	unsigned long mode_clock = mode->clock * 1000;
> -	unsigned long clk;
>  	u32 value;
>  	u32 escr;
> -	u32 div;
>
> -	/*
> -	 * Compute the clock divisor and select the internal or external dot
> -	 * clock based on the requested frequency.
> -	 */
> -	clk = clk_get_rate(rcrtc->clock);
> -	div = DIV_ROUND_CLOSEST(clk, mode_clock);
> -	div = clamp(div, 1U, 64U) - 1;
> -	escr = div | ESCR_DCLKSEL_CLKS;
> -
> -	if (rcrtc->extclock) {
> +	if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
> +		unsigned long target = mode_clock;
>  		struct dpll_info dpll = { 0 };
>  		unsigned long extclk;
> -		unsigned long extrate;
> -		unsigned long rate;
> -		u32 extdiv;
> +		u32 dpllcr;
> +		u32 div = 0;
>
> -		extclk = clk_get_rate(rcrtc->extclock);
> -		if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
> -			unsigned long target = mode_clock;
> +		/*
> +		 * DU channels that have a display PLL can't use the internal
> +		 * system clock, and have no internal clock divider.
> +		 */
>
> -			/*
> -			 * The H3 ES1.x exhibits dot clock duty cycle stability
> -			 * issues. We can work around them by configuring the
> -			 * DPLL to twice the desired frequency, coupled with a
> -			 * /2 post-divider. This isn't needed on other SoCs and
> -			 * breaks HDMI output on M3-W for a currently unknown
> -			 * reason, so restrict the workaround to H3 ES1.x.
> -			 */
> -			if (soc_device_match(rcar_du_r8a7795_es1))
> -				target *= 2;
> +		if (WARN_ON(!rcrtc->extclock))
> +			return;
>
> -			rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
> -			extclk = dpll.output;
> +		/*
> +		 * The H3 ES1.x exhibits dot clock duty cycle stability issues.
> +		 * We can work around them by configuring the DPLL to twice the
> +		 * desired frequency, coupled with a /2 post-divider. Restrict
> +		 * the workaround to H3 ES1.x as ES2.0 and all other SoCs have
> +		 * no post-divider when a display PLL is present (as shown by
> +		 * the workaround breaking HDMI output on M3-W during testing).
> +		 */
> +		if (soc_device_match(rcar_du_r8a7795_es1)) {
> +			target *= 2;
> +			div = 1;
>  		}
>
> -		extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
> -		extdiv = clamp(extdiv, 1U, 64U) - 1;
> +		extclk = clk_get_rate(rcrtc->extclock);
> +		rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
>
> -		rate = clk / (div + 1);
> -		extrate = extclk / (extdiv + 1);
> +		dpllcr = DPLLCR_CODE | DPLLCR_CLKE
> +		       | DPLLCR_FDPLL(dpll.fdpll)
> +		       | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
> +		       | DPLLCR_STBY;
>
> -		if (abs((long)extrate - (long)mode_clock) <
> -		    abs((long)rate - (long)mode_clock)) {
> +		if (rcrtc->index == 1)
> +			dpllcr |= DPLLCR_PLCS1
> +			       |  DPLLCR_INCS_DOTCLKIN1;
> +		else
> +			dpllcr |= DPLLCR_PLCS0
> +			       |  DPLLCR_INCS_DOTCLKIN0;
>
> -			if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
> -				u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
> -					   | DPLLCR_FDPLL(dpll.fdpll)
> -					   | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
> -					   | DPLLCR_STBY;
> +		rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>
> -				if (rcrtc->index == 1)
> -					dpllcr |= DPLLCR_PLCS1
> -					       |  DPLLCR_INCS_DOTCLKIN1;
> -				else
> -					dpllcr |= DPLLCR_PLCS0
> -					       |  DPLLCR_INCS_DOTCLKIN0;
> +		escr = ESCR_DCLKSEL_DCLKIN | div;
> +	} else {
> +		unsigned long clk;
> +		u32 div;
>
> -				rcar_du_group_write(rcrtc->group, DPLLCR,
> -						    dpllcr);
> -			}
> +		/*
> +		 * Compute the clock divisor and select the internal or external
> +		 * dot clock based on the requested frequency.
> +		 */
> +		clk = clk_get_rate(rcrtc->clock);
> +		div = DIV_ROUND_CLOSEST(clk, mode_clock);
> +		div = clamp(div, 1U, 64U) - 1;
>
> -			escr = ESCR_DCLKSEL_DCLKIN | extdiv;
> -		}
> +		escr = ESCR_DCLKSEL_CLKS | div;
>
> -		dev_dbg(rcrtc->group->dev->dev,
> -			"mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
> -			mode_clock, extrate, rate, escr);
> +		if (rcrtc->extclock) {
> +			unsigned long extclk;
> +			unsigned long extrate;
> +			unsigned long rate;
> +			u32 extdiv;
> +
> +			extclk = clk_get_rate(rcrtc->extclock);
> +			extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
> +			extdiv = clamp(extdiv, 1U, 64U) - 1;
> +
> +			extrate = extclk / (extdiv + 1);
> +			rate = clk / (div + 1);
> +
> +			if (abs((long)extrate - (long)mode_clock) <
> +			    abs((long)rate - (long)mode_clock))
> +				escr = ESCR_DCLKSEL_DCLKIN | extdiv;
> +
> +			dev_dbg(rcrtc->group->dev->dev,
> +				"mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
> +				mode_clock, extrate, rate, escr);
> +		}
>  	}
>
>  	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
> --
> 2.7.4
>

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux