X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fps2ser.c;h=8aea8fd44a31d2316e049d5517b899113e720ed8;hb=f0e3d2b42268a9ed8d28c50c662eeba08379ceab;hp=71658d7ca0a9c8649fa0e98c52a7d9c11fcaab0c;hpb=1c43771ba888bb9260692636d645fb2d73390a4b;p=u-boot diff --git a/drivers/ps2ser.c b/drivers/ps2ser.c index 71658d7ca0..8aea8fd44a 100644 --- a/drivers/ps2ser.c +++ b/drivers/ps2ser.c @@ -20,22 +20,123 @@ #include #include #include +#ifdef CFG_NS16550 +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; /* #define DEBUG */ #define PS2SER_BAUD 57600 +#ifdef CONFIG_MPC5xxx +#if CONFIG_PS2SERIAL == 1 +#define PSC_BASE MPC5XXX_PSC1 +#elif CONFIG_PS2SERIAL == 2 +#define PSC_BASE MPC5XXX_PSC2 +#elif CONFIG_PS2SERIAL == 3 +#define PSC_BASE MPC5XXX_PSC3 +#elif defined(CONFIG_MGT5100) +#error CONFIG_PS2SERIAL must be in 1, 2 or 3 +#elif CONFIG_PS2SERIAL == 4 +#define PSC_BASE MPC5XXX_PSC4 +#elif CONFIG_PS2SERIAL == 5 +#define PSC_BASE MPC5XXX_PSC5 +#elif CONFIG_PS2SERIAL == 6 +#define PSC_BASE MPC5XXX_PSC6 +#else +#error CONFIG_PS2SERIAL must be in 1 ... 6 +#endif + +#elif defined(CONFIG_MPC85xx) + +#if CONFIG_PS2SERIAL == 1 +#define COM_BASE (CFG_CCSRBAR+0x4500) +#elif CONFIG_PS2SERIAL == 2 +#define COM_BASE (CFG_CCSRBAR+0x4600) +#else +#error CONFIG_PS2SERIAL must be in 1 ... 2 +#endif + +#endif /* CONFIG_MPC5xxx / CONFIG_MPC85xx */ + static int ps2ser_getc_hw(void); static void ps2ser_interrupt(void *dev_id); extern struct serial_state rs_table[]; /* in serial.c */ -static struct serial_state *state = rs_table + CONFIG_PS2SERIAL; +#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC85xx) +static struct serial_state *state; +#endif static u_char ps2buf[PS2BUF_SIZE]; static atomic_t ps2buf_cnt; static int ps2buf_in_idx; static int ps2buf_out_idx; +#ifdef CONFIG_MPC5xxx +int ps2ser_init(void) +{ + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; + unsigned long baseclk; + int div; + + /* reset PSC */ + psc->command = PSC_SEL_MODE_REG_1; + + /* select clock sources */ +#if defined(CONFIG_MGT5100) + psc->psc_clock_select = 0xdd00; + baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32; +#elif defined(CONFIG_MPC5200) + psc->psc_clock_select = 0; + baseclk = (gd->ipb_clk + 16) / 32; +#endif + + /* switch to UART mode */ + psc->sicr = 0; + + /* configure parity, bit length and so on */ +#if defined(CONFIG_MGT5100) + psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE; +#elif defined(CONFIG_MPC5200) + psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; +#endif + psc->mode = PSC_MODE_ONE_STOP; + + /* set up UART divisor */ + div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD; + psc->ctur = (div >> 8) & 0xff; + psc->ctlr = div & 0xff; + + /* disable all interrupts */ + psc->psc_imr = 0; + + /* reset and enable Rx/Tx */ + psc->command = PSC_RST_RX; + psc->command = PSC_RST_TX; + psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; + + return (0); +} + +#elif defined(CONFIG_MPC85xx) +int ps2ser_init(void) +{ + NS16550_t com_port = (NS16550_t)COM_BASE; + + com_port->ier = 0x00; + com_port->lcr = LCR_BKSE | LCR_8N1; + com_port->dll = (CFG_NS16550_CLK / 16 / PS2SER_BAUD) & 0xff; + com_port->dlm = ((CFG_NS16550_CLK / 16 / PS2SER_BAUD) >> 8) & 0xff; + com_port->lcr = LCR_8N1; + com_port->mcr = (MCR_DTR | MCR_RTS); + com_port->fcr = (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR); + + return (0); +} + +#else /* !CONFIG_MPC5xxx && !CONFIG_MPC85xx */ static inline unsigned int ps2ser_in(int offset) { @@ -49,8 +150,13 @@ static inline void ps2ser_out(int offset, int value) int ps2ser_init(void) { - int quot = state->baud_base / PS2SER_BAUD; - unsigned cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */ + int quot; + unsigned cval; + + state = rs_table + CONFIG_PS2SERIAL; + + quot = state->baud_base / PS2SER_BAUD; + cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */ /* Set speed, enable interrupts, enable FIFO */ @@ -74,25 +180,55 @@ int ps2ser_init(void) return 0; } +#endif /* CONFIG_MPC5xxx / CONFIG_MPC85xx / other */ void ps2ser_putc(int chr) { +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC85xx) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif #ifdef DEBUG printf(">>>> 0x%02x\n", chr); #endif +#ifdef CONFIG_MPC5xxx + while (!(psc->psc_status & PSC_SR_TXRDY)); + + psc->psc_buffer_8 = chr; +#elif defined(CONFIG_MPC85xx) + while ((com_port->lsr & LSR_THRE) == 0); + com_port->thr = chr; +#else while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE)); ps2ser_out(UART_TX, chr); +#endif } static int ps2ser_getc_hw(void) { +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC85xx) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif int res = -1; +#ifdef CONFIG_MPC5xxx + if (psc->psc_status & PSC_SR_RXRDY) { + res = (psc->psc_buffer_8); + } +#elif defined(CONFIG_MPC85xx) + if (com_port->lsr & LSR_DR) { + res = com_port->rbr; + } +#else if (ps2ser_in(UART_LSR) & UART_LSR_DR) { res = (ps2ser_in(UART_RX)); } +#endif return res; } @@ -141,12 +277,23 @@ int ps2ser_check(void) static void ps2ser_interrupt(void *dev_id) { +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC85xx) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif int chr; - int iir; + int status; do { chr = ps2ser_getc_hw(); - iir = ps2ser_in(UART_IIR); +#ifdef CONFIG_MPC5xxx + status = psc->psc_status; +#elif defined(CONFIG_MPC85xx) + status = com_port->lsr; +#else + status = ps2ser_in(UART_IIR); +#endif if (chr < 0) continue; if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) { @@ -156,7 +303,13 @@ static void ps2ser_interrupt(void *dev_id) } else { printf ("ps2ser.c: buffer overflow\n"); } - } while (iir & UART_IIR_RDI); +#ifdef CONFIG_MPC5xxx + } while (status & PSC_SR_RXRDY); +#elif defined(CONFIG_MPC85xx) + } while (status & LSR_DR); +#else + } while (status & UART_IIR_RDI); +#endif if (atomic_read(&ps2buf_cnt)) { ps2mult_callback(atomic_read(&ps2buf_cnt));