| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * arch/arm/mach-ixp2000/ixdp2x01.c | 
 | 3 |  * | 
 | 4 |  * Code common to Intel IXDP2401 and IXDP2801 platforms | 
 | 5 |  * | 
 | 6 |  * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com> | 
 | 7 |  * Maintainer: Deepak Saxena <dsaxena@plexity.net> | 
 | 8 |  * | 
 | 9 |  * Copyright (C) 2002-2003 Intel Corp. | 
 | 10 |  * Copyright (C) 2003-2004 MontaVista Software, Inc. | 
 | 11 |  * | 
 | 12 |  *  This program is free software; you can redistribute  it and/or modify it | 
 | 13 |  *  under  the terms of  the GNU General  Public License as published by the | 
 | 14 |  *  Free Software Foundation;  either version 2 of the  License, or (at your | 
 | 15 |  *  option) any later version. | 
 | 16 |  */ | 
 | 17 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 18 | #include <linux/kernel.h> | 
 | 19 | #include <linux/init.h> | 
 | 20 | #include <linux/mm.h> | 
 | 21 | #include <linux/sched.h> | 
 | 22 | #include <linux/interrupt.h> | 
 | 23 | #include <linux/bitops.h> | 
 | 24 | #include <linux/pci.h> | 
 | 25 | #include <linux/ioport.h> | 
 | 26 | #include <linux/slab.h> | 
 | 27 | #include <linux/delay.h> | 
 | 28 | #include <linux/serial.h> | 
 | 29 | #include <linux/tty.h> | 
 | 30 | #include <linux/serial_core.h> | 
| Russell King | d052d1b | 2005-10-29 19:07:23 +0100 | [diff] [blame] | 31 | #include <linux/platform_device.h> | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 32 | #include <linux/serial_8250.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 33 |  | 
 | 34 | #include <asm/io.h> | 
 | 35 | #include <asm/irq.h> | 
 | 36 | #include <asm/pgtable.h> | 
 | 37 | #include <asm/page.h> | 
 | 38 | #include <asm/system.h> | 
 | 39 | #include <asm/hardware.h> | 
 | 40 | #include <asm/mach-types.h> | 
 | 41 |  | 
 | 42 | #include <asm/mach/pci.h> | 
 | 43 | #include <asm/mach/map.h> | 
 | 44 | #include <asm/mach/irq.h> | 
 | 45 | #include <asm/mach/time.h> | 
 | 46 | #include <asm/mach/arch.h> | 
 | 47 | #include <asm/mach/flash.h> | 
 | 48 |  | 
 | 49 | /************************************************************************* | 
 | 50 |  * IXDP2x01 IRQ Handling | 
 | 51 |  *************************************************************************/ | 
 | 52 | static void ixdp2x01_irq_mask(unsigned int irq) | 
 | 53 | { | 
| Lennert Buytenhek | e9b72e4 | 2005-11-01 19:44:26 +0000 | [diff] [blame] | 54 | 	ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 55 | 				IXP2000_BOARD_IRQ_MASK(irq)); | 
 | 56 | } | 
 | 57 |  | 
 | 58 | static void ixdp2x01_irq_unmask(unsigned int irq) | 
 | 59 | { | 
 | 60 | 	ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG, | 
 | 61 | 				IXP2000_BOARD_IRQ_MASK(irq)); | 
 | 62 | } | 
 | 63 |  | 
 | 64 | static u32 valid_irq_mask; | 
 | 65 |  | 
| Russell King | 10dd5ce | 2006-11-23 11:41:32 +0000 | [diff] [blame] | 66 | static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | { | 
 | 68 | 	u32 ex_interrupt; | 
 | 69 | 	int i; | 
 | 70 |  | 
 | 71 | 	desc->chip->mask(irq); | 
 | 72 |  | 
 | 73 | 	ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask; | 
 | 74 |  | 
 | 75 | 	if (!ex_interrupt) { | 
 | 76 | 		printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n"); | 
 | 77 | 		return; | 
 | 78 | 	} | 
 | 79 |  | 
 | 80 | 	for (i = 0; i < IXP2000_BOARD_IRQS; i++) { | 
 | 81 | 		if (ex_interrupt & (1 << i)) { | 
| Russell King | 10dd5ce | 2006-11-23 11:41:32 +0000 | [diff] [blame] | 82 | 			struct irq_desc *cpld_desc; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 83 | 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i; | 
 | 84 | 			cpld_desc = irq_desc + cpld_irq; | 
| Linus Torvalds | 0cd61b6 | 2006-10-06 10:53:39 -0700 | [diff] [blame] | 85 | 			desc_handle_irq(cpld_irq, cpld_desc); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | 		} | 
 | 87 | 	} | 
 | 88 |  | 
 | 89 | 	desc->chip->unmask(irq); | 
 | 90 | } | 
 | 91 |  | 
