1/* 2 * linux/arch/arm/mach-pxa/mainstone.c 3 * 4 * Support for the Intel HCDDBBVA0 Development Platform. 5 * (go figure how they came up with such name...) 6 * 7 * Author: Nicolas Pitre 8 * Created: Nov 05, 2002 9 * Copyright: MontaVista Software Inc. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/sysdev.h> 19#include <linux/interrupt.h> 20#include <linux/sched.h> 21#include <linux/bitops.h> 22#include <linux/fb.h> 23#include <linux/ioport.h> 24#include <linux/mtd/mtd.h> 25#include <linux/mtd/partitions.h> 26 27#include <asm/types.h> 28#include <asm/setup.h> 29#include <asm/memory.h> 30#include <asm/mach-types.h> 31#include <asm/hardware.h> 32#include <asm/irq.h> 33#include <asm/sizes.h> 34 35#include <asm/mach/arch.h> 36#include <asm/mach/map.h> 37#include <asm/mach/irq.h> 38#include <asm/mach/flash.h> 39 40#include <asm/arch/pxa-regs.h> 41#include <asm/arch/mainstone.h> 42#include <asm/arch/audio.h> 43#include <asm/arch/pxafb.h> 44#include <asm/arch/mmc.h> 45#include <asm/arch/irda.h> 46#include <asm/arch/ohci.h> 47 48#include "generic.h" 49 50 51static unsigned long mainstone_irq_enabled; 52 53static void mainstone_mask_irq(unsigned int irq) 54{ 55 int mainstone_irq = (irq - MAINSTONE_IRQ(0)); 56 MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq)); 57} 58 59static void mainstone_unmask_irq(unsigned int irq) 60{ 61 int mainstone_irq = (irq - MAINSTONE_IRQ(0)); 62 /* the irq can be acknowledged only if deasserted, so it's done here */ 63 MST_INTSETCLR &= ~(1 << mainstone_irq); 64 MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq)); 65} 66 67static struct irq_chip mainstone_irq_chip = { 68 .name = "FPGA", 69 .ack = mainstone_mask_irq, 70 .mask = mainstone_mask_irq, 71 .unmask = mainstone_unmask_irq, 72}; 73 74static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc) 75{ 76 unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; 77 do { 78 GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ 79 if (likely(pending)) { 80 irq = MAINSTONE_IRQ(0) + __ffs(pending); 81 desc = irq_desc + irq; 82 desc_handle_irq(irq, desc); 83 } 84 pending = MST_INTSETCLR & mainstone_irq_enabled; 85 } while (pending); 86} 87 88static void __init mainstone_init_irq(void) 89{ 90 int irq; 91 92 pxa_init_irq(); 93 94 /* setup extra Mainstone irqs */ 95 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { 96 set_irq_chip(irq, &mainstone_irq_chip); 97 set_irq_handler(irq, handle_level_irq); 98 if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) 99 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); 100 else 101 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 102 } 103 set_irq_flags(MAINSTONE_IRQ(8), 0); 104 set_irq_flags(MAINSTONE_IRQ(12), 0); 105 106 MST_INTMSKENA = 0; 107 MST_INTSETCLR = 0; 108 109 set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); 110 set_irq_type(IRQ_GPIO(0), IRQT_FALLING); 111} 112 113#ifdef CONFIG_PM 114 115static int mainstone_irq_resume(struct sys_device *dev) 116{ 117 MST_INTMSKENA = mainstone_irq_enabled; 118 return 0; 119} 120 121static struct sysdev_class mainstone_irq_sysclass = { 122 set_kset_name("cpld_irq"), 123 .resume = mainstone_irq_resume, 124}; 125 126static struct sys_device mainstone_irq_device = { 127 .cls = &mainstone_irq_sysclass, 128}; 129 130static int __init mainstone_irq_device_init(void) 131{ 132 int ret = sysdev_class_register(&mainstone_irq_sysclass); 133 if (ret == 0) 134 ret = sysdev_register(&mainstone_irq_device); 135 return ret; 136} 137 138device_initcall(mainstone_irq_device_init); 139 140#endif 141 142 143static struct resource smc91x_resources[] = { 144 [0] = { 145 .start = (MST_ETH_PHYS + 0x300), 146 .end = (MST_ETH_PHYS + 0xfffff), 147 .flags = IORESOURCE_MEM, 148 }, 149 [1] = { 150 .start = MAINSTONE_IRQ(3), 151 .end = MAINSTONE_IRQ(3), 152 .flags = IORESOURCE_IRQ, 153 } 154}; 155 156static struct platform_device smc91x_device = { 157 .name = "smc91x", 158 .id = 0, 159 .num_resources = ARRAY_SIZE(smc91x_resources), 160 .resource = smc91x_resources, 161}; 162 163static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv) 164{ 165 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 166 MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; 167 return 0; 168} 169 170static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv) 171{ 172 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 173 MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; 174} 175 176static long mst_audio_suspend_mask; 177 178static void mst_audio_suspend(void *priv) 179{ 180 mst_audio_suspend_mask = MST_MSCWR2; 181 MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; 182} 183 184static void mst_audio_resume(void *priv) 185{ 186 MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF; 187} 188 189static pxa2xx_audio_ops_t mst_audio_ops = { 190 .startup = mst_audio_startup, 191 .shutdown = mst_audio_shutdown, 192 .suspend = mst_audio_suspend, 193 .resume = mst_audio_resume, 194}; 195 196static struct platform_device mst_audio_device = { 197 .name = "pxa2xx-ac97", 198 .id = -1, 199 .dev = { .platform_data = &mst_audio_ops }, 200}; 201 202static struct resource flash_resources[] = { 203 [0] = { 204 .start = PXA_CS0_PHYS, 205 .end = PXA_CS0_PHYS + SZ_64M - 1, 206 .flags = IORESOURCE_MEM, 207 }, 208 [1] = { 209 .start = PXA_CS1_PHYS, 210 .end = PXA_CS1_PHYS + SZ_64M - 1, 211 .flags = IORESOURCE_MEM, 212 }, 213}; 214 215static struct mtd_partition mainstoneflash0_partitions[] = { 216 { 217 .name = "Bootloader", 218 .size = 0x00040000, 219 .offset = 0, 220 .mask_flags = MTD_WRITEABLE /* force read-only */ 221 },{ 222 .name = "Kernel", 223 .size = 0x00400000, 224 .offset = 0x00040000, 225 },{ 226 .name = "Filesystem", 227 .size = MTDPART_SIZ_FULL, 228 .offset = 0x00440000 229 } 230}; 231 232static struct flash_platform_data mst_flash_data[2] = { 233 { 234 .map_name = "cfi_probe", 235 .parts = mainstoneflash0_partitions, 236 .nr_parts = ARRAY_SIZE(mainstoneflash0_partitions), 237 }, { 238 .map_name = "cfi_probe", 239 .parts = NULL, 240 .nr_parts = 0, 241 } 242}; 243 244static struct platform_device mst_flash_device[2] = { 245 { 246 .name = "pxa2xx-flash", 247 .id = 0, 248 .dev = { 249 .platform_data = &mst_flash_data[0], 250 }, 251 .resource = &flash_resources[0], 252 .num_resources = 1, 253 }, 254 { 255 .name = "pxa2xx-flash", 256 .id = 1, 257 .dev = { 258 .platform_data = &mst_flash_data[1], 259 }, 260 .resource = &flash_resources[1], 261 .num_resources = 1, 262 }, 263}; 264 265static void mainstone_backlight_power(int on) 266{ 267 if (on) { 268 pxa_gpio_mode(GPIO16_PWM0_MD); 269 pxa_set_cken(CKEN_PWM0, 1); 270 PWM_CTRL0 = 0; 271 PWM_PWDUTY0 = 0x3ff; 272 PWM_PERVAL0 = 0x3ff; 273 } else { 274 PWM_CTRL0 = 0; 275 PWM_PWDUTY0 = 0x0; 276 PWM_PERVAL0 = 0x3FF; 277 pxa_set_cken(CKEN_PWM0, 0); 278 } 279} 280 281static struct pxafb_mode_info toshiba_ltm04c380k_mode = { 282 .pixclock = 50000, 283 .xres = 640, 284 .yres = 480, 285 .bpp = 16, 286 .hsync_len = 1, 287 .left_margin = 0x9f, 288 .right_margin = 1, 289 .vsync_len = 44, 290 .upper_margin = 0, 291 .lower_margin = 0, 292 .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, 293}; 294 295static struct pxafb_mode_info toshiba_ltm035a776c_mode = { 296 .pixclock = 110000, 297 .xres = 240, 298 .yres = 320, 299 .bpp = 16, 300 .hsync_len = 4, 301 .left_margin = 8, 302 .right_margin = 20, 303 .vsync_len = 3, 304 .upper_margin = 1, 305 .lower_margin = 10, 306 .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, 307}; 308 309static struct pxafb_mach_info mainstone_pxafb_info = { 310 .num_modes = 1, 311 .lccr0 = LCCR0_Act, 312 .lccr3 = LCCR3_PCP, 313 .pxafb_backlight_power = mainstone_backlight_power, 314}; 315 316static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data) 317{ 318 int err; 319 320 /* 321 * setup GPIO for PXA27x MMC controller 322 */ 323 pxa_gpio_mode(GPIO32_MMCCLK_MD); 324 pxa_gpio_mode(GPIO112_MMCCMD_MD); 325 pxa_gpio_mode(GPIO92_MMCDAT0_MD); 326 pxa_gpio_mode(GPIO109_MMCDAT1_MD); 327 pxa_gpio_mode(GPIO110_MMCDAT2_MD); 328 pxa_gpio_mode(GPIO111_MMCDAT3_MD); 329 330 /* make sure SD/Memory Stick multiplexer's signals 331 * are routed to MMC controller 332 */ 333 MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; 334 335 err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED, 336 "MMC card detect", data); 337 if (err) { 338 printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); 339 return -1; 340 } 341 342 return 0; 343} 344 345static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) 346{ 347 struct pxamci_platform_data* p_d = dev->platform_data; 348 349 if (( 1 << vdd) & p_d->ocr_mask) { 350 printk(KERN_DEBUG "%s: on\n", __FUNCTION__); 351 MST_MSCWR1 |= MST_MSCWR1_MMC_ON; 352 MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; 353 } else { 354 printk(KERN_DEBUG "%s: off\n", __FUNCTION__); 355 MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; 356 } 357} 358 359static void mainstone_mci_exit(struct device *dev, void *data) 360{ 361 free_irq(MAINSTONE_MMC_IRQ, data); 362} 363 364static struct pxamci_platform_data mainstone_mci_platform_data = { 365 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 366 .init = mainstone_mci_init, 367 .setpower = mainstone_mci_setpower, 368 .exit = mainstone_mci_exit, 369}; 370 371static void mainstone_irda_transceiver_mode(struct device *dev, int mode) 372{ 373 unsigned long flags; 374 375 local_irq_save(flags); 376 if (mode & IR_SIRMODE) { 377 MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR; 378 } else if (mode & IR_FIRMODE) { 379 MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR; 380 } 381 if (mode & IR_OFF) { 382 MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF; 383 } else { 384 MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL; 385 } 386 local_irq_restore(flags); 387} 388 389static struct pxaficp_platform_data mainstone_ficp_platform_data = { 390 .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, 391 .transceiver_mode = mainstone_irda_transceiver_mode, 392}; 393 394static struct platform_device *platform_devices[] __initdata = { 395 &smc91x_device, 396 &mst_audio_device, 397 &mst_flash_device[0], 398 &mst_flash_device[1], 399}; 400 401static int mainstone_ohci_init(struct device *dev) 402{ 403 /* setup Port1 GPIO pin. */ 404 pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ 405 pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ 406 407 /* Set the Power Control Polarity Low and Power Sense 408 Polarity Low to active low. */ 409 UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & 410 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); 411 412 return 0; 413} 414 415static struct pxaohci_platform_data mainstone_ohci_platform_data = { 416 .port_mode = PMM_PERPORT_MODE, 417 .init = mainstone_ohci_init, 418}; 419 420static void __init mainstone_init(void) 421{ 422 int SW7 = 0; 423 424 mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; 425 mst_flash_data[1].width = 4; 426 427 /* Compensate for SW7 which swaps the flash banks */ 428 mst_flash_data[SW7].name = "processor-flash"; 429 mst_flash_data[SW7 ^ 1].name = "mainboard-flash"; 430 431 printk(KERN_NOTICE "Mainstone configured to boot from %s\n", 432 mst_flash_data[0].name); 433 434 /* system bus arbiter setting 435 * - Core_Park 436 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4 437 */ 438 ARB_CNTRL = ARB_CORE_PARK | 0x234; 439 440 /* 441 * On Mainstone, we route AC97_SYSCLK via GPIO45 to 442 * the audio daughter card 443 */ 444 pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); 445 446 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); 447 448 /* reading Mainstone's "Virtual Configuration Register" 449 might be handy to select LCD type here */ 450 if (0) 451 mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode; 452 else 453 mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; 454 455 set_pxa_fb_info(&mainstone_pxafb_info); 456 457 pxa_set_mci_info(&mainstone_mci_platform_data); 458 pxa_set_ficp_info(&mainstone_ficp_platform_data); 459 pxa_set_ohci_info(&mainstone_ohci_platform_data); 460} 461 462 463static struct map_desc mainstone_io_desc[] __initdata = { 464 { /* CPLD */ 465 .virtual = MST_FPGA_VIRT, 466 .pfn = __phys_to_pfn(MST_FPGA_PHYS), 467 .length = 0x00100000, 468 .type = MT_DEVICE 469 } 470}; 471 472static void __init mainstone_map_io(void) 473{ 474 pxa_map_io(); 475 iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); 476 477 /* initialize sleep mode regs (wake-up sources, etc) */ 478 PGSR0 = 0x00008800; 479 PGSR1 = 0x00000002; 480 PGSR2 = 0x0001FC00; 481 PGSR3 = 0x00001F81; 482 PWER = 0xC0000002; 483 PRER = 0x00000002; 484 PFER = 0x00000002; 485 /* for use I SRAM as framebuffer. */ 486 PSLR |= 0xF04; 487 PCFR = 0x66; 488 /* For Keypad wakeup. */ 489 KPC &=~KPC_ASACT; 490 KPC |=KPC_AS; 491 PKWR = 0x000FD000; 492 /* Need read PKWR back after set it. */ 493 PKWR; 494} 495 496MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") 497 /* Maintainer: MontaVista Software Inc. */ 498 .phys_io = 0x40000000, 499 .boot_params = 0xa0000100, /* BLOB boot parameter setting */ 500 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 501 .map_io = mainstone_map_io, 502 .init_irq = mainstone_init_irq, 503 .timer = &pxa_timer, 504 .init_machine = mainstone_init, 505MACHINE_END 506