All of lore.kernel.org
 help / color / mirror / Atom feed
From: Neil Armstrong <narmstrong@baylibre.com>
To: Jerome Brunet <jbrunet@baylibre.com>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Carlo Caione <carlo@caione.org>,
	Kevin Hilman <khilman@baylibre.com>
Cc: linux-clk@vger.kernel.org, linux-amlogic@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v3 2/2] clk: meson: gxbb: Add sd_emmc clk0 clocks
Date: Tue, 1 Aug 2017 14:19:38 +0200	[thread overview]
Message-ID: <127b2dd8-72bf-1e44-9244-a539a0414c75@baylibre.com> (raw)
In-Reply-To: <20170731115603.29720-3-jbrunet@baylibre.com>

On 07/31/2017 01:56 PM, Jerome Brunet wrote:
> Input source 0 of the mmc controllers is not directly xtal, as currently
> described in DT. Each controller is fed by a composite clock (the usual
> mux, divider and gate). The muxes inputs are the xtal (default) and the
> fclk_div clocks. These parents, along with the divider, should be able to
> provide the necessary rates for mmc and nand operation.
> 
> The input muxes should also be able to take mpll2, mpll3 and gp0_pll but
> these are precious clocks, needed for other usage. It is better if the
> mmc does not use these them. For this reason, mpll2, mpll3 and gp0_pll is
> not listed among the possible parents.
> 
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>  drivers/clk/meson/gxbb.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 177 insertions(+)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index 8409d86cda24..dd78c5a1ce4b 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -974,6 +974,156 @@ static struct clk_mux gxbb_32k_clk_sel = {
>  	},
>  };
>  
> +static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
> +	"xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
> +
> +	/*
> +	 * Following these parent clocks, we should also have had mpll2, mpll3
> +	 * and gp0_pll but these clocks are too precious to be used here. All
> +	 * the necessary rates for MMC and NAND operation can be acheived using
> +	 * xtal or fclk_div clocks
> +	 */
> +};
> +
> +/* SDIO clock */
> +static struct clk_mux gxbb_sd_emmc_a_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_a_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_a_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_a_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
> +		.num_parents = 1,
> +
> +		/*
> +		 * FIXME:
> +		 * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal
> +		 * instead of this clock. CCF would gate this on boot, killing
> +		 * the mmc controller. Please remove this flag once DT properly
> +		 * point to this clock instead of xtal
> +		 *
> +		 * Same goes for emmc B and C clocks
> +		 */
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* SDcard clock */
> +static struct clk_mux gxbb_sd_emmc_b_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 25,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_b_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 16,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_b_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 23,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_b_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* EMMC/NAND clock */
> +static struct clk_mux gxbb_sd_emmc_c_clk0_sel = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_c_clk0_div = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_c_clk0 = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_c_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
> +		.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);
> @@ -1183,6 +1333,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1306,6 +1465,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1422,6 +1590,9 @@ static struct clk_gate *const gxbb_clk_gates[] = {
>  	&gxbb_cts_amclk,
>  	&gxbb_cts_mclk_i958,
>  	&gxbb_32k_clk,
> +	&gxbb_sd_emmc_a_clk0,
> +	&gxbb_sd_emmc_b_clk0,
> +	&gxbb_sd_emmc_c_clk0,
>  };
>  
>  static struct clk_mux *const gxbb_clk_muxes[] = {
> @@ -1434,6 +1605,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
>  	&gxbb_cts_mclk_i958_sel,
>  	&gxbb_cts_i958,
>  	&gxbb_32k_clk_sel,
> +	&gxbb_sd_emmc_a_clk0_sel,
> +	&gxbb_sd_emmc_b_clk0_sel,
> +	&gxbb_sd_emmc_c_clk0_sel,
>  };
>  
>  static struct clk_divider *const gxbb_clk_dividers[] = {
> @@ -1443,6 +1617,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
>  	&gxbb_mali_1_div,
>  	&gxbb_cts_mclk_i958_div,
>  	&gxbb_32k_clk_div,
> +	&gxbb_sd_emmc_a_clk0_div,
> +	&gxbb_sd_emmc_b_clk0_div,
> +	&gxbb_sd_emmc_c_clk0_div,
>  };
>  
>  static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
> 

