u-boot/board/MAI/AmigaOneG3SE/serial.c

246 lines
4.0 KiB
C

#include <common.h>
#include <ns16550.h>
#include "short_types.h"
#include "memio.h"
#include "articiaS.h"
DECLARE_GLOBAL_DATA_PTR;
#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)
{
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)
{
uint32 clock_divisor = 115200 / gd->baudrate;
NS16550_init (Com0, clock_divisor);
}