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