1/* 2 * linux/arch/arm/mach-realview/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/platform_device.h> 23#include <linux/dma-mapping.h> 24#include <linux/sysdev.h> 25#include <linux/interrupt.h> 26#include <linux/amba/bus.h> 27#include <linux/amba/clcd.h> 28 29#include <asm/system.h> 30#include <asm/hardware.h> 31#include <asm/io.h> 32#include <asm/irq.h> 33#include <asm/leds.h> 34#include <asm/hardware/arm_timer.h> 35#include <asm/hardware/icst307.h> 36 37#include <asm/mach/arch.h> 38#include <asm/mach/flash.h> 39#include <asm/mach/irq.h> 40#include <asm/mach/time.h> 41#include <asm/mach/map.h> 42#include <asm/mach/mmc.h> 43 44#include <asm/hardware/gic.h> 45 46#include "core.h" 47#include "clock.h" 48 49#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) 50 51/* 52 * This is the RealView sched_clock implementation. This has 53 * a resolution of 41.7ns, and a maximum value of about 179s. 54 */ 55unsigned long long sched_clock(void) 56{ 57 unsigned long long v; 58 59 v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125; 60 do_div(v, 3); 61 62 return v; 63} 64 65 66#define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET) 67 68static int realview_flash_init(void) 69{ 70 u32 val; 71 72 val = __raw_readl(REALVIEW_FLASHCTRL); 73 val &= ~REALVIEW_FLASHPROG_FLVPPEN; 74 __raw_writel(val, REALVIEW_FLASHCTRL); 75 76 return 0; 77} 78 79static void realview_flash_exit(void) 80{ 81 u32 val; 82 83 val = __raw_readl(REALVIEW_FLASHCTRL); 84 val &= ~REALVIEW_FLASHPROG_FLVPPEN; 85 __raw_writel(val, REALVIEW_FLASHCTRL); 86} 87 88static void realview_flash_set_vpp(int on) 89{ 90 u32 val; 91 92 val = __raw_readl(REALVIEW_FLASHCTRL); 93 if (on) 94 val |= REALVIEW_FLASHPROG_FLVPPEN; 95 else 96 val &= ~REALVIEW_FLASHPROG_FLVPPEN; 97 __raw_writel(val, REALVIEW_FLASHCTRL); 98} 99 100static struct flash_platform_data realview_flash_data = { 101 .map_name = "cfi_probe", 102 .width = 4, 103 .init = realview_flash_init, 104 .exit = realview_flash_exit, 105 .set_vpp = realview_flash_set_vpp, 106}; 107 108static struct resource realview_flash_resource = { 109 .start = REALVIEW_FLASH_BASE, 110 .end = REALVIEW_FLASH_BASE + REALVIEW_FLASH_SIZE, 111 .flags = IORESOURCE_MEM, 112}; 113 114struct platform_device realview_flash_device = { 115 .name = "armflash", 116 .id = 0, 117 .dev = { 118 .platform_data = &realview_flash_data, 119 }, 120 .num_resources = 1, 121 .resource = &realview_flash_resource, 122}; 123 124static struct resource realview_smc91x_resources[] = { 125 [0] = { 126 .start = REALVIEW_ETH_BASE, 127 .end = REALVIEW_ETH_BASE + SZ_64K - 1, 128 .flags = IORESOURCE_MEM, 129 }, 130 [1] = { 131 .start = IRQ_ETH, 132 .end = IRQ_ETH, 133 .flags = IORESOURCE_IRQ, 134 }, 135}; 136 137struct platform_device realview_smc91x_device = { 138 .name = "smc91x", 139 .id = 0, 140 .num_resources = ARRAY_SIZE(realview_smc91x_resources), 141 .resource = realview_smc91x_resources, 142}; 143 144static struct resource realview_i2c_resource = { 145 .start = REALVIEW_I2C_BASE, 146 .end = REALVIEW_I2C_BASE + SZ_4K - 1, 147 .flags = IORESOURCE_MEM, 148}; 149 150struct platform_device realview_i2c_device = { 151 .name = "versatile-i2c", 152 .id = -1, 153 .num_resources = 1, 154 .resource = &realview_i2c_resource, 155}; 156 157#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET) 158 159static unsigned int realview_mmc_status(struct device *dev) 160{ 161 struct amba_device *adev = container_of(dev, struct amba_device, dev); 162 u32 mask; 163 164 if (adev->res.start == REALVIEW_MMCI0_BASE) 165 mask = 1; 166 else 167 mask = 2; 168 169 return readl(REALVIEW_SYSMCI) & mask; 170} 171 172struct mmc_platform_data realview_mmc0_plat_data = { 173 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 174 .status = realview_mmc_status, 175}; 176 177struct mmc_platform_data realview_mmc1_plat_data = { 178 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 179 .status = realview_mmc_status, 180}; 181 182/* 183 * Clock handling 184 */ 185static const struct icst307_params realview_oscvco_params = { 186 .ref = 24000, 187 .vco_max = 200000, 188 .vd_min = 4 + 8, 189 .vd_max = 511 + 8, 190 .rd_min = 1 + 2, 191 .rd_max = 127 + 2, 192}; 193 194static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco) 195{ 196 void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; 197 void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; 198 u32 val; 199 200 val = readl(sys_osc) & ~0x7ffff; 201 val |= vco.v | (vco.r << 9) | (vco.s << 16); 202 203 writel(0xa05f, sys_lock); 204 writel(val, sys_osc); 205 writel(0, sys_lock); 206} 207 208struct clk realview_clcd_clk = { 209 .name = "CLCDCLK", 210 .params = &realview_oscvco_params, 211 .setvco = realview_oscvco_set, 212}; 213 214/* 215 * CLCD support. 216 */ 217#define SYS_CLCD_NLCDIOON (1 << 2) 218#define SYS_CLCD_VDDPOSSWITCH (1 << 3) 219#define SYS_CLCD_PWR3V5SWITCH (1 << 4) 220#define SYS_CLCD_ID_MASK (0x1f << 8) 221#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8) 222#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8) 223#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8) 224#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) 225#define SYS_CLCD_ID_VGA (0x1f << 8) 226 227static struct clcd_panel vga = { 228 .mode = { 229 .name = "VGA", 230 .refresh = 60, 231 .xres = 640, 232 .yres = 480, 233 .pixclock = 39721, 234 .left_margin = 40, 235 .right_margin = 24, 236 .upper_margin = 32, 237 .lower_margin = 11, 238 .hsync_len = 96, 239 .vsync_len = 2, 240 .sync = 0, 241 .vmode = FB_VMODE_NONINTERLACED, 242 }, 243 .width = -1, 244 .height = -1, 245 .tim2 = TIM2_BCD | TIM2_IPC, 246 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 247 .bpp = 16, 248}; 249 250static struct clcd_panel sanyo_3_8_in = { 251 .mode = { 252 .name = "Sanyo QVGA", 253 .refresh = 116, 254 .xres = 320, 255 .yres = 240, 256 .pixclock = 100000, 257 .left_margin = 6, 258 .right_margin = 6, 259 .upper_margin = 5, 260 .lower_margin = 5, 261 .hsync_len = 6, 262 .vsync_len = 6, 263 .sync = 0, 264 .vmode = FB_VMODE_NONINTERLACED, 265 }, 266 .width = -1, 267 .height = -1, 268 .tim2 = TIM2_BCD, 269 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 270 .bpp = 16, 271}; 272 273static struct clcd_panel sanyo_2_5_in = { 274 .mode = { 275 .name = "Sanyo QVGA Portrait", 276 .refresh = 116, 277 .xres = 240, 278 .yres = 320, 279 .pixclock = 100000, 280 .left_margin = 20, 281 .right_margin = 10, 282 .upper_margin = 2, 283 .lower_margin = 2, 284 .hsync_len = 10, 285 .vsync_len = 2, 286 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 287 .vmode = FB_VMODE_NONINTERLACED, 288 }, 289 .width = -1, 290 .height = -1, 291 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, 292 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 293 .bpp = 16, 294}; 295 296static struct clcd_panel epson_2_2_in = { 297 .mode = { 298 .name = "Epson QCIF", 299 .refresh = 390, 300 .xres = 176, 301 .yres = 220, 302 .pixclock = 62500, 303 .left_margin = 3, 304 .right_margin = 2, 305 .upper_margin = 1, 306 .lower_margin = 0, 307 .hsync_len = 3, 308 .vsync_len = 2, 309 .sync = 0, 310 .vmode = FB_VMODE_NONINTERLACED, 311 }, 312 .width = -1, 313 .height = -1, 314 .tim2 = TIM2_BCD | TIM2_IPC, 315 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), 316 .bpp = 16, 317}; 318 319/* 320 * Detect which LCD panel is connected, and return the appropriate 321 * clcd_panel structure. Note: we do not have any information on 322 * the required timings for the 8.4in panel, so we presently assume 323 * VGA timings. 324 */ 325static struct clcd_panel *realview_clcd_panel(void) 326{ 327 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET; 328 struct clcd_panel *panel = &vga; 329 u32 val; 330 331 val = readl(sys_clcd) & SYS_CLCD_ID_MASK; 332 if (val == SYS_CLCD_ID_SANYO_3_8) 333 panel = &sanyo_3_8_in; 334 else if (val == SYS_CLCD_ID_SANYO_2_5) 335 panel = &sanyo_2_5_in; 336 else if (val == SYS_CLCD_ID_EPSON_2_2) 337 panel = &epson_2_2_in; 338 else if (val == SYS_CLCD_ID_VGA) 339 panel = &vga; 340 else { 341 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", 342 val); 343 panel = &vga; 344 } 345 346 return panel; 347} 348 349/* 350 * Disable all display connectors on the interface module. 351 */ 352static void realview_clcd_disable(struct clcd_fb *fb) 353{ 354 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET; 355 u32 val; 356 357 val = readl(sys_clcd); 358 val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; 359 writel(val, sys_clcd); 360} 361 362/* 363 * Enable the relevant connector on the interface module. 364 */ 365static void realview_clcd_enable(struct clcd_fb *fb) 366{ 367 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET; 368 u32 val; 369 370 /* 371 * Enable the PSUs 372 */ 373 val = readl(sys_clcd); 374 val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; 375 writel(val, sys_clcd); 376} 377 378static unsigned long framesize = SZ_1M; 379 380static int realview_clcd_setup(struct clcd_fb *fb) 381{ 382 dma_addr_t dma; 383 384 fb->panel = realview_clcd_panel(); 385 386 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, 387 &dma, GFP_KERNEL); 388 if (!fb->fb.screen_base) { 389 printk(KERN_ERR "CLCD: unable to map framebuffer\n"); 390 return -ENOMEM; 391 } 392 393 fb->fb.fix.smem_start = dma; 394 fb->fb.fix.smem_len = framesize; 395 396 return 0; 397} 398 399static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 400{ 401 return dma_mmap_writecombine(&fb->dev->dev, vma, 402 fb->fb.screen_base, 403 fb->fb.fix.smem_start, 404 fb->fb.fix.smem_len); 405} 406 407static void realview_clcd_remove(struct clcd_fb *fb) 408{ 409 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, 410 fb->fb.screen_base, fb->fb.fix.smem_start); 411} 412 413struct clcd_board clcd_plat_data = { 414 .name = "RealView", 415 .check = clcdfb_check, 416 .decode = clcdfb_decode, 417 .disable = realview_clcd_disable, 418 .enable = realview_clcd_enable, 419 .setup = realview_clcd_setup, 420 .mmap = realview_clcd_mmap, 421 .remove = realview_clcd_remove, 422}; 423 424#ifdef CONFIG_LEDS 425#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET) 426 427void realview_leds_event(led_event_t ledevt) 428{ 429 unsigned long flags; 430 u32 val; 431 432 local_irq_save(flags); 433 val = readl(VA_LEDS_BASE); 434 435 switch (ledevt) { 436 case led_idle_start: 437 val = val & ~REALVIEW_SYS_LED0; 438 break; 439 440 case led_idle_end: 441 val = val | REALVIEW_SYS_LED0; 442 break; 443 444 case led_timer: 445 val = val ^ REALVIEW_SYS_LED1; 446 break; 447 448 case led_halted: 449 val = 0; 450 break; 451 452 default: 453 break; 454 } 455 456 writel(val, VA_LEDS_BASE); 457 local_irq_restore(flags); 458} 459#endif /* CONFIG_LEDS */ 460 461/* 462 * Where is the timer (VA)? 463 */ 464#define TIMER0_VA_BASE __io_address(REALVIEW_TIMER0_1_BASE) 465#define TIMER1_VA_BASE (__io_address(REALVIEW_TIMER0_1_BASE) + 0x20) 466#define TIMER2_VA_BASE __io_address(REALVIEW_TIMER2_3_BASE) 467#define TIMER3_VA_BASE (__io_address(REALVIEW_TIMER2_3_BASE) + 0x20) 468 469/* 470 * How long is the timer interval? 471 */ 472#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) 473#if TIMER_INTERVAL >= 0x100000 474#define TIMER_RELOAD (TIMER_INTERVAL >> 8) 475#define TIMER_DIVISOR (TIMER_CTRL_DIV256) 476#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) 477#elif TIMER_INTERVAL >= 0x10000 478#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ 479#define TIMER_DIVISOR (TIMER_CTRL_DIV16) 480#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) 481#else 482#define TIMER_RELOAD (TIMER_INTERVAL) 483#define TIMER_DIVISOR (TIMER_CTRL_DIV1) 484#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) 485#endif 486 487/* 488 * Returns number of ms since last clock interrupt. Note that interrupts 489 * will have been disabled by do_gettimeoffset() 490 */ 491static unsigned long realview_gettimeoffset(void) 492{ 493 unsigned long ticks1, ticks2, status; 494 495 /* 496 * Get the current number of ticks. Note that there is a race 497 * condition between us reading the timer and checking for 498 * an interrupt. We get around this by ensuring that the 499 * counter has not reloaded between our two reads. 500 */ 501 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; 502 do { 503 ticks1 = ticks2; 504 status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET) 505 + ((IRQ_TIMERINT0_1 >> 5) << 2)); 506 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; 507 } while (ticks2 > ticks1); 508 509 /* 510 * Number of ticks since last interrupt. 511 */ 512 ticks1 = TIMER_RELOAD - ticks2; 513 514 if (status & IRQMASK_TIMERINT0_1) 515 ticks1 += TIMER_RELOAD; 516 517 /* 518 * Convert the ticks to usecs 519 */ 520 return TICKS2USECS(ticks1); 521} 522 523/* 524 * IRQ handler for the timer 525 */ 526static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) 527{ 528 write_seqlock(&xtime_lock); 529 530 // ...clear the interrupt 531 writel(1, TIMER0_VA_BASE + TIMER_INTCLR); 532 533 timer_tick(); 534 535#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) 536 smp_send_timer(); 537 update_process_times(user_mode(get_irq_regs())); 538#endif 539 540 write_sequnlock(&xtime_lock); 541 542 return IRQ_HANDLED; 543} 544 545static struct irqaction realview_timer_irq = { 546 .name = "RealView Timer Tick", 547 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 548 .handler = realview_timer_interrupt, 549}; 550 551/* 552 * Set up timer interrupt, and return the current time in seconds. 553 */ 554static void __init realview_timer_init(void) 555{ 556 u32 val; 557 558 /* 559 * set clock frequency: 560 * REALVIEW_REFCLK is 32KHz 561 * REALVIEW_TIMCLK is 1MHz 562 */ 563 val = readl(__io_address(REALVIEW_SCTL_BASE)); 564 writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) | 565 (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | 566 (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) | 567 (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val, 568 __io_address(REALVIEW_SCTL_BASE)); 569 570 /* 571 * Initialise to a known state (all timers off) 572 */ 573 writel(0, TIMER0_VA_BASE + TIMER_CTRL); 574 writel(0, TIMER1_VA_BASE + TIMER_CTRL); 575 writel(0, TIMER2_VA_BASE + TIMER_CTRL); 576 writel(0, TIMER3_VA_BASE + TIMER_CTRL); 577 578 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); 579 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); 580 writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | 581 TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); 582 583 /* 584 * Make irqs happen for the system timer 585 */ 586 setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq); 587} 588 589struct sys_timer realview_timer = { 590 .init = realview_timer_init, 591 .offset = realview_gettimeoffset, 592}; 593