linux/arch/arm/mach-integrator/integrator_ap.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-integrator/integrator_ap.c
   3 *
   4 *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20#include <linux/types.h>
  21#include <linux/kernel.h>
  22#include <linux/init.h>
  23#include <linux/list.h>
  24#include <linux/device.h>
  25#include <linux/slab.h>
  26#include <linux/string.h>
  27#include <linux/sysdev.h>
  28
  29#include <asm/hardware.h>
  30#include <asm/io.h>
  31#include <asm/irq.h>
  32#include <asm/setup.h>
  33#include <asm/mach-types.h>
  34#include <asm/hardware/amba.h>
  35#include <asm/hardware/amba_kmi.h>
  36
  37#include <asm/arch/lm.h>
  38
  39#include <asm/mach/arch.h>
  40#include <asm/mach/flash.h>
  41#include <asm/mach/irq.h>
  42#include <asm/mach/map.h>
  43#include <asm/mach/time.h>
  44
  45#include "common.h"
  46
  47/* 
  48 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
  49 * is the (PA >> 12).
  50 *
  51 * Setup a VA for the Integrator interrupt controller (for header #0,
  52 * just for now).
  53 */
  54#define VA_IC_BASE      IO_ADDRESS(INTEGRATOR_IC_BASE) 
  55#define VA_SC_BASE      IO_ADDRESS(INTEGRATOR_SC_BASE)
  56#define VA_EBI_BASE     IO_ADDRESS(INTEGRATOR_EBI_BASE)
  57#define VA_CMIC_BASE    IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
  58
  59/*
  60 * Logical      Physical
  61 * e8000000     40000000        PCI memory              PHYS_PCI_MEM_BASE       (max 512M)
  62 * ec000000     61000000        PCI config space        PHYS_PCI_CONFIG_BASE    (max 16M)
  63 * ed000000     62000000        PCI V3 regs             PHYS_PCI_V3_BASE        (max 64k)
  64 * ee000000     60000000        PCI IO                  PHYS_PCI_IO_BASE        (max 16M)
  65 * ef000000                     Cache flush
  66 * f1000000     10000000        Core module registers
  67 * f1100000     11000000        System controller registers
  68 * f1200000     12000000        EBI registers
  69 * f1300000     13000000        Counter/Timer
  70 * f1400000     14000000        Interrupt controller
  71 * f1600000     16000000        UART 0
  72 * f1700000     17000000        UART 1
  73 * f1a00000     1a000000        Debug LEDs
  74 * f1b00000     1b000000        GPIO
  75 */
  76
  77static struct map_desc ap_io_desc[] __initdata = {
  78 { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
  79 { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
  80 { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
  81 { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
  82 { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
  83 { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
  84 { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
  85 { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
  86 { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
  87 { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
  88 { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
  89 { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
  90 { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
  91};
  92
  93static void __init ap_map_io(void)
  94{
  95        iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
  96}
  97
  98#define INTEGRATOR_SC_VALID_INT 0x003fffff
  99
 100static void sc_mask_irq(unsigned int irq)
 101{
 102        writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 103}
 104
 105static void sc_unmask_irq(unsigned int irq)
 106{
 107        writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
 108}
 109
 110static struct irqchip sc_chip = {
 111        .ack    = sc_mask_irq,
 112        .mask   = sc_mask_irq,
 113        .unmask = sc_unmask_irq,
 114};
 115
 116static void __init ap_init_irq(void)
 117{
 118        unsigned int i;
 119
 120        /* Disable all interrupts initially. */
 121        /* Do the core module ones */
 122        writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 123
 124        /* do the header card stuff next */
 125        writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 126        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 127
 128        for (i = 0; i < NR_IRQS; i++) {
 129                if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) {
 130                        set_irq_chip(i, &sc_chip);
 131                        set_irq_handler(i, do_level_IRQ);
 132                        set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 133                }
 134        }
 135}
 136
 137#ifdef CONFIG_PM
 138static unsigned long ic_irq_enable;
 139
 140static int irq_suspend(struct sys_device *dev, u32 state)
 141{
 142        ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
 143        return 0;
 144}
 145
 146static int irq_resume(struct sys_device *dev)
 147{
 148        /* disable all irq sources */
 149        writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 150        writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 151        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 152
 153        writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
 154        return 0;
 155}
 156#else
 157#define irq_suspend NULL
 158#define irq_resume NULL
 159#endif
 160
 161static struct sysdev_class irq_class = {
 162        set_kset_name("irq"),
 163        .suspend        = irq_suspend,
 164        .resume         = irq_resume,
 165};
 166
 167static struct sys_device irq_device = {
 168        .id     = 0,
 169        .cls    = &irq_class,
 170};
 171
 172static int __init irq_init_sysfs(void)
 173{
 174        int ret = sysdev_class_register(&irq_class);
 175        if (ret == 0)
 176                ret = sysdev_register(&irq_device);
 177        return ret;
 178}
 179
 180device_initcall(irq_init_sysfs);
 181
 182/*
 183 * Flash handling.
 184 */
 185#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
 186#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
 187#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
 188#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
 189
 190static int ap_flash_init(void)
 191{
 192        u32 tmp;
 193
 194        writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
 195
 196        tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
 197        writel(tmp, EBI_CSR1);
 198
 199        if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
 200                writel(0xa05f, EBI_LOCK);
 201                writel(tmp, EBI_CSR1);
 202                writel(0, EBI_LOCK);
 203        }
 204        return 0;
 205}
 206
 207static void ap_flash_exit(void)
 208{
 209        u32 tmp;
 210
 211        writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
 212
 213        tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
 214        writel(tmp, EBI_CSR1);
 215
 216        if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
 217                writel(0xa05f, EBI_LOCK);
 218                writel(tmp, EBI_CSR1);
 219                writel(0, EBI_LOCK);
 220        }
 221}
 222
 223static void ap_flash_set_vpp(int on)
 224{
 225        unsigned long reg = on ? SC_CTRLS : SC_CTRLC;
 226
 227        writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
 228}
 229
 230static struct flash_platform_data ap_flash_data = {
 231        .map_name       = "cfi_probe",
 232        .width          = 4,
 233        .init           = ap_flash_init,
 234        .exit           = ap_flash_exit,
 235        .set_vpp        = ap_flash_set_vpp,
 236};
 237
 238static struct resource cfi_flash_resource = {
 239        .start          = INTEGRATOR_FLASH_BASE,
 240        .end            = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
 241        .flags          = IORESOURCE_MEM,
 242};
 243
 244static struct platform_device cfi_flash_device = {
 245        .name           = "armflash",
 246        .id             = 0,
 247        .dev            = {
 248                .platform_data  = &ap_flash_data,
 249        },
 250        .num_resources  = 1,
 251        .resource       = &cfi_flash_resource,
 252};
 253
 254static void __init ap_init(void)
 255{
 256        unsigned long sc_dec;
 257        int i;
 258
 259        platform_device_register(&cfi_flash_device);
 260
 261        sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
 262        for (i = 0; i < 4; i++) {
 263                struct lm_device *lmdev;
 264
 265                if ((sc_dec & (16 << i)) == 0)
 266                        continue;
 267
 268                lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
 269                if (!lmdev)
 270                        continue;
 271
 272                memset(lmdev, 0, sizeof(struct lm_device));
 273
 274                lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
 275                lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
 276                lmdev->resource.flags = IORESOURCE_MEM;
 277                lmdev->irq = IRQ_AP_EXPINT0 + i;
 278                lmdev->id = i;
 279
 280                lm_device_register(lmdev);
 281        }
 282}
 283
 284static void __init ap_init_timer(void)
 285{
 286        integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
 287}
 288
 289static struct sys_timer ap_timer = {
 290        .init           = ap_init_timer,
 291        .offset         = integrator_gettimeoffset,
 292};
 293
 294MACHINE_START(INTEGRATOR, "ARM-Integrator")
 295        MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
 296        BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
 297        BOOT_PARAMS(0x00000100)
 298        MAPIO(ap_map_io)
 299        INITIRQ(ap_init_irq)
 300        .timer          = &ap_timer,
 301        INIT_MACHINE(ap_init)
 302MACHINE_END
 303
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.