[coreboot-gerrit] New patch to review for coreboot: f914d34 cpu/allwinner/a10: Implement udelay using timer 0

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Thu Jan 2 08:48:46 CET 2014


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4595

-gerrit

commit f914d346da8047c96126fee1ed2e901016d8f350
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Tue Dec 31 00:17:19 2013 -0500

    cpu/allwinner/a10: Implement udelay using timer 0
    
    Change-Id: I4825f0d57696cd28751c59ae133b7e3315fb78e5
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/cpu/allwinner/a10/Kconfig |  1 +
 src/cpu/allwinner/a10/timer.c | 42 ++++++++++++++++++--
 src/cpu/allwinner/a10/timer.h | 90 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/src/cpu/allwinner/a10/Kconfig b/src/cpu/allwinner/a10/Kconfig
index 3df1ceb..b782b9a 100644
--- a/src/cpu/allwinner/a10/Kconfig
+++ b/src/cpu/allwinner/a10/Kconfig
@@ -6,6 +6,7 @@ if CPU_ALLWINNER_A10
 
 config CPU_SPECIFIC_OPTIONS
 	def_bool y
+	select HAVE_INIT_TIMER
 	select HAVE_MONOTONIC_TIMER
 	select HAVE_UART_SPECIAL
 	select HAVE_UART_MEMORY_MAPPED
diff --git a/src/cpu/allwinner/a10/timer.c b/src/cpu/allwinner/a10/timer.c
index e156398..60cc60c 100644
--- a/src/cpu/allwinner/a10/timer.c
+++ b/src/cpu/allwinner/a10/timer.c
@@ -1,19 +1,55 @@
 /*
- * Placeholder for code to come(needed to complete build)
+ * Timer control and delays for Allwinner CPUs
  *
  * Copyright (C) 2013  Alexandru Gagniuc <mr.nuke.me at gmail.com>
  * Subject to the GNU GPL v2, or (at your option) any later version.
  */
 
+#include "timer.h"
+
+#include <arch/io.h>
 #include <delay.h>
 #include <timer.h>
 
+struct a1x_timer *const tmr0 =
+		&((struct a1x_timer_module *)A1X_TIMER_BASE)->timer[0];
+
+static inline u32 read_timer(void)
+{
+	return read32(&tmr0->val);
+}
+
 void init_timer(void)
 {
-	/* Stub */
+	u32 reg32;
+	/* Load the timer rollover value */
+	write32(0xffffffff, &tmr0->interval);
+	/* Configure the timer to run from 24MHz oscillator, no prescaler */
+	reg32 = TIMER_CTRL_PRESC_DIV_EXP(0);
+	reg32 |= TIMER_CTRL_CLK_SRC_OSC24M;
+	reg32 |= TIMER_CTRL_RELOAD;
+	reg32 |= TIMER_CTRL_TMR_EN;
+	write32(reg32, &tmr0->ctrl);
 }
 
 void udelay(unsigned usec)
 {
-	/* Stub */
+	u32 curr_tick, last_tick;
+	s32 ticks_left;
+
+	last_tick = read_timer();
+	/* 24 timer ticks per microsecond (24 MHz, divided by 1) */
+	ticks_left = usec * 24;
+
+	/* FIXME: Should we consider timer rollover?
+	 * From when we start the timer, we have almost three minutes before it
+	 * rolls over, so we should be long into having booted our payload.
+	 */
+	while (ticks_left > 0) {
+		curr_tick = read_timer();
+		/* Timer value decreases with each tick */
+		ticks_left -= last_tick - curr_tick;
+		last_tick = curr_tick;
+	}
+
 }
diff --git a/src/cpu/allwinner/a10/timer.h b/src/cpu/allwinner/a10/timer.h
new file mode 100644
index 0000000..9c0c0d1
--- /dev/null
+++ b/src/cpu/allwinner/a10/timer.h
@@ -0,0 +1,90 @@
+/*
+ * Definitions for timer control on Allwinner CPUs
+ *
+ * Copyright (C) 2007-2011 Allwinner Technology Co., Ltd.
+ *	Tom Cubie <tangliang at allwinnertech.com>
+ * Copyright (C) 2013  Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#ifndef CPU_ALLWINNER_A10_TIMER_H
+#define CPU_ALLWINNER_A10_TIMER_H
+
+#include "memmap.h"
+#include <types.h>
+
+/* TMRx_CTRL values */
+#define TIMER_CTRL_MODE_SINGLE		(1 << 7)
+#define TIMER_CTRL_PRESC_MASK		(0x7 << 4)
+#define  TIMER_CTRL_PRESC_DIV_EXP(ep)	((ep << 4) & TIMER_CTRL_PRESC_MASK)
+#define TIMER_CTRL_CLK_SRC_MASK		(0x3 << 2)
+#define  TIMER_CTRL_CLK_SRC_LOSC	(0x0 << 2)
+#define  TIMER_CTRL_CLK_SRC_OSC24M	(0x1 << 2)
+#define  TIMER_CTRL_CLK_SRC_PLL6	(0x2 << 2)
+#define TIMER_CTRL_RELOAD		(1 << 1)
+#define TIMER_CTRL_TMR_EN		(1 << 0)
+
+/* General purpose timer */
+struct a1x_timer {
+	u32 ctrl;
+	u32 interval;
+	u32 val;
+	u8 res[4];
+} __attribute__ ((packed));
+
+/* Audio video sync*/
+struct a1x_avs {
+	u32 ctrl;		/* 0x80 */
+	u32 cnt0;		/* 0x84 */
+	u32 cnt1;		/* 0x88 */
+	u32 div;		/* 0x8c */
+} __attribute__ ((packed));
+
+/* Watchdog */
+struct a1x_wdog {
+	u32 ctrl;		/* 0x90 */
+	u32 mode;		/* 0x94 */
+} __attribute__ ((packed));
+
+/* 64 bit counter */
+struct a1x_64cnt {
+	u32 ctrl;		/* 0xa0 */
+	u32 lo;			/* 0xa4 */
+	u32 hi;			/* 0xa8 */
+} __attribute__ ((packed));
+
+/* Rtc */
+struct a1x_rtc {
+	u32 ctrl;		/* 0x100 */
+	u32 yymmdd;		/* 0x104 */
+	u32 hhmmss;		/* 0x108 */
+} __attribute__ ((packed));
+
+/* Alarm */
+struct a1x_alarm {
+	u32 ddhhmmss;		/* 0x10c */
+	u32 hhmmss;		/* 0x110 */
+	u32 en;			/* 0x114 */
+	u32 irq_en;		/* 0x118 */
+	u32 irq_sta;		/* 0x11c */
+} __attribute__ ((packed));
+
+struct a1x_timer_module {
+	u32 irq_en;		/* 0x00 */
+	u32 irq_sta;		/* 0x04 */
+	u8 res1[8];
+	struct a1x_timer timer[6];	/* We have 6 timers */
+	u8 res2[16];
+	struct a1x_avs avs;
+	struct a1x_wdog wdog;
+	u8 res3[8];
+	struct a1x_64cnt cnt64;
+	u8 res4[0x58];
+	struct a1x_rtc rtc;
+	struct a1x_alarm alarm;
+	u32 gp_data[4];
+	u8 res5[8];
+	u32 cpu_cfg;
+} __attribute__ ((packed));
+
+#endif				/* CPU_ALLWINNER_A10_TIMER_H */



More information about the coreboot-gerrit mailing list