linux/arch/arm/mach-versatile/core.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-versatile/core.c
   3 *
   4 *  Copyright (C) 1999 - 2003 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#include <linux/init.h>
  22#include <linux/device.h>
  23#include <linux/dma-mapping.h>
  24#include <linux/platform_device.h>
  25#include <linux/sysdev.h>
  26#include <linux/interrupt.h>
  27#include <linux/amba/bus.h>
  28#include <linux/amba/clcd.h>
  29#include <linux/amba/pl061.h>
  30#include <linux/amba/mmci.h>
  31#include <linux/clocksource.h>
  32#include <linux/clockchips.h>
  33#include <linux/cnt32_to_63.h>
  34#include <linux/io.h>
  35
  36#include <asm/clkdev.h>
  37#include <asm/system.h>
  38#include <mach/hardware.h>
  39#include <asm/irq.h>
  40#include <asm/leds.h>
  41#include <asm/hardware/arm_timer.h>
  42#include <asm/hardware/icst307.h>
  43#include <asm/hardware/vic.h>
  44#include <asm/mach-types.h>
  45
  46#include <asm/mach/arch.h>
  47#include <asm/mach/flash.h>
  48#include <asm/mach/irq.h>
  49#include <asm/mach/time.h>
  50#include <asm/mach/map.h>
  51
  52#include "core.h"
  53#include "clock.h"
  54
  55/*
  56 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
  57 * is the (PA >> 12).
  58 *
  59 * Setup a VA for the Versatile Vectored Interrupt Controller.
  60 */
  61#define __io_address(n)         __io(IO_ADDRESS(n))
  62#define VA_VIC_BASE             __io_address(VERSATILE_VIC_BASE)
  63#define VA_SIC_BASE             __io_address(VERSATILE_SIC_BASE)
  64
  65static void sic_mask_irq(unsigned int irq)
  66{
  67        irq -= IRQ_SIC_START;
  68        writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
  69}
  70
  71static void sic_unmask_irq(unsigned int irq)
  72{
  73        irq -= IRQ_SIC_START;
  74        writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
  75}
  76
  77static struct irq_chip sic_chip = {
  78        .name   = "SIC",
  79        .ack    = sic_mask_irq,
  80        .mask   = sic_mask_irq,
  81        .unmask = sic_unmask_irq,
  82};
  83
  84static void
  85sic_handle_irq(unsigned int irq, struct irq_desc *desc)
  86{
  87        unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
  88
  89        if (status == 0) {
  90                do_bad_IRQ(irq, desc);
  91                return;
  92        }
  93
  94        do {
  95                irq = ffs(status) - 1;
  96                status &= ~(1 << irq);
  97
  98                irq += IRQ_SIC_START;
  99
 100                generic_handle_irq(irq);
 101        } while (status);
 102}
 103
 104#if 1
 105#define IRQ_MMCI0A      IRQ_VICSOURCE22
 106#define IRQ_AACI        IRQ_VICSOURCE24
 107#define IRQ_ETH         IRQ_VICSOURCE25
 108#define PIC_MASK        0xFFD00000
 109#else
 110#define IRQ_MMCI0A      IRQ_SIC_MMCI0A
 111#define IRQ_AACI        IRQ_SIC_AACI
 112#define IRQ_ETH         IRQ_SIC_ETH
 113#define PIC_MASK        0
 114#endif
 115
 116void __init versatile_init_irq(void)
 117{
 118        unsigned int i;
 119
 120        vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
 121
 122        set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
 123
 124        /* Do second interrupt controller */
 125        writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 126
 127        for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
 128                if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {
 129                        set_irq_chip(i, &sic_chip);
 130                        set_irq_handler(i, handle_level_irq);
 131                        set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 132                }
 133        }
 134
 135        /*
 136         * Interrupts on secondary controller from 0 to 8 are routed to
 137         * source 31 on PIC.
 138         * Interrupts from 21 to 31 are routed directly to the VIC on
 139         * the corresponding number on primary controller. This is controlled
 140         * by setting PIC_ENABLEx.
 141         */
 142        writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);
 143}
 144
 145static struct map_desc versatile_io_desc[] __initdata = {
 146        {
 147                .virtual        =  IO_ADDRESS(VERSATILE_SYS_BASE),
 148                .pfn            = __phys_to_pfn(VERSATILE_SYS_BASE),
 149                .length         = SZ_4K,
 150                .type           = MT_DEVICE
 151        }, {
 152                .virtual        =  IO_ADDRESS(VERSATILE_SIC_BASE),
 153                .pfn            = __phys_to_pfn(VERSATILE_SIC_BASE),
 154                .length         = SZ_4K,
 155                .type           = MT_DEVICE
 156        }, {
 157                .virtual        =  IO_ADDRESS(VERSATILE_VIC_BASE),
 158                .pfn            = __phys_to_pfn(VERSATILE_VIC_BASE),
 159                .length         = SZ_4K,
 160                .type           = MT_DEVICE
 161        }, {
 162                .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
 163                .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
 164                .length         = SZ_4K * 9,
 165                .type           = MT_DEVICE
 166        },
 167#ifdef CONFIG_MACH_VERSATILE_AB
 168        {
 169                .virtual        =  IO_ADDRESS(VERSATILE_GPIO0_BASE),
 170                .pfn            = __phys_to_pfn(VERSATILE_GPIO0_BASE),
 171                .length         = SZ_4K,
 172                .type           = MT_DEVICE
 173        }, {
 174                .virtual        =  IO_ADDRESS(VERSATILE_IB2_BASE),
 175                .pfn            = __phys_to_pfn(VERSATILE_IB2_BASE),
 176                .length         = SZ_64M,
 177                .type           = MT_DEVICE
 178        },
 179#endif
 180#ifdef CONFIG_DEBUG_LL
 181        {
 182                .virtual        =  IO_ADDRESS(VERSATILE_UART0_BASE),
 183                .pfn            = __phys_to_pfn(VERSATILE_UART0_BASE),
 184                .length         = SZ_4K,
 185                .type           = MT_DEVICE
 186        },
 187#endif
 188#ifdef CONFIG_PCI
 189        {
 190                .virtual        =  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
 191                .pfn            = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
 192                .length         = SZ_4K,
 193                .type           = MT_DEVICE
 194        }, {
 195                .virtual        =  (unsigned long)VERSATILE_PCI_VIRT_BASE,
 196                .pfn            = __phys_to_pfn(VERSATILE_PCI_BASE),
 197                .length         = VERSATILE_PCI_BASE_SIZE,
 198                .type           = MT_DEVICE
 199        }, {
 200                .virtual        =  (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,
 201                .pfn            = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
 202                .length         = VERSATILE_PCI_CFG_BASE_SIZE,
 203                .type           = MT_DEVICE
 204        },
 205#if 0
 206        {
 207                .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE0,
 208                .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
 209                .length         = SZ_16M,
 210                .type           = MT_DEVICE
 211        }, {
 212                .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE1,
 213                .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
 214                .length         = SZ_16M,
 215                .type           = MT_DEVICE
 216        }, {
 217                .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE2,
 218                .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
 219                .length         = SZ_16M,
 220                .type           = MT_DEVICE
 221        },
 222#endif
 223#endif
 224};
 225
 226void __init versatile_map_io(void)
 227{
 228        iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 229}
 230
 231#define VERSATILE_REFCOUNTER    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
 232
 233/*
 234 * This is the Versatile sched_clock implementation.  This has
 235 * a resolution of 41.7ns, and a maximum value of about 35583 days.
 236 *
 237 * The return value is guaranteed to be monotonic in that range as
 238 * long as there is always less than 89 seconds between successive
 239 * calls to this function.
 240 */
 241unsigned long long sched_clock(void)
 242{
 243        unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER));
 244
 245        /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
 246        v *= 125<<1;
 247        do_div(v, 3<<1);
 248
 249        return v;
 250}
 251
 252
 253#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 254
 255static int versatile_flash_init(void)
 256{
 257        u32 val;
 258
 259        val = __raw_readl(VERSATILE_FLASHCTRL);
 260        val &= ~VERSATILE_FLASHPROG_FLVPPEN;
 261        __raw_writel(val, VERSATILE_FLASHCTRL);
 262
 263        return 0;
 264}
 265
 266static void versatile_flash_exit(void)
 267{
 268        u32 val;
 269
 270        val = __raw_readl(VERSATILE_FLASHCTRL);
 271        val &= ~VERSATILE_FLASHPROG_FLVPPEN;
 272        __raw_writel(val, VERSATILE_FLASHCTRL);
 273}
 274
 275static void versatile_flash_set_vpp(int on)
 276{
 277        u32 val;
 278
 279        val = __raw_readl(VERSATILE_FLASHCTRL);
 280        if (on)
 281                val |= VERSATILE_FLASHPROG_FLVPPEN;
 282        else
 283                val &= ~VERSATILE_FLASHPROG_FLVPPEN;
 284        __raw_writel(val, VERSATILE_FLASHCTRL);
 285}
 286
 287static struct flash_platform_data versatile_flash_data = {
 288        .map_name               = "cfi_probe",
 289        .width                  = 4,
 290        .init                   = versatile_flash_init,
 291        .exit                   = versatile_flash_exit,
 292        .set_vpp                = versatile_flash_set_vpp,
 293};
 294
 295static struct resource versatile_flash_resource = {
 296        .start                  = VERSATILE_FLASH_BASE,
 297        .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
 298        .flags                  = IORESOURCE_MEM,
 299};
 300
 301static struct platform_device versatile_flash_device = {
 302        .name                   = "armflash",
 303        .id                     = 0,
 304        .dev                    = {
 305                .platform_data  = &versatile_flash_data,
 306        },
 307        .num_resources          = 1,
 308        .resource               = &versatile_flash_resource,
 309};
 310
 311static struct resource smc91x_resources[] = {
 312        [0] = {
 313                .start          = VERSATILE_ETH_BASE,
 314                .end            = VERSATILE_ETH_BASE + SZ_64K - 1,
 315                .flags          = IORESOURCE_MEM,
 316        },
 317        [1] = {
 318                .start          = IRQ_ETH,
 319                .end            = IRQ_ETH,
 320                .flags          = IORESOURCE_IRQ,
 321        },
 322};
 323
 324static struct platform_device smc91x_device = {
 325        .name           = "smc91x",
 326        .id             = 0,
 327        .num_resources  = ARRAY_SIZE(smc91x_resources),
 328        .resource       = smc91x_resources,
 329};
 330
 331static struct resource versatile_i2c_resource = {
 332        .start                  = VERSATILE_I2C_BASE,
 333        .end                    = VERSATILE_I2C_BASE + SZ_4K - 1,
 334        .flags                  = IORESOURCE_MEM,
 335};
 336
 337static struct platform_device versatile_i2c_device = {
 338        .name                   = "versatile-i2c",
 339        .id                     = 0,
 340        .num_resources          = 1,
 341        .resource               = &versatile_i2c_resource,
 342};
 343
 344static struct i2c_board_info versatile_i2c_board_info[] = {
 345        {
 346                I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
 347        },
 348};
 349
 350static int __init versatile_i2c_init(void)
 351{
 352        return i2c_register_board_info(0, versatile_i2c_board_info,
 353                                       ARRAY_SIZE(versatile_i2c_board_info));
 354}
 355arch_initcall(versatile_i2c_init);
 356
 357#define VERSATILE_SYSMCI        (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 358
 359unsigned int mmc_status(struct device *dev)
 360{
 361        struct amba_device *adev = container_of(dev, struct amba_device, dev);
 362        u32 mask;
 363
 364        if (adev->res.start == VERSATILE_MMCI0_BASE)
 365                mask = 1;
 366        else
 367                mask = 2;
 368
 369        return readl(VERSATILE_SYSMCI) & mask;
 370}
 371
 372static struct mmci_platform_data mmc0_plat_data = {
 373        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
 374        .status         = mmc_status,
 375        .gpio_wp        = -1,
 376        .gpio_cd        = -1,
 377};
 378
 379/*
 380 * Clock handling
 381 */
 382static const struct icst307_params versatile_oscvco_params = {
 383        .ref            = 24000,
 384        .vco_max        = 200000,
 385        .vd_min         = 4 + 8,
 386        .vd_max         = 511 + 8,
 387        .rd_min         = 1 + 2,
 388        .rd_max         = 127 + 2,
 389};
 390
 391static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
 392{
 393        void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
 394        void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET;
 395        u32 val;
 396
 397        val = readl(sys + clk->oscoff) & ~0x7ffff;
 398        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 399
 400        writel(0xa05f, sys_lock);
 401        writel(val, sys + clk->oscoff);
 402        writel(0, sys_lock);
 403}
 404
 405static struct clk osc4_clk = {
 406        .params = &versatile_oscvco_params,
 407        .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET,
 408        .setvco = versatile_oscvco_set,
 409};
 410
 411/*
 412 * These are fixed clocks.
 413 */
 414static struct clk ref24_clk = {
 415        .rate   = 24000000,
 416};
 417
 418static struct clk_lookup lookups[] = {
 419        {       /* UART0 */
 420                .dev_id         = "dev:f1",
 421                .clk            = &ref24_clk,
 422        }, {    /* UART1 */
 423                .dev_id         = "dev:f2",
 424                .clk            = &ref24_clk,
 425        }, {    /* UART2 */
 426                .dev_id         = "dev:f3",
 427                .clk            = &ref24_clk,
 428        }, {    /* UART3 */
 429                .dev_id         = "fpga:09",
 430                .clk            = &ref24_clk,
 431        }, {    /* KMI0 */
 432                .dev_id         = "fpga:06",
 433                .clk            = &ref24_clk,
 434        }, {    /* KMI1 */
 435                .dev_id         = "fpga:07",
 436                .clk            = &ref24_clk,
 437        }, {    /* MMC0 */
 438                .dev_id         = "fpga:05",
 439                .clk            = &ref24_clk,
 440        }, {    /* MMC1 */
 441                .dev_id         = "fpga:0b",
 442                .clk            = &ref24_clk,
 443        }, {    /* CLCD */
 444                .dev_id         = "dev:20",
 445                .clk            = &osc4_clk,
 446        }
 447};
 448
 449/*
 450 * CLCD support.
 451 */
 452#define SYS_CLCD_MODE_MASK      (3 << 0)
 453#define SYS_CLCD_MODE_888       (0 << 0)
 454#define SYS_CLCD_MODE_5551      (1 << 0)
 455#define SYS_CLCD_MODE_565_RLSB  (2 << 0)
 456#define SYS_CLCD_MODE_565_BLSB  (3 << 0)
 457#define SYS_CLCD_NLCDIOON       (1 << 2)
 458#define SYS_CLCD_VDDPOSSWITCH   (1 << 3)
 459#define SYS_CLCD_PWR3V5SWITCH   (1 << 4)
 460#define SYS_CLCD_ID_MASK        (0x1f << 8)
 461#define SYS_CLCD_ID_SANYO_3_8   (0x00 << 8)
 462#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
 463#define SYS_CLCD_ID_EPSON_2_2   (0x02 << 8)
 464#define SYS_CLCD_ID_SANYO_2_5   (0x07 << 8)
 465#define SYS_CLCD_ID_VGA         (0x1f << 8)
 466
 467static struct clcd_panel vga = {
 468        .mode           = {
 469                .name           = "VGA",
 470                .refresh        = 60,
 471                .xres           = 640,
 472                .yres           = 480,
 473                .pixclock       = 39721,
 474                .left_margin    = 40,
 475                .right_margin   = 24,
 476                .upper_margin   = 32,
 477                .lower_margin   = 11,
 478                .hsync_len      = 96,
 479                .vsync_len      = 2,
 480                .sync           = 0,
 481                .vmode          = FB_VMODE_NONINTERLACED,
 482        },
 483        .width          = -1,
 484        .height         = -1,
 485        .tim2           = TIM2_BCD | TIM2_IPC,
 486        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 487        .bpp            = 16,
 488};
 489
 490static struct clcd_panel sanyo_3_8_in = {
 491        .mode           = {
 492                .name           = "Sanyo QVGA",
 493                .refresh        = 116,
 494                .xres           = 320,
 495                .yres           = 240,
 496                .pixclock       = 100000,
 497                .left_margin    = 6,
 498                .right_margin   = 6,
 499                .upper_margin   = 5,
 500                .lower_margin   = 5,
 501                .hsync_len      = 6,
 502                .vsync_len      = 6,
 503                .sync           = 0,
 504                .vmode          = FB_VMODE_NONINTERLACED,
 505        },
 506        .width          = -1,
 507        .height         = -1,
 508        .tim2           = TIM2_BCD,
 509        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 510        .bpp            = 16,
 511};
 512
 513static struct clcd_panel sanyo_2_5_in = {
 514        .mode           = {
 515                .name           = "Sanyo QVGA Portrait",
 516                .refresh        = 116,
 517                .xres           = 240,
 518                .yres           = 320,
 519                .pixclock       = 100000,
 520                .left_margin    = 20,
 521                .right_margin   = 10,
 522                .upper_margin   = 2,
 523                .lower_margin   = 2,
 524                .hsync_len      = 10,
 525                .vsync_len      = 2,
 526                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 527                .vmode          = FB_VMODE_NONINTERLACED,
 528        },
 529        .width          = -1,
 530        .height         = -1,
 531        .tim2           = TIM2_IVS | TIM2_IHS | TIM2_IPC,
 532        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 533        .bpp            = 16,
 534};
 535
 536static struct clcd_panel epson_2_2_in = {
 537        .mode           = {
 538                .name           = "Epson QCIF",
 539                .refresh        = 390,
 540                .xres           = 176,
 541                .yres           = 220,
 542                .pixclock       = 62500,
 543                .left_margin    = 3,
 544                .right_margin   = 2,
 545                .upper_margin   = 1,
 546                .lower_margin   = 0,
 547                .hsync_len      = 3,
 548                .vsync_len      = 2,
 549                .sync           = 0,
 550                .vmode          = FB_VMODE_NONINTERLACED,
 551        },
 552        .width          = -1,
 553        .height         = -1,
 554        .tim2           = TIM2_BCD | TIM2_IPC,
 555        .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
 556        .bpp            = 16,
 557};
 558
 559/*
 560 * Detect which LCD panel is connected, and return the appropriate
 561 * clcd_panel structure.  Note: we do not have any information on
 562 * the required timings for the 8.4in panel, so we presently assume
 563 * VGA timings.
 564 */
 565static struct clcd_panel *versatile_clcd_panel(void)
 566{
 567        void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 568        struct clcd_panel *panel = &vga;
 569        u32 val;
 570
 571        val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
 572        if (val == SYS_CLCD_ID_SANYO_3_8)
 573                panel = &sanyo_3_8_in;
 574        else if (val == SYS_CLCD_ID_SANYO_2_5)
 575                panel = &sanyo_2_5_in;
 576        else if (val == SYS_CLCD_ID_EPSON_2_2)
 577                panel = &epson_2_2_in;
 578        else if (val == SYS_CLCD_ID_VGA)
 579                panel = &vga;
 580        else {
 581                printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
 582                        val);
 583                panel = &vga;
 584        }
 585
 586        return panel;
 587}
 588
 589/*
 590 * Disable all display connectors on the interface module.
 591 */
 592static void versatile_clcd_disable(struct clcd_fb *fb)
 593{
 594        void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 595        u32 val;
 596
 597        val = readl(sys_clcd);
 598        val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
 599        writel(val, sys_clcd);
 600
 601#ifdef CONFIG_MACH_VERSATILE_AB
 602        /*
 603         * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
 604         */
 605        if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) {
 606                void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 607                unsigned long ctrl;
 608
 609                ctrl = readl(versatile_ib2_ctrl);
 610                ctrl &= ~0x01;
 611                writel(ctrl, versatile_ib2_ctrl);
 612        }
 613#endif
 614}
 615
 616/*
 617 * Enable the relevant connector on the interface module.
 618 */
 619static void versatile_clcd_enable(struct clcd_fb *fb)
 620{
 621        void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 622        u32 val;
 623
 624        val = readl(sys_clcd);
 625        val &= ~SYS_CLCD_MODE_MASK;
 626
 627        switch (fb->fb.var.green.length) {
 628        case 5:
 629                val |= SYS_CLCD_MODE_5551;
 630                break;
 631        case 6:
 632                val |= SYS_CLCD_MODE_565_RLSB;
 633                break;
 634        case 8:
 635                val |= SYS_CLCD_MODE_888;
 636                break;
 637        }
 638
 639        /*
 640         * Set the MUX
 641         */
 642        writel(val, sys_clcd);
 643
 644        /*
 645         * And now enable the PSUs
 646         */
 647        val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
 648        writel(val, sys_clcd);
 649
 650#ifdef CONFIG_MACH_VERSATILE_AB
 651        /*
 652         * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
 653         */
 654        if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) {
 655                void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 656                unsigned long ctrl;
 657
 658                ctrl = readl(versatile_ib2_ctrl);
 659                ctrl |= 0x01;
 660                writel(ctrl, versatile_ib2_ctrl);
 661        }
 662#endif
 663}
 664
 665static unsigned long framesize = SZ_1M;
 666
 667static int versatile_clcd_setup(struct clcd_fb *fb)
 668{
 669        dma_addr_t dma;
 670
 671        fb->panel               = versatile_clcd_panel();
 672
 673        fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
 674                                                    &dma, GFP_KERNEL);
 675        if (!fb->fb.screen_base) {
 676                printk(KERN_ERR "CLCD: unable to map framebuffer\n");
 677                return -ENOMEM;
 678        }
 679
 680        fb->fb.fix.smem_start   = dma;
 681        fb->fb.fix.smem_len     = framesize;
 682
 683        return 0;
 684}
 685
 686static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 687{
 688        return dma_mmap_writecombine(&fb->dev->dev, vma,
 689                                     fb->fb.screen_base,
 690                                     fb->fb.fix.smem_start,
 691                                     fb->fb.fix.smem_len);
 692}
 693
 694static void versatile_clcd_remove(struct clcd_fb *fb)
 695{
 696        dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
 697                              fb->fb.screen_base, fb->fb.fix.smem_start);
 698}
 699
 700static struct clcd_board clcd_plat_data = {
 701        .name           = "Versatile",
 702        .check          = clcdfb_check,
 703        .decode         = clcdfb_decode,
 704        .disable        = versatile_clcd_disable,
 705        .enable         = versatile_clcd_enable,
 706        .setup          = versatile_clcd_setup,
 707        .mmap           = versatile_clcd_mmap,
 708        .remove         = versatile_clcd_remove,
 709};
 710
 711static struct pl061_platform_data gpio0_plat_data = {
 712        .gpio_base      = 0,
 713        .irq_base       = IRQ_GPIO0_START,
 714};
 715
 716static struct pl061_platform_data gpio1_plat_data = {
 717        .gpio_base      = 8,
 718        .irq_base       = IRQ_GPIO1_START,
 719};
 720
 721#define AACI_IRQ        { IRQ_AACI, NO_IRQ }
 722#define AACI_DMA        { 0x80, 0x81 }
 723#define MMCI0_IRQ       { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
 724#define MMCI0_DMA       { 0x84, 0 }
 725#define KMI0_IRQ        { IRQ_SIC_KMI0, NO_IRQ }
 726#define KMI0_DMA        { 0, 0 }
 727#define KMI1_IRQ        { IRQ_SIC_KMI1, NO_IRQ }
 728#define KMI1_DMA        { 0, 0 }
 729
 730/*
 731 * These devices are connected directly to the multi-layer AHB switch
 732 */
 733#define SMC_IRQ         { NO_IRQ, NO_IRQ }
 734#define SMC_DMA         { 0, 0 }
 735#define MPMC_IRQ        { NO_IRQ, NO_IRQ }
 736#define MPMC_DMA        { 0, 0 }
 737#define CLCD_IRQ        { IRQ_CLCDINT, NO_IRQ }
 738#define CLCD_DMA        { 0, 0 }
 739#define DMAC_IRQ        { IRQ_DMAINT, NO_IRQ }
 740#define DMAC_DMA        { 0, 0 }
 741
 742/*
 743 * These devices are connected via the core APB bridge
 744 */
 745#define SCTL_IRQ        { NO_IRQ, NO_IRQ }
 746#define SCTL_DMA        { 0, 0 }
 747#define WATCHDOG_IRQ    { IRQ_WDOGINT, NO_IRQ }
 748#define WATCHDOG_DMA    { 0, 0 }
 749#define GPIO0_IRQ       { IRQ_GPIOINT0, NO_IRQ }
 750#define GPIO0_DMA       { 0, 0 }
 751#define GPIO1_IRQ       { IRQ_GPIOINT1, NO_IRQ }
 752#define GPIO1_DMA       { 0, 0 }
 753#define RTC_IRQ         { IRQ_RTCINT, NO_IRQ }
 754#define RTC_DMA         { 0, 0 }
 755
 756/*
 757 * These devices are connected via the DMA APB bridge
 758 */
 759#define SCI_IRQ         { IRQ_SCIINT, NO_IRQ }
 760#define SCI_DMA         { 7, 6 }
 761#define UART0_IRQ       { IRQ_UARTINT0, NO_IRQ }
 762#define UART0_DMA       { 15, 14 }
 763#define UART1_IRQ       { IRQ_UARTINT1, NO_IRQ }
 764#define UART1_DMA       { 13, 12 }
 765#define UART2_IRQ       { IRQ_UARTINT2, NO_IRQ }
 766#define UART2_DMA       { 11, 10 }
 767#define SSP_IRQ         { IRQ_SSPINT, NO_IRQ }
 768#define SSP_DMA         { 9, 8 }
 769
 770/* FPGA Primecells */
 771AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
 772AMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);
 773AMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
 774AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
 775
 776/* DevChip Primecells */
 777AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL);
 778AMBA_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);
 779AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
 780AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
 781AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
 782AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
 783AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data);
 784AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
 785AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
 786AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
 787AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
 788AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
 789AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
 790AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);
 791
 792static struct amba_device *amba_devs[] __initdata = {
 793        &dmac_device,
 794        &uart0_device,
 795        &uart1_device,
 796        &uart2_device,
 797        &smc_device,
 798        &mpmc_device,
 799        &clcd_device,
 800        &sctl_device,
 801        &wdog_device,
 802        &gpio0_device,
 803        &gpio1_device,
 804        &rtc_device,
 805        &sci0_device,
 806        &ssp0_device,
 807        &aaci_device,
 808        &mmc0_device,
 809        &kmi0_device,
 810        &kmi1_device,
 811};
 812
 813#ifdef CONFIG_LEDS
 814#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
 815
 816static void versatile_leds_event(led_event_t ledevt)
 817{
 818        unsigned long flags;
 819        u32 val;
 820
 821        local_irq_save(flags);
 822        val = readl(VA_LEDS_BASE);
 823
 824        switch (ledevt) {
 825        case led_idle_start:
 826                val = val & ~VERSATILE_SYS_LED0;
 827                break;
 828
 829        case led_idle_end:
 830                val = val | VERSATILE_SYS_LED0;
 831                break;
 832
 833        case led_timer:
 834                val = val ^ VERSATILE_SYS_LED1;
 835                break;
 836
 837        case led_halted:
 838                val = 0;
 839                break;
 840
 841        default:
 842                break;
 843        }
 844
 845        writel(val, VA_LEDS_BASE);
 846        local_irq_restore(flags);
 847}
 848#endif  /* CONFIG_LEDS */
 849
 850void __init versatile_init(void)
 851{
 852        int i;
 853
 854        for (i = 0; i < ARRAY_SIZE(lookups); i++)
 855                clkdev_add(&lookups[i]);
 856
 857        platform_device_register(&versatile_flash_device);
 858        platform_device_register(&versatile_i2c_device);
 859        platform_device_register(&smc91x_device);
 860
 861        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 862                struct amba_device *d = amba_devs[i];
 863                amba_device_register(d, &iomem_resource);
 864        }
 865
 866#ifdef CONFIG_LEDS
 867        leds_event = versatile_leds_event;
 868#endif
 869}
 870
 871/*
 872 * Where is the timer (VA)?
 873 */
 874#define TIMER0_VA_BASE           __io_address(VERSATILE_TIMER0_1_BASE)
 875#define TIMER1_VA_BASE          (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
 876#define TIMER2_VA_BASE           __io_address(VERSATILE_TIMER2_3_BASE)
 877#define TIMER3_VA_BASE          (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
 878#define VA_IC_BASE               __io_address(VERSATILE_VIC_BASE) 
 879
 880/*
 881 * How long is the timer interval?
 882 */
 883#define TIMER_INTERVAL  (TICKS_PER_uSEC * mSEC_10)
 884#if TIMER_INTERVAL >= 0x100000
 885#define TIMER_RELOAD    (TIMER_INTERVAL >> 8)
 886#define TIMER_DIVISOR   (TIMER_CTRL_DIV256)
 887#define TICKS2USECS(x)  (256 * (x) / TICKS_PER_uSEC)
 888#elif TIMER_INTERVAL >= 0x10000
 889#define TIMER_RELOAD    (TIMER_INTERVAL >> 4)           /* Divide by 16 */
 890#define TIMER_DIVISOR   (TIMER_CTRL_DIV16)
 891#define TICKS2USECS(x)  (16 * (x) / TICKS_PER_uSEC)
 892#else
 893#define TIMER_RELOAD    (TIMER_INTERVAL)
 894#define TIMER_DIVISOR   (TIMER_CTRL_DIV1)
 895#define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
 896#endif
 897
 898static void timer_set_mode(enum clock_event_mode mode,
 899                           struct clock_event_device *clk)
 900{
 901        unsigned long ctrl;
 902
 903        switch(mode) {
 904        case CLOCK_EVT_MODE_PERIODIC:
 905                writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
 906
 907                ctrl = TIMER_CTRL_PERIODIC;
 908                ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
 909                break;
 910        case CLOCK_EVT_MODE_ONESHOT:
 911                /* period set, and timer enabled in 'next_event' hook */
 912                ctrl = TIMER_CTRL_ONESHOT;
 913                ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
 914                break;
 915        case CLOCK_EVT_MODE_UNUSED:
 916        case CLOCK_EVT_MODE_SHUTDOWN:
 917        default:
 918                ctrl = 0;
 919        }
 920
 921        writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
 922}
 923
 924static int timer_set_next_event(unsigned long evt,
 925                                struct clock_event_device *unused)
 926{
 927        unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
 928
 929        writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
 930        writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
 931
 932        return 0;
 933}
 934
 935static struct clock_event_device timer0_clockevent =     {
 936        .name           = "timer0",
 937        .shift          = 32,
 938        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 939        .set_mode       = timer_set_mode,
 940        .set_next_event = timer_set_next_event,
 941};
 942
 943/*
 944 * IRQ handler for the timer
 945 */
 946static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
 947{
 948        struct clock_event_device *evt = &timer0_clockevent;
 949
 950        writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 951
 952        evt->event_handler(evt);
 953
 954        return IRQ_HANDLED;
 955}
 956
 957static struct irqaction versatile_timer_irq = {
 958        .name           = "Versatile Timer Tick",
 959        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
 960        .handler        = versatile_timer_interrupt,
 961};
 962
 963static cycle_t versatile_get_cycles(struct clocksource *cs)
 964{
 965        return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
 966}
 967
 968static struct clocksource clocksource_versatile = {
 969        .name           = "timer3",
 970        .rating         = 200,
 971        .read           = versatile_get_cycles,
 972        .mask           = CLOCKSOURCE_MASK(32),
 973        .shift          = 20,
 974        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 975};
 976
 977static int __init versatile_clocksource_init(void)
 978{
 979        /* setup timer3 as free-running clocksource */
 980        writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 981        writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
 982        writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
 983        writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
 984               TIMER3_VA_BASE + TIMER_CTRL);
 985
 986        clocksource_versatile.mult =
 987                clocksource_khz2mult(1000, clocksource_versatile.shift);
 988        clocksource_register(&clocksource_versatile);
 989
 990        return 0;
 991}
 992
 993/*
 994 * Set up timer interrupt, and return the current time in seconds.
 995 */
 996static void __init versatile_timer_init(void)
 997{
 998        u32 val;
 999
1000        /* 
1001         * set clock frequency: 
1002         *      VERSATILE_REFCLK is 32KHz
1003         *      VERSATILE_TIMCLK is 1MHz
1004         */
1005        val = readl(__io_address(VERSATILE_SCTL_BASE));
1006        writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
1007               (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
1008               (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
1009               (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
1010               __io_address(VERSATILE_SCTL_BASE));
1011
1012        /*
1013         * Initialise to a known state (all timers off)
1014         */
1015        writel(0, TIMER0_VA_BASE + TIMER_CTRL);
1016        writel(0, TIMER1_VA_BASE + TIMER_CTRL);
1017        writel(0, TIMER2_VA_BASE + TIMER_CTRL);
1018        writel(0, TIMER3_VA_BASE + TIMER_CTRL);
1019
1020        /* 
1021         * Make irqs happen for the system timer
1022         */
1023        setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
1024
1025        versatile_clocksource_init();
1026
1027        timer0_clockevent.mult =
1028                div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
1029        timer0_clockevent.max_delta_ns =
1030                clockevent_delta2ns(0xffffffff, &timer0_clockevent);
1031        timer0_clockevent.min_delta_ns =
1032                clockevent_delta2ns(0xf, &timer0_clockevent);
1033
1034        timer0_clockevent.cpumask = cpumask_of(0);
1035        clockevents_register_device(&timer0_clockevent);
1036}
1037
1038struct sys_timer versatile_timer = {
1039        .init           = versatile_timer_init,
1040};
1041
1042