1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2004-2007 Cavium Networks 7 */ 8#include <linux/console.h> 9#include <linux/module.h> 10#include <linux/init.h> 11#include <linux/platform_device.h> 12#include <linux/serial.h> 13#include <linux/serial_8250.h> 14#include <linux/serial_reg.h> 15#include <linux/tty.h> 16 17#include <asm/time.h> 18 19#include <asm/octeon/octeon.h> 20 21#define DEBUG_UART 1 22 23unsigned int octeon_serial_in(struct uart_port *up, int offset) 24{ 25 int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); 26 if (offset == UART_IIR && (rv & 0xf) == 7) { 27 /* Busy interrupt, read the USR (39) and try again. */ 28 cvmx_read_csr((uint64_t)(up->membase + (39 << 3))); 29 rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3))); 30 } 31 return rv; 32} 33 34void octeon_serial_out(struct uart_port *up, int offset, int value) 35{ 36 /* 37 * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits 38 * working. 39 */ 40 if (offset == UART_LCR) 41 value &= 0x9f; 42 cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value); 43} 44 45/* 46 * Allocated in .bss, so it is all zeroed. 47 */ 48#define OCTEON_MAX_UARTS 3 49static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1]; 50static struct platform_device octeon_uart8250_device = { 51 .name = "serial8250", 52 .id = PLAT8250_DEV_PLATFORM, 53 .dev = { 54 .platform_data = octeon_uart8250_data, 55 }, 56}; 57 58static void __init octeon_uart_set_common(struct plat_serial8250_port *p) 59{ 60 p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; 61 p->type = PORT_OCTEON; 62 p->iotype = UPIO_MEM; 63 p->regshift = 3; /* I/O addresses are every 8 bytes */ 64 if (octeon_is_simulation()) 65 /* Make simulator output fast*/ 66 p->uartclk = 115200 * 16; 67 else 68 p->uartclk = mips_hpt_frequency; 69 p->serial_in = octeon_serial_in; 70 p->serial_out = octeon_serial_out; 71} 72 73static int __init octeon_serial_init(void) 74{ 75 int enable_uart0; 76 int enable_uart1; 77 int enable_uart2; 78 struct plat_serial8250_port *p; 79 80#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL 81 /* 82 * If we are configured to run as the second of two kernels, 83 * disable uart0 and enable uart1. Uart0 is owned by the first 84 * kernel 85 */ 86 enable_uart0 = 0; 87 enable_uart1 = 1; 88#else 89 /* 90 * We are configured for the first kernel. We'll enable uart0 91 * if the bootloader told us to use 0, otherwise will enable 92 * uart 1. 93 */ 94 enable_uart0 = (octeon_get_boot_uart() == 0); 95 enable_uart1 = (octeon_get_boot_uart() == 1); 96#ifdef CONFIG_KGDB 97 enable_uart1 = 1; 98#endif 99#endif 100 101 /* Right now CN52XX is the only chip with a third uart */ 102 enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX); 103 104 p = octeon_uart8250_data; 105 if (enable_uart0) { 106 /* Add a ttyS device for hardware uart 0 */ 107 octeon_uart_set_common(p); 108 p->membase = (void *) CVMX_MIO_UARTX_RBR(0); 109 p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1); 110 p->irq = OCTEON_IRQ_UART0; 111 p++; 112 } 113 114 if (enable_uart1) { 115 /* Add a ttyS device for hardware uart 1 */ 116 octeon_uart_set_common(p); 117 p->membase = (void *) CVMX_MIO_UARTX_RBR(1); 118 p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1); 119 p->irq = OCTEON_IRQ_UART1; 120 p++; 121 } 122 if (enable_uart2) { 123 /* Add a ttyS device for hardware uart 2 */ 124 octeon_uart_set_common(p); 125 p->membase = (void *) CVMX_MIO_UART2_RBR; 126 p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1); 127 p->irq = OCTEON_IRQ_UART2; 128 p++; 129 } 130 131 BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]); 132 133 return platform_device_register(&octeon_uart8250_device); 134} 135 136device_initcall(octeon_serial_init); 137