Subject: [PATCH 2/2] clk: meson: gxbb: Add VPU and VAPB clocks data

From: [email-masked] (Jerome Brunet)
Date: Fri, 20 Oct 2017 10:02:57 +0200

On Mon, 2017-10-16 at 17:34 +0200, Neil Armstrong wrote:
> The Amlogic Meson GX SoCs needs these two clocks to power up the
> VPU power domain.
> 
> These two clocks are similar to the MALI clocks by having a glitch-free
> mux and two similar clocks with gate, divider and muxes.
> 
> Signed-off-by: Neil Armstrong <[email-masked]>
> ---
>  drivers/clk/meson/gxbb.c | 292
> +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 292 insertions(+)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index b2d1e8e..a713744 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -1131,6 +1131,253 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = {
>  	},
>  };
>  
> +/* VPU Clock */
> +
> +static u32 mux_table_vpu[] = {0, 1, 2, 3};
> +static const char * const gxbb_vpu_parent_names[] = {
> +	"fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
> +};
> +
> +static struct clk_mux gxbb_vpu_0_sel = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.mask = 0x3,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.table = mux_table_vpu,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_sel",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_names = gxbb_vpu_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,

AFAIK, CLK_IGNORE_UNUSED is not useful for generic muxes and dividers since they
don't implement enable/disbale.

You can drop these.
With that changed:

Acked-by: Jerome Brunet <[email-masked]>

