cpu/allwinner/a10: Implement udelay using timer 0
Change-Id: I4825f0d57696cd28751c59ae133b7e3315fb78e5 Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Reviewed-on: http://review.coreboot.org/4595 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: David Hendricks <dhendrix@chromium.org>
This commit is contained in:
parent
b70a140bd0
commit
bd09dbe330
|
@ -6,6 +6,7 @@ if CPU_ALLWINNER_A10
|
||||||
|
|
||||||
config CPU_SPECIFIC_OPTIONS
|
config CPU_SPECIFIC_OPTIONS
|
||||||
def_bool y
|
def_bool y
|
||||||
|
select HAVE_INIT_TIMER
|
||||||
select HAVE_MONOTONIC_TIMER
|
select HAVE_MONOTONIC_TIMER
|
||||||
select HAVE_UART_SPECIAL
|
select HAVE_UART_SPECIAL
|
||||||
select HAVE_UART_MEMORY_MAPPED
|
select HAVE_UART_MEMORY_MAPPED
|
||||||
|
|
|
@ -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@gmail.com>
|
* Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||||
* Subject to the GNU GPL v2, or (at your option) any later version.
|
* Subject to the GNU GPL v2, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include <arch/io.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <timer.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)
|
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)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Definitions for timer control on Allwinner CPUs
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2011 Allwinner Technology Co., Ltd.
|
||||||
|
* Tom Cubie <tangliang@allwinnertech.com>
|
||||||
|
* Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@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 */
|
Loading…
Reference in New Issue