Skip to contentSkip to conversation

mx35 timer: Switch to 32-kHz source

PATCH New Benoît Thébaudeau 2 participants 9 messages Aug 14, 2012 – Aug 27, 2012 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mx35 timer: Switch to 32-kHz source

Switch the mx35 timer driver to the 32-kHz clock source to avoid calling mxc_get_clock() again and again, and to be consistent with the timer drivers of other i.MX SoCs.

---
 .../arch/arm/cpu/arm1136/mx35/timer.c              |   43 ++++++++++++--------
 .../include/configs/flea3.h                        |    1 +
 .../include/configs/mx35pdk.h                      |    1 +
 3 files changed, 27 insertions(+), 18 deletions(-)
arch/arm/cpu/arm1136/mx35/timer.c +25 -18
index 04937a1..25057af 100644
@@ -27,7 +27,7 @@
 #include <asm/io.h>
 #include <div64.h>
 #include <asm/arch/imx-regs.h>
-#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -37,43 +37,50 @@ DECLARE_GLOBAL_DATA_PTR;
 /* General purpose timers bitfields */
 #define GPTCR_SWR       (1<<15)	/* Software reset */
 #define GPTCR_FRR       (1<<9)	/* Freerun / restart */
-#define GPTCR_CLKSOURCE_32   (0x100<<6)	/* Clock source */
-#define GPTCR_CLKSOURCE_IPG (0x001<<6)	/* Clock source */
+#define GPTCR_CLKSOURCE_32   (4<<6)	/* Clock source */
 #define GPTCR_TEN       (1)	/* Timer enable */
 
-#define	TIMER_FREQ_HZ	mxc_get_clock(MXC_IPG_CLK)
-
+/*
+ * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period
+ */
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, TIMER_FREQ_HZ);
+	do_div(tick, CONFIG_MX35_CLK32);
 
 	return tick;
 }
 
-static inline unsigned long long us_to_tick(unsigned long long usec)
+static inline unsigned long long us_to_tick(unsigned long long us)
 {
-	usec *= TIMER_FREQ_HZ;
-	do_div(usec, 1000000);
+	us = us * CONFIG_MX35_CLK32 + 999999;
+	do_div(us, 1000000);
 
-	return usec;
+	return us;
 }
 
+/* nothing really to do with interrupts, just starts up a counter. */
+/* The 32KHz 32-bit timer overruns in 134217 seconds */
 int timer_init(void)
 {
 	int i;
 	struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
+	struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR;
 
 	/* setup GP Timer 1 */
 	writel(GPTCR_SWR, &gpt->ctrl);
-	for (i = 0; i < 100; i++)
-		writel(0, &gpt->ctrl);	/* We have no udelay by now */
 
-	writel(0, &gpt->pre);
-	/* Freerun Mode, PERCLK1 input */
-	writel(readl(&gpt->ctrl) |
-		GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
-		&gpt->ctrl);
+	writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1);
+
+	for (i = 0; i < 100; i++)
+		writel(0, &gpt->ctrl); /* We have no udelay by now */
+	writel(0, &gpt->pre); /* prescaler = 1 */
+	/* Freerun Mode, 32KHz input */
+	writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+			&gpt->ctrl);
+	writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl);
 
 	return 0;
 }
@@ -132,5 +139,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-	return TIMER_FREQ_HZ;
+	return CONFIG_MX35_CLK32;
 }
include/configs/flea3.h +1 -0
index 46939d4..26f1b3e 100644
@@ -32,6 +32,7 @@
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
 #define CONFIG_MX35_HCLK_FREQ	24000000
+#define CONFIG_MX35_CLK32	32768
 
 #define CONFIG_SYS_DCACHE_OFF
 #define CONFIG_SYS_CACHELINE_SIZE	32
include/configs/mx35pdk.h +1 -0
index 6eb5da5..d66f16b 100644
@@ -32,6 +32,7 @@
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
 #define CONFIG_MX35_HCLK_FREQ	24000000
+#define CONFIG_MX35_CLK32	32768
 
 #define CONFIG_DISPLAY_CPUINFO
 
#1 lore raw

PATCH 1/1 mx35 timer: Switch to 32-kHz source

