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