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 */
ASSABET_BCR_frob(unsigned int mask,unsigned int val)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
assabet_init_gpio(void __iomem * reg,u32 def_val)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
adv7171_start(void)119 static void adv7171_start(void)
120 {
121 GPSR = SCK;
122 udelay(1);
123 GPSR = SDA;
124 udelay(2);
125 GPCR = SDA;
126 }
127
adv7171_stop(void)128 static void adv7171_stop(void)
129 {
130 GPSR = SCK;
131 udelay(2);
132 GPSR = SDA;
133 udelay(1);
134 }
135
adv7171_send(unsigned byte)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
adv7171_write(unsigned reg,unsigned val)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
adv7171_sleep(void)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
assabet_codec_reset(unsigned mask,int set)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
assabet_ucb1x00_reset(enum ucb1x00_reset state)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
assabet_uda1341_reset(int set)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
assabet_lcd_set_visual(u32 visual)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
assabet_lcd_backlight_power(int on)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 */
assabet_lcd_power(int on)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
assabet_pal_backlight_power(int on)377 static void assabet_pal_backlight_power(int on)
378 {
379 ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
380 }
381
assabet_pal_power(int on)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
assabet_init(void)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 */
map_sa1100_gpio_regs(void)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 */
get_assabet_scr(void)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
fixup_assabet(struct tag * tags,char ** cmdline)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
assabet_uart_pm(struct uart_port * port,u_int state,u_int oldstate)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
assabet_map_io(void)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
assabet_init_irq(void)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