Quoted 7 lines · Beno?t Th?baudeau

Switch the mx35 timer driver to the 32-kHz clock source to avoid calling mxc_get_clock() again and again, and to be consistent with the timer drivers of other i.MX SoCs.

---

Hi Beno?t,

just some minor points:

Quoted 47 lines
 .../arch/arm/cpu/arm1136/mx35/timer.c              |   43 ++++++++++++--------
 .../include/configs/flea3.h                        |    1 +
 .../include/configs/mx35pdk.h                      |    1 +
 3 files changed, 27 insertions(+), 18 deletions(-)
arch/arm/cpu/arm1136/mx35/timer.c +9 -8
index 04937a1..25057af 100644
@@ -27,7 +27,7 @@
 #include <asm/io.h>
 #include <div64.h>
 #include <asm/arch/imx-regs.h>
-#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -37,43 +37,50 @@ DECLARE_GLOBAL_DATA_PTR;
 /* General purpose timers bitfields */
 #define GPTCR_SWR       (1<<15)	/* Software reset */
 #define GPTCR_FRR       (1<<9)	/* Freerun / restart */
-#define GPTCR_CLKSOURCE_32   (0x100<<6)	/* Clock source */
-#define GPTCR_CLKSOURCE_IPG (0x001<<6)	/* Clock source */
+#define GPTCR_CLKSOURCE_32   (4<<6)	/* Clock source */
 #define GPTCR_TEN       (1)	/* Timer enable */
 
-#define	TIMER_FREQ_HZ	mxc_get_clock(MXC_IPG_CLK)
-
+/*
+ * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period
+ */
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, TIMER_FREQ_HZ);
+	do_div(tick, CONFIG_MX35_CLK32);
 
 	return tick;
 }
 
-static inline unsigned long long us_to_tick(unsigned long long usec)
+static inline unsigned long long us_to_tick(unsigned long long us)
 {
-	usec *= TIMER_FREQ_HZ;

arch/arm/cpu/arm1136/mx35/timer.c DECLARE_GLOBAL_DATA_PTR; · line 65

Quoted 10 lines
arch/arm/cpu/arm1136/mx35/timer.c +5 -2
-	do_div(usec, 1000000);
+	us = us * CONFIG_MX35_CLK32 + 999999;
+	do_div(us, 1000000);
 
-	return usec;
+	return us;
 }
 
+/* nothing really to do with interrupts, just starts up a counter. */
+/* The 32KHz 32-bit timer overruns in 134217 seconds */

Wrong multiline comment. A multiline comment must be in the form:

/*
* blah blah blah
* blah blah blah
*/

Quoted 40 lines
arch/arm/cpu/arm1136/mx35/timer.c +11 -8
 int timer_init(void)
 {
 	int i;
 	struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
+	struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR;
 
 	/* setup GP Timer 1 */
 	writel(GPTCR_SWR, &gpt->ctrl);
-	for (i = 0; i < 100; i++)
-		writel(0, &gpt->ctrl);	/* We have no udelay by now */
 
-	writel(0, &gpt->pre);
-	/* Freerun Mode, PERCLK1 input */
-	writel(readl(&gpt->ctrl) |
-		GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
-		&gpt->ctrl);
+	writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1);
+
+	for (i = 0; i < 100; i++)
+		writel(0, &gpt->ctrl); /* We have no udelay by now */
+	writel(0, &gpt->pre); /* prescaler = 1 */
+	/* Freerun Mode, 32KHz input */
+	writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+			&gpt->ctrl);
+	writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl);
 
 	return 0;
 }
@@ -132,5 +139,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-	return TIMER_FREQ_HZ;
+	return CONFIG_MX35_CLK32;
 }
include/configs/flea3.h +0 -0
index 46939d4..26f1b3e 100644

include/configs/flea3.h line 35

Quoted 4 lines
include/configs/flea3.h +1 -0
@@ -32,6 +32,7 @@
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
 #define CONFIG_MX35_HCLK_FREQ	24000000
+#define CONFIG_MX35_CLK32	32768

I know the example in the tx25, but on all MX35 they share the same value and I doubt we will have a different one. And if we will had, it will be the exception that should be handled.