| Russell King | 10dd5ce | 2006-11-23 11:41:32 +0000 | [diff] [blame] | 92 | static struct irq_chip ixdp2x01_irq_chip = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 | 	.mask	= ixdp2x01_irq_mask, | 
 | 94 | 	.ack	= ixdp2x01_irq_mask, | 
 | 95 | 	.unmask	= ixdp2x01_irq_unmask | 
 | 96 | }; | 
 | 97 |  | 
 | 98 | /* | 
 | 99 |  * We only do anything if we are the master NPU on the board. | 
 | 100 |  * The slave NPU only has the ethernet chip going directly to | 
 | 101 |  * the PCIB interrupt input. | 
 | 102 |  */ | 
 | 103 | void __init ixdp2x01_init_irq(void) | 
 | 104 | { | 
 | 105 | 	int irq = 0; | 
 | 106 |  | 
 | 107 | 	/* initialize chip specific interrupts */ | 
 | 108 | 	ixp2000_init_irq(); | 
 | 109 |  | 
 | 110 | 	if (machine_is_ixdp2401()) | 
 | 111 | 		valid_irq_mask = IXDP2401_VALID_IRQ_MASK; | 
 | 112 | 	else | 
 | 113 | 		valid_irq_mask = IXDP2801_VALID_IRQ_MASK; | 
 | 114 |  | 
 | 115 | 	/* Mask all interrupts from CPLD, disable simulation */ | 
 | 116 | 	ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff); | 
| Lennert Buytenhek | e9b72e4 | 2005-11-01 19:44:26 +0000 | [diff] [blame] | 117 | 	ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 118 |  | 
 | 119 | 	for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { | 
 | 120 | 		if (irq & valid_irq_mask) { | 
 | 121 | 			set_irq_chip(irq, &ixdp2x01_irq_chip); | 
| Russell King | 10dd5ce | 2006-11-23 11:41:32 +0000 | [diff] [blame] | 122 | 			set_irq_handler(irq, handle_level_irq); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 | 			set_irq_flags(irq, IRQF_VALID); | 
 | 124 | 		} else { | 
 | 125 | 			set_irq_flags(irq, 0); | 
 | 126 | 		} | 
 | 127 | 	} | 
 | 128 |  | 
 | 129 | 	/* Hook into PCI interrupts */ | 
