* [PATCH V3 1/3] ARM: imx: add gpt_3m clk for i.mx6qdl
2014-09-11 3:29 ` Anson Huang
@ 2014-09-11 3:29 ` Anson Huang
-1 siblings, 0 replies; 10+ messages in thread
From: Anson Huang @ 2014-09-11 3:29 UTC (permalink / raw)
To: shawn.guo-QSEj5FYQhm4dnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
festevam-Re5JQEeQqe8AvxtiuMwx3w
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Add gpt_3m clock for i.mx6qdl, as gpt can source clock
from OSC, some i.MX6 series SOCs has fixed divider of
8 for gpt clock, so here add a fix clk of gpt_3m.
i.MX6Q TO1.0 has no gpt_3m option, so force it to be
from ipg_per.
Signed-off-by: Anson Huang <b20788-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
change log from v2 -> v3:
re-initialize gpt_3m to ipg_per on i.MX6Q TO1.0
arch/arm/mach-imx/clk-imx6q.c | 4 ++++
include/dt-bindings/clock/imx6qdl-clock.h | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 2edcebf..32ac04d 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -194,6 +194,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+ clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
if (cpu_is_imx6dl()) {
clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
@@ -405,6 +406,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+ if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
+ clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER];
+
imx_check_clocks(clk, ARRAY_SIZE(clk));
clk_data.clks = clk;
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 323e865..9bc2e07 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -220,6 +220,7 @@
#define IMX6QDL_CLK_LVDS2_GATE 207
#define IMX6QDL_CLK_ESAI_IPG 208
#define IMX6QDL_CLK_ESAI_MEM 209
-#define IMX6QDL_CLK_END 210
+#define IMX6QDL_CLK_GPT_3M 210
+#define IMX6QDL_CLK_END 211
#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V3 1/3] ARM: imx: add gpt_3m clk for i.mx6qdl
@ 2014-09-11 3:29 ` Anson Huang
0 siblings, 0 replies; 10+ messages in thread
From: Anson Huang @ 2014-09-11 3:29 UTC (permalink / raw)
To: linux-arm-kernel
Add gpt_3m clock for i.mx6qdl, as gpt can source clock
from OSC, some i.MX6 series SOCs has fixed divider of
8 for gpt clock, so here add a fix clk of gpt_3m.
i.MX6Q TO1.0 has no gpt_3m option, so force it to be
from ipg_per.
Signed-off-by: Anson Huang <b20788@freescale.com>
---
change log from v2 -> v3:
re-initialize gpt_3m to ipg_per on i.MX6Q TO1.0
arch/arm/mach-imx/clk-imx6q.c | 4 ++++
include/dt-bindings/clock/imx6qdl-clock.h | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 2edcebf..32ac04d 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -194,6 +194,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+ clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
if (cpu_is_imx6dl()) {
clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
@@ -405,6 +406,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+ if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
+ clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER];
+
imx_check_clocks(clk, ARRAY_SIZE(clk));
clk_data.clks = clk;
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 323e865..9bc2e07 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -220,6 +220,7 @@
#define IMX6QDL_CLK_LVDS2_GATE 207
#define IMX6QDL_CLK_ESAI_IPG 208
#define IMX6QDL_CLK_ESAI_MEM 209
-#define IMX6QDL_CLK_END 210
+#define IMX6QDL_CLK_GPT_3M 210
+#define IMX6QDL_CLK_END 211
#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V3 3/3] ARM: imx: source gpt per clk from OSC for system timer
2014-09-11 3:29 ` Anson Huang
@ 2014-09-11 3:29 ` Anson Huang
-1 siblings, 0 replies; 10+ messages in thread
From: Anson Huang @ 2014-09-11 3:29 UTC (permalink / raw)
To: shawn.guo-QSEj5FYQhm4dnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
festevam-Re5JQEeQqe8AvxtiuMwx3w
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On i.MX6Q TO > 1.0, i.MX6DL and i.MX6SX, gpt per clock
can be from OSC instead of ipg_per, as ipg_per's rate
may be scaled when system enter low bus mode, to keep
system timer NOT drift, better to make gpt per clock
at fixed rate, here add support for gpt per clock to
be from OSC which is at fixed rate always.
There are some difference on this implementation of
gpt per clock source, see below for details:
i.MX6Q TO > 1.0: GPT_CR_CLKSRC, b'101 selects fix clock
of OSC / 8 for gpt per clk;
i.MX6DL and i.MX6SX: GPT_CR_CLKSRC, b'101 selects OSC
for gpt per clk, and we must enable GPT_CR_24MEM to
enable OSC clk source for gpt per, GPT_PR_PRESCALER24M
is for pre-scaling of this OSC clk, here set it to 8
to make gpt per clk is 3MHz;
i.MX6SL: ipg_per can be from OSC directly, so no need to
implement this new clk source for gpt per.
Signed-off-by: Anson Huang <b20788-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
change log from v2->v3:
1.remove unnecessary definition V2_TCTL_CLK_OSC and
variable tprer_val;
2.optimize the logic of different gpt clk select.
arch/arm/mach-imx/time.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index bf92e5a..15d18e1 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -60,17 +60,22 @@
#define MX2_TSTAT_CAPT (1 << 1)
#define MX2_TSTAT_COMP (1 << 0)
-/* MX31, MX35, MX25, MX5 */
+/* MX31, MX35, MX25, MX5, MX6 */
#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
#define V2_TCTL_CLK_IPG (1 << 6)
#define V2_TCTL_CLK_PER (2 << 6)
+#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
#define V2_TCTL_FRR (1 << 9)
+#define V2_TCTL_24MEN (1 << 10)
+#define V2_TPRER_PRE24M 12
#define V2_IR 0x0c
#define V2_TSTAT 0x08
#define V2_TSTAT_OF1 (1 << 0)
#define V2_TCN 0x24
#define V2_TCMP 0x10
+#define V2_TIMER_RATE_OSC_DIV8 3000000
+
#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
#define timer_is_v2() (!timer_is_v1())
@@ -312,10 +317,22 @@ static void __init _mxc_timer_init(int irq,
__raw_writel(0, timer_base + MXC_TCTL);
__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
- if (timer_is_v2())
- tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
- else
+ if (timer_is_v2()) {
+ tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+ tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+ if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
+ /* 24 / 8 = 3 MHz */
+ __raw_writel(7 << V2_TPRER_PRE24M,
+ timer_base + MXC_TPRER);
+ tctl_val |= V2_TCTL_24MEN;
+ }
+ } else {
+ tctl_val |= V2_TCTL_CLK_PER;
+ }
+ } else {
tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+ }
__raw_writel(tctl_val, timer_base + MXC_TCTL);
@@ -349,9 +366,13 @@ static void __init mxc_timer_init_dt(struct device_node *np)
WARN_ON(!timer_base);
irq = irq_of_parse_and_map(np, 0);
- clk_per = of_clk_get_by_name(np, "per");
clk_ipg = of_clk_get_by_name(np, "ipg");
+ /* Try osc_per first, and fall back to per otherwise */
+ clk_per = of_clk_get_by_name(np, "osc_per");
+ if (IS_ERR(clk_per))
+ clk_per = of_clk_get_by_name(np, "per");
+
_mxc_timer_init(irq, clk_per, clk_ipg);
}
CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V3 3/3] ARM: imx: source gpt per clk from OSC for system timer
@ 2014-09-11 3:29 ` Anson Huang
0 siblings, 0 replies; 10+ messages in thread
From: Anson Huang @ 2014-09-11 3:29 UTC (permalink / raw)
To: linux-arm-kernel
On i.MX6Q TO > 1.0, i.MX6DL and i.MX6SX, gpt per clock
can be from OSC instead of ipg_per, as ipg_per's rate
may be scaled when system enter low bus mode, to keep
system timer NOT drift, better to make gpt per clock
at fixed rate, here add support for gpt per clock to
be from OSC which is at fixed rate always.
There are some difference on this implementation of
gpt per clock source, see below for details:
i.MX6Q TO > 1.0: GPT_CR_CLKSRC, b'101 selects fix clock
of OSC / 8 for gpt per clk;
i.MX6DL and i.MX6SX: GPT_CR_CLKSRC, b'101 selects OSC
for gpt per clk, and we must enable GPT_CR_24MEM to
enable OSC clk source for gpt per, GPT_PR_PRESCALER24M
is for pre-scaling of this OSC clk, here set it to 8
to make gpt per clk is 3MHz;
i.MX6SL: ipg_per can be from OSC directly, so no need to
implement this new clk source for gpt per.
Signed-off-by: Anson Huang <b20788@freescale.com>
---
change log from v2->v3:
1.remove unnecessary definition V2_TCTL_CLK_OSC and
variable tprer_val;
2.optimize the logic of different gpt clk select.
arch/arm/mach-imx/time.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index bf92e5a..15d18e1 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -60,17 +60,22 @@
#define MX2_TSTAT_CAPT (1 << 1)
#define MX2_TSTAT_COMP (1 << 0)
-/* MX31, MX35, MX25, MX5 */
+/* MX31, MX35, MX25, MX5, MX6 */
#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
#define V2_TCTL_CLK_IPG (1 << 6)
#define V2_TCTL_CLK_PER (2 << 6)
+#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
#define V2_TCTL_FRR (1 << 9)
+#define V2_TCTL_24MEN (1 << 10)
+#define V2_TPRER_PRE24M 12
#define V2_IR 0x0c
#define V2_TSTAT 0x08
#define V2_TSTAT_OF1 (1 << 0)
#define V2_TCN 0x24
#define V2_TCMP 0x10
+#define V2_TIMER_RATE_OSC_DIV8 3000000
+
#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
#define timer_is_v2() (!timer_is_v1())
@@ -312,10 +317,22 @@ static void __init _mxc_timer_init(int irq,
__raw_writel(0, timer_base + MXC_TCTL);
__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
- if (timer_is_v2())
- tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
- else
+ if (timer_is_v2()) {
+ tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+ tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+ if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
+ /* 24 / 8 = 3 MHz */
+ __raw_writel(7 << V2_TPRER_PRE24M,
+ timer_base + MXC_TPRER);
+ tctl_val |= V2_TCTL_24MEN;
+ }
+ } else {
+ tctl_val |= V2_TCTL_CLK_PER;
+ }
+ } else {
tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+ }
__raw_writel(tctl_val, timer_base + MXC_TCTL);
@@ -349,9 +366,13 @@ static void __init mxc_timer_init_dt(struct device_node *np)
WARN_ON(!timer_base);
irq = irq_of_parse_and_map(np, 0);
- clk_per = of_clk_get_by_name(np, "per");
clk_ipg = of_clk_get_by_name(np, "ipg");
+ /* Try osc_per first, and fall back to per otherwise */
+ clk_per = of_clk_get_by_name(np, "osc_per");
+ if (IS_ERR(clk_per))
+ clk_per = of_clk_get_by_name(np, "per");
+
_mxc_timer_init(irq, clk_per, clk_ipg);
}
CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH V3 0/3] move gpt per clk parent from ipg_per to OSC
2014-09-11 3:29 ` Anson Huang
@ 2014-09-12 6:37 ` Shawn Guo
-1 siblings, 0 replies; 10+ messages in thread
From: Shawn Guo @ 2014-09-12 6:37 UTC (permalink / raw)
To: Anson Huang
Cc: kernel-bIcnvbaLZ9MEGnE8C9+IrQ, festevam-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Thu, Sep 11, 2014 at 11:29:39AM +0800, Anson Huang wrote:
> Anson Huang (3):
> ARM: imx: add gpt_3m clk for i.mx6qdl
> ARM: dts: imx6: make gpt per clock can be from OSC
> ARM: imx: source gpt per clk from OSC for system timer
Applied all, thanks.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread