[PATCH v2 2/3] arch: m68k: Introduce trivial PIT based timer

Marek Vasut marek.vasut+renesas at mailbox.org
Thu Mar 23 01:20:40 CET 2023


The QEMU emulation of m68k does not support DMA timer, the only
timer that is supported is the PIT timer. Implement trivial PIT
timer support for m68k.

Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
---
Cc: Angelo Dureghello <angelo at kernel-space.org>
Cc: Huan Wang <alison.wang at nxp.com>
Cc: Marek Vasut <marek.vasut+renesas at mailbox.org>
Cc: Simon Glass <sjg at chromium.org>
Cc: Stefan Roese <sr at denx.de>
Cc: Tom Rini <trini at konsulko.com>
---
V2: Replace CFG_MCFTMR with CONFIG_MCFTMR in common/board_f.c
---
 arch/m68k/include/asm/immap.h | 24 +++++++++++++++++++++++
 arch/m68k/lib/time.c          | 36 +++++++++++++++++++++++++++++++++--
 common/board_f.c              |  2 +-
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/arch/m68k/include/asm/immap.h b/arch/m68k/include/asm/immap.h
index 3b515fe2c65..aafa4f40cb3 100644
--- a/arch/m68k/include/asm/immap.h
+++ b/arch/m68k/include/asm/immap.h
@@ -25,6 +25,8 @@
 #define CFG_SYS_TMRINTR_PEND		(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(6)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
@@ -47,6 +49,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(0x1E)		/* Level must include inorder to work */
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
@@ -72,6 +76,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 2000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif				/* CONFIG_M5249 */
 
@@ -95,6 +101,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL3 | MCFSIM_ICR_PRI3)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 2000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif				/* CONFIG_M5253 */
 
@@ -114,6 +122,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(0x1E) /* Interrupt level 3, priority 6 */
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
@@ -139,6 +149,8 @@
 #define CFG_SYS_TMRINTR_PEND	(0)
 #define CFG_SYS_TMRINTR_PRI		(INT_ICR1_TMR3PI | INT_ICR1_TMR3IPL(5))
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif				/* CONFIG_M5272 */
 
@@ -161,6 +173,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(0x1E)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif				/* CONFIG_M5275 */
 
@@ -183,6 +197,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(0x1E)		/* Level must include inorder to work */
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif				/* CONFIG_M5282 */
 
@@ -207,6 +223,8 @@
 #define CFG_SYS_TMRINTR_PRI          (MCFSIM_ICR_AUTOVEC | \
 					MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3)
 #define CFG_SYS_TIMER_PRESCALER      (((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 #endif                          /* CONFIG_M5307 */
 
@@ -226,6 +244,8 @@
 #define CFG_SYS_TMRINTR_PEND		(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(6)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
@@ -248,6 +268,8 @@
 #define CFG_SYS_TMRINTR_PEND	(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(6)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
@@ -278,6 +300,8 @@
 #define CFG_SYS_TMRINTR_PEND		(CFG_SYS_TMRINTR_MASK)
 #define CFG_SYS_TMRINTR_PRI		(6)
 #define CFG_SYS_TIMER_PRESCALER	(((gd->bus_clk / 1000000) - 1) << 8)
+#else
+#define CFG_SYS_UDELAY_BASE		(MMAP_PIT0)
 #endif
 
 #define CFG_SYS_INTR_BASE		(MMAP_INTC0)
diff --git a/arch/m68k/lib/time.c b/arch/m68k/lib/time.c
index 500e4dbbba2..61db1e6c500 100644
--- a/arch/m68k/lib/time.c
+++ b/arch/m68k/lib/time.c
@@ -111,8 +111,6 @@ ulong get_timer(ulong base)
 	return (timestamp - base);
 }
 
-#endif				/* CONFIG_MCFTMR */
-
 /*
  * This function is derived from PowerPC code (read timebase as long long).
  * On M68K it just returns the timer value.
@@ -121,6 +119,40 @@ unsigned long long get_ticks(void)
 {
 	return get_timer(0);
 }
+#else
+static u64 timer64 __section(".data");
+static u16 timer16 __section(".data");
+
+uint64_t __weak get_ticks(void)
+{
+	volatile pit_t *timerp = (pit_t *) (CFG_SYS_UDELAY_BASE);
+	u16 val = ~timerp->pcntr;
+
+	if (timer16 > val)
+		timer64 += 0xffff - timer16 + val;
+	else
+		timer64 += val - timer16;
+
+	timer16 = val;
+
+	return timer64;
+}
+
+/* PIT timer */
+int timer_init(void)
+{
+	volatile pit_t *timerp = (pit_t *) (CFG_SYS_UDELAY_BASE);
+
+	timer16 = 0;
+	timer64 = 0;
+
+	/* Set up PIT as timebase clock */
+	timerp->pmr = 0xffff;
+	timerp->pcsr = PIT_PCSR_EN | PIT_PCSR_OVW;
+
+	return 0;
+}
+#endif				/* CONFIG_MCFTMR */
 
 unsigned long usec2ticks(unsigned long usec)
 {
diff --git a/common/board_f.c b/common/board_f.c
index f3c1ab53b1c..1688e27071f 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -863,7 +863,7 @@ static const init_fnc_t init_sequence_f[] = {
 	/* get CPU and bus clocks according to the environment variable */
 	get_clocks,		/* get CPU and bus clocks (etc.) */
 #endif
-#if !defined(CONFIG_M68K)
+#if !defined(CONFIG_M68K) || (defined(CONFIG_M68K) && !defined(CONFIG_MCFTMR))
 	timer_init,		/* initialize timer */
 #endif
 #if defined(CONFIG_BOARD_POSTCLK_INIT)
-- 
2.39.2



More information about the U-Boot mailing list