Skip to contentSkip to conversation

clk-imx35: Add clko clock support

PATCH New Alexander Stein 3 participants 7 messages Jun 17, 2014 – Jun 25, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

This adds a new clk which is programmable using different sources and dividers.

---
I know some (most) of the new lines are larger than 80 characters, but I kept the same layout as the other lines.
Also lots of the clock sources are not used in linux, so I have given them a descriptive name though.

 arch/arm/mach-imx/clk-imx35.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
arch/arm/mach-imx/clk-imx35.c +20 -1
index 71c86a2..acf821c 100644
@@ -49,6 +49,13 @@ static struct clk_onecell_data clk_data;
 
 static const char *std_sel[] = {"ppll", "arm"};
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+static const char *clko_select[] = {"ckil", "osc", "osc_audio", "dummy",
+				 "mpll_075", "mpll", "ppll", "arm",
+				 "ahb", "ipg", "ipg_per", "usbdiv",
+				 "esdhc1_div", "ssi1_div_post", "mlb_gate",
+				 "mshc_gate", "mpll_lock", "csi_div",
+				 "spdif_div_post", "uart1_gate", "asrc",
+				 "dptc", "arm_ungated", "nfc_div", "hsp"};
 
 enum mx35_clks {
 	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
@@ -64,7 +71,7 @@ enum mx35_clks {
 	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
 	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
 	wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
-	gpu2d_gate, clk_max
+	gpu2d_gate, clko_sel, clko_div1, clko_div, clko_gate, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -146,6 +153,10 @@ int __init mx35_clocks_init(void)
 	clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
 	clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
 
+	clk[clko_sel] = imx_clk_mux("clko_sel", base + MX35_CCM_COSR, 0, 5, clko_select, ARRAY_SIZE(clko_select));
+	clk[clko_div1] = imx_clk_divider("clko_div1", "clko_sel", base + MX35_CCM_COSR, 6, 1);
+	clk[clko_div] = imx_clk_divider("clko_div", "clko_div1", base + MX35_CCM_COSR, 10, 6);
+
 	clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0,  0);
 	clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0,  2);
 	clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0,  4);
@@ -200,6 +211,8 @@ int __init mx35_clocks_init(void)
 	clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3,  2);
 	clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3,  4);
 
+	clk[clko_gate] = imx_clk_gate("clko_gate", "clko_div", base + MX35_CCM_COSR,  5);
+
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
 			pr_err("i.MX35 clk %d: register failed with %ld\n",
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");
 
 	clk_prepare_enable(clk[spba_gate]);
 	clk_prepare_enable(clk[gpio1_gate]);
@@ -286,6 +300,11 @@ int __init mx35_clocks_init(void)
 	mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
 #endif
 
+	/*
+	 * Let's initially set up CLKO parent as arm.
+	 */
+	clk_set_parent(clk[clko_sel], clk[arm]);
+
 	return 0;
 }
 
Signature · 1 line
1.8.5.5
#1 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

Quoted 18 lines · Alexander Stein

This adds a new clk which is programmable using different sources and dividers.

---
I know some (most) of the new lines are larger than 80 characters, but I kept the same layout as the other lines.
Also lots of the clock sources are not used in linux, so I have given them a descriptive name though.

 arch/arm/mach-imx/clk-imx35.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
arch/arm/mach-imx/clk-imx35.c +0 -0
index 71c86a2..acf821c 100644

arch/arm/mach-imx/clk-imx35.c static struct clk_onecell_data clk_data; · line 58

Quoted 10 lines
arch/arm/mach-imx/clk-imx35.c +7 -0
@@ -49,6 +49,13 @@ static struct clk_onecell_data clk_data;
 
 static const char *std_sel[] = {"ppll", "arm"};
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+static const char *clko_select[] = {"ckil", "osc", "osc_audio", "dummy",
+				 "mpll_075", "mpll", "ppll", "arm",
+				 "ahb", "ipg", "ipg_per", "usbdiv",
+				 "esdhc1_div", "ssi1_div_post", "mlb_gate",
+				 "mshc_gate", "mpll_lock", "csi_div",
+				 "spdif_div_post", "uart1_gate", "asrc",
+				 "dptc", "arm_ungated", "nfc_div", "hsp"};

Any new string you add here should have a corresponding clk in clock framework.

Quoted 33 lines
arch/arm/mach-imx/clk-imx35.c +7 -1
 enum mx35_clks {
 	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
@@ -64,7 +71,7 @@ enum mx35_clks {
 	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
 	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
 	wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
-	gpu2d_gate, clk_max
+	gpu2d_gate, clko_sel, clko_div1, clko_div, clko_gate, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -146,6 +153,10 @@ int __init mx35_clocks_init(void)
 	clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
 	clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
 
+	clk[clko_sel] = imx_clk_mux("clko_sel", base + MX35_CCM_COSR, 0, 5, clko_select, ARRAY_SIZE(clko_select));
+	clk[clko_div1] = imx_clk_divider("clko_div1", "clko_sel", base + MX35_CCM_COSR, 6, 1);
+	clk[clko_div] = imx_clk_divider("clko_div", "clko_div1", base + MX35_CCM_COSR, 10, 6);
+
 	clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0,  0);
 	clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0,  2);
 	clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0,  4);