| Thomas Gleixner | 64ffae8 | 2006-07-01 22:32:18 +0100 | [diff] [blame] | 130 | 	set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 131 | } | 
 | 132 |  | 
 | 133 |  | 
 | 134 | /************************************************************************* | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 135 |  * IXDP2x01 memory map | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 136 |  *************************************************************************/ | 
 | 137 | static struct map_desc ixdp2x01_io_desc __initdata = { | 
 | 138 | 	.virtual	= IXDP2X01_VIRT_CPLD_BASE,  | 
| Deepak Saxena | db0d087 | 2005-10-28 15:18:58 +0100 | [diff] [blame] | 139 | 	.pfn		= __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 140 | 	.length		= IXDP2X01_CPLD_REGION_SIZE, | 
 | 141 | 	.type		= MT_DEVICE | 
 | 142 | }; | 
 | 143 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 144 | static void __init ixdp2x01_map_io(void) | 
 | 145 | { | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 146 | 	ixp2000_map_io(); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 147 | 	iotable_init(&ixdp2x01_io_desc, 1); | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 148 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 149 |  | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 150 |  | 
 | 151 | /************************************************************************* | 
 | 152 |  * IXDP2x01 serial ports | 
 | 153 |  *************************************************************************/ | 
 | 154 | static struct plat_serial8250_port ixdp2x01_serial_port1[] = { | 
 | 155 | 	{ | 
 | 156 | 		.mapbase	= (unsigned long)IXDP2X01_UART1_PHYS_BASE, | 
 | 157 | 		.membase	= (char *)IXDP2X01_UART1_VIRT_BASE, | 
 | 158 | 		.irq		= IRQ_IXDP2X01_UART1, | 
 | 159 | 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 
 | 160 | 		.iotype		= UPIO_MEM32, | 
 | 161 | 		.regshift	= 2, | 
 | 162 | 		.uartclk	= IXDP2X01_UART_CLK, | 
 | 163 | 	}, | 
 | 164 | 	{ } | 
 | 165 | }; | 
 | 166 |  | 
 | 167 | static struct resource ixdp2x01_uart_resource1 = { | 
 | 168 | 	.start		= IXDP2X01_UART1_PHYS_BASE, | 
 | 169 | 	.end		= IXDP2X01_UART1_PHYS_BASE + 0xffff, | 
 | 170 | 	.flags		= IORESOURCE_MEM, | 
 | 171 | }; | 
 | 172 |  | 
 | 173 | static struct platform_device ixdp2x01_serial_device1 = { | 
 | 174 | 	.name		= "serial8250", | 
 | 175 | 	.id		= PLAT8250_DEV_PLATFORM1, | 
 | 176 | 	.dev		= { | 
 | 177 | 		.platform_data		= ixdp2x01_serial_port1, | 
 | 178 | 	}, | 
 | 179 | 	.num_resources	= 1, | 
 | 180 | 	.resource	= &ixdp2x01_uart_resource1, | 
 | 181 | }; | 
 | 182 |  | 
 | 183 | static struct plat_serial8250_port ixdp2x01_serial_port2[] = { | 
 | 184 | 	{ | 
 | 185 | 		.mapbase	= (unsigned long)IXDP2X01_UART2_PHYS_BASE, | 
 | 186 | 		.membase	= (char *)IXDP2X01_UART2_VIRT_BASE, | 
 | 187 | 		.irq		= IRQ_IXDP2X01_UART2, | 
 | 188 | 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 
 | 189 | 		.iotype		= UPIO_MEM32, | 
 | 190 | 		.regshift	= 2, | 
 | 191 | 		.uartclk	= IXDP2X01_UART_CLK, | 
 | 192 | 	},  | 
 | 193 | 	{ } | 
 | 194 | }; | 
 | 195 |  | 
 | 196 | static struct resource ixdp2x01_uart_resource2 = { | 
 | 197 | 	.start		= IXDP2X01_UART2_PHYS_BASE, | 
 | 198 | 	.end		= IXDP2X01_UART2_PHYS_BASE + 0xffff, | 
 | 199 | 	.flags		= IORESOURCE_MEM, | 
 | 200 | }; | 
 | 201 |  | 
 | 202 | static struct platform_device ixdp2x01_serial_device2 = { | 
 | 203 | 	.name		= "serial8250", | 
 | 204 | 	.id		= PLAT8250_DEV_PLATFORM2, | 
 | 205 | 	.dev		= { | 
 | 206 | 		.platform_data		= ixdp2x01_serial_port2, | 
 | 207 | 	}, | 
 | 208 | 	.num_resources	= 1, | 
 | 209 | 	.resource	= &ixdp2x01_uart_resource2, | 
 | 210 | }; | 
 | 211 |  | 
 | 212 | static void ixdp2x01_uart_init(void) | 
 | 213 | { | 
 | 214 | 	platform_device_register(&ixdp2x01_serial_device1); | 
 | 215 | 	platform_device_register(&ixdp2x01_serial_device2); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 216 | } | 
 | 217 |  | 
 | 218 |  | 
 | 219 | /************************************************************************* | 
 | 220 |  * IXDP2x01 timer tick configuration | 
 | 221 |  *************************************************************************/ | 
 | 222 | static unsigned int ixdp2x01_clock; | 
 | 223 |  | 
 | 224 | static int __init ixdp2x01_clock_setup(char *str) | 
 | 225 | { | 
 | 226 | 	ixdp2x01_clock = simple_strtoul(str, NULL, 10); | 
 | 227 |  | 
 | 228 | 	return 1; | 
 | 229 | } | 
 | 230 |  | 
 | 231 | __setup("ixdp2x01_clock=", ixdp2x01_clock_setup); | 
 | 232 |  | 
 | 233 | static void __init ixdp2x01_timer_init(void) | 
 | 234 | { | 
 | 235 | 	if (!ixdp2x01_clock) | 
 | 236 | 		ixdp2x01_clock = 50000000; | 
 | 237 |  | 
 | 238 | 	ixp2000_init_time(ixdp2x01_clock); | 
 | 239 | } | 
 | 240 |  | 
 | 241 | static struct sys_timer ixdp2x01_timer = { | 
 | 242 | 	.init		= ixdp2x01_timer_init, | 
 | 243 | 	.offset		= ixp2000_gettimeoffset, | 
 | 244 | }; | 
 | 245 |  | 
 | 246 | /************************************************************************* | 
 | 247 |  * IXDP2x01 PCI | 
 | 248 |  *************************************************************************/ | 
 | 249 | void __init ixdp2x01_pci_preinit(void) | 
 | 250 | { | 
 | 251 | 	ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); | 
 | 252 | 	ixp2000_pci_preinit(); | 
| Lennert Buytenhek | f8e5b28 | 2006-02-08 21:09:04 +0000 | [diff] [blame] | 253 | 	pcibios_setup("firmware"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 254 | } | 
 | 255 |  | 
 | 256 | #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) | 
 | 257 |  | 
 | 258 | static int __init ixdp2x01_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | 
 | 259 | { | 
 | 260 | 	u8 bus = dev->bus->number; | 
 | 261 | 	u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); | 
 | 262 | 	struct pci_bus *tmp_bus = dev->bus; | 
 | 263 |  | 
 | 264 | 	/* Primary bus, no interrupts here */ | 
 | 265 | 	if (bus == 0) { | 
 | 266 | 		return -1; | 
 | 267 | 	} | 
 | 268 |  | 
 | 269 | 	/* Lookup first leaf in bus tree */ | 
 | 270 | 	while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) { | 
 | 271 | 		tmp_bus = tmp_bus->parent; | 
 | 272 | 	} | 
 | 273 |  | 
 | 274 | 	/* Select between known bridges */ | 
 | 275 | 	switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) { | 
 | 276 | 	/* Device is located after first MB bridge */ | 
 | 277 | 	case 0x0008: | 
 | 278 | 		if (tmp_bus == dev->bus) { | 
| Simon Arlott | 6cbdc8c | 2007-05-11 20:40:30 +0100 | [diff] [blame] | 279 | 			/* Device is located directly after first MB bridge */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 280 | 			switch (devpin) { | 
 | 281 | 			case DEVPIN(1, 1):	/* Onboard 82546 ch 0 */ | 
 | 282 | 				if (machine_is_ixdp2401()) | 
 | 283 | 					return IRQ_IXDP2401_INTA_82546; | 
 | 284 | 				return -1; | 
 | 285 | 			case DEVPIN(1, 2):	/* Onboard 82546 ch 1 */ | 
 | 286 | 				if (machine_is_ixdp2401()) | 
 | 287 | 					return IRQ_IXDP2401_INTB_82546; | 
 | 288 | 				return -1; | 
 | 289 | 			case DEVPIN(0, 1):	/* PMC INTA# */ | 
 | 290 | 				return IRQ_IXDP2X01_SPCI_PMC_INTA; | 
 | 291 | 			case DEVPIN(0, 2):	/* PMC INTB# */ | 
 | 292 | 				return IRQ_IXDP2X01_SPCI_PMC_INTB; | 
 | 293 | 			case DEVPIN(0, 3):	/* PMC INTC# */ | 
 | 294 | 				return IRQ_IXDP2X01_SPCI_PMC_INTC; | 
 | 295 | 			case DEVPIN(0, 4):	/* PMC INTD# */ | 
 | 296 | 				return IRQ_IXDP2X01_SPCI_PMC_INTD; | 
 | 297 | 			} | 
 | 298 | 		} | 
 | 299 | 		break; | 
 | 300 | 	case 0x0010: | 
 | 301 | 		if (tmp_bus == dev->bus) { | 
| Simon Arlott | 6cbdc8c | 2007-05-11 20:40:30 +0100 | [diff] [blame] | 302 | 			/* Device is located directly after second MB bridge */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 303 | 			/* Secondary bus of second bridge */ | 
 | 304 | 			switch (devpin) { | 
 | 305 | 			case DEVPIN(0, 1):	/* DB#0 */ | 
 | 306 | 				return IRQ_IXDP2X01_SPCI_DB_0; | 
 | 307 | 			case DEVPIN(1, 1):	/* DB#1 */ | 
 | 308 | 				return IRQ_IXDP2X01_SPCI_DB_1; | 
 | 309 | 			} | 
 | 310 | 		} else { | 
 | 311 | 			/* Device is located indirectly after second MB bridge */ | 
 | 312 | 			/* Not supported now */ | 
 | 313 | 		} | 
 | 314 | 		break; | 
 | 315 | 	} | 
 | 316 |  | 
 | 317 | 	return -1; | 
 | 318 | } | 
 | 319 |  | 
 | 320 |  | 
 | 321 | static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) | 
 | 322 | { | 
 | 323 | 	sys->mem_offset = 0xe0000000; | 
 | 324 |  | 
| Deepak Saxena | 0328ad2 | 2006-03-20 17:10:08 +0000 | [diff] [blame] | 325 | 	if (machine_is_ixdp2801() || machine_is_ixdp28x5()) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 326 | 		sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16); | 
 | 327 |  | 
 | 328 | 	return ixp2000_pci_setup(nr, sys); | 
 | 329 | } | 
 | 330 |  | 
 | 331 | struct hw_pci ixdp2x01_pci __initdata = { | 
 | 332 | 	.nr_controllers	= 1, | 
 | 333 | 	.setup		= ixdp2x01_pci_setup, | 
 | 334 | 	.preinit	= ixdp2x01_pci_preinit, | 
 | 335 | 	.scan		= ixp2000_pci_scan_bus, | 
 | 336 | 	.map_irq	= ixdp2x01_pci_map_irq, | 
 | 337 | }; | 
 | 338 |  | 
 | 339 | int __init ixdp2x01_pci_init(void) | 
 | 340 | { | 
| Deepak Saxena | 0328ad2 | 2006-03-20 17:10:08 +0000 | [diff] [blame] | 341 | 	if (machine_is_ixdp2401() || machine_is_ixdp2801() ||\ | 
 | 342 | 		machine_is_ixdp28x5()) | 
| Lennert Buytenhek | 1b39401 | 2006-02-08 21:09:02 +0000 | [diff] [blame] | 343 | 		pci_common_init(&ixdp2x01_pci); | 
 | 344 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 345 | 	return 0; | 
 | 346 | } | 
 | 347 |  | 
 | 348 | subsys_initcall(ixdp2x01_pci_init); | 
 | 349 |  | 
 | 350 | /************************************************************************* | 
| Simon Arlott | 6cbdc8c | 2007-05-11 20:40:30 +0100 | [diff] [blame] | 351 |  * IXDP2x01 Machine Initialization | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 352 |  *************************************************************************/ | 
 | 353 | static struct flash_platform_data ixdp2x01_flash_platform_data = { | 
 | 354 | 	.map_name	= "cfi_probe", | 
 | 355 | 	.width		= 1, | 
 | 356 | }; | 
 | 357 |  | 
 | 358 | static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs) | 
 | 359 | { | 
| Lennert Buytenhek | e9b72e4 | 2005-11-01 19:44:26 +0000 | [diff] [blame] | 360 | 	ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 361 | 		((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN)); | 
 | 362 | 	return (ofs & IXDP2X01_FLASH_WINDOW_MASK); | 
 | 363 | } | 
 | 364 |  | 
 | 365 | static struct ixp2000_flash_data ixdp2x01_flash_data = { | 
 | 366 | 	.platform_data	= &ixdp2x01_flash_platform_data, | 
 | 367 | 	.bank_setup	= ixdp2x01_flash_bank_setup | 
 | 368 | }; | 
 | 369 |  | 
 | 370 | static struct resource ixdp2x01_flash_resource = { | 
 | 371 | 	.start		= 0xc4000000, | 
 | 372 | 	.end		= 0xc4000000 + 0x01ffffff, | 
 | 373 | 	.flags		= IORESOURCE_MEM, | 
 | 374 | }; | 
 | 375 |  | 
 | 376 | static struct platform_device ixdp2x01_flash = { | 
 | 377 | 	.name		= "IXP2000-Flash", | 
 | 378 | 	.id		= 0, | 
 | 379 | 	.dev		= { | 
 | 380 | 		.platform_data = &ixdp2x01_flash_data, | 
 | 381 | 	}, | 
 | 382 | 	.num_resources	= 1, | 
 | 383 | 	.resource	= &ixdp2x01_flash_resource, | 
 | 384 | }; | 
 | 385 |  | 
 | 386 | static struct ixp2000_i2c_pins ixdp2x01_i2c_gpio_pins = { | 
 | 387 | 	.sda_pin	= IXDP2X01_GPIO_SDA, | 
 | 388 | 	.scl_pin	= IXDP2X01_GPIO_SCL, | 
 | 389 | }; | 
 | 390 |  | 
 | 391 | static struct platform_device ixdp2x01_i2c_controller = { | 
 | 392 | 	.name		= "IXP2000-I2C", | 
 | 393 | 	.id		= 0, | 
 | 394 | 	.dev		= { | 
 | 395 | 		.platform_data = &ixdp2x01_i2c_gpio_pins, | 
 | 396 | 	}, | 
 | 397 | 	.num_resources	= 0 | 
 | 398 | }; | 
 | 399 |  | 
 | 400 | static struct platform_device *ixdp2x01_devices[] __initdata = { | 
 | 401 | 	&ixdp2x01_flash, | 
 | 402 | 	&ixdp2x01_i2c_controller | 
 | 403 | }; | 
 | 404 |  | 
 | 405 | static void __init ixdp2x01_init_machine(void) | 
 | 406 | { | 
| Lennert Buytenhek | e9b72e4 | 2005-11-01 19:44:26 +0000 | [diff] [blame] | 407 | 	ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 408 | 		(IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN)); | 
 | 409 | 	 | 
 | 410 | 	ixdp2x01_flash_data.nr_banks = | 
 | 411 | 		((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1); | 
 | 412 |  | 
 | 413 | 	platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices)); | 