Applied to clk-meson's next/drivers.

WARNING: multiple messages have this Message-ID (diff)
From: narmstrong@baylibre.com (Neil Armstrong)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 2/2] clk: meson: gxbb: Add sd_emmc clk0 clocks
Date: Tue, 1 Aug 2017 14:19:38 +0200	[thread overview]
Message-ID: <127b2dd8-72bf-1e44-9244-a539a0414c75@baylibre.com> (raw)
In-Reply-To: <20170731115603.29720-3-jbrunet@baylibre.com>

On 07/31/2017 01:56 PM, Jerome Brunet wrote:
> Input source 0 of the mmc controllers is not directly xtal, as currently
> described in DT. Each controller is fed by a composite clock (the usual
> mux, divider and gate). The muxes inputs are the xtal (default) and the
> fclk_div clocks. These parents, along with the divider, should be able to
> provide the necessary rates for mmc and nand operation.
> 
> The input muxes should also be able to take mpll2, mpll3 and gp0_pll but
> these are precious clocks, needed for other usage. It is better if the
> mmc does not use these them. For this reason, mpll2, mpll3 and gp0_pll is
> not listed among the possible parents.
> 
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>  drivers/clk/meson/gxbb.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 177 insertions(+)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index 8409d86cda24..dd78c5a1ce4b 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -974,6 +974,156 @@ static struct clk_mux gxbb_32k_clk_sel = {
>  	},
>  };
>  
> +static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
> +	"xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
> +
> +	/*
> +	 * Following these parent clocks, we should also have had mpll2, mpll3
> +	 * and gp0_pll but these clocks are too precious to be used here. All
> +	 * the necessary rates for MMC and NAND operation can be acheived using
> +	 * xtal or fclk_div clocks
> +	 */
> +};
> +
> +/* SDIO clock */
> +static struct clk_mux gxbb_sd_emmc_a_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_a_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_a_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_a_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
> +		.num_parents = 1,
> +
> +		/*
> +		 * FIXME:
> +		 * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal
> +		 * instead of this clock. CCF would gate this on boot, killing
> +		 * the mmc controller. Please remove this flag once DT properly
> +		 * point to this clock instead of xtal
> +		 *
> +		 * Same goes for emmc B and C clocks
> +		 */
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* SDcard clock */
> +static struct clk_mux gxbb_sd_emmc_b_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 25,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_b_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 16,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_b_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 23,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_b_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* EMMC/NAND clock */
> +static struct clk_mux gxbb_sd_emmc_c_clk0_sel = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_c_clk0_div = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_c_clk0 = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_c_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
> +		.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);
> @@ -1183,6 +1333,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1306,6 +1465,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1422,6 +1590,9 @@ static struct clk_gate *const gxbb_clk_gates[] = {
>  	&gxbb_cts_amclk,
>  	&gxbb_cts_mclk_i958,
>  	&gxbb_32k_clk,
> +	&gxbb_sd_emmc_a_clk0,
> +	&gxbb_sd_emmc_b_clk0,
> +	&gxbb_sd_emmc_c_clk0,
>  };
>  
>  static struct clk_mux *const gxbb_clk_muxes[] = {
> @@ -1434,6 +1605,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
>  	&gxbb_cts_mclk_i958_sel,
>  	&gxbb_cts_i958,
>  	&gxbb_32k_clk_sel,
> +	&gxbb_sd_emmc_a_clk0_sel,
> +	&gxbb_sd_emmc_b_clk0_sel,
> +	&gxbb_sd_emmc_c_clk0_sel,
>  };
>  
>  static struct clk_divider *const gxbb_clk_dividers[] = {
> @@ -1443,6 +1617,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
>  	&gxbb_mali_1_div,
>  	&gxbb_cts_mclk_i958_div,
>  	&gxbb_32k_clk_div,
> +	&gxbb_sd_emmc_a_clk0_div,
> +	&gxbb_sd_emmc_b_clk0_div,
> +	&gxbb_sd_emmc_c_clk0_div,
>  };
>  
>  static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
> 

