diff options
Diffstat (limited to 'arch/arm/cpu/arm926ejs/davinci')
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/Makefile | 59 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/config.mk | 32 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/cpu.c | 191 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/dm355.c | 45 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/dm365.c | 35 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/dm644x.c | 96 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/dm646x.c | 41 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/dp83848.c | 143 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S | 707 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/lxt972.c | 128 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/psc.c | 160 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/reset.S | 81 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/davinci/timer.c | 149 |
13 files changed, 1867 insertions, 0 deletions
diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile new file mode 100644 index 0000000000..d7e9e2ca04 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -0,0 +1,59 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y += cpu.o timer.o psc.o +COBJS-$(CONFIG_SOC_DM355) += dm355.o +COBJS-$(CONFIG_SOC_DM365) += dm365.o +COBJS-$(CONFIG_SOC_DM644X) += dm644x.o +COBJS-$(CONFIG_SOC_DM646X) += dm646x.o +COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o + +SOBJS = reset.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +SOBJS += lowlevel_init.o +endif + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk new file mode 100644 index 0000000000..565adda11d --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# +# 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 +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv5te +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm926ejs/davinci/cpu.c b/arch/arm/cpu/arm926ejs/davinci/cpu.c new file mode 100644 index 0000000000..fc3551c302 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/cpu.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2004 Texas Instruments. + * Copyright (C) 2009 David Brownell + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174 + +#define BIT(x) (1 << (x)) + +/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif + +#ifdef CONFIG_SOC_DM6447 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DA8XX +const dv_reg * const sysdiv[7] = { + &davinci_pllc_regs->plldiv1, &davinci_pllc_regs->plldiv2, + &davinci_pllc_regs->plldiv3, &davinci_pllc_regs->plldiv4, + &davinci_pllc_regs->plldiv5, &davinci_pllc_regs->plldiv6, + &davinci_pllc_regs->plldiv7 +}; + +int clk_get(enum davinci_clk_ids id) +{ + int pre_div; + int pllm; + int post_div; + int pll_out; + + pll_out = CONFIG_SYS_OSCIN_FREQ; + + if (id == DAVINCI_AUXCLK_CLKID) + goto out; + + /* + * Lets keep this simple. Combining operations can result in + * unexpected approximations + */ + pre_div = (readl(&davinci_pllc_regs->prediv) & + DAVINCI_PLLC_DIV_MASK) + 1; + pllm = readl(&davinci_pllc_regs->pllm) + 1; + + pll_out /= pre_div; + pll_out *= pllm; + + if (id == DAVINCI_PLLM_CLKID) + goto out; + + post_div = (readl(&davinci_pllc_regs->postdiv) & + DAVINCI_PLLC_DIV_MASK) + 1; + + pll_out /= post_div; + + if (id == DAVINCI_PLLC_CLKID) + goto out; + + pll_out /= (readl(sysdiv[id - 1]) & DAVINCI_PLLC_DIV_MASK) + 1; + +out: + return pll_out; +} +#endif /* CONFIG_SOC_DA8XX */ + +#ifdef CONFIG_DISPLAY_CPUINFO + +static unsigned pll_div(volatile void *pllbase, unsigned offset) +{ + u32 div; + + div = REG(pllbase + offset); + return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; +} + +static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + /* this register read seems to fail on pll0 */ + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return 8; + else + return pll_div(pllbase, PLLC_PREDIV); +#endif + return 1; +} + +static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + return pll_div(pllbase, PLLC_POSTDIV); +#elif defined(CONFIG_SOC_DM6446) + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return pll_div(pllbase, PLLC_POSTDIV); +#endif + return 1; +} + +static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{ + volatile void *pllbase = (volatile void *) pll_addr; + unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; + + /* the PLL might be bypassed */ + if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { + base /= pll_prediv(pllbase); + base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); + base /= pll_postdiv(pllbase); + } + return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); +} + +int print_cpuinfo(void) +{ + /* REVISIT fetch and display CPU ID and revision information + * too ... that will matter as more revisions appear. + */ + printf("Cores: ARM %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); + +#ifdef DSP_PLLDIV + printf(", DSP %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV)); +#endif + + printf("\nDDR: %d MHz\n", + /* DDR PHY uses an x2 input clock */ + pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) + / 2); + return 0; +} + +#endif + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DRIVER_TI_EMAC) + davinci_emac_initialize(); +#endif + return 0; +} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm355.c b/arch/arm/cpu/arm926ejs/davinci/dm355.c new file mode 100644 index 0000000000..bc45b67fbe --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm355.c @@ -0,0 +1,45 @@ +/* + * SoC-specific code for tms320dm355 and similar chips + * + * Copyright (C) 2009 David Brownell + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; +} + + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX3) |= (1 << 20) | (1 << 19); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm365.c b/arch/arm/cpu/arm926ejs/davinci/dm365.c new file mode 100644 index 0000000000..56c1bc032b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm365.c @@ -0,0 +1,35 @@ +/* + * SoC-specific code for tms320dm365 and similar chips + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); +} + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm644x.c b/arch/arm/cpu/arm926ejs/davinci/dm644x.c new file mode 100644 index 0000000000..bb105b56ee --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm644x.c @@ -0,0 +1,96 @@ +/* + * SoC-specific code for tms320dm644x chips + * + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * Copyright (C) 2004 Texas Instruments. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> + + +#define PINMUX0_EMACEN (1 << 31) +#define PINMUX0_AECS5 (1 << 11) +#define PINMUX0_AECS4 (1 << 10) + +#define PINMUX1_I2C (1 << 7) +#define PINMUX1_UART1 (1 << 1) +#define PINMUX1_UART0 (1 << 0) + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; + + /* Enable UART0 MUX lines */ + REG(PINMUX1) |= PINMUX1_UART0; +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_LPSC_EMAC); + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); + lpsc_on(DAVINCI_LPSC_MDIO); + + /* Enable GIO3.3V cells used for EMAC */ + REG(VDD3P3V_PWDN) = 0; + + /* Enable EMAC. */ + REG(PINMUX0) |= PINMUX0_EMACEN; +} +#endif + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX1) |= PINMUX1_I2C; +} +#endif + +void davinci_errata_workarounds(void) +{ + /* + * Workaround for TMS320DM6446 errata 1.3.22: + * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset + * Revision(s) Affected: 1.3 and earlier + */ + REG(PSC_SILVER_BULLET) = 0; + + /* + * 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. + * A hex value of 0x20 should provide a good ARM (cache enabled) + * performance and still allow good utilization by the VPSS or other + * modules. + */ + REG(VBPR) = 0x20; +} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm646x.c b/arch/arm/cpu/arm926ejs/davinci/dm646x.c new file mode 100644 index 0000000000..329825f453 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dm646x.c @@ -0,0 +1,41 @@ +/* + * SoC-specific code for TMS320DM646x chips + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <asm/arch/hardware.h> + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_UART0); +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_EMAC); +} +#endif + +#ifdef CONFIG_DRIVER_DAVINCI_I2C +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_I2C); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dp83848.c b/arch/arm/cpu/arm926ejs/davinci/dp83848.c new file mode 100644 index 0000000000..c71c685f72 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/dp83848.c @@ -0,0 +1,143 @@ +/* + * National Semiconductor DP83848 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 <dp83848.h> +#include <asm/arch/emac_defs.h> + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int dp83848_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) + return(0); + + if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) + return(1); + + return(0); +} + +int dp83848_get_link_speed(int phy_addr) +{ + u_int16_t tmp; + volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) + return(0); + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (tmp & DP83848_DUPLEX) { + /* 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); +} + + +int dp83848_init_phy(int phy_addr) +{ + int ret = 1; + + if (!dp83848_get_link_speed(phy_addr)) { + /* Try another time */ + udelay(100000); + ret = dp83848_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); + + return(ret); +} + + +int dp83848_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ + tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Set the Auto_negotiation Advertisement Register + * MII advertising for Next page, 100BaseTxFD and HD, + * 10BaseTFD and HD, IEEE 802.3 + */ + tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | + DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; + davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); + + + /* Read Control Register */ + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Restart Auto_negotiation */ + tmp |= DP83848_RESTART_AUTONEG; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /*check AutoNegotiate complete */ + udelay(10000); + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_AUTONEG_COMP)) + return(0); + + return (dp83848_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S new file mode 100644 index 0000000000..0a4b2cf674 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S @@ -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 --git a/arch/arm/cpu/arm926ejs/davinci/lxt972.c b/arch/arm/cpu/arm926ejs/davinci/lxt972.c new file mode 100644 index 0000000000..ce3e41c551 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/lxt972.c @@ -0,0 +1,128 @@ +/* + * 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 <miiphy.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 (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR2, &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 (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) + return(0); + + if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; + + davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); + /* Read back */ + if (!davinci_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_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); +} + + +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 */ + davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); + + return(ret); +} + + +int lxt972_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp |= PHY_BMCR_RST_NEG; + davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp); + + /*check AutoNegotiate complete */ + udelay (10000); + if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + return(0); + + if (!(tmp & PHY_BMSR_AUTN_COMP)) + return(0); + + return (lxt972_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/psc.c b/arch/arm/cpu/arm926ejs/davinci/psc.c new file mode 100644 index 0000000000..8273a7fae4 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/psc.c @@ -0,0 +1,160 @@ +/* + * Power and Sleep Controller (PSC) functions. + * + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * Copyright (C) 2004 Texas Instruments. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* + * The PSC manages three inputs to a "module" which may be a peripheral or + * CPU. Those inputs are the module's: clock; reset signal; and sometimes + * its power domain. For our purposes, we only care whether clock and power + * are active, and the module is out of reset. + * + * DaVinci chips may include two separate power domains: "Always On" and "DSP". + * Chips without a DSP generally have only one domain. + * + * The "Always On" power domain is always on when the chip is on, and is + * powered by the VDD pins (on DM644X). The majority of DaVinci modules + * lie within the "Always On" power domain. + * + * A separate domain called the "DSP" domain houses the C64x+ and other video + * hardware such as VICP. In some chips, the "DSP" domain is not always on. + * The "DSP" power domain is powered by the CVDDDSP pins (on DM644X). + */ + +/* Works on Always On power domain only (no PD argument) */ +void lpsc_on(unsigned int id) +{ + dv_reg_p mdstat, mdctl, ptstat, ptcmd; +#ifdef CONFIG_SOC_DA8XX + struct davinci_psc_regs *psc_regs; +#endif + +#ifndef CONFIG_SOC_DA8XX + if (id >= DAVINCI_LPSC_GEM) + return; /* Don't work on DSP Power Domain */ + + mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); + mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); + ptstat = REG_P(PSC_PTSTAT); + ptcmd = REG_P(PSC_PTCMD); +#else + if (id < DAVINCI_LPSC_PSC1_BASE) { + if (id >= PSC_PSC0_MODULE_ID_CNT) + return; + psc_regs = davinci_psc0_regs; + mdstat = &psc_regs->psc0.mdstat[id]; + mdctl = &psc_regs->psc0.mdctl[id]; + } else { + id -= DAVINCI_LPSC_PSC1_BASE; + if (id >= PSC_PSC1_MODULE_ID_CNT) + return; + psc_regs = davinci_psc1_regs; + mdstat = &psc_regs->psc1.mdstat[id]; + mdctl = &psc_regs->psc1.mdctl[id]; + } + ptstat = &psc_regs->ptstat; + ptcmd = &psc_regs->ptcmd; +#endif + + while (readl(ptstat) & 0x01) + continue; + + if ((readl(mdstat) & 0x1f) == 0x03) + return; /* Already on and enabled */ + + writel(readl(mdctl) | 0x03, mdctl); + + switch (id) { +#ifdef CONFIG_SOC_DM644X + /* Special treatment for some modules as for sprue14 p.7.4.2 */ + case DAVINCI_LPSC_VPSSSLV: + case DAVINCI_LPSC_EMAC: + case DAVINCI_LPSC_EMAC_WRAPPER: + case DAVINCI_LPSC_MDIO: + case DAVINCI_LPSC_USB: + case DAVINCI_LPSC_ATA: + case DAVINCI_LPSC_VLYNQ: + case DAVINCI_LPSC_UHPI: + case DAVINCI_LPSC_DDR_EMIF: + case DAVINCI_LPSC_AEMIF: + case DAVINCI_LPSC_MMC_SD: + case DAVINCI_LPSC_MEMSTICK: + case DAVINCI_LPSC_McBSP: + case DAVINCI_LPSC_GPIO: + writel(readl(mdctl) | 0x200, mdctl); + break; +#endif + } + + writel(0x01, ptcmd); + + while (readl(ptstat) & 0x01) + continue; + while ((readl(mdstat) & 0x1f) != 0x03) + continue; +} + +/* Not all DaVinci chips have a DSP power domain. */ +#ifdef CONFIG_SOC_DM644X + +/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ +#if !defined(CONFIG_SYS_USE_DSPLINK) +void dsp_on(void) +{ + int i; + + if (REG(PSC_PDSTAT1) & 0x1f) + return; /* Already on */ + + REG(PSC_GBLCTL) |= 0x01; + REG(PSC_PDCTL1) |= 0x01; + REG(PSC_PDCTL1) &= ~0x100; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; + REG(PSC_PTCMD) = 0x02; + + for (i = 0; i < 100; i++) { + if (REG(PSC_EPCPR) & 0x02) + break; + } + + REG(PSC_CHP_SHRTSW) = 0x01; + REG(PSC_PDCTL1) |= 0x100; + REG(PSC_EPCCR) = 0x02; + + for (i = 0; i < 100; i++) { + if (!(REG(PSC_PTSTAT) & 0x02)) + break; + } + + REG(PSC_GBLCTL) &= ~0x1f; +} +#endif /* CONFIG_SYS_USE_DSPLINK */ + +#endif /* have a DSP */ diff --git a/arch/arm/cpu/arm926ejs/davinci/reset.S b/arch/arm/cpu/arm926ejs/davinci/reset.S new file mode 100644 index 0000000000..ba0a7c3b4b --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/reset.S @@ -0,0 +1,81 @@ +/* + * 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] + /* Write an invalid value to the WDKEY field to trigger + * an immediate watchdog reset */ + mov r1, $0x4000 + 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 --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c new file mode 100644 index 0000000000..9da7443f30 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/timer.c @@ -0,0 +1,149 @@ +/* + * (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, <garyj@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 <asm/io.h> + +struct davinci_timer { + u_int32_t pid12; + u_int32_t emumgt; + u_int32_t na1; + u_int32_t na2; + 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; +}; + +static struct davinci_timer * const timer = + (struct davinci_timer *)CONFIG_SYS_TIMERBASE; + +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) +#define TIM_CLK_DIV 16 + +static ulong timestamp; +static ulong lastinc; + +int timer_init(void) +{ + /* We are using timer34 in unchained 32-bit mode, full speed */ + writel(0x0, &timer->tcr); + writel(0x0, &timer->tgcr); + writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); + writel(0x0, &timer->tim34); + writel(TIMER_LOAD_VAL, &timer->prd34); + lastinc = 0; + timestamp = 0; + writel(2 << 22, &timer->tcr); + + return(0); +} + +void reset_timer(void) +{ + writel(0x0, &timer->tcr); + writel(0x0, &timer->tim34); + lastinc = 0; + timestamp = 0; + writel(2 << 22, &timer->tcr); +} + +static ulong get_timer_raw(void) +{ + ulong now = readl(&timer->tim34); + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + return timestamp; +} + +ulong get_timer(ulong base) +{ + return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= (1000 * TIM_CLK_DIV); + + 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) +{ + return CONFIG_SYS_HZ; +} |