| Lennert Buytenhek | 28187f2 | 2005-07-10 19:44:53 +0100 | [diff] [blame] | 414 | 	ixp2000_uart_init(); | 
| Lennert Buytenhek | 104c7b03 | 2006-03-25 23:03:13 +0000 | [diff] [blame] | 415 | 	ixdp2x01_uart_init(); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 416 | } | 
 | 417 |  | 
 | 418 |  | 
 | 419 | #ifdef CONFIG_ARCH_IXDP2401 | 
 | 420 | MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 421 | 	/* Maintainer: MontaVista Software, Inc. */ | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 422 | 	.phys_io	= IXP2000_UART_PHYS_BASE, | 
 | 423 | 	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 
 | 424 | 	.boot_params	= 0x00000100, | 
 | 425 | 	.map_io		= ixdp2x01_map_io, | 
 | 426 | 	.init_irq	= ixdp2x01_init_irq, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 427 | 	.timer		= &ixdp2x01_timer, | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 428 | 	.init_machine	= ixdp2x01_init_machine, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 429 | MACHINE_END | 
 | 430 | #endif | 
 | 431 |  | 
 | 432 | #ifdef CONFIG_ARCH_IXDP2801 | 
 | 433 | MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 434 | 	/* Maintainer: MontaVista Software, Inc. */ | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 435 | 	.phys_io	= IXP2000_UART_PHYS_BASE, | 
 | 436 | 	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 
 | 437 | 	.boot_params	= 0x00000100, | 
 | 438 | 	.map_io		= ixdp2x01_map_io, | 
 | 439 | 	.init_irq	= ixdp2x01_init_irq, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 440 | 	.timer		= &ixdp2x01_timer, | 
| Russell King | e9dea0c | 2005-07-03 17:38:58 +0100 | [diff] [blame] | 441 | 	.init_machine	= ixdp2x01_init_machine, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 442 | MACHINE_END | 
| Deepak Saxena | 0328ad2 | 2006-03-20 17:10:08 +0000 | [diff] [blame] | 443 |  | 
 | 444 | /* | 
 | 445 |  * IXDP28x5 is basically an IXDP2801 with a different CPU but Intel | 
 | 446 |  * changed the machine ID in the bootloader | 
 | 447 |  */ | 
 | 448 | MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform") | 
 | 449 | 	/* Maintainer: MontaVista Software, Inc. */ | 
 | 450 | 	.phys_io	= IXP2000_UART_PHYS_BASE, | 
 | 451 | 	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 
 | 452 | 	.boot_params	= 0x00000100, | 
 | 453 | 	.map_io		= ixdp2x01_map_io, | 
 | 454 | 	.init_irq	= ixdp2x01_init_irq, | 
 | 455 | 	.timer		= &ixdp2x01_timer, | 
 | 456 | 	.init_machine	= ixdp2x01_init_machine, | 
 | 457 | MACHINE_END | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 458 | #endif | 
 | 459 |  | 
 | 460 |  |