/* * davinci.c - common DaVinci platform initialization * * Copyright (C) 2008 Hugo Villeneuve * * Based on TI DaVinci Flash and Boot Utilities, original copyright follows: * Copyright 2008 Texas Instruments, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "common.h" #include "davinci.h" #include "ddr.h" #include "util.h" #include "uart.h" #include "gpio.h" extern enum bootmode_t bootmode; extern const int8_t lpsc_en_list[]; extern const int8_t lpsc_emurstie_list[]; extern const size_t lpsc_en_list_len; extern const size_t lpsc_emurstie_list_len; /* Table of supported PLL settings */ #define PLL_DAVINCI_594_CFG 0 #define PLL_DAVINCI_810_CFG 1 static const struct pll_settings_t pll1_settings[] = { { 22 }, /* DSP=594 MHz ARM=297 MHz */ { 30 }, /* DSP=810 MHz ARM=405 MHz */ }; static const struct pll_settings_t pll2_settings[] = { { 24 }, /* DDRPHY=324 MHz DDRCLK=162 MHz */ { 28 }, /* DDRPHY=378 MHz DDRCLK=189 MHz */ }; /* Table of supported DDR devices */ #define DDR_MT47H32M16BN_3_162MHz_CFG 0 #define DDR_MT47H64M16HR_3IT_162MHz_CFG 1 #define DDR_MT47H64M16HR_3IT_189MHz_CFG 2 static const struct ddr_timing_infos_t ddr_timing_infos[] = { { /* Micron MT47H32M16BN-3 @ 162 MHz settings: * TCK = 6.17 nS -> 1 / 162 MHz * T_REF = 7.8 uS (varies with commercial vs industrial) * T_RFC = 105 nS (varies with capacity) * T_RP = 15 nS * T_RCD = 15 nS * T_WR = 15 nS * T_RAS = 40 nS * T_RASMAX = 70 uS * T_RTP = 7.5 nS * T_RC = 55 nS * T_RRD = 10 nS * T_WTR = 7.5 nS * T_XSRD = 200 nS * T_XSNR = 115 nS -> T_RFC(MIN) + 10 * T_CKE = 3 TCK * T_XP = 2 TCK */ .SDBCR = SDBCR_DEFAULT | (0 << 14) /* NM = 0; {32-bit bus with} */ | (3 << 9) /* CL = 3; */ | (2 << 4) /* IBANK = 2; {4 banks} */ | (2 << 0), /* PAGESIZE = 2; {1024-word} */ .SDTIMR = (16 << 25) /* T_RFC = 16; {(T_RFC * DDRCLK) - 1} */ | ( 2 << 22) /* T_RP = 2; {(T_RP * DDRCLK) - 1} */ | ( 2 << 19) /* T_RCD = 2; {(T_RCD * DDRCLK) - 1} */ | ( 2 << 16) /* T_WR = 2; {(T_WR * DDRCLK) - 1} */ | ( 6 << 11) /* T_RAS = 6; {(T_RAS * DDRCLK) - 1} */ | ( 8 << 6) /* T_RC = 8; {(T_RC * DDRCLK) - 1} */ | ( 1 << 3) /* T_RRD = 1; {(T_RRD * DDRCLK) - 1} */ | ( 1 << 0), /* T_WTR = 1; {(T_WTR * DDRCLK) - 1} */ .SDTIMR2 = ( 18 << 16) /* T_XSNR = 18; {(T_XSNR * DDRCLK) - 1} */ | (199 << 8) /* T_XSRD = 199; {T_XSRD - 1} */ | ( 1 << 5) /* T_RTP = 1; {(T_RTP * DDRCLK) - 1} */ | ( 2 << 0), /* T_CKE = 2; {T_CKE - 1} */ .SDRCR = 1265, /* RR = 1265; {DDRCLK * T_REF} */ .READ_Latency = 4, }, { /* Micron MT47H64M16HR-3IT @ 162 MHz settings: * TCK = 6.17 nS -> 1 / 162 MHz * T_REF = 3.9 uS (varies with commercial vs industrial) * T_RFC = 127.5 nS (varies with capacity) * T_RP = 15 nS * T_RCD = 15 nS * T_WR = 15 nS * T_RAS = 40 nS * T_RASMAX = 70 uS * T_RTP = 7.5 nS * T_RC = 55 nS * T_RRD = 10 nS * T_WTR = 7.5 nS * T_XSRD = 200 nS * T_XSNR = 138 nS -> T_RFC(MIN) + 10 * T_CKE = 3 TCK * T_XP = 2 TCK */ .SDBCR = SDBCR_DEFAULT | (0 << 14) /* NM = 0; {32-bit bus with} */ | (3 << 9) /* CL = 3; */ | (3 << 4) /* IBANK = 3; {8 banks} */ | (2 << 0), /* PAGESIZE = 2; {1024-word} */ .SDTIMR = (20 << 25) /* T_RFC = 20; {(T_RFC * DDRCLK) - 1} */ | ( 2 << 22) /* T_RP = 2; {(T_RP * DDRCLK) - 1} */ | ( 2 << 19) /* T_RCD = 2; {(T_RCD * DDRCLK) - 1} */ | ( 2 << 16) /* T_WR = 2; {(T_WR * DDRCLK) - 1} */ | ( 6 << 11) /* T_RAS = 6; {(T_RAS * DDRCLK) - 1} */ | ( 8 << 6) /* T_RC = 8; {(T_RC * DDRCLK) - 1} */ | ( 2 << 3) /* T_RRD = 2; {[((4 * T_RRD) + (2 * TCK)) / (4 * TCK)] - 1} */ | ( 1 << 0), /* T_WTR = 1; {(T_WTR * DDRCLK) - 1} */ .SDTIMR2 = ( 32 << 16) /* T_XSNR = 32; {(T_XSNR * DDRCLK) - 1} */ | (199 << 8) /* T_XSRD = 199; {T_XSRD - 1} */ | ( 1 << 5) /* T_RTP = 1; {(T_RTP * DDRCLK) - 1} */ | ( 2 << 0), /* T_CKE = 2; {T_CKE - 1} */ .SDRCR = 632, /* RR = 632; {DDRCLK * T_REF} */ .READ_Latency = 4, }, { /* Micron MT47H64M16HR-3IT @ 189 MHz settings: * TCK = 5.291 nS -> 1 / 189 MHz * T_REF = 3.9 uS (varies with commercial vs industrial) * T_RFC = 127.5 nS (varies with capacity) * T_RP = 15 nS * T_RCD = 15 nS * T_WR = 15 nS * T_RAS = 40 nS * T_RASMAX = 70 uS * T_RTP = 7.5 nS * T_RC = 55 nS * T_RRD = 10 nS * T_WTR = 7.5 nS * T_XSRD = 200 nS * T_XSNR = 138 nS -> T_RFC(MIN) + 10 * T_CKE = 3 TCK * T_XP = 2 TCK */ .SDBCR = SDBCR_DEFAULT | (0 << 14) /* NM = 0; {32-bit bus with} */ | (3 << 9) /* CL = 3; */ | (3 << 4) /* IBANK = 3; {8 banks} */ | (2 << 0), /* PAGESIZE = 2; {1024-word} */ .SDTIMR = (24 << 25) /* T_RFC = 24; {(T_RFC * DDRCLK) - 1} */ | ( 2 << 22) /* T_RP = 2; {(T_RP * DDRCLK) - 1} */ | ( 2 << 19) /* T_RCD = 2; {(T_RCD * DDRCLK) - 1} */ | ( 2 << 16) /* T_WR = 2; {(T_WR * DDRCLK) - 1} */ | ( 7 << 11) /* T_RAS = 7; {(T_RAS * DDRCLK) - 1} */ | (10 << 6) /* T_RC = 10; {(T_RC * DDRCLK) - 1} */ | ( 2 << 3) /* T_RRD = 2; {[((4 * T_RRD) + (2 * TCK)) / (4 * TCK)] - 1} */ | ( 1 << 0), /* T_WTR = 1; {(T_WTR * DDRCLK) - 1} */ .SDTIMR2 = ( 26 << 16) /* T_XSNR = 26; {(T_XSNR * DDRCLK) - 1} */ | (199 << 8) /* T_XSRD = 199; {T_XSRD - 1} */ | ( 1 << 5) /* T_RTP = 1; {(T_RTP * DDRCLK) - 1} */ | ( 2 << 0), /* T_CKE = 2; {T_CKE - 1} */ .SDRCR = 738, /* RR = 738; {DDRCLK * T_REF} */ .READ_Latency = 4, } }; /* Symbol from linker script */ extern uint32_t __DDR_START; uint32_t DDR_SIZE = (128 << 20); static void pinmuxControl(uint32_t regOffset, uint32_t mask, uint32_t value) { SYSTEM->PINMUX[regOffset] &= ~mask; SYSTEM->PINMUX[regOffset] |= (mask & value); } static void lpsc_tansition(uint8_t module, uint8_t domain, uint8_t state) { /* Wait for any outstanding transition to complete */ while ((PSC->PTSTAT) & (0x00000001 << domain)) ; /* If we are already in that state, just return */ if (((PSC->MDSTAT[module]) & 0x1F) == state) return; /* Perform transition */ PSC->MDCTL[module] = ((PSC->MDCTL[module]) & (0xFFFFFFE0)) | (state); PSC->PTCMD |= (0x00000001 << domain); /* Wait for transition to complete */ while ((PSC->PTSTAT) & (0x00000001 << domain)) ; /* Wait and verify the state */ while (((PSC->MDSTAT[module]) & 0x1F) != state) ; } static void ivt_init(void) { volatile uint32_t *ivect; extern uint32_t __IVT; if (bootmode == NON_SECURE_NOR) { ivect = &(__IVT); *ivect++ = 0xEAFFFFFE; /* Reset @ 0x00*/ } else ivect = &(__IVT) + 4; *ivect++ = 0xEAFFFFFE; /* Undefined Address @ 0x04 */ *ivect++ = 0xEAFFFFFE; /* Software Interrupt @0x08 */ *ivect++ = 0xEAFFFFFE; /* Pre-Fetch Abort @ 0x0C */ *ivect++ = 0xEAFFFFFE; /* Data Abort @ 0x10 */ *ivect++ = 0xEAFFFFFE; /* Reserved @ 0x14 */ *ivect++ = 0xEAFFFFFE; /* IRQ @ 0x18 */ *ivect = 0xEAFFFFFE; /* FIQ @ 0x1C */ } static int timer0_init(uint8_t timeout) { TIMER0->TGCR = 0x00000000; /* Reset timer */ TIMER0->TCR = 0x00000000; /* Disable timer */ TIMER0->TIM12 = 0x00000000; /* Reset timer count to zero */ /* Set timer period (5 seconds timeout) */ TIMER0->PRD12 = SYSTEM_CLK_HZ * timeout; return E_PASS; } void timer0_start(void) { AINTC->IRQ1 |= 0x00000001; /* Clear interrupt */ TIMER0->TGCR = 0x00000000; /* Reset timer */ TIMER0->TIM12 = 0x00000000; /* Reset timer count to zero */ TIMER0->TCR = 0x00000040; /* Setup for one-shot mode */ TIMER0->TGCR = 0x00000005; /* Start TIMER12 in 32-bits mode. */ } void timer0_settimeout(uint8_t timeout) { timer0_init(timeout); } int timer0_setdefault_timeout() { return timer0_init(5); } uint32_t timer0_status(void) { return AINTC->IRQ1 & 0x1; } static int uart0_init(void) { UART0->PWREMU_MGNT = 0; /* Reset UART TX & RX components */ waitloop(100); /* Set DLAB bit - allows setting of clock divisors */ UART0->LCR |= 0x80; /* * Compute divisor value. Normally, we should simply return: * SYSTEM_CLK_HZ / (16 * baudrate) * but we need to round that value by adding 0.5. * Rounding is especially important at high baud rates. */ UART0->DLL = (SYSTEM_CLK_HZ + (UART_BAUDRATE * (UART_BCLK_RATIO / 2))) / (UART_BCLK_RATIO * UART_BAUDRATE); UART0->DLH = 0x00; UART0->FCR = 0x0007; /* Clear UART TX & RX FIFOs */ UART0->MCR = 0x0000; /* RTS & CTS disabled, * Loopback mode disabled, * Autoflow disabled */ UART0->LCR = 0x0003; /* Clear DLAB bit * 8-bit words, * 1 STOP bit generated, * No Parity, No Stick paritiy, * No Break control */ /* Enable receiver, transmitter, set to run. */ UART0->PWREMU_MGNT |= 0x6001; return E_PASS; } static int pll_init(volatile struct pll_regs_t *pll, int pll_mult, int plldiv_ratio[5]) { int k; volatile uint32_t *plldiv_reg[5]; int pll_is_powered_up = (pll->PLLCTL & DEVICE_PLLCTL_PLLPWRDN_MASK) >> 1; plldiv_reg[0] = &pll->PLLDIV1; plldiv_reg[1] = &pll->PLLDIV2; plldiv_reg[2] = &pll->PLLDIV3; plldiv_reg[3] = &pll->PLLDIV4; plldiv_reg[4] = &pll->PLLDIV5; /* Set PLL clock input to internal osc. */ pll->PLLCTL &= ~(DEVICE_PLLCTL_CLKMODE_MASK); /* Set PLL to bypass, then wait for PLL to stabilize */ pll->PLLCTL &= ~(DEVICE_PLLCTL_PLLENSRC_MASK | DEVICE_PLLCTL_PLLEN_MASK); waitloop(150); /* Reset PLL: Warning, bit state is inverted for DM644x vs DM35x. */ #if defined(DM644x) pll->PLLCTL &= ~DEVICE_PLLCTL_PLLRST_MASK; #elif defined(DM35x) pll->PLLCTL |= DEVICE_PLLCTL_PLLRST_MASK; #endif if (pll_is_powered_up) { /* Disable PLL */ pll->PLLCTL |= DEVICE_PLLCTL_PLLDIS_MASK; /* Powerup PLL */ pll->PLLCTL &= ~(DEVICE_PLLCTL_PLLPWRDN_MASK); } /* Enable PLL */ pll->PLLCTL &= ~(DEVICE_PLLCTL_PLLDIS_MASK); /* Wait for PLL to stabilize */ waitloop(150); /* Load PLL multiplier. */ pll->PLLM = (pll_mult - 1) & 0xff; /* Set and enable dividers as needed. */ for (k = 0; k < 5; k++) { if (plldiv_ratio[k] > 0) *(plldiv_reg[k]) |= DEVICE_PLLDIV_EN_MASK | (plldiv_ratio[k] - 1); } #if defined(DM35x) /* Set the processor AIM wait state and PLL1 post-divider to to 1 */ SYSTEM->MISC &= ~(DEVICE_MISC_PLL1POSTDIV_MASK | DEVICE_MISC_AIMWAITST_MASK); #endif /* Initiate a new divider transition. */ pll->PLLCMD |= DEVICE_PLLCMD_GOSET_MASK; /* Wait for completion of phase alignment. */ while ((pll->PLLSTAT & DEVICE_PLLSTAT_GOSTAT_MASK)) ; /* Wait for PLL to reset ( ~5 usec ) */ waitloop(5000); /* Release PLL from reset */ /* Reset PLL: Warning, bit state is inverted for DM644x vs DM35x. */ #if defined(DM644x) pll->PLLCTL |= DEVICE_PLLCTL_PLLRST_MASK; #elif defined(DM35x) pll->PLLCTL &= ~DEVICE_PLLCTL_PLLRST_MASK; #endif /* Wait for PLL to re-lock: * DM644z: 2000P * DM35x: 8000P */ waitloop(8000); /* Switch out of BYPASS mode */ pll->PLLCTL |= DEVICE_PLLCTL_PLLEN_MASK; return E_PASS; } static int pll1_init(int cfg) { int plldiv_ratio[5]; #if defined(DM644x) plldiv_ratio[0] = 1; /* PLLDIV1 fixed */ plldiv_ratio[1] = 2; /* PLLDIV2 fixed */ plldiv_ratio[2] = 3; /* PLLDIV3 fixed */ plldiv_ratio[3] = -1; /* PLLDIV4 not used */ plldiv_ratio[4] = 6; /* PLLDIV5 fixed */ #elif defined(DM35x) plldiv_ratio[0] = 2; /* PLLDIV1 fixed */ plldiv_ratio[1] = 4; /* PLLDIV2 fixed */ /* Calculate PLL divider ratio for divider 3 (feeds VPBE) */ plldiv_ratio[2] = 0; while ((plldiv_ratio[2] * VPBE_CLK_HZ) < (SYSTEM_CLK_HZ * (pll1_settings[cfg].mult >> 3))) plldiv_ratio[2]++; /* Check to make sure we can supply accurate VPBE clock */ if ((plldiv_ratio[2] * VPBE_CLK_HZ) != (SYSTEM_CLK_HZ * (pll1_settings[cfg].mult >> 3))) return E_FAIL; /* See the device datasheet for more info (must be 2 or 4) */ plldiv_ratio[3] = 4; plldiv_ratio[4] = -1; /* PLLDIV5 not used */ #endif return pll_init(PLL1, pll1_settings[cfg].mult, plldiv_ratio); } static int pll2_init(int cfg) { int plldiv_ratio[5]; plldiv_ratio[0] = PLL2_Div1; plldiv_ratio[1] = PLL2_Div2; plldiv_ratio[2] = -1; /* PLLDIV3 not used */ plldiv_ratio[3] = -1; /* PLLDIV4 not used */ plldiv_ratio[4] = -1; /* PLLDIV5 not used */ return pll_init(PLL2, pll2_settings[cfg].mult, plldiv_ratio); } static void ddr_timing_setup(int cfg) { /* The configuration of DDRPHYCR is not dependent on the DDR2 device * specification but rather on the board layout. * Setup the read latency and clear DLLPWRDN */ DDR->DDRPHYCR = DDRPHYCR_DEFAULT | (ddr_timing_infos[cfg].READ_Latency & DDRPHYCR_READLAT_MASK); /* * Set the PR_OLD_COUNT bits in the Bus Burst Priority Register (PBBPR) * as suggested in TMS320DM6446 errata 2.1.2: * * On DM6446 Silicon Revision 2.1 and earlier, under certain conditions * low priority modules can occupy the bus and prevent high priority * modules like the VPSS from getting the required DDR2 throughput. */ DDR->PBBPR = DDR_PBBPR_PR_OLD_COUNT; /* TIMUNLOCK (unlocked), CAS Latency, number of banks and page size */ DDR->SDBCR = SDBCR_TIMUNLOCK | ddr_timing_infos[cfg].SDBCR; /* Program timing registers */ DDR->SDTIMR = ddr_timing_infos[cfg].SDTIMR; DDR->SDTIMR2 = ddr_timing_infos[cfg].SDTIMR2; /* Clear the TIMUNLOCK bit (locked) */ DDR->SDBCR &= ~SDBCR_TIMUNLOCK; /* Set the refresh rate */ DDR->SDRCR = ddr_timing_infos[cfg].SDRCR; } static void ddr_reset(void) { /* Perform a soft reset to the DDR2 memory controller: * Put in SYNCRESET and enable it again. */ lpsc_tansition(LPSC_DDR2, PD0, PSC_SYNCRESET); lpsc_tansition(LPSC_DDR2, PD0, PSC_ENABLE); } static int ddr_init(int cfg) { volatile uint32_t *ddr_start = &__DDR_START; /* For reading/writing dummy value in order to apply timing settings */ volatile uint32_t ddr_dummy_read; /* Enable DDR2 module. */ lpsc_tansition(LPSC_DDR2, PD0, PSC_ENABLE); #if defined(DM35x) ddr_vtp_calibration(); ddr_reset(); #endif ddr_timing_setup(cfg); /* Dummy read to apply timing settings */ ddr_dummy_read = ddr_start[0]; #if defined(DM644x) ddr_reset(); ddr_vtp_calibration(); #endif /* Verify correct initialization. */ ddr_start[0] = DDR_TEST_PATTERN; if (ddr_start[0] != DDR_TEST_PATTERN) { log_fail("DDR init failed"); return E_FAIL; } return E_PASS; } static void psc_init(void) { uint32_t i; #if defined(DM35x) /* Do always on power domain transitions */ while ((PSC->PTSTAT) & 0x00000001); #elif defined(DM644x) /* * Workaround for TMS320DM6446 errata 1.3.22 * (Revision(s) Affected: 1.3 and earlier): * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset. * Clear the reserved location at address 0x01C41A20 */ PSC_PTSTAT_WORKAROUND_REG = 0; /* Put the C64x+ Core into reset (if it's on) */ PSC->MDCTL[LPSC_DSP] &= (~0x00000100); PSC->PTCMD |= 0x00000002; while ((PSC->PTSTAT) & (0x00000002)); while ((PSC->MDSTAT[LPSC_DSP]) & (0x00000100)); #endif /* Enable selected modules */ for (i = 0; i < lpsc_en_list_len; i++) { int8_t k = lpsc_en_list[i]; PSC->MDCTL[k] = (PSC->MDCTL[k] & 0xFFFFFFE0) | PSC_ENABLE; } /* Set EMURSTIE on selected modules */ for (i = 0; i < lpsc_emurstie_list_len; i++) { int8_t k = lpsc_emurstie_list[i]; PSC->MDCTL[k] |= EMURSTIE_MASK; } /* Do Always-On Power Domain Transitions */ PSC->PTCMD |= 0x00000001; while ((PSC->PTSTAT) & 0x00000001); #if defined(DM644x) /* DO DSP Power Domain Transitions */ PSC->PTCMD |= 0x00000002; while ((PSC->PTSTAT) & (0x00000002)); #endif /* Clear EMURSTIE on selected modules */ for (i = 0; i < lpsc_emurstie_list_len; i++) { int8_t k = lpsc_emurstie_list[i]; PSC->MDCTL[k] &= (~EMURSTIE_MASK); } } int davinci_platform_init(char *version) { int pllCfg; int ddrCfg; int status = E_PASS; unsigned *gpio01 = (unsigned *)(DAVINCI_GPIO_BASE + 0x20); psc_init(); /* Disable ARM interrupts */ AINTC->INTCTL = 0x0; AINTC->EABASE = 0x0; AINTC->EINT0 = 0x0; AINTC->EINT1 = 0x0; AINTC->FIQ0 = 0xFFFFFFFF; AINTC->FIQ1 = 0xFFFFFFFF; AINTC->IRQ0 = 0xFFFFFFFF; AINTC->IRQ1 = 0xFFFFFFFF; #ifdef PINMUX0_DEFAULT pinmuxControl(0, 0xFFFFFFFF, PINMUX0_DEFAULT); #endif #ifdef PINMUX1_DEFAULT pinmuxControl(1, 0xFFFFFFFF, PINMUX1_DEFAULT); #endif /* The folowing are only available on DM35x */ #ifdef PINMUX2_DEFAULT pinmuxControl(2, 0xFFFFFFFF, PINMUX2_DEFAULT); #endif #ifdef PINMUX3_DEFAULT pinmuxControl(3, 0xFFFFFFFF, PINMUX3_DEFAULT); #endif #ifdef PINMUX4_DEFAULT pinmuxControl(4, 0xFFFFFFFF, PINMUX4_DEFAULT); #endif /* Init board configuration */ #if defined(board_sysmobts_v2) char boardVer; char boardCfg; boardCfg = (*gpio01 >> 10) & 0x001F; boardVer = (*gpio01 >> 15) & 0x0007; if ( boardVer > 1 ) { /* Davinci @ 405/810 MHz */ pllCfg = PLL_DAVINCI_810_CFG; /* Micron MT47H64M16HR-3IT @ 189 MHz */ ddrCfg = DDR_MT47H64M16HR_3IT_189MHz_CFG; uart_send_str_lf("CPU: Davinci @ 405/810 MHz"); uart_send_str_lf("DDR: Micron MT47H64M16HR-3IT @ 189 MHz"); } else if ( (boardVer == 1) && ((boardCfg == 0x02) || (boardCfg == 0x04) || (boardCfg == 0x05)) ) { /* Davinci @ 405/810 MHz */ pllCfg = PLL_DAVINCI_810_CFG; /* Micron MT47H64M16HR-3IT @ 189 MHz */ ddrCfg = DDR_MT47H64M16HR_3IT_189MHz_CFG; uart_send_str_lf("CPU: Davinci @ 405/810 MHz"); uart_send_str_lf("DDR: Micron MT47H64M16HR-3IT @ 189 MHz"); } else if ( (boardVer == 0) && (boardCfg != 0x00) ) { DDR_SIZE = (256 << 20); /* Davinci @ 297/594 MHz */ pllCfg = PLL_DAVINCI_594_CFG; /* Micron MT47H32M16BN-3 @ 162 MHz */ ddrCfg = DDR_MT47H64M16HR_3IT_162MHz_CFG; uart_send_str_lf("CPU: Davinci @ 297/594 MHz"); uart_send_str_lf("DDR: Micron MT47H32M16BN-3 @ 162 MHz"); } else #endif { #if defined(board_sysmobts_v2) DDR_SIZE = (256 << 20); #else DDR_SIZE = (128 << 20); #endif /* Davinci @ 297/594 MHz */ pllCfg = PLL_DAVINCI_594_CFG; /* Micron MT47H32M16BN-3 @ 162 MHz */ ddrCfg = DDR_MT47H32M16BN_3_162MHz_CFG; uart_send_str_lf("CPU: Davinci @ 297/594 MHz"); uart_send_str_lf("DDR: Micron MT47H32M16BN-3 @ 162 MHz"); } if (status == E_PASS) status |= pll1_init(pllCfg); if (status == E_PASS) status |= uart0_init(); if (status == E_PASS) status |= timer0_setdefault_timeout(); uart_send_lf(); log_info(version); #if defined(board_sysmobts_v2) char str[4]; uart_send_str("Board revision: "); str[0] = 'A' + boardVer; str[1] = '.'; str[2] = '0' + boardCfg; str[3] = '\0'; uart_send_str_lf(str); #endif if (status == E_PASS) status |= pll2_init(pllCfg); if (status == E_PASS) status |= ddr_init(ddrCfg); #ifdef STATUS_LED gpio_direction_out(STATUS_LED, 1); #endif /* STATUS_LED */ #ifdef board_minidas gpio_direction_out(FAN, 0); gpio_direction_out(BUZZER, 0); /* Put all peripherals in RESET state */ gpio_direction_out(DSP1_PWR_ENA, 0); gpio_direction_out(DSP2_PWR_ENA, 0); gpio_direction_out(WIFI_RESETn, 0); gpio_direction_out(GPS_RESETn, 0); gpio_direction_out(CAN_RESETn, 0); gpio_direction_out(ATA_RESETn, 0); gpio_direction_out(CAMERA_RESETn, 0); /* Enable power for hard disk */ gpio_direction_out(HDD_ENA, 1); #endif /* IRQ Vector Table Setup */ ivt_init(); return status; }