So set it inside timer.c and do not add it to the board configuartion files.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#2 lore raw

PATCH v2 1/2 mx35: Define default SoC input clock frequencies

Define default SoC input clock frequencies for i.MX35 in order to get rid of duplicated definitions.

---
This patch depends on http://patchwork.ozlabs.org/patch/177437/ .

Changes for v2:
- New patch.

 .../arch/arm/cpu/arm1136/mx35/generic.c            |   43 ++++++++------------
 .../arch/arm/cpu/arm1136/mx35/timer.c              |    2 +-
 .../arch/arm/include/asm/arch-mx35/clock.h         |   14 +++++++
 .../include/configs/flea3.h                        |    1 -
 .../include/configs/mx35pdk.h                      |    1 -
 5 files changed, 31 insertions(+), 30 deletions(-)
arch/arm/cpu/arm1136/mx35/generic.c +16 -27
index 8f61069..04c8341 100644
@@ -149,9 +149,7 @@ static u32 get_mcu_main_clk(void)
 	struct ccm_regs *ccm =
 		(struct ccm_regs *)IMX_CCM_BASE;
 	arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd);
-	fi *=
-		decode_pll(readl(&ccm->mpctl),
-			CONFIG_MX35_HCLK_FREQ);
+	fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK);
 	return fi / (arm_div * fd);
 }
 
@@ -193,12 +191,10 @@ u32 imx_get_uartclk(void)
 		(struct ccm_regs *)IMX_CCM_BASE;
 	u32 pdr4 = readl(&ccm->pdr4);
 
-	if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) {
+	if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U)
 		freq = get_mcu_main_clk();
-	} else {
-		freq = decode_pll(readl(&ccm->ppctl),
-			CONFIG_MX35_HCLK_FREQ);
-	}
+	else
+		freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
 	freq /= CCM_GET_DIVIDER(pdr4,
 			MXC_CCM_PDR4_UART_PODF_MASK,
 			MXC_CCM_PDR4_UART_PODF_OFFSET) + 1;
@@ -253,12 +249,10 @@ unsigned int mxc_get_main_clock(enum mxc_main_clock clk)
 		break;
 	case USB_CLK:
 		usb_podf = (reg4 >> 22) & 0x3F;
-		if (reg4 & 0x200) {
+		if (reg4 & 0x200)
 			pll = get_mcu_main_clk();
-		} else {
-			pll = decode_pll(readl(&ccm->ppctl),
-				CONFIG_MX35_HCLK_FREQ);
-		}
+		else
+			pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
 
 		ret_val = pll / (usb_podf + 1);
 		break;
@@ -285,15 +279,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		clk_sel = mpdr3 & (1 << 14);
 		pdf = (mpdr4 >> 10) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case SSI1_BAUD:
 		pre_pdf = (mpdr2 >> 24) & 0x7;
 		pdf = mpdr2 & 0x3F;
 		clk_sel = mpdr2 & (1 << 6);
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case SSI2_BAUD:
@@ -301,15 +294,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		pdf = (mpdr2 >> 8) & 0x3F;
 		clk_sel = mpdr2 & (1 << 6);
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case CSI_BAUD:
 		clk_sel = mpdr2 & (1 << 7);
 		pdf = (mpdr2 >> 16) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case MSHC_CLK:
 		pre_pdf = readl(&ccm->pdr1);
@@ -317,36 +309,33 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		pdf = (pre_pdf >> 22) & 0x3F;
 		pre_pdf = (pre_pdf >> 28) & 0x7;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case ESDHC1_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = mpdr3 & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case ESDHC2_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = (mpdr3 >> 8) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case ESDHC3_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = (mpdr3 >> 16) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case SPDIF_CLK:
 		clk_sel = mpdr3 & 0x400000;
 		pre_pdf = (mpdr3 >> 29) & 0x7;
 		pdf = (mpdr3 >> 23) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	default:
