Re: [PATCH V3 3/3] OMAPDSS: DISPC: Correct DISPC functional clock usage

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

 



On Mon, 2012-04-02 at 20:43 +0530, Chandrabhanu Mahapatra wrote:
> DISPC_FCLK is incorrectly used as functional clock of DISPC in scaling
> calculations. So, DISPC_CORE_CLK replaces as functional clock of DISPC.
> DISPC_CORE_CLK is derived from DISPC_FCLK divided by an independent DISPC
> divisor LCD.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@xxxxxx>
> ---
>  drivers/video/omap2/dss/dispc.c |   28 ++++++++++++++++++++++------
>  drivers/video/omap2/dss/dss.h   |    1 +
>  2 files changed, 23 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 17ffa71..cfde674 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -1813,6 +1813,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
>  				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
>  	const int max_decim_limit = 16;
>  	unsigned long fclk = 0;
> +	unsigned long dispc_core_clk = dispc_core_clk_rate(channel);
>  	int decim_x, decim_y, error, min_factor;
>  	u16 in_width, in_height, in_width_max = 0;
>  
> @@ -1855,7 +1856,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
>  			fclk = calc_fclk(channel, in_width, in_height,
>  					out_width, out_height);
>  			error = (in_width > maxsinglelinewidth || !fclk ||
> -				fclk > dispc_fclk_rate());
> +				fclk > dispc_core_clk);
>  			if (error) {
>  				if (decim_x == decim_y) {
>  					decim_x = min_factor;
> @@ -1893,7 +1894,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
>  					out_width, out_height);
>  			error = (error || in_width > maxsinglelinewidth * 2 ||
>  				(in_width > maxsinglelinewidth && *five_taps) ||
> -				!fclk || fclk > dispc_fclk_rate());
> +				!fclk || fclk > dispc_core_clk);
>  			if (error) {
>  				if (decim_x == decim_y) {
>  					decim_x = min_factor;
> @@ -1926,7 +1927,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
>  	} else {
>  		int decim_x_min = decim_x;
>  		in_height = DIV_ROUND_UP(height, decim_y);
> -		in_width_max = dispc_fclk_rate() /
> +		in_width_max = dispc_core_clk /
>  				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
>  						out_width);
>  		decim_x = DIV_ROUND_UP(width, in_width_max);
> @@ -1950,13 +1951,13 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
>  	}
>  
>  	DSSDBG("required fclk rate = %lu Hz\n", fclk);
> -	DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
> +	DSSDBG("current fclk rate = %lu Hz\n", dispc_core_clk);
>  
> -	if (!fclk || fclk > dispc_fclk_rate()) {
> +	if (!fclk || fclk > dispc_core_clk) {
>  		DSSERR("failed to set up scaling, "
>  			"required fclk rate = %lu Hz, "
>  			"current fclk rate = %lu Hz\n",
> -			fclk, dispc_fclk_rate());
> +			fclk, dispc_core_clk);
>  		return -EINVAL;
>  	}
>  
> @@ -2646,6 +2647,21 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
>  	}
>  }
>  
> +unsigned long dispc_core_clk_rate(enum omap_channel channel)
> +{
> +	int lcd = 1;
> +	unsigned long r = dispc_fclk_rate();
> +
> +	if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
> +		lcd = REG_GET(DISPC_DIVISOR, 23, 16);
> +	} else {
> +		if (dispc_mgr_is_lcd(channel))
> +			lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16);
> +	}
> +
> +	return r / lcd ;
> +}
> +

I wonder if this is correct. "channel" for dispc core clock doesn't make
sense, there's no channel related to that. At least on OMAP4.

If I'm not mistaken, in omap2/3 case (i.e.
dss_has_feature(FEAT_CORE_CLK_DIV) == false) we can just use channel 0
to get the lcd divisor. Although that would mean that LCD output's
divisor affects the tv-out's scaling calculations, which feels a bit
strange...

So... I don't know... Do we really have two different dispc core clocks
int omap2/3 (for lcd output and for tv output), but only one in omap4?
If so, then the above code is ok. Have you found explanations from TRM
which say what clock is required and where?

In any case, please remove the initialization of lcd variable, and add:

else
	lcd = 1;

I think that's much clearer. And "r" variable is commonly used as a
return value. I would rename the variable to something else, say, "fck".

 Tomi

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux