fix-cpu-input-pulldowns.patch
[u-boot-openmoko/mini2440.git] / board / neo1973 / gta02 / gta02.c
blob66fcc704481efe2c21894c525ec2e9a8870a9a28
1 /*
2 * (C) 2006-2007 by OpenMoko, Inc.
3 * Author: Harald Welte <laforge@openmoko.org>
5 * based on existing S3C2410 startup code in u-boot:
7 * (C) Copyright 2002
8 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
9 * Marius Groeger <mgroeger@sysgo.de>
11 * (C) Copyright 2002
12 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
14 * See file CREDITS for list of people who contributed to this
15 * project.
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 * MA 02111-1307 USA
33 #include <common.h>
34 #include <s3c2440.h>
35 #include <i2c.h>
36 #include <bootmenu.h>
38 #include "../common/neo1973.h"
39 #include "../common/jbt6k74.h"
41 #include "pcf50633.h"
43 DECLARE_GLOBAL_DATA_PTR;
45 /* That many seconds the power key needs to be pressed to power up */
46 #define POWER_KEY_SECONDS 1
48 #if defined(CONFIG_ARCH_GTA02_v1)
49 //#define M_MDIV 0x7f /* Fout = 405.00MHz */
50 #define M_MDIV 0x7d /* Fout = 399.00MHz */
51 #define M_PDIV 0x2
52 #define M_SDIV 0x1
54 #define U_M_MDIV 0x38
55 #define U_M_PDIV 0x2
56 #define U_M_SDIV 0x2
57 #else
58 #define M_MDIV 42
59 #define M_PDIV 1
60 #define M_SDIV 0
61 #define U_M_MDIV 88
62 #define U_M_PDIV 4
63 #define U_M_SDIV 2
64 #endif
66 unsigned int neo1973_wakeup_cause;
67 extern unsigned char booted_from_nand;
68 extern unsigned char booted_from_nor;
69 extern int nobootdelay;
71 static inline void delay (unsigned long loops)
73 __asm__ volatile ("1:\n"
74 "subs %0, %1, #1\n"
75 "bne 1b":"=r" (loops):"0" (loops));
78 enum gta02_led {
79 GTA02_LED_PWR_ORANGE = 0,
80 GTA02_LED_PWR_BLUE = 1,
81 GTA02_LED_AUX_RED = 2,
85 * Miscellaneous platform dependent initialisations
88 int board_init(void)
90 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
91 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
93 /* to reduce PLL lock time, adjust the LOCKTIME register */
94 clk_power->LOCKTIME = 0xFFFFFF;
96 /* configure MPLL */
97 clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
99 /* some delay between MPLL and UPLL */
100 delay (4000);
102 /* configure UPLL */
103 clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
105 /* clock divide */
106 clk_power->CLKDIVN = 0x05; /* 1:4:8 */
108 /* some delay between MPLL and UPLL */
109 delay (8000);
111 /* set up the I/O ports */
112 #if CONFIG_GTA02_REVISION == 1
113 gpio->GPACON = 0x007E1FFF;
114 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
116 gpio->GPBCON = 0x00155555;
117 gpio->GPBUP = 0x000007FF;
119 gpio->GPCCON = 0x55551155;
120 gpio->GPCUP = 0x0000FFFF;
122 gpio->GPDCON = 0x55555555;
123 gpio->GPDUP = 0x0000FFFF;
125 gpio->GPECON = 0xAAAAAAAA;
126 gpio->GPEUP = 0x0000FFFF;
128 gpio->GPFCON = 0x0000AAAA;
129 gpio->GPFUP = 0x000000FF;
131 gpio->GPGCON = 0x013DFDFA;
132 gpio->GPGUP = 0x0000FFFF;
134 gpio->GPHCON = 0x0028AAAA;
135 gpio->GPHUP = 0x000007FF;
137 gpio->GPJCON = 0x1545541;
138 #elif CONFIG_GTA02_REVISION == 2
139 gpio->GPACON = 0x007E1FFF;
140 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
142 gpio->GPBCON = 0x00155555;
143 gpio->GPBUP = 0x000007FF;
145 gpio->GPCCON = 0x55415155;
146 gpio->GPCUP = 0x0000FFFF;
148 gpio->GPDCON = 0x55555555;
149 gpio->GPDUP = 0x0000FFFF;
151 gpio->GPECON = 0xAAAAAAAA;
152 gpio->GPEUP = 0x0000FFFF;
154 gpio->GPFCON = 0x0000AAAA;
155 gpio->GPFUP = 0x000000FF;
157 gpio->GPGCON = 0x0156FE7A;
158 gpio->GPGUP = 0x0000FFFF;
160 gpio->GPHCON = 0x001AAAAA;
161 gpio->GPHUP = 0x000007FF;
163 gpio->GPJCON = 0x1551544;
164 gpio->GPJUP = 0x1ffff;
165 gpio->GPJDAT |= (1 << 4); /* Set GPJ4 to high (nGSM_EN) */
166 #elif CONFIG_GTA02_REVISION >= 3
167 gpio->GPACON = 0x007E5FFF;
168 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
170 gpio->GPBCON = 0x00155555;
171 gpio->GPBUP = 0x000007FF;
173 /* pulldown on "PIO_5" BT module to stop float when unpowered */
174 gpio->GPCCON = 0x55555155;
175 gpio->GPCUP = 0x0000FFFF & ~(1 << 5);
177 gpio->GPDCON = 0x55555555;
178 gpio->GPDUP = 0x0000FFFF;
180 /* pulldown on GPE11 / SPIMISO0 - goes to debug board and will float */
181 gpio->GPECON = 0xAAAAAAAA;
182 gpio->GPEUP = 0x0000FFFF & ~(1 << 11);
184 /* pulldown on GPF03: TP-4705+debug - debug conn will float */
185 gpio->GPFCON = 0x0000AAAA;
186 gpio->GPFUP = 0x000000FF & ~(1 << 3);
188 gpio->GPGCON = 0x01AAFE79;
189 gpio->GPGUP = 0x0000FFFF;
191 /* pulldown on GPH08: UEXTCLK, just floats!
192 * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off
193 * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off
195 gpio->GPHCON = 0x001AAAAA;
196 gpio->GPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3);
198 /* pulldown on GPJ00: input, just floats! */
199 /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */
200 gpio->GPJCON = 0x1551544;
201 gpio->GPJUP = 0x1ffff & ~(1 << 0) & ~(1 << 7);
202 gpio->GPJDAT |= (1 << 4) | (1 << 6);
203 /* Set GPJ4 to high (nGSM_EN) */
204 /* Set GPJ6 to high (nDL_GSM) */
205 gpio->GPJDAT &= ~(1 << 5); /* Set GPJ5 to low 3D RST */
206 gpio->GPJDAT &= ~(1 << 5); /* Set GPJ5 to low 3D RST */
208 /* leaving Glamo forced to Reset# active here killed
209 * U-Boot when you touched the memory region
212 gpio->GPJDAT |= (1 << 5); /* Set GPJ5 to high 3D RST */
213 #else
214 #error Please define GTA02 version
215 #endif
217 /* arch number of SMDK2410-Board */
218 gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA02;
220 /* adress of boot parameters */
221 gd->bd->bi_boot_params = 0x30000100;
223 icache_enable();
224 dcache_enable();
227 * Since the NOR is replaced by SteppingStone when the AUX button is
228 * released, we have to wait for this and copy our exception vectors
229 * before we can let u-boot enable interrupts.
231 if (booted_from_nor) {
232 extern char _start;
234 while (neo1973_aux_key_pressed());
235 memcpy((void *) 0, &_start, 0x40);
238 return 0;
241 int board_late_init(void)
243 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
244 uint8_t int1, int2;
245 char buf[32];
246 int menu_vote = 0; /* <= 0: no, > 0: yes */
247 int seconds = 0;
249 /* Initialize the Power Management Unit with a safe register set */
250 pcf50633_init();
252 /* obtain wake-up reason */
253 int1 = pcf50633_reg_read(PCF50633_REG_INT1);
254 int2 = pcf50633_reg_read(PCF50633_REG_INT2);
256 /* switch on one of the power led's */
257 neo1973_led(GTA02_LED_PWR_ORANGE, 1);
259 /* issue a short pulse with the vibrator */
260 neo1973_vibrator(1);
261 udelay(20000);
262 neo1973_vibrator(0);
264 #if defined(CONFIG_ARCH_GTA02_v1)
265 /* Glamo3362 reset and power cycle */
266 gpio->GPJDAT &= ~0x000000001; /* GTA02v1_GPIO_3D_RESET */
267 pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0);
268 udelay(50*1000);
269 pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0x2);
270 gpio->GPJDAT |= 0x000000001; /* GTA02v1_GPIO_3D_RESET */
271 #endif
273 /* if there's no other reason, must be regular reset */
274 neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
276 if (!booted_from_nand && !booted_from_nor)
277 goto woken_by_reset;
279 /* save wake-up reason in environment */
280 sprintf(buf, "0x%02x", int1);
281 setenv("pcf50633_int1", buf);
282 sprintf(buf, "0x%02x", int2);
283 setenv("pcf50633_int2", buf);
285 if (int1 & PCF50633_INT1_ALARM) {
286 /* we've been woken up by RTC alarm, boot */
287 neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
288 goto continue_boot;
290 if (int1 & PCF50633_INT1_USBINS) {
291 /* we've been woken up by charger insert */
292 neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
295 if (int2 & PCF50633_INT2_ONKEYF) {
296 /* we've been woken up by a falling edge of the onkey */
297 neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
300 if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
301 /* if we still think it was only a charger insert, boot */
302 goto continue_boot;
305 woken_by_reset:
307 while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
308 neo1973_on_key_pressed()) {
309 if (neo1973_aux_key_pressed())
310 menu_vote++;
311 else
312 menu_vote--;
314 if (neo1973_new_second())
315 seconds++;
316 if (seconds >= POWER_KEY_SECONDS)
317 goto continue_boot;
319 /* Power off if minimum number of seconds not reached */
320 neo1973_poweroff();
322 continue_boot:
323 jbt6k74_init();
324 jbt6k74_enter_state(JBT_STATE_NORMAL);
325 jbt6k74_display_onoff(1);
327 #if 0
329 /* check if sd card is inserted, and power-up if it is */
330 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
331 if (!(gpio->GPFDAT & (1 << 5)))
332 gpio->GPBDAT &= ~(1 << 2);
334 #endif
336 if (menu_vote > 0 || booted_from_nor) {
337 extern struct bootmenu_setup bootmenu_setup;
339 if (booted_from_nand)
340 bootmenu_setup.comment = "NAND";
341 if (booted_from_nor)
342 bootmenu_setup.comment = "NOR";
343 neo1973_bootmenu();
344 nobootdelay = 1;
347 return 0;
350 int dram_init (void)
352 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
353 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
355 return 0;
358 u_int32_t get_board_rev(void)
360 return 0x300+0x10*CONFIG_GTA02_REVISION;
363 void neo1973_poweroff(void)
365 printf("poweroff\n");
366 udc_disconnect();
367 pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 0x01);
368 /* don't return to caller */
369 while (1) ;
372 void neo1973_backlight(int on)
374 if (on)
375 pcf50633_reg_write(PCF50633_REG_LEDENA, 0x01);
376 else
377 pcf50633_reg_write(PCF50633_REG_LEDENA, 0x00);
380 /* FIXME: shared */
381 void neo1973_vibrator(int on)
383 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
384 if (on)
385 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
386 gpio->GPGDAT |= (1 << 11); /* GPG11 */
387 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
388 gpio->GPBDAT |= (1 << 10); /* GPB10 */
389 #else
390 gpio->GPBDAT |= (1 << 3); /* GPB3 */
391 #endif
392 else
393 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
394 gpio->GPGDAT &= ~(1 << 11); /* GPG11 */
395 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
396 gpio->GPBDAT &= ~(1 << 10); /* GPB10 */
397 #else
398 gpio->GPBDAT &= ~(1 << 3); /* GPB3 */
399 #endif
402 void neo1973_gsm(int on)
404 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
406 /* GPIO2 of PMU, GPB7(MODEM_ON)=1 and GPB5(MODEM_RST)=0 */
407 if (on) {
408 #if !defined(CONFIG_ARCH_GTA02_v1)
409 pcf50633_reg_write(PCF50633_REG_GPIO2CFG, 0x07);
410 #endif
411 gpio->GPBDAT &= ~(1 << 5); /* GTA02_GPIO_MODEM_RST */
412 gpio->GPBDAT |= (1 << 7); /* GTA02_GPIO_MODEM_ON */
413 gpio->GPJDAT &= ~(1 << 6); /* GTA02_GPIO_nDL_GSM */
414 } else {
415 gpio->GPBDAT &= ~(1 << 7); /* GTA02_GPIO_MODEM_ON */
416 #if !defined(CONFIG_ARCH_GTA02_v1)
417 pcf50633_reg_write(PCF50633_REG_GPIO2CFG, 0x00);
418 #endif
419 gpio->GPJDAT |= (1 << 6); /* GTA02_GPIO_nDL_GSM */
423 void neo1973_gps(int on)
425 if (on)
426 pcf50633_reg_write(PCF50633_REG_LDO5ENA, 0x01);
427 else
428 pcf50633_reg_write(PCF50633_REG_LDO5ENA, 0x00);
431 static int pwr_int_pending(void)
433 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
435 return !(gpio->GPGDAT & (1 << 1)); /* EINT9/GPG1 */
438 static int have_int(uint8_t mask1, uint8_t mask2)
440 static uint8_t pending1 = 0, pending2 = 0;
442 if (pwr_int_pending()) {
444 * We retrieve all interupts, so that we clear any stray ones
445 * in INT2 and INT3.
447 uint8_t ints[5];
448 int i;
450 for (i = 0; i != 5; i++)
451 ints[i] = pcf50633_reg_read(PCF50633_REG_INT1+i);
452 pending1 |= ints[0];
453 pending2 |= ints[1];
455 if (pending1 & mask1) {
456 pending1 &= ~mask1;
457 return 1;
459 if (pending2 & mask2) {
460 pending1 &= ~mask2;
461 return 1;
463 return 0;
466 int neo1973_new_second(void)
468 return have_int(PCF50633_INT1_SECOND, 0);
471 int neo1973_on_key_pressed(void)
473 static int pressed = -1;
475 if (pressed == -1 ||
476 have_int(0, PCF50633_INT2_ONKEYF | PCF50633_INT2_ONKEYR))
477 pressed = !(pcf50633_reg_read(PCF50633_REG_OOCSTAT) &
478 PCF50633_OOCSTAT_ONKEY);
479 return pressed;
482 int neo1973_aux_key_pressed(void)
484 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
486 return !!(gpio->GPFDAT & (1 << 6));
489 /* The sum of all part_size[]s must equal to or greater than the NAND size,
490 i.e., 0x10000000. */
492 unsigned int dynpart_size[] = {
493 CFG_UBOOT_SIZE, CFG_ENV_SIZE, 0x800000, 0xa0000, 0x40000, 0x10000000, 0 };
494 char *dynpart_names[] = {
495 "u-boot", "u-boot_env", "kernel", "splash", "factory", "rootfs", NULL };
498 const char *neo1973_get_charge_status(void)
500 /* FIXME */
501 return pcf50633_charger_state();
504 int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
506 /* FIXME */
507 puts("not implemented yet\n");
508 return -1;
511 void neo1973_led(int led, int on)
513 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
515 printf("switching led %u %u\n", led, on);
516 if (led > 2)
517 return;
519 if (on)
520 gpio->GPBDAT |= (1 << led);
521 else
522 gpio->GPBDAT &= ~(1 << led);