Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / powerpc / cpu / mpc5xxx / serial.c
diff --git a/qemu/roms/u-boot/arch/powerpc/cpu/mpc5xxx/serial.c b/qemu/roms/u-boot/arch/powerpc/cpu/mpc5xxx/serial.c
new file mode 100644 (file)
index 0000000..cb5b0bf
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * (C) Copyright 2000 - 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
+ * changes based on the file arch/powerpc/mbxboot/m8260_tty.c from the
+ * Linux/PPC sources (m8260_tty.c had no copyright info in it).
+ *
+ * Martin Krause, 8 Jun 2006
+ * Added SERIAL_MULTI support
+ */
+
+/*
+ * Minimal serial functions needed to use one of the PSC ports
+ * as serial console interface.
+ */
+
+#include <common.h>
+#include <linux/compiler.h>
+#include <mpc5xxx.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_PSC_CONSOLE)
+
+#if CONFIG_PSC_CONSOLE == 1
+#define PSC_BASE MPC5XXX_PSC1
+#elif CONFIG_PSC_CONSOLE == 2
+#define PSC_BASE MPC5XXX_PSC2
+#elif CONFIG_PSC_CONSOLE == 3
+#define PSC_BASE MPC5XXX_PSC3
+#elif CONFIG_PSC_CONSOLE == 4
+#define PSC_BASE MPC5XXX_PSC4
+#elif CONFIG_PSC_CONSOLE == 5
+#define PSC_BASE MPC5XXX_PSC5
+#elif CONFIG_PSC_CONSOLE == 6
+#define PSC_BASE MPC5XXX_PSC6
+#else
+#error CONFIG_PSC_CONSOLE must be in 1 ... 6
+#endif
+
+#if defined(CONFIG_PSC_CONSOLE2)
+
+#if CONFIG_PSC_CONSOLE2 == 1
+#define PSC_BASE2 MPC5XXX_PSC1
+#elif CONFIG_PSC_CONSOLE2 == 2
+#define PSC_BASE2 MPC5XXX_PSC2
+#elif CONFIG_PSC_CONSOLE2 == 3
+#define PSC_BASE2 MPC5XXX_PSC3
+#elif CONFIG_PSC_CONSOLE2 == 4
+#define PSC_BASE2 MPC5XXX_PSC4
+#elif CONFIG_PSC_CONSOLE2 == 5
+#define PSC_BASE2 MPC5XXX_PSC5
+#elif CONFIG_PSC_CONSOLE2 == 6
+#define PSC_BASE2 MPC5XXX_PSC6
+#else
+#error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
+#endif
+
+#endif
+
+int serial_init_dev (unsigned long dev_base)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+       unsigned long baseclk;
+       int div;
+
+       /* reset PSC */
+       psc->command = PSC_SEL_MODE_REG_1;
+
+       /* select clock sources */
+       psc->psc_clock_select = 0;
+       baseclk = (gd->arch.ipb_clk + 16) / 32;
+
+       /* switch to UART mode */
+       psc->sicr = 0;
+
+       /* configure parity, bit length and so on */
+       psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
+       psc->mode = PSC_MODE_ONE_STOP;
+
+       /* set up UART divisor */
+       div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
+       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);
+}
+
+void serial_putc_dev (unsigned long dev_base, const char c)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+
+       if (c == '\n')
+               serial_putc_dev (dev_base, '\r');
+
+       /* Wait for last character to go. */
+       while (!(psc->psc_status & PSC_SR_TXEMP))
+               ;
+
+       psc->psc_buffer_8 = c;
+}
+
+void serial_putc_raw_dev(unsigned long dev_base, const char c)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+       /* Wait for last character to go. */
+       while (!(psc->psc_status & PSC_SR_TXEMP))
+               ;
+
+       psc->psc_buffer_8 = c;
+}
+
+
+void serial_puts_dev (unsigned long dev_base, const char *s)
+{
+       while (*s) {
+               serial_putc_dev (dev_base, *s++);
+       }
+}
+
+int serial_getc_dev (unsigned long dev_base)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+
+       /* Wait for a character to arrive. */
+       while (!(psc->psc_status & PSC_SR_RXRDY))
+               ;
+
+       return psc->psc_buffer_8;
+}
+
+int serial_tstc_dev (unsigned long dev_base)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+
+       return (psc->psc_status & PSC_SR_RXRDY);
+}
+
+void serial_setbrg_dev (unsigned long dev_base)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+       unsigned long baseclk, div;
+
+       baseclk = (gd->arch.ipb_clk + 16) / 32;
+
+       /* set up UART divisor */
+       div = (baseclk + (gd->baudrate/2)) / gd->baudrate;
+       psc->ctur = (div >> 8) & 0xFF;
+       psc->ctlr =  div & 0xff;
+}
+
+void serial_setrts_dev (unsigned long dev_base, int s)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+
+       if (s) {
+               /* Assert RTS (become LOW) */
+               psc->op1 = 0x1;
+       }
+       else {
+               /* Negate RTS (become HIGH) */
+               psc->op0 = 0x1;
+       }
+}
+
+int serial_getcts_dev (unsigned long dev_base)
+{
+       volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+
+       return (psc->ip & 0x1) ? 0 : 1;
+}
+
+int serial0_init(void)
+{
+       return (serial_init_dev(PSC_BASE));
+}
+
+void serial0_setbrg (void)
+{
+       serial_setbrg_dev(PSC_BASE);
+}
+
+void serial0_putc(const char c)
+{
+       serial_putc_dev(PSC_BASE,c);
+}
+
+void serial0_puts(const char *s)
+{
+       serial_puts_dev(PSC_BASE, s);
+}
+
+int serial0_getc(void)
+{
+       return(serial_getc_dev(PSC_BASE));
+}
+
+int serial0_tstc(void)
+{
+       return (serial_tstc_dev(PSC_BASE));
+}
+
+struct serial_device serial0_device =
+{
+       .name   = "serial0",
+       .start  = serial0_init,
+       .stop   = NULL,
+       .setbrg = serial0_setbrg,
+       .getc   = serial0_getc,
+       .tstc   = serial0_tstc,
+       .putc   = serial0_putc,
+       .puts   = serial0_puts,
+};
+
+__weak struct serial_device *default_serial_console(void)
+{
+       return &serial0_device;
+}
+
+#ifdef CONFIG_PSC_CONSOLE2
+int serial1_init(void)
+{
+       return serial_init_dev(PSC_BASE2);
+}
+
+void serial1_setbrg(void)
+{
+       serial_setbrg_dev(PSC_BASE2);
+}
+
+void serial1_putc(const char c)
+{
+       serial_putc_dev(PSC_BASE2, c);
+}
+
+void serial1_puts(const char *s)
+{
+       serial_puts_dev(PSC_BASE2, s);
+}
+
+int serial1_getc(void)
+{
+       return serial_getc_dev(PSC_BASE2);
+}
+
+int serial1_tstc(void)
+{
+       return serial_tstc_dev(PSC_BASE2);
+}
+
+struct serial_device serial1_device =
+{
+       .name   = "serial1",
+       .start  = serial1_init,
+       .stop   = NULL,
+       .setbrg = serial1_setbrg,
+       .getc   = serial1_getc,
+       .tstc   = serial1_tstc,
+       .putc   = serial1_putc,
+       .puts   = serial1_puts,
+};
+#endif /* CONFIG_PSC_CONSOLE2 */
+
+#endif /* CONFIG_PSC_CONSOLE */