[PATCH v3 2/7] clk: st: flexgen: embed soc clock outputs within compatible data

Patrice CHOTARD patrice.chotard at foss.st.com
Wed Mar 31 17:06:22 BST 2021


Hi Alain

I have tested your series on STiH410-B2260 board and it misses a critical flag, see below

On 3/30/21 10:51 PM, Alain Volmat wrote:
> In order to avoid relying on the old style description via the DT
> clock-output-names, add compatible data describing the flexgen
> outputs clocks for all STiH407/STiH410 and STiH418 SOCs.
> 
> In order to ease transition between the two methods, this commit
> introduce the new compatible without removing the old method.
> Once DTs will be fixed, the method relying on DT clock-output-names
> will be removed from this driver as well as old compatibles.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
> v3: add comments about CLK_IS_CRITICAL reason
>     don't put clk-proc-stfe as CLK_IS_CRITICAL
> v2: add some missing clock as CLK_IS_CRITICAL
> 
>  drivers/clk/st/clk-flexgen.c | 366 +++++++++++++++++++++++++++++++++--
>  1 file changed, 352 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
> index 55873d4b7603..69711c6c47a4 100644
> --- a/drivers/clk/st/clk-flexgen.c
> +++ b/drivers/clk/st/clk-flexgen.c
> @@ -16,9 +16,16 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> +struct clkgen_clk_out {
> +	const char *name;
> +	unsigned long flags;
> +};
> +
>  struct clkgen_data {
>  	unsigned long flags;
>  	bool mode;
> +	const struct clkgen_clk_out *outputs;
> +	const unsigned int outputs_nb;
>  };
>  
>  struct flexgen {
> @@ -295,6 +302,289 @@ static const struct clkgen_data clkgen_video = {
>  	.mode = 1,
>  };
>  
> +static const struct clkgen_clk_out clkgen_stih407_a0_clk_out[] = {
> +	/* This clk needs to be on so that memory interface is accessible */
> +	{ .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL },
> +};
> +
> +static const struct clkgen_data clkgen_stih407_a0 = {
> +	.outputs = clkgen_stih407_a0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih407_a0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih410_a0_clk_out[] = {
> +	/* Those clks need to be on so that memory interface is accessible */
> +	{ .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-ic-lmi1", .flags = CLK_IS_CRITICAL },
> +};
> +
> +static const struct clkgen_data clkgen_stih410_a0 = {
> +	.outputs = clkgen_stih410_a0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih410_a0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih407_c0_clk_out[] = {
> +	{ .name = "clk-icn-gpu", },
> +	{ .name = "clk-fdma", },
> +	{ .name = "clk-nand", },
> +	{ .name = "clk-hva", },
> +	{ .name = "clk-proc-stfe", },
> +	{ .name = "clk-proc-tp", },
> +	{ .name = "clk-rx-icn-dmu", },
> +	{ .name = "clk-rx-icn-hva", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-mmc-0", },
> +	{ .name = "clk-mmc-1", },
> +	{ .name = "clk-jpegdec", },
> +	/* This clk needs to be on to keep A9 running */
> +	{ .name = "clk-ext2fa9", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-ic-bdisp-0", },
> +	{ .name = "clk-ic-bdisp-1", },
> +	{ .name = "clk-pp-dmu", },
> +	{ .name = "clk-vid-dmu", },
> +	{ .name = "clk-dss-lpc", },
> +	{ .name = "clk-st231-aud-0", },
> +	{ .name = "clk-st231-gp-1", },
> +	{ .name = "clk-st231-dmu", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-tx-icn-disp-1", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-stfe-frc2", },
> +	{ .name = "clk-eth-phy", },
> +	{ .name = "clk-eth-ref-phyclk", },
> +	{ .name = "clk-flash-promip", },
> +	{ .name = "clk-main-disp", },
> +	{ .name = "clk-aux-disp", },
> +	{ .name = "clk-compo-dvp", },
> +};
> +
> +static const struct clkgen_data clkgen_stih407_c0 = {
> +	.outputs = clkgen_stih407_c0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih407_c0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih410_c0_clk_out[] = {
> +	{ .name = "clk-icn-gpu", },
> +	{ .name = "clk-fdma", },
> +	{ .name = "clk-nand", },
> +	{ .name = "clk-hva", },
> +	{ .name = "clk-proc-stfe", },
> +	{ .name = "clk-proc-tp", },
> +	{ .name = "clk-rx-icn-dmu", },
> +	{ .name = "clk-rx-icn-hva", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-mmc-0", },
> +	{ .name = "clk-mmc-1", },
> +	{ .name = "clk-jpegdec", },
> +	/* This clk needs to be on to keep A9 running */
> +	{ .name = "clk-ext2fa9", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-ic-bdisp-0", },
> +	{ .name = "clk-ic-bdisp-1", },
> +	{ .name = "clk-pp-dmu", },
> +	{ .name = "clk-vid-dmu", },
> +	{ .name = "clk-dss-lpc", },
> +	{ .name = "clk-st231-aud-0", },
> +	{ .name = "clk-st231-gp-1", },
> +	{ .name = "clk-st231-dmu", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-tx-icn-disp-1", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-stfe-frc2", },
> +	{ .name = "clk-eth-phy", },
> +	{ .name = "clk-eth-ref-phyclk", },
> +	{ .name = "clk-flash-promip", },
> +	{ .name = "clk-main-disp", },
> +	{ .name = "clk-aux-disp", },
> +	{ .name = "clk-compo-dvp", },
> +	{ .name = "clk-tx-icn-hades", },
> +	{ .name = "clk-rx-icn-hades", },
> +	{ .name = "clk-icn-reg-16", },

Need to add CLK_IS_CRITICAL for clk-icn-reg-16
This was a long time bug which is hidden by usage of clk_ignore_unused in bootargs.

With that fix, you can add 

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice

> +	{ .name = "clk-pp-hades", },
> +	{ .name = "clk-clust-hades", },
> +	{ .name = "clk-hwpe-hades", },
> +	{ .name = "clk-fc-hades", },
> +};
> +
> +static const struct clkgen_data clkgen_stih410_c0 = {
> +	.outputs = clkgen_stih410_c0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih410_c0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih418_c0_clk_out[] = {
> +	{ .name = "clk-icn-gpu", },
> +	{ .name = "clk-fdma", },
> +	{ .name = "clk-nand", },
> +	{ .name = "clk-hva", },
> +	{ .name = "clk-proc-stfe", },
> +	{ .name = "clk-tp", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-rx-icn-dmu", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-rx-icn-hva", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-mmc-0", },
> +	{ .name = "clk-mmc-1", },
> +	{ .name = "clk-jpegdec", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-reg", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-proc-bdisp-0", },
> +	{ .name = "clk-proc-bdisp-1", },
> +	{ .name = "clk-pp-dmu", },
> +	{ .name = "clk-vid-dmu", },
> +	{ .name = "clk-dss-lpc", },
> +	{ .name = "clk-st231-aud-0", },
> +	{ .name = "clk-st231-gp-1", },
> +	{ .name = "clk-st231-dmu", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-tx-icn-1", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-stfe-frc2", },
> +	{ .name = "clk-eth-phyref", },
> +	{ .name = "clk-eth-ref-phyclk", },
> +	{ .name = "clk-flash-promip", },
> +	{ .name = "clk-main-disp", },
> +	{ .name = "clk-aux-disp", },
> +	{ .name = "clk-compo-dvp", },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-tx-icn-hades", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-rx-icn-hades", .flags = CLK_IS_CRITICAL },
> +	/* This clk needs to be on to keep bus interconnect alive */
> +	{ .name = "clk-icn-reg-16", .flags = CLK_IS_CRITICAL },
> +	{ .name = "clk-pp-hevc", },
> +	{ .name = "clk-clust-hevc", },
> +	{ .name = "clk-hwpe-hevc", },
> +	{ .name = "clk-fc-hevc", },
> +	{ .name = "clk-proc-mixer", },
> +	{ .name = "clk-proc-sc", },
> +	{ .name = "clk-avsp-hevc", },
> +};
> +
> +static const struct clkgen_data clkgen_stih418_c0 = {
> +	.outputs = clkgen_stih418_c0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih418_c0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih407_d0_clk_out[] = {
> +	{ .name = "clk-pcm-0", },
> +	{ .name = "clk-pcm-1", },
> +	{ .name = "clk-pcm-2", },
> +	{ .name = "clk-spdiff", },
> +};
> +
> +static const struct clkgen_data clkgen_stih407_d0 = {
> +	.flags = CLK_SET_RATE_PARENT,
> +	.outputs = clkgen_stih407_d0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih407_d0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih410_d0_clk_out[] = {
> +	{ .name = "clk-pcm-0", },
> +	{ .name = "clk-pcm-1", },
> +	{ .name = "clk-pcm-2", },
> +	{ .name = "clk-spdiff", },
> +	{ .name = "clk-pcmr10-master", },
> +	{ .name = "clk-usb2-phy", },
> +};
> +
> +static const struct clkgen_data clkgen_stih410_d0 = {
> +	.flags = CLK_SET_RATE_PARENT,
> +	.outputs = clkgen_stih410_d0_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih410_d0_clk_out),
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih407_d2_clk_out[] = {
> +	{ .name = "clk-pix-main-disp", },
> +	{ .name = "clk-pix-pip", },
> +	{ .name = "clk-pix-gdp1", },
> +	{ .name = "clk-pix-gdp2", },
> +	{ .name = "clk-pix-gdp3", },
> +	{ .name = "clk-pix-gdp4", },
> +	{ .name = "clk-pix-aux-disp", },
> +	{ .name = "clk-denc", },
> +	{ .name = "clk-pix-hddac", },
> +	{ .name = "clk-hddac", },
> +	{ .name = "clk-sddac", },
> +	{ .name = "clk-pix-dvo", },
> +	{ .name = "clk-dvo", },
> +	{ .name = "clk-pix-hdmi", },
> +	{ .name = "clk-tmds-hdmi", },
> +	{ .name = "clk-ref-hdmiphy", },
> +};
> +
> +static const struct clkgen_data clkgen_stih407_d2 = {
> +	.outputs = clkgen_stih407_d2_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih407_d2_clk_out),
> +	.flags = CLK_SET_RATE_PARENT,
> +	.mode = 1,
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih418_d2_clk_out[] = {
> +	{ .name = "clk-pix-main-disp", },
> +	{ .name = "", },
> +	{ .name = "", },
> +	{ .name = "", },
> +	{ .name = "", },
> +	{ .name = "clk-tmds-hdmi-div2", },
> +	{ .name = "clk-pix-aux-disp", },
> +	{ .name = "clk-denc", },
> +	{ .name = "clk-pix-hddac", },
> +	{ .name = "clk-hddac", },
> +	{ .name = "clk-sddac", },
> +	{ .name = "clk-pix-dvo", },
> +	{ .name = "clk-dvo", },
> +	{ .name = "clk-pix-hdmi", },
> +	{ .name = "clk-tmds-hdmi", },
> +	{ .name = "clk-ref-hdmiphy", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "", }, { .name = "", }, { .name = "", },
> +	{ .name = "clk-vp9", },
> +};
> +
> +static const struct clkgen_data clkgen_stih418_d2 = {
> +	.outputs = clkgen_stih418_d2_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih418_d2_clk_out),
> +	.flags = CLK_SET_RATE_PARENT,
> +	.mode = 1,
> +};
> +
> +static const struct clkgen_clk_out clkgen_stih407_d3_clk_out[] = {
> +	{ .name = "clk-stfe-frc1", },
> +	{ .name = "clk-tsout-0", },
> +	{ .name = "clk-tsout-1", },
> +	{ .name = "clk-mchi", },
> +	{ .name = "clk-vsens-compo", },
> +	{ .name = "clk-frc1-remote", },
> +	{ .name = "clk-lpc-0", },
> +	{ .name = "clk-lpc-1", },
> +};
> +
> +static const struct clkgen_data clkgen_stih407_d3 = {
> +	.outputs = clkgen_stih407_d3_clk_out,
> +	.outputs_nb = ARRAY_SIZE(clkgen_stih407_d3_clk_out),
> +};
> +
>  static const struct of_device_id flexgen_of_match[] = {
>  	{
>  		.compatible = "st,flexgen-audio",
> @@ -304,6 +594,46 @@ static const struct of_device_id flexgen_of_match[] = {
>  		.compatible = "st,flexgen-video",
>  		.data = &clkgen_video,
>  	},
> +	{
> +		.compatible = "st,flexgen-stih407-a0",
> +		.data = &clkgen_stih407_a0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih410-a0",
> +		.data = &clkgen_stih410_a0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih407-c0",
> +		.data = &clkgen_stih407_c0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih410-c0",
> +		.data = &clkgen_stih410_c0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih418-c0",
> +		.data = &clkgen_stih418_c0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih407-d0",
> +		.data = &clkgen_stih407_d0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih410-d0",
> +		.data = &clkgen_stih410_d0,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih407-d2",
> +		.data = &clkgen_stih407_d2,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih418-d2",
> +		.data = &clkgen_stih418_d2,
> +	},
> +	{
> +		.compatible = "st,flexgen-stih407-d3",
> +		.data = &clkgen_stih407_d3,
> +	},
>  	{}
>  };
>  
> @@ -320,6 +650,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
>  	unsigned long flex_flags = 0;
>  	int ret;
>  	bool clk_mode = 0;
> +	const char *clk_name;
>  
>  	pnode = of_get_parent(np);
>  	if (!pnode)
> @@ -347,13 +678,17 @@ static void __init st_of_flexgen_setup(struct device_node *np)
>  	if (!clk_data)
>  		goto err;
>  
> -	ret = of_property_count_strings(np, "clock-output-names");
> -	if (ret <= 0) {
> -		pr_err("%s: Failed to get number of output clocks (%d)",
> -				__func__, clk_data->clk_num);
> -		goto err;
> -	}
> -	clk_data->clk_num = ret;
> +	/* First try to get output information from the compatible data */
> +	if (!data || !data->outputs_nb || !data->outputs) {
> +		ret = of_property_count_strings(np, "clock-output-names");
> +		if (ret <= 0) {
> +			pr_err("%s: Failed to get number of output clocks (%d)",
> +					__func__, clk_data->clk_num);
> +			goto err;
> +		}
> +		clk_data->clk_num = ret;
> +	} else
> +		clk_data->clk_num = data->outputs_nb;
>  
>  	clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
>  			GFP_KERNEL);
> @@ -368,16 +703,19 @@ static void __init st_of_flexgen_setup(struct device_node *np)
>  
>  	for (i = 0; i < clk_data->clk_num; i++) {
>  		struct clk *clk;
> -		const char *clk_name;
>  
> -		if (of_property_read_string_index(np, "clock-output-names",
> -						  i, &clk_name)) {
> -			break;
> +		if (!data || !data->outputs_nb || !data->outputs) {
> +			if (of_property_read_string_index(np,
> +							  "clock-output-names",
> +							  i, &clk_name))
> +				break;
> +			flex_flags &= ~CLK_IS_CRITICAL;
> +			of_clk_detect_critical(np, i, &flex_flags);
> +		} else {
> +			clk_name = data->outputs[i].name;
> +			flex_flags = data->flags | data->outputs[i].flags;
>  		}
>  
> -		flex_flags &= ~CLK_IS_CRITICAL;
> -		of_clk_detect_critical(np, i, &flex_flags);
> -
>  		/*
>  		 * If we read an empty clock name then the output is unused
>  		 */
> 



More information about the linux-arm-kernel mailing list