[U-Boot-Users] [ARM] TI DaVinci support, hopefully final [3/5]

Signed-off-by: Sergey Kubushyn ksi@koi8.net
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/lowlevel_init.S u-boot.git/cpu/arm926ejs/davinci/lowlevel_init.S --- u-boot.git.orig/cpu/arm926ejs/davinci/lowlevel_init.S 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/lowlevel_init.S 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,707 @@ +/* + * Low-level board setup code for TI DaVinci SoC based boards. + * + * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * Partially based on TI sources, original copyrights follow: + */ + +/* + * Board specific setup info + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta Kshitij@ti.com + * + * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004 + * + * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004 + * See file CREDITS for list of people who contributed to this + * project. + * + * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005 + * See file CREDITS for list of people who contributed to this + * project. + * + * Modified for DV-EVM board by Swaminathan S, Nov 2005 + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> + +.globl lowlevel_init +lowlevel_init: + + /*-------------------------------------------------------* + * Mask all IRQs by setting all bits in the EINT default * + *-------------------------------------------------------*/ + mov r1, $0 + ldr r0, =EINT_ENABLE0 + str r1, [r0] + ldr r0, =EINT_ENABLE1 + str r1, [r0] + + /*------------------------------------------------------* + * Put the GEM in reset * + *------------------------------------------------------*/ + + /* Put the GEM in reset */ + ldr r8, PSC_GEM_FLAG_CLEAR + ldr r6, MDCTL_GEM + ldr r7, [r6] + and r7, r7, r8 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x02 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStopGem: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x02 + bne checkStatClkStopGem + + /* Check for GEM Reset Completion */ +checkGemStatClkStop: + ldr r6, MDSTAT_GEM + ldr r7, [r6] + ands r7, r7, $0x100 + bne checkGemStatClkStop + + /* Do this for enabling a WDT initiated reset this is a workaround + for a chip bug. Not required under normal situations */ + ldr r6, P1394 + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * Enable L1 & L2 Memories in Fast mode * + *------------------------------------------------------*/ + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, MMARG_BRF0 + ldr r10, MMARG_BRF0_VAL + str r10, [r6] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * DDR2 PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r10, $0 + ldr r6, PLL2_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r10, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 +WaitPPL2Loop: + subs r10, r10, $1 + bne WaitPPL2Loop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL2_PLLM + mov r2, $0x17 /* 162 MHz */ + str r2, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV2 + mov r3, $0x01 + str r3, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV1 + mov r4, $0x0b /* 54 MHz */ + str r4, [r6] + + /* PLL2 DIV2 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV2 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop_0: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop_0 + + /* PLL2 DIV1 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV1 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop + + /* Wait for PLL to Reset Properly */ + mov r10, $0x218 +ResetPPL2Loop: + subs r10, r10, $1 + bne ResetPPL2Loop + + /* Bring PLL out of Reset */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT +PLL2Lock: + subs r10, r10, $1 + bne PLL2Lock + + /* Enable the PLL */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x01 + str r8, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x03 + bne checkDDRStatClkStop + + /*------------------------------------------------------* + * Program DDR2 MMRs for 162MHz Setting * + *------------------------------------------------------*/ + + /* Program PHY Control Register */ + ldr r6, DDRCTL + ldr r7, DDRCTL_VAL + str r7, [r6] + + /* Program SDRAM Bank Config Register */ + ldr r6, SDCFG + ldr r7, SDCFG_VAL + str r7, [r6] + + /* Program SDRAM TIM-0 Config Register */ + ldr r6, SDTIM0 + ldr r7, SDTIM0_VAL_162MHz + str r7, [r6] + + /* Program SDRAM TIM-1 Config Register */ + ldr r6, SDTIM1 + ldr r7, SDTIM1_VAL_162MHz + str r7, [r6] + + /* Program the SDRAM Bank Config Control Register */ + ldr r10, MASK_VAL + ldr r8, SDCFG + ldr r9, SDCFG_VAL + and r9, r9, r10 + str r9, [r8] + + /* Program SDRAM SDREF Config Register */ + ldr r6, SDREF + ldr r7, SDREF_VAL + str r7, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Issue a Dummy DDR2 read/write */ + ldr r8, DDR2_START_ADDR + ldr r7, DUMMY_VAL + str r7, [r8] + ldr r7, [r8] + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x01 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x01 + bne checkDDRStatClkStop2 + + /*------------------------------------------------------* + * Turn DDR2 Controller Clocks On * + *------------------------------------------------------*/ + + /* Enable the DDR2 LPSC Module */ + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkEn2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkEn2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkEn2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $0x1f + cmp r7, $0x03 + bne checkDDRStatClkEn2 + + /* DDR Writes and Reads */ + ldr r6, CFGTEST + mov r3, $0x01 + str r3, [r6] + + /*------------------------------------------------------* + * System PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r2, $0 + ldr r6, PLL1_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r2, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 + +WaitLoop: + subs r10, r10, $1 + bne WaitLoop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Disable the PLL */ + orr r8, r8, $0x10 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL1_PLLM + mov r3, $0x15 /* For 594MHz */ + str r3, [r6] + + /* Wait for PLL to Reset Properly */ + mov r10, $0xff + +ResetLoop: + subs r10, r10, $1 + bne ResetLoop + + /* Bring PLL out of Reset */ + ldr r6, PLL1_CTL + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT + +PLL1Lock: + subs r10, r10, $1 + bne PLL1Lock + + /* Enable the PLL */ + orr r8, r8, $0x01 + str r8, [r6] + + nop + nop + nop + nop + + /*------------------------------------------------------* + * AEMIF configuration for NOR Flash (double check) * + *------------------------------------------------------*/ + ldr r0, _PINMUX0 + ldr r1, _DEV_SETTING + str r1, [r0] + + ldr r0, WAITCFG + ldr r1, WAITCFG_VAL + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + + ldr r0, ACFG3 + ldr r1, ACFG3_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG4 + ldr r1, ACFG4_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG5 + ldr r1, ACFG5_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + /*--------------------------------------* + * VTP manual Calibration * + *--------------------------------------*/ + ldr r0, VTPIOCR + ldr r1, VTP_MMR0 + str r1, [r0] + + ldr r0, VTPIOCR + ldr r1, VTP_MMR1 + str r1, [r0] + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTPLock: + subs r10, r10, $1 + bne VTPLock + + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, DDRVTPR + ldr r7, [r6] + and r7, r7, $0x1f + and r8, r7, $0x3e0 + orr r8, r7, r8 + ldr r7, VTP_RECAL + orr r8, r7, r8 + ldr r7, VTP_EN + orr r8, r7, r8 + str r8, [r0] + + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTP1Lock: + subs r10, r10, $1 + bne VTP1Lock + + ldr r1, [r0] + ldr r2, VTP_MASK + and r2, r1, r2 + str r2, [r0] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /* + * Call board-specific lowlevel init. + * That MUST be present and THAT returns + * back to arch calling code with "mov pc, lr." + */ + b dv_board_init + +.ltorg + +_PINMUX0: + .word 0x01c40000 /* Device Configuration Registers */ +_PINMUX1: + .word 0x01c40004 /* Device Configuration Registers */ + +_DEV_SETTING: + .word 0x00000c1f + +WAITCFG: + .word 0x01e00004 +WAITCFG_VAL: + .word 0 +ACFG3: + .word 0x01e00014 +ACFG3_VAL: + .word 0x3ffffffd +ACFG4: + .word 0x01e00018 +ACFG4_VAL: + .word 0x3ffffffd +ACFG5: + .word 0x01e0001c +ACFG5_VAL: + .word 0x3ffffffd + +MDCTL_DDR2: + .word 0x01c41a34 +MDSTAT_DDR2: + .word 0x01c41834 + +PTCMD: + .word 0x01c41120 +PTSTAT: + .word 0x01c41128 + +EINT_ENABLE0: + .word 0x01c48018 +EINT_ENABLE1: + .word 0x01c4801c + +PSC_FLAG_CLEAR: + .word 0xffffffe0 +PSC_GEM_FLAG_CLEAR: + .word 0xfffffeff + +/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ +DDRCTL: + .word 0x200000e4 +DDRCTL_VAL: + .word 0x50006405 +SDREF: + .word 0x2000000c +SDREF_VAL: + .word 0x000005c3 +SDCFG: + .word 0x20000008 +SDCFG_VAL: +#ifdef DDR_4BANKS + .word 0x00178622 +#elif defined DDR_8BANKS + .word 0x00178632 +#else +#error "Unknown DDR configuration!!!" +#endif +SDTIM0: + .word 0x20000010 +SDTIM0_VAL_162MHz: + .word 0x28923211 +SDTIM1: + .word 0x20000014 +SDTIM1_VAL_162MHz: + .word 0x0016c722 +VTPIOCR: + .word 0x200000f0 /* VTP IO Control register */ +DDRVTPR: + .word 0x01c42030 /* DDR VPTR MMR */ +VTP_MMR0: + .word 0x201f +VTP_MMR1: + .word 0xa01f +DFT_ENABLE: + .word 0x01c4004c +VTP_LOCK_COUNT: + .word 0x5b0 +VTP_MASK: + .word 0xffffdfff +VTP_RECAL: + .word 0x40000 +VTP_EN: + .word 0x02000 +CFGTEST: + .word 0x80010000 +MASK_VAL: + .word 0x00000fff + +/* GEM Power Up & LPSC Control Register */ +MDCTL_GEM: + .word 0x01c41a9c +MDSTAT_GEM: + .word 0x01c4189c + +/* For WDT reset chip bug */ +P1394: + .word 0x01c41a20 + +PLL_CLKSRC_MASK: + .word 0xfffffeff /* Mask the Clock Mode bit */ +PLL_ENSRC_MASK: + .word 0xffffffdf /* Select the PLLEN source */ +PLL_BYPASS_MASK: + .word 0xfffffffe /* Put the PLL in BYPASS */ +PLL_RESET_MASK: + .word 0xfffffff7 /* Put the PLL in Reset Mode */ +PLL_PWRUP_MASK: + .word 0xfffffffd /* PLL Power up Mask Bit */ +PLL_DISABLE_ENABLE_MASK: + .word 0xffffffef /* Enable the PLL from Disable */ +PLL_LOCK_COUNT: + .word 0x2000 + +/* PLL1-SYSTEM PLL MMRs */ +PLL1_CTL: + .word 0x01c40900 +PLL1_PLLM: + .word 0x01c40910 + +/* PLL2-SYSTEM PLL MMRs */ +PLL2_CTL: + .word 0x01c40d00 +PLL2_PLLM: + .word 0x01c40d10 +PLL2_DIV1: + .word 0x01c40d18 +PLL2_DIV2: + .word 0x01c40d1c +PLL2_PLLCMD: + .word 0x01c40d38 +PLL2_PLLSTAT: + .word 0x01c40d3c +PLL2_DIV_MASK: + .word 0xffff7fff + +MMARG_BRF0: + .word 0x01c42010 /* BRF margin mode 0 (R/W)*/ +MMARG_BRF0_VAL: + .word 0x00444400 + +DDR2_START_ADDR: + .word 0x80000000 +DUMMY_VAL: + .word 0xa55aa55a diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/lxt972.c u-boot.git/cpu/arm926ejs/davinci/lxt972.c --- u-boot.git.orig/cpu/arm926ejs/davinci/lxt972.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/lxt972.c 2007-08-07 10:23:53.000000000 -0700 @@ -0,0 +1,142 @@ +/* + * Intel LXT971/LXT972 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * -------------------------------------------------------- + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <net.h> +#include <lxt971a.h> +#include <asm/arch/emac_defs.h> + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int lxt972_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID1, &id1)) + return(0); + if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID2, &id2)) + return(0); + + if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) + return(1); + + return(0); +} + +int lxt972_get_link_speed(int phy_addr) +{ + u_int16_t stat1, tmp; + volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) + return(0); + + if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ + return(0); + + if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; + + dm644x_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); + /* Read back */ + if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (stat1 & PHY_LXT971_STAT2_100BTX) { + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); + } else { + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); + } + + return(0); +} + + +int lxt972_init_phy(int phy_addr) +{ + int ret = 1; + + if (!lxt972_get_link_speed(phy_addr)) { + /* Try another time */ + ret = lxt972_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + dm644x_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); + + return(ret); +} + + +int lxt972_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + + if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_CTRL, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp |= PHY_COMMON_CTRL_RES_AUTO; + dm644x_eth_phy_write(phy_addr, PHY_COMMON_CTRL, tmp); + + /*check AutoNegotiate complete */ + udelay (10000); + if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_STAT, &tmp)) + return(0); + + if (!(tmp & PHY_COMMON_STAT_AN_COMP)) + return(0); + + return (lxt972_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/nand.c u-boot.git/cpu/arm926ejs/davinci/nand.c --- u-boot.git.orig/cpu/arm926ejs/davinci/nand.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/nand.c 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,389 @@ +/* + * NAND driver for TI DaVinci based boards. + * + * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * Based on Linux DaVinci NAND driver by TI. Original copyright follows: + */ + +/* + * + * linux/drivers/mtd/nand/nand_davinci.c + * + * NAND Flash Driver + * + * Copyright (C) 2006 Texas Instruments. + * + * ---------------------------------------------------------------------------- + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * ---------------------------------------------------------------------------- + * + * Overview: + * This is a device driver for the NAND flash device found on the + * DaVinci board which utilizes the Samsung k9k2g08 part. + * + Modifications: + ver. 1.0: Feb 2005, Vinod/Sudhakar + - + * + */ + +#include <common.h> + +#ifdef CFG_USE_NAND +#if !defined(CFG_NAND_LEGACY) + +#include <nand.h> +#include <asm/arch/nand_defs.h> +#include <asm/arch/emif_defs.h> + +extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; + +static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W; + + IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); + + switch (cmd) { + case NAND_CTL_SETCLE: + IO_ADDR_W |= MASK_CLE; + break; + case NAND_CTL_SETALE: + IO_ADDR_W |= MASK_ALE; + break; + } + + this->IO_ADDR_W = (void *)IO_ADDR_W; +} + +/* Set WP on deselect, write enable on select */ +static void nand_davinci_select_chip(struct mtd_info *mtd, int chip) +{ +#define GPIO_SET_DATA01 0x01c67018 +#define GPIO_CLR_DATA01 0x01c6701c +#define GPIO_NAND_WP (1 << 4) +#ifdef SONATA_BOARD_GPIOWP + if (chip < 0) { + REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP; + } else { + REG(GPIO_SET_DATA01) |= GPIO_NAND_WP; + } +#endif +} + +#ifdef CFG_NAND_HW_ECC +#ifdef CFG_NAND_LARGEPAGE +static struct nand_oobinfo davinci_nand_oobinfo = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 12, + .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, + .oobfree = { {2, 6}, {12, 12}, {28, 12}, {44, 12}, {60, 4} } +}; +#elif defined(CFG_NAND_SMALLPAGE) +static struct nand_oobinfo davinci_nand_oobinfo = { + .useecc = MTD_NANDECC_AUTOPLACE, + .eccbytes = 3, + .eccpos = {0, 1, 2}, + .oobfree = { {6, 2}, {8, 8} } +}; +#else +#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" +#endif + +static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode) +{ + emifregs emif_addr; + int dummy; + + emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; + + dummy = emif_addr->NANDF1ECC; + dummy = emif_addr->NANDF2ECC; + dummy = emif_addr->NANDF3ECC; + dummy = emif_addr->NANDF4ECC; + + emif_addr->NANDFCR |= (1 << 8); +} + +static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region) +{ + u_int32_t ecc = 0; + emifregs emif_base_addr; + + emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; + + if (region == 1) + ecc = emif_base_addr->NANDF1ECC; + else if (region == 2) + ecc = emif_base_addr->NANDF2ECC; + else if (region == 3) + ecc = emif_base_addr->NANDF3ECC; + else if (region == 4) + ecc = emif_base_addr->NANDF4ECC; + + return(ecc); +} + +static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) +{ + u_int32_t tmp; + int region, n; + struct nand_chip *this = mtd->priv; + + n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + + region = 1; + while (n--) { + tmp = nand_davinci_readecc(mtd, region); + *ecc_code++ = tmp; + *ecc_code++ = tmp >> 16; + *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0); + region++; + } + return(0); +} + +static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf) +{ + u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8); + + ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp)); + ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp)); + ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp)); +} + +static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data) +{ + u_int32_t i; + u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8]; + u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8]; + u_int8_t ecc_bit[24]; + u_int8_t ecc_sum = 0; + u_int8_t find_bit = 0; + u_int32_t find_byte = 0; + int is_ecc_ff; + + is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff)); + + nand_davinci_gen_true_ecc(ecc_nand); + nand_davinci_gen_true_ecc(ecc_calc); + + for (i = 0; i <= 2; i++) { + *(ecc_nand + i) = ~(*(ecc_nand + i)); + *(ecc_calc + i) = ~(*(ecc_calc + i)); + } + + for (i = 0; i < 8; i++) { + tmp0_bit[i] = *ecc_nand % 2; + *ecc_nand = *ecc_nand / 2; + } + + for (i = 0; i < 8; i++) { + tmp1_bit[i] = *(ecc_nand + 1) % 2; + *(ecc_nand + 1) = *(ecc_nand + 1) / 2; + } + + for (i = 0; i < 8; i++) { + tmp2_bit[i] = *(ecc_nand + 2) % 2; + *(ecc_nand + 2) = *(ecc_nand + 2) / 2; + } + + for (i = 0; i < 8; i++) { + comp0_bit[i] = *ecc_calc % 2; + *ecc_calc = *ecc_calc / 2; + } + + for (i = 0; i < 8; i++) { + comp1_bit[i] = *(ecc_calc + 1) % 2; + *(ecc_calc + 1) = *(ecc_calc + 1) / 2; + } + + for (i = 0; i < 8; i++) { + comp2_bit[i] = *(ecc_calc + 2) % 2; + *(ecc_calc + 2) = *(ecc_calc + 2) / 2; + } + + for (i = 0; i< 6; i++) + ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2]; + + for (i = 0; i < 8; i++) + ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i]; + + for (i = 0; i < 8; i++) + ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i]; + + ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0]; + ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1]; + + for (i = 0; i < 24; i++) + ecc_sum += ecc_bit[i]; + + switch (ecc_sum) { + case 0: + /* Not reached because this function is not called if + ECC values are equal */ + return 0; + case 1: + /* Uncorrectable error */ + DEBUG (MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n"); + return(-1); + case 12: + /* Correctable error */ + find_byte = (ecc_bit[23] << 8) + + (ecc_bit[21] << 7) + + (ecc_bit[19] << 6) + + (ecc_bit[17] << 5) + + (ecc_bit[15] << 4) + + (ecc_bit[13] << 3) + + (ecc_bit[11] << 2) + + (ecc_bit[9] << 1) + + ecc_bit[7]; + + find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1]; + + DEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at offset: %d, bit: %d\n", find_byte, find_bit); + + page_data[find_byte] ^= (1 << find_bit); + + return(0); + default: + if (is_ecc_ff) { + if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0) + return(0); + } + DEBUG (MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n"); + return(-1); + } +} + +static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + struct nand_chip *this; + int block_count = 0, i, rc; + + this = mtd->priv; + block_count = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + for (i = 0; i < block_count; i++) { + if (memcmp(read_ecc, calc_ecc, 3) != 0) { + rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat); + if (rc < 0) { + return(rc); + } + } + read_ecc += 3; + calc_ecc += 3; + dat += 512; + } + return(0); +} +#endif + +static int nand_davinci_dev_ready(struct mtd_info *mtd) +{ + emifregs emif_addr; + + emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; + + return(emif_addr->NANDFSR & 0x1); +} + +static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this, int state) +{ + while(!nand_davinci_dev_ready(mtd)) {;} + *NAND_CE0CLE = NAND_STATUS; + return(*NAND_CE0DATA); +} + +static void nand_flash_init(void) +{ + u_int32_t acfg1 = 0x3ffffffc; + u_int32_t acfg2 = 0x3ffffffc; + u_int32_t acfg3 = 0x3ffffffc; + u_int32_t acfg4 = 0x3ffffffc; + emifregs emif_regs; + + /*------------------------------------------------------------------* + * NAND FLASH CHIP TIMEOUT @ 459 MHz * + * * + * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz * + * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns * + * * + *------------------------------------------------------------------*/ + acfg1 = 0 + | (0 << 31 ) /* selectStrobe */ + | (0 << 30 ) /* extWait */ + | (1 << 26 ) /* writeSetup 10 ns */ + | (3 << 20 ) /* writeStrobe 40 ns */ + | (1 << 17 ) /* writeHold 10 ns */ + | (1 << 13 ) /* readSetup 10 ns */ + | (5 << 7 ) /* readStrobe 60 ns */ + | (1 << 4 ) /* readHold 10 ns */ + | (3 << 2 ) /* turnAround ?? ns */ + | (0 << 0 ) /* asyncSize 8-bit bus */ + ; + + emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; + + emif_regs->AWCCR |= 0x10000000; + emif_regs->AB1CR = acfg1; /* 0x08244128 */; + emif_regs->AB2CR = acfg2; + emif_regs->AB3CR = acfg3; + emif_regs->AB4CR = acfg4; + emif_regs->NANDFCR = 0x00000101; +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA; + nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA; + nand->chip_delay = 0; + nand->select_chip = nand_davinci_select_chip; +#ifdef CFG_NAND_USE_FLASH_BBT + nand->options = NAND_USE_FLASH_BBT; +#endif +#ifdef CFG_NAND_HW_ECC +#ifdef CFG_NAND_LARGEPAGE + nand->eccmode = NAND_ECC_HW12_2048; +#elif defined(CFG_NAND_SMALLPAGE) + nand->eccmode = NAND_ECC_HW3_512; +#else +#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" +#endif + nand->autooob = &davinci_nand_oobinfo; + nand->calculate_ecc = nand_davinci_calculate_ecc; + nand->correct_data = nand_davinci_correct_data; + nand->enable_hwecc = nand_davinci_enable_hwecc; +#else + nand->eccmode = NAND_ECC_SOFT; +#endif + + /* Set address of hardware control function */ + nand->hwcontrol = nand_davinci_hwcontrol; + + nand->dev_ready = nand_davinci_dev_ready; + nand->waitfunc = nand_davinci_waitfunc; + + nand_flash_init(); + + return(0); +} + +#else +#error "U-Boot legacy NAND support not available for DaVinci chips" +#endif +#endif /* CFG_USE_NAND */ diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/reset.S u-boot.git/cpu/arm926ejs/davinci/reset.S --- u-boot.git.orig/cpu/arm926ejs/davinci/reset.S 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/reset.S 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,77 @@ +/* + * Processor reset using WDT for TI TMS320DM644x SoC. + * + * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * ----------------------------------------------------- + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +.globl reset_cpu +reset_cpu: + ldr r0, WDT_TGCR + mov r1, $0x08 + str r1, [r0] + ldr r1, [r0] + orr r1, r1, $0x03 + str r1, [r0] + mov r1, $0 + ldr r0, WDT_TIM12 + str r1, [r0] + ldr r0, WDT_TIM34 + str r1, [r0] + ldr r0, WDT_PRD12 + str r1, [r0] + ldr r0, WDT_PRD34 + str r1, [r0] + ldr r0, WDT_TCR + ldr r1, [r0] + orr r1, r1, $0x40 + str r1, [r0] + ldr r0, WDT_WDTCR + ldr r1, [r0] + orr r1, r1, $0x4000 + str r1, [r0] + ldr r1, WDTCR_VAL1 + str r1, [r0] + ldr r1, WDTCR_VAL2 + str r1, [r0] + nop + nop + nop + nop +reset_cpu_loop: + b reset_cpu_loop + +WDT_TGCR: + .word 0x01c21c24 +WDT_TIM12: + .word 0x01c21c10 +WDT_TIM34: + .word 0x01c21c14 +WDT_PRD12: + .word 0x01c21c18 +WDT_PRD34: + .word 0x01c21c1c +WDT_TCR: + .word 0x01c21c20 +WDT_WDTCR: + .word 0x01c21c28 +WDTCR_VAL1: + .word 0xa5c64000 +WDTCR_VAL2: + .word 0xda7e4000 diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/timer.c u-boot.git/cpu/arm926ejs/davinci/timer.c --- u-boot.git.orig/cpu/arm926ejs/davinci/timer.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/timer.c 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,165 @@ +/* + * (C) Copyright 2003 + * Texas Instruments <www.ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. philippe.robin@arm.com + * + * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <arm926ejs.h> + +typedef volatile struct { + u_int32_t pid12; + u_int32_t emumgt_clksped; + u_int32_t gpint_en; + u_int32_t gpdir_dat; + u_int32_t tim12; + u_int32_t tim34; + u_int32_t prd12; + u_int32_t prd34; + u_int32_t tcr; + u_int32_t tgcr; + u_int32_t wdtcr; + u_int32_t tlgc; + u_int32_t tlmr; +} davinci_timer; + +davinci_timer *timer = (davinci_timer *)CFG_TIMERBASE; + +#define TIMER_LOAD_VAL (CFG_HZ_CLOCK / CFG_HZ) +#define READ_TIMER timer->tim34 + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ + /* We are using timer34 in unchained 32-bit mode, full speed */ + timer->tcr = 0x0; + timer->tgcr = 0x0; + timer->tgcr = 0x06; + timer->tim34 = 0x0; + timer->prd34 = TIMER_LOAD_VAL; + lastinc = 0; + timer->tcr = 0x80 << 16; + timestamp = 0; + + return(0); +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return(get_timer_masked() - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + udelay_masked(usec); +} + +void reset_timer_masked(void) +{ + lastinc = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_raw(void) +{ + ulong now = READ_TIMER; + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + return timestamp; +} + +ulong get_timer_masked(void) +{ + return(get_timer_raw() / TIMER_LOAD_VAL); +} + +void udelay_masked(unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + tmo = CFG_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= 1000; + + endtime = get_timer_raw() + tmo; + + do { + ulong now = get_timer_raw(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return(get_timer(0)); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + ulong tbclk; + + tbclk = CFG_HZ; + return(tbclk); +}

