diff options
-rw-r--r-- | drivers/fpga/spartan3.c | 6 | ||||
-rw-r--r-- | drivers/serial/serial_pl01x.c | 50 | ||||
-rw-r--r-- | drivers/serial/serial_pl01x.h | 41 | ||||
-rw-r--r-- | include/spartan3.h | 1 |
4 files changed, 59 insertions, 39 deletions
diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c index 7a89b56..1dd6f26 100644 --- a/drivers/fpga/spartan3.c +++ b/drivers/fpga/spartan3.c @@ -366,6 +366,8 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) CONFIG_FPGA_DELAY (); if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ puts ("** Timeout waiting for INIT to start.\n"); + if (*fn->abort) + (*fn->abort) (cookie); return FPGA_FAIL; } } while (!(*fn->init) (cookie)); @@ -380,6 +382,8 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) CONFIG_FPGA_DELAY (); if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ puts ("** Timeout waiting for INIT to clear.\n"); + if (*fn->abort) + (*fn->abort) (cookie); return FPGA_FAIL; } } while ((*fn->init) (cookie)); @@ -394,6 +398,8 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) while DONE is low (inactive) */ if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { puts ("** CRC error during FPGA load.\n"); + if (*fn->abort) + (*fn->abort) (cookie); return (FPGA_FAIL); } val = data [bytecount ++]; diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index c0ae947..5dfcde8 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -47,14 +47,20 @@ static int pl01x_tstc (int portnum); unsigned int baudrate = CONFIG_BAUDRATE; DECLARE_GLOBAL_DATA_PTR; +static struct pl01x_regs *pl01x_get_regs(int portnum) +{ + return (struct pl01x_regs *) port[portnum]; +} + #ifdef CONFIG_PL010_SERIAL int serial_init (void) { + struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT); unsigned int divisor; /* First, disable everything */ - writel(0x0, port[CONSOLE_PORT] + UART_PL010_CR); + writel(0, ®s->pl010_cr); /* Set baud rate */ switch (baudrate) { @@ -82,15 +88,14 @@ int serial_init (void) divisor = UART_PL010_BAUD_38400; } - writel(((divisor & 0xf00) >> 8), port[CONSOLE_PORT] + UART_PL010_LCRM); - writel((divisor & 0xff), port[CONSOLE_PORT] + UART_PL010_LCRL); + writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); + writel(divisor & 0xff, ®s->pl010_lcrl); /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */ - writel((UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN), - port[CONSOLE_PORT] + UART_PL010_LCRH); + writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, ®s->pl010_lcrh); /* Finally, enable the UART */ - writel((UART_PL010_CR_UARTEN), port[CONSOLE_PORT] + UART_PL010_CR); + writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); return 0; } @@ -101,13 +106,14 @@ int serial_init (void) int serial_init (void) { + struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT); unsigned int temp; unsigned int divider; unsigned int remainder; unsigned int fraction; /* First, disable everything */ - writel(0x0, port[CONSOLE_PORT] + UART_PL011_CR); + writel(0, ®s->pl011_cr); /* * Set baud rate @@ -121,16 +127,16 @@ int serial_init (void) temp = (8 * remainder) / baudrate; fraction = (temp >> 1) + (temp & 1); - writel(divider, port[CONSOLE_PORT] + UART_PL011_IBRD); - writel(fraction, port[CONSOLE_PORT] + UART_PL011_FBRD); + writel(divider, ®s->pl011_ibrd); + writel(fraction, ®s->pl011_fbrd); /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */ - writel((UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN), - port[CONSOLE_PORT] + UART_PL011_LCRH); + writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN, + ®s->pl011_lcrh); /* Finally, enable the UART */ - writel((UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE), - port[CONSOLE_PORT] + UART_PL011_CR); + writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE, + ®s->pl011_cr); return 0; } @@ -170,28 +176,31 @@ void serial_setbrg (void) static void pl01x_putc (int portnum, char c) { + struct pl01x_regs *regs = pl01x_get_regs(portnum); + /* Wait until there is space in the FIFO */ - while (readl(port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF) + while (readl(®s->fr) & UART_PL01x_FR_TXFF) WATCHDOG_RESET(); /* Send the character */ - writel(c, port[portnum] + UART_PL01x_DR); + writel(c, ®s->dr); } static int pl01x_getc (int portnum) { + struct pl01x_regs *regs = pl01x_get_regs(portnum); unsigned int data; /* Wait until there is data in the FIFO */ - while (readl(port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE) + while (readl(®s->fr) & UART_PL01x_FR_RXFE) WATCHDOG_RESET(); - data = readl(port[portnum] + UART_PL01x_DR); + data = readl(®s->dr); /* Check for an error flag */ if (data & 0xFFFFFF00) { /* Clear the error */ - writel(0xFFFFFFFF, port[portnum] + UART_PL01x_ECR); + writel(0xFFFFFFFF, ®s->ecr); return -1; } @@ -200,7 +209,8 @@ static int pl01x_getc (int portnum) static int pl01x_tstc (int portnum) { + struct pl01x_regs *regs = pl01x_get_regs(portnum); + WATCHDOG_RESET(); - return !(readl(port[portnum] + UART_PL01x_FR) & - UART_PL01x_FR_RXFE); + return !(readl(®s->fr) & UART_PL01x_FR_RXFE); } diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h index 5f20fdd..b670c24 100644 --- a/drivers/serial/serial_pl01x.h +++ b/drivers/serial/serial_pl01x.h @@ -29,10 +29,28 @@ * Definitions common to both PL010 & PL011 * */ -#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ -#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ -#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ -#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ + +#ifndef __ASSEMBLY__ +/* + * We can use a combined structure for PL010 and PL011, because they overlap + * only in common registers. + */ +struct pl01x_regs { + u32 dr; /* 0x00 Data register */ + u32 ecr; /* 0x04 Error clear register (Write) */ + u32 pl010_lcrh; /* 0x08 Line control register, high byte */ + u32 pl010_lcrm; /* 0x0C Line control register, middle byte */ + u32 pl010_lcrl; /* 0x10 Line control register, low byte */ + u32 pl010_cr; /* 0x14 Control register */ + u32 fr; /* 0x18 Flag register (Read only) */ + u32 reserved; + u32 ilpr; /* 0x20 IrDA low-power counter register */ + u32 pl011_ibrd; /* 0x24 Integer baud rate register */ + u32 pl011_fbrd; /* 0x28 Fractional baud rate register */ + u32 pl011_lcrh; /* 0x2C Line control register */ + u32 pl011_cr; /* 0x30 Control register */ +}; +#endif #define UART_PL01x_RSR_OE 0x08 #define UART_PL01x_RSR_BE 0x04 @@ -50,14 +68,6 @@ * PL010 definitions * */ -#define UART_PL010_LCRH 0x08 /* Line control register, high byte. */ -#define UART_PL010_LCRM 0x0C /* Line control register, middle byte. */ -#define UART_PL010_LCRL 0x10 /* Line control register, low byte. */ -#define UART_PL010_CR 0x14 /* Control register. */ -#define UART_PL010_IIR 0x1C /* Interrupt indentification register (Read). */ -#define UART_PL010_ICR 0x1C /* Interrupt clear register (Write). */ -#define UART_PL010_ILPR 0x20 /* IrDA low power counter register. */ - #define UART_PL010_CR_LPE (1 << 7) #define UART_PL010_CR_RTIE (1 << 6) #define UART_PL010_CR_TIE (1 << 5) @@ -93,13 +103,6 @@ * PL011 definitions * */ -#define UART_PL011_IBRD 0x24 -#define UART_PL011_FBRD 0x28 -#define UART_PL011_LCRH 0x2C -#define UART_PL011_CR 0x30 -#define UART_PL011_IMSC 0x38 -#define UART_PL011_PERIPH_ID0 0xFE0 - #define UART_PL011_LCRH_SPS (1 << 7) #define UART_PL011_LCRH_WLEN_8 (3 << 5) #define UART_PL011_LCRH_WLEN_7 (2 << 5) diff --git a/include/spartan3.h b/include/spartan3.h index d5a589d..0f0b400 100644 --- a/include/spartan3.h +++ b/include/spartan3.h @@ -58,6 +58,7 @@ typedef struct { Xilinx_wr_fn wr; Xilinx_post_fn post; Xilinx_bwr_fn bwr; /* block write function */ + Xilinx_abort_fn abort; } Xilinx_Spartan3_Slave_Serial_fns; /* Device Image Sizes |