1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * linux/arch/arm/mach-sa1100/assabet.c 4 * 5 * Author: Nicolas Pitre 6 * 7 * This file contains all Assabet-specific tweaks. 8 */ 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/errno.h> 13 #include <linux/gpio/gpio-reg.h> 14 #include <linux/gpio/machine.h> 15 #include <linux/gpio_keys.h> 16 #include <linux/ioport.h> 17 #include <linux/platform_data/sa11x0-serial.h> 18 #include <linux/regulator/fixed.h> 19 #include <linux/regulator/machine.h> 20 #include <linux/serial_core.h> 21 #include <linux/platform_device.h> 22 #include <linux/mfd/ucb1x00.h> 23 #include <linux/mtd/mtd.h> 24 #include <linux/mtd/partitions.h> 25 #include <linux/delay.h> 26 #include <linux/mm.h> 27 #include <linux/leds.h> 28 #include <linux/slab.h> 29 30 #include <video/sa1100fb.h> 31 32 #include <mach/hardware.h> 33 #include <asm/mach-types.h> 34 #include <asm/setup.h> 35 #include <asm/page.h> 36 #include <asm/pgtable-hwdef.h> 37 #include <asm/tlbflush.h> 38 39 #include <asm/mach/arch.h> 40 #include <asm/mach/flash.h> 41 #include <asm/mach/map.h> 42 #include <mach/assabet.h> 43 #include <linux/platform_data/mfd-mcp-sa11x0.h> 44 #include <mach/irqs.h> 45 46 #include "generic.h" 47 48 #define ASSABET_BCR_DB1110 \ 49 (ASSABET_BCR_SPK_OFF | \ 50 ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ 51 ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ 52 ASSABET_BCR_IRDA_MD0) 53 54 #define ASSABET_BCR_DB1111 \ 55 (ASSABET_BCR_SPK_OFF | \ 56 ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ 57 ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ 58 ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ 59 ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST) 60 61 unsigned long SCR_value = ASSABET_SCR_INIT; 62 EXPORT_SYMBOL(SCR_value); 63 64 static struct gpio_chip *assabet_bcr_gc; 65 66 static const char *assabet_names[] = { 67 "cf_pwr", "cf_gfx_reset", "nsoft_reset", "irda_fsel", 68 "irda_md0", "irda_md1", "stereo_loopback", "ncf_bus_on", 69 "audio_pwr_on", "light_pwr_on", "lcd16data", "lcd_pwr_on", 70 "rs232_on", "nred_led", "ngreen_led", "vib_on", 71 "com_dtr", "com_rts", "radio_wake_mod", "i2c_enab", 72 "tvir_enab", "qmute", "radio_pwr_on", "spkr_off", 73 "rs232_valid", "com_dcd", "com_cts", "com_dsr", 74 "radio_cts", "radio_dsr", "radio_dcd", "radio_ri", 75 }; 76 77 /* The old deprecated interface */ 78 void ASSABET_BCR_frob(unsigned int mask, unsigned int val) 79 { 80 unsigned long m = mask, v = val; 81 82 assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v); 83 } 84 EXPORT_SYMBOL(ASSABET_BCR_frob); 85 86 static void __init assabet_init_gpio(void __iomem *reg, u32 def_val) 87 { 88 struct gpio_chip *gc; 89 90 writel_relaxed(def_val, reg); 91 92 gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val, 93 assabet_names, NULL, NULL); 94 95 if (IS_ERR(gc)) 96 return; 97 98 assabet_bcr_gc = gc; 99 } 100 101 /* 102 * The codec reset goes to three devices, so we need to release 103 * the rest when any one of these requests it. However, that 104 * causes the ADV7171 to consume around 100mA - more than half 105 * the LCD-blanked power. 106 * 107 * With the ADV7171, LCD and backlight enabled, we go over 108 * budget on the MAX846 Li-Ion charger, and if no Li-Ion battery 109 * is connected, the Assabet crashes. 110 */ 111 #define RST_UCB1X00 (1 << 0) 112 #define RST_UDA1341 (1 << 1) 113 #define RST_ADV7171 (1 << 2) 114 115 #define SDA GPIO_GPIO(15) 116 #define SCK GPIO_GPIO(18) 117 #define MOD GPIO_GPIO(17) 118 119 static void adv7171_start(void) 120 { 121 GPSR = SCK; 122 udelay(1); 123 GPSR = SDA; 124 udelay(2); 125 GPCR = SDA; 126 } 127 128 static void adv7171_stop(void) 129 { 130 GPSR = SCK; 131 udelay(2); 132 GPSR = SDA; 133 udelay(1); 134 } 135 136 static void adv7171_send(unsigned byte) 137 { 138 unsigned i; 139 140 for (i = 0; i < 8; i++, byte <<= 1) { 141 GPCR = SCK; 142 udelay(1); 143 if (byte & 0x80) 144 GPSR = SDA; 145 else 146 GPCR = SDA; 147 udelay(1); 148 GPSR = SCK; 149 udelay(1); 150 } 151 GPCR = SCK; 152 udelay(1); 153 GPSR = SDA; 154 udelay(1); 155 GPDR &= ~SDA; 156 GPSR = SCK; 157 udelay(1); 158 if (GPLR & SDA) 159 printk(KERN_WARNING "No ACK from ADV7171\n"); 160 udelay(1); 161 GPCR = SCK | SDA; 162 udelay(1); 163 GPDR |= SDA; 164 udelay(1); 165 } 166 167 static void adv7171_write(unsigned reg, unsigned val) 168 { 169 unsigned gpdr = GPDR; 170 unsigned gplr = GPLR; 171 172 ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON); 173 udelay(100); 174 175 GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */ 176 GPDR = (GPDR | SCK | MOD) & ~SDA; 177 udelay(10); 178 if (!(GPLR & SDA)) 179 printk(KERN_WARNING "Something dragging SDA down?\n"); 180 GPDR |= SDA; 181 182 adv7171_start(); 183 adv7171_send(0x54); 184 adv7171_send(reg); 185 adv7171_send(val); 186 adv7171_stop(); 187 188 /* Restore GPIO state for L3 bus */ 189 GPSR = gplr & (SDA | SCK | MOD); 190 GPCR = (~gplr) & (SDA | SCK | MOD); 191 GPDR = gpdr; 192 } 193 194 static void adv7171_sleep(void) 195 { 196 /* Put the ADV7171 into sleep mode */ 197 adv7171_write(0x04, 0x40); 198 } 199 200 static unsigned codec_nreset; 201 202 static void assabet_codec_reset(unsigned mask, int set) 203 { 204 unsigned long flags; 205 bool old; 206 207 local_irq_save(flags); 208 old = !codec_nreset; 209 if (set) 210 codec_nreset &= ~mask; 211 else 212 codec_nreset |= mask; 213 214 if (old != !codec_nreset) { 215 if (codec_nreset) { 216 ASSABET_BCR_set(ASSABET_BCR_NCODEC_RST); 217 adv7171_sleep(); 218 } else { 219 ASSABET_BCR_clear(ASSABET_BCR_NCODEC_RST); 220 } 221 } 222 local_irq_restore(flags); 223 } 224 225 static void assabet_ucb1x00_reset(enum ucb1x00_reset state) 226 { 227 int set = state == UCB_RST_REMOVE || state == UCB_RST_SUSPEND || 228 state == UCB_RST_PROBE_FAIL; 229 assabet_codec_reset(RST_UCB1X00, set); 230 } 231 232 void assabet_uda1341_reset(int set) 233 { 234 assabet_codec_reset(RST_UDA1341, set); 235 } 236 EXPORT_SYMBOL(assabet_uda1341_reset); 237 238 239 /* 240 * Assabet flash support code. 241 */ 242 243 #ifdef ASSABET_REV_4 244 /* 245 * Phase 4 Assabet has two 28F160B3 flash parts in bank 0: 246 */ 247 static struct mtd_partition assabet_partitions[] = { 248 { 249 .name = "bootloader", 250 .size = 0x00020000, 251 .offset = 0, 252 .mask_flags = MTD_WRITEABLE, 253 }, { 254 .name = "bootloader params", 255 .size = 0x00020000, 256 .offset = MTDPART_OFS_APPEND, 257 .mask_flags = MTD_WRITEABLE, 258 }, { 259 .name = "jffs", 260 .size = MTDPART_SIZ_FULL, 261 .offset = MTDPART_OFS_APPEND, 262 } 263 }; 264 #else 265 /* 266 * Phase 5 Assabet has two 28F128J3A flash parts in bank 0: 267 */ 268 static struct mtd_partition assabet_partitions[] = { 269 { 270 .name = "bootloader", 271 .size = 0x00040000, 272 .offset = 0, 273 .mask_flags = MTD_WRITEABLE, 274 }, { 275 .name = "bootloader params", 276 .size = 0x00040000, 277 .offset = MTDPART_OFS_APPEND, 278 .mask_flags = MTD_WRITEABLE, 279 }, { 280 .name = "jffs", 281 .size = MTDPART_SIZ_FULL, 282 .offset = MTDPART_OFS_APPEND, 283 } 284 }; 285 #endif 286 287 static struct flash_platform_data assabet_flash_data = { 288 .map_name = "cfi_probe", 289 .parts = assabet_partitions, 290 .nr_parts = ARRAY_SIZE(assabet_partitions), 291 }; 292 293 static struct resource assabet_flash_resources[] = { 294 DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), 295 DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), 296 }; 297 298 299 static struct ucb1x00_plat_data assabet_ucb1x00_data = { 300 .reset = assabet_ucb1x00_reset, 301 .gpio_base = -1, 302 .can_wakeup = 1, 303 }; 304 305 static struct mcp_plat_data assabet_mcp_data = { 306 .mccr0 = MCCR0_ADM, 307 .sclk_rate = 11981000, 308 .codec_pdata = &assabet_ucb1x00_data, 309 }; 310 311 static void assabet_lcd_set_visual(u32 visual) 312 { 313 u_int is_true_color = visual == FB_VISUAL_TRUECOLOR; 314 315 if (machine_is_assabet()) { 316 #if 1 // phase 4 or newer Assabet's 317 if (is_true_color) 318 ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); 319 else 320 ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); 321 #else 322 // older Assabet's 323 if (is_true_color) 324 ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); 325 else 326 ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); 327 #endif 328 } 329 } 330 331 #ifndef ASSABET_PAL_VIDEO 332 static void assabet_lcd_backlight_power(int on) 333 { 334 if (on) 335 ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); 336 else 337 ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); 338 } 339 340 /* 341 * Turn on/off the backlight. When turning the backlight on, we wait 342 * 500us after turning it on so we don't cause the supplies to droop 343 * when we enable the LCD controller (and cause a hard reset.) 344 */ 345 static void assabet_lcd_power(int on) 346 { 347 if (on) { 348 ASSABET_BCR_set(ASSABET_BCR_LCD_ON); 349 udelay(500); 350 } else 351 ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); 352 } 353 354 /* 355 * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually 356 * takes an RGB666 signal, but we provide it with an RGB565 signal 357 * instead (def_rgb_16). 358 */ 359 static struct sa1100fb_mach_info lq039q2ds54_info = { 360 .pixclock = 171521, .bpp = 16, 361 .xres = 320, .yres = 240, 362 363 .hsync_len = 5, .vsync_len = 1, 364 .left_margin = 61, .upper_margin = 3, 365 .right_margin = 9, .lower_margin = 0, 366 367 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 368 369 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, 370 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), 371 372 .backlight_power = assabet_lcd_backlight_power, 373 .lcd_power = assabet_lcd_power, 374 .set_visual = assabet_lcd_set_visual, 375 }; 376 #else 377 static void assabet_pal_backlight_power(int on) 378 { 379 ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); 380 } 381 382 static void assabet_pal_power(int on) 383 { 384 ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); 385 } 386 387 static struct sa1100fb_mach_info pal_info = { 388 .pixclock = 67797, .bpp = 16, 389 .xres = 640, .yres = 512, 390 391 .hsync_len = 64, .vsync_len = 6, 392 .left_margin = 125, .upper_margin = 70, 393 .right_margin = 115, .lower_margin = 36, 394 395 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, 396 .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), 397 398 .backlight_power = assabet_pal_backlight_power, 399 .lcd_power = assabet_pal_power, 400 .set_visual = assabet_lcd_set_visual, 401 }; 402 #endif 403 404 #ifdef CONFIG_ASSABET_NEPONSET 405 static struct resource neponset_resources[] = { 406 DEFINE_RES_MEM(0x10000000, 0x08000000), 407 DEFINE_RES_MEM(0x18000000, 0x04000000), 408 DEFINE_RES_MEM(0x40000000, SZ_8K), 409 DEFINE_RES_IRQ(IRQ_GPIO25), 410 }; 411 #endif 412 413 static struct gpiod_lookup_table assabet_cf_gpio_table = { 414 .dev_id = "sa11x0-pcmcia.1", 415 .table = { 416 GPIO_LOOKUP("gpio", 21, "ready", GPIO_ACTIVE_HIGH), 417 GPIO_LOOKUP("gpio", 22, "detect", GPIO_ACTIVE_LOW), 418 GPIO_LOOKUP("gpio", 24, "bvd2", GPIO_ACTIVE_HIGH), 419 GPIO_LOOKUP("gpio", 25, "bvd1", GPIO_ACTIVE_HIGH), 420 GPIO_LOOKUP("assabet", 1, "reset", GPIO_ACTIVE_HIGH), 421 GPIO_LOOKUP("assabet", 7, "bus-enable", GPIO_ACTIVE_LOW), 422 { }, 423 }, 424 }; 425 426 static struct regulator_consumer_supply assabet_cf_vcc_consumers[] = { 427 REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.1"), 428 }; 429 430 static struct fixed_voltage_config assabet_cf_vcc_pdata __initdata = { 431 .supply_name = "cf-power", 432 .microvolts = 3300000, 433 }; 434 435 static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = { 436 .dev_id = "reg-fixed-voltage.0", 437 .table = { 438 GPIO_LOOKUP("assabet", 0, NULL, GPIO_ACTIVE_HIGH), 439 { }, 440 }, 441 }; 442 443 static struct gpiod_lookup_table assabet_leds_gpio_table = { 444 .dev_id = "leds-gpio", 445 .table = { 446 GPIO_LOOKUP("assabet", 13, NULL, GPIO_ACTIVE_LOW), 447 GPIO_LOOKUP("assabet", 14, NULL, GPIO_ACTIVE_LOW), 448 { }, 449 }, 450 }; 451 452 static struct gpio_led assabet_leds[] __initdata = { 453 { 454 .name = "assabet:red", 455 .default_trigger = "cpu0", 456 .default_state = LEDS_GPIO_DEFSTATE_KEEP, 457 }, { 458 .name = "assabet:green", 459 .default_trigger = "heartbeat", 460 .default_state = LEDS_GPIO_DEFSTATE_KEEP, 461 }, 462 }; 463 464 static const struct gpio_led_platform_data assabet_leds_pdata __initconst = { 465 .num_leds = ARRAY_SIZE(assabet_leds), 466 .leds = assabet_leds, 467 }; 468 469 static struct gpio_keys_button assabet_keys_buttons[] = { 470 { 471 .gpio = 0, 472 .irq = IRQ_GPIO0, 473 .desc = "gpio0", 474 .wakeup = 1, 475 .can_disable = 1, 476 .debounce_interval = 5, 477 }, { 478 .gpio = 1, 479 .irq = IRQ_GPIO1, 480 .desc = "gpio1", 481 .wakeup = 1, 482 .can_disable = 1, 483 .debounce_interval = 5, 484 }, 485 }; 486 487 static const struct gpio_keys_platform_data assabet_keys_pdata = { 488 .buttons = assabet_keys_buttons, 489 .nbuttons = ARRAY_SIZE(assabet_keys_buttons), 490 .rep = 0, 491 }; 492 493 static struct gpiod_lookup_table assabet_uart1_gpio_table = { 494 .dev_id = "sa11x0-uart.1", 495 .table = { 496 GPIO_LOOKUP("assabet", 16, "dtr", GPIO_ACTIVE_LOW), 497 GPIO_LOOKUP("assabet", 17, "rts", GPIO_ACTIVE_LOW), 498 GPIO_LOOKUP("assabet", 25, "dcd", GPIO_ACTIVE_LOW), 499 GPIO_LOOKUP("assabet", 26, "cts", GPIO_ACTIVE_LOW), 500 GPIO_LOOKUP("assabet", 27, "dsr", GPIO_ACTIVE_LOW), 501 { }, 502 }, 503 }; 504 505 static struct gpiod_lookup_table assabet_uart3_gpio_table = { 506 .dev_id = "sa11x0-uart.3", 507 .table = { 508 GPIO_LOOKUP("assabet", 28, "cts", GPIO_ACTIVE_LOW), 509 GPIO_LOOKUP("assabet", 29, "dsr", GPIO_ACTIVE_LOW), 510 GPIO_LOOKUP("assabet", 30, "dcd", GPIO_ACTIVE_LOW), 511 GPIO_LOOKUP("assabet", 31, "rng", GPIO_ACTIVE_LOW), 512 { }, 513 }, 514 }; 515 516 static void __init assabet_init(void) 517 { 518 /* 519 * Ensure that the power supply is in "high power" mode. 520 */ 521 GPSR = GPIO_GPIO16; 522 GPDR |= GPIO_GPIO16; 523 524 /* 525 * Ensure that these pins are set as outputs and are driving 526 * logic 0. This ensures that we won't inadvertently toggle 527 * the WS latch in the CPLD, and we don't float causing 528 * excessive power drain. --rmk 529 */ 530 GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; 531 GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; 532 533 /* 534 * Also set GPIO27 as an output; this is used to clock UART3 535 * via the FPGA and as otherwise has no pullups or pulldowns, 536 * so stop it floating. 537 */ 538 GPCR = GPIO_GPIO27; 539 GPDR |= GPIO_GPIO27; 540 541 /* 542 * Set up registers for sleep mode. 543 */ 544 PWER = PWER_GPIO0; 545 PGSR = 0; 546 PCFR = 0; 547 PSDR = 0; 548 PPDR |= PPC_TXD3 | PPC_TXD1; 549 PPSR |= PPC_TXD3 | PPC_TXD1; 550 551 sa11x0_ppc_configure_mcp(); 552 553 if (machine_has_neponset()) { 554 #ifndef CONFIG_ASSABET_NEPONSET 555 printk( "Warning: Neponset detected but full support " 556 "hasn't been configured in the kernel\n" ); 557 #else 558 platform_device_register_simple("neponset", 0, 559 neponset_resources, ARRAY_SIZE(neponset_resources)); 560 #endif 561 } else { 562 gpiod_add_lookup_table(&assabet_uart1_gpio_table); 563 gpiod_add_lookup_table(&assabet_uart3_gpio_table); 564 gpiod_add_lookup_table(&assabet_cf_vcc_gpio_table); 565 566 sa11x0_register_fixed_regulator(0, &assabet_cf_vcc_pdata, 567 assabet_cf_vcc_consumers, 568 ARRAY_SIZE(assabet_cf_vcc_consumers), 569 true); 570 571 } 572 573 platform_device_register_resndata(NULL, "gpio-keys", 0, 574 NULL, 0, 575 &assabet_keys_pdata, 576 sizeof(assabet_keys_pdata)); 577 578 gpiod_add_lookup_table(&assabet_leds_gpio_table); 579 gpio_led_register_device(-1, &assabet_leds_pdata); 580 581 #ifndef ASSABET_PAL_VIDEO 582 sa11x0_register_lcd(&lq039q2ds54_info); 583 #else 584 sa11x0_register_lcd(&pal_video); 585 #endif 586 sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, 587 ARRAY_SIZE(assabet_flash_resources)); 588 sa11x0_register_mcp(&assabet_mcp_data); 589 590 if (!machine_has_neponset()) 591 sa11x0_register_pcmcia(1, &assabet_cf_gpio_table); 592 } 593 594 /* 595 * On Assabet, we must probe for the Neponset board _before_ 596 * paging_init() has occurred to actually determine the amount 597 * of RAM available. To do so, we map the appropriate IO section 598 * in the page table here in order to access GPIO registers. 599 */ 600 static void __init map_sa1100_gpio_regs( void ) 601 { 602 unsigned long phys = __PREG(GPLR) & PMD_MASK; 603 unsigned long virt = (unsigned long)io_p2v(phys); 604 int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO); 605 pmd_t *pmd; 606 607 pmd = pmd_off_k(virt); 608 *pmd = __pmd(phys | prot); 609 flush_pmd_entry(pmd); 610 } 611 612 /* 613 * Read System Configuration "Register" 614 * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board 615 * User's Guide", section 4.4.1) 616 * 617 * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S 618 * to set up the serial port for decompression status messages. We 619 * repeat it here because the kernel may not be loaded as a zImage, and 620 * also because it's a hassle to communicate the SCR value to the kernel 621 * from the decompressor. 622 * 623 * Note that IRQs are guaranteed to be disabled. 624 */ 625 static void __init get_assabet_scr(void) 626 { 627 unsigned long scr, i; 628 629 GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ 630 GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ 631 GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */ 632 for(i = 100; i--; ) /* Read GPIO 9:2 */ 633 scr = GPLR; 634 GPDR |= 0x3fc; /* restore correct pin direction */ 635 scr &= 0x3fc; /* save as system configuration byte. */ 636 SCR_value = scr; 637 } 638 639 static void __init 640 fixup_assabet(struct tag *tags, char **cmdline) 641 { 642 /* This must be done before any call to machine_has_neponset() */ 643 map_sa1100_gpio_regs(); 644 get_assabet_scr(); 645 646 if (machine_has_neponset()) 647 printk("Neponset expansion board detected\n"); 648 } 649 650 651 static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate) 652 { 653 if (port->mapbase == _Ser1UTCR0) { 654 if (state) 655 ASSABET_BCR_clear(ASSABET_BCR_RS232EN); 656 else 657 ASSABET_BCR_set(ASSABET_BCR_RS232EN); 658 } 659 } 660 661 static struct sa1100_port_fns assabet_port_fns __initdata = { 662 .pm = assabet_uart_pm, 663 }; 664 665 static struct map_desc assabet_io_desc[] __initdata = { 666 { /* Board Control Register */ 667 .virtual = 0xf1000000, 668 .pfn = __phys_to_pfn(0x12000000), 669 .length = 0x00100000, 670 .type = MT_DEVICE 671 }, { /* MQ200 */ 672 .virtual = 0xf2800000, 673 .pfn = __phys_to_pfn(0x4b800000), 674 .length = 0x00800000, 675 .type = MT_DEVICE 676 } 677 }; 678 679 static void __init assabet_map_io(void) 680 { 681 sa1100_map_io(); 682 iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc)); 683 684 /* 685 * Set SUS bit in SDCR0 so serial port 1 functions. 686 * Its called GPCLKR0 in my SA1110 manual. 687 */ 688 Ser1SDCR0 |= SDCR0_SUS; 689 MSC1 = (MSC1 & ~0xffff) | 690 MSC_NonBrst | MSC_32BitStMem | 691 MSC_RdAcc(2) | MSC_WrAcc(2) | MSC_Rec(0); 692 693 if (!machine_has_neponset()) 694 sa1100_register_uart_fns(&assabet_port_fns); 695 696 /* 697 * When Neponset is attached, the first UART should be 698 * UART3. That's what Angel is doing and many documents 699 * are stating this. 700 * 701 * We do the Neponset mapping even if Neponset support 702 * isn't compiled in so the user will still get something on 703 * the expected physical serial port. 704 * 705 * We no longer do this; not all boot loaders support it, 706 * and UART3 appears to be somewhat unreliable with blob. 707 */ 708 sa1100_register_uart(0, 1); 709 sa1100_register_uart(2, 3); 710 } 711 712 void __init assabet_init_irq(void) 713 { 714 u32 def_val; 715 716 sa1100_init_irq(); 717 718 if (machine_has_neponset()) 719 def_val = ASSABET_BCR_DB1111; 720 else 721 def_val = ASSABET_BCR_DB1110; 722 723 /* 724 * Angel sets this, but other bootloaders may not. 725 * 726 * This must precede any driver calls to BCR_set() or BCR_clear(). 727 */ 728 assabet_init_gpio((void *)&ASSABET_BCR, def_val); 729 } 730 731 MACHINE_START(ASSABET, "Intel-Assabet") 732 .atag_offset = 0x100, 733 .fixup = fixup_assabet, 734 .map_io = assabet_map_io, 735 .nr_irqs = SA1100_NR_IRQS, 736 .init_irq = assabet_init_irq, 737 .init_time = sa1100_timer_init, 738 .init_machine = assabet_init, 739 .init_late = sa11x0_init_late, 740 #ifdef CONFIG_SA1111 741 .dma_zone_size = SZ_1M, 742 #endif 743 .restart = sa11x0_restart, 744 MACHINE_END 745