> +	},
> +};
> +
> +static struct clk_divider gxbb_vpu_0_div = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "vpu_0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_gate gxbb_vpu_0 = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.bit_idx = 8,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "vpu_0_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_mux gxbb_vpu_1_sel = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.mask = 0x3,
> +	.shift = 25,
> +	.lock = &clk_lock,
> +	.table = mux_table_vpu,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_sel",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_names = gxbb_vpu_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_divider gxbb_vpu_1_div = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.shift = 16,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "vpu_1_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_gate gxbb_vpu_1 = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.bit_idx = 24,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_1",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "vpu_1_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_mux gxbb_vpu = {
> +	.reg = (void *)HHI_VPU_CLK_CNTL,
> +	.mask = 1,
> +	.shift = 31,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vpu_0 or vpu_1
> +		 */
> +		.parent_names = (const char *[]){ "vpu_0", "vpu_1" },
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* VAPB Clock */
> +
> +static u32 mux_table_vapb[] = {0, 1, 2, 3};
> +static const char * const gxbb_vapb_parent_names[] = {
> +	"fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
> +};
> +
> +static struct clk_mux gxbb_vapb_0_sel = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.mask = 0x3,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.table = mux_table_vapb,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_sel",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_names = gxbb_vapb_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_divider gxbb_vapb_0_div = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "vapb_0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_gate gxbb_vapb_0 = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.bit_idx = 8,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "vapb_0_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_mux gxbb_vapb_1_sel = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.mask = 0x3,
> +	.shift = 25,
> +	.lock = &clk_lock,
> +	.table = mux_table_vapb,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_sel",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_names = gxbb_vapb_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_divider gxbb_vapb_1_div = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.shift = 16,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "vapb_1_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_gate gxbb_vapb_1 = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.bit_idx = 24,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_1",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "vapb_1_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_mux gxbb_vapb_sel = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.mask = 1,
> +	.shift = 31,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_sel",
> +		.ops = &clk_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vapb_0 or vapb_1
> +		 */
> +		.parent_names = (const char *[]){ "vapb_0", "vapb_1" },
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_gate gxbb_vapb = {
> +	.reg = (void *)HHI_VAPBCLK_CNTL,
> +	.bit_idx = 30,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "vapb_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
>  /* Everything Else (EE) domain gates */
>  static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
>  static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
> @@ -1349,6 +1596,21 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data
> = {
>  		[CLKID_SD_EMMC_C_CLK0_SEL]  = &gxbb_sd_emmc_c_clk0_sel.hw,
>  		[CLKID_SD_EMMC_C_CLK0_DIV]  = &gxbb_sd_emmc_c_clk0_div.hw,
>  		[CLKID_SD_EMMC_C_CLK0]	    = &gxbb_sd_emmc_c_clk0.hw,
> +		[CLKID_VPU_0_SEL]	    = &gxbb_vpu_0_sel.hw,
> +		[CLKID_VPU_0_DIV]	    = &gxbb_vpu_0_div.hw,
> +		[CLKID_VPU_0]		    = &gxbb_vpu_0.hw,
> +		[CLKID_VPU_1_SEL]	    = &gxbb_vpu_1_sel.hw,
> +		[CLKID_VPU_1_DIV]	    = &gxbb_vpu_1_div.hw,
> +		[CLKID_VPU_1]		    = &gxbb_vpu_1.hw,
> +		[CLKID_VPU]		    = &gxbb_vpu.hw,
> +		[CLKID_VAPB_0_SEL]	    = &gxbb_vapb_0_sel.hw,
> +		[CLKID_VAPB_0_DIV]	    = &gxbb_vapb_0_div.hw,
> +		[CLKID_VAPB_0]		    = &gxbb_vapb_0.hw,
> +		[CLKID_VAPB_1_SEL]	    = &gxbb_vapb_1_sel.hw,
> +		[CLKID_VAPB_1_DIV]	    = &gxbb_vapb_1_div.hw,
> +		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
> +		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
> +		[CLKID_VAPB]		    = &gxbb_vapb.hw,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1481,6 +1743,21 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data =
> {
>  		[CLKID_SD_EMMC_C_CLK0_SEL]  = &gxbb_sd_emmc_c_clk0_sel.hw,
>  		[CLKID_SD_EMMC_C_CLK0_DIV]  = &gxbb_sd_emmc_c_clk0_div.hw,
>  		[CLKID_SD_EMMC_C_CLK0]	    = &gxbb_sd_emmc_c_clk0.hw,
> +		[CLKID_VPU_0_SEL]	    = &gxbb_vpu_0_sel.hw,
> +		[CLKID_VPU_0_DIV]	    = &gxbb_vpu_0_div.hw,
> +		[CLKID_VPU_0]		    = &gxbb_vpu_0.hw,
> +		[CLKID_VPU_1_SEL]	    = &gxbb_vpu_1_sel.hw,
> +		[CLKID_VPU_1_DIV]	    = &gxbb_vpu_1_div.hw,
> +		[CLKID_VPU_1]		    = &gxbb_vpu_1.hw,
> +		[CLKID_VPU]		    = &gxbb_vpu.hw,
> +		[CLKID_VAPB_0_SEL]	    = &gxbb_vapb_0_sel.hw,
> +		[CLKID_VAPB_0_DIV]	    = &gxbb_vapb_0_div.hw,
> +		[CLKID_VAPB_0]		    = &gxbb_vapb_0.hw,
> +		[CLKID_VAPB_1_SEL]	    = &gxbb_vapb_1_sel.hw,
> +		[CLKID_VAPB_1_DIV]	    = &gxbb_vapb_1_div.hw,
> +		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
> +		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
> +		[CLKID_VAPB]		    = &gxbb_vapb.hw,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1600,6 +1877,11 @@ static struct clk_gate *const gxbb_clk_gates[] = {
>  	&gxbb_sd_emmc_a_clk0,
>  	&gxbb_sd_emmc_b_clk0,
>  	&gxbb_sd_emmc_c_clk0,
> +	&gxbb_vpu_0,
> +	&gxbb_vpu_1,
> +	&gxbb_vapb_0,
> +	&gxbb_vapb_1,
> +	&gxbb_vapb,
>  };
>  
>  static struct clk_mux *const gxbb_clk_muxes[] = {
> @@ -1615,6 +1897,12 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
>  	&gxbb_sd_emmc_a_clk0_sel,
>  	&gxbb_sd_emmc_b_clk0_sel,
>  	&gxbb_sd_emmc_c_clk0_sel,
> +	&gxbb_vpu_0_sel,
> +	&gxbb_vpu_1_sel,
> +	&gxbb_vpu,
> +	&gxbb_vapb_0_sel,
> +	&gxbb_vapb_1_sel,
> +	&gxbb_vapb_sel,
>  };
>  
>  static struct clk_divider *const gxbb_clk_dividers[] = {
> @@ -1627,6 +1915,10 @@ static struct clk_divider *const gxbb_clk_dividers[] =
> {
>  	&gxbb_sd_emmc_a_clk0_div,
>  	&gxbb_sd_emmc_b_clk0_div,
>  	&gxbb_sd_emmc_c_clk0_div,
> +	&gxbb_vpu_0_div,
> +	&gxbb_vpu_1_div,
> +	&gxbb_vapb_0_div,
> +	&gxbb_vapb_1_div,
>  };
>  
>  static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {