Modified patch originates from Andy Green <andy@openmoko.com>
[u-boot-openmoko/mini2440.git] / board / neo1973 / gta01 / gta01.c
blob095f0800b66ed3efc58a3907f2488875e439adc0
1 /*
2 * (C) 2006 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 <devices.h>
35 #include <s3c2410.h>
36 #include <i2c.h>
38 #include "pcf50606.h"
40 #include "../common/neo1973.h"
41 #include "../common/jbt6k74.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 2
48 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
49 //#define M_MDIV 0xA1 /* Fout = 202.8MHz */
50 //#define M_PDIV 0x3
51 //#define M_SDIV 0x1
52 #define M_MDIV 0x90 /* Fout = 202.8MHz */
53 #define M_PDIV 0x7
54 #define M_SDIV 0x0
55 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
56 /* In case the debug board is attached, we cannot go beyond 200 MHz */
57 #if 0
58 #define M_MDIV 0x7d /* Fout = 266MHz */
59 #define M_PDIV 0x1
60 #define M_SDIV 0x1
61 #else
62 #define M_MDIV 0x90 /* Fout = 202.8MHz */
63 #define M_PDIV 0x7
64 #define M_SDIV 0x0
65 #endif
66 #elif defined(CONFIG_ARCH_GTA01B_v4)
67 /* This board doesn't have bus lines at teh debug port, and we can go to 266 */
68 #define M_MDIV 0x7d /* Fout = 266MHz */
69 #define M_PDIV 0x1
70 #define M_SDIV 0x1
71 #else
72 #error Please define GTA01 revision
73 #endif
75 #define U_M_MDIV 0x78
76 #define U_M_PDIV 0x2
77 #define U_M_SDIV 0x3
79 unsigned int neo1973_wakeup_cause;
80 extern int nobootdelay;
82 static inline void delay (unsigned long loops)
84 __asm__ volatile ("1:\n"
85 "subs %0, %1, #1\n"
86 "bne 1b":"=r" (loops):"0" (loops));
90 * Miscellaneous platform dependent initialisations
93 int board_init (void)
95 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
96 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
98 /* to reduce PLL lock time, adjust the LOCKTIME register */
99 clk_power->LOCKTIME = 0xFFFFFF;
101 /* configure MPLL */
102 clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
104 /* some delay between MPLL and UPLL */
105 delay (4000);
107 /* configure UPLL */
108 clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
110 /* some delay between MPLL and UPLL */
111 delay (8000);
113 /* set up the I/O ports */
114 #if defined(CONFIG_ARCH_GTA01_v3)
115 gpio->GPACON = 0x007FFFFF;
117 gpio->GPBCON = 0x00005055;
118 gpio->GPBUP = 0x000007FF;
120 gpio->GPCCON = 0xAAAA12A8;
121 gpio->GPCUP = 0x0000FFFF;
123 gpio->GPDCON = 0xAAAAAAAA;
124 gpio->GPDUP = 0x0000FFFF;
126 gpio->GPECON = 0xAAAAAAAA;
127 gpio->GPEUP = 0x0000FFFF;
129 gpio->GPFCON = 0x00002AA9;
130 gpio->GPFUP = 0x000000FF;
132 gpio->GPGCON = 0xA846F0C0;
133 gpio->GPGUP = 0x0000AFEF;
135 gpio->GPHCON = 0x0008FAAA;
136 gpio->GPHUP = 0x000007FF;
137 #elif defined(CONFIG_ARCH_GTA01_v4)
138 gpio->GPACON = 0x005E47FF;
140 gpio->GPBCON = 0x00045015;
141 gpio->GPBUP = 0x000007FF;
142 gpio->GPBDAT |= 0x4; /* Set GPB2 to high (Flash power-up) */
144 gpio->GPCCON = 0xAAAA12A9;
145 gpio->GPCUP = 0x0000FFFF;
147 gpio->GPDCON = 0xAAAAAAAA;
148 gpio->GPDUP = 0x0000FFFF;
150 gpio->GPECON = 0xA02AAAAA;
151 gpio->GPEUP = 0x0000FFFF;
153 gpio->GPFCON = 0x0000aa09;
154 gpio->GPFUP = 0x000000FF;
156 gpio->GPGCON = 0xFF40F0C1;
157 gpio->GPGUP = 0x0000AFEF;
159 gpio->GPHCON = 0x0000FAAA;
160 gpio->GPHUP = 0x000007FF;
161 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
162 gpio->GPACON = 0x005E4FFF;
164 gpio->GPBCON = 0x00145415;
165 gpio->GPBUP = 0x000007FF;
166 gpio->GPBDAT |= 0x4; /* Set GPB2 to high (Flash power-up) */
168 gpio->GPCCON = 0xAAAA12A9;
169 gpio->GPCUP = 0x0000FFFF;
171 gpio->GPDCON = 0xAAAAAAAA;
172 gpio->GPDUP = 0x0000FFFF;
174 gpio->GPECON = 0xA02AAAAA;
175 gpio->GPEUP = 0x0000FFFF;
177 gpio->GPFCON = 0x0000aa19;
178 gpio->GPFUP = 0x000000FF;
179 gpio->GPFDAT |= 0x4; /* Set GBF2 to high (nGSM_EN) */
181 gpio->GPGCON = 0xFF40F0C1;
182 gpio->GPGUP = 0x0000AFEF;
184 gpio->GPHCON = 0x0000FAAA;
185 gpio->GPHUP = 0x000007FF;
186 #elif defined(CONFIG_ARCH_GTA01B_v4)
187 gpio->GPACON = 0x0005E0FFF;
188 gpio->GPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */
190 gpio->GPBCON = 0x00045455;
191 gpio->GPBUP = 0x000007FF;
192 gpio->GPBDAT |= 0x4; /* Set GPB2 to high (SD power down) */
194 gpio->GPCCON = 0xAAAA12A9;
195 gpio->GPCUP = 0x0000FFFF;
197 gpio->GPDCON = 0xAAAAAAAA;
198 gpio->GPDUP = 0x0000FFFF;
200 gpio->GPECON = 0xAAAAAAAA;
201 gpio->GPEUP = 0x0000FFFF;
203 gpio->GPFCON = 0x0000aa99;
204 gpio->GPFUP = 0x000000FF;
205 gpio->GPFDAT |= 0x4; /* Set GBF2 to high (nGSM_EN) */
207 gpio->GPGCON = 0xFF14F0F8;
208 gpio->GPGUP = 0x0000AFEF;
210 gpio->GPHCON = 0x0000FAAA;
211 gpio->GPHUP = 0x000007FF;
212 #else
213 #error Please define GTA01 version
214 #endif
216 /* arch number of SMDK2410-Board */
217 gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA01;
219 /* adress of boot parameters */
220 gd->bd->bi_boot_params = 0x30000100;
222 icache_enable();
223 dcache_enable();
225 return 0;
228 int board_late_init(void)
230 extern unsigned char booted_from_nand;
231 unsigned char tmp;
232 char buf[32];
233 int menu_vote = 0; /* <= 0: no, > 0: yes */
234 int seconds = 0;
236 /* Initialize the Power Management Unit with a safe register set */
237 pcf50606_init();
239 /* if there's no other reason, must be regular reset */
240 neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
242 if (!booted_from_nand)
243 goto woken_by_reset;
245 /* obtain wake-up reason, save INT1 in environment */
246 tmp = pcf50606_reg_read(PCF50606_REG_INT1);
247 sprintf(buf, "0x%02x", tmp);
248 setenv("pcf50606_int1", buf);
250 if (tmp & PCF50606_INT1_ALARM) {
251 /* we've been woken up by RTC alarm, boot */
252 neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
253 goto continue_boot;
255 if (tmp & PCF50606_INT1_EXTONR) {
256 /* we've been woken up by charger insert */
257 neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
260 if (tmp & PCF50606_INT1_ONKEYF) {
261 /* we've been woken up by a falling edge of the onkey */
262 neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
265 if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
266 /* if we still think it was only a charger insert, boot */
267 goto continue_boot;
270 woken_by_reset:
272 while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
273 neo1973_on_key_pressed()) {
274 if (neo1973_aux_key_pressed())
275 menu_vote++;
276 else
277 menu_vote--;
279 if (neo1973_new_second())
280 seconds++;
281 if (seconds >= POWER_KEY_SECONDS)
282 goto continue_boot;
284 /* Power off if minimum number of seconds not reached */
285 neo1973_poweroff();
287 continue_boot:
288 jbt6k74_init();
289 jbt6k74_enter_state(JBT_STATE_NORMAL);
290 jbt6k74_display_onoff(1);
292 /* issue a short pulse with the vibrator */
293 neo1973_vibrator(1);
294 udelay(50000);
295 neo1973_vibrator(0);
297 /* switch on the backlight */
298 neo1973_backlight(1);
300 #if defined(CONFIG_ARCH_GTA01B_v4)
302 /* check if sd card is inserted, and power-up if it is */
303 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
304 if (!(gpio->GPFDAT & (1 << 5)))
305 gpio->GPBDAT &= ~(1 << 2);
307 #endif
309 if (menu_vote > 0) {
310 neo1973_bootmenu();
311 nobootdelay = 1;
314 return 0;
317 int dram_init (void)
319 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
320 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
322 return 0;
325 u_int32_t get_board_rev(void)
327 #if defined(CONFIG_ARCH_GTA01_v3)
328 return 0x00000130;
329 #elif defined(CONFIG_ARCH_GTA01_v4)
330 return 0x00000140;
331 #elif defined(CONFIG_ARCH_GTA01B_v2)
332 return 0x00000220;
333 #elif defined(CONFIG_ARCH_GTA01B_v3)
334 return 0x00000230;
335 #elif defined(CONFIG_ARCH_GTA01B_v4)
336 return 0x00000240;
337 #endif
340 void neo1973_poweroff(void)
342 serial_printf("poweroff\n");
343 udc_disconnect();
344 pcf50606_reg_write(PCF50606_REG_OOCC1, PCF50606_OOCC1_GOSTDBY);
345 /* don't return to caller */
346 while (1) ;
349 void neo1973_backlight(int on)
351 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
352 if (on)
353 gpio->GPBDAT |= 0x01;
354 else
355 gpio->GPBDAT &= ~0x01;
358 void neo1973_vibrator(int on)
360 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
361 if (on)
362 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
363 gpio->GPGDAT |= (1 << 11); /* GPG11 */
364 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
365 gpio->GPBDAT |= (1 << 10); /* GPB10 */
366 #elif defined(CONFIG_ARCH_GTA01B_v4)
367 gpio->GPBDAT |= (1 << 3); /* GPB3 */
368 #endif
369 else
370 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
371 gpio->GPGDAT &= ~(1 << 11); /* GPG11 */
372 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
373 gpio->GPBDAT &= ~(1 << 10); /* GPB10 */
374 #elif defined(CONFIG_ARCH_GTA01B_v4)
375 gpio->GPBDAT &= ~(1 << 3); /* GPB3 */
376 #endif
379 /* switch serial port 0 multiplexer */
380 void neo1973_gta01_serial0_gsm(int on)
382 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
383 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(0);
384 int i;
386 if (on) {
387 for (i = 0; i < 3; i++) {
388 if (!strcmp(stdio_devices[i]->name, "serial") ||
389 !strcmp(stdio_devices[i]->name, "s3ser0")) {
390 puts("ERROR: serial port busy, can't enable GSM!\n");
391 return;
394 puts("switching s3ser0 from console into GSM mode\n");
395 uart->UMCON |= 0x10; /* Hardware flow control */
396 gpio->GPFDAT &= ~(1 << 2); /* GPF2: nGSM_EN */
397 } else {
398 gpio->GPFDAT |= (1 << 2); /* GPF2: nGSM_EN */
399 uart->UMCON &= ~0x10; /* No Hardware flow control */
400 puts("switched s3ser0 from GSM mode back into console mode\n");
404 /* switch gsm power on/off */
405 void neo1973_gsm(int on)
407 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
408 device_t *dev = search_device(DEV_FLAGS_INPUT, "s3ser0");
409 if (!dev) {
410 puts("can't find s3ser0 device ?!?\n");
411 return;
414 if (on) {
415 gpio->GPBDAT &= ~(1 << 6); /* GPB6: MODEM_RST */
416 gpio->GPBDAT |= (1 << 7); /* GPB7: MODEM_ON */
417 } else {
418 /* unfortunately switching the modem off is not that easy.
419 * Ti's firmware is insisting on not switching off... */
420 gpio->GPBDAT &= ~(1 << 7); /* GPB7: MODEM_ON */
421 //gpio->GPBDAT |= (1 << 6); /* GPB6: MODEM_RST */
422 if (!(gpio->GPFDAT & (1 << 2)))
423 puts("Can't power modem off while serial console "
424 "in use!\n");
425 else {
426 S3C24X0_UART * const uart = S3C24X0_GetBase_UART(0);
427 uart->UMCON |= 0x10; /* Hardware flow control */
428 gpio->GPFDAT &= ~(1 << 2); /* GPF2: nGSM_EN */
429 dev->puts("AT@POFF\r\n");
430 gpio->GPFDAT |= (1 << 2); /* GPF2: nGSM_EN */
431 uart->UMCON &= ~0x10; /* No Hardware flow control */
436 /* switch gps power on/off */
437 void neo1973_gps(int on)
439 printf("not implemented yet!\n");
442 static int pwr_int_pending(void)
444 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
446 #if defined(CONFIG_ARCH_GTA01B_v4)
447 return !(gpio->GPGDAT & (1 << 1)); /* EINT9/GPG1 */
448 #else
449 return !(gpio->GPGDAT & (1 << 8)); /* EINT16/GPG8 */
450 #endif /* !CONFIG_ARCH_GTA01B_v4 */
453 static int have_int1(uint8_t mask)
455 static uint8_t pending = 0;
457 if (pwr_int_pending()) {
459 * We retrieve all interupts, so that we clear any stray ones
460 * in INT2 and INT3.
462 uint8_t int1,int2,int3;
464 int1 = pcf50606_reg_read(PCF50606_REG_INT1);
465 int2 = pcf50606_reg_read(PCF50606_REG_INT2);
466 int3 = pcf50606_reg_read(PCF50606_REG_INT3);
467 pending |= int1;
469 if (!(pending & mask))
470 return 0;
471 pending &= ~mask;
472 return 1;
475 int neo1973_new_second(void)
477 return have_int1(PCF50606_INT1_SECOND);
480 int neo1973_on_key_pressed(void)
482 static int pressed = -1;
484 if (pressed == -1 ||
485 have_int1(PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) {
486 pressed = !(pcf50606_reg_read(PCF50606_REG_OOCS) &
487 PFC50606_OOCS_ONKEY);
489 return pressed;
492 int neo1973_aux_key_pressed(void)
494 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
496 if (gpio->GPFDAT & (1 << 6))
497 return 0;
498 return 1;
501 static const char *chgstate_names[] = {
502 [PCF50606_MBCC1_CHGMOD_QUAL] = "qualification",
503 [PCF50606_MBCC1_CHGMOD_PRE] = "pre",
504 [PCF50606_MBCC1_CHGMOD_TRICKLE] = "trickle",
505 [PCF50606_MBCC1_CHGMOD_FAST_CCCV] = "fast_cccv",
506 [PCF50606_MBCC1_CHGMOD_FAST_NOCC] = "fast_nocc",
507 [PCF50606_MBCC1_CHGMOD_FAST_NOCV] = "fast_nocv",
508 [PCF50606_MBCC1_CHGMOD_FAST_SW] = "fast_switch",
509 [PCF50606_MBCC1_CHGMOD_IDLE] = "idle",
512 const char *neo1973_get_charge_status(void)
514 u_int8_t mbcc1 = pcf50606_reg_read(PCF50606_REG_MBCC1);
515 u_int8_t chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
516 return chgstate_names[chgmod];
519 int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
521 switch (cmd) {
522 case NEO1973_CHGCMD_NONE:
523 break;
524 case NEO1973_CHGCMD_AUTOFAST:
525 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
526 PCF50606_MBCC1_AUTOFST,
527 PCF50606_MBCC1_AUTOFST);
528 break;
529 case NEO1973_CHGCMD_NO_AUTOFAST:
530 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
531 PCF50606_MBCC1_AUTOFST, 0);
532 break;
533 case NEO1973_CHGCMD_OFF:
534 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
535 PCF50606_MBCC1_CHGMOD_MASK,
536 PCF50606_MBCC1_CHGMOD_IDLE);
537 break;
539 case NEO1973_CHGCMD_FAST:
540 case NEO1973_CHGCMD_FASTER:
541 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
542 PCF50606_MBCC1_CHGMOD_MASK,
543 PCF50606_MBCC1_CHGMOD_FAST_CCCV);
544 break;
546 return 0;
549 void neo1973_led(int led, int on)
551 printf("No LED's in this Neo1973 hardware revision\n");
556 /* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
557 "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
558 images: 640*480*2*2 = 1228800 < 1245184. */
560 unsigned int dynpart_size[] = {
561 CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
562 char *dynpart_names[] = {
563 "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };