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/interrupt.h> 26#include <linux/irqdomain.h> 27#include <linux/of_address.h> 28#include <linux/of_platform.h> 29#include <linux/amba/bus.h> 30#include <linux/amba/clcd.h> 31#include <linux/platform_data/video-clcd-versatile.h> 32#include <linux/amba/pl061.h> 33#include <linux/amba/mmci.h> 34#include <linux/amba/pl022.h> 35#include <linux/io.h> 36#include <linux/irqchip/arm-vic.h> 37#include <linux/irqchip/versatile-fpga.h> 38#include <linux/gfp.h> 39#include <linux/clkdev.h> 40#include <linux/mtd/physmap.h> 41#include <linux/bitops.h> 42#include <linux/reboot.h> 43 44#include <asm/irq.h> 45#include <asm/hardware/arm_timer.h> 46#include <asm/hardware/icst.h> 47#include <asm/mach-types.h> 48 49#include <asm/mach/arch.h> 50#include <asm/mach/irq.h> 51#include <asm/mach/time.h> 52#include <asm/mach/map.h> 53#include <mach/hardware.h> 54#include <mach/platform.h> 55#include <asm/hardware/timer-sp.h> 56 57#include <plat/sched_clock.h> 58 59#include "core.h" 60 61/* 62 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx 63 * is the (PA >> 12). 64 * 65 * Setup a VA for the Versatile Vectored Interrupt Controller. 66 */ 67#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) 68#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) 69 70/* These PIC IRQs are valid in each configuration */ 71#define PIC_VALID_ALL BIT(SIC_INT_KMI0) | BIT(SIC_INT_KMI1) | \ 72 BIT(SIC_INT_SCI3) | BIT(SIC_INT_UART3) | \ 73 BIT(SIC_INT_CLCD) | BIT(SIC_INT_TOUCH) | \ 74 BIT(SIC_INT_KEYPAD) | BIT(SIC_INT_DoC) | \ 75 BIT(SIC_INT_USB) | BIT(SIC_INT_PCI0) | \ 76 BIT(SIC_INT_PCI1) | BIT(SIC_INT_PCI2) | \ 77 BIT(SIC_INT_PCI3) 78#if 1 79#define IRQ_MMCI0A IRQ_VICSOURCE22 80#define IRQ_AACI IRQ_VICSOURCE24 81#define IRQ_ETH IRQ_VICSOURCE25 82#define PIC_MASK 0xFFD00000 83#define PIC_VALID PIC_VALID_ALL 84#else 85#define IRQ_MMCI0A IRQ_SIC_MMCI0A 86#define IRQ_AACI IRQ_SIC_AACI 87#define IRQ_ETH IRQ_SIC_ETH 88#define PIC_MASK 0 89#define PIC_VALID PIC_VALID_ALL | BIT(SIC_INT_MMCI0A) | \ 90 BIT(SIC_INT_MMCI1A) | BIT(SIC_INT_AACI) | \ 91 BIT(SIC_INT_ETH) 92#endif 93 94/* Lookup table for finding a DT node that represents the vic instance */ 95static const struct of_device_id vic_of_match[] __initconst = { 96 { .compatible = "arm,versatile-vic", }, 97 {} 98}; 99 100static const struct of_device_id sic_of_match[] __initconst = { 101 { .compatible = "arm,versatile-sic", }, 102 {} 103}; 104 105void __init versatile_init_irq(void) 106{ 107 struct device_node *np; 108 109 np = of_find_matching_node_by_address(NULL, vic_of_match, 110 VERSATILE_VIC_BASE); 111 __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np); 112 113 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); 114 115 np = of_find_matching_node_by_address(NULL, sic_of_match, 116 VERSATILE_SIC_BASE); 117 118 fpga_irq_init(VA_SIC_BASE, "SIC", IRQ_SIC_START, 119 IRQ_VICSOURCE31, PIC_VALID, np); 120 121 /* 122 * Interrupts on secondary controller from 0 to 8 are routed to 123 * source 31 on PIC. 124 * Interrupts from 21 to 31 are routed directly to the VIC on 125 * the corresponding number on primary controller. This is controlled 126 * by setting PIC_ENABLEx. 127 */ 128 writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE); 129} 130 131static struct map_desc versatile_io_desc[] __initdata __maybe_unused = { 132 { 133 .virtual = IO_ADDRESS(VERSATILE_SYS_BASE), 134 .pfn = __phys_to_pfn(VERSATILE_SYS_BASE), 135 .length = SZ_4K, 136 .type = MT_DEVICE 137 }, { 138 .virtual = IO_ADDRESS(VERSATILE_SIC_BASE), 139 .pfn = __phys_to_pfn(VERSATILE_SIC_BASE), 140 .length = SZ_4K, 141 .type = MT_DEVICE 142 }, { 143 .virtual = IO_ADDRESS(VERSATILE_VIC_BASE), 144 .pfn = __phys_to_pfn(VERSATILE_VIC_BASE), 145 .length = SZ_4K, 146 .type = MT_DEVICE 147 }, { 148 .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE), 149 .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE), 150 .length = SZ_4K * 9, 151 .type = MT_DEVICE 152 }, 153#ifdef CONFIG_MACH_VERSATILE_AB 154 { 155 .virtual = IO_ADDRESS(VERSATILE_IB2_BASE), 156 .pfn = __phys_to_pfn(VERSATILE_IB2_BASE), 157 .length = SZ_64M, 158 .type = MT_DEVICE 159 }, 160#endif 161#ifdef CONFIG_DEBUG_LL 162 { 163 .virtual = IO_ADDRESS(VERSATILE_UART0_BASE), 164 .pfn = __phys_to_pfn(VERSATILE_UART0_BASE), 165 .length = SZ_4K, 166 .type = MT_DEVICE 167 }, 168#endif 169#ifdef CONFIG_PCI 170 { 171 .virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE), 172 .pfn = __phys_to_pfn(VERSATILE_PCI_CORE_BASE), 173 .length = SZ_4K, 174 .type = MT_DEVICE 175 }, { 176 .virtual = (unsigned long)VERSATILE_PCI_VIRT_BASE, 177 .pfn = __phys_to_pfn(VERSATILE_PCI_BASE), 178 .length = VERSATILE_PCI_BASE_SIZE, 179 .type = MT_DEVICE 180 }, { 181 .virtual = (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE, 182 .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), 183 .length = VERSATILE_PCI_CFG_BASE_SIZE, 184 .type = MT_DEVICE 185 }, 186#endif 187}; 188 189void __init versatile_map_io(void) 190{ 191 iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc)); 192} 193 194 195#define VERSATILE_FLASHCTRL (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET) 196 197static void versatile_flash_set_vpp(struct platform_device *pdev, int on) 198{ 199 u32 val; 200 201 val = __raw_readl(VERSATILE_FLASHCTRL); 202 if (on) 203 val |= VERSATILE_FLASHPROG_FLVPPEN; 204 else 205 val &= ~VERSATILE_FLASHPROG_FLVPPEN; 206 __raw_writel(val, VERSATILE_FLASHCTRL); 207} 208 209static struct physmap_flash_data versatile_flash_data = { 210 .width = 4, 211 .set_vpp = versatile_flash_set_vpp, 212}; 213 214static struct resource versatile_flash_resource = { 215 .start = VERSATILE_FLASH_BASE, 216 .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1, 217 .flags = IORESOURCE_MEM, 218}; 219 220static struct platform_device versatile_flash_device = { 221 .name = "physmap-flash", 222 .id = 0, 223 .dev = { 224 .platform_data = &versatile_flash_data, 225 }, 226 .num_resources = 1, 227 .resource = &versatile_flash_resource, 228}; 229 230static struct resource smc91x_resources[] = { 231 [0] = { 232 .start = VERSATILE_ETH_BASE, 233 .end = VERSATILE_ETH_BASE + SZ_64K - 1, 234 .flags = IORESOURCE_MEM, 235 }, 236 [1] = { 237 .start = IRQ_ETH, 238 .end = IRQ_ETH, 239 .flags = IORESOURCE_IRQ, 240 }, 241}; 242 243static struct platform_device smc91x_device = { 244 .name = "smc91x", 245 .id = 0, 246 .num_resources = ARRAY_SIZE(smc91x_resources), 247 .resource = smc91x_resources, 248}; 249 250static struct resource versatile_i2c_resource = { 251 .start = VERSATILE_I2C_BASE, 252 .end = VERSATILE_I2C_BASE + SZ_4K - 1, 253 .flags = IORESOURCE_MEM, 254}; 255 256static struct platform_device versatile_i2c_device = { 257 .name = "versatile-i2c", 258 .id = 0, 259 .num_resources = 1, 260 .resource = &versatile_i2c_resource, 261}; 262 263static struct i2c_board_info versatile_i2c_board_info[] = { 264 { 265 I2C_BOARD_INFO("ds1338", 0xd0 >> 1), 266 }, 267}; 268 269static int __init versatile_i2c_init(void) 270{ 271 return i2c_register_board_info(0, versatile_i2c_board_info, 272 ARRAY_SIZE(versatile_i2c_board_info)); 273} 274arch_initcall(versatile_i2c_init); 275 276#define VERSATILE_SYSMCI (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET) 277 278unsigned int mmc_status(struct device *dev) 279{ 280 struct amba_device *adev = container_of(dev, struct amba_device, dev); 281 u32 mask; 282 283 if (adev->res.start == VERSATILE_MMCI0_BASE) 284 mask = 1; 285 else 286 mask = 2; 287 288 return readl(VERSATILE_SYSMCI) & mask; 289} 290 291static struct mmci_platform_data mmc0_plat_data = { 292 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 293 .status = mmc_status, 294 .gpio_wp = -1, 295 .gpio_cd = -1, 296}; 297 298static struct resource char_lcd_resources[] = { 299 { 300 .start = VERSATILE_CHAR_LCD_BASE, 301 .end = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1), 302 .flags = IORESOURCE_MEM, 303 }, 304}; 305 306static struct platform_device char_lcd_device = { 307 .name = "arm-charlcd", 308 .id = -1, 309 .num_resources = ARRAY_SIZE(char_lcd_resources), 310 .resource = char_lcd_resources, 311}; 312 313static struct resource leds_resources[] = { 314 { 315 .start = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET, 316 .end = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4, 317 .flags = IORESOURCE_MEM, 318 }, 319}; 320 321static struct platform_device leds_device = { 322 .name = "versatile-leds", 323 .id = -1, 324 .num_resources = ARRAY_SIZE(leds_resources), 325 .resource = leds_resources, 326}; 327 328/* 329 * Clock handling 330 */ 331static const struct icst_params versatile_oscvco_params = { 332 .ref = 24000000, 333 .vco_max = ICST307_VCO_MAX, 334 .vco_min = ICST307_VCO_MIN, 335 .vd_min = 4 + 8, 336 .vd_max = 511 + 8, 337 .rd_min = 1 + 2, 338 .rd_max = 127 + 2, 339 .s2div = icst307_s2div, 340 .idx2s = icst307_idx2s, 341}; 342 343static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco) 344{ 345 void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET; 346 u32 val; 347 348 val = readl(clk->vcoreg) & ~0x7ffff; 349 val |= vco.v | (vco.r << 9) | (vco.s << 16); 350 351 writel(0xa05f, sys_lock); 352 writel(val, clk->vcoreg); 353 writel(0, sys_lock); 354} 355 356static const struct clk_ops osc4_clk_ops = { 357 .round = icst_clk_round, 358 .set = icst_clk_set, 359 .setvco = versatile_oscvco_set, 360}; 361 362static struct clk osc4_clk = { 363 .ops = &osc4_clk_ops, 364 .params = &versatile_oscvco_params, 365}; 366 367/* 368 * These are fixed clocks. 369 */ 370static struct clk ref24_clk = { 371 .rate = 24000000, 372}; 373 374static struct clk sp804_clk = { 375 .rate = 1000000, 376}; 377 378static struct clk dummy_apb_pclk; 379 380static struct clk_lookup lookups[] = { 381 { /* AMBA bus clock */ 382 .con_id = "apb_pclk", 383 .clk = &dummy_apb_pclk, 384 }, { /* UART0 */ 385 .dev_id = "dev:f1", 386 .clk = &ref24_clk, 387 }, { /* UART1 */ 388 .dev_id = "dev:f2", 389 .clk = &ref24_clk, 390 }, { /* UART2 */ 391 .dev_id = "dev:f3", 392 .clk = &ref24_clk, 393 }, { /* UART3 */ 394 .dev_id = "fpga:09", 395 .clk = &ref24_clk, 396 }, { /* KMI0 */ 397 .dev_id = "fpga:06", 398 .clk = &ref24_clk, 399 }, { /* KMI1 */ 400 .dev_id = "fpga:07", 401 .clk = &ref24_clk, 402 }, { /* MMC0 */ 403 .dev_id = "fpga:05", 404 .clk = &ref24_clk, 405 }, { /* MMC1 */ 406 .dev_id = "fpga:0b", 407 .clk = &ref24_clk, 408 }, { /* SSP */ 409 .dev_id = "dev:f4", 410 .clk = &ref24_clk, 411 }, { /* CLCD */ 412 .dev_id = "dev:20", 413 .clk = &osc4_clk, 414 }, { /* SP804 timers */ 415 .dev_id = "sp804", 416 .clk = &sp804_clk, 417 }, 418}; 419 420/* 421 * CLCD support. 422 */ 423#define SYS_CLCD_MODE_MASK (3 << 0) 424#define SYS_CLCD_MODE_888 (0 << 0) 425#define SYS_CLCD_MODE_5551 (1 << 0) 426#define SYS_CLCD_MODE_565_RLSB (2 << 0) 427#define SYS_CLCD_MODE_565_BLSB (3 << 0) 428#define SYS_CLCD_NLCDIOON (1 << 2) 429#define SYS_CLCD_VDDPOSSWITCH (1 << 3) 430#define SYS_CLCD_PWR3V5SWITCH (1 << 4) 431#define SYS_CLCD_ID_MASK (0x1f << 8) 432#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8) 433#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8) 434#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8) 435#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) 436#define SYS_CLCD_ID_VGA (0x1f << 8) 437 438static bool is_sanyo_2_5_lcd; 439 440/* 441 * Disable all display connectors on the interface module. 442 */ 443static void versatile_clcd_disable(struct clcd_fb *fb) 444{ 445 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; 446 u32 val; 447 448 val = readl(sys_clcd); 449 val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; 450 writel(val, sys_clcd); 451 452#ifdef CONFIG_MACH_VERSATILE_AB 453 /* 454 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off 455 */ 456 if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) { 457 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); 458 unsigned long ctrl; 459 460 ctrl = readl(versatile_ib2_ctrl); 461 ctrl &= ~0x01; 462 writel(ctrl, versatile_ib2_ctrl); 463 } 464#endif 465} 466 467/* 468 * Enable the relevant connector on the interface module. 469 */ 470static void versatile_clcd_enable(struct clcd_fb *fb) 471{ 472 struct fb_var_screeninfo *var = &fb->fb.var; 473 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; 474 u32 val; 475 476 val = readl(sys_clcd); 477 val &= ~SYS_CLCD_MODE_MASK; 478 479 switch (var->green.length) { 480 case 5: 481 val |= SYS_CLCD_MODE_5551; 482 break; 483 case 6: 484 if (var->red.offset == 0) 485 val |= SYS_CLCD_MODE_565_RLSB; 486 else 487 val |= SYS_CLCD_MODE_565_BLSB; 488 break; 489 case 8: 490 val |= SYS_CLCD_MODE_888; 491 break; 492 } 493 494 /* 495 * Set the MUX 496 */ 497 writel(val, sys_clcd); 498 499 /* 500 * And now enable the PSUs 501 */ 502 val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; 503 writel(val, sys_clcd); 504 505#ifdef CONFIG_MACH_VERSATILE_AB 506 /* 507 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on 508 */ 509 if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) { 510 void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); 511 unsigned long ctrl; 512 513 ctrl = readl(versatile_ib2_ctrl); 514 ctrl |= 0x01; 515 writel(ctrl, versatile_ib2_ctrl); 516 } 517#endif 518} 519 520/* 521 * Detect which LCD panel is connected, and return the appropriate 522 * clcd_panel structure. Note: we do not have any information on 523 * the required timings for the 8.4in panel, so we presently assume 524 * VGA timings. 525 */ 526static int versatile_clcd_setup(struct clcd_fb *fb) 527{ 528 void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; 529 const char *panel_name; 530 u32 val; 531 532 is_sanyo_2_5_lcd = false; 533 534 val = readl(sys_clcd) & SYS_CLCD_ID_MASK; 535 if (val == SYS_CLCD_ID_SANYO_3_8) 536 panel_name = "Sanyo TM38QV67A02A"; 537 else if (val == SYS_CLCD_ID_SANYO_2_5) { 538 panel_name = "Sanyo QVGA Portrait"; 539 is_sanyo_2_5_lcd = true; 540 } else if (val == SYS_CLCD_ID_EPSON_2_2) 541 panel_name = "Epson L2F50113T00"; 542 else if (val == SYS_CLCD_ID_VGA) 543 panel_name = "VGA"; 544 else { 545 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", 546 val); 547 panel_name = "VGA"; 548 } 549 550 fb->panel = versatile_clcd_get_panel(panel_name); 551 if (!fb->panel) 552 return -EINVAL; 553 554 return versatile_clcd_setup_dma(fb, SZ_1M); 555} 556 557static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs) 558{ 559 clcdfb_decode(fb, regs); 560 561 /* Always clear BGR for RGB565: we do the routing externally */ 562 if (fb->fb.var.green.length == 6) 563 regs->cntl &= ~CNTL_BGR; 564} 565 566static struct clcd_board clcd_plat_data = { 567 .name = "Versatile", 568 .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, 569 .check = clcdfb_check, 570 .decode = versatile_clcd_decode, 571 .disable = versatile_clcd_disable, 572 .enable = versatile_clcd_enable, 573 .setup = versatile_clcd_setup, 574 .mmap = versatile_clcd_mmap_dma, 575 .remove = versatile_clcd_remove_dma, 576}; 577 578static struct pl061_platform_data gpio0_plat_data = { 579 .gpio_base = 0, 580 .irq_base = IRQ_GPIO0_START, 581}; 582 583static struct pl061_platform_data gpio1_plat_data = { 584 .gpio_base = 8, 585 .irq_base = IRQ_GPIO1_START, 586}; 587 588static struct pl061_platform_data gpio2_plat_data = { 589 .gpio_base = 16, 590 .irq_base = IRQ_GPIO2_START, 591}; 592 593static struct pl061_platform_data gpio3_plat_data = { 594 .gpio_base = 24, 595 .irq_base = IRQ_GPIO3_START, 596}; 597 598static struct pl022_ssp_controller ssp0_plat_data = { 599 .bus_id = 0, 600 .enable_dma = 0, 601 .num_chipselect = 1, 602}; 603 604#define AACI_IRQ { IRQ_AACI } 605#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } 606#define KMI0_IRQ { IRQ_SIC_KMI0 } 607#define KMI1_IRQ { IRQ_SIC_KMI1 } 608 609/* 610 * These devices are connected directly to the multi-layer AHB switch 611 */ 612#define SMC_IRQ { } 613#define MPMC_IRQ { } 614#define CLCD_IRQ { IRQ_CLCDINT } 615#define DMAC_IRQ { IRQ_DMAINT } 616 617/* 618 * These devices are connected via the core APB bridge 619 */ 620#define SCTL_IRQ { } 621#define WATCHDOG_IRQ { IRQ_WDOGINT } 622#define GPIO0_IRQ { IRQ_GPIOINT0 } 623#define GPIO1_IRQ { IRQ_GPIOINT1 } 624#define GPIO2_IRQ { IRQ_GPIOINT2 } 625#define GPIO3_IRQ { IRQ_GPIOINT3 } 626#define RTC_IRQ { IRQ_RTCINT } 627 628/* 629 * These devices are connected via the DMA APB bridge 630 */ 631#define SCI_IRQ { IRQ_SCIINT } 632#define UART0_IRQ { IRQ_UARTINT0 } 633#define UART1_IRQ { IRQ_UARTINT1 } 634#define UART2_IRQ { IRQ_UARTINT2 } 635#define SSP_IRQ { IRQ_SSPINT } 636 637/* FPGA Primecells */ 638APB_DEVICE(aaci, "fpga:04", AACI, NULL); 639APB_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); 640APB_DEVICE(kmi0, "fpga:06", KMI0, NULL); 641APB_DEVICE(kmi1, "fpga:07", KMI1, NULL); 642 643/* DevChip Primecells */ 644AHB_DEVICE(smc, "dev:00", SMC, NULL); 645AHB_DEVICE(mpmc, "dev:10", MPMC, NULL); 646AHB_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); 647AHB_DEVICE(dmac, "dev:30", DMAC, NULL); 648APB_DEVICE(sctl, "dev:e0", SCTL, NULL); 649APB_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); 650APB_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); 651APB_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); 652APB_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); 653APB_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); 654APB_DEVICE(rtc, "dev:e8", RTC, NULL); 655APB_DEVICE(sci0, "dev:f0", SCI, NULL); 656APB_DEVICE(uart0, "dev:f1", UART0, NULL); 657APB_DEVICE(uart1, "dev:f2", UART1, NULL); 658APB_DEVICE(uart2, "dev:f3", UART2, NULL); 659APB_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data); 660 661static struct amba_device *amba_devs[] __initdata = { 662 &dmac_device, 663 &uart0_device, 664 &uart1_device, 665 &uart2_device, 666 &smc_device, 667 &mpmc_device, 668 &clcd_device, 669 &sctl_device, 670 &wdog_device, 671 &gpio0_device, 672 &gpio1_device, 673 &gpio2_device, 674 &gpio3_device, 675 &rtc_device, 676 &sci0_device, 677 &ssp0_device, 678 &aaci_device, 679 &mmc0_device, 680 &kmi0_device, 681 &kmi1_device, 682}; 683 684#ifdef CONFIG_OF 685/* 686 * Lookup table for attaching a specific name and platform_data pointer to 687 * devices as they get created by of_platform_populate(). Ideally this table 688 * would not exist, but the current clock implementation depends on some devices 689 * having a specific name. 690 */ 691struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = { 692 OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data), 693 OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL), 694 OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL), 695 OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL), 696 /* FIXME: this is buggy, the platform data is needed for this MMC instance too */ 697 OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL), 698 699 OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data), 700 OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL), 701 OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL), 702 OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL), 703 OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", &ssp0_plat_data), 704 705#if 0 706 /* 707 * These entries are unnecessary because no clocks referencing 708 * them. I've left them in for now as place holders in case 709 * any of them need to be added back, but they should be 710 * removed before actually committing this patch. --gcl 711 */ 712 OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL), 713 OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL), 714 OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL), 715 OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL), 716 OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL), 717 718 OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL), 719 OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL), 720 OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL), 721 OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL), 722 OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL), 723 OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL), 724 OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL), 725 OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL), 726#endif 727 {} 728}; 729#endif 730 731void versatile_restart(enum reboot_mode mode, const char *cmd) 732{ 733 void __iomem *sys = __io_address(VERSATILE_SYS_BASE); 734 u32 val; 735 736 val = __raw_readl(sys + VERSATILE_SYS_RESETCTL_OFFSET); 737 val |= 0x105; 738 739 __raw_writel(0xa05f, sys + VERSATILE_SYS_LOCK_OFFSET); 740 __raw_writel(val, sys + VERSATILE_SYS_RESETCTL_OFFSET); 741 __raw_writel(0, sys + VERSATILE_SYS_LOCK_OFFSET); 742} 743 744/* Early initializations */ 745void __init versatile_init_early(void) 746{ 747 u32 val; 748 void __iomem *sys = __io_address(VERSATILE_SYS_BASE); 749 750 osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET; 751 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 752 753 versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000); 754 755 /* 756 * set clock frequency: 757 * VERSATILE_REFCLK is 32KHz 758 * VERSATILE_TIMCLK is 1MHz 759 */ 760 val = readl(__io_address(VERSATILE_SCTL_BASE)); 761 writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | 762 (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 763 (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | 764 (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, 765 __io_address(VERSATILE_SCTL_BASE)); 766} 767 768void __init versatile_init(void) 769{ 770 int i; 771 772 platform_device_register(&versatile_flash_device); 773 platform_device_register(&versatile_i2c_device); 774 platform_device_register(&smc91x_device); 775 platform_device_register(&char_lcd_device); 776 platform_device_register(&leds_device); 777 778 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 779 struct amba_device *d = amba_devs[i]; 780 amba_device_register(d, &iomem_resource); 781 } 782} 783 784/* 785 * Where is the timer (VA)? 786 */ 787#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE) 788#define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20) 789#define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE) 790#define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20) 791 792/* 793 * Set up timer interrupt, and return the current time in seconds. 794 */ 795void __init versatile_timer_init(void) 796{ 797 798 /* 799 * Initialise to a known state (all timers off) 800 */ 801 writel(0, TIMER0_VA_BASE + TIMER_CTRL); 802 writel(0, TIMER1_VA_BASE + TIMER_CTRL); 803 writel(0, TIMER2_VA_BASE + TIMER_CTRL); 804 writel(0, TIMER3_VA_BASE + TIMER_CTRL); 805 806 sp804_clocksource_init(TIMER3_VA_BASE, "timer3"); 807 sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0"); 808} 809