@@ -200,6 +211,8 @@ int __init mx35_clocks_init(void)
 	clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3,  2);
 	clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3,  4);
 
+	clk[clko_gate] = imx_clk_gate("clko_gate", "clko_div", base + MX35_CCM_COSR,  5);
+
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
 			pr_err("i.MX35 clk %d: register failed with %ld\n",

arch/arm/mach-imx/clk-imx35.c int __init mx35_clocks_init(void) · line 276

Quoted 4 lines
arch/arm/mach-imx/clk-imx35.c +1 -0
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");

Will this lookup be used somewhere?

Shawn

Quoted 18 lines
arch/arm/mach-imx/clk-imx35.c +5 -0
 	clk_prepare_enable(clk[spba_gate]);
 	clk_prepare_enable(clk[gpio1_gate]);
@@ -286,6 +300,11 @@ int __init mx35_clocks_init(void)
 	mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
 #endif
 
+	/*
+	 * Let's initially set up CLKO parent as arm.
+	 */
+	clk_set_parent(clk[clko_sel], clk[arm]);
+
 	return 0;
 }
 
Signature · 1 line
1.8.5.5
#2 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

Quoted 20 lines · Shawn Guo
Quoted 19 lines · Alexander Stein

This adds a new clk which is programmable using different sources and dividers.

---
I know some (most) of the new lines are larger than 80 characters, but I kept the same layout as the other lines.
Also lots of the clock sources are not used in linux, so I have given them a descriptive name though.

 arch/arm/mach-imx/clk-imx35.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
arch/arm/mach-imx/clk-imx35.c +0 -0
index 71c86a2..acf821c 100644
@@ -49,6 +49,13 @@ static struct clk_onecell_data clk_data;
 
Quoted 12 lines

arch/arm/mach-imx/clk-imx35.c static struct clk_onecell_data clk_data; · line 58

Quoted 9 lines
arch/arm/mach-imx/clk-imx35.c +7 -0
 static const char *std_sel[] = {"ppll", "arm"};
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+static const char *clko_select[] = {"ckil", "osc", "osc_audio", "dummy",
+				 "mpll_075", "mpll", "ppll", "arm",
+				 "ahb", "ipg", "ipg_per", "usbdiv",
+				 "esdhc1_div", "ssi1_div_post", "mlb_gate",
+				 "mshc_gate", "mpll_lock", "csi_div",
+				 "spdif_div_post", "uart1_gate", "asrc",
+				 "dptc", "arm_ungated", "nfc_div", "hsp"};

Any new string you add here should have a corresponding clk in clock framework.

Ew, ok... As lots of those clocks are not (yet?) supported in the clock framework this list will contains many "dummy" entries, but well I get your point.

Quoted 26 lines
Quoted 26 lines
arch/arm/mach-imx/clk-imx35.c +5 -1
 enum mx35_clks {
 	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
@@ -64,7 +71,7 @@ enum mx35_clks {
 	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
 	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
 	wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
-	gpu2d_gate, clk_max
+	gpu2d_gate, clko_sel, clko_div1, clko_div, clko_gate, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -146,6 +153,10 @@ int __init mx35_clocks_init(void)
 	clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel));
 	clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6);
 
+	clk[clko_sel] = imx_clk_mux("clko_sel", base + MX35_CCM_COSR, 0, 5, clko_select, ARRAY_SIZE(clko_select));
+	clk[clko_div1] = imx_clk_divider("clko_div1", "clko_sel", base + MX35_CCM_COSR, 6, 1);
+	clk[clko_div] = imx_clk_divider("clko_div", "clko_div1", base + MX35_CCM_COSR, 10, 6);
+
 	clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0,  0);
 	clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0,  2);
 	clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0,  4);
@@ -200,6 +211,8 @@ int __init mx35_clocks_init(void)
 	clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3,  2);
 	clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3,  4);
 
Quoted 12 lines

arch/arm/mach-imx/clk-imx35.c int __init mx35_clocks_init(void) · line 276

