linux/arch/arm/mach-u300/core.c
<<
>>
Prefs
   1/*
   2 *
   3 * arch/arm/mach-u300/core.c
   4 *
   5 *
   6 * Copyright (C) 2007-2009 ST-Ericsson AB
   7 * License terms: GNU General Public License (GPL) version 2
   8 * Core platform support, IRQ handling and device definitions.
   9 * Author: Linus Walleij <linus.walleij@stericsson.com>
  10 */
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/spinlock.h>
  14#include <linux/interrupt.h>
  15#include <linux/bitops.h>
  16#include <linux/device.h>
  17#include <linux/mm.h>
  18#include <linux/termios.h>
  19#include <linux/amba/bus.h>
  20#include <linux/platform_device.h>
  21#include <linux/gpio.h>
  22
  23#include <asm/types.h>
  24#include <asm/setup.h>
  25#include <asm/memory.h>
  26#include <asm/hardware/vic.h>
  27#include <asm/mach/map.h>
  28#include <asm/mach/irq.h>
  29
  30#include <mach/hardware.h>
  31#include <mach/syscon.h>
  32
  33#include "clock.h"
  34#include "mmc.h"
  35#include "spi.h"
  36#include "i2c.h"
  37
  38/*
  39 * Static I/O mappings that are needed for booting the U300 platforms. The
  40 * only things we need are the areas where we find the timer, syscon and
  41 * intcon, since the remaining device drivers will map their own memory
  42 * physical to virtual as the need arise.
  43 */
  44static struct map_desc u300_io_desc[] __initdata = {
  45        {
  46                .virtual        = U300_SLOW_PER_VIRT_BASE,
  47                .pfn            = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
  48                .length         = SZ_64K,
  49                .type           = MT_DEVICE,
  50        },
  51        {
  52                .virtual        = U300_AHB_PER_VIRT_BASE,
  53                .pfn            = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
  54                .length         = SZ_32K,
  55                .type           = MT_DEVICE,
  56        },
  57        {
  58                .virtual        = U300_FAST_PER_VIRT_BASE,
  59                .pfn            = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
  60                .length         = SZ_32K,
  61                .type           = MT_DEVICE,
  62        },
  63        {
  64                .virtual        = 0xffff2000, /* TCM memory */
  65                .pfn            = __phys_to_pfn(0xffff2000),
  66                .length         = SZ_16K,
  67                .type           = MT_DEVICE,
  68        },
  69
  70        /*
  71         * This overlaps with the IRQ vectors etc at 0xffff0000, so these
  72         * may have to be moved to 0x00000000 in order to use the ROM.
  73         */
  74        /*
  75        {
  76                .virtual        = U300_BOOTROM_VIRT_BASE,
  77                .pfn            = __phys_to_pfn(U300_BOOTROM_PHYS_BASE),
  78                .length         = SZ_64K,
  79                .type           = MT_ROM,
  80        },
  81        */
  82};
  83
  84void __init u300_map_io(void)
  85{
  86        iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
  87}
  88
  89/*
  90 * Declaration of devices found on the U300 board and
  91 * their respective memory locations.
  92 */
  93static struct amba_device uart0_device = {
  94        .dev = {
  95                .init_name = "uart0", /* Slow device at 0x3000 offset */
  96                .platform_data = NULL,
  97        },
  98        .res = {
  99                .start = U300_UART0_BASE,
 100                .end   = U300_UART0_BASE + SZ_4K - 1,
 101                .flags = IORESOURCE_MEM,
 102        },
 103        .irq = { IRQ_U300_UART0, NO_IRQ },
 104};
 105
 106/* The U335 have an additional UART1 on the APP CPU */
 107#ifdef CONFIG_MACH_U300_BS335
 108static struct amba_device uart1_device = {
 109        .dev = {
 110                .init_name = "uart1", /* Fast device at 0x7000 offset */
 111                .platform_data = NULL,
 112        },
 113        .res = {
 114                .start = U300_UART1_BASE,
 115                .end   = U300_UART1_BASE + SZ_4K - 1,
 116                .flags = IORESOURCE_MEM,
 117        },
 118        .irq = { IRQ_U300_UART1, NO_IRQ },
 119};
 120#endif
 121
 122static struct amba_device pl172_device = {
 123        .dev = {
 124                .init_name = "pl172", /* AHB device at 0x4000 offset */
 125                .platform_data = NULL,
 126        },
 127        .res = {
 128                .start = U300_EMIF_CFG_BASE,
 129                .end   = U300_EMIF_CFG_BASE + SZ_4K - 1,
 130                .flags = IORESOURCE_MEM,
 131        },
 132};
 133
 134
 135/*
 136 * Everything within this next ifdef deals with external devices connected to
 137 * the APP SPI bus.
 138 */
 139static struct amba_device pl022_device = {
 140        .dev = {
 141                .coherent_dma_mask = ~0,
 142                .init_name = "pl022", /* Fast device at 0x6000 offset */
 143        },
 144        .res = {
 145                .start = U300_SPI_BASE,
 146                .end   = U300_SPI_BASE + SZ_4K - 1,
 147                .flags = IORESOURCE_MEM,
 148        },
 149        .irq = {IRQ_U300_SPI, NO_IRQ },
 150        /*
 151         * This device has a DMA channel but the Linux driver does not use
 152         * it currently.
 153         */
 154};
 155
 156static struct amba_device mmcsd_device = {
 157        .dev = {
 158                .init_name = "mmci", /* Fast device at 0x1000 offset */
 159                .platform_data = NULL, /* Added later */
 160        },
 161        .res = {
 162                .start = U300_MMCSD_BASE,
 163                .end   = U300_MMCSD_BASE + SZ_4K - 1,
 164                .flags = IORESOURCE_MEM,
 165        },
 166        .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
 167        /*
 168         * This device has a DMA channel but the Linux driver does not use
 169         * it currently.
 170         */
 171};
 172
 173/*
 174 * The order of device declaration may be important, since some devices
 175 * have dependencies on other devices being initialized first.
 176 */
 177static struct amba_device *amba_devs[] __initdata = {
 178        &uart0_device,
 179#ifdef CONFIG_MACH_U300_BS335
 180        &uart1_device,
 181#endif
 182        &pl022_device,
 183        &pl172_device,
 184        &mmcsd_device,
 185};
 186
 187/* Here follows a list of all hw resources that the platform devices
 188 * allocate. Note, clock dependencies are not included
 189 */
 190
 191static struct resource gpio_resources[] = {
 192        {
 193                .start = U300_GPIO_BASE,
 194                .end   = (U300_GPIO_BASE + SZ_4K - 1),
 195                .flags = IORESOURCE_MEM,
 196        },
 197        {
 198                .name  = "gpio0",
 199                .start = IRQ_U300_GPIO_PORT0,
 200                .end   = IRQ_U300_GPIO_PORT0,
 201                .flags = IORESOURCE_IRQ,
 202        },
 203        {
 204                .name  = "gpio1",
 205                .start = IRQ_U300_GPIO_PORT1,
 206                .end   = IRQ_U300_GPIO_PORT1,
 207                .flags = IORESOURCE_IRQ,
 208        },
 209        {
 210                .name  = "gpio2",
 211                .start = IRQ_U300_GPIO_PORT2,
 212                .end   = IRQ_U300_GPIO_PORT2,
 213                .flags = IORESOURCE_IRQ,
 214        },
 215#ifdef U300_COH901571_3
 216        {
 217                .name  = "gpio3",
 218                .start = IRQ_U300_GPIO_PORT3,
 219                .end   = IRQ_U300_GPIO_PORT3,
 220                .flags = IORESOURCE_IRQ,
 221        },
 222        {
 223                .name  = "gpio4",
 224                .start = IRQ_U300_GPIO_PORT4,
 225                .end   = IRQ_U300_GPIO_PORT4,
 226                .flags = IORESOURCE_IRQ,
 227        },
 228#ifdef CONFIG_MACH_U300_BS335
 229        {
 230                .name  = "gpio5",
 231                .start = IRQ_U300_GPIO_PORT5,
 232                .end   = IRQ_U300_GPIO_PORT5,
 233                .flags = IORESOURCE_IRQ,
 234        },
 235        {
 236                .name  = "gpio6",
 237                .start = IRQ_U300_GPIO_PORT6,
 238                .end   = IRQ_U300_GPIO_PORT6,
 239                .flags = IORESOURCE_IRQ,
 240        },
 241#endif /* CONFIG_MACH_U300_BS335 */
 242#endif /* U300_COH901571_3 */
 243};
 244
 245static struct resource keypad_resources[] = {
 246        {
 247                .start = U300_KEYPAD_BASE,
 248                .end   = U300_KEYPAD_BASE + SZ_4K - 1,
 249                .flags = IORESOURCE_MEM,
 250        },
 251        {
 252                .name  = "coh901461-press",
 253                .start = IRQ_U300_KEYPAD_KEYBF,
 254                .end   = IRQ_U300_KEYPAD_KEYBF,
 255                .flags = IORESOURCE_IRQ,
 256        },
 257        {
 258                .name  = "coh901461-release",
 259                .start = IRQ_U300_KEYPAD_KEYBR,
 260                .end   = IRQ_U300_KEYPAD_KEYBR,
 261                .flags = IORESOURCE_IRQ,
 262        },
 263};
 264
 265static struct resource rtc_resources[] = {
 266        {
 267                .start = U300_RTC_BASE,
 268                .end   = U300_RTC_BASE + SZ_4K - 1,
 269                .flags = IORESOURCE_MEM,
 270        },
 271        {
 272                .start = IRQ_U300_RTC,
 273                .end   = IRQ_U300_RTC,
 274                .flags = IORESOURCE_IRQ,
 275        },
 276};
 277
 278/*
 279 * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
 280 * but these are not yet used by the driver.
 281 */
 282static struct resource fsmc_resources[] = {
 283        {
 284                .start = U300_NAND_IF_PHYS_BASE,
 285                .end   = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
 286                .flags = IORESOURCE_MEM,
 287        },
 288};
 289
 290static struct resource i2c0_resources[] = {
 291        {
 292                .start = U300_I2C0_BASE,
 293                .end   = U300_I2C0_BASE + SZ_4K - 1,
 294                .flags = IORESOURCE_MEM,
 295        },
 296        {
 297                .start = IRQ_U300_I2C0,
 298                .end   = IRQ_U300_I2C0,
 299                .flags = IORESOURCE_IRQ,
 300        },
 301};
 302
 303static struct resource i2c1_resources[] = {
 304        {
 305                .start = U300_I2C1_BASE,
 306                .end   = U300_I2C1_BASE + SZ_4K - 1,
 307                .flags = IORESOURCE_MEM,
 308        },
 309        {
 310                .start = IRQ_U300_I2C1,
 311                .end   = IRQ_U300_I2C1,
 312                .flags = IORESOURCE_IRQ,
 313        },
 314
 315};
 316
 317static struct resource wdog_resources[] = {
 318        {
 319                .start = U300_WDOG_BASE,
 320                .end   = U300_WDOG_BASE + SZ_4K - 1,
 321                .flags = IORESOURCE_MEM,
 322        },
 323        {
 324                .start = IRQ_U300_WDOG,
 325                .end   = IRQ_U300_WDOG,
 326                .flags = IORESOURCE_IRQ,
 327        }
 328};
 329
 330/* TODO: These should be protected by suitable #ifdef's */
 331static struct resource ave_resources[] = {
 332        {
 333                .name  = "AVE3e I/O Area",
 334                .start = U300_VIDEOENC_BASE,
 335                .end   = U300_VIDEOENC_BASE + SZ_512K - 1,
 336                .flags = IORESOURCE_MEM,
 337        },
 338        {
 339                .name  = "AVE3e IRQ0",
 340                .start = IRQ_U300_VIDEO_ENC_0,
 341                .end   = IRQ_U300_VIDEO_ENC_0,
 342                .flags = IORESOURCE_IRQ,
 343        },
 344        {
 345                .name  = "AVE3e IRQ1",
 346                .start = IRQ_U300_VIDEO_ENC_1,
 347                .end   = IRQ_U300_VIDEO_ENC_1,
 348                .flags = IORESOURCE_IRQ,
 349        },
 350        {
 351                .name  = "AVE3e Physmem Area",
 352                .start = 0, /* 0 will be remapped to reserved memory */
 353                .end   = SZ_1M - 1,
 354                .flags = IORESOURCE_MEM,
 355        },
 356        /*
 357         * The AVE3e requires two regions of 256MB that it considers
 358         * "invisible". The hardware will not be able to access these
 359         * adresses, so they should never point to system RAM.
 360         */
 361        {
 362                .name  = "AVE3e Reserved 0",
 363                .start = 0xd0000000,
 364                .end   = 0xd0000000 + SZ_256M - 1,
 365                .flags = IORESOURCE_MEM,
 366        },
 367        {
 368                .name  = "AVE3e Reserved 1",
 369                .start = 0xe0000000,
 370                .end   = 0xe0000000 + SZ_256M - 1,
 371                .flags = IORESOURCE_MEM,
 372        },
 373};
 374
 375static struct platform_device wdog_device = {
 376        .name = "wdog",
 377        .id = -1,
 378        .num_resources = ARRAY_SIZE(wdog_resources),
 379        .resource = wdog_resources,
 380};
 381
 382static struct platform_device i2c0_device = {
 383        .name = "stu300",
 384        .id = 0,
 385        .num_resources = ARRAY_SIZE(i2c0_resources),
 386        .resource = i2c0_resources,
 387};
 388
 389static struct platform_device i2c1_device = {
 390        .name = "stu300",
 391        .id = 1,
 392        .num_resources = ARRAY_SIZE(i2c1_resources),
 393        .resource = i2c1_resources,
 394};
 395
 396static struct platform_device gpio_device = {
 397        .name = "u300-gpio",
 398        .id = -1,
 399        .num_resources = ARRAY_SIZE(gpio_resources),
 400        .resource = gpio_resources,
 401};
 402
 403static struct platform_device keypad_device = {
 404        .name = "keypad",
 405        .id = -1,
 406        .num_resources = ARRAY_SIZE(keypad_resources),
 407        .resource = keypad_resources,
 408};
 409
 410static struct platform_device rtc_device = {
 411        .name = "rtc-coh901331",
 412        .id = -1,
 413        .num_resources = ARRAY_SIZE(rtc_resources),
 414        .resource = rtc_resources,
 415};
 416
 417static struct platform_device fsmc_device = {
 418        .name = "nandif",
 419        .id = -1,
 420        .num_resources = ARRAY_SIZE(fsmc_resources),
 421        .resource = fsmc_resources,
 422};
 423
 424static struct platform_device ave_device = {
 425        .name = "video_enc",
 426        .id = -1,
 427        .num_resources = ARRAY_SIZE(ave_resources),
 428        .resource = ave_resources,
 429};
 430
 431/*
 432 * Notice that AMBA devices are initialized before platform devices.
 433 *
 434 */
 435static struct platform_device *platform_devs[] __initdata = {
 436        &i2c0_device,
 437        &i2c1_device,
 438        &keypad_device,
 439        &rtc_device,
 440        &gpio_device,
 441        &fsmc_device,
 442        &wdog_device,
 443        &ave_device
 444};
 445
 446
 447/*
 448 * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
 449 * together so some interrupts are connected to the first one and some
 450 * to the second one.
 451 */
 452void __init u300_init_irq(void)
 453{
 454        u32 mask[2] = {0, 0};
 455        int i;
 456
 457        for (i = 0; i < NR_IRQS; i++)
 458                set_bit(i, (unsigned long *) &mask[0]);
 459        u300_enable_intcon_clock();
 460        vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]);
 461        vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);
 462}
 463
 464
 465/*
 466 * U300 platforms peripheral handling
 467 */
 468struct db_chip {
 469        u16 chipid;
 470        const char *name;
 471};
 472
 473/*
 474 * This is a list of the Digital Baseband chips used in the U300 platform.
 475 */
 476static struct db_chip db_chips[] __initdata = {
 477        {
 478                .chipid = 0xb800,
 479                .name = "DB3000",
 480        },
 481        {
 482                .chipid = 0xc000,
 483                .name = "DB3100",
 484        },
 485        {
 486                .chipid = 0xc800,
 487                .name = "DB3150",
 488        },
 489        {
 490                .chipid = 0xd800,
 491                .name = "DB3200",
 492        },
 493        {
 494                .chipid = 0xe000,
 495                .name = "DB3250",
 496        },
 497        {
 498                .chipid = 0xe800,
 499                .name = "DB3210",
 500        },
 501        {
 502                .chipid = 0xf000,
 503                .name = "DB3350 P1x",
 504        },
 505        {
 506                .chipid = 0xf100,
 507                .name = "DB3350 P2x",
 508        },
 509        {
 510                .chipid = 0x0000, /* List terminator */
 511                .name = NULL,
 512        }
 513};
 514
 515static void __init u300_init_check_chip(void)
 516{
 517
 518        u16 val;
 519        struct db_chip *chip;
 520        const char *chipname;
 521        const char unknown[] = "UNKNOWN";
 522
 523        /* Read out and print chip ID */
 524        val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
 525        /* This is in funky bigendian order... */
 526        val = (val & 0xFFU) << 8 | (val >> 8);
 527        chip = db_chips;
 528        chipname = unknown;
 529
 530        for ( ; chip->chipid; chip++) {
 531                if (chip->chipid == (val & 0xFF00U)) {
 532                        chipname = chip->name;
 533                        break;
 534                }
 535        }
 536        printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
 537               "(chip ID 0x%04x)\n", chipname, val);
 538
 539#ifdef CONFIG_MACH_U300_BS26
 540        if ((val & 0xFF00U) != 0xc800) {
 541                printk(KERN_ERR "Platform configured for BS25/BS26 " \
 542                       "with DB3150 but %s detected, expect problems!",
 543                       chipname);
 544        }
 545#endif
 546#ifdef CONFIG_MACH_U300_BS330
 547        if ((val & 0xFF00U) != 0xd800) {
 548                printk(KERN_ERR "Platform configured for BS330 " \
 549                       "with DB3200 but %s detected, expect problems!",
 550                       chipname);
 551        }
 552#endif
 553#ifdef CONFIG_MACH_U300_BS335
 554        if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
 555                printk(KERN_ERR "Platform configured for BS365 " \
 556                       " with DB3350 but %s detected, expect problems!",
 557                       chipname);
 558        }
 559#endif
 560#ifdef CONFIG_MACH_U300_BS365
 561        if ((val & 0xFF00U) != 0xe800) {
 562                printk(KERN_ERR "Platform configured for BS365 " \
 563                       "with DB3210 but %s detected, expect problems!",
 564                       chipname);
 565        }
 566#endif
 567
 568
 569}
 570
 571/*
 572 * Some devices and their resources require reserved physical memory from
 573 * the end of the available RAM. This function traverses the list of devices
 574 * and assigns actual adresses to these.
 575 */
 576static void __init u300_assign_physmem(void)
 577{
 578        unsigned long curr_start = __pa(high_memory);
 579        int i, j;
 580
 581        for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
 582                for (j = 0; j < platform_devs[i]->num_resources; j++) {
 583                        struct resource *const res =
 584                          &platform_devs[i]->resource[j];
 585
 586                        if (IORESOURCE_MEM == res->flags &&
 587                                     0 == res->start) {
 588                                res->start  = curr_start;
 589                                res->end   += curr_start;
 590                                curr_start += (res->end - res->start + 1);
 591
 592                                printk(KERN_INFO "core.c: Mapping RAM " \
 593                                       "%#x-%#x to device %s:%s\n",
 594                                        res->start, res->end,
 595                                       platform_devs[i]->name, res->name);
 596                        }
 597                }
 598        }
 599}
 600
 601void __init u300_init_devices(void)
 602{
 603        int i;
 604        u16 val;
 605
 606        /* Check what platform we run and print some status information */
 607        u300_init_check_chip();
 608
 609        /* Set system to run at PLL208, max performance, a known state. */
 610        val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
 611        val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
 612        writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
 613        /* Wait for the PLL208 to lock if not locked in yet */
 614        while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
 615                 U300_SYSCON_CSR_PLL208_LOCK_IND));
 616        /* Initialize SPI device with some board specifics */
 617        u300_spi_init(&pl022_device);
 618
 619        /* Register the AMBA devices in the AMBA bus abstraction layer */
 620        u300_clock_primecells();
 621        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 622                struct amba_device *d = amba_devs[i];
 623                amba_device_register(d, &iomem_resource);
 624        }
 625        u300_unclock_primecells();
 626
 627        u300_assign_physmem();
 628
 629        /* Register subdevices on the I2C buses */
 630        u300_i2c_register_board_devices();
 631
 632        /* Register subdevices on the SPI bus */
 633        u300_spi_register_board_devices();
 634
 635        /* Register the platform devices */
 636        platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
 637
 638#ifndef CONFIG_MACH_U300_SEMI_IS_SHARED
 639        /*
 640         * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when
 641         * both subsystems are requesting this mode.
 642         * If we not share the Acc SDRAM, this is never the case. Therefore
 643         * enable it here from the App side.
 644         */
 645        val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
 646                U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
 647        writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
 648#endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */
 649}
 650
 651static int core_module_init(void)
 652{
 653        /*
 654         * This needs to be initialized later: it needs the input framework
 655         * to be initialized first.
 656         */
 657        return mmc_init(&mmcsd_device);
 658}
 659module_init(core_module_init);
 660