1/* 2 * arch/arm/mach-ixp4xx/common.c 3 * 4 * Generic code shared across all IXP4XX platforms 5 * 6 * Maintainer: Deepak Saxena <dsaxena@plexity.net> 7 * 8 * Copyright 2002 (c) Intel Corporation 9 * Copyright 2003-2004 (c) MontaVista, Software, Inc. 10 * 11 * This file is licensed under the terms of the GNU General Public 12 * License version 2. This program is licensed "as is" without any 13 * warranty of any kind, whether express or implied. 14 */ 15 16#include <linux/kernel.h> 17#include <linux/mm.h> 18#include <linux/init.h> 19#include <linux/serial.h> 20#include <linux/tty.h> 21#include <linux/platform_device.h> 22#include <linux/serial_core.h> 23#include <linux/interrupt.h> 24#include <linux/bitops.h> 25#include <linux/io.h> 26#include <linux/export.h> 27#include <linux/cpu.h> 28#include <linux/pci.h> 29#include <linux/sched_clock.h> 30#include <linux/irqchip/irq-ixp4xx.h> 31#include <linux/platform_data/timer-ixp4xx.h> 32#include <linux/dma-map-ops.h> 33#include <mach/udc.h> 34#include <mach/hardware.h> 35#include <mach/io.h> 36#include <linux/uaccess.h> 37#include <asm/page.h> 38#include <asm/exception.h> 39#include <asm/irq.h> 40#include <asm/system_misc.h> 41#include <asm/mach/map.h> 42#include <asm/mach/irq.h> 43#include <asm/mach/time.h> 44 45#include "irqs.h" 46 47#define IXP4XX_TIMER_FREQ 66666000 48 49/************************************************************************* 50 * IXP4xx chipset I/O mapping 51 *************************************************************************/ 52static struct map_desc ixp4xx_io_desc[] __initdata = { 53 { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */ 54 .virtual = (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT, 55 .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS), 56 .length = IXP4XX_PERIPHERAL_REGION_SIZE, 57 .type = MT_DEVICE 58 }, { /* Expansion Bus Config Registers */ 59 .virtual = (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT, 60 .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS), 61 .length = IXP4XX_EXP_CFG_REGION_SIZE, 62 .type = MT_DEVICE 63 }, { /* PCI Registers */ 64 .virtual = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT, 65 .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), 66 .length = IXP4XX_PCI_CFG_REGION_SIZE, 67 .type = MT_DEVICE 68 }, 69}; 70 71void __init ixp4xx_map_io(void) 72{ 73 iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc)); 74} 75 76void __init ixp4xx_init_irq(void) 77{ 78 /* 79 * ixp4xx does not implement the XScale PWRMODE register 80 * so it must not call cpu_do_idle(). 81 */ 82 cpu_idle_poll_ctrl(true); 83 84 ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS, 85 (cpu_is_ixp46x() || cpu_is_ixp43x())); 86} 87 88void __init ixp4xx_timer_init(void) 89{ 90 return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS, 91 IRQ_IXP4XX_TIMER1, 92 IXP4XX_TIMER_FREQ); 93} 94 95static struct pxa2xx_udc_mach_info ixp4xx_udc_info; 96 97void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info) 98{ 99 memcpy(&ixp4xx_udc_info, info, sizeof *info); 100} 101 102static struct resource ixp4xx_udc_resources[] = { 103 [0] = { 104 .start = 0xc800b000, 105 .end = 0xc800bfff, 106 .flags = IORESOURCE_MEM, 107 }, 108 [1] = { 109 .start = IRQ_IXP4XX_USB, 110 .end = IRQ_IXP4XX_USB, 111 .flags = IORESOURCE_IRQ, 112 }, 113}; 114 115static struct resource ixp4xx_gpio_resource[] = { 116 { 117 .start = IXP4XX_GPIO_BASE_PHYS, 118 .end = IXP4XX_GPIO_BASE_PHYS + 0xfff, 119 .flags = IORESOURCE_MEM, 120 }, 121}; 122 123static struct platform_device ixp4xx_gpio_device = { 124 .name = "ixp4xx-gpio", 125 .id = -1, 126 .dev = { 127 .coherent_dma_mask = DMA_BIT_MASK(32), 128 }, 129 .resource = ixp4xx_gpio_resource, 130 .num_resources = ARRAY_SIZE(ixp4xx_gpio_resource), 131}; 132 133/* 134 * USB device controller. The IXP4xx uses the same controller as PXA25X, 135 * so we just use the same device. 136 */ 137static struct platform_device ixp4xx_udc_device = { 138 .name = "pxa25x-udc", 139 .id = -1, 140 .num_resources = 2, 141 .resource = ixp4xx_udc_resources, 142 .dev = { 143 .platform_data = &ixp4xx_udc_info, 144 }, 145}; 146 147static struct resource ixp4xx_npe_resources[] = { 148 { 149 .start = IXP4XX_NPEA_BASE_PHYS, 150 .end = IXP4XX_NPEA_BASE_PHYS + 0xfff, 151 .flags = IORESOURCE_MEM, 152 }, 153 { 154 .start = IXP4XX_NPEB_BASE_PHYS, 155 .end = IXP4XX_NPEB_BASE_PHYS + 0xfff, 156 .flags = IORESOURCE_MEM, 157 }, 158 { 159 .start = IXP4XX_NPEC_BASE_PHYS, 160 .end = IXP4XX_NPEC_BASE_PHYS + 0xfff, 161 .flags = IORESOURCE_MEM, 162 }, 163 164}; 165 166static struct platform_device ixp4xx_npe_device = { 167 .name = "ixp4xx-npe", 168 .id = -1, 169 .num_resources = ARRAY_SIZE(ixp4xx_npe_resources), 170 .resource = ixp4xx_npe_resources, 171}; 172 173static struct resource ixp4xx_qmgr_resources[] = { 174 { 175 .start = IXP4XX_QMGR_BASE_PHYS, 176 .end = IXP4XX_QMGR_BASE_PHYS + 0x3fff, 177 .flags = IORESOURCE_MEM, 178 }, 179 { 180 .start = IRQ_IXP4XX_QM1, 181 .end = IRQ_IXP4XX_QM1, 182 .flags = IORESOURCE_IRQ, 183 }, 184 { 185 .start = IRQ_IXP4XX_QM2, 186 .end = IRQ_IXP4XX_QM2, 187 .flags = IORESOURCE_IRQ, 188 }, 189}; 190 191static struct platform_device ixp4xx_qmgr_device = { 192 .name = "ixp4xx-qmgr", 193 .id = -1, 194 .num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources), 195 .resource = ixp4xx_qmgr_resources, 196}; 197 198static struct platform_device *ixp4xx_devices[] __initdata = { 199 &ixp4xx_npe_device, 200 &ixp4xx_qmgr_device, 201 &ixp4xx_gpio_device, 202 &ixp4xx_udc_device, 203}; 204 205static struct resource ixp46x_i2c_resources[] = { 206 [0] = { 207 .start = 0xc8011000, 208 .end = 0xc801101c, 209 .flags = IORESOURCE_MEM, 210 }, 211 [1] = { 212 .start = IRQ_IXP4XX_I2C, 213 .end = IRQ_IXP4XX_I2C, 214 .flags = IORESOURCE_IRQ 215 } 216}; 217 218/* 219 * I2C controller. The IXP46x uses the same block as the IOP3xx, so 220 * we just use the same device name. 221 */ 222static struct platform_device ixp46x_i2c_controller = { 223 .name = "IOP3xx-I2C", 224 .id = 0, 225 .num_resources = 2, 226 .resource = ixp46x_i2c_resources 227}; 228 229static struct platform_device *ixp46x_devices[] __initdata = { 230 &ixp46x_i2c_controller 231}; 232 233unsigned long ixp4xx_exp_bus_size; 234EXPORT_SYMBOL(ixp4xx_exp_bus_size); 235 236void __init ixp4xx_sys_init(void) 237{ 238 ixp4xx_exp_bus_size = SZ_16M; 239 240 platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); 241 242 if (cpu_is_ixp46x()) { 243 int region; 244 245 platform_add_devices(ixp46x_devices, 246 ARRAY_SIZE(ixp46x_devices)); 247 248 for (region = 0; region < 7; region++) { 249 if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) { 250 ixp4xx_exp_bus_size = SZ_32M; 251 break; 252 } 253 } 254 } 255 256 printk("IXP4xx: Using %luMiB expansion bus window size\n", 257 ixp4xx_exp_bus_size >> 20); 258} 259 260unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; 261EXPORT_SYMBOL(ixp4xx_timer_freq); 262 263void ixp4xx_restart(enum reboot_mode mode, const char *cmd) 264{ 265 if (mode == REBOOT_SOFT) { 266 /* Jump into ROM at address 0 */ 267 soft_restart(0); 268 } else { 269 /* Use on-chip reset capability */ 270 271 /* set the "key" register to enable access to 272 * "timer" and "enable" registers 273 */ 274 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 275 276 /* write 0 to the timer register for an immediate reset */ 277 *IXP4XX_OSWT = 0; 278 279 *IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE; 280 } 281} 282 283#ifdef CONFIG_PCI 284static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) 285{ 286 return (dma_addr + size) > SZ_64M; 287} 288 289static int ixp4xx_platform_notify_remove(struct device *dev) 290{ 291 if (dev_is_pci(dev)) 292 dmabounce_unregister_dev(dev); 293 294 return 0; 295} 296#endif 297 298/* 299 * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things. 300 */ 301static int ixp4xx_platform_notify(struct device *dev) 302{ 303 dev->dma_mask = &dev->coherent_dma_mask; 304 305#ifdef CONFIG_PCI 306 if (dev_is_pci(dev)) { 307 dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */ 308 dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce); 309 return 0; 310 } 311#endif 312 313 dev->coherent_dma_mask = DMA_BIT_MASK(32); 314 return 0; 315} 316 317int dma_set_coherent_mask(struct device *dev, u64 mask) 318{ 319 if (dev_is_pci(dev)) 320 mask &= DMA_BIT_MASK(28); /* 64 MB */ 321 322 if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) { 323 dev->coherent_dma_mask = mask; 324 return 0; 325 } 326 327 return -EIO; /* device wanted sub-64MB mask */ 328} 329EXPORT_SYMBOL(dma_set_coherent_mask); 330 331#ifdef CONFIG_IXP4XX_INDIRECT_PCI 332/* 333 * In the case of using indirect PCI, we simply return the actual PCI 334 * address and our read/write implementation use that to drive the 335 * access registers. If something outside of PCI is ioremap'd, we 336 * fallback to the default. 337 */ 338 339static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size, 340 unsigned int mtype, void *caller) 341{ 342 if (!is_pci_memory(addr)) 343 return __arm_ioremap_caller(addr, size, mtype, caller); 344 345 return (void __iomem *)addr; 346} 347 348static void ixp4xx_iounmap(volatile void __iomem *addr) 349{ 350 if (!is_pci_memory((__force u32)addr)) 351 __iounmap(addr); 352} 353#endif 354 355void __init ixp4xx_init_early(void) 356{ 357 platform_notify = ixp4xx_platform_notify; 358#ifdef CONFIG_PCI 359 platform_notify_remove = ixp4xx_platform_notify_remove; 360#endif 361#ifdef CONFIG_IXP4XX_INDIRECT_PCI 362 arch_ioremap_caller = ixp4xx_ioremap_caller; 363 arch_iounmap = ixp4xx_iounmap; 364#endif 365} 366