diff options
38 files changed, 2876 insertions, 3 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4ef015f..f6b25ae 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -489,6 +489,16 @@ config HYPERTRANSPORT bool "Hypertransport Support for PMC-Sierra Yosemite" depends on PMC_YOSEMITE +config PNX8550_V2PCI + bool "Support for Philips PNX8550 based Viper2-PCI board" + select PNX8550 + select SYS_SUPPORTS_LITTLE_ENDIAN + +config PNX8550_JBS + bool "Support for Philips PNX8550 based JBS board" + select PNX8550 + select SYS_SUPPORTS_LITTLE_ENDIAN + config DDB5074 bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -827,6 +837,7 @@ config TOSHIBA_FPCIB0 source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" +source "arch/mips/philips/pnx8550/common/Kconfig" config RWSEM_GENERIC_SPINLOCK bool @@ -954,6 +965,16 @@ config ITE_BOARD_GEN depends on MIPS_IVR || MIPS_ITE8172 default y +config PNX8550 + bool + select SOC_PNX8550 + +config SOC_PNX8550 + bool + select SYS_SUPPORTS_32BIT_KERNEL + select DMA_NONCOHERENT + select HW_HAS_PCI + config SWAP_IO_SPACE bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6780d11..d62787a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -228,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000) += \ $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ -Wa,--trap + cflags-$(CONFIG_CPU_SB1) += \ $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ -Wa,--trap @@ -561,6 +562,19 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000 load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000 # +# Common Philips PNX8550 +# +core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/ +cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550 + +# +# Philips PNX8550 JBS board +# +libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/ +#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550 +load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000 + +# # SGI IP22 (Indy/Indigo2) # # Set the load address to >= 0xffffffff88069000 if you want to leave space for diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 844126b..70c8ad9 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -121,6 +121,7 @@ static inline void check_wait(void) case CPU_24K: case CPU_25KF: case CPU_34K: + case CPU_PR4450: cpu_wait = r4k_wait; printk(" available.\n"); break; @@ -624,6 +625,21 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) } } +static inline void cpu_probe_philips(struct cpuinfo_mips *c) +{ + decode_configs(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_PR4450: + c->cputype = CPU_PR4450; + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + panic("Unknown Philips Core!"); /* REVISIT: die? */ + break; + } +} + + __init void cpu_probe(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -649,6 +665,9 @@ __init void cpu_probe(void) case PRID_COMP_SANDCRAFT: cpu_probe_sandcraft(c); break; + case PRID_COMP_PHILIPS: + cpu_probe_philips(c); + break; default: c->cputype = CPU_UNKNOWN; } diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 1bd40af..e46a92d 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -80,7 +80,8 @@ static const char *cpu_name[] = { [CPU_VR4133] = "NEC VR4133", [CPU_VR4181] = "NEC VR4181", [CPU_VR4181A] = "NEC VR4181A", - [CPU_SR71000] = "Sandcraft SR71000" + [CPU_SR71000] = "Sandcraft SR71000", + [CPU_PR4450] = "Philips PR4450", }; diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index fbc153c8..a24651d 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,6 +11,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> @@ -112,8 +113,10 @@ static void c0_timer_ack(void) { unsigned int count; +#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */ /* Ack this timer interrupt and set the next one. */ expirelo += cycles_per_jiffy; +#endif write_c0_compare(expirelo); /* Check to see if we have missed any timer interrupts. */ diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index c1d394d..a876ed6 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -844,6 +844,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l, case CPU_AU1500: case CPU_AU1550: case CPU_AU1200: + case CPU_PR4450: i_nop(p); tlbw(p); break; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 83d81c9..ea8438b 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o +obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c new file mode 100644 index 0000000..4256b3b --- /dev/null +++ b/arch/mips/pci/fixup-pnx8550.c @@ -0,0 +1,57 @@ +/* + * Philips PNX8550 pci fixups. + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddealley.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/mach-pnx8550/pci.h> +#include <asm/mach-pnx8550/int.h> + + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +extern char irq_tab_jbs[][5]; + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* no need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return irq_tab_jbs[slot][pin]; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c new file mode 100644 index 0000000..454b65c --- /dev/null +++ b/arch/mips/pci/ops-pnx8550.c @@ -0,0 +1,284 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * + * 2.6 port, Embedded Alley Solutions, Inc + * + * Based on: + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/vmalloc.h> +#include <linux/delay.h> + +#include <asm/mach-pnx8550/pci.h> +#include <asm/mach-pnx8550/glb.h> +#include <asm/debug.h> + + +static inline void clear_status(void) +{ + unsigned long pci_stat; + + pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS); + outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR); +} + +static inline unsigned int +calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where) +{ + unsigned int addr; + + addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0); + addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc); + + return addr; +} + +static int +config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val) +{ + unsigned int flags; + unsigned long loops = 0; + unsigned long ioaddr = calc_cfg_addr(bus, devfn, where); + + local_irq_save(flags); + /*Clear pending interrupt status */ + if (inl(PCI_BASE | PCI_GPPM_STATUS)) { + clear_status(); + while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ; + } + + outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR); + + if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE)) + outl(*val, PCI_BASE | PCI_GPPM_WDAT); + + outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK), + PCI_BASE | PCI_GPPM_CTRL); + + loops = + ((loops_per_jiffy * + PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT)); + while (1) { + if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) { + if ((pci_cmd == PCI_CMD_IOR) || + (pci_cmd == PCI_CMD_CONFIG_READ)) + *val = inl(PCI_BASE | PCI_GPPM_RDAT); + clear_status(); + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) { + break; + } + + loops--; + if (loops == 0) { + printk("%s : Arbiter Locked.\n", __FUNCTION__); + } + } + + clear_status(); + if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) { + printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n", + __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr, + pci_cmd); + } + + if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ)) + *val = 0xffffffff; + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int +read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val) +{ + unsigned int data = 0; + int err; + + if (bus == 0) + return -1; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data); + switch (where & 0x03) { + case 0: + *val = (unsigned char)(data & 0x000000ff); + break; + case 1: + *val = (unsigned char)((data & 0x0000ff00) >> 8); + break; + case 2: + *val = (unsigned char)((data & 0x00ff0000) >> 16); + break; + case 3: + *val = (unsigned char)((data & 0xff000000) >> 24); + break; + } + + return err; +} + +static int +read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val) +{ + unsigned int data = 0; + int err; + + if (bus == 0) + return -1; + + if (where & 0x01) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data); + switch (where & 0x02) { + case 0: + *val = (unsigned short)(data & 0x0000ffff); + break; + case 2: + *val = (unsigned short)((data & 0xffff0000) >> 16); + break; + } + + return err; +} + +static int +read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val) +{ + int err; + if (bus == 0) + return -1; + + if (where & 0x03) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val); + + return err; +} + +static int +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val) +{ + unsigned int data = (unsigned int)val; + int err; + + if (bus == 0) + return -1; + + switch (where & 0x03) { + case 1: + data = (data << 8); + break; + case 2: + data = (data << 16); + break; + case 3: + data = (data << 24); + break; + default: + break; + } + + err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data); + + return err; +} + +static int +write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val) +{ + unsigned int data = (unsigned int)val; + int err; + + if (bus == 0) + return -1; + + if (where & 0x01) + return PCIBIOS_BAD_REGISTER_NUMBER; + + switch (where & 0x02) { + case 2: + data = (data << 16); + break; + default: + break; + } + err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data); + + return err; +} + +static int +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val) +{ + int err; + if (bus == 0) + return -1; + + if (where & 0x03) + return PCIBIOS_BAD_REGISTER_NUMBER; + + err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val); + + return err; +} + +static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) +{ + switch (size) { + case 1: { + u8 _val; + int rc = read_config_byte(bus, devfn, where, &_val); + *val = _val; + return rc; + } + case 2: { + u16 _val; + int rc = read_config_word(bus, devfn, where, &_val); + *val = _val; + return rc; + } + default: + return read_config_dword(bus, devfn, where, val); + } +} + +static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + switch (size) { + case 1: + return write_config_byte(bus, devfn, where, (u8) val); + case 2: + return write_config_word(bus, devfn, where, (u16) val); + default: + return write_config_dword(bus, devfn, where, val); + } +} + +struct pci_ops pnx8550_pci_ops = { + config_read, + config_write +}; diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig new file mode 100644 index 0000000..072572d --- /dev/null +++ b/arch/mips/philips/pnx8550/common/Kconfig @@ -0,0 +1 @@ +# Place holder diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile new file mode 100644 index 0000000..6e38f3b --- /dev/null +++ b/arch/mips/philips/pnx8550/common/Makefile @@ -0,0 +1,27 @@ +# +# Per Hallsmark, per.hallsmark@mvista.com +# +# ######################################################################## +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# ####################################################################### +# +# Makefile for the PNX8550 specific kernel interface routines +# under Linux. +# + +obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_KGDB) += gdb_hook.o diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c new file mode 100644 index 0000000..ad4624f --- /dev/null +++ b/arch/mips/philips/pnx8550/common/gdb_hook.c @@ -0,0 +1,109 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * This is the interface to the remote debugger stub. + * + */ +#include <linux/types.h> +#include <linux/serial.h> +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <linux/serial_ip3106.h> + +#include <asm/serial.h> +#include <asm/io.h> + +#include <uart.h> + +static struct serial_state rs_table[IP3106_NR_PORTS] = { +}; +static struct async_struct kdb_port_info = {0}; + +void rs_kgdb_hook(int tty_no) +{ + struct serial_state *ser = &rs_table[tty_no]; + + kdb_port_info.state = ser; + kdb_port_info.magic = SERIAL_MAGIC; + kdb_port_info.port = tty_no; + kdb_port_info.flags = ser->flags; + + /* + * Clear all interrupts + */ + /* Clear all the transmitter FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST; + /* Clear all the receiver FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST; + /* Clear all interrupts */ + ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX | + IP3106_UART_INT_ALLTX; + + /* + * Now, initialize the UART + */ + ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT; + ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud +} + +int putDebugChar(char c) +{ + /* Wait until FIFO not full */ + while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16) + ; + /* Send one char */ + ip3106_fifo(UART_BASE, kdb_port_info.port) = c; + + return 1; +} + +char getDebugChar(void) +{ + char ch; + + /* Wait until there is a char in the FIFO */ + while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) & + IP3106_UART_FIFO_RXFIFO) >> 8)) + ; + /* Read one char */ + ch = ip3106_fifo(UART_BASE, kdb_port_info.port) & + IP3106_UART_FIFO_RBRTHR; + /* Advance the RX FIFO read pointer */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT; + return (ch); +} + +void rs_disable_debug_interrupts(void) +{ + ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */ +} + +void rs_enable_debug_interrupts(void) +{ + /* Clear all the transmitter FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST; + /* Clear all the receiver FIFO counters (pointer and status) */ + ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST; + /* Clear all interrupts */ + ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX | + IP3106_UART_INT_ALLTX; + ip3106_ien(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */ +} diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c new file mode 100644 index 0000000..5461449 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/int.c @@ -0,0 +1,293 @@ +/* + * + * Copyright (C) 2005 Embedded Alley Solutions, Inc + * Ported to 2.6. + * + * Per Hallsmark, per.hallsmark@mvista.com + * Copyright (C) 2000, 2001 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * + * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/random.h> +#include <linux/module.h> + +#include <asm/io.h> +#include <asm/gdb-stub.h> +#include <int.h> +#include <uart.h> + +extern asmlinkage void cp0_irqdispatch(void); + +static DEFINE_SPINLOCK(irq_lock); + +/* default prio for interrupts */ +/* first one is a no-no so therefore always prio 0 (disabled) */ +static char gic_prio[PNX8550_INT_GIC_TOTINT] = { + 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69 + 1 // 70 +}; + +void hw0_irqdispatch(int irq, struct pt_regs *regs) +{ + /* find out which interrupt */ + irq = PNX8550_GIC_VECTOR_0 >> 3; + + if (irq == 0) { + printk("hw0_irqdispatch: irq 0, spurious interrupt?\n"); + return; + } + do_IRQ(PNX8550_INT_GIC_MIN + irq, regs); +} + + +void timer_irqdispatch(int irq, struct pt_regs *regs) +{ + irq = (0x01c0 & read_c0_config7()) >> 6; + + if (irq == 0) { + printk("timer_irqdispatch: irq 0, spurious interrupt?\n"); + return; + } + + if (irq & 0x1) { + do_IRQ(PNX8550_INT_TIMER1, regs); + } + if (irq & 0x2) { + do_IRQ(PNX8550_INT_TIMER2, regs); + } + if (irq & 0x4) { + do_IRQ(PNX8550_INT_TIMER3, regs); + } +} + +static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) +{ + unsigned long status = read_c0_status(); + + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + + write_c0_status(status); +} + +static inline void mask_gic_int(unsigned int irq_nr) +{ + /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */ + PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */ +} + +static inline void unmask_gic_int(unsigned int irq_nr) +{ + /* set prio mask to lower four bits and enable interrupt */ + PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr]; +} + +static inline void mask_irq(unsigned int irq_nr) +{ + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { + modify_cp0_intmask(1 << irq_nr, 0); + } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_GIC_MAX)) { + mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN); + } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_TIMER_MAX)) { + modify_cp0_intmask(1 << 7, 0); + } else { + printk("mask_irq: irq %d doesn't exist!\n", irq_nr); + } +} + +static inline void unmask_irq(unsigned int irq_nr) +{ + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { + modify_cp0_intmask(0, 1 << irq_nr); + } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_GIC_MAX)) { + unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN); + } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) && + (irq_nr <= PNX8550_INT_TIMER_MAX)) { + modify_cp0_intmask(0, 1 << 7); + } else { + printk("mask_irq: irq %d doesn't exist!\n", irq_nr); + } +} + +#define pnx8550_disable pnx8550_ack +static void pnx8550_ack(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define pnx8550_enable pnx8550_unmask +static void pnx8550_unmask(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_irq(unsigned int irq_nr) +{ + pnx8550_unmask(irq_nr); + return 0; +} + +static void shutdown_irq(unsigned int irq_nr) +{ + pnx8550_ack(irq_nr); + return; +} + +int pnx8550_set_gic_priority(int irq, int priority) +{ + int gic_irq = irq-PNX8550_INT_GIC_MIN; + int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf; + + gic_prio[gic_irq] = priority; + PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]); + + return prev_priority; +} + +static inline void mask_and_ack_level_irq(unsigned int irq) +{ + pnx8550_disable(irq); + return; +} + +static void end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + pnx8550_enable(irq); + } +} + +static struct hw_interrupt_type level_irq_type = { + .typename = "PNX Level IRQ", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = pnx8550_enable, + .disable = pnx8550_disable, + .ack = mask_and_ack_level_irq, + .end = end_irq, +}; + +static struct irqaction gic_action = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "GIC", +}; + +static struct irqaction timer_action = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "Timer", +}; + +void __init arch_init_irq(void) +{ + int i; + int configPR; + + /* init of cp0 interrupts */ + set_except_vector(0, cp0_irqdispatch); + + for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { + irq_desc[i].handler = &level_irq_type; + pnx8550_ack(i); /* mask the irq just in case */ + } + + /* init of GIC/IPC interrupts */ + /* should be done before cp0 since cp0 init enables the GIC int */ + for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) { + int gic_int_line = i - PNX8550_INT_GIC_MIN; + if (gic_int_line == 0 ) + continue; // don't fiddle with int 0 + /* + * enable change of TARGET, ENABLE and ACTIVE_LOW bits + * set TARGET 0 to route through hw0 interrupt + * set ACTIVE_LOW 0 active high (correct?) + * + * We really should setup an interrupt description table + * to do this nicely. + * Note, PCI INTA is active low on the bus, but inverted + * in the GIC, so to us it's active high. + */ +#ifdef CONFIG_PNX8550_V2PCI + if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) { + /* PCI INT through gpio 8, which is setup in + * pnx8550_setup.c and routed to GPIO + * Interrupt Level 0 (GPIO Connection 58). + * Set it active low. */ + + PNX8550_GIC_REQ(gic_int_line) = 0x1E020000; + } else +#endif + { + PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000; + } + + /* mask/priority is still 0 so we will not get any + * interrupts until it is unmasked */ + + irq_desc[i].handler = &level_irq_type; + } + + /* Priority level 0 */ + PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0; + + /* Set int vector table address */ + PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; + + irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type; + setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); + + /* init of Timer interrupts */ + for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { + irq_desc[i].handler = &level_irq_type; + } + + /* Stop Timer 1-3 */ + configPR = read_c0_config7(); + configPR |= 0x00000038; + write_c0_config7(configPR); + + irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type; + setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); +} + +EXPORT_SYMBOL(pnx8550_set_gic_priority); diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S new file mode 100644 index 0000000..338bffd --- /dev/null +++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002 Philips, Inc. All rights. + * Copyright (c) 2002 Red Hat, Inc. All rights. + * + * This software may be freely redistributed under the terms of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon arch/mips/galileo-boards/ev64240/int-handler.S + * + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* + * cp0_irqdispatch + * + * Code to handle in-core interrupt exception. + */ + + .align 5 + .set reorder + .set noat + NESTED(cp0_irqdispatch, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0,CP0_CAUSE + mfc0 t2,CP0_STATUS + + and t0,t2 + + andi t1,t0,STATUSF_IP2 /* int0 hardware line */ + bnez t1,ll_hw0_irq + nop + + andi t1,t0,STATUSF_IP7 /* int5 hardware line */ + bnez t1,ll_timer_irq + nop + + /* wrong alarm or masked ... */ + + j spurious_interrupt + nop + END(cp0_irqdispatch) + + .align 5 + .set reorder +ll_hw0_irq: + li a0,2 + move a1,sp + jal hw0_irqdispatch + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_timer_irq: + mfc0 t3,CP0_CONFIG,7 + andi t4,t3,0x01c0 + beqz t4,ll_timer_out + nop + li a0,7 + move a1,sp + jal timer_irqdispatch + nop + +ll_timer_out: j ret_from_irq + nop diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c new file mode 100644 index 0000000..baa6905 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/pci.c @@ -0,0 +1,133 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <pci.h> +#include <glb.h> +#include <nand.h> + +static struct resource pci_io_resource = { + "pci IO space", + (u32)(PNX8550_PCIIO + 0x1000), /* reserve regacy I/O space */ + (u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE), + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "pci memory space", + (u32)(PNX8550_PCIMEM), + (u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1), + IORESOURCE_MEM +}; + +extern struct pci_ops pnx8550_pci_ops; + +static struct pci_controller pnx8550_controller = { + .pci_ops = &pnx8550_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ +static inline unsigned long get_system_mem_size(void) +{ + /* Read IP2031_RANK0_ADDR_LO */ + unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); + /* Read IP2031_RANK1_ADDR_HI */ + unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); + + return dram_r1_hi - dram_r0_lo + 1; +} + +static int __init pnx8550_pci_setup(void) +{ + int pci_mem_code; + int mem_size = get_system_mem_size() >> 20; + + /* Clear the Global 2 Register, PCI Inta Output Enable Registers + Bit 1:Enable DAC Powerdown + -> 0:DACs are enabled and are working normally + 1:DACs are powerdown + Bit 0:Enable of PCI inta output + -> 0 = Disable PCI inta output + 1 = Enable PCI inta output + */ + PNX8550_GLB2_ENAB_INTA_O = 0; + + /* Calc the PCI mem size code */ + if (mem_size >= 128) + pci_mem_code = SIZE_128M; + else if (mem_size >= 64) + pci_mem_code = SIZE_64M; + else if (mem_size >= 32) + pci_mem_code = SIZE_32M; + else + pci_mem_code = SIZE_16M; + + /* Set PCI_XIO registers */ + outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO); + outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI); + outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO); + outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI); + + /* Send memory transaction via PCI_BASE2 */ + outl(0x00000001, PCI_BASE | PCI_IO); + + /* Unlock the setup register */ + outl(0xca, PCI_BASE | PCI_UNLOCKREG); + + /* + * BAR0 of PNX8550 (pci base 10) must be zero in order for ide + * to work, and in order for bus_to_baddr to work without any + * hacks. + */ + outl(0x00000000, PCI_BASE | PCI_BASE10); + + /* + *These two bars are set by default or the boot code. + * However, it's safer to set them here so we're not boot + * code dependent. + */ + outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */ + outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */ + + outl(PCI_EN_TA | + PCI_EN_PCI2MMI | + PCI_EN_XIO | + PCI_SETUP_BASE18_SIZE(SIZE_32M) | + PCI_SETUP_BASE18_EN | + PCI_SETUP_BASE14_EN | + PCI_SETUP_BASE10_PREF | + PCI_SETUP_BASE10_SIZE(pci_mem_code) | + PCI_SETUP_CFGMANAGE_EN | + PCI_SETUP_PCIARB_EN, + PCI_BASE | + PCI_SETUP); /* PCI_SETUP */ + outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */ + + register_pci_controller(&pnx8550_controller); + + return 0; +} + +arch_initcall(pnx8550_pci_setup); diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c new file mode 100644 index 0000000..8aa9bd6 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/platform.c @@ -0,0 +1,135 @@ +/* + * Platform device support for Philips PNX8550 SoCs + * + * Copyright 2005, Embedded Alley Solutions, Inc + * + * Based on arch/mips/au1000/common/platform.c + * Platform device support for Au1x00 SoCs. + * + * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/resource.h> +#include <linux/serial.h> +#include <linux/serial_ip3106.h> + +#include <int.h> +#include <usb.h> +#include <uart.h> + +extern struct uart_ops ip3106_pops; + +static struct resource pnx8550_usb_ohci_resources[] = { + [0] = { + .start = PNX8550_USB_OHCI_OP_BASE, + .end = PNX8550_USB_OHCI_OP_BASE + + PNX8550_USB_OHCI_OP_LEN, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8550_INT_USB, + .end = PNX8550_INT_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource pnx8550_uart_resources[] = { + [0] = { + .start = PNX8550_UART_PORT0, + .end = PNX8550_UART_PORT0 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8550_UART_INT(0), + .end = PNX8550_UART_INT(0), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = PNX8550_UART_PORT1, + .end = PNX8550_UART_PORT1 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = PNX8550_UART_INT(1), + .end = PNX8550_UART_INT(1), + .flags = IORESOURCE_IRQ, + }, +}; + +struct ip3106_port ip3106_ports[] = { + [0] = { + .port = { + .type = PORT_IP3106, + .iotype = SERIAL_IO_MEM, + .membase = (void __iomem *)PNX8550_UART_PORT0, + .mapbase = PNX8550_UART_PORT0, + .irq = PNX8550_UART_INT(0), + .uartclk = 3692300, + .fifosize = 16, + .ops = &ip3106_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + }, + [1] = { + .port = { + .type = PORT_IP3106, + .iotype = SERIAL_IO_MEM, + .membase = (void __iomem *)PNX8550_UART_PORT1, + .mapbase = PNX8550_UART_PORT1, + .irq = PNX8550_UART_INT(1), + .uartclk = 3692300, + .fifosize = 16, + .ops = &ip3106_pops, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static u64 uart_dmamask = ~(u32)0; + +static struct platform_device pnx8550_usb_ohci_device = { + .name = "pnx8550-ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), + .resource = pnx8550_usb_ohci_resources, +}; + +static struct platform_device pnx8550_uart_device = { + .name = "ip3106-uart", + .id = -1, + .dev = { + .dma_mask = &uart_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ip3106_ports, + }, + .num_resources = ARRAY_SIZE(pnx8550_uart_resources), + .resource = pnx8550_uart_resources, +}; + +static struct platform_device *pnx8550_platform_devices[] __initdata = { + &pnx8550_usb_ohci_device, + &pnx8550_uart_device, +}; + +int pnx8550_platform_init(void) +{ + return platform_add_devices(pnx8550_platform_devices, + ARRAY_SIZE(pnx8550_platform_devices)); +} + +arch_initcall(pnx8550_platform_init); diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c new file mode 100644 index 0000000..72a0167 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/proc.c @@ -0,0 +1,113 @@ +/* + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/init.h> +#include <linux/proc_fs.h> +#include <linux/irq.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/random.h> + +#include <asm/io.h> +#include <asm/gdb-stub.h> +#include <int.h> +#include <uart.h> + + +static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data) +{ + int len = 0; + int configPR = read_c0_config7(); + + if (offset==0) { + len += sprintf(&page[len],"Timer: count, compare, tc, status\n"); + len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n", + read_c0_count(), read_c0_compare(), + (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on"); + len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n", + read_c0_count2(), read_c0_compare2(), + (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on"); + len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n", + read_c0_count3(), read_c0_compare3(), + (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on"); + } + + return len; +} + +static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data) +{ + int len = 0; + + if (offset==0) { + len += sprintf(&page[len],"config1: %#10.8x\n",read_c0_config1()); + len += sprintf(&page[len],"config2: %#10.8x\n",read_c0_config2()); + len += sprintf(&page[len],"config3: %#10.8x\n",read_c0_config3()); + len += sprintf(&page[len],"configPR: %#10.8x\n",read_c0_config7()); + len += sprintf(&page[len],"status: %#10.8x\n",read_c0_status()); + len += sprintf(&page[len],"cause: %#10.8x\n",read_c0_cause()); + len += sprintf(&page[len],"count: %#10.8x\n",read_c0_count()); + len += sprintf(&page[len],"count_2: %#10.8x\n",read_c0_count2()); + len += sprintf(&page[len],"count_3: %#10.8x\n",read_c0_count3()); + len += sprintf(&page[len],"compare: %#10.8x\n",read_c0_compare()); + len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2()); + len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3()); + } + + return len; +} + +static struct proc_dir_entry* pnx8550_dir = NULL; +static struct proc_dir_entry* pnx8550_timers = NULL; +static struct proc_dir_entry* pnx8550_registers = NULL; + +static int pnx8550_proc_init( void ) +{ + + // Create /proc/pnx8550 + pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL); + if (pnx8550_dir){ + pnx8550_dir->nlink = 1; + } + else { + printk(KERN_ERR "Can't create pnx8550 proc dir\n"); + return -1; + } + + // Create /proc/pnx8550/timers + pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir ); + if (pnx8550_timers){ + pnx8550_timers->nlink = 1; + pnx8550_timers->read_proc = pnx8550_timers_read; + } + else { + printk(KERN_ERR "Can't create pnx8550 timers proc file\n"); + } + + // Create /proc/pnx8550/registers + pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir ); + if (pnx8550_registers){ + pnx8550_registers->nlink = 1; + pnx8550_registers->read_proc = pnx8550_registers_read; + } + else { + printk(KERN_ERR "Can't create pnx8550 registers proc file\n"); + } + + return 0; +} + +__initcall(pnx8550_proc_init); diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c new file mode 100644 index 0000000..70aac97 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/prom.c @@ -0,0 +1,138 @@ +/* + * + * Per Hallsmark, per.hallsmark@mvista.com + * + * Based on jmr3927/common/prom.c + * + * 2004 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/string.h> +#include <linux/serial_ip3106.h> + +#include <asm/bootinfo.h> +#include <uart.h> + +/* #define DEBUG_CMDLINE */ + +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +typedef struct +{ + char *name; +/* char *val; */ +}t_env_var; + + +char * prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + * Environment variables are stored in the form of "memsize=64". + */ + + t_env_var *env = (t_env_var *)prom_envp; + int i; + + i = strlen(envname); + + while(env->name) { + if(strncmp(envname, env->name, i) == 0) { + return(env->name + strlen(envname) + 1); + } + env++; + } + return(NULL); +} + +inline unsigned char str2hexnum(unsigned char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; /* foo */ +} + +inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + return 0; +} + +unsigned long __init prom_free_prom_memory(void) +{ + return 0; +} + +extern int pnx8550_console_port; + +/* used by prom_printf */ +void prom_putchar(char c) +{ + if (pnx8550_console_port != -1) { + /* Wait until FIFO not full */ + while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16) + ; + /* Send one char */ + ip3106_fifo(UART_BASE, pnx8550_console_port) = c; + } +} + +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c new file mode 100644 index 0000000..7b2cbc5 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/reset.c @@ -0,0 +1,49 @@ +/*. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Reset the PNX8550 board. + * + */ +#include <linux/slab.h> +#include <asm/reboot.h> +#include <glb.h> + +void pnx8550_machine_restart(char *command) +{ + char head[] = "************* Machine restart *************"; + char foot[] = "*******************************************"; + + printk("\n\n"); + printk("%s\n", head); + if (command != NULL) + printk("* %s\n", command); + printk("%s\n", foot); + + PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; +} + +void pnx8550_machine_halt(void) +{ + printk("*** Machine halt. (Not implemented) ***\n"); +} + +void pnx8550_machine_power_off(void) +{ + printk("*** Machine power off. (Not implemented) ***\n"); +} diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c new file mode 100644 index 0000000..ee6bf72 --- /dev/null +++ b/arch/mips/philips/pnx8550/common/setup.c @@ -0,0 +1,149 @@ +/* + * + * 2.6 port, Embedded Alley Solutions, Inc + * + * Based on Per Hallsmark, per.hallsmark@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/serial_ip3106.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> +#include <asm/time.h> + +#include <glb.h> +#include <int.h> +#include <pci.h> +#include <uart.h> +#include <nand.h> + +extern void prom_printf(char *fmt, ...); + +extern void __init board_setup(void); +extern void pnx8550_machine_restart(char *); +extern void pnx8550_machine_halt(void); +extern void pnx8550_machine_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +extern void (*board_time_init)(void); +extern void pnx8550_time_init(void); +extern void (*board_timer_setup)(struct irqaction *irq); +extern void pnx8550_timer_setup(struct irqaction *irq); +extern void rs_kgdb_hook(int tty_no); +extern void prom_printf(char *fmt, ...); +extern char *prom_getcmdline(void); + +struct resource standard_io_resources[] = { + {"dma1", 0x00, 0x1f, IORESOURCE_BUSY}, + {"timer", 0x40, 0x5f, IORESOURCE_BUSY}, + {"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, + {"dma2", 0xc0, 0xdf, IORESOURCE_BUSY}, +}; + +#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ +unsigned long get_system_mem_size(void) +{ + /* Read IP2031_RANK0_ADDR_LO */ + unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); + /* Read IP2031_RANK1_ADDR_HI */ + unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); + + return dram_r1_hi - dram_r0_lo + 1; +} + +int pnx8550_console_port = -1; + +void __init plat_setup(void) +{ + int i; + char* argptr; + + board_setup(); /* board specific setup */ + + _machine_restart = pnx8550_machine_restart; + _machine_halt = pnx8550_machine_halt; + _machine_power_off = pnx8550_machine_power_off; + + board_time_init = pnx8550_time_init; + board_timer_setup = pnx8550_timer_setup; + + /* Clear the Global 2 Register, PCI Inta Output Enable Registers + Bit 1:Enable DAC Powerdown + -> 0:DACs are enabled and are working normally + 1:DACs are powerdown + Bit 0:Enable of PCI inta output + -> 0 = Disable PCI inta output + 1 = Enable PCI inta output + */ + PNX8550_GLB2_ENAB_INTA_O = 0; + + /* IO/MEM resources. */ + set_io_port_base(KSEG1); + ioport_resource.start = 0; + ioport_resource.end = ~0; + iomem_resource.start = 0; + iomem_resource.end = ~0; + + /* Request I/O space for devices on this board */ + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, standard_io_resources + i); + + /* Place the Mode Control bit for GPIO pin 16 in primary function */ + /* Pin 16 is used by UART1, UA1_TX */ + outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) | + (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT), + PNX8550_GPIO_MC1); + + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "console=ttyS")) != NULL) { + argptr += strlen("console=ttyS"); + pnx8550_console_port = *argptr == '0' ? 0 : 1; + + /* We must initialize the UART (console) before prom_printf */ + /* Set LCR to 8-bit and BAUD to 38400 (no 5) */ + ip3106_lcr(UART_BASE, pnx8550_console_port) = + IP3106_UART_LCR_8BIT; + ip3106_baud(UART_BASE, pnx8550_console_port) = 5; + } + +#ifdef CONFIG_KGDB + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { + int line; + argptr += strlen("kgdb=ttyS"); + line = *argptr == '0' ? 0 : 1; + rs_kgdb_hook(line); + prom_printf("KGDB: Using ttyS%i for session, " + "please connect your debugger\n", line ? 1 : 0); + } +#endif + return; +} diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c new file mode 100644 index 0000000..70664ea --- /dev/null +++ b/arch/mips/philips/pnx8550/common/time.c @@ -0,0 +1,105 @@ +/* + * Copyright 2001, 2002, 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Common time service routines for MIPS machines. See + * Documents/MIPS/README.txt. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/param.h> +#include <linux/time.h> +#include <linux/timer.h> +#include <linux/smp.h> +#include <linux/kernel_stat.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/module.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/time.h> +#include <asm/hardirq.h> +#include <asm/div64.h> +#include <asm/debug.h> + +#include <int.h> +#include <cm.h> + +extern unsigned int mips_hpt_frequency; + +/* + * pnx8550_time_init() - it does the following things: + * + * 1) board_time_init() - + * a) (optional) set up RTC routines, + * b) (optional) calibrate and set the mips_hpt_frequency + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) + */ + +void pnx8550_time_init(void) +{ + unsigned int n; + unsigned int m; + unsigned int p; + unsigned int pow2p; + + /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */ + /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */ + + n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16; + m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8; + p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2; + pow2p = (1 << p); + + db_assert(m != 0 && pow2p != 0); + + /* + * Compute the frequency as in the PNX8550 User Manual 1.0, p.186 + * (a.k.a. 8-10). Divide by HZ for a timer offset that results in + * HZ timer interrupts per second. + */ + mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p)); +} + +/* + * pnx8550_timer_setup() - it does the following things: + * + * 5) board_timer_setup() - + * a) (optional) over-write any choices made above by time_init(). + * b) machine specific code should setup the timer irqaction. + * c) enable the timer interrupt + */ + +void __init pnx8550_timer_setup(struct irqaction *irq) +{ + int configPR; + + setup_irq(PNX8550_INT_TIMER1, irq); + + /* Start timer1 */ + configPR = read_c0_config7(); + configPR &= ~0x00000008; + write_c0_config7(configPR); + + /* Timer 2 stop */ + configPR = read_c0_config7(); + configPR |= 0x00000010; + write_c0_config7(configPR); + + write_c0_count2(0); + write_c0_compare2(0xffffffff); + + /* Timer 3 stop */ + configPR = read_c0_config7(); + configPR |= 0x00000020; + write_c0_config7(configPR); +} diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile new file mode 100644 index 0000000..e8228db --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/Makefile @@ -0,0 +1,4 @@ + +# Makefile for the Philips JBS Board. + +lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c new file mode 100644 index 0000000..f92826e --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/board_setup.c @@ -0,0 +1,65 @@ +/* + * JBS Specific board startup routines. + * + * Copyright 2005, Embedded Alley Solutions, Inc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/console.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> + +#include <glb.h> + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void __init board_setup(void) +{ + unsigned long config0, configpr; + + config0 = read_c0_config(); + + /* clear all three cache coherency fields */ + config0 &= ~(0x7 | (7<<25) | (7<<28)); + config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) | + (CONF_CM_DEFAULT<<28)); + write_c0_config(config0); + BARRIER; + + configpr = read_c0_config7(); + configpr |= (1<<19); /* enable tlb */ + write_c0_config7(configpr); + BARRIER; +} diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c new file mode 100644 index 0000000..85f4491 --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/init.c @@ -0,0 +1,57 @@ +/* + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddedalley.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/string.h> +#include <linux/kernel.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Philips PNX8550/JBS"; +} + +void __init prom_init(void) +{ + + unsigned long memsize; + + mips_machgroup = MACH_GROUP_PHILIPS; + mips_machtype = MACH_PHILIPS_JBS; + + //memsize = 0x02800000; /* Trimedia uses memory above */ + memsize = 0x08000000; /* Trimedia uses memory above */ + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c new file mode 100644 index 0000000..f78e042 --- /dev/null +++ b/arch/mips/philips/pnx8550/jbs/irqmap.c @@ -0,0 +1,36 @@ +/* + * Philips JBS board irqmap. + * + * Copyright 2005 Embedded Alley Solutions, Inc + * source@embeddealley.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <int.h> + +char irq_tab_jbs[][5] __initdata = { + [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, +}; + diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index e5c03c5..3870a76 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -137,6 +137,7 @@ #define MACH_GROUP_PHILIPS 14 #define MACH_PHILIPS_NINO 0 /* Nino */ #define MACH_PHILIPS_VELO 1 /* Velo */ +#define MACH_PHILIPS_JBS 2 /* JBS */ /* * Valid machtype for group Globespan diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 3bbb643..ed92c0b 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -52,6 +52,7 @@ #define PRID_IMP_VR41XX 0x0c00 #define PRID_IMP_R12000 0x0e00 #define PRID_IMP_R8000 0x1000 +#define PRID_IMP_PR4450 0x1200 #define PRID_IMP_R4600 0x2000 #define PRID_IMP_R4700 0x2100 #define PRID_IMP_TX39 0x2200 @@ -187,7 +188,8 @@ #define CPU_24K 58 #define CPU_AU1200 59 #define CPU_34K 60 -#define CPU_LAST 60 +#define CPU_PR4450 61 +#define CPU_LAST 61 /* * ISA Level encodings diff --git a/include/asm-mips/mach-pnx8550/cm.h b/include/asm-mips/mach-pnx8550/cm.h new file mode 100644 index 0000000..bb0a56c --- /dev/null +++ b/include/asm-mips/mach-pnx8550/cm.h @@ -0,0 +1,43 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Clock module specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_CM_H +#define __PNX8550_CM_H + +#define PNX8550_CM_BASE 0xBBE47000 + +#define PNX8550_CM_PLL0_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000) +#define PNX8550_CM_PLL1_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004) +#define PNX8550_CM_PLL2_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008) +#define PNX8550_CM_PLL3_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C) + +// Table not complete..... + +#define PNX8550_CM_PLL_BLOCKED_MASK 0x80000000 +#define PNX8550_CM_PLL_LOCK_MASK 0x40000000 +#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000 +#define PNX8550_CM_PLL_N_MASK 0x01ff0000 +#define PNX8550_CM_PLL_M_MASK 0x00003f00 +#define PNX8550_CM_PLL_P_MASK 0x0000000c +#define PNX8550_CM_PLL_PD_MASK 0x00000002 + + +#endif diff --git a/include/asm-mips/mach-pnx8550/glb.h b/include/asm-mips/mach-pnx8550/glb.h new file mode 100644 index 0000000..07aa85e --- /dev/null +++ b/include/asm-mips/mach-pnx8550/glb.h @@ -0,0 +1,86 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PNX8550 global definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_GLB_H +#define __PNX8550_GLB_H + +#define PNX8550_GLB1_BASE 0xBBE63000 +#define PNX8550_GLB2_BASE 0xBBE4d000 +#define PNX8550_RESET_BASE 0xBBE60000 + +/* PCI Inta Output Enable Registers */ +#define PNX8550_GLB2_ENAB_INTA_O *(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050) + +/* Bit 1:Enable DAC Powerdown + 0:DACs are enabled and are working normally + 1:DACs are powerdown +*/ +#define PNX8550_GLB_DAC_PD 0x2 +/* Bit 0:Enable of PCI inta output + 0 = Disable PCI inta output + 1 = Enable PCI inta output +*/ +#define PNX8550_GLB_ENABLE_INTA_O 0x1 + +/* PCI Direct Mappings */ +#define PNX8550_PCIMEM 0x12000000 +#define PNX8550_PCIMEM_SIZE 0x08000000 +#define PNX8550_PCIIO 0x1c000000 +#define PNX8550_PCIIO_SIZE 0x02000000 /* 32M */ + +#define PNX8550_PORT_BASE KSEG1 + +// GPIO def +#define PNX8550_GPIO_BASE 0x1Be00000 + +#define PNX8550_GPIO_DIRQ0 (PNX8550_GPIO_BASE + 0x104500) +#define PNX8550_GPIO_MC1 (PNX8550_GPIO_BASE + 0x104004) +#define PNX8550_GPIO_MC_31_BIT 30 +#define PNX8550_GPIO_MC_30_BIT 28 +#define PNX8550_GPIO_MC_29_BIT 26 +#define PNX8550_GPIO_MC_28_BIT 24 +#define PNX8550_GPIO_MC_27_BIT 22 +#define PNX8550_GPIO_MC_26_BIT 20 +#define PNX8550_GPIO_MC_25_BIT 18 +#define PNX8550_GPIO_MC_24_BIT 16 +#define PNX8550_GPIO_MC_23_BIT 14 +#define PNX8550_GPIO_MC_22_BIT 12 +#define PNX8550_GPIO_MC_21_BIT 10 +#define PNX8550_GPIO_MC_20_BIT 8 +#define PNX8550_GPIO_MC_19_BIT 6 +#define PNX8550_GPIO_MC_18_BIT 4 +#define PNX8550_GPIO_MC_17_BIT 2 +#define PNX8550_GPIO_MC_16_BIT 0 + +#define PNX8550_GPIO_MODE_PRIMOP 0x1 +#define PNX8550_GPIO_MODE_NO_OPENDR 0x2 +#define PNX8550_GPIO_MODE_OPENDR 0x3 + +// RESET module +#define PNX8550_RST_CTL *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0) +#define PNX8550_RST_CAUSE *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4) +#define PNX8550_RST_EN_WATCHDOG *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8) + +#define PNX8550_RST_REL_MIPS_RST_N 0x8 +#define PNX8550_RST_DO_SW_RST 0x4 +#define PNX8550_RST_REL_SYS_RST_OUT 0x2 +#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1 +#endif diff --git a/include/asm-mips/mach-pnx8550/int.h b/include/asm-mips/mach-pnx8550/int.h new file mode 100644 index 0000000..0e0668b --- /dev/null +++ b/include/asm-mips/mach-pnx8550/int.h @@ -0,0 +1,140 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Interrupt specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_INT_H +#define __PNX8550_INT_H + +#define PNX8550_GIC_BASE 0xBBE3E000 + +#define PNX8550_GIC_PRIMASK_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000) +#define PNX8550_GIC_PRIMASK_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004) +#define PNX8550_GIC_VECTOR_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100) +#define PNX8550_GIC_VECTOR_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104) +#define PNX8550_GIC_PEND_1_31 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200) +#define PNX8550_GIC_PEND_32_63 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204) +#define PNX8550_GIC_PEND_64_70 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208) +#define PNX8550_GIC_FEATURES *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300) +#define PNX8550_GIC_REQ(x) *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4) +#define PNX8550_GIC_MOD_ID *(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC) + +// cp0 is two software + six hw exceptions +#define PNX8550_INT_CP0_TOTINT 8 +#define PNX8550_INT_CP0_MIN 0 +#define PNX8550_INT_CP0_MAX (PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1) + +#define MIPS_CPU_GIC_IRQ 2 +#define MIPS_CPU_TIMER_IRQ 7 + +// GIC are 71 exceptions connected to cp0's first hardware exception +#define PNX8550_INT_GIC_TOTINT 71 +#define PNX8550_INT_GIC_MIN (PNX8550_INT_CP0_MAX+1) +#define PNX8550_INT_GIC_MAX (PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1) + +#define PNX8550_INT_UNDEF (PNX8550_INT_GIC_MIN+0) +#define PNX8550_INT_IPC_TARGET0_MIPS (PNX8550_INT_GIC_MIN+1) +#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2) +#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3) +#define PNX8550_INT_RESERVED_4 (PNX8550_INT_GIC_MIN+4) +#define PNX8550_INT_USB (PNX8550_INT_GIC_MIN+5) +#define PNX8550_INT_GPIO_EQ1 (PNX8550_INT_GIC_MIN+6) +#define PNX8550_INT_GPIO_EQ2 (PNX8550_INT_GIC_MIN+7) +#define PNX8550_INT_GPIO_EQ3 (PNX8550_INT_GIC_MIN+8) +#define PNX8550_INT_GPIO_EQ4 (PNX8550_INT_GIC_MIN+9) + +#define PNX8550_INT_GPIO_EQ5 (PNX8550_INT_GIC_MIN+10) +#define PNX8550_INT_GPIO_EQ6 (PNX8550_INT_GIC_MIN+11) +#define PNX8550_INT_RESERVED_12 (PNX8550_INT_GIC_MIN+12) +#define PNX8550_INT_QVCP1 (PNX8550_INT_GIC_MIN+13) +#define PNX8550_INT_QVCP2 (PNX8550_INT_GIC_MIN+14) +#define PNX8550_INT_I2C1 (PNX8550_INT_GIC_MIN+15) +#define PNX8550_INT_I2C2 (PNX8550_INT_GIC_MIN+16) +#define PNX8550_INT_ISO_UART1 (PNX8550_INT_GIC_MIN+17) +#define PNX8550_INT_ISO_UART2 (PNX8550_INT_GIC_MIN+18) +#define PNX8550_INT_UART1 (PNX8550_INT_GIC_MIN+19) + +#define PNX8550_INT_UART2 (PNX8550_INT_GIC_MIN+20) +#define PNX8550_INT_QNTR (PNX8550_INT_GIC_MIN+21) +#define PNX8550_INT_RESERVED22 (PNX8550_INT_GIC_MIN+22) +#define PNX8550_INT_T_DSC (PNX8550_INT_GIC_MIN+23) +#define PNX8550_INT_M_DSC (PNX8550_INT_GIC_MIN+24) +#define PNX8550_INT_RESERVED25 (PNX8550_INT_GIC_MIN+25) +#define PNX8550_INT_2D_DRAW_ENG (PNX8550_INT_GIC_MIN+26) +#define PNX8550_INT_MEM_BASED_SCALAR1 (PNX8550_INT_GIC_MIN+27) +#define PNX8550_INT_VIDEO_MPEG (PNX8550_INT_GIC_MIN+28) +#define PNX8550_INT_VIDEO_INPUT_P1 (PNX8550_INT_GIC_MIN+29) + +#define PNX8550_INT_VIDEO_INPUT_P2 (PNX8550_INT_GIC_MIN+30) +#define PNX8550_INT_SPDI1 (PNX8550_INT_GIC_MIN+31) +#define PNX8550_INT_SPDO (PNX8550_INT_GIC_MIN+32) +#define PNX8550_INT_AUDIO_INPUT1 (PNX8550_INT_GIC_MIN+33) +#define PNX8550_INT_AUDIO_OUTPUT1 (PNX8550_INT_GIC_MIN+34) +#define PNX8550_INT_AUDIO_INPUT2 (PNX8550_INT_GIC_MIN+35) +#define PNX8550_INT_AUDIO_OUTPUT2 (PNX8550_INT_GIC_MIN+36) +#define PNX8550_INT_MEMBASED_SCALAR2 (PNX8550_INT_GIC_MIN+37) +#define PNX8550_INT_VPK (PNX8550_INT_GIC_MIN+38) +#define PNX8550_INT_MPEG1_MIPS (PNX8550_INT_GIC_MIN+39) + +#define PNX8550_INT_MPEG1_TM (PNX8550_INT_GIC_MIN+40) +#define PNX8550_INT_MPEG2_MIPS (PNX8550_INT_GIC_MIN+41) +#define PNX8550_INT_MPEG2_TM (PNX8550_INT_GIC_MIN+42) +#define PNX8550_INT_TS_DMA (PNX8550_INT_GIC_MIN+43) +#define PNX8550_INT_EDMA (PNX8550_INT_GIC_MIN+44) +#define PNX8550_INT_TM_DEBUG1 (PNX8550_INT_GIC_MIN+45) +#define PNX8550_INT_TM_DEBUG2 (PNX8550_INT_GIC_MIN+46) +#define PNX8550_INT_PCI_INTA (PNX8550_INT_GIC_MIN+47) +#define PNX8550_INT_CLOCK_MODULE (PNX8550_INT_GIC_MIN+48) +#define PNX8550_INT_PCI_XIO_INTA_PCI (PNX8550_INT_GIC_MIN+49) + +#define PNX8550_INT_PCI_XIO_INTB_DMA (PNX8550_INT_GIC_MIN+50) +#define PNX8550_INT_PCI_XIO_INTC_GPPM (PNX8550_INT_GIC_MIN+51) +#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52) +#define PNX8550_INT_DVD_CSS (PNX8550_INT_GIC_MIN+53) +#define PNX8550_INT_VLD (PNX8550_INT_GIC_MIN+54) +#define PNX8550_INT_GPIO_TSU_7_0 (PNX8550_INT_GIC_MIN+55) +#define PNX8550_INT_GPIO_TSU_15_8 (PNX8550_INT_GIC_MIN+56) +#define PNX8550_INT_GPIO_CTU_IR (PNX8550_INT_GIC_MIN+57) +#define PNX8550_INT_GPIO0 (PNX8550_INT_GIC_MIN+58) +#define PNX8550_INT_GPIO1 (PNX8550_INT_GIC_MIN+59) + +#define PNX8550_INT_GPIO2 (PNX8550_INT_GIC_MIN+60) +#define PNX8550_INT_GPIO3 (PNX8550_INT_GIC_MIN+61) +#define PNX8550_INT_GPIO4 (PNX8550_INT_GIC_MIN+62) +#define PNX8550_INT_GPIO5 (PNX8550_INT_GIC_MIN+63) +#define PNX8550_INT_GPIO6 (PNX8550_INT_GIC_MIN+64) +#define PNX8550_INT_GPIO7 (PNX8550_INT_GIC_MIN+65) +#define PNX8550_INT_PMAN_SECURITY (PNX8550_INT_GIC_MIN+66) +#define PNX8550_INT_I2C3 (PNX8550_INT_GIC_MIN+67) +#define PNX8550_INT_RESERVED_68 (PNX8550_INT_GIC_MIN+68) +#define PNX8550_INT_SPDI2 (PNX8550_INT_GIC_MIN+69) + +#define PNX8550_INT_I2C4 (PNX8550_INT_GIC_MIN+70) + +// Timer are 3 exceptions connected to cp0's 7th hardware exception +#define PNX8550_INT_TIMER_TOTINT 3 +#define PNX8550_INT_TIMER_MIN (PNX8550_INT_GIC_MAX+1) +#define PNX8550_INT_TIMER_MAX (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1) + +#define PNX8550_INT_TIMER1 (PNX8550_INT_TIMER_MIN+0) +#define PNX8550_INT_TIMER2 (PNX8550_INT_TIMER_MIN+1) +#define PNX8550_INT_TIMER3 (PNX8550_INT_TIMER_MIN+2) +#define PNX8550_INT_WATCHDOG PNX8550_INT_TIMER3 + +#endif diff --git a/include/asm-mips/mach-pnx8550/kernel-entry-init.h b/include/asm-mips/mach-pnx8550/kernel-entry-init.h new file mode 100644 index 0000000..57102fa --- /dev/null +++ b/include/asm-mips/mach-pnx8550/kernel-entry-init.h @@ -0,0 +1,262 @@ +/* + * 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) 2005 Embedded Alley Solutions, Inc + */ +#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H +#define __ASM_MACH_KERNEL_ENTRY_INIT_H + +#include <asm/cacheops.h> +#include <asm/addrspace.h> + +#define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */ +#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; +#define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */ +#define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */ +#define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */ + +#define ICACHE_SET_COUNT 256 /* Instruction cache set count */ +#define DCACHE_SET_COUNT 128 /* Data cache set count */ + +#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE) +#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE) + + .macro kernel_entry_setup + .set push + .set noreorder + /* + * PNX8550 entry point, when running a non compressed + * kernel. When loading a zImage, the head.S code in + * arch/mips/zboot/pnx8550 will init the caches and, + * decompress the kernel, and branch to kernel_entry. + */ +cache_begin: li t0, (1<<28) + mtc0 t0, CP0_STATUS /* cp0 usable */ + HAZARD_CP0 + + mtc0 zero, CP0_CAUSE + HAZARD_CP0 + + + /* Set static virtual to phys address translation and TLB disabled */ + mfc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + and t0,~((1<<19) | (1<<20)) /* TLB/MAP cleared */ + mtc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */ + + init_icache + nop + init_dcache + nop + + cachePr4450ICReset + nop + + cachePr4450DCReset + nop + + /* read ConfigPR into t0 */ + mfc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 + + /* enable the TLB */ + or t0, (1<<19) + + /* disable the ICACHE: at least 10x slower */ + /* or t0, (1<<26) */ + + /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */ + /* or t0, (1<<27) */ + + and t0, CO_CONFIGPR_VALID + + /* enable TLB. */ + mtc0 t0, CP0_CONFIG, 7 + HAZARD_CP0 +cache_end: + /* Setup CMEM_0 to MMIO address space, 2MB */ + lui t0, 0x1BE0 + addi t0, t0, 0x3 + mtc0 $8, $22, 4 + nop + + /* Setup CMEM_1, 128MB */ + lui t0, 0x1000 + addi t0, t0, 0xf + mtc0 $8, $22, 5 + nop + + + /* Setup CMEM_2, 32MB */ + lui t0, 0x1C00 + addi t0, t0, 0xb + mtc0 $8, $22, 6 + nop + + /* Setup CMEM_3, 0MB */ + lui t0, 0x0 + addi t0, t0, 0x0 + mtc0 $8, $22, 7 + nop + + /* Enable cache */ + mfc0 t0, CP0_CONFIG + HAZARD_CP0 + and t0, t0, 0xFFFFFFF8 + or t0, t0, 3 + mtc0 t0, CP0_CONFIG + HAZARD_CP0 + .set pop + .endm + + .macro init_icache + .set push + .set noreorder + + /* Get Cache Configuration */ + mfc0 t3, CP0_CONFIG, 1 + HAZARD_CP0 + + /* get cache Line size */ + + srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */ + andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */ + beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */ + nop + addiu t0, t1, 1 + ori t1, zero, 1 + sllv t1, t1, t0 + + /* get max cache Index */ + srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */ + andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */ + addiu t0, t2, 6 + ori t2, zero, 1 + sllv t2, t2, t0 + + /* get max cache way */ + srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */ + andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */ + addiu t3, t3, 1 + + /* total no of cache lines */ + multu t2, t3 /* max index * max way */ + mflo t2 + addiu t2, t2, -1 + + move t0, zero +pr4450_next_instruction_cache_set: + cache Index_Invalidate_I, 0(t0) + addu t0, t0, t1 /* add bytes in a line */ + bne t2, zero, pr4450_next_instruction_cache_set + addiu t2, t2, -1 /* reduce no of lines to invalidate by one */ +pr4450_instr_cache_invalidated: + .set pop + .endm + + .macro init_dcache + .set push + .set noreorder + move t1, zero + + /* Store Tag Information */ + mtc0 zero, CP0_TAGLO, 0 + HAZARD_CP0 + + mtc0 zero, CP0_TAGHI, 0 + HAZARD_CP0 + + /* Cache size is 16384 = 512 lines x 32 bytes per line */ + or t2, zero, (128*4)-1 /* 512 lines */ + /* Invalidate all lines */ +2: + cache Index_Store_Tag_D, 0(t1) + addiu t2, t2, -1 + bne t2, zero, 2b + addiu t1, t1, 32 /* 32 bytes in a line */ + .set pop + .endm + + .macro cachePr4450ICReset + .set push + .set noreorder + + /* Save CP0 status reg on entry; */ + /* disable interrupts during cache reset */ + mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */ + HAZARD_CP0 + + mtc0 zero, CP0_STATUS /* disable CPU interrupts */ + HAZARD_CP0 + + or t1, zero, zero /* T1 = starting cache index (0) */ + ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */ + + icache_invd_loop: + /* 9 == register t1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \ + (0 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY0 */ + .word (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \ + (1 * ICACHE_SET_SIZE)) /* invalidate inst cache WAY1 */ + + addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */ + bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */ + addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */ + + /* Initialize the latches in the instruction cache tag */ + /* that drive the way selection tri-state bus drivers, by doing a */ + /* dummy load while the instruction cache is still disabled. */ + /* TODO: Is this needed ? */ + la t1, KSEG0 /* T1 = cached memory base address */ + lw zero, 0x0000(t1) /* (dummy read of first memory word) */ + + mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ + HAZARD_CP0 + .set pop + .endm + + .macro cachePr4450DCReset + .set push + .set noreorder + mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */ + HAZARD_CP0 + mtc0 zero, CP0_STATUS /* disable CPU interrupts */ + HAZARD_CP0 + + /* Writeback/invalidate entire data cache sets/ways/lines */ + or t1, zero, zero /* T1 = starting cache index (0) */ + ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */ + + dcache_wbinvd_loop: + /* 9 == register t1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (0 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY0 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (1 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY1 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (2 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY2 */ + .word (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \ + (3 * DCACHE_SET_SIZE)) /* writeback/invalidate WAY3 */ + + addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */ + bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */ + addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */ + + /* Initialize the latches in the data cache tag that drive the way + selection tri-state bus drivers, by doing a dummy load while the + data cache is still in the disabled mode. TODO: Is this needed ? */ + la t1, KSEG0 /* T1 = cached memory base address */ + lw zero, 0x0000(t1) /* (dummy read of first memory word) */ + + mtc0 t0, CP0_STATUS /* restore interrupt status on entry */ + HAZARD_CP0 + .set pop + .endm + +#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */ diff --git a/include/asm-mips/mach-pnx8550/nand.h b/include/asm-mips/mach-pnx8550/nand.h new file mode 100644 index 0000000..aefbc51 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/nand.h @@ -0,0 +1,121 @@ +#ifndef __PNX8550_NAND_H +#define __PNX8550_NAND_H + +#define PNX8550_NAND_BASE_ADDR 0x10000000 +#define PNX8550_PCIXIO_BASE 0xBBE40000 + +#define PNX8550_DMA_EXT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800) +#define PNX8550_DMA_INT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804) +#define PNX8550_DMA_TRANS_SIZE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808) +#define PNX8550_DMA_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c) +#define PNX8550_XIO_SEL0 *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814) +#define PNX8550_GPXIO_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820) +#define PNX8550_GPXIO_WR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824) +#define PNX8550_GPXIO_RD *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828) +#define PNX8550_GPXIO_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C) +#define PNX8550_XIO_FLASH_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830) +#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0) +#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4) +#define PNX8550_GPXIO_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8) +#define PNX8550_DMA_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0) +#define PNX8550_DMA_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4) +#define PNX8550_DMA_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8) + +#define PNX8550_XIO_SEL0_EN_16BIT 0x00800000 +#define PNX8550_XIO_SEL0_USE_ACK 0x00400000 +#define PNX8550_XIO_SEL0_REN_HIGH 0x00100000 +#define PNX8550_XIO_SEL0_REN_LOW 0x00040000 +#define PNX8550_XIO_SEL0_WEN_HIGH 0x00010000 +#define PNX8550_XIO_SEL0_WEN_LOW 0x00004000 +#define PNX8550_XIO_SEL0_WAIT 0x00000200 +#define PNX8550_XIO_SEL0_OFFSET 0x00000020 +#define PNX8550_XIO_SEL0_TYPE_68360 0x00000000 +#define PNX8550_XIO_SEL0_TYPE_NOR 0x00000008 +#define PNX8550_XIO_SEL0_TYPE_NAND 0x00000010 +#define PNX8550_XIO_SEL0_TYPE_IDE 0x00000018 +#define PNX8550_XIO_SEL0_SIZE_8MB 0x00000000 +#define PNX8550_XIO_SEL0_SIZE_16MB 0x00000002 +#define PNX8550_XIO_SEL0_SIZE_32MB 0x00000004 +#define PNX8550_XIO_SEL0_SIZE_64MB 0x00000006 +#define PNX8550_XIO_SEL0_ENAB 0x00000001 + +#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT) | \ + (PNX8550_XIO_SEL0_REN_HIGH*0)| \ + (PNX8550_XIO_SEL0_REN_LOW*2) | \ + (PNX8550_XIO_SEL0_WEN_HIGH*0)| \ + (PNX8550_XIO_SEL0_WEN_LOW*2) | \ + (PNX8550_XIO_SEL0_WAIT*4) | \ + (PNX8550_XIO_SEL0_OFFSET*0) | \ + (PNX8550_XIO_SEL0_TYPE_NAND) | \ + (PNX8550_XIO_SEL0_SIZE_32MB) | \ + (PNX8550_XIO_SEL0_ENAB)) + +#define PNX8550_GPXIO_PENDING 0x00000200 +#define PNX8550_GPXIO_DONE 0x00000100 +#define PNX8550_GPXIO_CLR_DONE 0x00000080 +#define PNX8550_GPXIO_INIT 0x00000040 +#define PNX8550_GPXIO_READ_CMD 0x00000010 +#define PNX8550_GPXIO_BEN 0x0000000F + +#define PNX8550_XIO_FLASH_64MB 0x00200000 +#define PNX8550_XIO_FLASH_INC_DATA 0x00100000 +#define PNX8550_XIO_FLASH_CMD_PH 0x000C0000 +#define PNX8550_XIO_FLASH_CMD_PH2 0x00080000 +#define PNX8550_XIO_FLASH_CMD_PH1 0x00040000 +#define PNX8550_XIO_FLASH_CMD_PH0 0x00000000 +#define PNX8550_XIO_FLASH_ADR_PH 0x00030000 +#define PNX8550_XIO_FLASH_ADR_PH3 0x00030000 +#define PNX8550_XIO_FLASH_ADR_PH2 0x00020000 +#define PNX8550_XIO_FLASH_ADR_PH1 0x00010000 +#define PNX8550_XIO_FLASH_ADR_PH0 0x00000000 +#define PNX8550_XIO_FLASH_CMD_B(x) ((x<<8) & 0x0000FF00) +#define PNX8550_XIO_FLASH_CMD_A(x) (x & 0x000000FF) + +#define PNX8550_XIO_INT_ACK 0x00004000 +#define PNX8550_XIO_INT_COMPL 0x00002000 +#define PNX8550_XIO_INT_NONSUP 0x00000200 +#define PNX8550_XIO_INT_ABORT 0x00000004 + +#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400 +#define PNX8550_DMA_CTRL_SND2XIO 0x00000200 +#define PNX8550_DMA_CTRL_FIX_ADDR 0x00000100 +#define PNX8550_DMA_CTRL_BURST_8 0x00000000 +#define PNX8550_DMA_CTRL_BURST_16 0x00000020 +#define PNX8550_DMA_CTRL_BURST_32 0x00000040 +#define PNX8550_DMA_CTRL_BURST_64 0x00000060 +#define PNX8550_DMA_CTRL_BURST_128 0x00000080 +#define PNX8550_DMA_CTRL_BURST_256 0x000000A0 +#define PNX8550_DMA_CTRL_BURST_512 0x000000C0 +#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0 +#define PNX8550_DMA_CTRL_INIT_DMA 0x00000010 +#define PNX8550_DMA_CTRL_CMD_TYPE 0x0000000F + +/* see PCI system arch, page 100 for the full list: */ +#define PNX8550_DMA_CTRL_PCI_CMD_READ 0x00000006 +#define PNX8550_DMA_CTRL_PCI_CMD_WRITE 0x00000007 + +#define PNX8550_DMA_INT_STAT_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_STAT_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_STAT_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_STAT_PERR5 (1<<5) +#define PNX8550_DMA_INT_STAT_PERR4 (1<<4) +#define PNX8550_DMA_INT_STAT_M_ABORT (1<<2) +#define PNX8550_DMA_INT_STAT_T_ABORT (1<<1) + +#define PNX8550_DMA_INT_EN_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_EN_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_EN_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_EN_PERR5 (1<<5) +#define PNX8550_DMA_INT_EN_PERR4 (1<<4) +#define PNX8550_DMA_INT_EN_M_ABORT (1<<2) +#define PNX8550_DMA_INT_EN_T_ABORT (1<<1) + +#define PNX8550_DMA_INT_CLR_ACK_DONE (1<<14) +#define PNX8550_DMA_INT_CLR_DMA_DONE (1<<12) +#define PNX8550_DMA_INT_CLR_DMA_ERR (1<<9) +#define PNX8550_DMA_INT_CLR_PERR5 (1<<5) +#define PNX8550_DMA_INT_CLR_PERR4 (1<<4) +#define PNX8550_DMA_INT_CLR_M_ABORT (1<<2) +#define PNX8550_DMA_INT_CLR_T_ABORT (1<<1) + +#endif diff --git a/include/asm-mips/mach-pnx8550/pci.h b/include/asm-mips/mach-pnx8550/pci.h new file mode 100644 index 0000000..b921508 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/pci.h @@ -0,0 +1,185 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PCI specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_PCI_H +#define __PNX8550_PCI_H + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define PCI_CMD_IOR 0x20 +#define PCI_CMD_IOW 0x30 +#define PCI_CMD_CONFIG_READ 0xa0 +#define PCI_CMD_CONFIG_WRITE 0xb0 + +#define PCI_IO_TIMEOUT 1000 +#define PCI_IO_RETRY 5 +/* Timeout for IO and CFG accesses. + This is in 1/1024 th of a jiffie(=10ms) + i.e. approx 10us */ +#define PCI_IO_JIFFIES_TIMEOUT 40 +#define PCI_IO_JIFFIES_SHIFT 10 + +#define PCI_BYTE_ENABLE_MASK 0x0000000f +#define PCI_CFG_BUS_SHIFT 16 +#define PCI_CFG_FUNC_SHIFT 8 +#define PCI_CFG_REG_SHIFT 2 + +#define PCI_BASE 0x1be00000 +#define PCI_SETUP 0x00040010 +#define PCI_DIS_REQGNT (1<<30) +#define PCI_DIS_REQGNTA (1<<29) +#define PCI_DIS_REQGNTB (1<<28) +#define PCI_D2_SUPPORT (1<<27) +#define PCI_D1_SUPPORT (1<<26) +#define PCI_EN_TA (1<<24) +#define PCI_EN_PCI2MMI (1<<23) +#define PCI_EN_XIO (1<<22) +#define PCI_BASE18_PREF (1<<21) +#define SIZE_16M 0x3 +#define SIZE_32M 0x4 +#define SIZE_64M 0x5 +#define SIZE_128M 0x6 +#define PCI_SETUP_BASE18_SIZE(X) (X<<18) +#define PCI_SETUP_BASE18_EN (1<<17) +#define PCI_SETUP_BASE14_PREF (1<<16) +#define PCI_SETUP_BASE14_SIZE(X) (X<<12) +#define PCI_SETUP_BASE14_EN (1<<11) +#define PCI_SETUP_BASE10_PREF (1<<10) +#define PCI_SETUP_BASE10_SIZE(X) (X<<7) +#define PCI_SETUP_CFGMANAGE_EN (1<<1) +#define PCI_SETUP_PCIARB_EN (1<<0) + +#define PCI_CTRL 0x040014 +#define PCI_SWPB_DCS_PCI (1<<16) +#define PCI_SWPB_PCI_PCI (1<<15) +#define PCI_SWPB_PCI_DCS (1<<14) +#define PCI_REG_WR_POST (1<<13) +#define PCI_XIO_WR_POST (1<<12) +#define PCI_PCI2_WR_POST (1<<13) +#define PCI_PCI1_WR_POST (1<<12) +#define PCI_SERR_SEEN (1<<11) +#define PCI_B10_SPEC_RD (1<<6) +#define PCI_B14_SPEC_RD (1<<5) +#define PCI_B18_SPEC_RD (1<<4) +#define PCI_B10_NOSUBWORD (1<<3) +#define PCI_B14_NOSUBWORD (1<<2) +#define PCI_B18_NOSUBWORD (1<<1) +#define PCI_RETRY_TMREN (1<<0) + +#define PCI_BASE1_LO 0x040018 +#define PCI_BASE1_HI 0x04001C +#define PCI_BASE2_LO 0x040020 +#define PCI_BASE2_HI 0x040024 +#define PCI_RDLIFETIM 0x040028 +#define PCI_GPPM_ADDR 0x04002C +#define PCI_GPPM_WDAT 0x040030 +#define PCI_GPPM_RDAT 0x040034 +#define PCI_GPPM_CTRL 0x040038 +#define GPPM_DONE (1<<10) +#define INIT_PCI_CYCLE (1<<9) +#define GPPM_CMD(X) (((X)&0xf)<<4) +#define GPPM_BYTEEN(X) ((X)&0xf) +#define PCI_UNLOCKREG 0x04003C +#define UNLOCK_SSID(X) (((X)&0xff)<<8) +#define UNLOCK_SETUP(X) (((X)&0xff)<<0) +#define UNLOCK_MAGIC 0xCA +#define PCI_DEV_VEND_ID 0x040040 +#define DEVICE_ID(X) (((X)>>16)&0xffff) +#define VENDOR_ID(X) (((X)&0xffff)) +#define PCI_CFG_CMDSTAT 0x040044 +#define PCI_CFG_STATUS(X) (((X)>>16)&0xffff) +#define PCI_CFG_COMMAND(X) ((X)&0xffff) +#define PCI_CLASS_REV 0x040048 +#define PCI_CLASSCODE(X) (((X)>>8)&0xffffff) +#define PCI_REVID(X) ((X)&0xff) +#define PCI_LAT_TMR 0x04004c +#define PCI_BASE10 0x040050 +#define PCI_BASE14 0x040054 +#define PCI_BASE18 0x040058 +#define PCI_SUBSYS_ID 0x04006c +#define PCI_CAP_PTR 0x040074 +#define PCI_CFG_MISC 0x04007c +#define PCI_PMC 0x040080 +#define PCI_PWR_STATE 0x040084 +#define PCI_IO 0x040088 +#define PCI_SLVTUNING 0x04008C +#define PCI_DMATUNING 0x040090 +#define PCI_DMAEADDR 0x040800 +#define PCI_DMAIADDR 0x040804 +#define PCI_DMALEN 0x040808 +#define PCI_DMACTRL 0x04080C +#define PCI_XIOCTRL 0x040810 +#define PCI_SEL0PROF 0x040814 +#define PCI_SEL1PROF 0x040818 +#define PCI_SEL2PROF 0x04081C +#define PCI_GPXIOADDR 0x040820 +#define PCI_NANDCTRLS 0x400830 +#define PCI_SEL3PROF 0x040834 +#define PCI_SEL4PROF 0x040838 +#define PCI_GPXIO_STAT 0x040FB0 +#define PCI_GPXIO_IMASK 0x040FB4 +#define PCI_GPXIO_ICLR 0x040FB8 +#define PCI_GPXIO_ISET 0x040FBC +#define PCI_GPPM_STATUS 0x040FC0 +#define GPPM_DONE (1<<10) +#define GPPM_ERR (1<<9) +#define GPPM_MPAR_ERR (1<<8) +#define GPPM_PAR_ERR (1<<7) +#define GPPM_R_MABORT (1<<2) +#define GPPM_R_TABORT (1<<1) +#define PCI_GPPM_IMASK 0x040FC4 +#define PCI_GPPM_ICLR 0x040FC8 +#define PCI_GPPM_ISET 0x040FCC +#define PCI_DMA_STATUS 0x040FD0 +#define PCI_DMA_IMASK 0x040FD4 +#define PCI_DMA_ICLR 0x040FD8 +#define PCI_DMA_ISET 0x040FDC +#define PCI_ISTATUS 0x040FE0 +#define PCI_IMASK 0x040FE4 +#define PCI_ICLR 0x040FE8 +#define PCI_ISET 0x040FEC +#define PCI_MOD_ID 0x040FFC + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +/* + * Ethernet device DP83816 definition + */ +#define DP83816_IRQ_ETHER 66 + +#endif diff --git a/include/asm-mips/mach-pnx8550/uart.h b/include/asm-mips/mach-pnx8550/uart.h new file mode 100644 index 0000000..e32b9a2 --- /dev/null +++ b/include/asm-mips/mach-pnx8550/uart.h @@ -0,0 +1,16 @@ +#ifndef __IP3106_UART_H +#define __IP3106_UART_H + +#include <int.h> + +/* early macros for kgdb use. fixme: clean this up */ + +#define UART_BASE 0xbbe4a000 /* PNX8550 */ + +#define PNX8550_UART_PORT0 (UART_BASE) +#define PNX8550_UART_PORT1 (UART_BASE + 0x1000) + +#define PNX8550_UART_INT(x) (PNX8550_INT_GIC_MIN+19+x) +#define IRQ_TO_UART(x) (x-PNX8550_INT_GIC_MIN-19) + +#endif diff --git a/include/asm-mips/mach-pnx8550/usb.h b/include/asm-mips/mach-pnx8550/usb.h new file mode 100644 index 0000000..483b7fc --- /dev/null +++ b/include/asm-mips/mach-pnx8550/usb.h @@ -0,0 +1,32 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * USB specific definitions + * + * Author: source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#ifndef __PNX8550_USB_H +#define __PNX8550_USB_H + +/* + * USB Host controller + */ + +#define PNX8550_USB_OHCI_OP_BASE 0x1be48000 +#define PNX8550_USB_OHCI_OP_LEN 0x1000 + +#endif diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index a7a43ff..08aa231 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -841,12 +841,24 @@ do { \ #define read_c0_count() __read_32bit_c0_register($9, 0) #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) +#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ +#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) + +#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ +#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) + #define read_c0_entryhi() __read_ulong_c0_register($10, 0) #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) #define read_c0_compare() __read_32bit_c0_register($11, 0) #define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) +#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ +#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) + +#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ +#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) + #define read_c0_status() __read_32bit_c0_register($12, 0) #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 27db8da..2b0401b 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -39,7 +39,8 @@ #define PORT_RSA 13 #define PORT_NS16550A 14 #define PORT_XSCALE 15 -#define PORT_MAX_8250 15 /* max port ID */ +#define PORT_IP3106 16 +#define PORT_MAX_8250 16 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed diff --git a/include/linux/serial_ip3106.h b/include/linux/serial_ip3106.h new file mode 100644 index 0000000..f500ac6 --- /dev/null +++ b/include/linux/serial_ip3106.h @@ -0,0 +1,81 @@ +/* + * Embedded Alley Solutions, source@embeddedalley.com. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_SERIAL_IP3106_H +#define _LINUX_SERIAL_IP3106_H + +#include <linux/serial_core.h> +#include <linux/device.h> + +#define IP3106_NR_PORTS 2 + +struct ip3106_port { + struct uart_port port; + struct timer_list timer; + unsigned int old_status; +}; + +/* register offsets */ +#define IP3106_LCR 0 +#define IP3106_MCR 0x004 +#define IP3106_BAUD 0x008 +#define IP3106_CFG 0x00c +#define IP3106_FIFO 0x028 +#define IP3106_ISTAT 0xfe0 +#define IP3106_IEN 0xfe4 +#define IP3106_ICLR 0xfe8 +#define IP3106_ISET 0xfec +#define IP3106_PD 0xff4 +#define IP3106_MID 0xffc + +#define IP3106_UART_LCR_TXBREAK (1<<30) +#define IP3106_UART_LCR_PAREVN 0x10000000 +#define IP3106_UART_LCR_PAREN 0x08000000 +#define IP3106_UART_LCR_2STOPB 0x04000000 +#define IP3106_UART_LCR_8BIT 0x01000000 +#define IP3106_UART_LCR_TX_RST 0x00040000 +#define IP3106_UART_LCR_RX_RST 0x00020000 +#define IP3106_UART_LCR_RX_NEXT 0x00010000 + +#define IP3106_UART_MCR_SCR 0xFF000000 +#define IP3106_UART_MCR_DCD 0x00800000 +#define IP3106_UART_MCR_CTS 0x00100000 +#define IP3106_UART_MCR_LOOP 0x00000010 +#define IP3106_UART_MCR_RTS 0x00000002 +#define IP3106_UART_MCR_DTR 0x00000001 + +#define IP3106_UART_INT_TX 0x00000080 +#define IP3106_UART_INT_EMPTY 0x00000040 +#define IP3106_UART_INT_RCVTO 0x00000020 +#define IP3106_UART_INT_RX 0x00000010 +#define IP3106_UART_INT_RXOVRN 0x00000008 +#define IP3106_UART_INT_FRERR 0x00000004 +#define IP3106_UART_INT_BREAK 0x00000002 +#define IP3106_UART_INT_PARITY 0x00000001 +#define IP3106_UART_INT_ALLRX 0x0000003F +#define IP3106_UART_INT_ALLTX 0x000000C0 + +#define IP3106_UART_FIFO_TXFIFO 0x001F0000 +#define IP3106_UART_FIFO_TXFIFO_STA (0x1f<<16) +#define IP3106_UART_FIFO_RXBRK 0x00008000 +#define IP3106_UART_FIFO_RXFE 0x00004000 +#define IP3106_UART_FIFO_RXPAR 0x00002000 +#define IP3106_UART_FIFO_RXFIFO 0x00001F00 +#define IP3106_UART_FIFO_RBRTHR 0x000000FF + +#endif |