forked from luck/tmp_suning_uos_patched
5b3b16880f
These are the rest of the new files needed to add OCTEON processor support to the Linux kernel. Other than Makefile and Kconfig which should be obvious, we have: csrc-octeon.c -- Clock source driver for OCTEON. dma-octeon.c -- Helper functions for mapping DMA memory. flash_setup.c -- Register on-board flash with the MTD subsystem. octeon-irq.c -- OCTEON interrupt controller managment. octeon-memcpy.S -- Optimized memcpy() implementation. serial.c -- Register 8250 platform driver and early console. setup.c -- Early architecture initialization. smp.c -- OCTEON SMP support. octeon_switch.S -- Scheduler context switch for OCTEON. c-octeon.c -- OCTEON cache controller support. cex-oct.S -- OCTEON cache exception handler. asm/mach-cavium-octeon/*.h -- Architecture include files. Signed-off-by: Tomaso Paoletti <tpaoletti@caviumnetworks.com> Signed-off-by: David Daney <ddaney@caviumnetworks.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org> create mode 100644 arch/mips/cavium-octeon/Kconfig create mode 100644 arch/mips/cavium-octeon/Makefile create mode 100644 arch/mips/cavium-octeon/csrc-octeon.c create mode 100644 arch/mips/cavium-octeon/dma-octeon.c create mode 100644 arch/mips/cavium-octeon/flash_setup.c create mode 100644 arch/mips/cavium-octeon/octeon-irq.c create mode 100644 arch/mips/cavium-octeon/octeon-memcpy.S create mode 100644 arch/mips/cavium-octeon/serial.c create mode 100644 arch/mips/cavium-octeon/setup.c create mode 100644 arch/mips/cavium-octeon/smp.c create mode 100644 arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h create mode 100644 arch/mips/include/asm/mach-cavium-octeon/irq.h create mode 100644 arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-cavium-octeon/war.h create mode 100644 arch/mips/include/asm/octeon/octeon.h create mode 100644 arch/mips/kernel/octeon_switch.S create mode 100644 arch/mips/mm/c-octeon.c create mode 100644 arch/mips/mm/cex-oct.S
137 lines
3.5 KiB
C
137 lines
3.5 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (C) 2004-2007 Cavium Networks
|
|
*/
|
|
#include <linux/console.h>
|
|
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/serial.h>
|
|
#include <linux/serial_8250.h>
|
|
#include <linux/serial_reg.h>
|
|
#include <linux/tty.h>
|
|
|
|
#include <asm/time.h>
|
|
|
|
#include <asm/octeon/octeon.h>
|
|
|
|
#ifdef CONFIG_GDB_CONSOLE
|
|
#define DEBUG_UART 0
|
|
#else
|
|
#define DEBUG_UART 1
|
|
#endif
|
|
|
|
unsigned int octeon_serial_in(struct uart_port *up, int offset)
|
|
{
|
|
int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
|
|
if (offset == UART_IIR && (rv & 0xf) == 7) {
|
|
/* Busy interrupt, read the USR (39) and try again. */
|
|
cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
|
|
rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
void octeon_serial_out(struct uart_port *up, int offset, int value)
|
|
{
|
|
/*
|
|
* If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
|
|
* working.
|
|
*/
|
|
if (offset == UART_LCR)
|
|
value &= 0x9f;
|
|
cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
|
|
}
|
|
|
|
/*
|
|
* Allocated in .bss, so it is all zeroed.
|
|
*/
|
|
#define OCTEON_MAX_UARTS 3
|
|
static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1];
|
|
static struct platform_device octeon_uart8250_device = {
|
|
.name = "serial8250",
|
|
.id = PLAT8250_DEV_PLATFORM,
|
|
.dev = {
|
|
.platform_data = octeon_uart8250_data,
|
|
},
|
|
};
|
|
|
|
static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
|
|
{
|
|
p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
|
|
p->type = PORT_OCTEON;
|
|
p->iotype = UPIO_MEM;
|
|
p->regshift = 3; /* I/O addresses are every 8 bytes */
|
|
p->uartclk = mips_hpt_frequency;
|
|
p->serial_in = octeon_serial_in;
|
|
p->serial_out = octeon_serial_out;
|
|
}
|
|
|
|
static int __init octeon_serial_init(void)
|
|
{
|
|
int enable_uart0;
|
|
int enable_uart1;
|
|
int enable_uart2;
|
|
struct plat_serial8250_port *p;
|
|
|
|
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
|
|
/*
|
|
* If we are configured to run as the second of two kernels,
|
|
* disable uart0 and enable uart1. Uart0 is owned by the first
|
|
* kernel
|
|
*/
|
|
enable_uart0 = 0;
|
|
enable_uart1 = 1;
|
|
#else
|
|
/*
|
|
* We are configured for the first kernel. We'll enable uart0
|
|
* if the bootloader told us to use 0, otherwise will enable
|
|
* uart 1.
|
|
*/
|
|
enable_uart0 = (octeon_get_boot_uart() == 0);
|
|
enable_uart1 = (octeon_get_boot_uart() == 1);
|
|
#ifdef CONFIG_KGDB
|
|
enable_uart1 = 1;
|
|
#endif
|
|
#endif
|
|
|
|
/* Right now CN52XX is the only chip with a third uart */
|
|
enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);
|
|
|
|
p = octeon_uart8250_data;
|
|
if (enable_uart0) {
|
|
/* Add a ttyS device for hardware uart 0 */
|
|
octeon_uart_set_common(p);
|
|
p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
|
|
p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
|
|
p->irq = OCTEON_IRQ_UART0;
|
|
p++;
|
|
}
|
|
|
|
if (enable_uart1) {
|
|
/* Add a ttyS device for hardware uart 1 */
|
|
octeon_uart_set_common(p);
|
|
p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
|
|
p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
|
|
p->irq = OCTEON_IRQ_UART1;
|
|
p++;
|
|
}
|
|
if (enable_uart2) {
|
|
/* Add a ttyS device for hardware uart 2 */
|
|
octeon_uart_set_common(p);
|
|
p->membase = (void *) CVMX_MIO_UART2_RBR;
|
|
p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
|
|
p->irq = OCTEON_IRQ_UART2;
|
|
p++;
|
|
}
|
|
|
|
BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
|
|
|
|
return platform_device_register(&octeon_uart8250_device);
|
|
}
|
|
|
|
device_initcall(octeon_serial_init);
|