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+rene...@mailbox.org>
---
Cc: Angelo Dureghello <ang...@kernel-space.org>
Cc: Huan Wang <alison.w...@nxp.com>
Cc: Marek Vasut <marek.vasut+rene...@mailbox.org>
Cc: Simon Glass <s...@chromium.org>
Cc: Stefan Roese <s...@denx.de>
Cc: Tom Rini <tr...@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

Reply via email to