aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/nxp
diff options
context:
space:
mode:
authorDaniel Laird <daniel.j.laird@nxp.com>2008-06-16 15:49:21 +0100
committerRalf Baechle <ralf@linux-mips.org>2008-10-27 16:18:29 +0000
commitedb6310aaa0dfc3da303a4ba6dff9dce3fbaa8d3 (patch)
treec57fb86878978d13b4959109f1a9760b18cc177b /arch/mips/nxp
parent537fa37c8606793b9998c35de0abfcb7d549a3f2 (diff)
MIPS: Add support for NXP PNX833x (STB222/5) into linux kernel
The following patch add support for the NXP PNX833x SOC. More specifically it adds support for the STB222/5 variant. It fixes the vectored interrupt issue. Signed-off-by: daniel.j.laird <daniel.j.laird@nxp.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/nxp')
-rw-r--r--arch/mips/nxp/pnx833x/common/Makefile3
-rw-r--r--arch/mips/nxp/pnx833x/common/interrupts.c380
-rw-r--r--arch/mips/nxp/pnx833x/common/platform.c319
-rw-r--r--arch/mips/nxp/pnx833x/common/prom.c70
-rw-r--r--arch/mips/nxp/pnx833x/common/reset.c45
-rw-r--r--arch/mips/nxp/pnx833x/common/setup.c64
-rw-r--r--arch/mips/nxp/pnx833x/stb22x/Makefile3
-rw-r--r--arch/mips/nxp/pnx833x/stb22x/board.c133
8 files changed, 1017 insertions, 0 deletions
diff --git a/arch/mips/nxp/pnx833x/common/Makefile b/arch/mips/nxp/pnx833x/common/Makefile
new file mode 100644
index 00000000000..4a16f3b503b
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/Makefile
@@ -0,0 +1,3 @@
+obj-y := interrupts.o platform.o prom.o setup.o reset.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c
new file mode 100644
index 00000000000..30533ba200e
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/interrupts.c
@@ -0,0 +1,380 @@
+/*
+ * interrupts.c: Interrupt mappings for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <asm/mipsregs.h>
+#include <asm/irq_cpu.h>
+#include <irq.h>
+#include <irq-mapping.h>
+#include <gpio.h>
+
+static int mips_cpu_timer_irq;
+
+static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] =
+{
+ 0, /* unused */
+ 4, /* PNX833X_PIC_I2C0_INT 1 */
+ 4, /* PNX833X_PIC_I2C1_INT 2 */
+ 1, /* PNX833X_PIC_UART0_INT 3 */
+ 1, /* PNX833X_PIC_UART1_INT 4 */
+ 6, /* PNX833X_PIC_TS_IN0_DV_INT 5 */
+ 6, /* PNX833X_PIC_TS_IN0_DMA_INT 6 */
+ 7, /* PNX833X_PIC_GPIO_INT 7 */
+ 4, /* PNX833X_PIC_AUDIO_DEC_INT 8 */
+ 5, /* PNX833X_PIC_VIDEO_DEC_INT 9 */
+ 4, /* PNX833X_PIC_CONFIG_INT 10 */
+ 4, /* PNX833X_PIC_AOI_INT 11 */
+ 9, /* PNX833X_PIC_SYNC_INT 12 */
+ 9, /* PNX8335_PIC_SATA_INT 13 */
+ 4, /* PNX833X_PIC_OSD_INT 14 */
+ 9, /* PNX833X_PIC_DISP1_INT 15 */
+ 4, /* PNX833X_PIC_DEINTERLACER_INT 16 */
+ 9, /* PNX833X_PIC_DISPLAY2_INT 17 */
+ 4, /* PNX833X_PIC_VC_INT 18 */
+ 4, /* PNX833X_PIC_SC_INT 19 */
+ 9, /* PNX833X_PIC_IDE_INT 20 */
+ 9, /* PNX833X_PIC_IDE_DMA_INT 21 */
+ 6, /* PNX833X_PIC_TS_IN1_DV_INT 22 */
+ 6, /* PNX833X_PIC_TS_IN1_DMA_INT 23 */
+ 4, /* PNX833X_PIC_SGDX_DMA_INT 24 */
+ 4, /* PNX833X_PIC_TS_OUT_INT 25 */
+ 4, /* PNX833X_PIC_IR_INT 26 */
+ 3, /* PNX833X_PIC_VMSP1_INT 27 */
+ 3, /* PNX833X_PIC_VMSP2_INT 28 */
+ 4, /* PNX833X_PIC_PIBC_INT 29 */
+ 4, /* PNX833X_PIC_TS_IN0_TRD_INT 30 */
+ 4, /* PNX833X_PIC_SGDX_TPD_INT 31 */
+ 5, /* PNX833X_PIC_USB_INT 32 */
+ 4, /* PNX833X_PIC_TS_IN1_TRD_INT 33 */
+ 4, /* PNX833X_PIC_CLOCK_INT 34 */
+ 4, /* PNX833X_PIC_SGDX_PARSER_INT 35 */
+ 4, /* PNX833X_PIC_VMSP_DMA_INT 36 */
+#if defined(CONFIG_SOC_PNX8335)
+ 4, /* PNX8335_PIC_MIU_INT 37 */
+ 4, /* PNX8335_PIC_AVCHIP_IRQ_INT 38 */
+ 9, /* PNX8335_PIC_SYNC_HD_INT 39 */
+ 9, /* PNX8335_PIC_DISP_HD_INT 40 */
+ 9, /* PNX8335_PIC_DISP_SCALER_INT 41 */
+ 4, /* PNX8335_PIC_OSD_HD1_INT 42 */
+ 4, /* PNX8335_PIC_DTL_WRITER_Y_INT 43 */
+ 4, /* PNX8335_PIC_DTL_WRITER_C_INT 44 */
+ 4, /* PNX8335_PIC_DTL_EMULATOR_Y_IR_INT 45 */
+ 4, /* PNX8335_PIC_DTL_EMULATOR_C_IR_INT 46 */
+ 4, /* PNX8335_PIC_DENC_TTX_INT 47 */
+ 4, /* PNX8335_PIC_MMI_SIF0_INT 48 */
+ 4, /* PNX8335_PIC_MMI_SIF1_INT 49 */
+ 4, /* PNX8335_PIC_MMI_CDMMU_INT 50 */
+ 4, /* PNX8335_PIC_PIBCS_INT 51 */
+ 12, /* PNX8335_PIC_ETHERNET_INT 52 */
+ 3, /* PNX8335_PIC_VMSP1_0_INT 53 */
+ 3, /* PNX8335_PIC_VMSP1_1_INT 54 */
+ 4, /* PNX8335_PIC_VMSP1_DMA_INT 55 */
+ 4, /* PNX8335_PIC_TDGR_DE_INT 56 */
+ 4, /* PNX8335_PIC_IR1_IRQ_INT 57 */
+#endif
+};
+
+static void pnx833x_timer_dispatch(void)
+{
+ do_IRQ(mips_cpu_timer_irq);
+}
+
+static void pic_dispatch(void)
+{
+ unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC);
+
+ if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) {
+ unsigned long priority = PNX833X_PIC_INT_PRIORITY;
+ PNX833X_PIC_INT_PRIORITY = irq_prio[irq];
+
+ if (irq == PNX833X_PIC_GPIO_INT) {
+ unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE;
+ int pin;
+ while ((pin = ffs(mask & 0xffff))) {
+ pin -= 1;
+ do_IRQ(PNX833X_GPIO_IRQ_BASE + pin);
+ mask &= ~(1 << pin);
+ }
+ } else {
+ do_IRQ(irq + PNX833X_PIC_IRQ_BASE);
+ }
+
+ PNX833X_PIC_INT_PRIORITY = priority;
+ } else {
+ printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq);
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+
+ if (pending & STATUSF_IP4)
+ pic_dispatch();
+ else if (pending & STATUSF_IP7)
+ do_IRQ(PNX833X_TIMER_IRQ);
+ else
+ spurious_interrupt();
+}
+
+static inline void pnx833x_hard_enable_pic_irq(unsigned int irq)
+{
+ /* Currently we do this by setting IRQ priority to 1.
+ If priority support is being implemented, 1 should be repalced
+ by a better value. */
+ PNX833X_PIC_INT_REG(irq) = irq_prio[irq];
+}
+
+static inline void pnx833x_hard_disable_pic_irq(unsigned int irq)
+{
+ /* Disable IRQ by writing setting it's priority to 0 */
+ PNX833X_PIC_INT_REG(irq) = 0;
+}
+
+static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */
+#define IRQFLAG_STARTED 1
+#define IRQFLAG_DISABLED 2
+
+static DEFINE_SPINLOCK(pnx833x_irq_lock);
+
+static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
+
+ spin_lock_irqsave(&pnx833x_irq_lock, flags);
+
+ irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */
+ pnx833x_hard_enable_pic_irq(pic_irq);
+
+ spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+ return 0;
+}
+
+static void pnx833x_shutdown_pic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
+
+ spin_lock_irqsave(&pnx833x_irq_lock, flags);
+
+ irqflags[pic_irq] = 0; /* not started */
+ pnx833x_hard_disable_pic_irq(pic_irq);
+
+ spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_enable_pic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
+
+ spin_lock_irqsave(&pnx833x_irq_lock, flags);
+
+ irqflags[pic_irq] &= ~IRQFLAG_DISABLED;
+ if (irqflags[pic_irq] == IRQFLAG_STARTED)
+ pnx833x_hard_enable_pic_irq(pic_irq);
+
+ spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_disable_pic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
+
+ spin_lock_irqsave(&pnx833x_irq_lock, flags);
+
+ irqflags[pic_irq] |= IRQFLAG_DISABLED;
+ pnx833x_hard_disable_pic_irq(pic_irq);
+
+ spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_ack_pic_irq(unsigned int irq)
+{
+}
+
+static void pnx833x_end_pic_irq(unsigned int irq)
+{
+}
+
+static DEFINE_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
+
+static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
+{
+ int pin = irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_enable_irq(pin);
+ spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ return 0;
+}
+
+static void pnx833x_enable_gpio_irq(unsigned int irq)
+{
+ int pin = irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_enable_irq(pin);
+ spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_disable_gpio_irq(unsigned int irq)
+{
+ int pin = irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_disable_irq(pin);
+ spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_ack_gpio_irq(unsigned int irq)
+{
+}
+
+static void pnx833x_end_gpio_irq(unsigned int irq)
+{
+ int pin = irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_clear_irq(pin);
+ spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+}
+
+static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
+{
+ int pin = irq - PNX833X_GPIO_IRQ_BASE;
+ int gpio_mode;
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ gpio_mode = GPIO_INT_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ gpio_mode = GPIO_INT_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ gpio_mode = GPIO_INT_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ gpio_mode = GPIO_INT_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ gpio_mode = GPIO_INT_LEVEL_LOW;
+ break;
+ default:
+ gpio_mode = GPIO_INT_NONE;
+ break;
+ }
+
+ pnx833x_gpio_setup_irq(gpio_mode, pin);
+
+ return 0;
+}
+
+static struct irq_chip pnx833x_pic_irq_type = {
+ .typename = "PNX-PIC",
+ .startup = pnx833x_startup_pic_irq,
+ .shutdown = pnx833x_shutdown_pic_irq,
+ .enable = pnx833x_enable_pic_irq,
+ .disable = pnx833x_disable_pic_irq,
+ .ack = pnx833x_ack_pic_irq,
+ .end = pnx833x_end_pic_irq
+};
+
+static struct irq_chip pnx833x_gpio_irq_type = {
+ .typename = "PNX-GPIO",
+ .startup = pnx833x_startup_gpio_irq,
+ .shutdown = pnx833x_disable_gpio_irq,
+ .enable = pnx833x_enable_gpio_irq,
+ .disable = pnx833x_disable_gpio_irq,
+ .ack = pnx833x_ack_gpio_irq,
+ .end = pnx833x_end_gpio_irq,
+ .set_type = pnx833x_set_type_gpio_irq
+};
+
+void __init arch_init_irq(void)
+{
+ unsigned int irq;
+
+ /* setup standard internal cpu irqs */
+ mips_cpu_irq_init();
+
+ /* Set IRQ information in irq_desc */
+ for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) {
+ pnx833x_hard_disable_pic_irq(irq);
+ set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq);
+ }
+
+ for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++)
+ set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq);
+
+ /* Set PIC priority limiter register to 0 */
+ PNX833X_PIC_INT_PRIORITY = 0;
+
+ /* Setup GPIO IRQ dispatching */
+ pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT);
+
+ /* Enable PIC IRQs (HWIRQ2) */
+ if (cpu_has_vint)
+ set_vi_handler(4, pic_dispatch);
+
+ write_c0_status(read_c0_status() | IE_IRQ2);
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ if (cpu_has_vint)
+ set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch);
+
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+ /* calculate mips_hpt_frequency based on PNX833X_CLOCK_CPUCP_CTL reg */
+
+ extern unsigned long mips_hpt_frequency;
+ unsigned long reg = PNX833X_CLOCK_CPUCP_CTL;
+
+ if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) {
+ /* Functional clock is disabled so use crystal frequency */
+ mips_hpt_frequency = 25;
+ } else {
+#if defined(CONFIG_SOC_PNX8335)
+ /* Functional clock is enabled, so get clock multiplier */
+ mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ));
+#else
+ static const unsigned long int freq[4] = {240, 160, 120, 80};
+ mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)];
+#endif
+ }
+
+ printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency);
+
+ mips_hpt_frequency *= 500000;
+}
+
diff --git a/arch/mips/nxp/pnx833x/common/platform.c b/arch/mips/nxp/pnx833x/common/platform.c
new file mode 100644
index 00000000000..b1ccbcc18f7
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/platform.c
@@ -0,0 +1,319 @@
+/*
+ * platform.c: platform support for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#ifdef CONFIG_I2C_PNX0105
+/* Until i2c driver available in kernel.*/
+#include <linux/i2c-pnx0105.h>
+#endif
+
+#include <irq.h>
+#include <irq-mapping.h>
+#include <pnx833x.h>
+
+static u64 uart_dmamask = DMA_32BIT_MASK;
+
+static struct resource pnx833x_uart_resources[] = {
+ [0] = {
+ .start = PNX833X_UART0_PORTS_START,
+ .end = PNX833X_UART0_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX833X_PIC_UART0_INT,
+ .end = PNX833X_PIC_UART0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = PNX833X_UART1_PORTS_START,
+ .end = PNX833X_UART1_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = PNX833X_PIC_UART1_INT,
+ .end = PNX833X_PIC_UART1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct pnx8xxx_port pnx8xxx_ports[] = {
+ [0] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX833X_UART0_PORTS_START,
+ .mapbase = PNX833X_UART0_PORTS_START,
+ .irq = PNX833X_PIC_UART0_INT,
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ [1] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX833X_UART1_PORTS_START,
+ .mapbase = PNX833X_UART1_PORTS_START,
+ .irq = PNX833X_PIC_UART1_INT,
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+};
+
+static struct platform_device pnx833x_uart_device = {
+ .name = "pnx8xxx-uart",
+ .id = -1,
+ .dev = {
+ .dma_mask = &uart_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = pnx8xxx_ports,
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_uart_resources),
+ .resource = pnx833x_uart_resources,
+};
+
+static u64 ehci_dmamask = DMA_32BIT_MASK;
+
+static struct resource pnx833x_usb_ehci_resources[] = {
+ [0] = {
+ .start = PNX833X_USB_PORTS_START,
+ .end = PNX833X_USB_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX833X_PIC_USB_INT,
+ .end = PNX833X_PIC_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_usb_ehci_device = {
+ .name = "pnx833x-ehci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources),
+ .resource = pnx833x_usb_ehci_resources,
+};
+
+#ifdef CONFIG_I2C_PNX0105
+static struct resource pnx833x_i2c0_resources[] = {
+ {
+ .start = PNX833X_I2C0_PORTS_START,
+ .end = PNX833X_I2C0_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PNX833X_PIC_I2C0_INT,
+ .end = PNX833X_PIC_I2C0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pnx833x_i2c1_resources[] = {
+ {
+ .start = PNX833X_I2C1_PORTS_START,
+ .end = PNX833X_I2C1_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PNX833X_PIC_I2C1_INT,
+ .end = PNX833X_PIC_I2C1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = {
+ {
+ .base = PNX833X_I2C0_PORTS_START,
+ .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */
+ .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Prefered HDCP) */
+ .bus_addr = 0, /* no slave support */
+ },
+ {
+ .base = PNX833X_I2C1_PORTS_START,
+ .irq = -1, /* on high freq, polling is faster */
+ /*.irq = PNX833X_PIC_I2C1_INT,*/
+ .clock = 4, /* 0 == 400 kHz, 4 == 100 kHz. 100 kHz seems a safe default for now */
+ .bus_addr = 0, /* no slave support */
+ },
+};
+
+static struct platform_device pnx833x_i2c0_device = {
+ .name = "i2c-pnx0105",
+ .id = 0,
+ .dev = {
+ .platform_data = &pnx833x_i2c_dev[0],
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_i2c0_resources),
+ .resource = pnx833x_i2c0_resources,
+};
+
+static struct platform_device pnx833x_i2c1_device = {
+ .name = "i2c-pnx0105",
+ .id = 1,
+ .dev = {
+ .platform_data = &pnx833x_i2c_dev[1],
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_i2c1_resources),
+ .resource = pnx833x_i2c1_resources,
+};
+#endif
+
+static u64 ethernet_dmamask = DMA_32BIT_MASK;
+
+static struct resource pnx833x_ethernet_resources[] = {
+ [0] = {
+ .start = PNX8335_IP3902_PORTS_START,
+ .end = PNX8335_IP3902_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8335_PIC_ETHERNET_INT,
+ .end = PNX8335_PIC_ETHERNET_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_ethernet_device = {
+ .name = "ip3902-eth",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ethernet_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_ethernet_resources),
+ .resource = pnx833x_ethernet_resources,
+};
+
+static struct resource pnx833x_sata_resources[] = {
+ [0] = {
+ .start = PNX8335_SATA_PORTS_START,
+ .end = PNX8335_SATA_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8335_PIC_SATA_INT,
+ .end = PNX8335_PIC_SATA_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_sata_device = {
+ .name = "pnx833x-sata",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pnx833x_sata_resources),
+ .resource = pnx833x_sata_resources,
+};
+
+static const char *part_probes[] = {
+ "cmdlinepart",
+ NULL
+};
+
+static void
+pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_CLE_MASK));
+ else
+ writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_ALE_MASK));
+}
+
+static struct platform_nand_data pnx833x_flash_nand_data = {
+ .chip = {
+ .chip_delay = 25,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = pnx833x_flash_nand_cmd_ctrl
+ }
+};
+
+/*
+ * Set start to be the correct address (PNX8335_NAND_BASE with no 0xb!!),
+ * 12 bytes more seems to be the standard that allows for NAND access.
+ */
+static struct resource pnx833x_flash_nand_resource = {
+ .start = PNX8335_NAND_BASE,
+ .end = PNX8335_NAND_BASE + 12,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pnx833x_flash_nand = {
+ .name = "gen_nand",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &pnx833x_flash_nand_resource,
+ .dev = {
+ .platform_data = &pnx833x_flash_nand_data,
+ },
+};
+
+static struct platform_device *pnx833x_platform_devices[] __initdata = {
+ &pnx833x_uart_device,
+ &pnx833x_usb_ehci_device,
+#ifdef CONFIG_I2C_PNX0105
+ &pnx833x_i2c0_device,
+ &pnx833x_i2c1_device,
+#endif
+ &pnx833x_ethernet_device,
+ &pnx833x_sata_device,
+ &pnx833x_flash_nand,
+};
+
+static int __init pnx833x_platform_init(void)
+{
+ int res;
+
+ res = platform_add_devices(pnx833x_platform_devices,
+ ARRAY_SIZE(pnx833x_platform_devices));
+
+ return res;
+}
+
+arch_initcall(pnx833x_platform_init);
diff --git a/arch/mips/nxp/pnx833x/common/prom.c b/arch/mips/nxp/pnx833x/common/prom.c
new file mode 100644
index 00000000000..2a41e8fec21
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/prom.c
@@ -0,0 +1,70 @@
+/*
+ * prom.c:
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+
+void __init prom_init_cmdline(void)
+{
+ int argc = fw_arg0;
+ char **argv = (char **)fw_arg1;
+ char *c = &(arcs_cmdline[0]);
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ strcpy(c, argv[i]);
+ c += strlen(argv[i]);
+ if (i < argc-1)
+ *c++ = ' ';
+ }
+ *c = 0;
+}
+
+char __init *prom_getenv(char *envname)
+{
+ extern char **prom_envp;
+ char **env = prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while (*env) {
+ if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=')
+ return *env + i + 1;
+ env++;
+ }
+
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+char * __init prom_getcmdline(void)
+{
+ return arcs_cmdline;
+}
+
diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/nxp/pnx833x/common/reset.c
new file mode 100644
index 00000000000..a9bc9bacad2
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/reset.c
@@ -0,0 +1,45 @@
+/*
+ * reset.c: reset support for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/slab.h>
+#include <linux/reboot.h>
+#include <pnx833x.h>
+
+void pnx833x_machine_restart(char *command)
+{
+ PNX833X_RESET_CONTROL_2 = 0;
+ PNX833X_RESET_CONTROL = 0;
+}
+
+void pnx833x_machine_halt(void)
+{
+ while (1)
+ __asm__ __volatile__ ("wait");
+
+}
+
+void pnx833x_machine_power_off(void)
+{
+ pnx833x_machine_halt();
+}
diff --git a/arch/mips/nxp/pnx833x/common/setup.c b/arch/mips/nxp/pnx833x/common/setup.c
new file mode 100644
index 00000000000..e51fbc4b644
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/common/setup.c
@@ -0,0 +1,64 @@
+/*
+ * setup.c: Setup PNX833X Soc.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <asm/reboot.h>
+#include <pnx833x.h>
+#include <gpio.h>
+
+extern void pnx833x_board_setup(void);
+extern void pnx833x_machine_restart(char *);
+extern void pnx833x_machine_halt(void);
+extern void pnx833x_machine_power_off(void);
+
+int __init plat_mem_setup(void)
+{
+ /* fake pci bus to avoid bounce buffers */
+ PCI_DMA_BUS_IS_PHYS = 1;
+
+ /* set mips clock to 320MHz */
+#if defined(CONFIG_SOC_PNX8335)
+ PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ);
+#endif
+ pnx833x_gpio_init(); /* so it will be ready in board_setup() */
+
+ pnx833x_board_setup();
+
+ _machine_restart = pnx833x_machine_restart;
+ _machine_halt = pnx833x_machine_halt;
+ pm_power_off = pnx833x_machine_power_off;
+
+ /* IO/MEM resources. */
+ set_io_port_base(KSEG1);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ return 0;
+}
diff --git a/arch/mips/nxp/pnx833x/stb22x/Makefile b/arch/mips/nxp/pnx833x/stb22x/Makefile
new file mode 100644
index 00000000000..f81c5801f45
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/stb22x/Makefile
@@ -0,0 +1,3 @@
+lib-y := board.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/nxp/pnx833x/stb22x/board.c
new file mode 100644
index 00000000000..90cc604bdad
--- /dev/null
+++ b/arch/mips/nxp/pnx833x/stb22x/board.c
@@ -0,0 +1,133 @@
+/*
+ * board.c: STB225 board support.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <linux/mm.h>
+#include <pnx833x.h>
+#include <gpio.h>
+
+/* endianess twiddlers */
+#define PNX8335_DEBUG0 0x4400
+#define PNX8335_DEBUG1 0x4404
+#define PNX8335_DEBUG2 0x4408
+#define PNX8335_DEBUG3 0x440c
+#define PNX8335_DEBUG4 0x4410
+#define PNX8335_DEBUG5 0x4414
+#define PNX8335_DEBUG6 0x4418
+#define PNX8335_DEBUG7 0x441c
+
+int prom_argc;
+char **prom_argv = 0, **prom_envp = 0;
+
+extern void prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "NXP STB22x";
+}
+
+static inline unsigned long env_or_default(char *env, unsigned long dfl)
+{
+ char *str = prom_getenv(env);
+ return str ? simple_strtol(str, 0, 0) : dfl;
+}
+
+void __init prom_init(void)
+{
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize = env_or_default("memsize", 0x02000000);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void __init pnx833x_board_setup(void)
+{
+ pnx833x_gpio_select_function_alt(4);
+ pnx833x_gpio_select_output(4);
+ pnx833x_gpio_select_function_alt(5);
+ pnx833x_gpio_select_input(5);
+ pnx833x_gpio_select_function_alt(6);
+ pnx833x_gpio_select_input(6);
+ pnx833x_gpio_select_function_alt(7);
+ pnx833x_gpio_select_output(7);
+
+ pnx833x_gpio_select_function_alt(25);
+ pnx833x_gpio_select_function_alt(26);
+
+ pnx833x_gpio_select_function_alt(27);
+ pnx833x_gpio_select_function_alt(28);
+ pnx833x_gpio_select_function_alt(29);
+ pnx833x_gpio_select_function_alt(30);
+ pnx833x_gpio_select_function_alt(31);
+ pnx833x_gpio_select_function_alt(32);
+ pnx833x_gpio_select_function_alt(33);
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+ /* Setup MIU for NAND access on CS0...
+ *
+ * (it seems that we must also configure CS1 for reliable operation,
+ * otherwise the first read ID command will fail if it's read as 4 bytes
+ * but pass if it's read as 1 word.)
+ */
+
+ /* Setup MIU CS0 & CS1 timing */
+ PNX833X_MIU_SEL0 = 0;
+ PNX833X_MIU_SEL1 = 0;
+ PNX833X_MIU_SEL0_TIMING = 0x50003081;
+ PNX833X_MIU_SEL1_TIMING = 0x50003081;
+
+ /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
+ pnx833x_gpio_select_function_alt(0);
+
+ /* Setup GPIO 04 to input NAND read/busy signal */
+ pnx833x_gpio_select_function_io(4);
+ pnx833x_gpio_select_input(4);
+
+ /* Setup GPIO 05 to disable NAND write protect */
+ pnx833x_gpio_select_function_io(5);
+ pnx833x_gpio_select_output(5);
+ pnx833x_gpio_write(1, 5);
+
+#elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE)
+
+ /* Set up MIU for 16-bit NOR access on CS0 and CS1... */
+
+ /* Setup MIU CS0 & CS1 timing */
+ PNX833X_MIU_SEL0 = 1;
+ PNX833X_MIU_SEL1 = 1;
+ PNX833X_MIU_SEL0_TIMING = 0x6A08D082;
+ PNX833X_MIU_SEL1_TIMING = 0x6A08D082;
+
+ /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
+ pnx833x_gpio_select_function_alt(0);
+#endif
+}