Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <arch/arm.h>
00045
00046 #ifndef PMM_RST_BASE
00047
00048 #define PMM_RST_BASE PIOB_BASE
00049 #endif
00050
00051 #ifndef PMM_RST_PIN
00052
00053 #define PMM_RST_PIN 8
00054 #endif
00055
00056
00060 #define PWRMAN_REG_VERS 0
00061
00062 #define PWRMAN_REG_STA 1
00063
00064 #define PWRMAN_REG_ENA 2
00065
00066 #define PWRMAN_REG_DIS 3
00067
00068 #define PWRMAN_REG_TEMP 4
00069
00070 #define PWRMAN_REG_VAUX 6
00071
00072 #define PWRMAN_REG_LEDCTL 8
00073
00075
00078 #define PWRMAN_BOARD 0x01
00079
00080 #define PWRMAN_VBIN 0x02
00081
00082 #define PWRMAN_VBOUT 0x04
00083
00084 #define PWRMAN_MMC 0x08
00085
00086 #define PWRMAN_RS232 0x10
00087
00088 #define PWRMAN_ETHCLK 0x20
00089
00090 #define PWRMAN_ETHRST 0x40
00091
00092 #define PWRMAN_WAKEUP 0x80
00093
00095 #define ARM_TTD_DOM_LSB 5
00096 #define ARM_TTD_DOM(x) ((x) << ARM_TTD_DOM_LSB)
00097
00098 #define ARM_TTD_AP_PN_UN 0x000
00099 #define ARM_TTD_AP_PW_UN 0x400
00100 #define ARM_TTD_AP_PW_UR 0x800
00101 #define ARM_TTD_AP_PW_UW 0xC00
00102
00103 #define ARM_TTD_INVALID 0x0
00104 #define ARM_TTD_COARSE_PAGE 0x1
00105 #define ARM_TTD_SECTION 0x12
00106 #define ARM_TTD_FINE_PAGE 0x3
00107
00108
00109 #define ARM_TTD_NC_NB 0x0
00110
00111 #define ARM_TTD_NC_B 0x4
00112
00113 #define ARM_TTD_C_WT 0x8
00114
00115 #define ARM_TTD_C_WB 0xC
00116
00117 #define ARM_SET_CP15_TTBR(val) __asm__ __volatile__("mcr p15, 0, %0, c2, c0, 0" :: "r"(val) : "cc")
00118 #define ARM_SET_CP15_DACR(val) __asm__ __volatile__("mcr p15, 0, %0, c3, c0, 0" :: "r"(val) : "cc")
00119
00120 void __set_stacks(void) __attribute__ ((naked));
00121
00122 void __init2(void) __attribute__ ((naked)) __attribute__ ((section(".init2.user")));
00123 void __init2(void)
00124 {
00125
00126
00127
00128 #if defined(NUT_WDT_START)
00129 #if NUT_WDT_START
00130
00131 outr(WDT_MR, NUT_WDT_START);
00132 #else
00133
00134 outr(WDT_MR, WDT_WDDIS);
00135 #endif
00136 #endif
00137
00138
00139
00140 outr(RSTC_MR, RSTC_KEY | RSTC_URSTEN);
00141
00142 __set_stacks();
00143 }
00144
00145
00146 void __clear_bss(void) __attribute__ ((naked));
00147
00148 void __init3(void) __attribute__ ((naked)) __attribute__ ((section(".init3.user")));
00149 void __init3(void)
00150 {
00151
00152 ARM_SET_CP15_CR(ARM_GET_CP15_CR() | (1 << 12));
00153
00154
00155 __clear_bss();
00156 }
00157
00158 void __call_rtos(void) __attribute__ ((naked));
00159
00160 void __init4(void) __attribute__ ((naked)) __attribute__ ((section(".init4.user")));
00161 void __init4(void)
00162 {
00163 static unsigned int *ttb = (unsigned int *) 0x20000000;
00164 static const unsigned int dom = 0xC0000000;
00165 static unsigned int i;
00166
00167
00168 ARM_SET_CP15_TTBR((unsigned int) ttb);
00169
00170 ARM_SET_CP15_DACR(dom);
00171
00172 for(i = 0; i < 4096; i++) {
00173 ttb[i] = 0;
00174 }
00175
00176 ttb[0x000] = 0x00000000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WB | ARM_TTD_SECTION;
00177
00178 ttb[0x002] = 0x00200000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WT | ARM_TTD_SECTION;
00179 for(i = 0; i < 128; i++) {
00180 ttb[0x200 + i] = (0x20000000 + (i << 20)) | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_C_WB | ARM_TTD_SECTION;
00181 }
00182
00183 for(i = 0; i < 256; i++) {
00184 ttb[0x400 + i] = (0x40000000 + (i << 20)) | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_SECTION;
00185 }
00186
00187 ttb[0xFFF] = 0xFFF00000 | ARM_TTD_AP_PW_UN | ARM_TTD_DOM(15) | ARM_TTD_SECTION;
00188
00189
00190 ARM_SET_CP15_CR(ARM_GET_CP15_CR() | (1 << 12) | (1 << 2));
00191
00192
00193 __call_rtos();
00194 }
00195
00203 static void BootLoopDelay(int n)
00204 {
00205 while (n--) {
00206 _NOP();
00207 }
00208 }
00209
00215 static void BootMicroDelay(int us)
00216 {
00217 while (us--) {
00218 BootLoopDelay(200);
00219 }
00220 }
00221
00230 static void BootMilliDelay(int ms)
00231 {
00232 while (ms--) {
00233 BootMicroDelay(1000);
00234 }
00235 }
00236
00240 static void PmmInit(void)
00241 {
00242 #if defined(PMM_RST_BASE) && defined(PMM_RST_PIN)
00243
00244 outr(PMM_RST_BASE + PIO_SODR_OFF, _BV(PMM_RST_PIN));
00245 outr(PMM_RST_BASE + PIO_PER_OFF, _BV(PMM_RST_PIN));
00246 outr(PMM_RST_BASE + PIO_OER_OFF, _BV(PMM_RST_PIN));
00247 BootMilliDelay(1);
00248
00249 outr(PMM_RST_BASE + PIO_CODR_OFF, _BV(PMM_RST_PIN));
00250 BootMilliDelay(100);
00251 #endif
00252
00253 outr(PIOA_ASR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00254 outr(PIOA_PDR, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00255
00256 outr(PIOA_MDER, _BV(PA23_TWD_A) | _BV(PA24_TWCK_A));
00257
00258 outr(PMC_PCER, _BV(TWI_ID));
00259
00260 outr(TWI_IDR, 0xFFFFFFFF);
00261 outr(TWI_CR, TWI_SWRST);
00262
00263 outr(TWI_CR, TWI_MSEN | TWI_SVDIS);
00264
00265 outr(TWI_CWGR, (7 << TWI_CKDIV_LSB) | (128 << TWI_CHDIV_LSB) | (128 << TWI_CLDIV_LSB));
00266 }
00267
00276 static int PmmWriteReg(unsigned int reg, unsigned int val)
00277 {
00278 volatile int tmo;
00279
00280 outr(TWI_MMR, 0x22 << TWI_DADR_LSB);
00281 outr(TWI_CR, TWI_START);
00282 outr(TWI_THR, reg);
00283 for (tmo = 0; (inr(TWI_SR) & TWI_TXRDY) == 0; tmo++) {
00284 if (tmo > 100000) {
00285 return -1;
00286 }
00287 }
00288 outr(TWI_CR, TWI_STOP);
00289 outr(TWI_THR, val);
00290 for (tmo = 0; (inr(TWI_SR) & TWI_TXCOMP) == 0; tmo++) {
00291 if (tmo > 100000) {
00292 return -1;
00293 }
00294 }
00295 return 0;
00296 }
00297
00298 #if 0
00299
00300
00301
00302
00303 static int PmmReadReg(unsigned int reg, unsigned char *val)
00304 {
00305 unsigned long sr;
00306 volatile unsigned int tmo;
00307
00308 outr(TWI_IADRR, reg);
00309 outr(TWI_MMR, 0x22 << TWI_DADR_LSB | TWI_IADRSZ_1BYTE | TWI_MREAD);
00310 outr(TWI_CR, TWI_START | TWI_STOP);
00311 for (tmo = 0; ((sr = inr(TWI_SR)) & TWI_RXRDY) == 0; tmo++) {
00312 if (tmo > 100000) {
00313 return -1;
00314 }
00315 }
00316 if (sr & TWI_NACK) {
00317 return -1;
00318 }
00319 *val = inb(TWI_RHR);
00320 return 0;
00321 }
00322 #endif
00323
00327 static void PmmPhyReset(void)
00328 {
00329
00330 outr(PIOA_ODR, _BV(14) | _BV(15) | _BV(17));
00331 outr(PIOA_PUER, _BV(14) | _BV(15) | _BV(17));
00332 outr(PIOA_PER, _BV(14) | _BV(15) | _BV(17));
00333
00334
00335 outr(PIOA_ODR, _BV(18));
00336 outr(PIOA_PUDR, _BV(18));
00337 outr(PIOA_PER, _BV(18));
00338
00339 BootMilliDelay(10);
00340 PmmWriteReg(PWRMAN_REG_ENA, PWRMAN_ETHRST | PWRMAN_ETHCLK);
00341 BootMilliDelay(1);
00342 PmmWriteReg(PWRMAN_REG_DIS, PWRMAN_ETHRST);
00343 BootMilliDelay(10);
00344 }
00345
00349 void NutBoardInit(void)
00350 {
00351 PmmInit();
00352 PmmPhyReset();
00353 }