arch/arm/cpu/arm1136/mx35/timer.c +1 -1
index 04937a1..6000042 100644
@@ -101,7 +101,7 @@ ulong get_timer_masked(void)
 {
 	/*
 	 * get_ticks() returns a long long (64 bit), it wraps in
-	 * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+	 * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
 	 * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
 	 * 5 * 10^6 days - long enough.
 	 */
arch/arm/include/asm/arch-mx35/clock.h +14 -0
index 0575dad..60285df 100644
@@ -24,6 +24,20 @@
 #ifndef __ASM_ARCH_CLOCK_H
 #define __ASM_ARCH_CLOCK_H
 
+#include <common.h>
+
+#ifdef CONFIG_MX35_HCLK_FREQ
+#define MXC_HCLK	CONFIG_MX35_HCLK_FREQ
+#else
+#define MXC_HCLK	24000000
+#endif
+
+#ifdef CONFIG_MX35_CLK32
+#define MXC_CLK32	CONFIG_MX35_CLK32
+#else
+#define MXC_CLK32	32768
+#endif
+
 enum mxc_clock {
 	MXC_ARM_CLK,
 	MXC_AHB_CLK,
include/configs/flea3.h +0 -1
index e8e3c6a..815e2c5 100644
@@ -31,7 +31,6 @@
  /* High Level Configuration Options */
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
-#define CONFIG_MX35_HCLK_FREQ	24000000
 
 #define CONFIG_SYS_DCACHE_OFF
 #define CONFIG_SYS_CACHELINE_SIZE	32
include/configs/mx35pdk.h +0 -1
index f930ed0..751a1e3 100644
@@ -31,7 +31,6 @@
  /* High Level Configuration Options */
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
-#define CONFIG_MX35_HCLK_FREQ	24000000
 
 #define CONFIG_DISPLAY_CPUINFO
 
#3 lore raw

PATCH v2 2/2 mx35 timer: Switch to 32-kHz source

Switch the mx35 timer driver to the 32-kHz clock source to avoid calling mxc_get_clock() again and again, and to be consistent with the timer drivers of other i.MX SoCs.

---
Changes for v2:
- Fix multiline comment style.
- Use default SoC input clock frequency definitions instead of duplicating frequency definitions in all board files.

 .../arch/arm/cpu/arm1136/mx35/timer.c              |   44 ++++++++++++--------
 1 file changed, 27 insertions(+), 17 deletions(-)
arch/arm/cpu/arm1136/mx35/timer.c +27 -17
index 6000042..9680b7f 100644
@@ -27,6 +27,7 @@
 #include <asm/io.h>
 #include <div64.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -37,43 +38,52 @@ DECLARE_GLOBAL_DATA_PTR;
 /* General purpose timers bitfields */
 #define GPTCR_SWR       (1<<15)	/* Software reset */
 #define GPTCR_FRR       (1<<9)	/* Freerun / restart */
-#define GPTCR_CLKSOURCE_32   (0x100<<6)	/* Clock source */
-#define GPTCR_CLKSOURCE_IPG (0x001<<6)	/* Clock source */
+#define GPTCR_CLKSOURCE_32   (4<<6)	/* Clock source */
 #define GPTCR_TEN       (1)	/* Timer enable */
 
-#define	TIMER_FREQ_HZ	mxc_get_clock(MXC_IPG_CLK)
-
+/*
+ * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period
+ */
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, TIMER_FREQ_HZ);
+	do_div(tick, MXC_CLK32);
 
 	return tick;
 }
 
-static inline unsigned long long us_to_tick(unsigned long long usec)
+static inline unsigned long long us_to_tick(unsigned long long us)
 {
-	usec *= TIMER_FREQ_HZ;
-	do_div(usec, 1000000);
+	us = us * MXC_CLK32 + 999999;
+	do_div(us, 1000000);
 
-	return usec;
+	return us;
 }
 
+/*
+ * nothing really to do with interrupts, just starts up a counter.
+ * The 32KHz 32-bit timer overruns in 134217 seconds
+ */
 int timer_init(void)
 {
 	int i;
 	struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
+	struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR;
 
 	/* setup GP Timer 1 */
 	writel(GPTCR_SWR, &gpt->ctrl);
-	for (i = 0; i < 100; i++)
-		writel(0, &gpt->ctrl);	/* We have no udelay by now */
 
-	writel(0, &gpt->pre);
-	/* Freerun Mode, PERCLK1 input */
-	writel(readl(&gpt->ctrl) |
-		GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
-		&gpt->ctrl);
+	writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1);
+
+	for (i = 0; i < 100; i++)
+		writel(0, &gpt->ctrl); /* We have no udelay by now */
+	writel(0, &gpt->pre); /* prescaler = 1 */
+	/* Freerun Mode, 32KHz input */
+	writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+			&gpt->ctrl);
+	writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl);
 
 	return 0;
 }
