Date: Fri, 6 Jan 2006 20:29:08 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 89293 for review Message-ID: <200601062029.k06KT8sJ041817@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=89293 Change 89293 by imp@imp_Speedy on 2006/01/06 20:29:07 Streamline the timer driver a little. Move from using TIMER_ defines to ST_ defines, to match the atmel datasheet. Use macros rather than raw-bus_space calls to access these registers. Fix DELAY by writing the RTMR in attach rather than at clock init time as well as making sure it will terminate. Optimize DELAY as well to avoid complicated math. Moved cpu_reset to the at91rm92timer device file, since that's where the reset hardware lives. Remove redundant definitions of ST_ that I created before. # DELAY needs to migrate Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91rm92.c#10 edit .. //depot/projects/arm/src/sys/arm/at91/at91rm92reg.h#11 edit .. //depot/projects/arm/src/sys/arm/at91/at91rm92timer.c#5 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91rm92.c#10 (text+ko) ==== @@ -291,22 +291,6 @@ return (0); } -void -cpu_reset(void) -{ - struct at91rm92_softc *sc = at91rm92_softc; - - /* - * Reset the CPU by programmig the watchdog timer to reset the - * CPU after 128 'slow' clocks, or about ~4ms. Loop until - * the reset happens for safety. - */ - bus_space_write_4(sc->sc_st, sc->sc_sys_sh, ST_WDMR, ST_RSTEN | 2); - bus_space_write_4(sc->sc_st, sc->sc_sys_sh, ST_CR, ST_WDRST); - while (1) - continue; -} - static struct resource * at91rm92_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) ==== //depot/projects/arm/src/sys/arm/at91/at91rm92reg.h#11 (text+ko) ==== @@ -203,19 +203,6 @@ #define PIOD_OWDR (0xa00 + 164) /* Output write disable register */ #define PIOD_OWSR (0xa00 + 168) /* Output write status register */ -#define ST_CR (0xd00 + 0) /* Control register */ -#define ST_WDRST 1 -#define ST_PIMR (0xd00 + 4) /* Period Interval Mode register */ -#define ST_WDMR (0xd00 + 8) /* Watchdog Mode register */ -#define ST_RSTEN (1 << 16) -#define ST_RTMR (0xd00 + 12) /* Reat-time Mode register */ -#define ST_SR (0xd00 + 16) /* Status register */ -#define ST_IER (0xd00 + 20) /* Interrupt Enable register */ -#define ST_IDR (0xd00 + 24) /* Interrupt Disable register */ -#define ST_IMR (0xd00 + 28) /* Interrupt Mask register */ -#define ST_RTAR (0xd00 + 32) /* Real-time Alarm register */ -#define ST_CRTR (0xd00 + 36) /* Current Real-time register */ - /* IRQs : */ /* * 0: AIC @@ -280,19 +267,27 @@ /* Timer */ -#define AT91RM92_TIMER_BASE 0xffffd00 -#define AT91RM92_TIMER_SIZE 0x100 +#define AT91RM92_ST_BASE 0xffffd00 +#define AT91RM92_ST_SIZE 0x100 -#define TIMER_CR 0x00 /* Control register */ -#define TIMER_PIMR 0x04 /* Period interval mode register */ -#define TIMER_WMR 0x08 /* Watchdog mode register */ -#define TIMER_RTMR 0x0c /* Real-time mode register */ -#define TIMER_SR 0x10 /* Status register */ -#define TIMER_IER 0x14 /* Interrupt enable register */ -#define TIMER_IDR 0x18 /* Interrupt disable register */ -#define TIMER_IMR 0x1c /* Interrupt mask register */ -#define TIMER_RTAR 0x20 /* Real-time alarm register */ -#define TIMER_CRTR 0x24 /* Current real-time register */ +#define ST_CR 0x00 /* Control register */ +#define ST_CR_WDRST (1U << 0) /* WDRST: Watchdog Timer Restart */ +#define ST_PIMR 0x04 /* Period interval mode register */ +#define ST_WDMR 0x08 /* Watchdog mode register */ +#define ST_WDMR_EXTEN (1U << 17) /* EXTEN: External Signal Assert Enable */ +#define ST_WDMR_RSTEN (1U << 16) /* RSTEN: Reset Enable */ +#define ST_RTMR 0x0c /* Real-time mode register */ +#define ST_SR 0x10 /* Status register */ +#define ST_SR_PITS (1U << 0) /* PITS: Period Interval Timer Status */ +#define ST_SR_WDOVF (1U << 1) /* WDOVF: Watchdog Overflow */ +#define ST_SR_RTTINC (1U << 2) /* RTTINC: Real-time Timer Increment */ +#define ST_SR_ALMS (1U << 3) /* ALMS: Alarm Status */ +#define ST_IER 0x14 /* Interrupt enable register */ +#define ST_IDR 0x18 /* Interrupt disable register */ +#define ST_IMR 0x1c /* Interrupt mask register */ +#define ST_RTAR 0x20 /* Real-time alarm register */ +#define ST_CRTR 0x24 /* Current real-time register */ +#define ST_CRTR_MASK 0xfffff /* 20-bit counter */ #define AT91RM92_SPI_BASE 0xffe0000 #define AT91RM92_SPI_SIZE 0x4000 ==== //depot/projects/arm/src/sys/arm/at91/at91rm92timer.c#5 (text+ko) ==== @@ -50,6 +50,22 @@ device_t dev; } *timer_softc; +#define RD4(off) \ + bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, (off)) +#define WR4(off, val) \ + bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, (off), (val)) + +static inline int +st_crtr(void) +{ + int cur1, cur2; + do { + cur1 = RD4(ST_CRTR); + cur2 = RD4(ST_CRTR); + } while (cur1 != cur2); + return (cur1); +} + static unsigned at91rm92timer_get_timecount(struct timecounter *tc); static struct timecounter at91rm92timer_timecounter = { @@ -75,9 +91,15 @@ timer_softc = device_get_softc(dev); timer_softc->sc_st = sc->sc_st; timer_softc->dev = dev; - if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_TIMER_BASE, - AT91RM92_TIMER_SIZE, &timer_softc->sc_sh) != 0) + if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_ST_BASE, + AT91RM92_ST_SIZE, &timer_softc->sc_sh) != 0) panic("couldn't subregion timer registers"); + /* + * Real time counter increments every clock cycle, need to set before + * initializing clocks so that DELAY works. + */ + WR4(ST_RTMR, 1); + return (0); } @@ -100,14 +122,7 @@ static unsigned at91rm92timer_get_timecount(struct timecounter *tc) { - int cur1, cur2; - do { - cur1 = bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_CRTR); - cur2 = bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_CRTR); - } while (cur1 != cur2); - return (cur1); + return (st_crtr()); } static void @@ -116,10 +131,8 @@ struct trapframe *fp = arg; /* The interrupt is shared, so we have to make sure it's for us. */ - if (bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_SR) & 1) { + if (RD4(ST_SR) & ST_SR_PITS) hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp)); - } } void @@ -137,8 +150,7 @@ } rel_value = 32768 / hz; /* Disable all interrupts. */ - bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_IDR, 0xffffffff); + WR4(ST_IDR, 0xffffffff); /* The system timer shares the system irq (1) */ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1, RF_ACTIVE | RF_SHAREABLE); @@ -148,42 +160,45 @@ bus_setup_intr(dev, irq, INTR_TYPE_CLK | INTR_FAST, clock_intr, NULL, &ih); - bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_PIMR, rel_value); - /* Real time counter increments every clock cycle. */ - bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_RTMR, 1); + WR4(ST_PIMR, rel_value); /* Enable PITS interrupts. */ - bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_IER, 1); + WR4(ST_IER, ST_SR_PITS); tc_init(&at91rm92timer_timecounter); } void DELAY(int n) { - uint32_t usec = 0; - uint32_t cur1, cur2, old, delta = 0; + uint32_t start, end, cur; - old = bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, - TIMER_CRTR); - while (usec < n) { - do { - cur1 = bus_space_read_4(timer_softc->sc_st, - timer_softc->sc_sh, TIMER_CRTR); - cur2 = bus_space_read_4(timer_softc->sc_st, - timer_softc->sc_sh, TIMER_CRTR); - } while (cur1 != cur2); - if (old > cur1) - delta += (old + (0xfffff + 1 - cur1)); - else - delta += (cur1 - old); - usec += delta / 32768 * 1000000; - delta = 0; - + start = st_crtr(); + n = (n * 1000000) / 32768; + if (n <= 0) + n = 1; + end = (start + n) & ST_CRTR_MASK; + cur = start; + if (start > end) { + while (cur >= start || cur < end) + cur = st_crtr(); + } else { + while (cur < end) + cur = st_crtr(); + } +} - } +void +cpu_reset(void) +{ + /* + * Reset the CPU by programmig the watchdog timer to reset the + * CPU after 128 'slow' clocks, or about ~4ms. Loop until + * the reset happens for safety. + */ + WR4(ST_WDMR, ST_WDMR_RSTEN | 2); + WR4(ST_CR, ST_CR_WDRST); + while (1) + continue; } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601062029.k06KT8sJ041817>