Quoted 10 lines
arch/arm/mach-imx/clk-imx35.c +3 -0
+	clk[clko_gate] = imx_clk_gate("clko_gate", "clko_div", base + MX35_CCM_COSR,  5);
+
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
 			pr_err("i.MX35 clk %d: register failed with %ld\n",
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");

Will this lookup be used somewhere?

Well, as this is a pretty customizable output clock signal, I think this will only be used in custom board implementation. Or is there any generic driver to configure an arbitrary programmable clock?

Alexander

#3 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

Quoted 15 lines · Alexander Stein
Quoted 14 lines

arch/arm/mach-imx/clk-imx35.c static struct clk_onecell_data clk_data; · line 58

Quoted 11 lines
arch/arm/mach-imx/clk-imx35.c +7 -0
@@ -49,6 +49,13 @@ static struct clk_onecell_data clk_data;
 
 static const char *std_sel[] = {"ppll", "arm"};
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+static const char *clko_select[] = {"ckil", "osc", "osc_audio", "dummy",
+				 "mpll_075", "mpll", "ppll", "arm",
+				 "ahb", "ipg", "ipg_per", "usbdiv",
+				 "esdhc1_div", "ssi1_div_post", "mlb_gate",
+				 "mshc_gate", "mpll_lock", "csi_div",
+				 "spdif_div_post", "uart1_gate", "asrc",
+				 "dptc", "arm_ungated", "nfc_div", "hsp"};

Any new string you add here should have a corresponding clk in clock framework.

Quoted 2 lines

Ew, ok... As lots of those clocks are not (yet?) supported in the clock framework this list will contains many "dummy" entries, but well I get your point.

Right. Either you do not create the string or you create the clock behind the string together.

...

Quoted 10 lines
Quoted 7 lines

arch/arm/mach-imx/clk-imx35.c int __init mx35_clocks_init(void) · line 276

Quoted 5 lines
arch/arm/mach-imx/clk-imx35.c +1 -0
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");

Will this lookup be used somewhere?

Well, as this is a pretty customizable output clock signal, I think this will only be used in custom board implementation. Or is there any generic driver to configure an arbitrary programmable clock?

I prefer to add this lookup only when there is an in-tree user for it.

Shawn

#4 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

Hello,

Quoted 16 lines · Shawn Guo
Quoted 15 lines · Alexander Stein
Quoted 14 lines

arch/arm/mach-imx/clk-imx35.c static struct clk_onecell_data clk_data; · line 58

Quoted 11 lines
arch/arm/mach-imx/clk-imx35.c +7 -0
@@ -49,6 +49,13 @@ static struct clk_onecell_data clk_data;
 
 static const char *std_sel[] = {"ppll", "arm"};
 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+static const char *clko_select[] = {"ckil", "osc", "osc_audio", "dummy",
+				 "mpll_075", "mpll", "ppll", "arm",
+				 "ahb", "ipg", "ipg_per", "usbdiv",
+				 "esdhc1_div", "ssi1_div_post", "mlb_gate",
+				 "mshc_gate", "mpll_lock", "csi_div",
+				 "spdif_div_post", "uart1_gate", "asrc",
+				 "dptc", "arm_ungated", "nfc_div", "hsp"};

Any new string you add here should have a corresponding clk in clock framework.

Quoted 5 lines
Quoted 2 lines

Ew, ok... As lots of those clocks are not (yet?) supported in the clock framework this list will contains many "dummy" entries, but well I get your point.

Right. Either you do not create the string or you create the clock behind the string together.

Ok, I'll recheck.

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

arch/arm/mach-imx/clk-imx35.c int __init mx35_clocks_init(void) · line 276

Quoted 5 lines
arch/arm/mach-imx/clk-imx35.c +1 -0
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");

Will this lookup be used somewhere?

Quoted 4 lines
Quoted 2 lines

Well, as this is a pretty customizable output clock signal, I think this will only be used in custom board implementation. Or is there any generic driver to configure an arbitrary programmable clock?

I prefer to add this lookup only when there is an in-tree user for it.

Well, the cko (cko1 and cko2) clocks on i.MX6 are also added. Though I can't find any user of that. So why addind it despite that?

Best regards,
Alexander

#5 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

Quoted 2 lines · Alexander Stein

Well, the cko (cko1 and cko2) clocks on i.MX6 are also added. Though I can't find any user of that. So why addind it despite that?

They are definitely used, I've recently added one user to my DT config, and there are other users in the DT configs already present in the kernel tree. Look for <&clks 201> for iMX6.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
#6 lore raw

PATCH 1/1 clk-imx35: Add clko clock support

In reply to Alexander Stein
Quoted 8 lines · Alexander Stein
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

arch/arm/mach-imx/clk-imx35.c int __init mx35_clocks_init(void) · line 276

Quoted 5 lines
arch/arm/mach-imx/clk-imx35.c +1 -0
@@ -260,6 +273,7 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
+	clk_register_clkdev(clk[clko_gate], NULL, "clko.0");

Will this lookup be used somewhere?

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Well, as this is a pretty customizable output clock signal, I think this will only be used in custom board implementation. Or is there any generic driver to configure an arbitrary programmable clock?

I prefer to add this lookup only when there is an in-tree user for it.

Well, the cko (cko1 and cko2) clocks on i.MX6 are also added. Though I can't find any user of that. So why addind it despite that?

To be clear, I'm not talking about the cko clock itself but the lookup to cko, i.e. clk_register_clkdev() of "clko.0".

Shawn