@@ -132,5 +142,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-	return TIMER_FREQ_HZ;
+	return MXC_CLK32;
 }
#4 lore raw

PATCH v2 2/2 mx35 timer: Switch to 32-kHz source

Quoted 98 lines · Beno?t Th?baudeau

Switch the mx35 timer driver to the 32-kHz clock source to avoid calling mxc_get_clock() again and again, and to be consistent with the timer drivers of other i.MX SoCs.

---
Changes for v2:
- Fix multiline comment style.
- Use default SoC input clock frequency definitions instead of duplicating frequency definitions in all board files.

 .../arch/arm/cpu/arm1136/mx35/timer.c              |   44 ++++++++++++--------
 1 file changed, 27 insertions(+), 17 deletions(-)
arch/arm/cpu/arm1136/mx35/timer.c +26 -16
index 6000042..9680b7f 100644
@@ -27,6 +27,7 @@
 #include <asm/io.h>
 #include <div64.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -37,43 +38,52 @@ DECLARE_GLOBAL_DATA_PTR;
 /* General purpose timers bitfields */
 #define GPTCR_SWR       (1<<15)	/* Software reset */
 #define GPTCR_FRR       (1<<9)	/* Freerun / restart */
-#define GPTCR_CLKSOURCE_32   (0x100<<6)	/* Clock source */
-#define GPTCR_CLKSOURCE_IPG (0x001<<6)	/* Clock source */
+#define GPTCR_CLKSOURCE_32   (4<<6)	/* Clock source */
 #define GPTCR_TEN       (1)	/* Timer enable */
 
-#define	TIMER_FREQ_HZ	mxc_get_clock(MXC_IPG_CLK)
-
+/*
+ * "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period
+ */
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
 static inline unsigned long long tick_to_time(unsigned long long tick)
 {
 	tick *= CONFIG_SYS_HZ;
-	do_div(tick, TIMER_FREQ_HZ);
+	do_div(tick, MXC_CLK32);
 
 	return tick;
 }
 
-static inline unsigned long long us_to_tick(unsigned long long usec)
+static inline unsigned long long us_to_tick(unsigned long long us)
 {
-	usec *= TIMER_FREQ_HZ;
-	do_div(usec, 1000000);
+	us = us * MXC_CLK32 + 999999;
+	do_div(us, 1000000);
 
-	return usec;
+	return us;
 }
 
+/*
+ * nothing really to do with interrupts, just starts up a counter.
+ * The 32KHz 32-bit timer overruns in 134217 seconds
+ */
 int timer_init(void)
 {
 	int i;
 	struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
+	struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR;
 
 	/* setup GP Timer 1 */
 	writel(GPTCR_SWR, &gpt->ctrl);
-	for (i = 0; i < 100; i++)
-		writel(0, &gpt->ctrl);	/* We have no udelay by now */
 
-	writel(0, &gpt->pre);
-	/* Freerun Mode, PERCLK1 input */
-	writel(readl(&gpt->ctrl) |
-		GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
-		&gpt->ctrl);
+	writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1);
+
+	for (i = 0; i < 100; i++)
+		writel(0, &gpt->ctrl); /* We have no udelay by now */
+	writel(0, &gpt->pre); /* prescaler = 1 */
+	/* Freerun Mode, 32KHz input */
+	writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR,
+			&gpt->ctrl);
+	writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl);
 
 	return 0;
 }

arch/arm/cpu/arm1136/mx35/timer.c void __udelay(unsigned long usec) · line 146

Quoted 6 lines
arch/arm/cpu/arm1136/mx35/timer.c +1 -1
@@ -132,5 +142,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-	return TIMER_FREQ_HZ;
+	return MXC_CLK32;
 }

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#5 lore raw

PATCH v2 1/2 mx35: Define default SoC input clock frequencies