ksi@koi8.net wrote:
Signed-off-by: Sergey Kubushyn ksi@koi8.net
Acked-by: Dirk Behme dirk.behme@gmail.com
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/lowlevel_init.S u-boot.git/cpu/arm926ejs/davinci/lowlevel_init.S --- u-boot.git.orig/cpu/arm926ejs/davinci/lowlevel_init.S 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/lowlevel_init.S 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,707 @@ +/*
- Low-level board setup code for TI DaVinci SoC based boards.
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- Partially based on TI sources, original copyrights follow:
- */
+/*
- Board specific setup info
- (C) Copyright 2003
- Texas Instruments, <www.ti.com>
- Kshitij Gupta Kshitij@ti.com
- Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
- Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004
- See file CREDITS for list of people who contributed to this
- project.
- Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005
- See file CREDITS for list of people who contributed to this
- project.
- Modified for DV-EVM board by Swaminathan S, Nov 2005
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <config.h>
+.globl lowlevel_init +lowlevel_init:
- /*-------------------------------------------------------*
* Mask all IRQs by setting all bits in the EINT default *
*-------------------------------------------------------*/
- mov r1, $0
- ldr r0, =EINT_ENABLE0
- str r1, [r0]
- ldr r0, =EINT_ENABLE1
- str r1, [r0]
- /*------------------------------------------------------*
* Put the GEM in reset *
*------------------------------------------------------*/
- /* Put the GEM in reset */
- ldr r8, PSC_GEM_FLAG_CLEAR
- ldr r6, MDCTL_GEM
- ldr r7, [r6]
- and r7, r7, r8
- str r7, [r6]
- /* Enable the Power Domain Transition Command */
- ldr r6, PTCMD
- ldr r7, [r6]
- orr r7, r7, $0x02
- str r7, [r6]
- /* Check for Transition Complete(PTSTAT) */
+checkStatClkStopGem:
- ldr r6, PTSTAT
- ldr r7, [r6]
- ands r7, r7, $0x02
- bne checkStatClkStopGem
- /* Check for GEM Reset Completion */
+checkGemStatClkStop:
- ldr r6, MDSTAT_GEM
- ldr r7, [r6]
- ands r7, r7, $0x100
- bne checkGemStatClkStop
- /* Do this for enabling a WDT initiated reset this is a workaround
for a chip bug. Not required under normal situations */
- ldr r6, P1394
- mov r10, $0
- str r10, [r6]
- /*------------------------------------------------------*
* Enable L1 & L2 Memories in Fast mode *
*------------------------------------------------------*/
- ldr r6, DFT_ENABLE
- mov r10, $0x01
- str r10, [r6]
- ldr r6, MMARG_BRF0
- ldr r10, MMARG_BRF0_VAL
- str r10, [r6]
- ldr r6, DFT_ENABLE
- mov r10, $0
- str r10, [r6]
- /*------------------------------------------------------*
* DDR2 PLL Initialization *
*------------------------------------------------------*/
- /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */
- mov r10, $0
- ldr r6, PLL2_CTL
- ldr r7, PLL_CLKSRC_MASK
- ldr r8, [r6]
- and r8, r8, r7
- mov r9, r10, lsl $8
- orr r8, r8, r9
- str r8, [r6]
- /* Select the PLLEN source */
- ldr r7, PLL_ENSRC_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Bypass the PLL */
- ldr r7, PLL_BYPASS_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
- mov r10, $0x20
+WaitPPL2Loop:
- subs r10, r10, $1
- bne WaitPPL2Loop
- /* Reset the PLL */
- ldr r7, PLL_RESET_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Power up the PLL */
- ldr r7, PLL_PWRUP_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Enable the PLL from Disable Mode */
- ldr r7, PLL_DISABLE_ENABLE_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Program the PLL Multiplier */
- ldr r6, PLL2_PLLM
- mov r2, $0x17 /* 162 MHz */
- str r2, [r6]
- /* Program the PLL2 Divisor Value */
- ldr r6, PLL2_DIV2
- mov r3, $0x01
- str r3, [r6]
- /* Program the PLL2 Divisor Value */
- ldr r6, PLL2_DIV1
- mov r4, $0x0b /* 54 MHz */
- str r4, [r6]
- /* PLL2 DIV2 MMR */
- ldr r8, PLL2_DIV_MASK
- ldr r6, PLL2_DIV2
- ldr r9, [r6]
- and r8, r8, r9
- mov r9, $0x01
- mov r9, r9, lsl $15
- orr r8, r8, r9
- str r8, [r6]
- /* Program the GOSET bit to take new divider values */
- ldr r6, PLL2_PLLCMD
- ldr r7, [r6]
- orr r7, r7, $0x01
- str r7, [r6]
- /* Wait for Done */
- ldr r6, PLL2_PLLSTAT
+doneLoop_0:
- ldr r7, [r6]
- ands r7, r7, $0x01
- bne doneLoop_0
- /* PLL2 DIV1 MMR */
- ldr r8, PLL2_DIV_MASK
- ldr r6, PLL2_DIV1
- ldr r9, [r6]
- and r8, r8, r9
- mov r9, $0x01
- mov r9, r9, lsl $15
- orr r8, r8, r9
- str r8, [r6]
- /* Program the GOSET bit to take new divider values */
- ldr r6, PLL2_PLLCMD
- ldr r7, [r6]
- orr r7, r7, $0x01
- str r7, [r6]
- /* Wait for Done */
- ldr r6, PLL2_PLLSTAT
+doneLoop:
- ldr r7, [r6]
- ands r7, r7, $0x01
- bne doneLoop
- /* Wait for PLL to Reset Properly */
- mov r10, $0x218
+ResetPPL2Loop:
- subs r10, r10, $1
- bne ResetPPL2Loop
- /* Bring PLL out of Reset */
- ldr r6, PLL2_CTL
- ldr r8, [r6]
- orr r8, r8, $0x08
- str r8, [r6]
- /* Wait for PLL to Lock */
- ldr r10, PLL_LOCK_COUNT
+PLL2Lock:
- subs r10, r10, $1
- bne PLL2Lock
- /* Enable the PLL */
- ldr r6, PLL2_CTL
- ldr r8, [r6]
- orr r8, r8, $0x01
- str r8, [r6]
- /*------------------------------------------------------*
* Issue Soft Reset to DDR Module *
*------------------------------------------------------*/
- /* Shut down the DDR2 LPSC Module */
- ldr r8, PSC_FLAG_CLEAR
- ldr r6, MDCTL_DDR2
- ldr r7, [r6]
- and r7, r7, r8
- orr r7, r7, $0x03
- str r7, [r6]
- /* Enable the Power Domain Transition Command */
- ldr r6, PTCMD
- ldr r7, [r6]
- orr r7, r7, $0x01
- str r7, [r6]
- /* Check for Transition Complete(PTSTAT) */
+checkStatClkStop:
- ldr r6, PTSTAT
- ldr r7, [r6]
- ands r7, r7, $0x01
- bne checkStatClkStop
- /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop:
- ldr r6, MDSTAT_DDR2
- ldr r7, [r6]
- and r7, r7, $0x1f
- cmp r7, $0x03
- bne checkDDRStatClkStop
- /*------------------------------------------------------*
* Program DDR2 MMRs for 162MHz Setting *
*------------------------------------------------------*/
- /* Program PHY Control Register */
- ldr r6, DDRCTL
- ldr r7, DDRCTL_VAL
- str r7, [r6]
- /* Program SDRAM Bank Config Register */
- ldr r6, SDCFG
- ldr r7, SDCFG_VAL
- str r7, [r6]
- /* Program SDRAM TIM-0 Config Register */
- ldr r6, SDTIM0
- ldr r7, SDTIM0_VAL_162MHz
- str r7, [r6]
- /* Program SDRAM TIM-1 Config Register */
- ldr r6, SDTIM1
- ldr r7, SDTIM1_VAL_162MHz
- str r7, [r6]
- /* Program the SDRAM Bank Config Control Register */
- ldr r10, MASK_VAL
- ldr r8, SDCFG
- ldr r9, SDCFG_VAL
- and r9, r9, r10
- str r9, [r8]
- /* Program SDRAM SDREF Config Register */
- ldr r6, SDREF
- ldr r7, SDREF_VAL
- str r7, [r6]
- /*------------------------------------------------------*
* Issue Soft Reset to DDR Module *
*------------------------------------------------------*/
- /* Issue a Dummy DDR2 read/write */
- ldr r8, DDR2_START_ADDR
- ldr r7, DUMMY_VAL
- str r7, [r8]
- ldr r7, [r8]
- /* Shut down the DDR2 LPSC Module */
- ldr r8, PSC_FLAG_CLEAR
- ldr r6, MDCTL_DDR2
- ldr r7, [r6]
- and r7, r7, r8
- orr r7, r7, $0x01
- str r7, [r6]
- /* Enable the Power Domain Transition Command */
- ldr r6, PTCMD
- ldr r7, [r6]
- orr r7, r7, $0x01
- str r7, [r6]
- /* Check for Transition Complete(PTSTAT) */
+checkStatClkStop2:
- ldr r6, PTSTAT
- ldr r7, [r6]
- ands r7, r7, $0x01
- bne checkStatClkStop2
- /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkStop2:
- ldr r6, MDSTAT_DDR2
- ldr r7, [r6]
- and r7, r7, $0x1f
- cmp r7, $0x01
- bne checkDDRStatClkStop2
- /*------------------------------------------------------*
* Turn DDR2 Controller Clocks On *
*------------------------------------------------------*/
- /* Enable the DDR2 LPSC Module */
- ldr r6, MDCTL_DDR2
- ldr r7, [r6]
- orr r7, r7, $0x03
- str r7, [r6]
- /* Enable the Power Domain Transition Command */
- ldr r6, PTCMD
- ldr r7, [r6]
- orr r7, r7, $0x01
- str r7, [r6]
- /* Check for Transition Complete(PTSTAT) */
+checkStatClkEn2:
- ldr r6, PTSTAT
- ldr r7, [r6]
- ands r7, r7, $0x01
- bne checkStatClkEn2
- /* Check for DDR2 Controller Enable Completion */
+checkDDRStatClkEn2:
- ldr r6, MDSTAT_DDR2
- ldr r7, [r6]
- and r7, r7, $0x1f
- cmp r7, $0x03
- bne checkDDRStatClkEn2
- /* DDR Writes and Reads */
- ldr r6, CFGTEST
- mov r3, $0x01
- str r3, [r6]
- /*------------------------------------------------------*
* System PLL Initialization *
*------------------------------------------------------*/
- /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */
- mov r2, $0
- ldr r6, PLL1_CTL
- ldr r7, PLL_CLKSRC_MASK
- ldr r8, [r6]
- and r8, r8, r7
- mov r9, r2, lsl $8
- orr r8, r8, r9
- str r8, [r6]
- /* Select the PLLEN source */
- ldr r7, PLL_ENSRC_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Bypass the PLL */
- ldr r7, PLL_BYPASS_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */
- mov r10, $0x20
+WaitLoop:
- subs r10, r10, $1
- bne WaitLoop
- /* Reset the PLL */
- ldr r7, PLL_RESET_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Disable the PLL */
- orr r8, r8, $0x10
- str r8, [r6]
- /* Power up the PLL */
- ldr r7, PLL_PWRUP_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Enable the PLL from Disable Mode */
- ldr r7, PLL_DISABLE_ENABLE_MASK
- and r8, r8, r7
- str r8, [r6]
- /* Program the PLL Multiplier */
- ldr r6, PLL1_PLLM
- mov r3, $0x15 /* For 594MHz */
- str r3, [r6]
- /* Wait for PLL to Reset Properly */
- mov r10, $0xff
+ResetLoop:
- subs r10, r10, $1
- bne ResetLoop
- /* Bring PLL out of Reset */
- ldr r6, PLL1_CTL
- orr r8, r8, $0x08
- str r8, [r6]
- /* Wait for PLL to Lock */
- ldr r10, PLL_LOCK_COUNT
+PLL1Lock:
- subs r10, r10, $1
- bne PLL1Lock
- /* Enable the PLL */
- orr r8, r8, $0x01
- str r8, [r6]
- nop
- nop
- nop
- nop
- /*------------------------------------------------------*
* AEMIF configuration for NOR Flash (double check) *
*------------------------------------------------------*/
- ldr r0, _PINMUX0
- ldr r1, _DEV_SETTING
- str r1, [r0]
- ldr r0, WAITCFG
- ldr r1, WAITCFG_VAL
- ldr r2, [r0]
- orr r2, r2, r1
- str r2, [r0]
- ldr r0, ACFG3
- ldr r1, ACFG3_VAL
- ldr r2, [r0]
- and r1, r2, r1
- str r1, [r0]
- ldr r0, ACFG4
- ldr r1, ACFG4_VAL
- ldr r2, [r0]
- and r1, r2, r1
- str r1, [r0]
- ldr r0, ACFG5
- ldr r1, ACFG5_VAL
- ldr r2, [r0]
- and r1, r2, r1
- str r1, [r0]
- /*--------------------------------------*
* VTP manual Calibration *
*--------------------------------------*/
- ldr r0, VTPIOCR
- ldr r1, VTP_MMR0
- str r1, [r0]
- ldr r0, VTPIOCR
- ldr r1, VTP_MMR1
- str r1, [r0]
- /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */
- ldr r10, VTP_LOCK_COUNT
+VTPLock:
- subs r10, r10, $1
- bne VTPLock
- ldr r6, DFT_ENABLE
- mov r10, $0x01
- str r10, [r6]
- ldr r6, DDRVTPR
- ldr r7, [r6]
- and r7, r7, $0x1f
- and r8, r7, $0x3e0
- orr r8, r7, r8
- ldr r7, VTP_RECAL
- orr r8, r7, r8
- ldr r7, VTP_EN
- orr r8, r7, r8
- str r8, [r0]
- /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */
- ldr r10, VTP_LOCK_COUNT
+VTP1Lock:
- subs r10, r10, $1
- bne VTP1Lock
- ldr r1, [r0]
- ldr r2, VTP_MASK
- and r2, r1, r2
- str r2, [r0]
- ldr r6, DFT_ENABLE
- mov r10, $0
- str r10, [r6]
- /*
* Call board-specific lowlevel init.
* That MUST be present and THAT returns
* back to arch calling code with "mov pc, lr."
*/
- b dv_board_init
+.ltorg
+_PINMUX0:
- .word 0x01c40000 /* Device Configuration Registers */
+_PINMUX1:
- .word 0x01c40004 /* Device Configuration Registers */
+_DEV_SETTING:
- .word 0x00000c1f
+WAITCFG:
- .word 0x01e00004
+WAITCFG_VAL:
- .word 0
+ACFG3:
- .word 0x01e00014
+ACFG3_VAL:
- .word 0x3ffffffd
+ACFG4:
- .word 0x01e00018
+ACFG4_VAL:
- .word 0x3ffffffd
+ACFG5:
- .word 0x01e0001c
+ACFG5_VAL:
- .word 0x3ffffffd
+MDCTL_DDR2:
- .word 0x01c41a34
+MDSTAT_DDR2:
- .word 0x01c41834
+PTCMD:
- .word 0x01c41120
+PTSTAT:
- .word 0x01c41128
+EINT_ENABLE0:
- .word 0x01c48018
+EINT_ENABLE1:
- .word 0x01c4801c
+PSC_FLAG_CLEAR:
- .word 0xffffffe0
+PSC_GEM_FLAG_CLEAR:
- .word 0xfffffeff
+/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ +DDRCTL:
- .word 0x200000e4
+DDRCTL_VAL:
- .word 0x50006405
+SDREF:
- .word 0x2000000c
+SDREF_VAL:
- .word 0x000005c3
+SDCFG:
- .word 0x20000008
+SDCFG_VAL: +#ifdef DDR_4BANKS
- .word 0x00178622
+#elif defined DDR_8BANKS
- .word 0x00178632
+#else +#error "Unknown DDR configuration!!!" +#endif +SDTIM0:
- .word 0x20000010
+SDTIM0_VAL_162MHz:
- .word 0x28923211
+SDTIM1:
- .word 0x20000014
+SDTIM1_VAL_162MHz:
- .word 0x0016c722
+VTPIOCR:
- .word 0x200000f0 /* VTP IO Control register */
+DDRVTPR:
- .word 0x01c42030 /* DDR VPTR MMR */
+VTP_MMR0:
- .word 0x201f
+VTP_MMR1:
- .word 0xa01f
+DFT_ENABLE:
- .word 0x01c4004c
+VTP_LOCK_COUNT:
- .word 0x5b0
+VTP_MASK:
- .word 0xffffdfff
+VTP_RECAL:
- .word 0x40000
+VTP_EN:
- .word 0x02000
+CFGTEST:
- .word 0x80010000
+MASK_VAL:
- .word 0x00000fff
+/* GEM Power Up & LPSC Control Register */ +MDCTL_GEM:
- .word 0x01c41a9c
+MDSTAT_GEM:
- .word 0x01c4189c
+/* For WDT reset chip bug */ +P1394:
- .word 0x01c41a20
+PLL_CLKSRC_MASK:
- .word 0xfffffeff /* Mask the Clock Mode bit */
+PLL_ENSRC_MASK:
- .word 0xffffffdf /* Select the PLLEN source */
+PLL_BYPASS_MASK:
- .word 0xfffffffe /* Put the PLL in BYPASS */
+PLL_RESET_MASK:
- .word 0xfffffff7 /* Put the PLL in Reset Mode */
+PLL_PWRUP_MASK:
- .word 0xfffffffd /* PLL Power up Mask Bit */
+PLL_DISABLE_ENABLE_MASK:
- .word 0xffffffef /* Enable the PLL from Disable */
+PLL_LOCK_COUNT:
- .word 0x2000
+/* PLL1-SYSTEM PLL MMRs */ +PLL1_CTL:
- .word 0x01c40900
+PLL1_PLLM:
- .word 0x01c40910
+/* PLL2-SYSTEM PLL MMRs */ +PLL2_CTL:
- .word 0x01c40d00
+PLL2_PLLM:
- .word 0x01c40d10
+PLL2_DIV1:
- .word 0x01c40d18
+PLL2_DIV2:
- .word 0x01c40d1c
+PLL2_PLLCMD:
- .word 0x01c40d38
+PLL2_PLLSTAT:
- .word 0x01c40d3c
+PLL2_DIV_MASK:
- .word 0xffff7fff
+MMARG_BRF0:
- .word 0x01c42010 /* BRF margin mode 0 (R/W)*/
+MMARG_BRF0_VAL:
- .word 0x00444400
+DDR2_START_ADDR:
- .word 0x80000000
+DUMMY_VAL:
- .word 0xa55aa55a
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/lxt972.c u-boot.git/cpu/arm926ejs/davinci/lxt972.c --- u-boot.git.orig/cpu/arm926ejs/davinci/lxt972.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/lxt972.c 2007-08-07 10:23:53.000000000 -0700 @@ -0,0 +1,142 @@ +/*
- Intel LXT971/LXT972 PHY Driver for TI DaVinci
- (TMS320DM644x) based boards.
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <net.h> +#include <lxt971a.h> +#include <asm/arch/emac_defs.h>
+#ifdef CONFIG_DRIVER_TI_EMAC
+#ifdef CONFIG_CMD_NET
+int lxt972_is_phy_connected(int phy_addr) +{
- u_int16_t id1, id2;
- if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID1, &id1))
return(0);
- if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_ID2, &id2))
return(0);
- if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0))
return(1);
- return(0);
+}
+int lxt972_get_link_speed(int phy_addr) +{
- u_int16_t stat1, tmp;
- volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR;
- if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1))
return(0);
- if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */
return(0);
- if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
return(0);
- tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE;
- dm644x_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp);
- /* Read back */
- if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp))
return(0);
- /* Speed doesn't matter, there is no setting for it in EMAC... */
- if (stat1 & PHY_LXT971_STAT2_100BTX) {
if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
/* set DM644x EMAC for Full Duplex */
emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
} else {
/*set DM644x EMAC for Half Duplex */
emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
}
return(1);
- } else {
if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) {
/* set DM644x EMAC for Full Duplex */
emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
} else {
/*set DM644x EMAC for Half Duplex */
emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
}
return(1);
- }
- return(0);
+}
+int lxt972_init_phy(int phy_addr) +{
- int ret = 1;
- if (!lxt972_get_link_speed(phy_addr)) {
/* Try another time */
ret = lxt972_get_link_speed(phy_addr);
- }
- /* Disable PHY Interrupts */
- dm644x_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0);
- return(ret);
+}
+int lxt972_auto_negotiate(int phy_addr) +{
- u_int16_t tmp;
- if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_CTRL, &tmp))
return(0);
- /* Restart Auto_negotiation */
- tmp |= PHY_COMMON_CTRL_RES_AUTO;
- dm644x_eth_phy_write(phy_addr, PHY_COMMON_CTRL, tmp);
- /*check AutoNegotiate complete */
- udelay (10000);
- if (!dm644x_eth_phy_read(phy_addr, PHY_COMMON_STAT, &tmp))
return(0);
- if (!(tmp & PHY_COMMON_STAT_AN_COMP))
return(0);
- return (lxt972_get_link_speed(phy_addr));
+}
+#endif /* CONFIG_CMD_NET */
+#endif /* CONFIG_DRIVER_ETHER */ diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/nand.c u-boot.git/cpu/arm926ejs/davinci/nand.c --- u-boot.git.orig/cpu/arm926ejs/davinci/nand.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/nand.c 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,389 @@ +/*
- NAND driver for TI DaVinci based boards.
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- Based on Linux DaVinci NAND driver by TI. Original copyright follows:
- */
+/*
- linux/drivers/mtd/nand/nand_davinci.c
- NAND Flash Driver
- Copyright (C) 2006 Texas Instruments.
- 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- Overview:
- This is a device driver for the NAND flash device found on the
- DaVinci board which utilizes the Samsung k9k2g08 part.
- Modifications:
- ver. 1.0: Feb 2005, Vinod/Sudhakar
- */
+#include <common.h>
+#ifdef CFG_USE_NAND +#if !defined(CFG_NAND_LEGACY)
+#include <nand.h> +#include <asm/arch/nand_defs.h> +#include <asm/arch/emif_defs.h>
+extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd) +{
- struct nand_chip *this = mtd->priv;
- u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
- IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
- switch (cmd) {
case NAND_CTL_SETCLE:
IO_ADDR_W |= MASK_CLE;
break;
case NAND_CTL_SETALE:
IO_ADDR_W |= MASK_ALE;
break;
- }
- this->IO_ADDR_W = (void *)IO_ADDR_W;
+}
+/* Set WP on deselect, write enable on select */ +static void nand_davinci_select_chip(struct mtd_info *mtd, int chip) +{ +#define GPIO_SET_DATA01 0x01c67018 +#define GPIO_CLR_DATA01 0x01c6701c +#define GPIO_NAND_WP (1 << 4) +#ifdef SONATA_BOARD_GPIOWP
- if (chip < 0) {
REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
- } else {
REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
- }
+#endif +}
+#ifdef CFG_NAND_HW_ECC +#ifdef CFG_NAND_LARGEPAGE +static struct nand_oobinfo davinci_nand_oobinfo = {
- .useecc = MTD_NANDECC_AUTOPLACE,
- .eccbytes = 12,
- .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
- .oobfree = { {2, 6}, {12, 12}, {28, 12}, {44, 12}, {60, 4} }
+}; +#elif defined(CFG_NAND_SMALLPAGE) +static struct nand_oobinfo davinci_nand_oobinfo = {
- .useecc = MTD_NANDECC_AUTOPLACE,
- .eccbytes = 3,
- .eccpos = {0, 1, 2},
- .oobfree = { {6, 2}, {8, 8} }
+}; +#else +#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" +#endif
+static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode) +{
- emifregs emif_addr;
- int dummy;
- emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
- dummy = emif_addr->NANDF1ECC;
- dummy = emif_addr->NANDF2ECC;
- dummy = emif_addr->NANDF3ECC;
- dummy = emif_addr->NANDF4ECC;
- emif_addr->NANDFCR |= (1 << 8);
+}
+static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region) +{
- u_int32_t ecc = 0;
- emifregs emif_base_addr;
- emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
- if (region == 1)
ecc = emif_base_addr->NANDF1ECC;
- else if (region == 2)
ecc = emif_base_addr->NANDF2ECC;
- else if (region == 3)
ecc = emif_base_addr->NANDF3ECC;
- else if (region == 4)
ecc = emif_base_addr->NANDF4ECC;
- return(ecc);
+}
+static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) +{
- u_int32_t tmp;
- int region, n;
- struct nand_chip *this = mtd->priv;
- n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
- region = 1;
- while (n--) {
tmp = nand_davinci_readecc(mtd, region);
*ecc_code++ = tmp;
*ecc_code++ = tmp >> 16;
*ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
region++;
- }
- return(0);
+}
+static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf) +{
- u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
- ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
- ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
- ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp));
+}
+static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data) +{
- u_int32_t i;
- u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
- u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8];
- u_int8_t ecc_bit[24];
- u_int8_t ecc_sum = 0;
- u_int8_t find_bit = 0;
- u_int32_t find_byte = 0;
- int is_ecc_ff;
- is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff));
- nand_davinci_gen_true_ecc(ecc_nand);
- nand_davinci_gen_true_ecc(ecc_calc);
- for (i = 0; i <= 2; i++) {
*(ecc_nand + i) = ~(*(ecc_nand + i));
*(ecc_calc + i) = ~(*(ecc_calc + i));
- }
- for (i = 0; i < 8; i++) {
tmp0_bit[i] = *ecc_nand % 2;
*ecc_nand = *ecc_nand / 2;
- }
- for (i = 0; i < 8; i++) {
tmp1_bit[i] = *(ecc_nand + 1) % 2;
*(ecc_nand + 1) = *(ecc_nand + 1) / 2;
- }
- for (i = 0; i < 8; i++) {
tmp2_bit[i] = *(ecc_nand + 2) % 2;
*(ecc_nand + 2) = *(ecc_nand + 2) / 2;
- }
- for (i = 0; i < 8; i++) {
comp0_bit[i] = *ecc_calc % 2;
*ecc_calc = *ecc_calc / 2;
- }
- for (i = 0; i < 8; i++) {
comp1_bit[i] = *(ecc_calc + 1) % 2;
*(ecc_calc + 1) = *(ecc_calc + 1) / 2;
- }
- for (i = 0; i < 8; i++) {
comp2_bit[i] = *(ecc_calc + 2) % 2;
*(ecc_calc + 2) = *(ecc_calc + 2) / 2;
- }
- for (i = 0; i< 6; i++)
ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
- for (i = 0; i < 8; i++)
ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
- for (i = 0; i < 8; i++)
ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
- ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
- ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
- for (i = 0; i < 24; i++)
ecc_sum += ecc_bit[i];
- switch (ecc_sum) {
case 0:
/* Not reached because this function is not called if
ECC values are equal */
return 0;
case 1:
/* Uncorrectable error */
DEBUG (MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
return(-1);
case 12:
/* Correctable error */
find_byte = (ecc_bit[23] << 8) +
(ecc_bit[21] << 7) +
(ecc_bit[19] << 6) +
(ecc_bit[17] << 5) +
(ecc_bit[15] << 4) +
(ecc_bit[13] << 3) +
(ecc_bit[11] << 2) +
(ecc_bit[9] << 1) +
ecc_bit[7];
find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
DEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at offset: %d, bit: %d\n", find_byte, find_bit);
page_data[find_byte] ^= (1 << find_bit);
return(0);
default:
if (is_ecc_ff) {
if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0)
return(0);
}
DEBUG (MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
return(-1);
- }
+}
+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{
- struct nand_chip *this;
- int block_count = 0, i, rc;
- this = mtd->priv;
- block_count = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
- for (i = 0; i < block_count; i++) {
if (memcmp(read_ecc, calc_ecc, 3) != 0) {
rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat);
if (rc < 0) {
return(rc);
}
}
read_ecc += 3;
calc_ecc += 3;
dat += 512;
- }
- return(0);
+} +#endif
+static int nand_davinci_dev_ready(struct mtd_info *mtd) +{
- emifregs emif_addr;
- emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
- return(emif_addr->NANDFSR & 0x1);
+}
+static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this, int state) +{
- while(!nand_davinci_dev_ready(mtd)) {;}
- *NAND_CE0CLE = NAND_STATUS;
- return(*NAND_CE0DATA);
+}
+static void nand_flash_init(void) +{
- u_int32_t acfg1 = 0x3ffffffc;
- u_int32_t acfg2 = 0x3ffffffc;
- u_int32_t acfg3 = 0x3ffffffc;
- u_int32_t acfg4 = 0x3ffffffc;
- emifregs emif_regs;
- /*------------------------------------------------------------------*
* NAND FLASH CHIP TIMEOUT @ 459 MHz *
* *
* AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
* AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
* *
*------------------------------------------------------------------*/
acfg1 = 0
| (0 << 31 ) /* selectStrobe */
| (0 << 30 ) /* extWait */
| (1 << 26 ) /* writeSetup 10 ns */
| (3 << 20 ) /* writeStrobe 40 ns */
| (1 << 17 ) /* writeHold 10 ns */
| (1 << 13 ) /* readSetup 10 ns */
| (5 << 7 ) /* readStrobe 60 ns */
| (1 << 4 ) /* readHold 10 ns */
| (3 << 2 ) /* turnAround ?? ns */
| (0 << 0 ) /* asyncSize 8-bit bus */
;
- emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
- emif_regs->AWCCR |= 0x10000000;
- emif_regs->AB1CR = acfg1; /* 0x08244128 */;
- emif_regs->AB2CR = acfg2;
- emif_regs->AB3CR = acfg3;
- emif_regs->AB4CR = acfg4;
- emif_regs->NANDFCR = 0x00000101;
+}
+int board_nand_init(struct nand_chip *nand) +{
- nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA;
- nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA;
- nand->chip_delay = 0;
- nand->select_chip = nand_davinci_select_chip;
+#ifdef CFG_NAND_USE_FLASH_BBT
- nand->options = NAND_USE_FLASH_BBT;
+#endif +#ifdef CFG_NAND_HW_ECC +#ifdef CFG_NAND_LARGEPAGE
- nand->eccmode = NAND_ECC_HW12_2048;
+#elif defined(CFG_NAND_SMALLPAGE)
- nand->eccmode = NAND_ECC_HW3_512;
+#else +#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" +#endif
- nand->autooob = &davinci_nand_oobinfo;
- nand->calculate_ecc = nand_davinci_calculate_ecc;
- nand->correct_data = nand_davinci_correct_data;
- nand->enable_hwecc = nand_davinci_enable_hwecc;
+#else
- nand->eccmode = NAND_ECC_SOFT;
+#endif
- /* Set address of hardware control function */
- nand->hwcontrol = nand_davinci_hwcontrol;
- nand->dev_ready = nand_davinci_dev_ready;
- nand->waitfunc = nand_davinci_waitfunc;
- nand_flash_init();
- return(0);
+}
+#else +#error "U-Boot legacy NAND support not available for DaVinci chips" +#endif +#endif /* CFG_USE_NAND */ diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/reset.S u-boot.git/cpu/arm926ejs/davinci/reset.S --- u-boot.git.orig/cpu/arm926ejs/davinci/reset.S 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/reset.S 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,77 @@ +/*
- Processor reset using WDT for TI TMS320DM644x SoC.
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+.globl reset_cpu +reset_cpu:
- ldr r0, WDT_TGCR
- mov r1, $0x08
- str r1, [r0]
- ldr r1, [r0]
- orr r1, r1, $0x03
- str r1, [r0]
- mov r1, $0
- ldr r0, WDT_TIM12
- str r1, [r0]
- ldr r0, WDT_TIM34
- str r1, [r0]
- ldr r0, WDT_PRD12
- str r1, [r0]
- ldr r0, WDT_PRD34
- str r1, [r0]
- ldr r0, WDT_TCR
- ldr r1, [r0]
- orr r1, r1, $0x40
- str r1, [r0]
- ldr r0, WDT_WDTCR
- ldr r1, [r0]
- orr r1, r1, $0x4000
- str r1, [r0]
- ldr r1, WDTCR_VAL1
- str r1, [r0]
- ldr r1, WDTCR_VAL2
- str r1, [r0]
- nop
- nop
- nop
- nop
+reset_cpu_loop:
- b reset_cpu_loop
+WDT_TGCR:
- .word 0x01c21c24
+WDT_TIM12:
- .word 0x01c21c10
+WDT_TIM34:
- .word 0x01c21c14
+WDT_PRD12:
- .word 0x01c21c18
+WDT_PRD34:
- .word 0x01c21c1c
+WDT_TCR:
- .word 0x01c21c20
+WDT_WDTCR:
- .word 0x01c21c28
+WDTCR_VAL1:
- .word 0xa5c64000
+WDTCR_VAL2:
- .word 0xda7e4000
diff -purN u-boot.git.orig/cpu/arm926ejs/davinci/timer.c u-boot.git/cpu/arm926ejs/davinci/timer.c --- u-boot.git.orig/cpu/arm926ejs/davinci/timer.c 1969-12-31 16:00:00.000000000 -0800 +++ u-boot.git/cpu/arm926ejs/davinci/timer.c 2007-08-07 10:15:34.000000000 -0700 @@ -0,0 +1,165 @@ +/*
- (C) Copyright 2003
- Texas Instruments <www.ti.com>
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- Marius Groeger mgroeger@sysgo.de
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- Alex Zuepke azu@sysgo.de
- (C) Copyright 2002-2004
- Gary Jennejohn, DENX Software Engineering, gj@denx.de
- (C) Copyright 2004
- Philippe Robin, ARM Ltd. philippe.robin@arm.com
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <arm926ejs.h>
+typedef volatile struct {
- u_int32_t pid12;
- u_int32_t emumgt_clksped;
- u_int32_t gpint_en;
- u_int32_t gpdir_dat;
- u_int32_t tim12;
- u_int32_t tim34;
- u_int32_t prd12;
- u_int32_t prd34;
- u_int32_t tcr;
- u_int32_t tgcr;
- u_int32_t wdtcr;
- u_int32_t tlgc;
- u_int32_t tlmr;
+} davinci_timer;
+davinci_timer *timer = (davinci_timer *)CFG_TIMERBASE;
+#define TIMER_LOAD_VAL (CFG_HZ_CLOCK / CFG_HZ) +#define READ_TIMER timer->tim34
+static ulong timestamp; +static ulong lastinc;
+int timer_init(void) +{
- /* We are using timer34 in unchained 32-bit mode, full speed */
- timer->tcr = 0x0;
- timer->tgcr = 0x0;
- timer->tgcr = 0x06;
- timer->tim34 = 0x0;
- timer->prd34 = TIMER_LOAD_VAL;
- lastinc = 0;
- timer->tcr = 0x80 << 16;
- timestamp = 0;
- return(0);
+}
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return(get_timer_masked() - base);
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void udelay(unsigned long usec) +{
- udelay_masked(usec);
+}
+void reset_timer_masked(void) +{
- lastinc = READ_TIMER;
- timestamp = 0;
+}
+ulong get_timer_raw(void) +{
- ulong now = READ_TIMER;
- if (now >= lastinc) {
/* normal mode */
timestamp += now - lastinc;
- } else {
/* overflow ... */
timestamp += now + TIMER_LOAD_VAL - lastinc;
- }
- lastinc = now;
- return timestamp;
+}
+ulong get_timer_masked(void) +{
- return(get_timer_raw() / TIMER_LOAD_VAL);
+}
+void udelay_masked(unsigned long usec) +{
- ulong tmo;
- ulong endtime;
- signed long diff;
- tmo = CFG_HZ_CLOCK / 1000;
- tmo *= usec;
- tmo /= 1000;
- endtime = get_timer_raw() + tmo;
- do {
ulong now = get_timer_raw();
diff = endtime - now;
- } while (diff >= 0);
+}
+/*
- This function is derived from PowerPC code (read timebase as long long).
- On ARM it just returns the timer value.
- */
+unsigned long long get_ticks(void) +{
- return(get_timer(0));
+}
+/*
- This function is derived from PowerPC code (timebase clock frequency).
- On ARM it returns the number of timer ticks per second.
- */
+ulong get_tbclk(void) +{
- ulong tbclk;
- tbclk = CFG_HZ;
- return(tbclk);
+}
This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users
participants (2)
-
Dirk Behme
-
ksi@koi8.net