diff options
author | wdenk <wdenk> | 2003-06-19 23:01:32 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2003-06-19 23:01:32 +0000 |
commit | 48b42616e928ce6eacfe20276a1614e2b27ac4b5 (patch) | |
tree | 0c194fbd1059185f158c0b37dc3c846b50c2ee2f /cpu | |
parent | 15ef8a5d17181ea376fac94579dce0af1cfcdeb7 (diff) | |
download | u-boot-imx-48b42616e928ce6eacfe20276a1614e2b27ac4b5.zip u-boot-imx-48b42616e928ce6eacfe20276a1614e2b27ac4b5.tar.gz u-boot-imx-48b42616e928ce6eacfe20276a1614e2b27ac4b5.tar.bz2 |
* Patches by David Müller, 12 Jun 2003:
- rewrite of the S3C24X0 register definitions stuff
- "driver" for the built-in S3C24X0 RTC
* Patches by Yuli Barcohen, 12 Jun 2003:
- Add MII support and Ethernet PHY initialization for MPC8260ADS board
- Fix incorrect SIUMCR initialisation caused by wrong Hard Reset
configuration word supplied by FPGA on some MPC8260ADS boards
* Patch by Pantelis Antoniou, 10 Jun 2003:
Unify status LED interface
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/arm920t/interrupts.c | 21 | ||||
-rw-r--r-- | cpu/arm920t/serial.c | 98 | ||||
-rw-r--r-- | cpu/arm920t/speed.c | 13 | ||||
-rw-r--r-- | cpu/mpc5xx/Makefile | 2 | ||||
-rw-r--r-- | cpu/mpc5xx/status_led.c | 161 | ||||
-rw-r--r-- | cpu/mpc8260/Makefile | 2 | ||||
-rw-r--r-- | cpu/mpc8260/ether_scc.c | 2 | ||||
-rw-r--r-- | cpu/mpc8260/start.S | 13 | ||||
-rw-r--r-- | cpu/mpc8260/status_led.c | 160 | ||||
-rw-r--r-- | cpu/mpc8xx/Makefile | 2 | ||||
-rw-r--r-- | cpu/mpc8xx/status_led.c | 168 |
11 files changed, 76 insertions, 566 deletions
diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c index 195fb01..dd944fb 100644 --- a/cpu/arm920t/interrupts.c +++ b/cpu/arm920t/interrupts.c @@ -43,7 +43,12 @@ extern void reset_cpu(ulong addr); int timer_load_val = 0; /* macro to read the 16 bit timer */ -#define READ_TIMER (rTCNTO4 & 0xffff) +static inline ulong READ_TIMER(void) +{ + S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); + + return (timers->TCNTO4 & 0xffff); +} #ifdef CONFIG_USE_IRQ /* enable IRQ interrupts */ @@ -184,9 +189,11 @@ static ulong lastdec; int interrupt_init (void) { + S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); + /* use PWM Timer 4 because it has no output */ /* prescaler for Timer 4 is 16 */ - rTCFG0 = 0x0f00; + timers->TCFG0 = 0x0f00; if (timer_load_val == 0) { /* @@ -197,11 +204,11 @@ int interrupt_init (void) timer_load_val = get_PCLK()/(2 * 16 * 100); } /* load value for 10 ms timeout */ - lastdec = rTCNTB4 = timer_load_val; + lastdec = timers->TCNTB4 = timer_load_val; /* auto load, manual update of Timer 4 */ - rTCON = (rTCON & ~0x0700000) | 0x600000; + timers->TCON = (timers->TCON & ~0x0700000) | 0x600000; /* auto load, start Timer 4 */ - rTCON = (rTCON & ~0x0700000) | 0x500000; + timers->TCON = (timers->TCON & ~0x0700000) | 0x500000; timestamp = 0; return (0); @@ -243,13 +250,13 @@ void udelay (unsigned long usec) void reset_timer_masked (void) { /* reset time */ - lastdec = READ_TIMER; + lastdec = READ_TIMER(); timestamp = 0; } ulong get_timer_masked (void) { - ulong now = READ_TIMER; + ulong now = READ_TIMER(); if (lastdec >= now) { /* normal mode */ diff --git a/cpu/arm920t/serial.c b/cpu/arm920t/serial.c index c32e73b..10cfade 100644 --- a/cpu/arm920t/serial.c +++ b/cpu/arm920t/serial.c @@ -25,57 +25,51 @@ #include <s3c2410.h> #endif +#ifdef CONFIG_SERIAL1 +#define UART_NR S3C24X0_UART0 + +#elif CONFIG_SERIAL2 +# if defined(CONFIG_TRAB) +# #error "TRAB supports only CONFIG_SERIAL1" +# endif +#define UART_NR S3C24X0_UART1 + +#elif CONFIG_SERIAL3 +# if defined(CONFIG_TRAB) +# #error "TRAB supports only CONFIG_SERIAL1" +# endif +#define UART_NR S3C24X0_UART2 + +#else +#error "Bad: you didn't configure serial ..." +#endif void serial_setbrg (void) { DECLARE_GLOBAL_DATA_PTR; - + S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); int i; unsigned int reg = 0; /* value is calculated so : (int)(PCLK/16./baudrate) -1 */ reg = get_PCLK() / (16 * gd->baudrate) - 1; -#ifdef CONFIG_SERIAL1 /* FIFO enable, Tx/Rx FIFO clear */ - rUFCON0 = 0x07; - rUMCON0 = 0x0; + uart->UFCON = 0x07; + uart->UMCON = 0x0; /* Normal,No parity,1 stop,8 bit */ - rULCON0 = 0x3; + uart->ULCON = 0x3; /* * tx=level,rx=edge,disable timeout int.,enable rx error int., * normal,interrupt or polling */ - rUCON0 = 0x245; - rUBRDIV0 = reg; + uart->UCON = 0x245; + uart->UBRDIV = reg; #ifdef CONFIG_HWFLOW - rUMCON0 = 0x1; /* RTS up */ + uart->UMCON = 0x1; /* RTS up */ #endif for (i = 0; i < 100; i++); -#elif CONFIG_SERIAL2 -# if defined(CONFIG_TRAB) -# #error "TRAB supports only CONFIG_SERIAL1" -# endif - /* FIFO enable, Tx/Rx FIFO clear */ - rUFCON1 = 0x06; - rUMCON1 = 0x0; - /* Normal,No parity,1 stop,8 bit */ - rULCON1 = 0x3; - /* - * tx=level,rx=edge,disable timeout int.,enable rx error int., - * normal,interrupt or polling - */ - rUCON1 = 0x245; - rUBRDIV1 = reg; - -#ifdef CONFIG_HWFLOW - rUMCON1 = 0x1; /* RTS up */ -#endif - for (i = 0; i < 100; i++); -#else -#error "Bad: you didn't configure serial ..." -#endif } /* @@ -97,15 +91,12 @@ int serial_init (void) */ int serial_getc (void) { -#ifdef CONFIG_SERIAL1 - while (!(rUTRSTAT0 & 0x1)); + S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); + + /* wait for character to arrive */ + while (!(uart->UTRSTAT & 0x1)); - return rURXH0 & 0xff; -#elif CONFIG_SERIAL2 - while (!(rUTRSTAT1 & 0x1)); - - return rURXH1 & 0xff; -#endif + return uart->URXH & 0xff; } #ifdef CONFIG_HWFLOW @@ -146,33 +137,22 @@ void enable_putc(void) */ void serial_putc (const char c) { + S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); #ifdef CONFIG_MODEM_SUPPORT if (be_quiet) return; #endif -#ifdef CONFIG_SERIAL1 - /* wait for room in the tx FIFO on SERIAL1 */ - while (!(rUTRSTAT0 & 0x2)); + /* wait for room in the tx FIFO */ + while (!(uart->UTRSTAT & 0x2)); #ifdef CONFIG_HWFLOW /* Wait for CTS up */ - while(hwflow && !(rUMSTAT0 & 0x1)) + while(hwflow && !(uart->UMSTAT & 0x1)) ; #endif - rUTXH0 = c; -#elif CONFIG_SERIAL2 - /* wait for room in the tx FIFO on SERIAL2 */ - while (!(rUTRSTAT1 & 0x2)); - -#ifdef CONFIG_HWFLOW - /* Wait for CTS up */ - while(hwflow && !(rUMSTAT1 & 0x1)) - ; -#endif - rUTXH1 = c; -#endif + uart->UTXH = c; /* If \n, also do \r */ if (c == '\n') @@ -184,11 +164,9 @@ void serial_putc (const char c) */ int serial_tstc (void) { -#ifdef CONFIG_SERIAL1 - return rUTRSTAT0 & 0x1; -#elif CONFIG_SERIAL2 - return rUTRSTAT1 & 0x1; -#endif + S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); + + return uart->UTRSTAT & 0x1; } void diff --git a/cpu/arm920t/speed.c b/cpu/arm920t/speed.c index 4942727..1f43543 100644 --- a/cpu/arm920t/speed.c +++ b/cpu/arm920t/speed.c @@ -51,12 +51,13 @@ static ulong get_PLLCLK(int pllreg) { + S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); ulong r, m, p, s; if (pllreg == MPLL) - r = rMPLLCON; + r = clk_power->MPLLCON; else if (pllreg == UPLL) - r = rUPLLCON; + r = clk_power->UPLLCON; else hang(); @@ -76,17 +77,17 @@ ulong get_FCLK(void) /* return HCLK frequency */ ulong get_HCLK(void) { - ulong clkdiv = rCLKDIVN; + S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); - return((clkdiv & 0x2) ? get_FCLK()/2 : get_FCLK()); + return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK()); } /* return PCLK frequency */ ulong get_PCLK(void) { - ulong clkdiv = rCLKDIVN; + S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); - return((clkdiv & 0x1) ? get_HCLK()/2 : get_HCLK()); + return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK()); } /* return UCLK frequency */ diff --git a/cpu/mpc5xx/Makefile b/cpu/mpc5xx/Makefile index a1e0421..c05b394 100644 --- a/cpu/mpc5xx/Makefile +++ b/cpu/mpc5xx/Makefile @@ -35,7 +35,7 @@ include $(TOPDIR)/config.mk LIB = lib$(CPU).a START = start.S -OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o status_led.o +OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o all: .depend $(START) $(LIB) diff --git a/cpu/mpc5xx/status_led.c b/cpu/mpc5xx/status_led.c deleted file mode 100644 index f15bbe8..0000000 --- a/cpu/mpc5xx/status_led.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de - * (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * File: status_led.c - * - * Discription: Blink a board led to show boot progress. Led's - * are connected via the MIOS module. - */ - -#include <common.h> -#include <mpc5xx.h> -#include <status_led.h> - -#ifdef CONFIG_STATUS_LED - -typedef struct { - ulong mask; - int state; - int period; - int cnt; -} led_dev_t; - -led_dev_t led_dev[] = { - { STATUS_LED_BIT, - STATUS_LED_STATE, - STATUS_LED_PERIOD, - 0, - }, -#if defined(STATUS_LED_BIT1) - { STATUS_LED_BIT1, - STATUS_LED_STATE1, - STATUS_LED_PERIOD1, - 0, - }, -#endif -#if defined(STATUS_LED_BIT2) - { STATUS_LED_BIT2, - STATUS_LED_STATE2, - STATUS_LED_PERIOD2, - 0, - }, -#endif -#if defined(STATUS_LED_BIT3) - { STATUS_LED_BIT3, - STATUS_LED_STATE3, - STATUS_LED_PERIOD3, - 0, - }, -#endif -}; - -#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) - -static int status_led_init_done = 0; - -static void status_led_init (void) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - immr->STATUS_LED_DIR = STATUS_LED_BIT; - -#if (STATUS_LED_ACTIVE == 0) - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT &= ~(ld->mask); - else - immr->STATUS_LED_DAT |= ld->mask ; -#else - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT |= ld->mask ; - else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - } - - status_led_init_done = 1; -} - -void status_led_tick (ulong timestamp) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - if (!status_led_init_done) - status_led_init(); - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - if (ld->state != STATUS_LED_BLINKING) - continue; - - if (++(ld->cnt) >= ld->period) { - immr->STATUS_LED_DAT ^= ld->mask; - ld->cnt -= ld->period; - } - } -} - -void status_led_set (int led, int state) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - led_dev_t *ld; - - if (led < 0 || led >= MAX_LED_DEV) - return; - - if (!status_led_init_done) - status_led_init(); - - ld = &led_dev[led]; - - switch (state) { - default: - return; - case STATUS_LED_BLINKING: - ld->cnt = 0; /* always start with full period */ - /* fall through */ /* always start with LED _ON_ */ - case STATUS_LED_ON: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT &= ~(ld->mask); -#else - immr->STATUS_LED_DAT |= ld->mask ; -#endif - break; - case STATUS_LED_OFF: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT |= ld->mask ; -#else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - break; - } - ld->state = state; -} - -#endif /* CONFIG_STATUS_LED */ diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile index 81f74ec..b4c269f 100644 --- a/cpu/mpc8260/Makefile +++ b/cpu/mpc8260/Makefile @@ -28,7 +28,7 @@ LIB = lib$(CPU).a START = start.o kgdb.o OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \ interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \ - bedbug_603e.o status_led.o pci.o spi.o + bedbug_603e.o pci.o spi.o all: .depend $(START) $(LIB) diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c index ff164fe..8b6af31 100644 --- a/cpu/mpc8260/ether_scc.c +++ b/cpu/mpc8260/ether_scc.c @@ -333,7 +333,7 @@ int eth_init(bd_t *bis) immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - return 1; + return 0; } diff --git a/cpu/mpc8260/start.S b/cpu/mpc8260/start.S index 0e6b963..2070ecc 100644 --- a/cpu/mpc8260/start.S +++ b/cpu/mpc8260/start.S @@ -161,6 +161,7 @@ _hrcw_table: .globl _start _start: li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH*/ + nop b boot_cold . = EXC_OFF_SYS_RESET + 0x10 @@ -171,6 +172,18 @@ _start_warm: b boot_warm boot_cold: +#if defined(CONFIG_MPC8260ADS) + lis r3, CFG_DEFAULT_IMMR@h + nop + lwz r4, 0(r3) + nop + rlwinm r4, r4, 0, 8, 5 + nop + oris r4, r4, 0x0200 + nop + stw r4, 0(r3) + nop +#endif /* CONFIG_MPC8260ADS */ boot_warm: mfmsr r5 /* save msr contents */ diff --git a/cpu/mpc8260/status_led.c b/cpu/mpc8260/status_led.c deleted file mode 100644 index 0174e39..0000000 --- a/cpu/mpc8260/status_led.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <status_led.h> - -/* - * The purpose of this code is to signal the operational status of a - * target which usually boots over the network; while running in - * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply - * message has been received, the LED is turned off. The Linux - * kernel, once it is running, will start blinking the LED again, - * with another frequency. - */ - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_STATUS_LED - -typedef struct { - ulong mask; - int state; - int period; - int cnt; -} led_dev_t; - -led_dev_t led_dev[] = { - { STATUS_LED_BIT, - STATUS_LED_STATE, - STATUS_LED_PERIOD, - 0, - }, -#if defined(STATUS_LED_BIT1) - { STATUS_LED_BIT1, - STATUS_LED_STATE1, - STATUS_LED_PERIOD1, - 0, - }, -#endif -#if defined(STATUS_LED_BIT2) - { STATUS_LED_BIT2, - STATUS_LED_STATE2, - STATUS_LED_PERIOD2, - 0, - }, -#endif -}; - -#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) - -static int status_led_init_done = 0; - -static void status_led_init (void) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - immr->STATUS_LED_PAR &= ~(ld->mask); -#ifdef STATUS_LED_ODR - immr->STATUS_LED_ODR &= ~(ld->mask); -#endif -#if (STATUS_LED_ACTIVE == 0) - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT &= ~(ld->mask); - else - immr->STATUS_LED_DAT |= ld->mask ; -#else - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT |= ld->mask ; - else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - immr->STATUS_LED_DIR |= ld->mask ; - } - - status_led_init_done = 1; -} - -void status_led_tick (ulong timestamp) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - if (!status_led_init_done) - status_led_init(); - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - if (ld->state != STATUS_LED_BLINKING) - continue; - - if (++(ld->cnt) >= ld->period) { - immr->STATUS_LED_DAT ^= ld->mask; - ld->cnt -= ld->period; - } - } -} - -void status_led_set (int led, int state) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - led_dev_t *ld; - - if (led < 0 || led >= MAX_LED_DEV) - return; - - if (!status_led_init_done) - status_led_init(); - - ld = &led_dev[led]; - - switch (state) { - default: - return; - case STATUS_LED_BLINKING: - ld->cnt = 0; /* always start with full period */ - /* fall through */ /* always start with LED _ON_ */ - case STATUS_LED_ON: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT &= ~(ld->mask); -#else - immr->STATUS_LED_DAT |= ld->mask ; -#endif - break; - case STATUS_LED_OFF: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT |= ld->mask ; -#else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - break; - } - ld->state = state; -} - -#endif /* CONFIG_STATUS_LED */ diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile index 8b05721..e8c93cc 100644 --- a/cpu/mpc8xx/Makefile +++ b/cpu/mpc8xx/Makefile @@ -30,7 +30,7 @@ LIB = lib$(CPU).a START = start.o kgdb.o OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \ fec.o i2c.o interrupts.o lcd.o scc.o \ - serial.o speed.o spi.o status_led.o\ + serial.o speed.o spi.o \ traps.o upatch.o video.o all: .depend $(START) $(LIB) diff --git a/cpu/mpc8xx/status_led.c b/cpu/mpc8xx/status_led.c deleted file mode 100644 index d8aaeec..0000000 --- a/cpu/mpc8xx/status_led.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <mpc8xx.h> -#include <status_led.h> - -/* - * The purpose of this code is to signal the operational status of a - * target which usually boots over the network; while running in - * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply - * message has been received, the LED is turned off. The Linux - * kernel, once it is running, will start blinking the LED again, - * with another frequency. - */ - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_STATUS_LED - -typedef struct { - ulong mask; - int state; - int period; - int cnt; -} led_dev_t; - -led_dev_t led_dev[] = { - { STATUS_LED_BIT, - STATUS_LED_STATE, - STATUS_LED_PERIOD, - 0, - }, -#if defined(STATUS_LED_BIT1) - { STATUS_LED_BIT1, - STATUS_LED_STATE1, - STATUS_LED_PERIOD1, - 0, - }, -#endif -#if defined(STATUS_LED_BIT2) - { STATUS_LED_BIT2, - STATUS_LED_STATE2, - STATUS_LED_PERIOD2, - 0, - }, -#endif -#if defined(STATUS_LED_BIT3) - { STATUS_LED_BIT3, - STATUS_LED_STATE3, - STATUS_LED_PERIOD3, - 0, - }, -#endif -}; - -#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) - -static int status_led_init_done = 0; - -static void status_led_init (void) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - immr->STATUS_LED_PAR &= ~(ld->mask); -#ifdef STATUS_LED_ODR - immr->STATUS_LED_ODR &= ~(ld->mask); -#endif -#if (STATUS_LED_ACTIVE == 0) - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT &= ~(ld->mask); - else - immr->STATUS_LED_DAT |= ld->mask ; -#else - if (ld->state == STATUS_LED_ON) - immr->STATUS_LED_DAT |= ld->mask ; - else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - immr->STATUS_LED_DIR |= ld->mask ; - } - - status_led_init_done = 1; -} - -void status_led_tick (ulong timestamp) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - int i; - - if (!status_led_init_done) - status_led_init(); - - for (i=0; i<MAX_LED_DEV; ++i) { - led_dev_t *ld = &led_dev[i]; - - if (ld->state != STATUS_LED_BLINKING) - continue; - - if (++(ld->cnt) >= ld->period) { - immr->STATUS_LED_DAT ^= ld->mask; - ld->cnt -= ld->period; - } - } -} - -void status_led_set (int led, int state) -{ - volatile immap_t *immr = (immap_t *)CFG_IMMR; - led_dev_t *ld; - - if (led < 0 || led >= MAX_LED_DEV) - return; - - if (!status_led_init_done) - status_led_init(); - - ld = &led_dev[led]; - - switch (state) { - default: - return; - case STATUS_LED_BLINKING: - ld->cnt = 0; /* always start with full period */ - /* fall through */ /* always start with LED _ON_ */ - case STATUS_LED_ON: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT &= ~(ld->mask); -#else - immr->STATUS_LED_DAT |= ld->mask ; -#endif - break; - case STATUS_LED_OFF: -#if (STATUS_LED_ACTIVE == 0) - immr->STATUS_LED_DAT |= ld->mask ; -#else - immr->STATUS_LED_DAT &= ~(ld->mask); -#endif - break; - } - ld->state = state; -} - -#endif /* CONFIG_STATUS_LED */ |