aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pnx833x
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pnx833x')
-rw-r--r--arch/mips/pnx833x/common/Makefile3
-rw-r--r--arch/mips/pnx833x/common/interrupts.c379
-rw-r--r--arch/mips/pnx833x/common/platform.c319
-rw-r--r--arch/mips/pnx833x/common/prom.c64
-rw-r--r--arch/mips/pnx833x/common/reset.c44
-rw-r--r--arch/mips/pnx833x/common/setup.c64
-rw-r--r--arch/mips/pnx833x/stb22x/Makefile3
-rw-r--r--arch/mips/pnx833x/stb22x/board.c133
8 files changed, 1009 insertions, 0 deletions
diff --git a/arch/mips/pnx833x/common/Makefile b/arch/mips/pnx833x/common/Makefile
new file mode 100644
index 000000000000..4a16f3b503b5
--- /dev/null
+++ b/arch/mips/pnx833x/common/Makefile
@@ -0,0 +1,3 @@
1obj-y := interrupts.o platform.o prom.o setup.o reset.o
2
3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c
new file mode 100644
index 000000000000..941916f8aaff
--- /dev/null
+++ b/arch/mips/pnx833x/common/interrupts.c
@@ -0,0 +1,379 @@
1/*
2 * interrupts.c: Interrupt mappings for PNX833X.
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#include <linux/kernel.h>
23#include <linux/irq.h>
24#include <linux/hardirq.h>
25#include <linux/interrupt.h>
26#include <asm/mipsregs.h>
27#include <asm/irq_cpu.h>
28#include <irq.h>
29#include <irq-mapping.h>
30#include <gpio.h>
31
32static int mips_cpu_timer_irq;
33
34static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] =
35{
36 0, /* unused */
37 4, /* PNX833X_PIC_I2C0_INT 1 */
38 4, /* PNX833X_PIC_I2C1_INT 2 */
39 1, /* PNX833X_PIC_UART0_INT 3 */
40 1, /* PNX833X_PIC_UART1_INT 4 */
41 6, /* PNX833X_PIC_TS_IN0_DV_INT 5 */
42 6, /* PNX833X_PIC_TS_IN0_DMA_INT 6 */
43 7, /* PNX833X_PIC_GPIO_INT 7 */
44 4, /* PNX833X_PIC_AUDIO_DEC_INT 8 */
45 5, /* PNX833X_PIC_VIDEO_DEC_INT 9 */
46 4, /* PNX833X_PIC_CONFIG_INT 10 */
47 4, /* PNX833X_PIC_AOI_INT 11 */
48 9, /* PNX833X_PIC_SYNC_INT 12 */
49 9, /* PNX8335_PIC_SATA_INT 13 */
50 4, /* PNX833X_PIC_OSD_INT 14 */
51 9, /* PNX833X_PIC_DISP1_INT 15 */
52 4, /* PNX833X_PIC_DEINTERLACER_INT 16 */
53 9, /* PNX833X_PIC_DISPLAY2_INT 17 */
54 4, /* PNX833X_PIC_VC_INT 18 */
55 4, /* PNX833X_PIC_SC_INT 19 */
56 9, /* PNX833X_PIC_IDE_INT 20 */
57 9, /* PNX833X_PIC_IDE_DMA_INT 21 */
58 6, /* PNX833X_PIC_TS_IN1_DV_INT 22 */
59 6, /* PNX833X_PIC_TS_IN1_DMA_INT 23 */
60 4, /* PNX833X_PIC_SGDX_DMA_INT 24 */
61 4, /* PNX833X_PIC_TS_OUT_INT 25 */
62 4, /* PNX833X_PIC_IR_INT 26 */
63 3, /* PNX833X_PIC_VMSP1_INT 27 */
64 3, /* PNX833X_PIC_VMSP2_INT 28 */
65 4, /* PNX833X_PIC_PIBC_INT 29 */
66 4, /* PNX833X_PIC_TS_IN0_TRD_INT 30 */
67 4, /* PNX833X_PIC_SGDX_TPD_INT 31 */
68 5, /* PNX833X_PIC_USB_INT 32 */
69 4, /* PNX833X_PIC_TS_IN1_TRD_INT 33 */
70 4, /* PNX833X_PIC_CLOCK_INT 34 */
71 4, /* PNX833X_PIC_SGDX_PARSER_INT 35 */
72 4, /* PNX833X_PIC_VMSP_DMA_INT 36 */
73#if defined(CONFIG_SOC_PNX8335)
74 4, /* PNX8335_PIC_MIU_INT 37 */
75 4, /* PNX8335_PIC_AVCHIP_IRQ_INT 38 */
76 9, /* PNX8335_PIC_SYNC_HD_INT 39 */
77 9, /* PNX8335_PIC_DISP_HD_INT 40 */
78 9, /* PNX8335_PIC_DISP_SCALER_INT 41 */
79 4, /* PNX8335_PIC_OSD_HD1_INT 42 */
80 4, /* PNX8335_PIC_DTL_WRITER_Y_INT 43 */
81 4, /* PNX8335_PIC_DTL_WRITER_C_INT 44 */
82 4, /* PNX8335_PIC_DTL_EMULATOR_Y_IR_INT 45 */
83 4, /* PNX8335_PIC_DTL_EMULATOR_C_IR_INT 46 */
84 4, /* PNX8335_PIC_DENC_TTX_INT 47 */
85 4, /* PNX8335_PIC_MMI_SIF0_INT 48 */
86 4, /* PNX8335_PIC_MMI_SIF1_INT 49 */
87 4, /* PNX8335_PIC_MMI_CDMMU_INT 50 */
88 4, /* PNX8335_PIC_PIBCS_INT 51 */
89 12, /* PNX8335_PIC_ETHERNET_INT 52 */
90 3, /* PNX8335_PIC_VMSP1_0_INT 53 */
91 3, /* PNX8335_PIC_VMSP1_1_INT 54 */
92 4, /* PNX8335_PIC_VMSP1_DMA_INT 55 */
93 4, /* PNX8335_PIC_TDGR_DE_INT 56 */
94 4, /* PNX8335_PIC_IR1_IRQ_INT 57 */
95#endif
96};
97
98static void pnx833x_timer_dispatch(void)
99{
100 do_IRQ(mips_cpu_timer_irq);
101}
102
103static void pic_dispatch(void)
104{
105 unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC);
106
107 if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) {
108 unsigned long priority = PNX833X_PIC_INT_PRIORITY;
109 PNX833X_PIC_INT_PRIORITY = irq_prio[irq];
110
111 if (irq == PNX833X_PIC_GPIO_INT) {
112 unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE;
113 int pin;
114 while ((pin = ffs(mask & 0xffff))) {
115 pin -= 1;
116 do_IRQ(PNX833X_GPIO_IRQ_BASE + pin);
117 mask &= ~(1 << pin);
118 }
119 } else {
120 do_IRQ(irq + PNX833X_PIC_IRQ_BASE);
121 }
122
123 PNX833X_PIC_INT_PRIORITY = priority;
124 } else {
125 printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq);
126 }
127}
128
129asmlinkage void plat_irq_dispatch(void)
130{
131 unsigned int pending = read_c0_status() & read_c0_cause();
132
133 if (pending & STATUSF_IP4)
134 pic_dispatch();
135 else if (pending & STATUSF_IP7)
136 do_IRQ(PNX833X_TIMER_IRQ);
137 else
138 spurious_interrupt();
139}
140
141static inline void pnx833x_hard_enable_pic_irq(unsigned int irq)
142{
143 /* Currently we do this by setting IRQ priority to 1.
144 If priority support is being implemented, 1 should be repalced
145 by a better value. */
146 PNX833X_PIC_INT_REG(irq) = irq_prio[irq];
147}
148
149static inline void pnx833x_hard_disable_pic_irq(unsigned int irq)
150{
151 /* Disable IRQ by writing setting it's priority to 0 */
152 PNX833X_PIC_INT_REG(irq) = 0;
153}
154
155static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */
156#define IRQFLAG_STARTED 1
157#define IRQFLAG_DISABLED 2
158
159static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
160
161static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
162{
163 unsigned long flags;
164 unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
165
166 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
167
168 irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */
169 pnx833x_hard_enable_pic_irq(pic_irq);
170
171 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
172 return 0;
173}
174
175static void pnx833x_shutdown_pic_irq(unsigned int irq)
176{
177 unsigned long flags;
178 unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
179
180 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
181
182 irqflags[pic_irq] = 0; /* not started */
183 pnx833x_hard_disable_pic_irq(pic_irq);
184
185 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
186}
187
188static void pnx833x_enable_pic_irq(unsigned int irq)
189{
190 unsigned long flags;
191 unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
192
193 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
194
195 irqflags[pic_irq] &= ~IRQFLAG_DISABLED;
196 if (irqflags[pic_irq] == IRQFLAG_STARTED)
197 pnx833x_hard_enable_pic_irq(pic_irq);
198
199 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
200}
201
202static void pnx833x_disable_pic_irq(unsigned int irq)
203{
204 unsigned long flags;
205 unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
206
207 raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
208
209 irqflags[pic_irq] |= IRQFLAG_DISABLED;
210 pnx833x_hard_disable_pic_irq(pic_irq);
211
212 raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
213}
214
215static void pnx833x_ack_pic_irq(unsigned int irq)
216{
217}
218
219static void pnx833x_end_pic_irq(unsigned int irq)
220{
221}
222
223static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
224
225static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
226{
227 int pin = irq - PNX833X_GPIO_IRQ_BASE;
228 unsigned long flags;
229 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
230 pnx833x_gpio_enable_irq(pin);
231 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
232 return 0;
233}
234
235static void pnx833x_enable_gpio_irq(unsigned int irq)
236{
237 int pin = irq - PNX833X_GPIO_IRQ_BASE;
238 unsigned long flags;
239 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
240 pnx833x_gpio_enable_irq(pin);
241 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
242}
243
244static void pnx833x_disable_gpio_irq(unsigned int irq)
245{
246 int pin = irq - PNX833X_GPIO_IRQ_BASE;
247 unsigned long flags;
248 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
249 pnx833x_gpio_disable_irq(pin);
250 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
251}
252
253static void pnx833x_ack_gpio_irq(unsigned int irq)
254{
255}
256
257static void pnx833x_end_gpio_irq(unsigned int irq)
258{
259 int pin = irq - PNX833X_GPIO_IRQ_BASE;
260 unsigned long flags;
261 raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
262 pnx833x_gpio_clear_irq(pin);
263 raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
264}
265
266static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
267{
268 int pin = irq - PNX833X_GPIO_IRQ_BASE;
269 int gpio_mode;
270
271 switch (flow_type) {
272 case IRQ_TYPE_EDGE_RISING:
273 gpio_mode = GPIO_INT_EDGE_RISING;
274 break;
275 case IRQ_TYPE_EDGE_FALLING:
276 gpio_mode = GPIO_INT_EDGE_FALLING;
277 break;
278 case IRQ_TYPE_EDGE_BOTH:
279 gpio_mode = GPIO_INT_EDGE_BOTH;
280 break;
281 case IRQ_TYPE_LEVEL_HIGH:
282 gpio_mode = GPIO_INT_LEVEL_HIGH;
283 break;
284 case IRQ_TYPE_LEVEL_LOW:
285 gpio_mode = GPIO_INT_LEVEL_LOW;
286 break;
287 default:
288 gpio_mode = GPIO_INT_NONE;
289 break;
290 }
291
292 pnx833x_gpio_setup_irq(gpio_mode, pin);
293
294 return 0;
295}
296
297static struct irq_chip pnx833x_pic_irq_type = {
298 .name = "PNX-PIC",
299 .startup = pnx833x_startup_pic_irq,
300 .shutdown = pnx833x_shutdown_pic_irq,
301 .enable = pnx833x_enable_pic_irq,
302 .disable = pnx833x_disable_pic_irq,
303 .ack = pnx833x_ack_pic_irq,
304 .end = pnx833x_end_pic_irq
305};
306
307static struct irq_chip pnx833x_gpio_irq_type = {
308 .name = "PNX-GPIO",
309 .startup = pnx833x_startup_gpio_irq,
310 .shutdown = pnx833x_disable_gpio_irq,
311 .enable = pnx833x_enable_gpio_irq,
312 .disable = pnx833x_disable_gpio_irq,
313 .ack = pnx833x_ack_gpio_irq,
314 .end = pnx833x_end_gpio_irq,
315 .set_type = pnx833x_set_type_gpio_irq
316};
317
318void __init arch_init_irq(void)
319{
320 unsigned int irq;
321
322 /* setup standard internal cpu irqs */
323 mips_cpu_irq_init();
324
325 /* Set IRQ information in irq_desc */
326 for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) {
327 pnx833x_hard_disable_pic_irq(irq);
328 set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq);
329 }
330
331 for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++)
332 set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq);
333
334 /* Set PIC priority limiter register to 0 */
335 PNX833X_PIC_INT_PRIORITY = 0;
336
337 /* Setup GPIO IRQ dispatching */
338 pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT);
339
340 /* Enable PIC IRQs (HWIRQ2) */
341 if (cpu_has_vint)
342 set_vi_handler(4, pic_dispatch);
343
344 write_c0_status(read_c0_status() | IE_IRQ2);
345}
346
347unsigned int __cpuinit get_c0_compare_int(void)
348{
349 if (cpu_has_vint)
350 set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch);
351
352 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
353 return mips_cpu_timer_irq;
354}
355
356void __init plat_time_init(void)
357{
358 /* calculate mips_hpt_frequency based on PNX833X_CLOCK_CPUCP_CTL reg */
359
360 extern unsigned long mips_hpt_frequency;
361 unsigned long reg = PNX833X_CLOCK_CPUCP_CTL;
362
363 if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) {
364 /* Functional clock is disabled so use crystal frequency */
365 mips_hpt_frequency = 25;
366 } else {
367#if defined(CONFIG_SOC_PNX8335)
368 /* Functional clock is enabled, so get clock multiplier */
369 mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ));
370#else
371 static const unsigned long int freq[4] = {240, 160, 120, 80};
372 mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)];
373#endif
374 }
375
376 printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency);
377
378 mips_hpt_frequency *= 500000;
379}
diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c
new file mode 100644
index 000000000000..01f8345a2069
--- /dev/null
+++ b/arch/mips/pnx833x/common/platform.c
@@ -0,0 +1,319 @@
1/*
2 * platform.c: platform support for PNX833X.
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * Based on software written by:
9 * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/device.h>
26#include <linux/dma-mapping.h>
27#include <linux/platform_device.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/resource.h>
31#include <linux/serial.h>
32#include <linux/serial_pnx8xxx.h>
33#include <linux/mtd/nand.h>
34#include <linux/mtd/partitions.h>
35
36#ifdef CONFIG_I2C_PNX0105
37/* Until i2c driver available in kernel.*/
38#include <linux/i2c-pnx0105.h>
39#endif
40
41#include <irq.h>
42#include <irq-mapping.h>
43#include <pnx833x.h>
44
45static u64 uart_dmamask = DMA_BIT_MASK(32);
46
47static struct resource pnx833x_uart_resources[] = {
48 [0] = {
49 .start = PNX833X_UART0_PORTS_START,
50 .end = PNX833X_UART0_PORTS_END,
51 .flags = IORESOURCE_MEM,
52 },
53 [1] = {
54 .start = PNX833X_PIC_UART0_INT,
55 .end = PNX833X_PIC_UART0_INT,
56 .flags = IORESOURCE_IRQ,
57 },
58 [2] = {
59 .start = PNX833X_UART1_PORTS_START,
60 .end = PNX833X_UART1_PORTS_END,
61 .flags = IORESOURCE_MEM,
62 },
63 [3] = {
64 .start = PNX833X_PIC_UART1_INT,
65 .end = PNX833X_PIC_UART1_INT,
66 .flags = IORESOURCE_IRQ,
67 },
68};
69
70struct pnx8xxx_port pnx8xxx_ports[] = {
71 [0] = {
72 .port = {
73 .type = PORT_PNX8XXX,
74 .iotype = UPIO_MEM,
75 .membase = (void __iomem *)PNX833X_UART0_PORTS_START,
76 .mapbase = PNX833X_UART0_PORTS_START,
77 .irq = PNX833X_PIC_UART0_INT,
78 .uartclk = 3692300,
79 .fifosize = 16,
80 .flags = UPF_BOOT_AUTOCONF,
81 .line = 0,
82 },
83 },
84 [1] = {
85 .port = {
86 .type = PORT_PNX8XXX,
87 .iotype = UPIO_MEM,
88 .membase = (void __iomem *)PNX833X_UART1_PORTS_START,
89 .mapbase = PNX833X_UART1_PORTS_START,
90 .irq = PNX833X_PIC_UART1_INT,
91 .uartclk = 3692300,
92 .fifosize = 16,
93 .flags = UPF_BOOT_AUTOCONF,
94 .line = 1,
95 },
96 },
97};
98
99static struct platform_device pnx833x_uart_device = {
100 .name = "pnx8xxx-uart",
101 .id = -1,
102 .dev = {
103 .dma_mask = &uart_dmamask,
104 .coherent_dma_mask = DMA_BIT_MASK(32),
105 .platform_data = pnx8xxx_ports,
106 },
107 .num_resources = ARRAY_SIZE(pnx833x_uart_resources),
108 .resource = pnx833x_uart_resources,
109};
110
111static u64 ehci_dmamask = DMA_BIT_MASK(32);
112
113static struct resource pnx833x_usb_ehci_resources[] = {
114 [0] = {
115 .start = PNX833X_USB_PORTS_START,
116 .end = PNX833X_USB_PORTS_END,
117 .flags = IORESOURCE_MEM,
118 },
119 [1] = {
120 .start = PNX833X_PIC_USB_INT,
121 .end = PNX833X_PIC_USB_INT,
122 .flags = IORESOURCE_IRQ,
123 },
124};
125
126static struct platform_device pnx833x_usb_ehci_device = {
127 .name = "pnx833x-ehci",
128 .id = -1,
129 .dev = {
130 .dma_mask = &ehci_dmamask,
131 .coherent_dma_mask = DMA_BIT_MASK(32),
132 },
133 .num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources),
134 .resource = pnx833x_usb_ehci_resources,
135};
136
137#ifdef CONFIG_I2C_PNX0105
138static struct resource pnx833x_i2c0_resources[] = {
139 {
140 .start = PNX833X_I2C0_PORTS_START,
141 .end = PNX833X_I2C0_PORTS_END,
142 .flags = IORESOURCE_MEM,
143 },
144 {
145 .start = PNX833X_PIC_I2C0_INT,
146 .end = PNX833X_PIC_I2C0_INT,
147 .flags = IORESOURCE_IRQ,
148 },
149};
150
151static struct resource pnx833x_i2c1_resources[] = {
152 {
153 .start = PNX833X_I2C1_PORTS_START,
154 .end = PNX833X_I2C1_PORTS_END,
155 .flags = IORESOURCE_MEM,
156 },
157 {
158 .start = PNX833X_PIC_I2C1_INT,
159 .end = PNX833X_PIC_I2C1_INT,
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = {
165 {
166 .base = PNX833X_I2C0_PORTS_START,
167 .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */
168 .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Prefered HDCP) */
169 .bus_addr = 0, /* no slave support */
170 },
171 {
172 .base = PNX833X_I2C1_PORTS_START,
173 .irq = -1, /* on high freq, polling is faster */
174 /*.irq = PNX833X_PIC_I2C1_INT,*/
175 .clock = 4, /* 0 == 400 kHz, 4 == 100 kHz. 100 kHz seems a safe default for now */
176 .bus_addr = 0, /* no slave support */
177 },
178};
179
180static struct platform_device pnx833x_i2c0_device = {
181 .name = "i2c-pnx0105",
182 .id = 0,
183 .dev = {
184 .platform_data = &pnx833x_i2c_dev[0],
185 },
186 .num_resources = ARRAY_SIZE(pnx833x_i2c0_resources),
187 .resource = pnx833x_i2c0_resources,
188};
189
190static struct platform_device pnx833x_i2c1_device = {
191 .name = "i2c-pnx0105",
192 .id = 1,
193 .dev = {
194 .platform_data = &pnx833x_i2c_dev[1],
195 },
196 .num_resources = ARRAY_SIZE(pnx833x_i2c1_resources),
197 .resource = pnx833x_i2c1_resources,
198};
199#endif
200
201static u64 ethernet_dmamask = DMA_BIT_MASK(32);
202
203static struct resource pnx833x_ethernet_resources[] = {
204 [0] = {
205 .start = PNX8335_IP3902_PORTS_START,
206 .end = PNX8335_IP3902_PORTS_END,
207 .flags = IORESOURCE_MEM,
208 },
209 [1] = {
210 .start = PNX8335_PIC_ETHERNET_INT,
211 .end = PNX8335_PIC_ETHERNET_INT,
212 .flags = IORESOURCE_IRQ,
213 },
214};
215
216static struct platform_device pnx833x_ethernet_device = {
217 .name = "ip3902-eth",
218 .id = -1,
219 .dev = {
220 .dma_mask = &ethernet_dmamask,
221 .coherent_dma_mask = DMA_BIT_MASK(32),
222 },
223 .num_resources = ARRAY_SIZE(pnx833x_ethernet_resources),
224 .resource = pnx833x_ethernet_resources,
225};
226
227static struct resource pnx833x_sata_resources[] = {
228 [0] = {
229 .start = PNX8335_SATA_PORTS_START,
230 .end = PNX8335_SATA_PORTS_END,
231 .flags = IORESOURCE_MEM,
232 },
233 [1] = {
234 .start = PNX8335_PIC_SATA_INT,
235 .end = PNX8335_PIC_SATA_INT,
236 .flags = IORESOURCE_IRQ,
237 },
238};
239
240static struct platform_device pnx833x_sata_device = {
241 .name = "pnx833x-sata",
242 .id = -1,
243 .num_resources = ARRAY_SIZE(pnx833x_sata_resources),
244 .resource = pnx833x_sata_resources,
245};
246
247static const char *part_probes[] = {
248 "cmdlinepart",
249 NULL
250};
251
252static void
253pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
254{
255 struct nand_chip *this = mtd->priv;
256 unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
257
258 if (cmd == NAND_CMD_NONE)
259 return;
260
261 if (ctrl & NAND_CLE)
262 writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_CLE_MASK));
263 else
264 writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_ALE_MASK));
265}
266
267static struct platform_nand_data pnx833x_flash_nand_data = {
268 .chip = {
269 .chip_delay = 25,
270 .part_probe_types = part_probes,
271 },
272 .ctrl = {
273 .cmd_ctrl = pnx833x_flash_nand_cmd_ctrl
274 }
275};
276
277/*
278 * Set start to be the correct address (PNX8335_NAND_BASE with no 0xb!!),
279 * 12 bytes more seems to be the standard that allows for NAND access.
280 */
281static struct resource pnx833x_flash_nand_resource = {
282 .start = PNX8335_NAND_BASE,
283 .end = PNX8335_NAND_BASE + 12,
284 .flags = IORESOURCE_MEM,
285};
286
287static struct platform_device pnx833x_flash_nand = {
288 .name = "gen_nand",
289 .id = -1,
290 .num_resources = 1,
291 .resource = &pnx833x_flash_nand_resource,
292 .dev = {
293 .platform_data = &pnx833x_flash_nand_data,
294 },
295};
296
297static struct platform_device *pnx833x_platform_devices[] __initdata = {
298 &pnx833x_uart_device,
299 &pnx833x_usb_ehci_device,
300#ifdef CONFIG_I2C_PNX0105
301 &pnx833x_i2c0_device,
302 &pnx833x_i2c1_device,
303#endif
304 &pnx833x_ethernet_device,
305 &pnx833x_sata_device,
306 &pnx833x_flash_nand,
307};
308
309static int __init pnx833x_platform_init(void)
310{
311 int res;
312
313 res = platform_add_devices(pnx833x_platform_devices,
314 ARRAY_SIZE(pnx833x_platform_devices));
315
316 return res;
317}
318
319arch_initcall(pnx833x_platform_init);
diff --git a/arch/mips/pnx833x/common/prom.c b/arch/mips/pnx833x/common/prom.c
new file mode 100644
index 000000000000..29969f90a6b0
--- /dev/null
+++ b/arch/mips/pnx833x/common/prom.c
@@ -0,0 +1,64 @@
1/*
2 * prom.c:
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * Based on software written by:
9 * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/init.h>
26#include <asm/bootinfo.h>
27#include <linux/string.h>
28
29void __init prom_init_cmdline(void)
30{
31 int argc = fw_arg0;
32 char **argv = (char **)fw_arg1;
33 char *c = &(arcs_cmdline[0]);
34 int i;
35
36 for (i = 1; i < argc; i++) {
37 strcpy(c, argv[i]);
38 c += strlen(argv[i]);
39 if (i < argc-1)
40 *c++ = ' ';
41 }
42 *c = 0;
43}
44
45char __init *prom_getenv(char *envname)
46{
47 extern char **prom_envp;
48 char **env = prom_envp;
49 int i;
50
51 i = strlen(envname);
52
53 while (*env) {
54 if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=')
55 return *env + i + 1;
56 env++;
57 }
58
59 return 0;
60}
61
62void __init prom_free_prom_memory(void)
63{
64}
diff --git a/arch/mips/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c
new file mode 100644
index 000000000000..e0ea96d29fde
--- /dev/null
+++ b/arch/mips/pnx833x/common/reset.c
@@ -0,0 +1,44 @@
1/*
2 * reset.c: reset support for PNX833X.
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * Based on software written by:
9 * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/reboot.h>
26#include <pnx833x.h>
27
28void pnx833x_machine_restart(char *command)
29{
30 PNX833X_RESET_CONTROL_2 = 0;
31 PNX833X_RESET_CONTROL = 0;
32}
33
34void pnx833x_machine_halt(void)
35{
36 while (1)
37 __asm__ __volatile__ ("wait");
38
39}
40
41void pnx833x_machine_power_off(void)
42{
43 pnx833x_machine_halt();
44}
diff --git a/arch/mips/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c
new file mode 100644
index 000000000000..e51fbc4b644d
--- /dev/null
+++ b/arch/mips/pnx833x/common/setup.c
@@ -0,0 +1,64 @@
1/*
2 * setup.c: Setup PNX833X Soc.
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * Based on software written by:
9 * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28#include <linux/io.h>
29#include <linux/pci.h>
30#include <asm/reboot.h>
31#include <pnx833x.h>
32#include <gpio.h>
33
34extern void pnx833x_board_setup(void);
35extern void pnx833x_machine_restart(char *);
36extern void pnx833x_machine_halt(void);
37extern void pnx833x_machine_power_off(void);
38
39int __init plat_mem_setup(void)
40{
41 /* fake pci bus to avoid bounce buffers */
42 PCI_DMA_BUS_IS_PHYS = 1;
43
44 /* set mips clock to 320MHz */
45#if defined(CONFIG_SOC_PNX8335)
46 PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ);
47#endif
48 pnx833x_gpio_init(); /* so it will be ready in board_setup() */
49
50 pnx833x_board_setup();
51
52 _machine_restart = pnx833x_machine_restart;
53 _machine_halt = pnx833x_machine_halt;
54 pm_power_off = pnx833x_machine_power_off;
55
56 /* IO/MEM resources. */
57 set_io_port_base(KSEG1);
58 ioport_resource.start = 0;
59 ioport_resource.end = ~0;
60 iomem_resource.start = 0;
61 iomem_resource.end = ~0;
62
63 return 0;
64}
diff --git a/arch/mips/pnx833x/stb22x/Makefile b/arch/mips/pnx833x/stb22x/Makefile
new file mode 100644
index 000000000000..f81c5801f455
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/Makefile
@@ -0,0 +1,3 @@
1lib-y := board.o
2
3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c
new file mode 100644
index 000000000000..644eb7c3210f
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/board.c
@@ -0,0 +1,133 @@
1/*
2 * board.c: STB225 board support.
3 *
4 * Copyright 2008 NXP Semiconductors
5 * Chris Steel <chris.steel@nxp.com>
6 * Daniel Laird <daniel.j.laird@nxp.com>
7 *
8 * Based on software written by:
9 * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/init.h>
26#include <asm/bootinfo.h>
27#include <linux/mm.h>
28#include <pnx833x.h>
29#include <gpio.h>
30
31/* endianess twiddlers */
32#define PNX8335_DEBUG0 0x4400
33#define PNX8335_DEBUG1 0x4404
34#define PNX8335_DEBUG2 0x4408
35#define PNX8335_DEBUG3 0x440c
36#define PNX8335_DEBUG4 0x4410
37#define PNX8335_DEBUG5 0x4414
38#define PNX8335_DEBUG6 0x4418
39#define PNX8335_DEBUG7 0x441c
40
41int prom_argc;
42char **prom_argv, **prom_envp;
43
44extern void prom_init_cmdline(void);
45extern char *prom_getenv(char *envname);
46
47const char *get_system_type(void)
48{
49 return "NXP STB22x";
50}
51
52static inline unsigned long env_or_default(char *env, unsigned long dfl)
53{
54 char *str = prom_getenv(env);
55 return str ? simple_strtol(str, 0, 0) : dfl;
56}
57
58void __init prom_init(void)
59{
60 unsigned long memsize;
61
62 prom_argc = fw_arg0;
63 prom_argv = (char **)fw_arg1;
64 prom_envp = (char **)fw_arg2;
65
66 prom_init_cmdline();
67
68 memsize = env_or_default("memsize", 0x02000000);
69 add_memory_region(0, memsize, BOOT_MEM_RAM);
70}
71
72void __init pnx833x_board_setup(void)
73{
74 pnx833x_gpio_select_function_alt(4);
75 pnx833x_gpio_select_output(4);
76 pnx833x_gpio_select_function_alt(5);
77 pnx833x_gpio_select_input(5);
78 pnx833x_gpio_select_function_alt(6);
79 pnx833x_gpio_select_input(6);
80 pnx833x_gpio_select_function_alt(7);
81 pnx833x_gpio_select_output(7);
82
83 pnx833x_gpio_select_function_alt(25);
84 pnx833x_gpio_select_function_alt(26);
85
86 pnx833x_gpio_select_function_alt(27);
87 pnx833x_gpio_select_function_alt(28);
88 pnx833x_gpio_select_function_alt(29);
89 pnx833x_gpio_select_function_alt(30);
90 pnx833x_gpio_select_function_alt(31);
91 pnx833x_gpio_select_function_alt(32);
92 pnx833x_gpio_select_function_alt(33);
93
94#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
95 /* Setup MIU for NAND access on CS0...
96 *
97 * (it seems that we must also configure CS1 for reliable operation,
98 * otherwise the first read ID command will fail if it's read as 4 bytes
99 * but pass if it's read as 1 word.)
100 */
101
102 /* Setup MIU CS0 & CS1 timing */
103 PNX833X_MIU_SEL0 = 0;
104 PNX833X_MIU_SEL1 = 0;
105 PNX833X_MIU_SEL0_TIMING = 0x50003081;
106 PNX833X_MIU_SEL1_TIMING = 0x50003081;
107
108 /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
109 pnx833x_gpio_select_function_alt(0);
110
111 /* Setup GPIO 04 to input NAND read/busy signal */
112 pnx833x_gpio_select_function_io(4);
113 pnx833x_gpio_select_input(4);
114
115 /* Setup GPIO 05 to disable NAND write protect */
116 pnx833x_gpio_select_function_io(5);
117 pnx833x_gpio_select_output(5);
118 pnx833x_gpio_write(1, 5);
119
120#elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE)
121
122 /* Set up MIU for 16-bit NOR access on CS0 and CS1... */
123
124 /* Setup MIU CS0 & CS1 timing */
125 PNX833X_MIU_SEL0 = 1;
126 PNX833X_MIU_SEL1 = 1;
127 PNX833X_MIU_SEL0_TIMING = 0x6A08D082;
128 PNX833X_MIU_SEL1_TIMING = 0x6A08D082;
129
130 /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
131 pnx833x_gpio_select_function_alt(0);
132#endif
133}