Applied to clk-meson's next/drivers.

WARNING: multiple messages have this Message-ID (diff)
From: narmstrong@baylibre.com (Neil Armstrong)
To: linus-amlogic@lists.infradead.org
Subject: [PATCH v3 2/2] clk: meson: gxbb: Add sd_emmc clk0 clocks
Date: Tue, 1 Aug 2017 14:19:38 +0200	[thread overview]
Message-ID: <127b2dd8-72bf-1e44-9244-a539a0414c75@baylibre.com> (raw)
In-Reply-To: <20170731115603.29720-3-jbrunet@baylibre.com>

On 07/31/2017 01:56 PM, Jerome Brunet wrote:
> Input source 0 of the mmc controllers is not directly xtal, as currently
> described in DT. Each controller is fed by a composite clock (the usual
> mux, divider and gate). The muxes inputs are the xtal (default) and the
> fclk_div clocks. These parents, along with the divider, should be able to
> provide the necessary rates for mmc and nand operation.
> 
> The input muxes should also be able to take mpll2, mpll3 and gp0_pll but
> these are precious clocks, needed for other usage. It is better if the
> mmc does not use these them. For this reason, mpll2, mpll3 and gp0_pll is
> not listed among the possible parents.
> 
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>  drivers/clk/meson/gxbb.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 177 insertions(+)
> 
> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
> index 8409d86cda24..dd78c5a1ce4b 100644
> --- a/drivers/clk/meson/gxbb.c
> +++ b/drivers/clk/meson/gxbb.c
> @@ -974,6 +974,156 @@ static struct clk_mux gxbb_32k_clk_sel = {
>  	},
>  };
>  
> +static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
> +	"xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
> +
> +	/*
> +	 * Following these parent clocks, we should also have had mpll2, mpll3
> +	 * and gp0_pll but these clocks are too precious to be used here. All
> +	 * the necessary rates for MMC and NAND operation can be acheived using
> +	 * xtal or fclk_div clocks
> +	 */
> +};
> +
> +/* SDIO clock */
> +static struct clk_mux gxbb_sd_emmc_a_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_a_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_a_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_a_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
> +		.num_parents = 1,
> +
> +		/*
> +		 * FIXME:
> +		 * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal
> +		 * instead of this clock. CCF would gate this on boot, killing
> +		 * the mmc controller. Please remove this flag once DT properly
> +		 * point to this clock instead of xtal
> +		 *
> +		 * Same goes for emmc B and C clocks
> +		 */
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* SDcard clock */
> +static struct clk_mux gxbb_sd_emmc_b_clk0_sel = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 25,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_b_clk0_div = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.shift = 16,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_b_clk0 = {
> +	.reg = (void *)HHI_SD_EMMC_CLK_CNTL,
> +	.bit_idx = 23,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_b_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* EMMC/NAND clock */
> +static struct clk_mux gxbb_sd_emmc_c_clk0_sel = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.mask = 0x7,
> +	.shift = 9,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_sel",
> +		.ops = &clk_mux_ops,
> +		.parent_names = gxbb_sd_emmc_clk0_parent_names,
> +		.num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_divider gxbb_sd_emmc_c_clk0_div = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.shift = 0,
> +	.width = 7,
> +	.lock = &clk_lock,
> +	.flags = CLK_DIVIDER_ROUND_CLOSEST,
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c_clk0_div",
> +		.ops = &clk_divider_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_gate gxbb_sd_emmc_c_clk0 = {
> +	.reg = (void *)HHI_NAND_CLK_CNTL,
> +	.bit_idx = 7,
> +	.lock = &clk_lock,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_c_clk0",
> +		.ops = &clk_gate_ops,
> +		.parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
> +		.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);
> @@ -1183,6 +1333,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1306,6 +1465,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
>  		[CLKID_32K_CLK]		    = &gxbb_32k_clk.hw,
>  		[CLKID_32K_CLK_SEL]	    = &gxbb_32k_clk_sel.hw,
>  		[CLKID_32K_CLK_DIV]	    = &gxbb_32k_clk_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0_SEL]  = &gxbb_sd_emmc_a_clk0_sel.hw,
> +		[CLKID_SD_EMMC_A_CLK0_DIV]  = &gxbb_sd_emmc_a_clk0_div.hw,
> +		[CLKID_SD_EMMC_A_CLK0]	    = &gxbb_sd_emmc_a_clk0.hw,
> +		[CLKID_SD_EMMC_B_CLK0_SEL]  = &gxbb_sd_emmc_b_clk0_sel.hw,
> +		[CLKID_SD_EMMC_B_CLK0_DIV]  = &gxbb_sd_emmc_b_clk0_div.hw,
> +		[CLKID_SD_EMMC_B_CLK0]	    = &gxbb_sd_emmc_b_clk0.hw,
> +		[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,
>  		[NR_CLKS]		    = NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1422,6 +1590,9 @@ static struct clk_gate *const gxbb_clk_gates[] = {
>  	&gxbb_cts_amclk,
>  	&gxbb_cts_mclk_i958,
>  	&gxbb_32k_clk,
> +	&gxbb_sd_emmc_a_clk0,
> +	&gxbb_sd_emmc_b_clk0,
> +	&gxbb_sd_emmc_c_clk0,
>  };
>  
>  static struct clk_mux *const gxbb_clk_muxes[] = {
> @@ -1434,6 +1605,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
>  	&gxbb_cts_mclk_i958_sel,
>  	&gxbb_cts_i958,
>  	&gxbb_32k_clk_sel,
> +	&gxbb_sd_emmc_a_clk0_sel,
> +	&gxbb_sd_emmc_b_clk0_sel,
> +	&gxbb_sd_emmc_c_clk0_sel,
>  };
>  
>  static struct clk_divider *const gxbb_clk_dividers[] = {
> @@ -1443,6 +1617,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
>  	&gxbb_mali_1_div,
>  	&gxbb_cts_mclk_i958_div,
>  	&gxbb_32k_clk_div,
> +	&gxbb_sd_emmc_a_clk0_div,
> +	&gxbb_sd_emmc_b_clk0_div,
> +	&gxbb_sd_emmc_c_clk0_div,
>  };
>  
>  static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
> 

Applied to clk-meson's next/drivers.

  reply	other threads:[~2017-08-01 12:19 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-31 11:56 [PATCH v3 0/2] clk: meson: add mmc input 0 clocks Jerome Brunet
2017-07-31 11:56 ` Jerome Brunet
2017-07-31 11:56 ` Jerome Brunet
2017-07-31 11:56 ` Jerome Brunet
2017-07-31 11:56 ` [PATCH v3 1/2] clk: meson: gxbb: Add sd_emmc clk0 clkids Jerome Brunet
2017-07-31 11:56   ` Jerome Brunet
2017-07-31 11:56   ` Jerome Brunet
2017-07-31 11:56   ` Jerome Brunet
2017-08-01 12:09   ` Neil Armstrong
2017-08-01 12:09     ` Neil Armstrong
2017-08-01 12:09     ` Neil Armstrong
2017-07-31 11:56 ` [PATCH v3 2/2] clk: meson: gxbb: Add sd_emmc clk0 clocks Jerome Brunet
2017-07-31 11:56   ` Jerome Brunet
2017-07-31 11:56   ` Jerome Brunet
2017-08-01 12:19   ` Neil Armstrong [this message]
2017-08-01 12:19     ` Neil Armstrong
2017-08-01 12:19     ` Neil Armstrong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=127b2dd8-72bf-1e44-9244-a539a0414c75@baylibre.com \
    --to=narmstrong@baylibre.com \
    --cc=carlo@caione.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jbrunet@baylibre.com \
    --cc=khilman@baylibre.com \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=sboyd@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.