1/* 2 * linux/arch/arm/mach-pxa/viper.c 3 * 4 * Support for the Arcom VIPER SBC. 5 * 6 * Author: Ian Campbell 7 * Created: Feb 03, 2003 8 * Copyright: Arcom Control Systems 9 * 10 * Maintained by Marc Zyngier <maz@misterjones.org> 11 * <marc.zyngier@altran.com> 12 * 13 * Based on lubbock.c: 14 * Author: Nicolas Pitre 15 * Created: Jun 15, 2001 16 * Copyright: MontaVista Software Inc. 17 * 18 * This program is free software; you can redistribute it and/or modify 19 * it under the terms of the GNU General Public License version 2 as 20 * published by the Free Software Foundation. 21 */ 22 23#include <linux/types.h> 24#include <linux/memory.h> 25#include <linux/cpu.h> 26#include <linux/cpufreq.h> 27#include <linux/delay.h> 28#include <linux/fs.h> 29#include <linux/init.h> 30#include <linux/slab.h> 31#include <linux/interrupt.h> 32#include <linux/major.h> 33#include <linux/module.h> 34#include <linux/pm.h> 35#include <linux/sched.h> 36#include <linux/gpio.h> 37#include <linux/jiffies.h> 38#include <linux/i2c-gpio.h> 39#include <linux/i2c/pxa-i2c.h> 40#include <linux/serial_8250.h> 41#include <linux/smc91x.h> 42#include <linux/pwm_backlight.h> 43#include <linux/usb/isp116x.h> 44#include <linux/mtd/mtd.h> 45#include <linux/mtd/partitions.h> 46#include <linux/mtd/physmap.h> 47#include <linux/syscore_ops.h> 48 49#include <mach/pxa25x.h> 50#include <mach/audio.h> 51#include <linux/platform_data/video-pxafb.h> 52#include <mach/regs-uart.h> 53#include <linux/platform_data/pcmcia-pxa2xx_viper.h> 54#include <mach/viper.h> 55 56#include <asm/setup.h> 57#include <asm/mach-types.h> 58#include <asm/irq.h> 59#include <asm/sizes.h> 60#include <asm/system_info.h> 61 62#include <asm/mach/arch.h> 63#include <asm/mach/map.h> 64#include <asm/mach/irq.h> 65 66#include "generic.h" 67#include "devices.h" 68 69static unsigned int icr; 70 71static void viper_icr_set_bit(unsigned int bit) 72{ 73 icr |= bit; 74 VIPER_ICR = icr; 75} 76 77static void viper_icr_clear_bit(unsigned int bit) 78{ 79 icr &= ~bit; 80 VIPER_ICR = icr; 81} 82 83/* This function is used from the pcmcia module to reset the CF */ 84static void viper_cf_reset(int state) 85{ 86 if (state) 87 viper_icr_set_bit(VIPER_ICR_CF_RST); 88 else 89 viper_icr_clear_bit(VIPER_ICR_CF_RST); 90} 91 92static struct arcom_pcmcia_pdata viper_pcmcia_info = { 93 .cd_gpio = VIPER_CF_CD_GPIO, 94 .rdy_gpio = VIPER_CF_RDY_GPIO, 95 .pwr_gpio = VIPER_CF_POWER_GPIO, 96 .reset = viper_cf_reset, 97}; 98 99static struct platform_device viper_pcmcia_device = { 100 .name = "viper-pcmcia", 101 .id = -1, 102 .dev = { 103 .platform_data = &viper_pcmcia_info, 104 }, 105}; 106 107/* 108 * The CPLD version register was not present on VIPER boards prior to 109 * v2i1. On v1 boards where the version register is not present we 110 * will just read back the previous value from the databus. 111 * 112 * Therefore we do two reads. The first time we write 0 to the 113 * (read-only) register before reading and the second time we write 114 * 0xff first. If the two reads do not match or they read back as 0xff 115 * or 0x00 then we have version 1 hardware. 116 */ 117static u8 viper_hw_version(void) 118{ 119 u8 v1, v2; 120 unsigned long flags; 121 122 local_irq_save(flags); 123 124 VIPER_VERSION = 0; 125 v1 = VIPER_VERSION; 126 VIPER_VERSION = 0xff; 127 v2 = VIPER_VERSION; 128 129 v1 = (v1 != v2 || v1 == 0xff) ? 0 : v1; 130 131 local_irq_restore(flags); 132 return v1; 133} 134 135/* CPU system core operations. */ 136static int viper_cpu_suspend(void) 137{ 138 viper_icr_set_bit(VIPER_ICR_R_DIS); 139 return 0; 140} 141 142static void viper_cpu_resume(void) 143{ 144 viper_icr_clear_bit(VIPER_ICR_R_DIS); 145} 146 147static struct syscore_ops viper_cpu_syscore_ops = { 148 .suspend = viper_cpu_suspend, 149 .resume = viper_cpu_resume, 150}; 151 152static unsigned int current_voltage_divisor; 153 154/* 155 * If force is not true then step from existing to new divisor. If 156 * force is true then jump straight to the new divisor. Stepping is 157 * used because if the jump in voltage is too large, the VCC can dip 158 * too low and the regulator cuts out. 159 * 160 * force can be used to initialize the divisor to a know state by 161 * setting the value for the current clock speed, since we are already 162 * running at that speed we know the voltage should be pretty close so 163 * the jump won't be too large 164 */ 165static void viper_set_core_cpu_voltage(unsigned long khz, int force) 166{ 167 int i = 0; 168 unsigned int divisor = 0; 169 const char *v; 170 171 if (khz < 200000) { 172 v = "1.0"; divisor = 0xfff; 173 } else if (khz < 300000) { 174 v = "1.1"; divisor = 0xde5; 175 } else { 176 v = "1.3"; divisor = 0x325; 177 } 178 179 pr_debug("viper: setting CPU core voltage to %sV at %d.%03dMHz\n", 180 v, (int)khz / 1000, (int)khz % 1000); 181 182#define STEP 0x100 183 do { 184 int step; 185 186 if (force) 187 step = divisor; 188 else if (current_voltage_divisor < divisor - STEP) 189 step = current_voltage_divisor + STEP; 190 else if (current_voltage_divisor > divisor + STEP) 191 step = current_voltage_divisor - STEP; 192 else 193 step = divisor; 194 force = 0; 195 196 gpio_set_value(VIPER_PSU_CLK_GPIO, 0); 197 gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0); 198 199 for (i = 1 << 11 ; i > 0 ; i >>= 1) { 200 udelay(1); 201 202 gpio_set_value(VIPER_PSU_DATA_GPIO, step & i); 203 udelay(1); 204 205 gpio_set_value(VIPER_PSU_CLK_GPIO, 1); 206 udelay(1); 207 208 gpio_set_value(VIPER_PSU_CLK_GPIO, 0); 209 } 210 udelay(1); 211 212 gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 1); 213 udelay(1); 214 215 gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0); 216 217 current_voltage_divisor = step; 218 } while (current_voltage_divisor != divisor); 219} 220 221/* Interrupt handling */ 222static unsigned long viper_irq_enabled_mask; 223static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 }; 224static const int viper_isa_irq_map[] = { 225 0, /* ISA irq #0, invalid */ 226 0, /* ISA irq #1, invalid */ 227 0, /* ISA irq #2, invalid */ 228 1 << 0, /* ISA irq #3 */ 229 1 << 1, /* ISA irq #4 */ 230 1 << 2, /* ISA irq #5 */ 231 1 << 3, /* ISA irq #6 */ 232 1 << 4, /* ISA irq #7 */ 233 0, /* ISA irq #8, invalid */ 234 1 << 8, /* ISA irq #9 */ 235 1 << 5, /* ISA irq #10 */ 236 1 << 6, /* ISA irq #11 */ 237 1 << 7, /* ISA irq #12 */ 238 0, /* ISA irq #13, invalid */ 239 1 << 9, /* ISA irq #14 */ 240 1 << 10, /* ISA irq #15 */ 241}; 242 243static inline int viper_irq_to_bitmask(unsigned int irq) 244{ 245 return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)]; 246} 247 248static inline int viper_bit_to_irq(int bit) 249{ 250 return viper_isa_irqs[bit] + PXA_ISA_IRQ(0); 251} 252 253static void viper_ack_irq(struct irq_data *d) 254{ 255 int viper_irq = viper_irq_to_bitmask(d->irq); 256 257 if (viper_irq & 0xff) 258 VIPER_LO_IRQ_STATUS = viper_irq; 259 else 260 VIPER_HI_IRQ_STATUS = (viper_irq >> 8); 261} 262 263static void viper_mask_irq(struct irq_data *d) 264{ 265 viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(d->irq)); 266} 267 268static void viper_unmask_irq(struct irq_data *d) 269{ 270 viper_irq_enabled_mask |= viper_irq_to_bitmask(d->irq); 271} 272 273static inline unsigned long viper_irq_pending(void) 274{ 275 return (VIPER_HI_IRQ_STATUS << 8 | VIPER_LO_IRQ_STATUS) & 276 viper_irq_enabled_mask; 277} 278 279static void viper_irq_handler(unsigned int irq, struct irq_desc *desc) 280{ 281 unsigned long pending; 282 283 pending = viper_irq_pending(); 284 do { 285 /* we're in a chained irq handler, 286 * so ack the interrupt by hand */ 287 desc->irq_data.chip->irq_ack(&desc->irq_data); 288 289 if (likely(pending)) { 290 irq = viper_bit_to_irq(__ffs(pending)); 291 generic_handle_irq(irq); 292 } 293 pending = viper_irq_pending(); 294 } while (pending); 295} 296 297static struct irq_chip viper_irq_chip = { 298 .name = "ISA", 299 .irq_ack = viper_ack_irq, 300 .irq_mask = viper_mask_irq, 301 .irq_unmask = viper_unmask_irq 302}; 303 304static void __init viper_init_irq(void) 305{ 306 int level; 307 int isa_irq; 308 309 pxa25x_init_irq(); 310 311 /* setup ISA IRQs */ 312 for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) { 313 isa_irq = viper_bit_to_irq(level); 314 irq_set_chip_and_handler(isa_irq, &viper_irq_chip, 315 handle_edge_irq); 316 set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); 317 } 318 319 irq_set_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO), 320 viper_irq_handler); 321 irq_set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH); 322} 323 324/* Flat Panel */ 325static struct pxafb_mode_info fb_mode_info[] = { 326 { 327 .pixclock = 157500, 328 329 .xres = 320, 330 .yres = 240, 331 332 .bpp = 16, 333 334 .hsync_len = 63, 335 .left_margin = 7, 336 .right_margin = 13, 337 338 .vsync_len = 20, 339 .upper_margin = 0, 340 .lower_margin = 0, 341 342 .sync = 0, 343 }, 344}; 345 346static struct pxafb_mach_info fb_info = { 347 .modes = fb_mode_info, 348 .num_modes = 1, 349 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, 350}; 351 352static int viper_backlight_init(struct device *dev) 353{ 354 int ret; 355 356 /* GPIO9 and 10 control FB backlight. Initialise to off */ 357 ret = gpio_request(VIPER_BCKLIGHT_EN_GPIO, "Backlight"); 358 if (ret) 359 goto err_request_bckl; 360 361 ret = gpio_request(VIPER_LCD_EN_GPIO, "LCD"); 362 if (ret) 363 goto err_request_lcd; 364 365 ret = gpio_direction_output(VIPER_BCKLIGHT_EN_GPIO, 0); 366 if (ret) 367 goto err_dir; 368 369 ret = gpio_direction_output(VIPER_LCD_EN_GPIO, 0); 370 if (ret) 371 goto err_dir; 372 373 return 0; 374 375err_dir: 376 gpio_free(VIPER_LCD_EN_GPIO); 377err_request_lcd: 378 gpio_free(VIPER_BCKLIGHT_EN_GPIO); 379err_request_bckl: 380 dev_err(dev, "Failed to setup LCD GPIOs\n"); 381 382 return ret; 383} 384 385static int viper_backlight_notify(struct device *dev, int brightness) 386{ 387 gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness); 388 gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness); 389 390 return brightness; 391} 392 393static void viper_backlight_exit(struct device *dev) 394{ 395 gpio_free(VIPER_LCD_EN_GPIO); 396 gpio_free(VIPER_BCKLIGHT_EN_GPIO); 397} 398 399static struct platform_pwm_backlight_data viper_backlight_data = { 400 .pwm_id = 0, 401 .max_brightness = 100, 402 .dft_brightness = 100, 403 .pwm_period_ns = 1000000, 404 .enable_gpio = -1, 405 .init = viper_backlight_init, 406 .notify = viper_backlight_notify, 407 .exit = viper_backlight_exit, 408}; 409 410static struct platform_device viper_backlight_device = { 411 .name = "pwm-backlight", 412 .dev = { 413 .parent = &pxa25x_device_pwm0.dev, 414 .platform_data = &viper_backlight_data, 415 }, 416}; 417 418/* Ethernet */ 419static struct resource smc91x_resources[] = { 420 [0] = { 421 .name = "smc91x-regs", 422 .start = VIPER_ETH_PHYS + 0x300, 423 .end = VIPER_ETH_PHYS + 0x30f, 424 .flags = IORESOURCE_MEM, 425 }, 426 [1] = { 427 .start = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), 428 .end = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO), 429 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 430 }, 431 [2] = { 432 .name = "smc91x-data32", 433 .start = VIPER_ETH_DATA_PHYS, 434 .end = VIPER_ETH_DATA_PHYS + 3, 435 .flags = IORESOURCE_MEM, 436 }, 437}; 438 439static struct smc91x_platdata viper_smc91x_info = { 440 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, 441 .leda = RPC_LED_100_10, 442 .ledb = RPC_LED_TX_RX, 443}; 444 445static struct platform_device smc91x_device = { 446 .name = "smc91x", 447 .id = -1, 448 .num_resources = ARRAY_SIZE(smc91x_resources), 449 .resource = smc91x_resources, 450 .dev = { 451 .platform_data = &viper_smc91x_info, 452 }, 453}; 454 455/* i2c */ 456static struct i2c_gpio_platform_data i2c_bus_data = { 457 .sda_pin = VIPER_RTC_I2C_SDA_GPIO, 458 .scl_pin = VIPER_RTC_I2C_SCL_GPIO, 459 .udelay = 10, 460 .timeout = HZ, 461}; 462 463static struct platform_device i2c_bus_device = { 464 .name = "i2c-gpio", 465 .id = 1, /* pxa2xx-i2c is bus 0, so start at 1 */ 466 .dev = { 467 .platform_data = &i2c_bus_data, 468 } 469}; 470 471static struct i2c_board_info __initdata viper_i2c_devices[] = { 472 { 473 I2C_BOARD_INFO("ds1338", 0x68), 474 }, 475}; 476 477/* 478 * Serial configuration: 479 * You can either have the standard PXA ports driven by the PXA driver, 480 * or all the ports (PXA + 16850) driven by the 8250 driver. 481 * Choose your poison. 482 */ 483 484static struct resource viper_serial_resources[] = { 485#ifndef CONFIG_SERIAL_PXA 486 { 487 .start = 0x40100000, 488 .end = 0x4010001f, 489 .flags = IORESOURCE_MEM, 490 }, 491 { 492 .start = 0x40200000, 493 .end = 0x4020001f, 494 .flags = IORESOURCE_MEM, 495 }, 496 { 497 .start = 0x40700000, 498 .end = 0x4070001f, 499 .flags = IORESOURCE_MEM, 500 }, 501 { 502 .start = VIPER_UARTA_PHYS, 503 .end = VIPER_UARTA_PHYS + 0xf, 504 .flags = IORESOURCE_MEM, 505 }, 506 { 507 .start = VIPER_UARTB_PHYS, 508 .end = VIPER_UARTB_PHYS + 0xf, 509 .flags = IORESOURCE_MEM, 510 }, 511#else 512 { 513 0, 514 }, 515#endif 516}; 517 518static struct plat_serial8250_port serial_platform_data[] = { 519#ifndef CONFIG_SERIAL_PXA 520 /* Internal UARTs */ 521 { 522 .membase = (void *)&FFUART, 523 .mapbase = __PREG(FFUART), 524 .irq = IRQ_FFUART, 525 .uartclk = 921600 * 16, 526 .regshift = 2, 527 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 528 .iotype = UPIO_MEM, 529 }, 530 { 531 .membase = (void *)&BTUART, 532 .mapbase = __PREG(BTUART), 533 .irq = IRQ_BTUART, 534 .uartclk = 921600 * 16, 535 .regshift = 2, 536 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 537 .iotype = UPIO_MEM, 538 }, 539 { 540 .membase = (void *)&STUART, 541 .mapbase = __PREG(STUART), 542 .irq = IRQ_STUART, 543 .uartclk = 921600 * 16, 544 .regshift = 2, 545 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 546 .iotype = UPIO_MEM, 547 }, 548 /* External UARTs */ 549 { 550 .mapbase = VIPER_UARTA_PHYS, 551 .irq = PXA_GPIO_TO_IRQ(VIPER_UARTA_GPIO), 552 .irqflags = IRQF_TRIGGER_RISING, 553 .uartclk = 1843200, 554 .regshift = 1, 555 .iotype = UPIO_MEM, 556 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | 557 UPF_SKIP_TEST, 558 }, 559 { 560 .mapbase = VIPER_UARTB_PHYS, 561 .irq = PXA_GPIO_TO_IRQ(VIPER_UARTB_GPIO), 562 .irqflags = IRQF_TRIGGER_RISING, 563 .uartclk = 1843200, 564 .regshift = 1, 565 .iotype = UPIO_MEM, 566 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | 567 UPF_SKIP_TEST, 568 }, 569#endif 570 { }, 571}; 572 573static struct platform_device serial_device = { 574 .name = "serial8250", 575 .id = 0, 576 .dev = { 577 .platform_data = serial_platform_data, 578 }, 579 .num_resources = ARRAY_SIZE(viper_serial_resources), 580 .resource = viper_serial_resources, 581}; 582 583/* USB */ 584static void isp116x_delay(struct device *dev, int delay) 585{ 586 ndelay(delay); 587} 588 589static struct resource isp116x_resources[] = { 590 [0] = { /* DATA */ 591 .start = VIPER_USB_PHYS + 0, 592 .end = VIPER_USB_PHYS + 1, 593 .flags = IORESOURCE_MEM, 594 }, 595 [1] = { /* ADDR */ 596 .start = VIPER_USB_PHYS + 2, 597 .end = VIPER_USB_PHYS + 3, 598 .flags = IORESOURCE_MEM, 599 }, 600 [2] = { 601 .start = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), 602 .end = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO), 603 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 604 }, 605}; 606 607/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */ 608static struct isp116x_platform_data isp116x_platform_data = { 609 /* Enable internal resistors on downstream ports */ 610 .sel15Kres = 1, 611 /* On-chip overcurrent protection */ 612 .oc_enable = 1, 613 /* INT output polarity */ 614 .int_act_high = 1, 615 /* INT edge or level triggered */ 616 .int_edge_triggered = 0, 617 618 /* WAKEUP pin connected - NOT SUPPORTED */ 619 /* .remote_wakeup_connected = 0, */ 620 /* Wakeup by devices on usb bus enabled */ 621 .remote_wakeup_enable = 0, 622 .delay = isp116x_delay, 623}; 624 625static struct platform_device isp116x_device = { 626 .name = "isp116x-hcd", 627 .id = -1, 628 .num_resources = ARRAY_SIZE(isp116x_resources), 629 .resource = isp116x_resources, 630 .dev = { 631 .platform_data = &isp116x_platform_data, 632 }, 633 634}; 635 636/* MTD */ 637static struct resource mtd_resources[] = { 638 [0] = { /* RedBoot config + filesystem flash */ 639 .start = VIPER_FLASH_PHYS, 640 .end = VIPER_FLASH_PHYS + SZ_32M - 1, 641 .flags = IORESOURCE_MEM, 642 }, 643 [1] = { /* Boot flash */ 644 .start = VIPER_BOOT_PHYS, 645 .end = VIPER_BOOT_PHYS + SZ_1M - 1, 646 .flags = IORESOURCE_MEM, 647 }, 648 [2] = { /* 649 * SRAM size is actually 256KB, 8bits, with a sparse mapping 650 * (each byte is on a 16bit boundary). 651 */ 652 .start = _VIPER_SRAM_BASE, 653 .end = _VIPER_SRAM_BASE + SZ_512K - 1, 654 .flags = IORESOURCE_MEM, 655 }, 656}; 657 658static struct mtd_partition viper_boot_flash_partition = { 659 .name = "RedBoot", 660 .size = SZ_1M, 661 .offset = 0, 662 .mask_flags = MTD_WRITEABLE, /* force R/O */ 663}; 664 665static struct physmap_flash_data viper_flash_data[] = { 666 [0] = { 667 .width = 2, 668 .parts = NULL, 669 .nr_parts = 0, 670 }, 671 [1] = { 672 .width = 2, 673 .parts = &viper_boot_flash_partition, 674 .nr_parts = 1, 675 }, 676}; 677 678static struct platform_device viper_mtd_devices[] = { 679 [0] = { 680 .name = "physmap-flash", 681 .id = 0, 682 .dev = { 683 .platform_data = &viper_flash_data[0], 684 }, 685 .resource = &mtd_resources[0], 686 .num_resources = 1, 687 }, 688 [1] = { 689 .name = "physmap-flash", 690 .id = 1, 691 .dev = { 692 .platform_data = &viper_flash_data[1], 693 }, 694 .resource = &mtd_resources[1], 695 .num_resources = 1, 696 }, 697}; 698 699static struct platform_device *viper_devs[] __initdata = { 700 &smc91x_device, 701 &i2c_bus_device, 702 &serial_device, 703 &isp116x_device, 704 &viper_mtd_devices[0], 705 &viper_mtd_devices[1], 706 &viper_backlight_device, 707 &viper_pcmcia_device, 708}; 709 710static mfp_cfg_t viper_pin_config[] __initdata = { 711 /* Chip selects */ 712 GPIO15_nCS_1, 713 GPIO78_nCS_2, 714 GPIO79_nCS_3, 715 GPIO80_nCS_4, 716 GPIO33_nCS_5, 717 718 /* AC97 */ 719 GPIO28_AC97_BITCLK, 720 GPIO29_AC97_SDATA_IN_0, 721 GPIO30_AC97_SDATA_OUT, 722 GPIO31_AC97_SYNC, 723 724 /* FP Backlight */ 725 GPIO9_GPIO, /* VIPER_BCKLIGHT_EN_GPIO */ 726 GPIO10_GPIO, /* VIPER_LCD_EN_GPIO */ 727 GPIO16_PWM0_OUT, 728 729 /* Ethernet PHY Ready */ 730 GPIO18_RDY, 731 732 /* Serial shutdown */ 733 GPIO12_GPIO | MFP_LPM_DRIVE_HIGH, /* VIPER_UART_SHDN_GPIO */ 734 735 /* Compact-Flash / PC104 */ 736 GPIO48_nPOE, 737 GPIO49_nPWE, 738 GPIO50_nPIOR, 739 GPIO51_nPIOW, 740 GPIO52_nPCE_1, 741 GPIO53_nPCE_2, 742 GPIO54_nPSKTSEL, 743 GPIO55_nPREG, 744 GPIO56_nPWAIT, 745 GPIO57_nIOIS16, 746 GPIO8_GPIO, /* VIPER_CF_RDY_GPIO */ 747 GPIO32_GPIO, /* VIPER_CF_CD_GPIO */ 748 GPIO82_GPIO, /* VIPER_CF_POWER_GPIO */ 749 750 /* Integrated UPS control */ 751 GPIO20_GPIO, /* VIPER_UPS_GPIO */ 752 753 /* Vcc regulator control */ 754 GPIO6_GPIO, /* VIPER_PSU_DATA_GPIO */ 755 GPIO11_GPIO, /* VIPER_PSU_CLK_GPIO */ 756 GPIO19_GPIO, /* VIPER_PSU_nCS_LD_GPIO */ 757 758 /* i2c busses */ 759 GPIO26_GPIO, /* VIPER_TPM_I2C_SDA_GPIO */ 760 GPIO27_GPIO, /* VIPER_TPM_I2C_SCL_GPIO */ 761 GPIO83_GPIO, /* VIPER_RTC_I2C_SDA_GPIO */ 762 GPIO84_GPIO, /* VIPER_RTC_I2C_SCL_GPIO */ 763 764 /* PC/104 Interrupt */ 765 GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* VIPER_CPLD_GPIO */ 766}; 767 768static unsigned long viper_tpm; 769 770static int __init viper_tpm_setup(char *str) 771{ 772 return kstrtoul(str, 10, &viper_tpm) >= 0; 773} 774 775__setup("tpm=", viper_tpm_setup); 776 777static void __init viper_tpm_init(void) 778{ 779 struct platform_device *tpm_device; 780 struct i2c_gpio_platform_data i2c_tpm_data = { 781 .sda_pin = VIPER_TPM_I2C_SDA_GPIO, 782 .scl_pin = VIPER_TPM_I2C_SCL_GPIO, 783 .udelay = 10, 784 .timeout = HZ, 785 }; 786 char *errstr; 787 788 /* Allocate TPM i2c bus if requested */ 789 if (!viper_tpm) 790 return; 791 792 tpm_device = platform_device_alloc("i2c-gpio", 2); 793 if (tpm_device) { 794 if (!platform_device_add_data(tpm_device, 795 &i2c_tpm_data, 796 sizeof(i2c_tpm_data))) { 797 if (platform_device_add(tpm_device)) { 798 errstr = "register TPM i2c bus"; 799 goto error_free_tpm; 800 } 801 } else { 802 errstr = "allocate TPM i2c bus data"; 803 goto error_free_tpm; 804 } 805 } else { 806 errstr = "allocate TPM i2c device"; 807 goto error_tpm; 808 } 809 810 return; 811 812error_free_tpm: 813 kfree(tpm_device); 814error_tpm: 815 pr_err("viper: Couldn't %s, giving up\n", errstr); 816} 817 818static void __init viper_init_vcore_gpios(void) 819{ 820 if (gpio_request(VIPER_PSU_DATA_GPIO, "PSU data")) 821 goto err_request_data; 822 823 if (gpio_request(VIPER_PSU_CLK_GPIO, "PSU clock")) 824 goto err_request_clk; 825 826 if (gpio_request(VIPER_PSU_nCS_LD_GPIO, "PSU cs")) 827 goto err_request_cs; 828 829 if (gpio_direction_output(VIPER_PSU_DATA_GPIO, 0) || 830 gpio_direction_output(VIPER_PSU_CLK_GPIO, 0) || 831 gpio_direction_output(VIPER_PSU_nCS_LD_GPIO, 0)) 832 goto err_dir; 833 834 /* c/should assume redboot set the correct level ??? */ 835 viper_set_core_cpu_voltage(get_clk_frequency_khz(0), 1); 836 837 return; 838 839err_dir: 840 gpio_free(VIPER_PSU_nCS_LD_GPIO); 841err_request_cs: 842 gpio_free(VIPER_PSU_CLK_GPIO); 843err_request_clk: 844 gpio_free(VIPER_PSU_DATA_GPIO); 845err_request_data: 846 pr_err("viper: Failed to setup vcore control GPIOs\n"); 847} 848 849static void __init viper_init_serial_gpio(void) 850{ 851 if (gpio_request(VIPER_UART_SHDN_GPIO, "UARTs shutdown")) 852 goto err_request; 853 854 if (gpio_direction_output(VIPER_UART_SHDN_GPIO, 0)) 855 goto err_dir; 856 857 return; 858 859err_dir: 860 gpio_free(VIPER_UART_SHDN_GPIO); 861err_request: 862 pr_err("viper: Failed to setup UART shutdown GPIO\n"); 863} 864 865#ifdef CONFIG_CPU_FREQ 866static int viper_cpufreq_notifier(struct notifier_block *nb, 867 unsigned long val, void *data) 868{ 869 struct cpufreq_freqs *freq = data; 870 871 /* TODO: Adjust timings??? */ 872 873 switch (val) { 874 case CPUFREQ_PRECHANGE: 875 if (freq->old < freq->new) { 876 /* we are getting faster so raise the voltage 877 * before we change freq */ 878 viper_set_core_cpu_voltage(freq->new, 0); 879 } 880 break; 881 case CPUFREQ_POSTCHANGE: 882 if (freq->old > freq->new) { 883 /* we are slowing down so drop the power 884 * after we change freq */ 885 viper_set_core_cpu_voltage(freq->new, 0); 886 } 887 break; 888 default: 889 /* ignore */ 890 break; 891 } 892 893 return 0; 894} 895 896static struct notifier_block viper_cpufreq_notifier_block = { 897 .notifier_call = viper_cpufreq_notifier 898}; 899 900static void __init viper_init_cpufreq(void) 901{ 902 if (cpufreq_register_notifier(&viper_cpufreq_notifier_block, 903 CPUFREQ_TRANSITION_NOTIFIER)) 904 pr_err("viper: Failed to setup cpufreq notifier\n"); 905} 906#else 907static inline void viper_init_cpufreq(void) {} 908#endif 909 910static void viper_power_off(void) 911{ 912 pr_notice("Shutting off UPS\n"); 913 gpio_set_value(VIPER_UPS_GPIO, 1); 914 /* Spin to death... */ 915 while (1); 916} 917 918static void __init viper_init(void) 919{ 920 u8 version; 921 922 pm_power_off = viper_power_off; 923 924 pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config)); 925 926 pxa_set_ffuart_info(NULL); 927 pxa_set_btuart_info(NULL); 928 pxa_set_stuart_info(NULL); 929 930 /* Wake-up serial console */ 931 viper_init_serial_gpio(); 932 933 pxa_set_fb_info(NULL, &fb_info); 934 935 /* v1 hardware cannot use the datacs line */ 936 version = viper_hw_version(); 937 if (version == 0) 938 smc91x_device.num_resources--; 939 940 pxa_set_i2c_info(NULL); 941 platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs)); 942 943 viper_init_vcore_gpios(); 944 viper_init_cpufreq(); 945 946 register_syscore_ops(&viper_cpu_syscore_ops); 947 948 if (version) { 949 pr_info("viper: hardware v%di%d detected. " 950 "CPLD revision %d.\n", 951 VIPER_BOARD_VERSION(version), 952 VIPER_BOARD_ISSUE(version), 953 VIPER_CPLD_REVISION(version)); 954 system_rev = (VIPER_BOARD_VERSION(version) << 8) | 955 (VIPER_BOARD_ISSUE(version) << 4) | 956 VIPER_CPLD_REVISION(version); 957 } else { 958 pr_info("viper: No version register.\n"); 959 } 960 961 i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices)); 962 963 viper_tpm_init(); 964 pxa_set_ac97_info(NULL); 965} 966 967static struct map_desc viper_io_desc[] __initdata = { 968 { 969 .virtual = VIPER_CPLD_BASE, 970 .pfn = __phys_to_pfn(VIPER_CPLD_PHYS), 971 .length = 0x00300000, 972 .type = MT_DEVICE, 973 }, 974 { 975 .virtual = VIPER_PC104IO_BASE, 976 .pfn = __phys_to_pfn(0x30000000), 977 .length = 0x00800000, 978 .type = MT_DEVICE, 979 }, 980}; 981 982static void __init viper_map_io(void) 983{ 984 pxa25x_map_io(); 985 986 iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc)); 987 988 PCFR |= PCFR_OPDE; 989} 990 991MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC") 992 /* Maintainer: Marc Zyngier <maz@misterjones.org> */ 993 .atag_offset = 0x100, 994 .map_io = viper_map_io, 995 .nr_irqs = PXA_NR_IRQS, 996 .init_irq = viper_init_irq, 997 .handle_irq = pxa25x_handle_irq, 998 .init_time = pxa_timer_init, 999 .init_machine = viper_init, 1000 .restart = pxa_restart, 1001MACHINE_END 1002