In reply to Benoît Thébaudeau
Quoted 199 lines · Beno?t Th?baudeau

Define default SoC input clock frequencies for i.MX35 in order to get rid of duplicated definitions.

---
This patch depends on http://patchwork.ozlabs.org/patch/177437/ .

Changes for v2:
- New patch.

 .../arch/arm/cpu/arm1136/mx35/generic.c            |   43 ++++++++------------
 .../arch/arm/cpu/arm1136/mx35/timer.c              |    2 +-
 .../arch/arm/include/asm/arch-mx35/clock.h         |   14 +++++++
 .../include/configs/flea3.h                        |    1 -
 .../include/configs/mx35pdk.h                      |    1 -
 5 files changed, 31 insertions(+), 30 deletions(-)
arch/arm/cpu/arm1136/mx35/generic.c +16 -27
index 8f61069..04c8341 100644
@@ -149,9 +149,7 @@ static u32 get_mcu_main_clk(void)
 	struct ccm_regs *ccm =
 		(struct ccm_regs *)IMX_CCM_BASE;
 	arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd);
-	fi *=
-		decode_pll(readl(&ccm->mpctl),
-			CONFIG_MX35_HCLK_FREQ);
+	fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK);
 	return fi / (arm_div * fd);
 }
 
@@ -193,12 +191,10 @@ u32 imx_get_uartclk(void)
 		(struct ccm_regs *)IMX_CCM_BASE;
 	u32 pdr4 = readl(&ccm->pdr4);
 
-	if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) {
+	if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U)
 		freq = get_mcu_main_clk();
-	} else {
-		freq = decode_pll(readl(&ccm->ppctl),
-			CONFIG_MX35_HCLK_FREQ);
-	}
+	else
+		freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
 	freq /= CCM_GET_DIVIDER(pdr4,
 			MXC_CCM_PDR4_UART_PODF_MASK,
 			MXC_CCM_PDR4_UART_PODF_OFFSET) + 1;
@@ -253,12 +249,10 @@ unsigned int mxc_get_main_clock(enum mxc_main_clock clk)
 		break;
 	case USB_CLK:
 		usb_podf = (reg4 >> 22) & 0x3F;
-		if (reg4 & 0x200) {
+		if (reg4 & 0x200)
 			pll = get_mcu_main_clk();
-		} else {
-			pll = decode_pll(readl(&ccm->ppctl),
-				CONFIG_MX35_HCLK_FREQ);
-		}
+		else
+			pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
 
 		ret_val = pll / (usb_podf + 1);
 		break;
@@ -285,15 +279,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		clk_sel = mpdr3 & (1 << 14);
 		pdf = (mpdr4 >> 10) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case SSI1_BAUD:
 		pre_pdf = (mpdr2 >> 24) & 0x7;
 		pdf = mpdr2 & 0x3F;
 		clk_sel = mpdr2 & (1 << 6);
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case SSI2_BAUD:
@@ -301,15 +294,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		pdf = (mpdr2 >> 8) & 0x3F;
 		clk_sel = mpdr2 & (1 << 6);
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case CSI_BAUD:
 		clk_sel = mpdr2 & (1 << 7);
 		pdf = (mpdr2 >> 16) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case MSHC_CLK:
 		pre_pdf = readl(&ccm->pdr1);
@@ -317,36 +309,33 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
 		pdf = (pre_pdf >> 22) & 0x3F;
 		pre_pdf = (pre_pdf >> 28) & 0x7;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	case ESDHC1_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = mpdr3 & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case ESDHC2_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = (mpdr3 >> 8) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case ESDHC3_CLK:
 		clk_sel = mpdr3 & 0x40;
 		pdf = (mpdr3 >> 16) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
-				(pdf + 1);
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
 		break;
 	case SPDIF_CLK:
 		clk_sel = mpdr3 & 0x400000;
 		pre_pdf = (mpdr3 >> 29) & 0x7;
 		pdf = (mpdr3 >> 23) & 0x3F;
 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
-			decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
+			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
 				((pre_pdf + 1) * (pdf + 1));
 		break;
 	default:
