linux/arch/arm/mach-realview/realview_pba8.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-realview/realview_pba8.c
   3 *
   4 *  Copyright (C) 2008 ARM Limited
   5 *  Copyright (C) 2000 Deep Blue Solutions Ltd
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/platform_device.h>
  24#include <linux/device.h>
  25#include <linux/amba/bus.h>
  26#include <linux/amba/pl061.h>
  27#include <linux/amba/mmci.h>
  28#include <linux/amba/pl022.h>
  29#include <linux/io.h>
  30#include <linux/irqchip/arm-gic.h>
  31#include <linux/platform_data/clk-realview.h>
  32#include <linux/reboot.h>
  33
  34#include <asm/irq.h>
  35#include <asm/mach-types.h>
  36#include <asm/pgtable.h>
  37
  38#include <asm/mach/arch.h>
  39#include <asm/mach/map.h>
  40#include <asm/mach/time.h>
  41
  42#include <mach/hardware.h>
  43#include <mach/board-pba8.h>
  44#include <mach/irqs.h>
  45
  46#include "core.h"
  47
  48static struct map_desc realview_pba8_io_desc[] __initdata = {
  49        {
  50                .virtual        = IO_ADDRESS(REALVIEW_SYS_BASE),
  51                .pfn            = __phys_to_pfn(REALVIEW_SYS_BASE),
  52                .length         = SZ_4K,
  53                .type           = MT_DEVICE,
  54        }, {
  55                .virtual        = IO_ADDRESS(REALVIEW_PBA8_GIC_CPU_BASE),
  56                .pfn            = __phys_to_pfn(REALVIEW_PBA8_GIC_CPU_BASE),
  57                .length         = SZ_4K,
  58                .type           = MT_DEVICE,
  59        }, {
  60                .virtual        = IO_ADDRESS(REALVIEW_PBA8_GIC_DIST_BASE),
  61                .pfn            = __phys_to_pfn(REALVIEW_PBA8_GIC_DIST_BASE),
  62                .length         = SZ_4K,
  63                .type           = MT_DEVICE,
  64        }, {
  65                .virtual        = IO_ADDRESS(REALVIEW_SCTL_BASE),
  66                .pfn            = __phys_to_pfn(REALVIEW_SCTL_BASE),
  67                .length         = SZ_4K,
  68                .type           = MT_DEVICE,
  69        }, {
  70                .virtual        = IO_ADDRESS(REALVIEW_PBA8_TIMER0_1_BASE),
  71                .pfn            = __phys_to_pfn(REALVIEW_PBA8_TIMER0_1_BASE),
  72                .length         = SZ_4K,
  73                .type           = MT_DEVICE,
  74        }, {
  75                .virtual        = IO_ADDRESS(REALVIEW_PBA8_TIMER2_3_BASE),
  76                .pfn            = __phys_to_pfn(REALVIEW_PBA8_TIMER2_3_BASE),
  77                .length         = SZ_4K,
  78                .type           = MT_DEVICE,
  79        },
  80#ifdef CONFIG_PCI
  81        {
  82                .virtual        = PCIX_UNIT_BASE,
  83                .pfn            = __phys_to_pfn(REALVIEW_PBA8_PCI_BASE),
  84                .length         = REALVIEW_PBA8_PCI_BASE_SIZE,
  85                .type           = MT_DEVICE
  86        },
  87#endif
  88#ifdef CONFIG_DEBUG_LL
  89        {
  90                .virtual        = IO_ADDRESS(REALVIEW_PBA8_UART0_BASE),
  91                .pfn            = __phys_to_pfn(REALVIEW_PBA8_UART0_BASE),
  92                .length         = SZ_4K,
  93                .type           = MT_DEVICE,
  94        },
  95#endif
  96};
  97
  98static void __init realview_pba8_map_io(void)
  99{
 100        iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc));
 101}
 102
 103static struct pl061_platform_data gpio0_plat_data = {
 104        .gpio_base      = 0,
 105};
 106
 107static struct pl061_platform_data gpio1_plat_data = {
 108        .gpio_base      = 8,
 109};
 110
 111static struct pl061_platform_data gpio2_plat_data = {
 112        .gpio_base      = 16,
 113};
 114
 115static struct pl022_ssp_controller ssp0_plat_data = {
 116        .bus_id = 0,
 117        .enable_dma = 0,
 118        .num_chipselect = 1,
 119};
 120
 121/*
 122 * RealView PBA8Core AMBA devices
 123 */
 124
 125#define GPIO2_IRQ               { IRQ_PBA8_GPIO2 }
 126#define GPIO3_IRQ               { IRQ_PBA8_GPIO3 }
 127#define AACI_IRQ                { IRQ_PBA8_AACI }
 128#define MMCI0_IRQ               { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
 129#define KMI0_IRQ                { IRQ_PBA8_KMI0 }
 130#define KMI1_IRQ                { IRQ_PBA8_KMI1 }
 131#define PBA8_SMC_IRQ            { }
 132#define MPMC_IRQ                { }
 133#define PBA8_CLCD_IRQ           { IRQ_PBA8_CLCD }
 134#define DMAC_IRQ                { IRQ_PBA8_DMAC }
 135#define SCTL_IRQ                { }
 136#define PBA8_WATCHDOG_IRQ       { IRQ_PBA8_WATCHDOG }
 137#define PBA8_GPIO0_IRQ          { IRQ_PBA8_GPIO0 }
 138#define GPIO1_IRQ               { IRQ_PBA8_GPIO1 }
 139#define PBA8_RTC_IRQ            { IRQ_PBA8_RTC }
 140#define SCI_IRQ                 { IRQ_PBA8_SCI }
 141#define PBA8_UART0_IRQ          { IRQ_PBA8_UART0 }
 142#define PBA8_UART1_IRQ          { IRQ_PBA8_UART1 }
 143#define PBA8_UART2_IRQ          { IRQ_PBA8_UART2 }
 144#define PBA8_UART3_IRQ          { IRQ_PBA8_UART3 }
 145#define PBA8_SSP_IRQ            { IRQ_PBA8_SSP }
 146
 147/* FPGA Primecells */
 148APB_DEVICE(aaci,        "fpga:aaci",    AACI,           NULL);
 149APB_DEVICE(mmc0,        "fpga:mmc0",    MMCI0,          &realview_mmc0_plat_data);
 150APB_DEVICE(kmi0,        "fpga:kmi0",    KMI0,           NULL);
 151APB_DEVICE(kmi1,        "fpga:kmi1",    KMI1,           NULL);
 152APB_DEVICE(uart3,       "fpga:uart3",   PBA8_UART3,     NULL);
 153
 154/* DevChip Primecells */
 155AHB_DEVICE(smc,         "dev:smc",      PBA8_SMC,       NULL);
 156AHB_DEVICE(sctl,        "dev:sctl",     SCTL,           NULL);
 157APB_DEVICE(wdog,        "dev:wdog",     PBA8_WATCHDOG, NULL);
 158APB_DEVICE(gpio0,       "dev:gpio0",    PBA8_GPIO0,     &gpio0_plat_data);
 159APB_DEVICE(gpio1,       "dev:gpio1",    GPIO1,          &gpio1_plat_data);
 160APB_DEVICE(gpio2,       "dev:gpio2",    GPIO2,          &gpio2_plat_data);
 161APB_DEVICE(rtc,         "dev:rtc",      PBA8_RTC,       NULL);
 162APB_DEVICE(sci0,        "dev:sci0",     SCI,            NULL);
 163APB_DEVICE(uart0,       "dev:uart0",    PBA8_UART0,     NULL);
 164APB_DEVICE(uart1,       "dev:uart1",    PBA8_UART1,     NULL);
 165APB_DEVICE(uart2,       "dev:uart2",    PBA8_UART2,     NULL);
 166APB_DEVICE(ssp0,        "dev:ssp0",     PBA8_SSP,       &ssp0_plat_data);
 167
 168/* Primecells on the NEC ISSP chip */
 169AHB_DEVICE(clcd,        "issp:clcd",    PBA8_CLCD,      &clcd_plat_data);
 170AHB_DEVICE(dmac,        "issp:dmac",    DMAC,           NULL);
 171
 172static struct amba_device *amba_devs[] __initdata = {
 173        &dmac_device,
 174        &uart0_device,
 175        &uart1_device,
 176        &uart2_device,
 177        &uart3_device,
 178        &smc_device,
 179        &clcd_device,
 180        &sctl_device,
 181        &wdog_device,
 182        &gpio0_device,
 183        &gpio1_device,
 184        &gpio2_device,
 185        &rtc_device,
 186        &sci0_device,
 187        &ssp0_device,
 188        &aaci_device,
 189        &mmc0_device,
 190        &kmi0_device,
 191        &kmi1_device,
 192};
 193
 194/*
 195 * RealView PB-A8 platform devices
 196 */
 197static struct resource realview_pba8_flash_resource[] = {
 198        [0] = {
 199                .start          = REALVIEW_PBA8_FLASH0_BASE,
 200                .end            = REALVIEW_PBA8_FLASH0_BASE + REALVIEW_PBA8_FLASH0_SIZE - 1,
 201                .flags          = IORESOURCE_MEM,
 202        },
 203        [1] = {
 204                .start          = REALVIEW_PBA8_FLASH1_BASE,
 205                .end            = REALVIEW_PBA8_FLASH1_BASE + REALVIEW_PBA8_FLASH1_SIZE - 1,
 206                .flags          = IORESOURCE_MEM,
 207        },
 208};
 209
 210static struct resource realview_pba8_smsc911x_resources[] = {
 211        [0] = {
 212                .start          = REALVIEW_PBA8_ETH_BASE,
 213                .end            = REALVIEW_PBA8_ETH_BASE + SZ_64K - 1,
 214                .flags          = IORESOURCE_MEM,
 215        },
 216        [1] = {
 217                .start          = IRQ_PBA8_ETH,
 218                .end            = IRQ_PBA8_ETH,
 219                .flags          = IORESOURCE_IRQ,
 220        },
 221};
 222
 223static struct resource realview_pba8_isp1761_resources[] = {
 224        [0] = {
 225                .start          = REALVIEW_PBA8_USB_BASE,
 226                .end            = REALVIEW_PBA8_USB_BASE + SZ_128K - 1,
 227                .flags          = IORESOURCE_MEM,
 228        },
 229        [1] = {
 230                .start          = IRQ_PBA8_USB,
 231                .end            = IRQ_PBA8_USB,
 232                .flags          = IORESOURCE_IRQ,
 233        },
 234};
 235
 236static struct resource pmu_resource = {
 237        .start          = IRQ_PBA8_PMU,
 238        .end            = IRQ_PBA8_PMU,
 239        .flags          = IORESOURCE_IRQ,
 240};
 241
 242static struct platform_device pmu_device = {
 243        .name                   = "arm-pmu",
 244        .id                     = -1,
 245        .num_resources          = 1,
 246        .resource               = &pmu_resource,
 247};
 248
 249static void __init gic_init_irq(void)
 250{
 251        /* ARM PB-A8 on-board GIC */
 252        gic_init(0, IRQ_PBA8_GIC_START,
 253                 __io_address(REALVIEW_PBA8_GIC_DIST_BASE),
 254                 __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
 255}
 256
 257static void __init realview_pba8_timer_init(void)
 258{
 259        timer0_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE);
 260        timer1_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE) + 0x20;
 261        timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
 262        timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
 263
 264        realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
 265        realview_timer_init(IRQ_PBA8_TIMER0_1);
 266}
 267
 268static void realview_pba8_restart(enum reboot_mode mode, const char *cmd)
 269{
 270        void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 271        void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
 272
 273        /*
 274         * To reset, we hit the on-board reset register
 275         * in the system FPGA
 276         */
 277        __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
 278        __raw_writel(0x0000, reset_ctrl);
 279        __raw_writel(0x0004, reset_ctrl);
 280        dsb();
 281}
 282
 283static void __init realview_pba8_init(void)
 284{
 285        int i;
 286
 287        realview_flash_register(realview_pba8_flash_resource,
 288                                ARRAY_SIZE(realview_pba8_flash_resource));
 289        realview_eth_register(NULL, realview_pba8_smsc911x_resources);
 290        platform_device_register(&realview_i2c_device);
 291        platform_device_register(&realview_cf_device);
 292        platform_device_register(&realview_leds_device);
 293        realview_usb_register(realview_pba8_isp1761_resources);
 294        platform_device_register(&pmu_device);
 295
 296        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 297                struct amba_device *d = amba_devs[i];
 298                amba_device_register(d, &iomem_resource);
 299        }
 300}
 301
 302MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
 303        /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 304        .atag_offset    = 0x100,
 305        .fixup          = realview_fixup,
 306        .map_io         = realview_pba8_map_io,
 307        .init_early     = realview_init_early,
 308        .init_irq       = gic_init_irq,
 309        .init_time      = realview_pba8_timer_init,
 310        .init_machine   = realview_pba8_init,
 311#ifdef CONFIG_ZONE_DMA
 312        .dma_zone_size  = SZ_256M,
 313#endif
 314        .restart        = realview_pba8_restart,
 315MACHINE_END
 316