root/arch/arm/mach-ixp4xx/common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ixp4xx_map_io
  2. ixp4xx_init_irq
  3. ixp4xx_timer_init
  4. ixp4xx_set_udc_info
  5. ixp4xx_sys_init
  6. ixp4xx_restart
  7. ixp4xx_needs_bounce
  8. ixp4xx_platform_notify_remove
  9. ixp4xx_platform_notify
  10. dma_set_coherent_mask
  11. ixp4xx_ioremap_caller
  12. ixp4xx_iounmap
  13. ixp4xx_init_early

   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 <mach/udc.h>
  33 #include <mach/hardware.h>
  34 #include <mach/io.h>
  35 #include <linux/uaccess.h>
  36 #include <asm/pgtable.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  *************************************************************************/
  52 static 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 
  71 void __init ixp4xx_map_io(void)
  72 {
  73         iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
  74 }
  75 
  76 void __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 
  88 void __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 
  95 static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
  96 
  97 void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
  98 {
  99         memcpy(&ixp4xx_udc_info, info, sizeof *info);
 100 }
 101 
 102 static 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 
 115 static 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 
 123 static 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  */
 137 static 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 
 147 static 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 
 166 static 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 
 173 static 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 
 191 static 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 
 198 static struct platform_device *ixp4xx_devices[] __initdata = {
 199         &ixp4xx_npe_device,
 200         &ixp4xx_qmgr_device,
 201         &ixp4xx_gpio_device,
 202         &ixp4xx_udc_device,
 203 };
 204 
 205 static 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  */
 222 static struct platform_device ixp46x_i2c_controller = {
 223         .name           = "IOP3xx-I2C",
 224         .id             = 0,
 225         .num_resources  = 2,
 226         .resource       = ixp46x_i2c_resources
 227 };
 228 
 229 static struct platform_device *ixp46x_devices[] __initdata = {
 230         &ixp46x_i2c_controller
 231 };
 232 
 233 unsigned long ixp4xx_exp_bus_size;
 234 EXPORT_SYMBOL(ixp4xx_exp_bus_size);
 235 
 236 void __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 
 260 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
 261 EXPORT_SYMBOL(ixp4xx_timer_freq);
 262 
 263 void 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
 284 static 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 
 289 static 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  */
 301 static 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 
 317 int 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 }
 329 EXPORT_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 
 339 static 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 
 348 static void ixp4xx_iounmap(volatile void __iomem *addr)
 349 {
 350         if (!is_pci_memory((__force u32)addr))
 351                 __iounmap(addr);
 352 }
 353 #endif
 354 
 355 void __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 }

/* [<][>][^][v][top][bottom][index][help] */