arch/arm/cpu/arm1136/mx35/timer.c +1 -1
index 04937a1..6000042 100644
@@ -101,7 +101,7 @@ ulong get_timer_masked(void)
 {
 	/*
 	 * get_ticks() returns a long long (64 bit), it wraps in
-	 * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+	 * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
 	 * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
 	 * 5 * 10^6 days - long enough.
 	 */
arch/arm/include/asm/arch-mx35/clock.h +14 -0
index 0575dad..60285df 100644
@@ -24,6 +24,20 @@
 #ifndef __ASM_ARCH_CLOCK_H
 #define __ASM_ARCH_CLOCK_H
 
+#include <common.h>
+
+#ifdef CONFIG_MX35_HCLK_FREQ
+#define MXC_HCLK	CONFIG_MX35_HCLK_FREQ
+#else
+#define MXC_HCLK	24000000
+#endif
+
+#ifdef CONFIG_MX35_CLK32
+#define MXC_CLK32	CONFIG_MX35_CLK32
+#else
+#define MXC_CLK32	32768
+#endif
+
 enum mxc_clock {
 	MXC_ARM_CLK,
 	MXC_AHB_CLK,
include/configs/flea3.h +0 -1
index e8e3c6a..815e2c5 100644
@@ -31,7 +31,6 @@
  /* High Level Configuration Options */
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
-#define CONFIG_MX35_HCLK_FREQ	24000000
 
 #define CONFIG_SYS_DCACHE_OFF
 #define CONFIG_SYS_CACHELINE_SIZE	32
include/configs/mx35pdk.h +0 -0
index f930ed0..751a1e3 100644

include/configs/mx35pdk.h line 36

Quoted 7 lines
include/configs/mx35pdk.h +0 -1
@@ -31,7 +31,6 @@
  /* High Level Configuration Options */
 #define CONFIG_ARM1136	/* This is an arm1136 CPU core */
 #define CONFIG_MX35
-#define CONFIG_MX35_HCLK_FREQ	24000000
 
 #define CONFIG_DISPLAY_CPUINFO
 

Nice clean-up

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#6 lore raw

PATCH v2 1/2 mx35: Define default SoC input clock frequencies

In reply to Benoît Thébaudeau
Quoted 8 lines · Beno?t Th?baudeau

Define default SoC input clock frequencies for i.MX35 in order to get rid of duplicated definitions.

---
This patch depends on http://patchwork.ozlabs.org/patch/177437/ .

Hi Beno?t,

I cannot apply this series. Can you take a look, please ?

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#7 lore raw

PATCH v2 1/2 mx35: Define default SoC input clock frequencies

Hi Stefano,

Quoted 11 lines · Beno?t Th?baudeau
Quoted 9 lines

Define default SoC input clock frequencies for i.MX35 in order to get rid of
duplicated definitions.

---
This patch depends on http://patchwork.ozlabs.org/patch/177437/ .

Quoted 3 lines

Hi Beno?t,

I cannot apply this series. Can you take a look, please ?

Yes, it's because it should be applied only after
http://patchwork.ozlabs.org/patch/177437/ (dependency indicated after the patch header). Both series touch the same lines, and I didn't know which one you would apply first. I won't be able to work on that this week (vacation). Do you prefer to review and apply (if it's correct for you) the other series first, or do you prefer that I swap these two series?

Best regards,
Beno?t

#8 lore raw

PATCH v2 1/2 mx35: Define default SoC input clock frequencies

Quoted 7 lines · Beno?t Th?baudeau
Quoted 3 lines

Hi Beno?t,

I cannot apply this series. Can you take a look, please ?

Yes, it's because it should be applied only after
http://patchwork.ozlabs.org/patch/177437/ (dependency indicated after the patch header).

I see, I have missed this comment. However, in case of this dependency, I have expected that all patches belong to the same patchset.

Quoted 2 lines

Both series touch the same lines, and I didn't know which one you would apply first. I won't be able to work on that this week (vacation).

Take your time, you are in vacation !

Quoted 3 lines

Do you prefer
to review and apply (if it's correct for you) the other series first, or do you prefer that I swap these two series?

Wait - I take a closer look to the clock series. If there something to do, you can make your changes when you will be back posting it as a whole patchset, else I will apply them in the order you posted.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================