1/* 2 * arch/arm/mach-pnx4008/core.c 3 * 4 * PNX4008 core startup code 5 * 6 * Authors: Vitaly Wool, Dmitry Chigirev, 7 * Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com> 8 * 9 * Based on reference code received from Philips: 10 * Copyright (C) 2003 Philips Semiconductors 11 * 12 * 2005 (c) MontaVista Software, Inc. This file is licensed under 13 * the terms of the GNU General Public License version 2. This program 14 * is licensed "as is" without any warranty of any kind, whether express 15 * or implied. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/types.h> 20#include <linux/mm.h> 21#include <linux/interrupt.h> 22#include <linux/list.h> 23#include <linux/init.h> 24#include <linux/ioport.h> 25#include <linux/serial_8250.h> 26#include <linux/device.h> 27#include <linux/spi/spi.h> 28 29#include <asm/hardware.h> 30#include <asm/io.h> 31#include <asm/setup.h> 32#include <asm/mach-types.h> 33#include <asm/pgtable.h> 34#include <asm/page.h> 35#include <asm/system.h> 36 37#include <asm/mach/arch.h> 38#include <asm/mach/map.h> 39#include <asm/mach/time.h> 40 41#include <asm/arch/irq.h> 42#include <asm/arch/clock.h> 43#include <asm/arch/dma.h> 44 45struct resource spipnx_0_resources[] = { 46 { 47 .start = PNX4008_SPI1_BASE, 48 .end = PNX4008_SPI1_BASE + SZ_4K, 49 .flags = IORESOURCE_MEM, 50 }, { 51 .start = PER_SPI1_REC_XMIT, 52 .flags = IORESOURCE_DMA, 53 }, { 54 .start = SPI1_INT, 55 .flags = IORESOURCE_IRQ, 56 }, { 57 .flags = 0, 58 }, 59}; 60 61struct resource spipnx_1_resources[] = { 62 { 63 .start = PNX4008_SPI2_BASE, 64 .end = PNX4008_SPI2_BASE + SZ_4K, 65 .flags = IORESOURCE_MEM, 66 }, { 67 .start = PER_SPI2_REC_XMIT, 68 .flags = IORESOURCE_DMA, 69 }, { 70 .start = SPI2_INT, 71 .flags = IORESOURCE_IRQ, 72 }, { 73 .flags = 0, 74 } 75}; 76 77static struct spi_board_info spi_board_info[] __initdata = { 78 { 79 .modalias = "m25p80", 80 .max_speed_hz = 1000000, 81 .bus_num = 1, 82 .chip_select = 0, 83 }, 84}; 85 86static struct platform_device spipnx_1 = { 87 .name = "spipnx", 88 .id = 1, 89 .num_resources = ARRAY_SIZE(spipnx_0_resources), 90 .resource = spipnx_0_resources, 91 .dev = { 92 .coherent_dma_mask = 0xFFFFFFFF, 93 }, 94}; 95 96static struct platform_device spipnx_2 = { 97 .name = "spipnx", 98 .id = 2, 99 .num_resources = ARRAY_SIZE(spipnx_1_resources), 100 .resource = spipnx_1_resources, 101 .dev = { 102 .coherent_dma_mask = 0xFFFFFFFF, 103 }, 104}; 105 106static struct plat_serial8250_port platform_serial_ports[] = { 107 { 108 .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)), 109 .mapbase = (unsigned long)PNX4008_UART5_BASE, 110 .irq = IIR5_INT, 111 .uartclk = PNX4008_UART_CLK, 112 .regshift = 2, 113 .iotype = UPIO_MEM, 114 .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST, 115 }, 116 { 117 .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)), 118 .mapbase = (unsigned long)PNX4008_UART3_BASE, 119 .irq = IIR3_INT, 120 .uartclk = PNX4008_UART_CLK, 121 .regshift = 2, 122 .iotype = UPIO_MEM, 123 .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST, 124 }, 125 {} 126}; 127 128static struct platform_device serial_device = { 129 .name = "serial8250", 130 .id = PLAT8250_DEV_PLATFORM, 131 .dev = { 132 .platform_data = &platform_serial_ports, 133 }, 134}; 135 136static struct platform_device nand_flash_device = { 137 .name = "pnx4008-flash", 138 .id = -1, 139 .dev = { 140 .coherent_dma_mask = 0xFFFFFFFF, 141 }, 142}; 143 144/* The dmamask must be set for OHCI to work */ 145static u64 ohci_dmamask = ~(u32) 0; 146 147static struct resource ohci_resources[] = { 148 { 149 .start = IO_ADDRESS(PNX4008_USB_CONFIG_BASE), 150 .end = IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x100), 151 .flags = IORESOURCE_MEM, 152 }, { 153 .start = USB_HOST_INT, 154 .flags = IORESOURCE_IRQ, 155 }, 156}; 157 158static struct platform_device ohci_device = { 159 .name = "pnx4008-usb-ohci", 160 .id = -1, 161 .dev = { 162 .dma_mask = &ohci_dmamask, 163 .coherent_dma_mask = 0xffffffff, 164 }, 165 .num_resources = ARRAY_SIZE(ohci_resources), 166 .resource = ohci_resources, 167}; 168 169static struct platform_device sdum_device = { 170 .name = "pnx4008-sdum", 171 .id = 0, 172 .dev = { 173 .coherent_dma_mask = 0xffffffff, 174 }, 175}; 176 177static struct platform_device rgbfb_device = { 178 .name = "pnx4008-rgbfb", 179 .id = 0, 180 .dev = { 181 .coherent_dma_mask = 0xffffffff, 182 } 183}; 184 185struct resource watchdog_resources[] = { 186 { 187 .start = PNX4008_WDOG_BASE, 188 .end = PNX4008_WDOG_BASE + SZ_4K - 1, 189 .flags = IORESOURCE_MEM, 190 }, 191}; 192 193static struct platform_device watchdog_device = { 194 .name = "pnx4008-watchdog", 195 .id = -1, 196 .num_resources = ARRAY_SIZE(watchdog_resources), 197 .resource = watchdog_resources, 198}; 199 200static struct platform_device *devices[] __initdata = { 201 &spipnx_1, 202 &spipnx_2, 203 &serial_device, 204 &ohci_device, 205 &nand_flash_device, 206 &sdum_device, 207 &rgbfb_device, 208 &watchdog_device, 209}; 210 211 212extern void pnx4008_uart_init(void); 213 214static void __init pnx4008_init(void) 215{ 216 /*disable all START interrupt sources, 217 and clear all START interrupt flags */ 218 __raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT)); 219 __raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT)); 220 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT)); 221 __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT)); 222 223 platform_add_devices(devices, ARRAY_SIZE(devices)); 224 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 225 /* Switch on the UART clocks */ 226 pnx4008_uart_init(); 227} 228 229static struct map_desc pnx4008_io_desc[] __initdata = { 230 { 231 .virtual = IO_ADDRESS(PNX4008_IRAM_BASE), 232 .pfn = __phys_to_pfn(PNX4008_IRAM_BASE), 233 .length = SZ_64K, 234 .type = MT_DEVICE, 235 }, { 236 .virtual = IO_ADDRESS(PNX4008_NDF_FLASH_BASE), 237 .pfn = __phys_to_pfn(PNX4008_NDF_FLASH_BASE), 238 .length = SZ_1M - SZ_128K, 239 .type = MT_DEVICE, 240 }, { 241 .virtual = IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE), 242 .pfn = __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE), 243 .length = SZ_128K * 3, 244 .type = MT_DEVICE, 245 }, { 246 .virtual = IO_ADDRESS(PNX4008_DMA_CONFIG_BASE), 247 .pfn = __phys_to_pfn(PNX4008_DMA_CONFIG_BASE), 248 .length = SZ_1M, 249 .type = MT_DEVICE, 250 }, { 251 .virtual = IO_ADDRESS(PNX4008_AHB2FAB_BASE), 252 .pfn = __phys_to_pfn(PNX4008_AHB2FAB_BASE), 253 .length = SZ_1M, 254 .type = MT_DEVICE, 255 }, 256}; 257 258void __init pnx4008_map_io(void) 259{ 260 iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc)); 261} 262 263extern struct sys_timer pnx4008_timer; 264 265MACHINE_START(PNX4008, "Philips PNX4008") 266 /* Maintainer: MontaVista Software Inc. */ 267 .phys_io = 0x40090000, 268 .io_pg_offst = (0xf4090000 >> 18) & 0xfffc, 269 .boot_params = 0x80000100, 270 .map_io = pnx4008_map_io, 271 .init_irq = pnx4008_init_irq, 272 .init_machine = pnx4008_init, 273 .timer = &pnx4008_timer, 274MACHINE_END 275