diff options
Diffstat (limited to 'board/MAI/AmigaOneG3SE/serial.c')
-rw-r--r-- | board/MAI/AmigaOneG3SE/serial.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/board/MAI/AmigaOneG3SE/serial.c b/board/MAI/AmigaOneG3SE/serial.c new file mode 100644 index 0000000..e83fb46 --- /dev/null +++ b/board/MAI/AmigaOneG3SE/serial.c @@ -0,0 +1,247 @@ +#include <common.h> +#include <ns16550.h> +#include "short_types.h" +#include "memio.h" +#include "articiaS.h" + +#ifndef CFG_NS16550 +static uint32 ComPort1; + +uint16 SerialEcho = 1; + + +#define RECEIVER_HOLDING 0 +#define TRANSMITTER_HOLDING 0 +#define INTERRUPT_ENABLE 1 +#define INTERRUPT_STATUS 2 +#define FIFO_CONTROL 2 +#define LINE_CONTROL 3 +#define MODEM_CONTROL 4 +#define LINE_STATUS 5 +#define MODEM_STATUS 6 +#define SCRATCH_PAD 7 + +#define DIVISOR_LATCH_LSB 0 +#define DIVISOR_LATCH_MSB 1 +#define PRESCALER_DIVISION 5 + +#define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte) +#define COM_READ_BYTE(reg) in_byte((ComPort1+reg)) + +static int serial_init_done = 0; + +void serial_init (void) +{ +#if 0 + uint32 clock_divisor = 115200 / baudrate; + uint8 cfg; + uint8 a; + uint16 devfn = 7 << 3; + + if (serial_init_done) + return; + + /* Enter configuration mode */ + cfg = pci_read_cfg_byte (0, devfn, 0x85); + pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02); + + /* Set serial port COM1 as 3F8 */ + out_byte (0x3F0, 0xE7); + out_byte (0x3f1, 0xfe); + + /* Set serial port COM2 as 2F8 */ + out_byte (0x3f0, 0xe8); + out_byte (0x3f1, 0xeb); + + /* Enable */ + out_byte (0x3f0, 0xe2); + a = in_byte (0x3f1); + a |= 0xc; + out_byte (0x3f0, 0xe2); + out_byte (0x3f1, a); + + /* Reset the configuration mode */ + pci_write_cfg_byte (0, devfn, 0x85, cfg); +#endif + + ComPort1 = 0x3F8; + + /* Disable interrupts */ + COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00); + + /* Set baud rate */ + /* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */ + /* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */ + /* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */ + /* __asm("eieio"); */ + + /* Set 8-N-1 */ + COM_WRITE_BYTE (LINE_CONTROL, 0x03); + __asm ("eieio"); + + /* Disable FIFO */ + COM_WRITE_BYTE (MODEM_CONTROL, 0x03); + COM_WRITE_BYTE (FIFO_CONTROL, 0x07); + + __asm ("eieio"); + serial_init_done = 1; +} + +extern int console_changed; + +void serial_putc (const char sendme) +{ + if (sendme == '\n') { + while ((in_byte (0x3FD) & 0x40) == 0); + out_byte (0x3f8, 0x0D); + } + + while ((in_byte (0x3FD) & 0x40) == 0); + out_byte (0x3f8, sendme); +} + +int serial_getc (void) +{ +#if 0 + uint8 c; + + for (;;) { + uint8 x = in_byte (0x3FD); + + if (x & 0x01) + break; + + if (x & 0x0C) + out_byte (0x3fd, 0x0c); + } + + c = in_byte (0x3F8); + + return c; +#else + while ((in_byte (0x3FD) & 0x01) == 0) { + if (console_changed != 0) { + printf ("Console changed\n"); + console_changed = 0; + return 0; + } + } + return in_byte (0x3F8); +#endif +} + +int serial_tstc (void) +{ + return (in_byte (0x03FD) & 0x01) != 0; +} + +void serial_debug_putc (int c) +{ + serial_puts ("DBG"); + serial_putc (c); + serial_putc (0x0d); + serial_putc (0x0A); +} + +#else + +const NS16550_t Com0 = (NS16550_t) CFG_NS16550_COM1; +const NS16550_t Com1 = (NS16550_t) CFG_NS16550_COM2; + +int serial_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + uint32 clock_divisor = 115200 / gd->baudrate; + + NS16550_init (Com0, clock_divisor); + /* NS16550_reinit(Com1, clock_divisor); */ + /* serial_puts("COM1: 3F8h initalized"); */ + + return (0); +} + +#if 0 +void serial_putc (const char c) +{ + NS16550_putc (Com0, c); + if (c == '\n') + NS16550_putc (Com0, 0x0D); +} + +int serial_getc (void) +{ + return (int) NS16550_getc (Com0); +} + +int serial_tstc (void) +{ + return NS16550_tstc (Com0); +} +#else +void serial_putc (const char sendme) +{ + if (sendme == '\n') { + while ((in_byte (0x3FD) & 0x40) == 0); + out_byte (0x3f8, 0x0D); + } + + while ((in_byte (0x3FD) & 0x40) == 0); + out_byte (0x3f8, sendme); +} + + +extern int console_changed; + +int serial_getc (void) +{ +#if 0 + uint8 c; + + for (;;) { + uint8 x = in_byte (0x3FD); + + if (x & 0x01) + break; + + if (x & 0x0C) + out_byte (0x3fd, 0x0c); + } + + c = in_byte (0x3F8); + + return c; +#else + while ((in_byte (0x3FD) & 0x01) == 0) { + if (console_changed != 0) { + console_changed = 0; + return 0; + } + } + + return in_byte (0x3F8); +#endif +} + +int serial_tstc (void) +{ + return (in_byte (0x03FD) & 0x01) != 0; +} +#endif + +#endif + +void serial_puts (const char *string) +{ + while (*string) + serial_putc (*string++); +} + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + uint32 clock_divisor = 115200 / gd->baudrate; + + NS16550_init (Com0, clock_divisor); +} |