linux/arch/arm/mach-vexpress/v2m.c
<<
>>
Prefs
   1/*
   2 * Versatile Express V2M Motherboard Support
   3 */
   4#include <linux/device.h>
   5#include <linux/amba/bus.h>
   6#include <linux/amba/mmci.h>
   7#include <linux/io.h>
   8#include <linux/smp.h>
   9#include <linux/init.h>
  10#include <linux/of_address.h>
  11#include <linux/of_fdt.h>
  12#include <linux/of_irq.h>
  13#include <linux/of_platform.h>
  14#include <linux/platform_device.h>
  15#include <linux/ata_platform.h>
  16#include <linux/smsc911x.h>
  17#include <linux/spinlock.h>
  18#include <linux/usb/isp1760.h>
  19#include <linux/mtd/physmap.h>
  20#include <linux/regulator/fixed.h>
  21#include <linux/regulator/machine.h>
  22#include <linux/vexpress.h>
  23#include <linux/clkdev.h>
  24
  25#include <asm/mach-types.h>
  26#include <asm/sizes.h>
  27#include <asm/mach/arch.h>
  28#include <asm/mach/map.h>
  29#include <asm/mach/time.h>
  30#include <asm/hardware/arm_timer.h>
  31#include <asm/hardware/cache-l2x0.h>
  32#include <asm/hardware/timer-sp.h>
  33
  34#include <mach/ct-ca9x4.h>
  35#include <mach/motherboard.h>
  36
  37#include <plat/sched_clock.h>
  38#include <plat/platsmp.h>
  39
  40#include "core.h"
  41
  42#define V2M_PA_CS0      0x40000000
  43#define V2M_PA_CS1      0x44000000
  44#define V2M_PA_CS2      0x48000000
  45#define V2M_PA_CS3      0x4c000000
  46#define V2M_PA_CS7      0x10000000
  47
  48static struct map_desc v2m_io_desc[] __initdata = {
  49        {
  50                .virtual        = V2M_PERIPH,
  51                .pfn            = __phys_to_pfn(V2M_PA_CS7),
  52                .length         = SZ_128K,
  53                .type           = MT_DEVICE,
  54        },
  55};
  56
  57static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
  58{
  59        if (WARN_ON(!base || irq == NO_IRQ))
  60                return;
  61
  62        sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
  63        sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
  64}
  65
  66
  67static struct resource v2m_pcie_i2c_resource = {
  68        .start  = V2M_SERIAL_BUS_PCI,
  69        .end    = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
  70        .flags  = IORESOURCE_MEM,
  71};
  72
  73static struct platform_device v2m_pcie_i2c_device = {
  74        .name           = "versatile-i2c",
  75        .id             = 0,
  76        .num_resources  = 1,
  77        .resource       = &v2m_pcie_i2c_resource,
  78};
  79
  80static struct resource v2m_ddc_i2c_resource = {
  81        .start  = V2M_SERIAL_BUS_DVI,
  82        .end    = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
  83        .flags  = IORESOURCE_MEM,
  84};
  85
  86static struct platform_device v2m_ddc_i2c_device = {
  87        .name           = "versatile-i2c",
  88        .id             = 1,
  89        .num_resources  = 1,
  90        .resource       = &v2m_ddc_i2c_resource,
  91};
  92
  93static struct resource v2m_eth_resources[] = {
  94        {
  95                .start  = V2M_LAN9118,
  96                .end    = V2M_LAN9118 + SZ_64K - 1,
  97                .flags  = IORESOURCE_MEM,
  98        }, {
  99                .start  = IRQ_V2M_LAN9118,
 100                .end    = IRQ_V2M_LAN9118,
 101                .flags  = IORESOURCE_IRQ,
 102        },
 103};
 104
 105static struct smsc911x_platform_config v2m_eth_config = {
 106        .flags          = SMSC911X_USE_32BIT,
 107        .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
 108        .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
 109        .phy_interface  = PHY_INTERFACE_MODE_MII,
 110};
 111
 112static struct platform_device v2m_eth_device = {
 113        .name           = "smsc911x",
 114        .id             = -1,
 115        .resource       = v2m_eth_resources,
 116        .num_resources  = ARRAY_SIZE(v2m_eth_resources),
 117        .dev.platform_data = &v2m_eth_config,
 118};
 119
 120static struct regulator_consumer_supply v2m_eth_supplies[] = {
 121        REGULATOR_SUPPLY("vddvario", "smsc911x"),
 122        REGULATOR_SUPPLY("vdd33a", "smsc911x"),
 123};
 124
 125static struct resource v2m_usb_resources[] = {
 126        {
 127                .start  = V2M_ISP1761,
 128                .end    = V2M_ISP1761 + SZ_128K - 1,
 129                .flags  = IORESOURCE_MEM,
 130        }, {
 131                .start  = IRQ_V2M_ISP1761,
 132                .end    = IRQ_V2M_ISP1761,
 133                .flags  = IORESOURCE_IRQ,
 134        },
 135};
 136
 137static struct isp1760_platform_data v2m_usb_config = {
 138        .is_isp1761             = true,
 139        .bus_width_16           = false,
 140        .port1_otg              = true,
 141        .analog_oc              = false,
 142        .dack_polarity_high     = false,
 143        .dreq_polarity_high     = false,
 144};
 145
 146static struct platform_device v2m_usb_device = {
 147        .name           = "isp1760",
 148        .id             = -1,
 149        .resource       = v2m_usb_resources,
 150        .num_resources  = ARRAY_SIZE(v2m_usb_resources),
 151        .dev.platform_data = &v2m_usb_config,
 152};
 153
 154static struct physmap_flash_data v2m_flash_data = {
 155        .width          = 4,
 156};
 157
 158static struct resource v2m_flash_resources[] = {
 159        {
 160                .start  = V2M_NOR0,
 161                .end    = V2M_NOR0 + SZ_64M - 1,
 162                .flags  = IORESOURCE_MEM,
 163        }, {
 164                .start  = V2M_NOR1,
 165                .end    = V2M_NOR1 + SZ_64M - 1,
 166                .flags  = IORESOURCE_MEM,
 167        },
 168};
 169
 170static struct platform_device v2m_flash_device = {
 171        .name           = "physmap-flash",
 172        .id             = -1,
 173        .resource       = v2m_flash_resources,
 174        .num_resources  = ARRAY_SIZE(v2m_flash_resources),
 175        .dev.platform_data = &v2m_flash_data,
 176};
 177
 178static struct pata_platform_info v2m_pata_data = {
 179        .ioport_shift   = 2,
 180};
 181
 182static struct resource v2m_pata_resources[] = {
 183        {
 184                .start  = V2M_CF,
 185                .end    = V2M_CF + 0xff,
 186                .flags  = IORESOURCE_MEM,
 187        }, {
 188                .start  = V2M_CF + 0x100,
 189                .end    = V2M_CF + SZ_4K - 1,
 190                .flags  = IORESOURCE_MEM,
 191        },
 192};
 193
 194static struct platform_device v2m_cf_device = {
 195        .name           = "pata_platform",
 196        .id             = -1,
 197        .resource       = v2m_pata_resources,
 198        .num_resources  = ARRAY_SIZE(v2m_pata_resources),
 199        .dev.platform_data = &v2m_pata_data,
 200};
 201
 202static struct mmci_platform_data v2m_mmci_data = {
 203        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
 204        .status         = vexpress_get_mci_cardin,
 205        .gpio_cd        = -1,
 206        .gpio_wp        = -1,
 207};
 208
 209static struct resource v2m_sysreg_resources[] = {
 210        {
 211                .start  = V2M_SYSREGS,
 212                .end    = V2M_SYSREGS + 0xfff,
 213                .flags  = IORESOURCE_MEM,
 214        },
 215};
 216
 217static struct platform_device v2m_sysreg_device = {
 218        .name           = "vexpress-sysreg",
 219        .id             = -1,
 220        .resource       = v2m_sysreg_resources,
 221        .num_resources  = ARRAY_SIZE(v2m_sysreg_resources),
 222};
 223
 224static struct platform_device v2m_muxfpga_device = {
 225        .name           = "vexpress-muxfpga",
 226        .id             = 0,
 227        .num_resources  = 1,
 228        .resource       = (struct resource []) {
 229                VEXPRESS_RES_FUNC(0, 7),
 230        }
 231};
 232
 233static struct platform_device v2m_shutdown_device = {
 234        .name           = "vexpress-shutdown",
 235        .id             = 0,
 236        .num_resources  = 1,
 237        .resource       = (struct resource []) {
 238                VEXPRESS_RES_FUNC(0, 8),
 239        }
 240};
 241
 242static struct platform_device v2m_reboot_device = {
 243        .name           = "vexpress-reboot",
 244        .id             = 0,
 245        .num_resources  = 1,
 246        .resource       = (struct resource []) {
 247                VEXPRESS_RES_FUNC(0, 9),
 248        }
 249};
 250
 251static struct platform_device v2m_dvimode_device = {
 252        .name           = "vexpress-dvimode",
 253        .id             = 0,
 254        .num_resources  = 1,
 255        .resource       = (struct resource []) {
 256                VEXPRESS_RES_FUNC(0, 11),
 257        }
 258};
 259
 260static AMBA_APB_DEVICE(aaci,  "mb:aaci",  0, V2M_AACI, IRQ_V2M_AACI, NULL);
 261static AMBA_APB_DEVICE(mmci,  "mb:mmci",  0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data);
 262static AMBA_APB_DEVICE(kmi0,  "mb:kmi0",  0, V2M_KMI0, IRQ_V2M_KMI0, NULL);
 263static AMBA_APB_DEVICE(kmi1,  "mb:kmi1",  0, V2M_KMI1, IRQ_V2M_KMI1, NULL);
 264static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL);
 265static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL);
 266static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL);
 267static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL);
 268static AMBA_APB_DEVICE(wdt,   "mb:wdt",   0, V2M_WDT, IRQ_V2M_WDT, NULL);
 269static AMBA_APB_DEVICE(rtc,   "mb:rtc",   0, V2M_RTC, IRQ_V2M_RTC, NULL);
 270
 271static struct amba_device *v2m_amba_devs[] __initdata = {
 272        &aaci_device,
 273        &mmci_device,
 274        &kmi0_device,
 275        &kmi1_device,
 276        &uart0_device,
 277        &uart1_device,
 278        &uart2_device,
 279        &uart3_device,
 280        &wdt_device,
 281        &rtc_device,
 282};
 283
 284static void __init v2m_timer_init(void)
 285{
 286        vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
 287        v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
 288}
 289
 290static void __init v2m_init_early(void)
 291{
 292        if (ct_desc->init_early)
 293                ct_desc->init_early();
 294        versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
 295}
 296
 297struct ct_desc *ct_desc;
 298
 299static struct ct_desc *ct_descs[] __initdata = {
 300#ifdef CONFIG_ARCH_VEXPRESS_CA9X4
 301        &ct_ca9x4_desc,
 302#endif
 303};
 304
 305static void __init v2m_populate_ct_desc(void)
 306{
 307        int i;
 308        u32 current_tile_id;
 309
 310        ct_desc = NULL;
 311        current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER)
 312                                & V2M_CT_ID_MASK;
 313
 314        for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
 315                if (ct_descs[i]->id == current_tile_id)
 316                        ct_desc = ct_descs[i];
 317
 318        if (!ct_desc)
 319                panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n"
 320                      "You may need a device tree blob or a different kernel to boot on this board.\n",
 321                      current_tile_id);
 322}
 323
 324static void __init v2m_map_io(void)
 325{
 326        iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
 327        vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K));
 328        v2m_populate_ct_desc();
 329        ct_desc->map_io();
 330}
 331
 332static void __init v2m_init_irq(void)
 333{
 334        ct_desc->init_irq();
 335}
 336
 337static void __init v2m_init(void)
 338{
 339        int i;
 340
 341        regulator_register_fixed(0, v2m_eth_supplies,
 342                        ARRAY_SIZE(v2m_eth_supplies));
 343
 344        platform_device_register(&v2m_sysreg_device);
 345        platform_device_register(&v2m_pcie_i2c_device);
 346        platform_device_register(&v2m_ddc_i2c_device);
 347        platform_device_register(&v2m_flash_device);
 348        platform_device_register(&v2m_cf_device);
 349        platform_device_register(&v2m_eth_device);
 350        platform_device_register(&v2m_usb_device);
 351
 352        for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
 353                amba_device_register(v2m_amba_devs[i], &iomem_resource);
 354
 355        vexpress_syscfg_device_register(&v2m_muxfpga_device);
 356        vexpress_syscfg_device_register(&v2m_shutdown_device);
 357        vexpress_syscfg_device_register(&v2m_reboot_device);
 358        vexpress_syscfg_device_register(&v2m_dvimode_device);
 359
 360        ct_desc->init_tile();
 361}
 362
 363MACHINE_START(VEXPRESS, "ARM-Versatile Express")
 364        .atag_offset    = 0x100,
 365        .smp            = smp_ops(vexpress_smp_ops),
 366        .map_io         = v2m_map_io,
 367        .init_early     = v2m_init_early,
 368        .init_irq       = v2m_init_irq,
 369        .init_time      = v2m_timer_init,
 370        .init_machine   = v2m_init,
 371MACHINE_END
 372
 373static void __init v2m_dt_init(void)
 374{
 375        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 376}
 377
 378static const char * const v2m_dt_match[] __initconst = {
 379        "arm,vexpress",
 380        NULL,
 381};
 382
 383DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
 384        .dt_compat      = v2m_dt_match,
 385        .l2c_aux_val    = 0x00400000,
 386        .l2c_aux_mask   = 0xfe0fffff,
 387        .smp            = smp_ops(vexpress_smp_dt_ops),
 388        .smp_init       = smp_init_ops(vexpress_smp_init_ops),
 389        .init_machine   = v2m_dt_init,
 390MACHINE_END
 391