gta01.c

浏览该文件的文档。
00001 /*
00002  * (C) 2006 by OpenMoko, Inc.
00003  * Author: Harald Welte <laforge@openmoko.org>
00004  *
00005  * based on existing S3C2410 startup code in u-boot:
00006  *
00007  * (C) Copyright 2002
00008  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
00009  * Marius Groeger <mgroeger@sysgo.de>
00010  *
00011  * (C) Copyright 2002
00012  * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
00013  *
00014  * See file CREDITS for list of people who contributed to this
00015  * project.
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of
00020  * the License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful,
00023  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025  * GNU General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00030  * MA 02111-1307 USA
00031  */
00032 
00033 #include <common.h>
00034 #include <devices.h>
00035 #include <s3c2410.h>
00036 #include <i2c.h>
00037 
00038 #include "pcf50606.h"
00039 
00040 #include "../common/neo1973.h"
00041 #include "../common/jbt6k74.h"
00042 
00043 DECLARE_GLOBAL_DATA_PTR;
00044 
00045 /* That many seconds the power key needs to be pressed to power up */
00046 #define POWER_KEY_SECONDS       2
00047 
00048 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
00049 //#define M_MDIV        0xA1            /* Fout = 202.8MHz */
00050 //#define M_PDIV        0x3
00051 //#define M_SDIV        0x1
00052 #define M_MDIV  0x90            /* Fout = 202.8MHz */
00053 #define M_PDIV  0x7
00054 #define M_SDIV  0x0
00055 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
00056 /* In case the debug board is attached, we cannot go beyond 200 MHz */
00057 #if 0
00058 #define M_MDIV  0x7d            /* Fout = 266MHz */
00059 #define M_PDIV  0x1
00060 #define M_SDIV  0x1
00061 #else
00062 #define M_MDIV  0x90            /* Fout = 202.8MHz */
00063 #define M_PDIV  0x7
00064 #define M_SDIV  0x0
00065 #endif
00066 #elif defined(CONFIG_ARCH_GTA01B_v4)
00067 /* This board doesn't have bus lines at teh debug port, and we can go to 266 */
00068 #define M_MDIV  0x7d            /* Fout = 266MHz */
00069 #define M_PDIV  0x1
00070 #define M_SDIV  0x1
00071 #else
00072 #error Please define GTA01 revision
00073 #endif
00074 
00075 #define U_M_MDIV        0x78
00076 #define U_M_PDIV        0x2
00077 #define U_M_SDIV        0x3
00078 
00079 unsigned int neo1973_wakeup_cause;
00080 extern int nobootdelay;
00081 
00082 static inline void delay (unsigned long loops)
00083 {
00084         __asm__ volatile ("1:\n"
00085           "subs %0, %1, #1\n"
00086           "bne 1b":"=r" (loops):"0" (loops));
00087 }
00088 
00089 /*
00090  * Miscellaneous platform dependent initialisations
00091  */
00092 
00093 int board_init (void)
00094 {
00095         S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
00096         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00097 
00098         /* to reduce PLL lock time, adjust the LOCKTIME register */
00099         clk_power->LOCKTIME = 0xFFFFFF;
00100 
00101         /* configure MPLL */
00102         clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
00103 
00104         /* some delay between MPLL and UPLL */
00105         delay (4000);
00106 
00107         /* configure UPLL */
00108         clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
00109 
00110         /* some delay between MPLL and UPLL */
00111         delay (8000);
00112 
00113         /* set up the I/O ports */
00114 #if defined(CONFIG_ARCH_GTA01_v3)
00115         gpio->GPACON = 0x007FFFFF;
00116 
00117         gpio->GPBCON = 0x00005055;
00118         gpio->GPBUP = 0x000007FF;
00119 
00120         gpio->GPCCON = 0xAAAA12A8;
00121         gpio->GPCUP = 0x0000FFFF;
00122 
00123         gpio->GPDCON = 0xAAAAAAAA;
00124         gpio->GPDUP = 0x0000FFFF;
00125 
00126         gpio->GPECON = 0xAAAAAAAA;
00127         gpio->GPEUP = 0x0000FFFF;
00128 
00129         gpio->GPFCON = 0x00002AA9;
00130         gpio->GPFUP = 0x000000FF;
00131 
00132         gpio->GPGCON = 0xA846F0C0;
00133         gpio->GPGUP = 0x0000AFEF;
00134 
00135         gpio->GPHCON = 0x0008FAAA;
00136         gpio->GPHUP = 0x000007FF;
00137 #elif defined(CONFIG_ARCH_GTA01_v4)
00138         gpio->GPACON = 0x005E47FF;
00139 
00140         gpio->GPBCON = 0x00045015;
00141         gpio->GPBUP = 0x000007FF;
00142         gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (Flash power-up) */
00143 
00144         gpio->GPCCON = 0xAAAA12A9;
00145         gpio->GPCUP = 0x0000FFFF;
00146 
00147         gpio->GPDCON = 0xAAAAAAAA;
00148         gpio->GPDUP = 0x0000FFFF;
00149 
00150         gpio->GPECON = 0xA02AAAAA;
00151         gpio->GPEUP = 0x0000FFFF;
00152 
00153         gpio->GPFCON = 0x0000aa09;
00154         gpio->GPFUP = 0x000000FF;
00155 
00156         gpio->GPGCON = 0xFF40F0C1;
00157         gpio->GPGUP = 0x0000AFEF;
00158 
00159         gpio->GPHCON = 0x0000FAAA;
00160         gpio->GPHUP = 0x000007FF;
00161 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
00162         gpio->GPACON = 0x005E4FFF;
00163 
00164         gpio->GPBCON = 0x00145415;
00165         gpio->GPBUP = 0x000007FF;
00166         gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (Flash power-up) */
00167 
00168         gpio->GPCCON = 0xAAAA12A9;
00169         gpio->GPCUP = 0x0000FFFF;
00170 
00171         gpio->GPDCON = 0xAAAAAAAA;
00172         gpio->GPDUP = 0x0000FFFF;
00173 
00174         gpio->GPECON = 0xA02AAAAA;
00175         gpio->GPEUP = 0x0000FFFF;
00176 
00177         gpio->GPFCON = 0x0000aa19;
00178         gpio->GPFUP = 0x000000FF;
00179         gpio->GPFDAT |= 0x4;            /* Set GBF2 to high (nGSM_EN) */
00180 
00181         gpio->GPGCON = 0xFF40F0C1;
00182         gpio->GPGUP = 0x0000AFEF;
00183 
00184         gpio->GPHCON = 0x0000FAAA;
00185         gpio->GPHUP = 0x000007FF;
00186 #elif defined(CONFIG_ARCH_GTA01B_v4)
00187         gpio->GPACON = 0x0005E0FFF;
00188         gpio->GPADAT |= (1 << 16);      /* Set GPA16 to high (nNAND_WP) */
00189 
00190         gpio->GPBCON = 0x00045455;
00191         gpio->GPBUP = 0x000007FF;
00192         gpio->GPBDAT |= 0x4;            /* Set GPB2 to high (SD power down) */
00193 
00194         gpio->GPCCON = 0xAAAA12A9;
00195         gpio->GPCUP = 0x0000FFFF;
00196 
00197         gpio->GPDCON = 0xAAAAAAAA;
00198         gpio->GPDUP = 0x0000FFFF;
00199 
00200         gpio->GPECON = 0xAAAAAAAA;
00201         gpio->GPEUP = 0x0000FFFF;
00202 
00203         gpio->GPFCON = 0x0000aa99;
00204         gpio->GPFUP = 0x000000FF;
00205         gpio->GPFDAT |= 0x4;            /* Set GBF2 to high (nGSM_EN) */
00206 
00207         gpio->GPGCON = 0xFF14F0F8;
00208         gpio->GPGUP = 0x0000AFEF;
00209 
00210         gpio->GPHCON = 0x0000FAAA;
00211         gpio->GPHUP = 0x000007FF;
00212 #else
00213 #error Please define GTA01 version
00214 #endif
00215 
00216         /* arch number of SMDK2410-Board */
00217         gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA01;
00218 
00219         /* adress of boot parameters */
00220         gd->bd->bi_boot_params = 0x30000100;
00221 
00222         icache_enable();
00223         dcache_enable();
00224 
00225         return 0;
00226 }
00227 
00228 int board_late_init(void)
00229 {
00230         extern unsigned char booted_from_nand;
00231         unsigned char tmp;
00232         char buf[32];
00233         int menu_vote = 0; /* <= 0: no, > 0: yes */
00234         int seconds = 0;
00235 
00236         /* Initialize the Power Management Unit with a safe register set */
00237         pcf50606_init();
00238 
00239         /* if there's no other reason, must be regular reset */
00240         neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
00241 
00242         if (!booted_from_nand)
00243                 goto woken_by_reset;
00244 
00245         /* obtain wake-up reason, save INT1 in environment */
00246         tmp = pcf50606_reg_read(PCF50606_REG_INT1);
00247         sprintf(buf, "0x%02x", tmp);
00248         setenv("pcf50606_int1", buf);
00249 
00250         if (tmp & PCF50606_INT1_ALARM) {
00251                 /* we've been woken up by RTC alarm, boot */
00252                 neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
00253                 goto continue_boot;
00254         }
00255         if (tmp & PCF50606_INT1_EXTONR) {
00256                 /* we've been woken up by charger insert */
00257                 neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
00258         }
00259 
00260         if (tmp & PCF50606_INT1_ONKEYF) {
00261                 /* we've been woken up by a falling edge of the onkey */
00262                 neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
00263         }
00264 
00265         if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
00266                 /* if we still think it was only a charger insert, boot */
00267                 goto continue_boot;
00268         }
00269 
00270 woken_by_reset:
00271 
00272         while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
00273             neo1973_on_key_pressed()) {
00274                 if (neo1973_aux_key_pressed())
00275                         menu_vote++;
00276                 else
00277                         menu_vote--;
00278 
00279                 if (neo1973_new_second())
00280                         seconds++;
00281                 if (seconds >= POWER_KEY_SECONDS)
00282                         goto continue_boot;
00283         }
00284         /* Power off if minimum number of seconds not reached */
00285         neo1973_poweroff();
00286 
00287 continue_boot:
00288         jbt6k74_init();
00289         jbt6k74_enter_state(JBT_STATE_NORMAL);
00290         jbt6k74_display_onoff(1);
00291 
00292         /* issue a short pulse with the vibrator */
00293         neo1973_vibrator(1);
00294         udelay(50000);
00295         neo1973_vibrator(0);
00296 
00297         /* switch on the backlight */
00298         neo1973_backlight(1);
00299 
00300 #if defined(CONFIG_ARCH_GTA01B_v4)
00301         {
00302                 /* check if sd card is inserted, and power-up if it is */
00303                 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00304                 if (!(gpio->GPFDAT & (1 << 5)))
00305                         gpio->GPBDAT &= ~(1 << 2);
00306         }
00307 #endif
00308 
00309         if (menu_vote > 0) {
00310                 neo1973_bootmenu();
00311                 nobootdelay = 1;
00312         }
00313 
00314         return 0;
00315 }
00316 
00317 int dram_init (void)
00318 {
00319         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
00320         gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
00321 
00322         return 0;
00323 }
00324 
00325 u_int32_t get_board_rev(void)
00326 {
00327 #if defined(CONFIG_ARCH_GTA01_v3)
00328         return 0x00000130;
00329 #elif defined(CONFIG_ARCH_GTA01_v4)
00330         return 0x00000140;
00331 #elif defined(CONFIG_ARCH_GTA01B_v2)
00332         return 0x00000220;
00333 #elif defined(CONFIG_ARCH_GTA01B_v3)
00334         return 0x00000230;
00335 #elif defined(CONFIG_ARCH_GTA01B_v4)
00336         return 0x00000240;
00337 #endif
00338 }
00339 
00340 void neo1973_poweroff(void)
00341 {
00342         serial_printf("poweroff\n");
00343         udc_disconnect();
00344         pcf50606_reg_write(PCF50606_REG_OOCC1, PCF50606_OOCC1_GOSTDBY);
00345         /* don't return to caller */
00346         while (1) ;
00347 }
00348 
00349 void neo1973_backlight(int on)
00350 {
00351         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00352         if (on)
00353                 gpio->GPBDAT |= 0x01;
00354         else
00355                 gpio->GPBDAT &= ~0x01;
00356 }
00357 
00358 void neo1973_vibrator(int on)
00359 {
00360         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00361         if (on)
00362 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
00363                 gpio->GPGDAT |= (1 << 11);      /* GPG11 */
00364 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
00365                 gpio->GPBDAT |= (1 << 10);      /* GPB10 */
00366 #elif defined(CONFIG_ARCH_GTA01B_v4)
00367                 gpio->GPBDAT |= (1 << 3);       /* GPB3 */
00368 #endif
00369         else
00370 #if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4)
00371                 gpio->GPGDAT &= ~(1 << 11);     /* GPG11 */
00372 #elif defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
00373                 gpio->GPBDAT &= ~(1 << 10);     /* GPB10 */
00374 #elif defined(CONFIG_ARCH_GTA01B_v4)
00375                 gpio->GPBDAT &= ~(1 << 3);      /* GPB3 */
00376 #endif
00377 }
00378 
00379 /* switch serial port 0 multiplexer */
00380 void neo1973_gta01_serial0_gsm(int on)
00381 {
00382         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00383         S3C24X0_UART * const uart = S3C24X0_GetBase_UART(0);
00384         int i;
00385 
00386         if (on) {
00387                 for (i = 0; i < 3; i++) {
00388                         if (!strcmp(stdio_devices[i]->name, "serial") ||
00389                             !strcmp(stdio_devices[i]->name, "s3ser0")) {
00390                                 puts("ERROR: serial port busy, can't enable GSM!\n");
00391                                 return;
00392                         }
00393                 }
00394                 puts("switching s3ser0 from console into GSM mode\n");
00395                 uart->UMCON |= 0x10;            /* Hardware flow control */
00396                 gpio->GPFDAT &= ~(1 << 2);      /* GPF2: nGSM_EN */
00397         } else {
00398                 gpio->GPFDAT |= (1 << 2);       /* GPF2: nGSM_EN */
00399                 uart->UMCON &= ~0x10;           /* No Hardware flow control */
00400                 puts("switched s3ser0 from GSM mode back into console mode\n");
00401         }
00402 }
00403 
00404 /* switch gsm power on/off */
00405 void neo1973_gsm(int on)
00406 {
00407         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00408         device_t *dev = search_device(DEV_FLAGS_INPUT, "s3ser0");
00409         if (!dev) {
00410                 puts("can't find s3ser0 device ?!?\n");
00411                 return;
00412         }
00413 
00414         if (on) {
00415                 gpio->GPBDAT &= ~(1 << 6);      /* GPB6: MODEM_RST */
00416                 gpio->GPBDAT |= (1 << 7);       /* GPB7: MODEM_ON */
00417         } else {
00418                 /* unfortunately switching the modem off is not that easy.
00419                  * Ti's firmware is insisting on not switching off... */
00420                 gpio->GPBDAT &= ~(1 << 7);      /* GPB7: MODEM_ON */
00421                 //gpio->GPBDAT |= (1 << 6);     /* GPB6: MODEM_RST */
00422                 if (!(gpio->GPFDAT & (1 << 2)))
00423                         puts("Can't power modem off while serial console "
00424                              "in use!\n");
00425                 else {
00426                         S3C24X0_UART * const uart = S3C24X0_GetBase_UART(0);
00427                         uart->UMCON |= 0x10;            /* Hardware flow control */
00428                         gpio->GPFDAT &= ~(1 << 2);      /* GPF2: nGSM_EN */
00429                         dev->puts("AT@POFF\r\n");
00430                         gpio->GPFDAT |= (1 << 2);       /* GPF2: nGSM_EN */
00431                         uart->UMCON &= ~0x10;           /* No Hardware flow control */
00432                 }
00433         }
00434 }
00435 
00436 /* switch gps power on/off */
00437 void neo1973_gps(int on)
00438 {
00439         printf("not implemented yet!\n");
00440 }
00441 
00442 static int pwr_int_pending(void)
00443 {
00444         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00445 
00446 #if defined(CONFIG_ARCH_GTA01B_v4)
00447         return !(gpio->GPGDAT & (1 << 1));      /* EINT9/GPG1 */
00448 #else
00449         return !(gpio->GPGDAT & (1 << 8));      /* EINT16/GPG8 */
00450 #endif /* !CONFIG_ARCH_GTA01B_v4 */
00451 }
00452 
00453 static int have_int1(uint8_t mask)
00454 {
00455         static uint8_t pending = 0;
00456 
00457         if (pwr_int_pending()) {
00458                 /*
00459                  * We retrieve all interupts, so that we clear any stray ones
00460                  * in INT2 and INT3.
00461                  */
00462                 uint8_t int1,int2,int3;
00463 
00464                 int1 = pcf50606_reg_read(PCF50606_REG_INT1);
00465                 int2 = pcf50606_reg_read(PCF50606_REG_INT2);
00466                 int3 = pcf50606_reg_read(PCF50606_REG_INT3);
00467                 pending |= int1;
00468         }
00469         if (!(pending & mask))
00470                 return 0;
00471         pending &= ~mask;
00472         return 1;
00473 }
00474 
00475 int neo1973_new_second(void)
00476 {
00477         return have_int1(PCF50606_INT1_SECOND);
00478 }
00479 
00480 int neo1973_on_key_pressed(void)
00481 {
00482         static int pressed = -1;
00483 
00484         if (pressed == -1 ||
00485             have_int1(PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) {
00486                 pressed = !(pcf50606_reg_read(PCF50606_REG_OOCS) &
00487                      PFC50606_OOCS_ONKEY);
00488 }
00489         return pressed;
00490 }
00491 
00492 int neo1973_aux_key_pressed(void)
00493 {
00494         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
00495 
00496         if (gpio->GPFDAT & (1 << 6))
00497                 return 0;
00498         return 1;
00499 }
00500 
00501 static const char *chgstate_names[] = {
00502         [PCF50606_MBCC1_CHGMOD_QUAL]            = "qualification",
00503         [PCF50606_MBCC1_CHGMOD_PRE]             = "pre",
00504         [PCF50606_MBCC1_CHGMOD_TRICKLE]         = "trickle",
00505         [PCF50606_MBCC1_CHGMOD_FAST_CCCV]       = "fast_cccv",
00506         [PCF50606_MBCC1_CHGMOD_FAST_NOCC]       = "fast_nocc",
00507         [PCF50606_MBCC1_CHGMOD_FAST_NOCV]       = "fast_nocv",
00508         [PCF50606_MBCC1_CHGMOD_FAST_SW]         = "fast_switch",
00509         [PCF50606_MBCC1_CHGMOD_IDLE]            = "idle",
00510 };
00511 
00512 const char *neo1973_get_charge_status(void)
00513 {
00514         u_int8_t mbcc1 = pcf50606_reg_read(PCF50606_REG_MBCC1);
00515         u_int8_t chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK);
00516         return chgstate_names[chgmod];
00517 }
00518 
00519 int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd)
00520 {
00521         switch (cmd) {
00522         case NEO1973_CHGCMD_NONE:
00523                 break;
00524         case NEO1973_CHGCMD_AUTOFAST:
00525                 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
00526                                           PCF50606_MBCC1_AUTOFST,
00527                                           PCF50606_MBCC1_AUTOFST);
00528                 break;
00529         case NEO1973_CHGCMD_NO_AUTOFAST:
00530                 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
00531                                           PCF50606_MBCC1_AUTOFST, 0);
00532                 break;
00533         case NEO1973_CHGCMD_OFF:
00534                 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
00535                                           PCF50606_MBCC1_CHGMOD_MASK,
00536                                           PCF50606_MBCC1_CHGMOD_IDLE);
00537                 break;
00538 
00539         case NEO1973_CHGCMD_FAST:
00540         case NEO1973_CHGCMD_FASTER:
00541                 pcf50606_reg_set_bit_mask(PCF50606_REG_MBCC1,
00542                                           PCF50606_MBCC1_CHGMOD_MASK,
00543                                           PCF50606_MBCC1_CHGMOD_FAST_CCCV);
00544                 break;
00545         }
00546         return 0;
00547 }
00548 
00549 void neo1973_led(int led, int on)
00550 {
00551         printf("No LED's in this Neo1973 hardware revision\n");
00552 }
00553 
00554 
00555 
00556 /* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
00557    "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
00558    images: 640*480*2*2 = 1228800 < 1245184. */
00559 
00560 unsigned int dynpart_size[] = {
00561     CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
00562 char *dynpart_names[] = {
00563     "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
00564 
00565 

Document for u-boot-1.3.2-moko-linuxbj by  forum_linuxbj