[PATCH] clk: versal: Fix the function versal_clock_ref

Michal Simek michal.simek at amd.com
Mon Sep 18 11:10:27 CEST 2023



On 9/12/23 05:30, Venkatesh Yadav Abbarapu wrote:
> For reference clocks, PM_CLK_GET_PARENT call is not allowed.
> PM_CLK_GET_PARENT only allowed for MUX clocks. Rename the
> versal_clock_ref() with versal_clock_get_ref_rate() for better
> readability. Fix the versal_clock_get_ref_rate function by
> passing the parent_id, and check whether the parent_id
> belongs to ref_clk or pl_alt_ref_clk.
> Also adding the function versal_clock_get_fixed_factor_rate()
> if the clk_id belongs to the fixed factor clock.
> 
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
> ---
>   drivers/clk/clk_versal.c | 98 ++++++++++++++++++++++++++--------------
>   1 file changed, 65 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c
> index b3b3333123..2e004beca2 100644
> --- a/drivers/clk/clk_versal.c
> +++ b/drivers/clk/clk_versal.c
> @@ -68,6 +68,13 @@
>   #define CLOCK_NODE_TYPE_DIV	4
>   #define CLOCK_NODE_TYPE_GATE	6
>   
> +#define PM_CLK_REF_CLK		(0x830c06aU)
> +#define PM_CLK_PL_ALT_REF_CLK	(0x830c06bU)
> +#define PM_CLK_MUXED_IRO	(0x830c06cU)
> +#define PM_CLK_EMIO		(0x830c071U)
> +
> +#define TOPOLOGY_TYPE_FIXEDFACTOR	0x3
> +
>   enum clk_type {
>   	CLK_TYPE_OUTPUT,
>   	CLK_TYPE_EXTERNAL,
> @@ -365,48 +372,37 @@ static u32 versal_clock_set_div(u32 clk_id, u32 div)
>   	return div;
>   }
>   
> -static u64 versal_clock_ref(u32 clk_id)
> +static u64 versal_clock_get_ref_rate(u32 clk_id)
>   {
> -	u32 ret_payload[PAYLOAD_ARG_CNT];
> -	int ref;
> -
> -	xilinx_pm_request(PM_CLOCK_GETPARENT, clk_id, 0, 0, 0, ret_payload);
> -	ref = ret_payload[0];
> -	if (!(ref & 1))
> +	if (clk_id == PM_CLK_REF_CLK || clk_id == PM_CLK_MUXED_IRO || clk_id == PM_CLK_EMIO)
>   		return ref_clk;
> -	if (ref & 2)
> +	else if (clk_id == PM_CLK_PL_ALT_REF_CLK)
>   		return pl_alt_ref_clk;
> -	return 0;
> +	else
> +		return 0;
>   }
>   
> -static u64 versal_clock_get_pll_rate(u32 clk_id)
> +static int versal_clock_get_fixed_factor_rate(u32 clock_id, u32 parent_id)
>   {
> +	struct versal_pm_query_data qdata = {0};
>   	u32 ret_payload[PAYLOAD_ARG_CNT];
> -	u32 fbdiv;
> -	u32 res;
> -	u32 frac;
> -	u64 freq;
> -	u32 parent_rate, parent_id;
> -	u32 id = clk_id & 0xFFF;
> +	u32 mult, div;
> +	u32 parent_rate;
> +	int ret;
>   
> -	xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, ret_payload);
> -	res = ret_payload[1];
> -	if (!res) {
> -		printf("0%x PLL not enabled\n", clk_id);
> -		return 0;
> -	}
> +	qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
> +	qdata.arg1 = clock_id;
>   
> -	parent_id = clock[clock[id].parent[0].id].clk_id;
> -	parent_rate = versal_clock_ref(parent_id);
> +	ret = versal_pm_query(qdata, ret_payload);
> +	if (ret)
> +		return ret;
>   
> -	xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload);
> -	fbdiv = ret_payload[1];
> -	xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, ret_payload);
> -	frac = ret_payload[1];
> +	mult = ret_payload[1];
> +	div = ret_payload[2];
>   
> -	freq = (fbdiv * parent_rate) >> (1 << frac);
> +	parent_rate = versal_clock_get_ref_rate(parent_id);
> +	return parent_rate * mult / div;
>   
> -	return freq;
>   }
>   
>   static u32 versal_clock_mux(u32 clk_id)
> @@ -437,6 +433,37 @@ static u32 versal_clock_get_parentid(u32 clk_id)
>   	return clock[clock[id].parent[parent_id].id].clk_id;
>   }
>   
> +static u64 versal_clock_get_pll_rate(u32 clk_id)
> +{
> +	u32 ret_payload[PAYLOAD_ARG_CNT];
> +	u32 fbdiv;
> +	u32 res;
> +	u32 frac;
> +	u64 freq;
> +	u32 parent_rate, parent_id, parent_ref_clk_id;
> +	u32 id = clk_id & 0xFFF;
> +
> +	xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, ret_payload);
> +	res = ret_payload[1];
> +	if (!res) {
> +		printf("0%x PLL not enabled\n", clk_id);
> +		return 0;
> +	}
> +
> +	parent_id = clock[clock[id].parent[0].id].clk_id;
> +	parent_ref_clk_id = versal_clock_get_parentid(parent_id);
> +	parent_rate = versal_clock_get_ref_rate(parent_ref_clk_id);
> +
> +	xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload);
> +	fbdiv = ret_payload[1];
> +	xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, ret_payload);
> +	frac = ret_payload[1];
> +
> +	freq = (fbdiv * parent_rate) >> (1 << frac);
> +
> +	return freq;
> +}
> +
>   static u32 versal_clock_gate(u32 clk_id)
>   {
>   	u32 id = clk_id & 0xFFF;
> @@ -479,14 +506,19 @@ static u64 versal_clock_calc(u32 clk_id)
>   	u32 parent_id;
>   	u64 clk_rate;
>   	u32 div;
> +	struct clock_topology topology;
>   
>   	if (versal_clock_pll(clk_id, &clk_rate))
>   		return clk_rate;
>   
>   	parent_id = versal_clock_get_parentid(clk_id);
>   	if (((parent_id >> NODE_SUBCLASS_SHIFT) &
> -	     NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF)
> -		return versal_clock_ref(clk_id);
> +	     NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF) {
> +		topology = clock[clk_id & 0x3FF].node[0];
> +		if (topology.type == TOPOLOGY_TYPE_FIXEDFACTOR)
> +			return versal_clock_get_fixed_factor_rate(clk_id, parent_id);
> +		return versal_clock_get_ref_rate(parent_id);
> +	}
>   
>   	if (!parent_id)
>   		return 0;
> @@ -505,7 +537,7 @@ static int versal_clock_get_rate(u32 clk_id, u64 *clk_rate)
>   {
>   	if (((clk_id >>  NODE_SUBCLASS_SHIFT) &
>   	     NODE_CLASS_MASK) == NODE_SUBCLASS_CLOCK_REF)
> -		*clk_rate = versal_clock_ref(clk_id);
> +		*clk_rate = versal_clock_get_ref_rate(clk_id);
>   
>   	if (versal_clock_pll(clk_id, clk_rate))
>   		return 0;

Applied.
M


More information about the U-Boot mailing list