diff options
114 files changed, 4346 insertions, 502 deletions
@@ -19,6 +19,7 @@ # Top-level generic files # +/MLO /System.map /u-boot /u-boot.hex diff --git a/MAINTAINERS b/MAINTAINERS index 5b2fb57..287938a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -634,6 +634,7 @@ Kristoffer Ericson <kristoffer.ericson@gmail.com> Fabio Estevam <fabio.estevam@freescale.com> + mx25pdk i.MX25 mx31pdk i.MX31 mx53ard i.MX53 mx53smd i.MX53 @@ -797,8 +798,6 @@ Nomadik Linux Team <STN_WMM_nomadik_linux@list.st.com> Steve Sakoman <sakoman@gmail.com> omap3_overo ARM ARMV7 (OMAP3xx SoC) - omap4_panda ARM ARMV7 (OMAP4xx SoC) - omap4_sdp4430 ARM ARMV7 (OMAP4xx SoC) Jens Scharsig <esw@bus-elektronik.de> @@ -838,6 +837,11 @@ Greg Ungerer <greg.ungerer@opengear.com> cm4116 ks8695p cm4148 ks8695p +Aneesh V <aneesh@ti.com> + + omap4_panda ARM ARMV7 (OMAP4xx SoC) + omap4_sdp4430 ARM ARMV7 (OMAP4xx SoC) + Marek Vasut <marek.vasut@gmail.com> balloon3 xscale/pxa @@ -847,6 +851,7 @@ Marek Vasut <marek.vasut@gmail.com> vpac270 xscale/pxa zipitz2 xscale/pxa efikamx i.MX51 + efikasb i.MX51 Hugo Villeneuve <hugo.villeneuve@lyrtech.com> diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index e3a4d1b..c6def5d 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -180,7 +180,7 @@ int print_cpuinfo (void) { u32 srev = get_cpu_rev(); - printf("CPU: Freescale i.MX31 rev %d.%d%s at %d MHz.", + printf("CPU: Freescale i.MX31 rev %d.%d%s at %d MHz.\n", (srev & 0xF0) >> 4, (srev & 0x0F), ((srev & 0x8000) ? " unknown" : ""), mx31_get_mcu_main_clk() / 1000000); diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index c05a39d..717a2b7 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -173,8 +173,8 @@ void mxc_hw_watchdog_enable(void) #else secs = 64; #endif - writew(readw(&wdog->wcr) | (secs << WDOG_WT_SHIFT) | WDOG_ENABLE, - &wdog->wcr); + setbits_le16(&wdog->wcr, (secs << WDOG_WT_SHIFT) | WDOG_ENABLE + | WDOG_WDZST); } diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile index 3183e6a..0310957 100644 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -28,11 +28,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o COBJS-y += cpu.o timer.o psc.o +COBJS-$(CONFIG_AM18018_LOWLEVEL) += am1808_lowlevel.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 et1011c.o +COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o SOBJS = reset.o diff --git a/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c b/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c new file mode 100644 index 0000000..1ea4a9f --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c @@ -0,0 +1,428 @@ +/* + * SoC-specific lowlevel code for AM1808 and similar chips + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <common.h> +#include <nand.h> +#include <ns16550.h> +#include <post.h> +#include <asm/arch/am1808_lowlevel.h> +#include <asm/arch/hardware.h> +#include <asm/arch/ddr2_defs.h> +#include <asm/arch/emif_defs.h> + +void am1808_waitloop(unsigned long loopcnt) +{ + unsigned long i; + + for (i = 0; i < loopcnt; i++) + asm(" NOP"); +} + +int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult) +{ + if (reg == davinci_pllc0_regs) + /* Unlock PLL registers. */ + clrbits_le32(&davinci_syscfg_regs->cfgchip0, 0x00000010); + + /* + * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled + * through MMR + */ + clrbits_le32(®->pllctl, 0x00000020); + /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ + clrbits_le32(®->pllctl, 0x00000200); + + /* Set PLLEN=0 => PLL BYPASS MODE */ + clrbits_le32(®->pllctl, 0x00000001); + + am1808_waitloop(150); + + if (reg == davinci_pllc0_regs) { + /* + * Select the Clock Mode bit 8 as External Clock or On Chip + * Oscilator + */ + dv_maskbits(®->pllctl, 0xFFFFFEFF); + setbits_le32(®->pllctl, (CONFIG_SYS_DV_CLKMODE << 8)); + } + + /* Clear PLLRST bit to reset the PLL */ + clrbits_le32(®->pllctl, 0x00000008); + + /* Disable the PLL output */ + setbits_le32(®->pllctl, 0x00000010); + + /* PLL initialization sequence */ + /* + * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of + * power down bit + */ + clrbits_le32(®->pllctl, 0x00000002); + + /* Enable the PLL from Disable Mode PLLDIS bit to 0 */ + clrbits_le32(®->pllctl, 0x00000010); + + /* Program the required multiplier value in PLLM */ + writel(pllmult, ®->pllm); + + /* program the postdiv */ + if (reg == davinci_pllc0_regs) + writel((0x8000 | CONFIG_SYS_AM1808_PLL0_POSTDIV), + ®->postdiv); + else + writel((0x8000 | CONFIG_SYS_AM1808_PLL1_POSTDIV), + ®->postdiv); + + /* + * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that + * no GO operation is currently in progress + */ + while ((readl(®->pllstat) & 0x1) == 1) + ; + + if (reg == davinci_pllc0_regs) { + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV1, ®->plldiv1); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV2, ®->plldiv2); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV3, ®->plldiv3); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV4, ®->plldiv4); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV5, ®->plldiv5); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV6, ®->plldiv6); + writel(CONFIG_SYS_AM1808_PLL0_PLLDIV7, ®->plldiv7); + } else { + writel(CONFIG_SYS_AM1808_PLL1_PLLDIV1, ®->plldiv1); + writel(CONFIG_SYS_AM1808_PLL1_PLLDIV2, ®->plldiv2); + writel(CONFIG_SYS_AM1808_PLL1_PLLDIV3, ®->plldiv3); + } + + /* + * Set the GOSET bit in PLLCMD to 1 to initiate a new divider + * transition. + */ + setbits_le32(®->pllcmd, 0x01); + + /* + * Wait for the GOSTAT bit in PLLSTAT to clear to 0 + * (completion of phase alignment). + */ + while ((readl(®->pllstat) & 0x1) == 1) + ; + + /* Wait for PLL to reset properly. See PLL spec for PLL reset time */ + am1808_waitloop(200); + + /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */ + setbits_le32(®->pllctl, 0x00000008); + + /* Wait for PLL to lock. See PLL spec for PLL lock time */ + am1808_waitloop(2400); + + /* + * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass + * mode + */ + setbits_le32(®->pllctl, 0x00000001); + + + /* + * clear EMIFA and EMIFB clock source settings, let them + * run off SYSCLK + */ + if (reg == davinci_pllc0_regs) + dv_maskbits(&davinci_syscfg_regs->cfgchip3, 0xFFFFFFF8); + + return 0; +} + +void am1808_lpc_transition(unsigned char pscnum, unsigned char module, + unsigned char domain, unsigned char state) +{ + struct davinci_psc_regs *reg; + dv_reg_p mdstat, mdctl; + + if (pscnum == 0) { + reg = davinci_psc0_regs; + mdstat = ®->psc0.mdstat[module]; + mdctl = ®->psc0.mdctl[module]; + } else { + reg = davinci_psc1_regs; + mdstat = ®->psc1.mdstat[module]; + mdctl = ®->psc1.mdctl[module]; + } + + /* Wait for any outstanding transition to complete */ + while ((readl(®->ptstat) & (0x00000001 << domain))) + ; + + /* If we are already in that state, just return */ + if ((readl(mdstat) & 0x1F) == state) + return; + + /* Perform transition */ + writel((readl(mdctl) & 0xFFFFFFE0) | state, mdctl); + setbits_le32(®->ptcmd, (0x00000001 << domain)); + + /* Wait for transition to complete */ + while (readl(®->ptstat) & (0x00000001 << domain)) + ; + + /* Wait and verify the state */ + while ((readl(mdstat) & 0x1F) != state) + ; +} + +int am1808_ddr_setup(unsigned int freq) +{ + unsigned long tmp; + + /* Enable the Clock to DDR2/mDDR */ + am1808_lpc_transition(1, 6, 0, PSC_ENABLE); + + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) { + /* Begin VTP Calibration */ + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + + /* Polling READY bit to see when VTP calibration is done */ + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + while ((tmp & VTP_READY) != VTP_READY) + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); + + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN); + } + + writel(CONFIG_SYS_AM1808_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr); + clrbits_le32(&davinci_syscfg1_regs->ddr_slew, + (1 << DDR_SLEW_CMOSEN_BIT)); + + setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK); + + writel((CONFIG_SYS_AM1808_DDR2_SDBCR & ~0xf0000000) | + (readl(&dv_ddr2_regs_ctrl->sdbcr) & 0xf0000000), /*rsv Bytes*/ + &dv_ddr2_regs_ctrl->sdbcr); + writel(CONFIG_SYS_AM1808_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2); + + writel(CONFIG_SYS_AM1808_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr); + writel(CONFIG_SYS_AM1808_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2); + + clrbits_le32(&dv_ddr2_regs_ctrl->sdbcr, + (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT)); + + /* + * LPMODEN and MCLKSTOPEN must be set! + * Without this bits set, PSC don;t switch states !! + */ + writel(CONFIG_SYS_AM1808_DDR2_SDRCR | + (1 << DV_DDR_SRCR_LPMODEN_SHIFT) | + (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT), + &dv_ddr2_regs_ctrl->sdrcr); + + /* SyncReset the Clock to EMIF3A SDRAM */ + am1808_lpc_transition(1, 6, 0, PSC_SYNCRESET); + /* Enable the Clock to EMIF3A SDRAM */ + am1808_lpc_transition(1, 6, 0, PSC_ENABLE); + + /* disable self refresh */ + clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, 0xc0000000); + writel(0x30, &dv_ddr2_regs_ctrl->pbbpr); + + return 0; +} + +static void am1808_set_mdctl(dv_reg_p mdctl) +{ + if ((readl(mdctl) & 0x1F) != PSC_ENABLE) + writel(((readl(mdctl) & 0xFFFFFFE0) | PSC_ENABLE), mdctl); +} + +void am1808_psc_init(void) +{ + struct davinci_psc_regs *reg; + int i; + + /* PSC 0 domain 0 init */ + reg = davinci_psc0_regs; + while ((readl(®->ptstat) & 0x00000001)) + ; + + for (i = 3; i <= 4 ; i++) + am1808_set_mdctl(®->psc0.mdctl[i]); + + for (i = 7; i <= 12 ; i++) + am1808_set_mdctl(®->psc0.mdctl[i]); + + /* Do Always-On Power Domain Transitions */ + setbits_le32(®->ptcmd, 0x00000001); + while (readl(®->ptstat) & 0x00000001) + ; + + /* PSC1, domain 1 init */ + reg = davinci_psc1_regs; + while ((readl(®->ptstat) & 0x00000001)) + ; + + am1808_set_mdctl(®->psc1.mdctl[3]); + am1808_set_mdctl(®->psc1.mdctl[6]); + + /* UART1 + UART2 */ + for (i = 12 ; i <= 13 ; i++) + am1808_set_mdctl(®->psc1.mdctl[i]); + + am1808_set_mdctl(®->psc1.mdctl[26]); + am1808_set_mdctl(®->psc1.mdctl[31]); + + /* Do Always-On Power Domain Transitions */ + setbits_le32(®->ptcmd, 0x00000001); + while (readl(®->ptstat) & 0x00000001) + ; +} + +void am1808_pinmux_ctl(unsigned long offset, unsigned long mask, + unsigned long value) +{ + clrbits_le32(&davinci_syscfg_regs->pinmux[offset], mask); + setbits_le32(&davinci_syscfg_regs->pinmux[offset], (mask & value)); +} + +__attribute__((weak)) +void board_gpio_init(void) +{ + return; +} + +#if defined(CONFIG_NAND_SPL) +void nand_boot(void) +{ + __attribute__((noreturn)) void (*uboot)(void); + + /* copy image from NOR to RAM */ + memcpy((void *)CONFIG_SYS_NAND_U_BOOT_DST, + (void *)CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_U_BOOT_SIZE); + + /* and jump to it ... */ + uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; + (*uboot)(); +} +#endif + +#if defined(CONFIG_NAND_SPL) +void board_init_f(ulong bootflag) +#else +int arch_cpu_init(void) +#endif +{ + /* + * copied from arch/arm/cpu/arm926ejs/start.S + * + * flush v4 I/D caches + */ + asm("mov r0, #0"); + asm("mcr p15, 0, r0, c7, c7, 0"); /* flush v3/v4 cache */ + asm("mcr p15, 0, r0, c8, c7, 0"); /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + asm("mrc p15, 0, r0, c1, c0, 0"); + /* clear bits 13, 9:8 (--V- --RS) */ + asm("bic r0, r0, #0x00002300"); + /* clear bits 7, 2:0 (B--- -CAM) */ + asm("bic r0, r0, #0x00000087"); + /* set bit 2 (A) Align */ + asm("orr r0, r0, #0x00000002"); + /* set bit 12 (I) I-Cache */ + asm("orr r0, r0, #0x00001000"); + asm("mcr p15, 0, r0, c1, c0, 0"); + + /* Unlock kick registers */ + writel(0x83e70b13, &davinci_syscfg_regs->kick0); + writel(0x95a4f1e0, &davinci_syscfg_regs->kick1); + + dv_maskbits(&davinci_syscfg_regs->suspsrc, + ((1 << 27) | (1 << 22) | (1 << 20) | (1 << 5) | (1 << 16))); + + /* System PSC setup - enable all */ + am1808_psc_init(); + + /* Setup Pinmux */ + am1808_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX0); + am1808_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX1); + am1808_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX2); + am1808_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX3); + am1808_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX4); + am1808_pinmux_ctl(5, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX5); + am1808_pinmux_ctl(6, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX6); + am1808_pinmux_ctl(7, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX7); + am1808_pinmux_ctl(8, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX8); + am1808_pinmux_ctl(9, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX9); + am1808_pinmux_ctl(10, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX10); + am1808_pinmux_ctl(11, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX11); + am1808_pinmux_ctl(12, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX12); + am1808_pinmux_ctl(13, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX13); + am1808_pinmux_ctl(14, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX14); + am1808_pinmux_ctl(15, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX15); + am1808_pinmux_ctl(16, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX16); + am1808_pinmux_ctl(17, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX17); + am1808_pinmux_ctl(18, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX18); + am1808_pinmux_ctl(19, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX19); + + /* PLL setup */ + am1808_pll_init(davinci_pllc0_regs, CONFIG_SYS_AM1808_PLL0_PLLM); + am1808_pll_init(davinci_pllc1_regs, CONFIG_SYS_AM1808_PLL1_PLLM); + + /* GPIO setup */ + board_gpio_init(); + + /* setup CSn config */ + writel(CONFIG_SYS_AM1808_CS2CFG, &davinci_emif_regs->ab1cr); + writel(CONFIG_SYS_AM1808_CS3CFG, &davinci_emif_regs->ab2cr); + + am1808_lpc_transition(1, 13, 0, PSC_ENABLE); + NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), + CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); + + /* + * Fix Power and Emulation Management Register + * see sprufw3a.pdf page 37 Table 24 + */ + writel(readl((CONFIG_SYS_NS16550_COM1 + 0x30)) | 0x00006001, + (CONFIG_SYS_NS16550_COM1 + 0x30)); +#if defined(CONFIG_NAND_SPL) + puts("ddr init\n"); + am1808_ddr_setup(132); + + puts("boot u-boot ...\n"); + + nand_boot(); +#else + am1808_ddr_setup(132); + return 0; +#endif +} diff --git a/arch/arm/cpu/arm926ejs/davinci/cpu.c b/arch/arm/cpu/arm926ejs/davinci/cpu.c index b705dfd..02819f6 100644 --- a/arch/arm/cpu/arm926ejs/davinci/cpu.c +++ b/arch/arm/cpu/arm926ejs/davinci/cpu.c @@ -115,7 +115,18 @@ int clk_get(enum davinci_clk_ids id) out: return pll_out; } -#endif /* CONFIG_SOC_DA8XX */ +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + printf("Cores: ARM %d MHz", + clk_get(DAVINCI_ARM_CLKID) / 1000000); + printf("\nDDR: %d MHz\n", + /* DDR PHY uses an x2 input clock */ + clk_get(0x10001) / 1000000); + return 0; +} +#endif +#else /* CONFIG_SOC_DA8XX */ #ifdef CONFIG_DISPLAY_CPUINFO @@ -194,7 +205,8 @@ unsigned int davinci_arm_clk_get() return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000; } #endif -#endif +#endif /* CONFIG_DISPLAY_CPUINFO */ +#endif /* !CONFIG_SOC_DA8XX */ /* * Initializes on-chip ethernet controllers. diff --git a/arch/arm/cpu/arm926ejs/davinci/ksz8873.c b/arch/arm/cpu/arm926ejs/davinci/ksz8873.c new file mode 100644 index 0000000..634eda0 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/ksz8873.c @@ -0,0 +1,68 @@ +/* + * Micrel KSZ8873 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2011 Heiko Schocher <hsdenx.de> + * + * based on: + * 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 <miiphy.h> +#include <net.h> +#include <asm/arch/emac_defs.h> +#include <asm/io.h> + +int ksz8873_is_phy_connected(int phy_addr) +{ + u_int16_t dummy; + + return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); +} + +int ksz8873_get_link_speed(int phy_addr) +{ + emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; + + /* we always have a link to the switch, 100 FD */ + writel((EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE), + &emac->MACCONTROL); + return 1; +} + + +int ksz8873_init_phy(int phy_addr) +{ + return 1; +} + + +int ksz8873_auto_negotiate(int phy_addr) +{ + return dp83848_get_link_speed(phy_addr); +} diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c index 8b1734c..c7bf7a5 100644 --- a/arch/arm/cpu/arm926ejs/davinci/timer.c +++ b/arch/arm/cpu/arm926ejs/davinci/timer.c @@ -39,23 +39,10 @@ #include <common.h> #include <asm/io.h> +#include <asm/arch/timer_defs.h> DECLARE_GLOBAL_DATA_PTR; -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; @@ -121,3 +108,34 @@ ulong get_tbclk(void) { return CONFIG_SYS_HZ; } + +#ifdef CONFIG_HW_WATCHDOG +static struct davinci_timer * const wdttimer = + (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; + +/* + * See prufw2.pdf for using Timer as a WDT + */ +void davinci_hw_watchdog_enable(void) +{ + writel(0x0, &wdttimer->tcr); + writel(0x0, &wdttimer->tgcr); + /* TIMMODE = 2h */ + writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr); + writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12); + writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34); + writel(2 << 22, &wdttimer->tcr); + writel(0x0, &wdttimer->tim12); + writel(0x0, &wdttimer->tim34); + /* set WDEN bit, WDKEY 0xa5c6 */ + writel(0xa5c64000, &wdttimer->wdtcr); + /* clear counter register */ + writel(0xda7e4000, &wdttimer->wdtcr); +} + +void davinci_hw_watchdog_reset(void) +{ + writel(0xa5c64000, &wdttimer->wdtcr); + writel(0xda7e4000, &wdttimer->wdtcr); +} +#endif diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c index 76e4b5c..8e60a26 100644 --- a/arch/arm/cpu/arm926ejs/mx25/generic.c +++ b/arch/arm/cpu/arm926ejs/mx25/generic.c @@ -105,13 +105,64 @@ ulong imx_get_perclk (int clk) return lldiv (fref, div); } +u32 get_cpu_rev(void) +{ + u32 srev; + u32 system_rev = 0x25000; + + /* read SREV register from IIM module */ + struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; + srev = readl(&iim->iim_srev); + + switch (srev) { + case 0x00: + system_rev |= CHIP_REV_1_0; + break; + case 0x01: + system_rev |= CHIP_REV_1_1; + break; + default: + system_rev |= 0x8000; + break; + } + + return system_rev; +} + #if defined(CONFIG_DISPLAY_CPUINFO) +static char *get_reset_cause(void) +{ + /* read RCSR register from CCM module */ + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + + u32 cause = readl(&ccm->rcsr) & 0x0f; + + if (cause == 0) + return "POR"; + else if (cause == 1) + return "RST"; + else if ((cause & 2) == 2) + return "WDOG"; + else if ((cause & 4) == 4) + return "SW RESET"; + else if ((cause & 8) == 8) + return "JTAG"; + else + return "unknown reset"; + +} + int print_cpuinfo (void) { char buf[32]; + u32 cpurev = get_cpu_rev(); - printf ("CPU: Freescale i.MX25 at %s MHz\n\n", + printf("CPU: Freescale i.MX25 rev%d.%d%s at %s MHz\n", + (cpurev & 0xF0) >> 4, (cpurev & 0x0F), + ((cpurev & 0x8000) ? " unknown" : ""), strmhz (buf, imx_get_armclk ())); + printf("Reset cause: %s\n\n", get_reset_cause()); return 0; } #endif diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index d164d6d..5e30745 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -51,9 +51,18 @@ */ +#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG .globl _start _start: +.globl _NOR_BOOT_CFG +_NOR_BOOT_CFG: + .word CONFIG_SYS_DV_NOR_BOOT_CFG b reset +#else +.globl _start +_start: + b reset +#endif #ifdef CONFIG_SPL_BUILD /* No exception handlers in preloader */ ldr pc, _hang diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c index 00610a0..0769a64 100644 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -29,11 +29,13 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/crm_regs.h> #include <asm/arch/clock.h> +#include <div64.h> enum pll_clocks { PLL1_CLOCK = 0, PLL2_CLOCK, PLL3_CLOCK, + PLL4_CLOCK, PLL_CLOCKS, }; @@ -41,25 +43,65 @@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, +#ifdef CONFIG_MX53 + [PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR, +#endif }; struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; /* - * Calculate the frequency of this pll. + * Calculate the frequency of PLLn. */ -static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq) +static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) { - u32 mfi, mfn, mfd, pd; + uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret; + uint64_t refclk, temp; + int32_t mfn_abs; + + ctrl = readl(&pll->ctrl); + + if (ctrl & MXC_DPLLC_CTL_HFSM) { + mfn = __raw_readl(&pll->hfs_mfn); + mfd = __raw_readl(&pll->hfs_mfd); + op = __raw_readl(&pll->hfs_op); + } else { + mfn = __raw_readl(&pll->mfn); + mfd = __raw_readl(&pll->mfd); + op = __raw_readl(&pll->op); + } - mfn = __raw_readl(&pll->mfn); - mfd = __raw_readl(&pll->mfd) + 1; - mfi = __raw_readl(&pll->op); - pd = (mfi & 0xF) + 1; - mfi = (mfi >> 4) & 0xF; - mfi = (mfi >= 5) ? mfi : 5; + mfd &= MXC_DPLLC_MFD_MFD_MASK; + mfn &= MXC_DPLLC_MFN_MFN_MASK; + pdf = op & MXC_DPLLC_OP_PDF_MASK; + mfi = (op & MXC_DPLLC_OP_MFI_MASK) >> MXC_DPLLC_OP_MFI_OFFSET; + + /* 21.2.3 */ + if (mfi < 5) + mfi = 5; + + /* Sign extend */ + if (mfn >= 0x04000000) { + mfn |= 0xfc000000; + mfn_abs = -mfn; + } else + mfn_abs = mfn; + + refclk = infreq * 2; + if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN) + refclk *= 2; + + refclk /= pdf + 1; + temp = refclk * mfn_abs; + do_div(temp, mfd + 1); + ret = refclk * mfi; + + if ((int)mfn < 0) + ret -= temp; + else + ret += temp; - return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; + return ret; } /* @@ -99,18 +141,35 @@ static u32 get_periph_clk(void) } /* + * Get the rate of ahb clock. + */ +static u32 get_ahb_clk(void) +{ + uint32_t freq, div, reg; + + freq = get_periph_clk(); + + reg = __raw_readl(&mxc_ccm->cbcdr); + div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> + MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; + + return freq / div; +} + +/* * Get the rate of ipg clock. */ static u32 get_ipg_clk(void) { - u32 ahb_podf, ipg_podf; - - ahb_podf = __raw_readl(&mxc_ccm->cbcdr); - ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET; - ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >> - MXC_CCM_CBCDR_AHB_PODF_OFFSET; - return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1)); + uint32_t freq, reg, div; + + freq = get_ahb_clk(); + + reg = __raw_readl(&mxc_ccm->cbcdr); + div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> + MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; + + return freq / div; } /* @@ -237,7 +296,7 @@ unsigned int mxc_get_clock(enum mxc_clock clk) case MXC_ARM_CLK: return get_mcu_main_clk(); case MXC_AHB_CLK: - break; + return get_ahb_clk(); case MXC_IPG_CLK: return get_ipg_clk(); case MXC_IPG_PERCLK: @@ -274,13 +333,20 @@ int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) u32 freq; freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); - printf("pll1: %dMHz\n", freq / 1000000); + printf("PLL1 %8d MHz\n", freq / 1000000); freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK); - printf("pll2: %dMHz\n", freq / 1000000); + printf("PLL2 %8d MHz\n", freq / 1000000); freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK); - printf("pll3: %dMHz\n", freq / 1000000); - printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK)); - printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK)); + printf("PLL3 %8d MHz\n", freq / 1000000); +#ifdef CONFIG_MX53 + freq = decode_pll(mxc_plls[PLL4_CLOCK], CONFIG_SYS_MX5_HCLK); + printf("PLL4 %8d MHz\n", freq / 1000000); +#endif + + printf("\n"); + printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); + printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); + printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); return 0; } diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index ea9f8ec..0b96b47 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -33,6 +33,12 @@ COBJS += gpio.o ifdef CONFIG_SPL_BUILD COBJS += spl.o +ifdef CONFIG_SPL_NAND_SUPPORT +COBJS += spl_nand.o +endif +ifdef CONFIG_SPL_MMC_SUPPORT +COBJS += spl_mmc.o +endif endif SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index d177652..c76fea6 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -26,6 +26,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <nand.h> #include <mmc.h> #include <fat.h> #include <timestamp_autogenerated.h> @@ -37,14 +38,11 @@ DECLARE_GLOBAL_DATA_PTR; +struct spl_image_info spl_image; + /* Define global data structure pointer to it*/ static gd_t gdata __attribute__ ((section(".data"))); static bd_t bdata __attribute__ ((section(".data"))); -static const char *image_name; -static u8 image_os; -static u32 image_load_addr; -static u32 image_entry_point; -static u32 image_size; inline void hang(void) { @@ -65,154 +63,40 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); } -#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (omap_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0); - break; - case BOOT_DEVICE_MMC2: - omap_mmc_init(1); - break; - } - return 0; -} -#endif - -static void parse_image_header(const struct image_header *header) +void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { - image_size = __be32_to_cpu(header->ih_size) + header_size; - image_entry_point = __be32_to_cpu(header->ih_load); + spl_image.size = __be32_to_cpu(header->ih_size) + header_size; + spl_image.entry_point = __be32_to_cpu(header->ih_load); /* Load including the header */ - image_load_addr = image_entry_point - header_size; - image_os = header->ih_os; - image_name = (const char *)&header->ih_name; + spl_image.load_addr = spl_image.entry_point - header_size; + spl_image.os = header->ih_os; + spl_image.name = (const char *)&header->ih_name; debug("spl: payload image: %s load addr: 0x%x size: %d\n", - image_name, image_load_addr, image_size); + spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); puts("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ - image_size = 200 * 1024; - image_entry_point = CONFIG_SYS_TEXT_BASE; - image_load_addr = CONFIG_SYS_TEXT_BASE; - image_os = IH_OS_U_BOOT; - image_name = "U-Boot"; - } -} - -static void mmc_load_image_raw(struct mmc *mmc) -{ - u32 image_size_sectors, err; - const struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - /* read image header to find the image size & load address */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, - (void *)header); - - if (err <= 0) - goto end; - - parse_image_header(header); - - /* convert size to sectors - round up */ - image_size_sectors = (image_size + MMCSD_SECTOR_SIZE - 1) / - MMCSD_SECTOR_SIZE; - - /* Read the header too to avoid extra memcpy */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, - image_size_sectors, (void *)image_load_addr); - -end: - if (err <= 0) { - printf("spl: mmc blk read err - %d\n", err); - hang(); + spl_image.size = 200 * 1024; + spl_image.entry_point = CONFIG_SYS_TEXT_BASE; + spl_image.load_addr = CONFIG_SYS_TEXT_BASE; + spl_image.os = IH_OS_U_BOOT; + spl_image.name = "U-Boot"; } } -static void mmc_load_image_fat(struct mmc *mmc) -{ - s32 err; - struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - err = fat_register_device(&mmc->block_dev, - CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); - if (err) { - printf("spl: fat register err - %d\n", err); - hang(); - } - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)header, sizeof(struct image_header)); - if (err <= 0) - goto end; - - parse_image_header(header); - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)image_load_addr, 0); - -end: - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); - hang(); - } -} - -static void mmc_load_image(void) -{ - struct mmc *mmc; - int err; - u32 boot_mode; - - mmc_initialize(gd->bd); - /* We register only one device. So, the dev id is always 0 */ - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } - - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - - boot_mode = omap_boot_mode(); - if (boot_mode == MMCSD_MODE_RAW) { - debug("boot mode - RAW\n"); - mmc_load_image_raw(mmc); - } else if (boot_mode == MMCSD_MODE_FAT) { - debug("boot mode - FAT\n"); - mmc_load_image_fat(mmc); - } else { - puts("spl: wrong MMC boot mode\n"); - hang(); - } -} - -void jump_to_image_no_args(void) +static void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = - (image_entry_noargs_t) image_entry_point; + (image_entry_noargs_t) spl_image.entry_point; + debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } @@ -228,17 +112,24 @@ void board_init_r(gd_t *id, ulong dummy) boot_device = omap_boot_device(); debug("boot device - %d\n", boot_device); switch (boot_device) { +#ifdef CONFIG_SPL_MMC_SUPPORT case BOOT_DEVICE_MMC1: case BOOT_DEVICE_MMC2: - mmc_load_image(); + spl_mmc_load_image(); break; +#endif +#ifdef CONFIG_SPL_NAND_SUPPORT + case BOOT_DEVICE_NAND: + spl_nand_load_image(); + break; +#endif default: printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device); hang(); break; } - switch (image_os) { + switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to U-Boot\n"); jump_to_image_no_args(); @@ -249,6 +140,7 @@ void board_init_r(gd_t *id, ulong dummy) } } +/* This requires UART clocks to be enabled */ void preloader_console_init(void) { const char *u_boot_rev = U_BOOT_VERSION; @@ -259,7 +151,6 @@ void preloader_console_init(void) gd->flags |= GD_FLG_RELOC; gd->baudrate = CONFIG_BAUDRATE; - setup_clocks_for_console(); serial_init(); /* serial communications setup */ /* Avoid a second "U-Boot" coming from this string */ diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c new file mode 100644 index 0000000..1d1e50c --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -0,0 +1,150 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * 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/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <mmc.h> +#include <fat.h> +#include <timestamp_autogenerated.h> +#include <version_autogenerated.h> +#include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + switch (omap_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0); + break; + case BOOT_DEVICE_MMC2: + omap_mmc_init(1); + break; + } + return 0; +} +#endif + +static void mmc_load_image_raw(struct mmc *mmc) +{ + u32 image_size_sectors, err; + const struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + /* read image header to find the image size & load address */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, + (void *)header); + + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + /* convert size to sectors - round up */ + image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) / + MMCSD_SECTOR_SIZE; + + /* Read the header too to avoid extra memcpy */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + image_size_sectors, (void *)spl_image.load_addr); + +end: + if (err <= 0) { + printf("spl: mmc blk read err - %d\n", err); + hang(); + } +} + +static void mmc_load_image_fat(struct mmc *mmc) +{ + s32 err; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + err = fat_register_device(&mmc->block_dev, + CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); + if (err) { + printf("spl: fat register err - %d\n", err); + hang(); + } + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)header, sizeof(struct image_header)); + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)spl_image.load_addr, 0); + +end: + if (err <= 0) { + printf("spl: error reading image %s, err - %d\n", + CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); + hang(); + } +} + +void spl_mmc_load_image(void) +{ + struct mmc *mmc; + int err; + u32 boot_mode; + + mmc_initialize(gd->bd); + /* We register only one device. So, the dev id is always 0 */ + mmc = find_mmc_device(0); + if (!mmc) { + puts("spl: mmc device not found!!\n"); + hang(); + } + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc init failed: err - %d\n", err); + hang(); + } + boot_mode = omap_boot_mode(); + if (boot_mode == MMCSD_MODE_RAW) { + debug("boot mode - RAW\n"); + mmc_load_image_raw(mmc); + } else if (boot_mode == MMCSD_MODE_FAT) { + debug("boot mode - FAT\n"); + mmc_load_image_fat(mmc); + } else { + puts("spl: wrong MMC boot mode\n"); + hang(); + } +} diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c new file mode 100644 index 0000000..af02a59 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.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 + */ +#include <common.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <nand.h> +#include <timestamp_autogenerated.h> +#include <version_autogenerated.h> +#include <asm/omap_common.h> + + +void spl_nand_load_image(void) +{ + struct image_header *header; + switch (omap_boot_mode()) { + case NAND_MODE_HW_ECC: + debug("spl: nand - using hw ecc\n"); + gpmc_init(); + nand_init(); + break; + default: + puts("spl: ERROR: This bootmode is not implemented - hanging"); + hang(); + } + + /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); + +#ifdef CONFIG_NAND_ENV_DST + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)image_load_addr); +#ifdef CONFIG_ENV_OFFSET_REDUND + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)image_load_addr); +#endif +#endif + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); +} diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 0448bc9..1b3ef69 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -39,6 +39,7 @@ #include <asm/cache.h> #include <asm/armv7.h> #include <asm/arch/gpio.h> +#include <asm/omap_common.h> /* Declarations */ extern omap3_sysinfo sysinfo; @@ -56,6 +57,41 @@ static const struct gpio_bank gpio_bank_34xx[6] = { const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; +#ifdef CONFIG_SPL_BUILD +/* +* We use static variables because global data is not ready yet. +* Initialized data is available in SPL right from the beginning. +* We would not typically need to save these parameters in regular +* U-Boot. This is needed only in SPL at the moment. +*/ +u32 omap3_boot_device = BOOT_DEVICE_NAND; + +/* auto boot mode detection is not possible for OMAP3 - hard code */ +u32 omap_boot_mode(void) +{ + switch (omap_boot_device()) { + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_RAW; + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_FAT; + break; + case BOOT_DEVICE_NAND: + return NAND_MODE_HW_ECC; + break; + default: + puts("spl: ERROR: unknown device - can't select boot mode\n"); + hang(); + } +} + +u32 omap_boot_device(void) +{ + return omap3_boot_device; +} + +#endif /* CONFIG_SPL_BUILD */ + + /****************************************************************************** * Routine: delay * Description: spinning delay to use before udelay works @@ -197,6 +233,10 @@ void s_init(void) per_clocks_enable(); +#ifdef CONFIG_SPL_BUILD + preloader_console_init(); +#endif + if (!in_sdram) mem_init(); } @@ -245,7 +285,7 @@ void abort(void) { } -#ifdef CONFIG_NAND_OMAP_GPMC +#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD) /****************************************************************************** * OMAP3 specific command to switch between NAND HW and SW ecc *****************************************************************************/ @@ -273,7 +313,7 @@ U_BOOT_CMD( "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm" ); -#endif /* CONFIG_NAND_OMAP_GPMC */ +#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */ #ifdef CONFIG_DISPLAY_BOARDINFO /** @@ -410,3 +450,9 @@ void enable_caches(void) dcache_enable(); } #endif + +void omap_rev_string(char *omap_rev_string) +{ + sprintf(omap_rev_string, "OMAP3, sorry revision detection" \ + " unimplemented"); +} diff --git a/arch/arm/cpu/armv7/omap3/config.mk b/arch/arm/cpu/armv7/omap3/config.mk new file mode 100644 index 0000000..b34fa64 --- /dev/null +++ b/arch/arm/cpu/armv7/omap3/config.mk @@ -0,0 +1,30 @@ +# +# Copyright 2011 Linaro Limited +# See file CREDITS for list of people who contributed to this +# project. +# +# (C) Copyright 2010 +# Texas Instruments, <www.ti.com> +# +# Aneesh V <aneesh@ti.com> +# +# 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 +# +ifdef CONFIG_SPL_BUILD +ALL-y += $(OBJTREE)/MLO +else +ALL-y += $(obj)u-boot.img +endif diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S index 67e8ceb..a308ebd 100644 --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S @@ -35,6 +35,16 @@ _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ +.global save_boot_params +save_boot_params: +#ifdef CONFIG_SPL_BUILD + ldr r4, =omap3_boot_device + ldr r5, [r0, #0x4] + and r5, r5, #0xff + str r5, [r4] +#endif + bx lr + .global omap3_gp_romcode_call omap3_gp_romcode_call: PUSH {r4-r12, lr} @ Save all registers from ROM code! diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 2a7970b..0dd1955 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -8,6 +8,9 @@ * Copyright (C) 2004-2010 * Texas Instruments Incorporated - http://www.ti.com/ * + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * * Author : * Vaibhav Hiremath <hvaibhav@ti.com> * @@ -133,13 +136,40 @@ void do_sdrc_init(u32 cs, u32 early) sdelay(0x20000); } +/* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need + * to prevent this to be build in non-SPL build */ +#ifdef CONFIG_SPL_BUILD + /* If we use a SPL there is no x-loader nor config header so we have + * to do the job ourselfs + */ + if (cs == CS0) { + sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; + + /* General SDRC config */ + writel(V_MCFG, &sdrc_base->cs[cs].mcfg); + writel(V_RFR_CTRL, &sdrc_base->cs[cs].rfr_ctrl); + + /* AC timings */ + writel(V_ACTIMA_165, &sdrc_actim_base0->ctrla); + writel(V_ACTIMB_165, &sdrc_actim_base0->ctrlb); + + /* Initialize */ + writel(CMD_NOP, &sdrc_base->cs[cs].manual); + writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + + writel(V_MR, &sdrc_base->cs[cs].mr); + } +#endif + /* * SDRC timings are set up by x-load or config header * We don't need to redo them here. * Older x-loads configure only CS0 * configure CS1 to handle this ommission */ - if (cs) { + if (cs == CS1) { sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; writel(readl(&sdrc_base->cs[CS0].mcfg), diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c index bdb151d..22887ae 100644 --- a/arch/arm/cpu/armv7/omap3/sys_info.c +++ b/arch/arm/cpu/armv7/omap3/sys_info.c @@ -44,13 +44,13 @@ static char *rev_s[CPU_3XX_MAX_REV] = { "UNKNOWN", "UNKNOWN", "3.1.2"}; -#endif /* CONFIG_DISPLAY_CPUINFO */ /* this is the revision table for 37xx CPUs */ static char *rev_s_37xx[CPU_37XX_MAX_REV] = { "1.0", "1.1", "1.2"}; +#endif /* CONFIG_DISPLAY_CPUINFO */ /***************************************************************** * dieid_num_r(void) - read and set die ID diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 309b244..8584fdd 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -257,6 +257,7 @@ void s_init(void) watchdog_init(); set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD + setup_clocks_for_console(); preloader_console_init(); do_io_settings(); #endif diff --git a/arch/arm/include/asm/arch-armada100/armada100.h b/arch/arm/include/asm/arch-armada100/armada100.h index d5d125a..c449d4e 100644 --- a/arch/arm/include/asm/arch-armada100/armada100.h +++ b/arch/arm/include/asm/arch-armada100/armada100.h @@ -41,8 +41,13 @@ /* Functional Clock Selection Mask */ #define APBC_FNCLKSEL(x) (((x) & 0xf) << 4) +/* Fast Ethernet Controller Clock register definition */ +#define FE_CLK_RST 0x1 +#define FE_CLK_ENA 0x8 + /* Register Base Addresses */ #define ARMD1_DRAM_BASE 0xB0000000 +#define ARMD1_FEC_BASE 0xC0800000 #define ARMD1_TIMER_BASE 0xD4014000 #define ARMD1_APBC1_BASE 0xD4015000 #define ARMD1_APBC2_BASE 0xD4015800 @@ -84,6 +89,59 @@ struct armd1mpmu_registers { }; /* + * Application Subsystem Power Management + * Refer Datasheet Appendix A.9 + */ +struct armd1apmu_registers { + u32 pcr; /* 0x000 */ + u32 ccr; /* 0x004 */ + u32 pad1; + u32 ccsr; /* 0x00C */ + u32 fc_timer; /* 0x010 */ + u32 pad2; + u32 ideal_cfg; /* 0x018 */ + u8 pad3[0x04C - 0x018 - 4]; + u32 lcdcrc; /* 0x04C */ + u32 cciccrc; /* 0x050 */ + u32 sd1crc; /* 0x054 */ + u32 sd2crc; /* 0x058 */ + u32 usbcrc; /* 0x05C */ + u32 nfccrc; /* 0x060 */ + u32 dmacrc; /* 0x064 */ + u32 pad4; + u32 buscrc; /* 0x06C */ + u8 pad5[0x07C - 0x06C - 4]; + u32 wake_clr; /* 0x07C */ + u8 pad6[0x090 - 0x07C - 4]; + u32 core_status; /* 0x090 */ + u32 rfsc; /* 0x094 */ + u32 imr; /* 0x098 */ + u32 irwc; /* 0x09C */ + u32 isr; /* 0x0A0 */ + u8 pad7[0x0B0 - 0x0A0 - 4]; + u32 mhst; /* 0x0B0 */ + u32 msr; /* 0x0B4 */ + u8 pad8[0x0C0 - 0x0B4 - 4]; + u32 msst; /* 0x0C0 */ + u32 pllss; /* 0x0C4 */ + u32 smb; /* 0x0C8 */ + u32 gccrc; /* 0x0CC */ + u8 pad9[0x0D4 - 0x0CC - 4]; + u32 smccrc; /* 0x0D4 */ + u32 pad10; + u32 xdcrc; /* 0x0DC */ + u32 sd3crc; /* 0x0E0 */ + u32 sd4crc; /* 0x0E4 */ + u8 pad11[0x0F0 - 0x0E4 - 4]; + u32 cfcrc; /* 0x0F0 */ + u32 mspcrc; /* 0x0F4 */ + u32 cmucrc; /* 0x0F8 */ + u32 fecrc; /* 0x0FC */ + u32 pciecrc; /* 0x100 */ + u32 epdcrc; /* 0x104 */ +}; + +/* * APB1 Clock Reset/Control Registers * Refer Datasheet Appendix A.10 */ diff --git a/arch/arm/include/asm/arch-armada100/gpio.h b/arch/arm/include/asm/arch-armada100/gpio.h new file mode 100644 index 0000000..9e5e7b9 --- /dev/null +++ b/arch/arm/include/asm/arch-armada100/gpio.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2011 + * eInfochips Ltd. <www.einfochips.com> + * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> + * + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _ASM_ARCH_GPIO_H +#define _ASM_ARCH_GPIO_H + +#include <asm/types.h> +#include <asm/arch/armada100.h> + +#define GPIO_HIGH 1 +#define GPIO_LOW 0 + +#define GPIO_TO_REG(gp) (gp >> 5) +#define GPIO_TO_BIT(gp) (1 << (gp & 0x1F)) +#define GPIO_VAL(gp, val) ((val >> (gp & 0x1F)) & 0x01) + +static inline void *get_gpio_base(int bank) +{ + const unsigned int offset[4] = {0, 4, 8, 0x100}; + /* gpio register bank offset - refer Appendix A.36 */ + return (struct gpio_reg *)(ARMD1_GPIO_BASE + offset[bank]); +} + +#endif /* _ASM_ARCH_GPIO_H */ diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h index d6e0494..da76b58 100644 --- a/arch/arm/include/asm/arch-armada100/mfp.h +++ b/arch/arm/include/asm/arch-armada100/mfp.h @@ -64,6 +64,25 @@ #define MFP105_CI2C_SDA (MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM) #define MFP106_CI2C_SCL (MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM) +/* Fast Ethernet */ +#define MFP086_ETH_TXCLK (MFP_REG(0x158) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP087_ETH_TXEN (MFP_REG(0x15C) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP088_ETH_TXDQ3 (MFP_REG(0x160) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP089_ETH_TXDQ2 (MFP_REG(0x164) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP090_ETH_TXDQ1 (MFP_REG(0x168) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP091_ETH_TXDQ0 (MFP_REG(0x16C) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP092_ETH_CRS (MFP_REG(0x170) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP093_ETH_COL (MFP_REG(0x174) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP094_ETH_RXCLK (MFP_REG(0x178) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP095_ETH_RXER (MFP_REG(0x17C) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP096_ETH_RXDQ3 (MFP_REG(0x180) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP097_ETH_RXDQ2 (MFP_REG(0x184) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP098_ETH_RXDQ1 (MFP_REG(0x188) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP099_ETH_RXDQ0 (MFP_REG(0x18C) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP100_ETH_MDC (MFP_REG(0x190) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP101_ETH_MDIO (MFP_REG(0x194) | MFP_AF5 | MFP_DRIVE_MEDIUM) +#define MFP103_ETH_RXDV (MFP_REG(0x19C) | MFP_AF5 | MFP_DRIVE_MEDIUM) + /* More macros can be defined here... */ #define MFP_PIN_MAX 117 diff --git a/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h b/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h new file mode 100644 index 0000000..0bc7f76 --- /dev/null +++ b/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h @@ -0,0 +1,44 @@ +/* + * SoC-specific lowlevel code for AM1808 and similar chips + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __AM1808_LOWLEVEL_H +#define __AM1808_LOWLEVEL_H + +/* NOR Boot Configuration Word Field Descriptions */ +#define AM1808_NORBOOT_COPY_XK(X) ((X - 1) << 8) +#define AM1808_NORBOOT_METHOD_DIRECT (1 << 4) +#define AM1808_NORBOOT_16BIT (1 << 0) + +#define dv_maskbits(addr, val) \ + writel((readl(addr) & val), addr) + +void am1808_waitloop(unsigned long loopcnt); +int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult); +void am1808_lpc_transition(unsigned char pscnum, unsigned char module, + unsigned char domain, unsigned char state); +int am1808_ddr_setup(unsigned int freq); +void am1808_psc_init(void); +void am1808_pinmux_ctl(unsigned long offset, unsigned long mask, + unsigned long value); + +#endif /* #ifndef __AM1808_LOWLEVEL_H */ diff --git a/arch/arm/include/asm/arch-davinci/ddr2_defs.h b/arch/arm/include/asm/arch-davinci/ddr2_defs.h new file mode 100644 index 0000000..1b9430c --- /dev/null +++ b/arch/arm/include/asm/arch-davinci/ddr2_defs.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@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 + */ +#ifndef _DV_DDR2_DEFS_H_ +#define _DV_DDR2_DEFS_H_ + +/* + * DDR2 Memory Ctrl Register structure + * See sprueh7d.pdf for more details. + */ +struct dv_ddr2_regs_ctrl { + unsigned char rsvd0[4]; /* 0x00 */ + unsigned int sdrstat; /* 0x04 */ + unsigned int sdbcr; /* 0x08 */ + unsigned int sdrcr; /* 0x0C */ + unsigned int sdtimr; /* 0x10 */ + unsigned int sdtimr2; /* 0x14 */ + unsigned char rsvd1[4]; /* 0x18 */ + unsigned int sdbcr2; /* 0x1C */ + unsigned int pbbpr; /* 0x20 */ + unsigned char rsvd2[156]; /* 0x24 */ + unsigned int irr; /* 0xC0 */ + unsigned int imr; /* 0xC4 */ + unsigned int imsr; /* 0xC8 */ + unsigned int imcr; /* 0xCC */ + unsigned char rsvd3[20]; /* 0xD0 */ + unsigned int ddrphycr; /* 0xE4 */ + unsigned int ddrphycr2; /* 0xE8 */ + unsigned char rsvd4[4]; /* 0xEC */ +}; + +#define DV_DDR_PHY_PWRDNEN 0x40 +#define DV_DDR_PHY_EXT_STRBEN 0x80 +#define DV_DDR_PHY_RD_LATENCY_SHIFT 0 + +#define DV_DDR_SDTMR1_RFC_SHIFT 25 +#define DV_DDR_SDTMR1_RP_SHIFT 22 +#define DV_DDR_SDTMR1_RCD_SHIFT 19 +#define DV_DDR_SDTMR1_WR_SHIFT 16 +#define DV_DDR_SDTMR1_RAS_SHIFT 11 +#define DV_DDR_SDTMR1_RC_SHIFT 6 +#define DV_DDR_SDTMR1_RRD_SHIFT 3 +#define DV_DDR_SDTMR1_WTR_SHIFT 0 + +#define DV_DDR_SDTMR2_RASMAX_SHIFT 27 +#define DV_DDR_SDTMR2_XP_SHIFT 25 +#define DV_DDR_SDTMR2_XSNR_SHIFT 16 +#define DV_DDR_SDTMR2_XSRD_SHIFT 8 +#define DV_DDR_SDTMR2_RTP_SHIFT 5 +#define DV_DDR_SDTMR2_CKE_SHIFT 0 + +#define DV_DDR_SDCR_DDR2TERM1_SHIFT 27 +#define DV_DDR_SDCR_IBANK_POS_SHIFT 26 +#define DV_DDR_SDCR_MSDRAMEN_SHIFT 25 +#define DV_DDR_SDCR_DDRDRIVE1_SHIFT 24 +#define DV_DDR_SDCR_BOOTUNLOCK_SHIFT 23 +#define DV_DDR_SDCR_DDR_DDQS_SHIFT 22 +#define DV_DDR_SDCR_DDR2EN_SHIFT 20 +#define DV_DDR_SDCR_DDRDRIVE0_SHIFT 18 +#define DV_DDR_SDCR_DDREN_SHIFT 17 +#define DV_DDR_SDCR_SDRAMEN_SHIFT 16 +#define DV_DDR_SDCR_TIMUNLOCK_SHIFT 15 +#define DV_DDR_SDCR_BUS_WIDTH_SHIFT 14 +#define DV_DDR_SDCR_CL_SHIFT 9 +#define DV_DDR_SDCR_IBANK_SHIFT 4 +#define DV_DDR_SDCR_PAGESIZE_SHIFT 0 + +#define DV_DDR_SRCR_LPMODEN_SHIFT 31 +#define DV_DDR_SRCR_MCLKSTOPEN_SHIFT 30 + +#define DV_DDR_BOOTUNLOCK (1 << DV_DDR_SDCR_BOOTUNLOCK_SHIFT) +#define DV_DDR_TIMUNLOCK (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT) + +#define dv_ddr2_regs_ctrl \ + ((struct dv_ddr2_regs_ctrl *)DAVINCI_DDR_EMIF_CTRL_BASE) + +#endif /* _DV_DDR2_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/emac_defs.h b/arch/arm/include/asm/arch-davinci/emac_defs.h index 4a4ee04..294a9a8 100644 --- a/arch/arm/include/asm/arch-davinci/emac_defs.h +++ b/arch/arm/include/asm/arch-davinci/emac_defs.h @@ -377,6 +377,12 @@ typedef struct int (*auto_negotiate)(int phy_addr); } phy_t; +#define PHY_KSZ8873 (0x00221450) +int ksz8873_is_phy_connected(int phy_addr); +int ksz8873_get_link_speed(int phy_addr); +int ksz8873_init_phy(int phy_addr); +int ksz8873_auto_negotiate(int phy_addr); + #define PHY_LXT972 (0x001378e2) int lxt972_is_phy_connected(int phy_addr); int lxt972_get_link_speed(int phy_addr); diff --git a/arch/arm/include/asm/arch-davinci/gpio.h b/arch/arm/include/asm/arch-davinci/gpio.h index 29dcccf..ef65ffb 100644 --- a/arch/arm/include/asm/arch-davinci/gpio.h +++ b/arch/arm/include/asm/arch-davinci/gpio.h @@ -35,6 +35,7 @@ #define DAVINCI_GPIO_BANK23 0x01E26038 #define DAVINCI_GPIO_BANK45 0x01E26060 #define DAVINCI_GPIO_BANK67 0x01E26088 +#define DAVINCI_GPIO_BANK8 0x01E260B0 #endif /* CONFIG_SOC_DA8XX */ struct davinci_gpio { @@ -62,6 +63,7 @@ struct davinci_gpio_bank { #define davinci_gpio_bank23 ((struct davinci_gpio *)DAVINCI_GPIO_BANK23) #define davinci_gpio_bank45 ((struct davinci_gpio *)DAVINCI_GPIO_BANK45) #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) +#define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8) #define gpio_status() gpio_info() #define GPIO_NAME_SIZE 20 diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h index 692d507..b6a3209 100644 --- a/arch/arm/include/asm/arch-davinci/hardware.h +++ b/arch/arm/include/asm/arch-davinci/hardware.h @@ -128,6 +128,7 @@ typedef volatile unsigned int * dv_reg_p; #define DAVINCI_TIMER0_BASE 0x01c20000 #define DAVINCI_TIMER1_BASE 0x01c21000 #define DAVINCI_WDOG_BASE 0x01c21000 +#define DAVINCI_RTC_BASE 0x01c23000 #define DAVINCI_PLL_CNTRL0_BASE 0x01c11000 #define DAVINCI_PLL_CNTRL1_BASE 0x01e1a000 #define DAVINCI_PSC0_BASE 0x01c10000 @@ -141,8 +142,11 @@ typedef volatile unsigned int * dv_reg_p; #define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x01e22000 #define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x01e20000 #define DAVINCI_MDIO_CNTRL_REGS_BASE 0x01e24000 +#define DAVINCI_SYSCFG1_BASE 0x01e2c000 #define DAVINCI_MMC_SD0_BASE 0x01c40000 #define DAVINCI_MMC_SD1_BASE 0x01e1b000 +#define DAVINCI_TIMER2_BASE 0x01f0c000 +#define DAVINCI_TIMER3_BASE 0x01f0d000 #define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x68000000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x40000000 #define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x60000000 @@ -318,6 +322,11 @@ void davinci_errata_workarounds(void); #else /* CONFIG_SOC_DA8XX */ +#define PSC_ENABLE 0x3 +#define PSC_DISABLE 0x2 +#define PSC_SYNCRESET 0x1 +#define PSC_SWRSTDISABLE 0x0 + #define PSC_PSC0_MODULE_ID_CNT 16 #define PSC_PSC1_MODULE_ID_CNT 32 @@ -445,6 +454,27 @@ struct davinci_syscfg_regs { #define DAVINCI_SYSCFG_SUSPSRC_UART2 (1 << 20) #define DAVINCI_SYSCFG_SUSPSRC_TIMER0 (1 << 27) +struct davinci_syscfg1_regs { + dv_reg vtpio_ctl; + dv_reg ddr_slew; + dv_reg deepsleep; + dv_reg pupd_ena; + dv_reg pupd_sel; + dv_reg rxactive; + dv_reg pwrdwn; +}; + +#define davinci_syscfg1_regs \ + ((struct davinci_syscfg1_regs *)DAVINCI_SYSCFG1_BASE) + +#define DDR_SLEW_CMOSEN_BIT 4 + +#define VTP_POWERDWN (1 << 6) +#define VTP_LOCK (1 << 7) +#define VTP_CLKRZ (1 << 13) +#define VTP_READY (1 << 15) +#define VTP_IOPWRDWN (1 << 14) + /* Interrupt controller */ struct davinci_aintc_regs { dv_reg revid; diff --git a/arch/arm/include/asm/arch-davinci/timer_defs.h b/arch/arm/include/asm/arch-davinci/timer_defs.h new file mode 100644 index 0000000..53c961e --- /dev/null +++ b/arch/arm/include/asm/arch-davinci/timer_defs.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 DENX Software Engineering GmbH + * Heiko Schocher <hs@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 + */ +#ifndef _TIMER_DEFS_H_ +#define _TIMER_DEFS_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; +}; + +#ifdef CONFIG_HW_WATCHDOG +void davinci_hw_watchdog_enable(void); +void davinci_hw_watchdog_reset(void); +#endif +#endif /* _TIMER_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-mx25/imx-regs.h b/arch/arm/include/asm/arch-mx25/imx-regs.h index 9e30f7c..eece138 100644 --- a/arch/arm/include/asm/arch-mx25/imx-regs.h +++ b/arch/arm/include/asm/arch-mx25/imx-regs.h @@ -36,7 +36,6 @@ #ifndef __ASSEMBLY__ #ifdef CONFIG_FEC_MXC extern void mx25_fec_init_pins(void); -extern void imx_get_mac_from_fuse(unsigned char *mac); #endif /* Clock Control Module (CCM) registers */ @@ -351,4 +350,7 @@ struct aips_regs { #define GPIO3_BASE_ADDR IMX_GPIO3_BASE #define GPIO4_BASE_ADDR IMX_GPIO4_BASE +#define CHIP_REV_1_0 0x10 +#define CHIP_REV_1_1 0x11 + #endif /* _IMX_REGS_H */ diff --git a/arch/arm/include/asm/arch-mx25/sys_proto.h b/arch/arm/include/asm/arch-mx25/sys_proto.h new file mode 100644 index 0000000..6a01a7b0 --- /dev/null +++ b/arch/arm/include/asm/arch-mx25/sys_proto.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2009 + * Stefano Babic, DENX Software Engineering, sbabic@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 + */ + +#ifndef _SYS_PROTO_H_ +#define _SYS_PROTO_H_ + +void mx25_uart1_init_pins(void); + +#endif diff --git a/arch/arm/include/asm/arch-mx27/imx-regs.h b/arch/arm/include/asm/arch-mx27/imx-regs.h index b4b2fe6..83ab216 100644 --- a/arch/arm/include/asm/arch-mx27/imx-regs.h +++ b/arch/arm/include/asm/arch-mx27/imx-regs.h @@ -34,7 +34,6 @@ extern void mx27_uart1_init_pins(void); #ifdef CONFIG_FEC_MXC extern void mx27_fec_init_pins(void); -extern void imx_get_mac_from_fuse(unsigned char *mac); #endif /* CONFIG_FEC_MXC */ #ifdef CONFIG_MXC_MMC diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h index 2064870..0dcd9fe 100644 --- a/arch/arm/include/asm/arch-mx31/imx-regs.h +++ b/arch/arm/include/asm/arch-mx31/imx-regs.h @@ -71,6 +71,8 @@ struct cspi_regs { /* Watchdog Timer (WDOG) registers */ #define WDOG_ENABLE (1 << 2) #define WDOG_WT_SHIFT 8 +#define WDOG_WDZST (1 << 0) + struct wdog_regs { u16 wcr; /* Control */ u16 wsr; /* Service */ diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h index e741fb0..0c566f2 100644 --- a/arch/arm/include/asm/arch-mx35/imx-regs.h +++ b/arch/arm/include/asm/arch-mx35/imx-regs.h @@ -178,8 +178,6 @@ #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> -extern void imx_get_mac_from_fuse(unsigned char *mac); - enum mxc_main_clocks { CPU_CLK, AHB_CLK, diff --git a/arch/arm/include/asm/arch-mx5/crm_regs.h b/arch/arm/include/asm/arch-mx5/crm_regs.h index 4ed8eb3..fcc0e36 100644 --- a/arch/arm/include/asm/arch-mx5/crm_regs.h +++ b/arch/arm/include/asm/arch-mx5/crm_regs.h @@ -200,4 +200,15 @@ struct mxc_ccm_reg { /* Define the bits in register CLPCR */ #define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18) +#define MXC_DPLLC_CTL_HFSM (1 << 7) +#define MXC_DPLLC_CTL_DPDCK0_2_EN (1 << 12) + +#define MXC_DPLLC_OP_PDF_MASK 0xf +#define MXC_DPLLC_OP_MFI_MASK (0xf << 4) +#define MXC_DPLLC_OP_MFI_OFFSET 4 + +#define MXC_DPLLC_MFD_MFD_MASK 0x7ffffff + +#define MXC_DPLLC_MFN_MFN_MASK 0x7ffffff + #endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */ diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h index a4e680b..d069209 100644 --- a/arch/arm/include/asm/arch-mx5/imx-regs.h +++ b/arch/arm/include/asm/arch-mx5/imx-regs.h @@ -100,6 +100,9 @@ #define PLL1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) #define PLL2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) #define PLL3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000) +#ifdef CONFIG_MX53 +#define PLL4_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008c000) +#endif #define AHBMAX_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) #define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) #define CSU_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000) @@ -282,8 +285,6 @@ #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> -extern void imx_get_mac_from_fuse(unsigned char *mac); - #define __REG(x) (*((volatile u32 *)(x))) #define __REG16(x) (*((volatile u16 *)(x))) #define __REG8(x) (*((volatile u8 *)(x))) diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h index f165949..8e28f77 100644 --- a/arch/arm/include/asm/arch-omap3/mem.h +++ b/arch/arm/include/asm/arch-omap3/mem.h @@ -128,6 +128,33 @@ enum { (MICRON_XSR_165 << 0) | (MICRON_TXP_165 << 8) | \ (MICRON_TWTR_165 << 16)) +#define MICRON_RAMTYPE 0x1 +#define MICRON_DDRTYPE 0x0 +#define MICRON_DEEPPD 0x1 +#define MICRON_B32NOT16 0x1 +#define MICRON_BANKALLOCATION 0x2 +#define MICRON_RAMSIZE ((PHYS_SDRAM_1_SIZE/(1024*1024))/2) +#define MICRON_ADDRMUXLEGACY 0x1 +#define MICRON_CASWIDTH 0x5 +#define MICRON_RASWIDTH 0x2 +#define MICRON_LOCKSTATUS 0x0 +#define MICRON_V_MCFG ((MICRON_LOCKSTATUS << 30) | (MICRON_RASWIDTH << 24) | \ + (MICRON_CASWIDTH << 20) | (MICRON_ADDRMUXLEGACY << 19) | \ + (MICRON_RAMSIZE << 8) | (MICRON_BANKALLOCATION << 6) | \ + (MICRON_B32NOT16 << 4) | (MICRON_DEEPPD << 3) | \ + (MICRON_DDRTYPE << 2) | (MICRON_RAMTYPE)) + +#define MICRON_ARCV 2030 +#define MICRON_ARE 0x1 +#define MICRON_V_RFR_CTRL ((MICRON_ARCV << 8) | (MICRON_ARE)) + +#define MICRON_BL 0x2 +#define MICRON_SIL 0x0 +#define MICRON_CASL 0x3 +#define MICRON_WBST 0x0 +#define MICRON_V_MR ((MICRON_WBST << 9) | (MICRON_CASL << 4) | \ + (MICRON_SIL << 3) | (MICRON_BL)) + /* * NUMONYX part of IGEP v2 (165MHz optimized) 6.06ns * ACTIMA @@ -171,10 +198,15 @@ enum { #define V_ACTIMA_165 INFINEON_V_ACTIMA_165 #define V_ACTIMB_165 INFINEON_V_ACTIMB_165 #endif + #ifdef CONFIG_OMAP3_MICRON_DDR #define V_ACTIMA_165 MICRON_V_ACTIMA_165 #define V_ACTIMB_165 MICRON_V_ACTIMB_165 +#define V_MCFG MICRON_V_MCFG +#define V_RFR_CTRL MICRON_V_RFR_CTRL +#define V_MR MICRON_V_MR #endif + #ifdef CONFIG_OMAP3_NUMONYX_DDR #define V_ACTIMA_165 NUMONYX_V_ACTIMA_165 #define V_ACTIMB_165 NUMONYX_V_ACTIMB_165 @@ -184,6 +216,10 @@ enum { #error "Please choose the right DDR type in config header" #endif +#if defined(CONFIG_SPL_BUILD) && (!defined(V_MCFG) || !defined(V_RFR_CTRL)) +#error "Please choose the right DDR type in config header" +#endif + /* * GPMC settings - * Definitions is as per the following format diff --git a/arch/arm/include/asm/arch-omap3/omap_gpmc.h b/arch/arm/include/asm/arch-omap3/omap_gpmc.h index bd22bce..800e4ee 100644 --- a/arch/arm/include/asm/arch-omap3/omap_gpmc.h +++ b/arch/arm/include/asm/arch-omap3/omap_gpmc.h @@ -80,4 +80,13 @@ } #endif +/* GPMC CS configuration for an SMSC LAN9221 ethernet controller */ +#define NET_LAN9221_GPMC_CONFIG1 0x00001000 +#define NET_LAN9221_GPMC_CONFIG2 0x00060700 +#define NET_LAN9221_GPMC_CONFIG3 0x00020201 +#define NET_LAN9221_GPMC_CONFIG4 0x06000700 +#define NET_LAN9221_GPMC_CONFIG5 0x0006090A +#define NET_LAN9221_GPMC_CONFIG6 0x87030000 +#define NET_LAN9221_GPMC_CONFIG7 0x00000f6c + #endif /* __ASM_ARCH_OMAP_GPMC_H */ diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 995e7cb..7b60051 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -71,4 +71,5 @@ void power_init_r(void); void dieid_num_r(void); void do_omap3_emu_romcode_call(u32 service_id, u32 parameters); void omap3_gp_romcode_call(u32 service_id, u32 parameter); +void omap_rev_string(char *omap_rev_string); #endif diff --git a/arch/arm/include/asm/arch-omap4/omap4.h b/arch/arm/include/asm/arch-omap4/omap4.h index a6e1e42..fc9c555 100644 --- a/arch/arm/include/asm/arch-omap4/omap4.h +++ b/arch/arm/include/asm/arch-omap4/omap4.h @@ -125,6 +125,10 @@ /* CONTROL_EFUSE_2 */ #define CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1 0x00ffc000 +#define MMC1_PWRDNZ (1 << 26) +#define MMC1_PBIASLITE_PWRDNZ (1 << 22) +#define MMC1_PBIASLITE_VMODE (1 << 21) + #ifndef __ASSEMBLY__ struct s32ktimer { @@ -141,7 +145,9 @@ struct omap4_sys_ctrl_regs { unsigned int control_ldosram_iva_voltage_ctrl; /* 0x4A002320 */ unsigned int control_ldosram_mpu_voltage_ctrl; /* 0x4A002324 */ unsigned int control_ldosram_core_voltage_ctrl; /* 0x4A002328 */ - unsigned int pad3[260341]; + unsigned int pad3[260277]; + unsigned int control_pbiaslite; /* 0x4A100600 */ + unsigned int pad4[63]; unsigned int control_efuse_1; /* 0x4A100700 */ unsigned int control_efuse_2; /* 0x4A100704 */ }; diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index d3cb857..66d6b71 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -37,6 +37,7 @@ void preloader_console_init(void); /* Boot device */ +#ifdef CONFIG_OMAP44XX /* OMAP4 */ #define BOOT_DEVICE_NONE 0 #define BOOT_DEVICE_XIP 1 #define BOOT_DEVICE_XIPWAIT 2 @@ -44,13 +45,43 @@ void preloader_console_init(void); #define BOOT_DEVICE_ONE_NAND 4 #define BOOT_DEVICE_MMC1 5 #define BOOT_DEVICE_MMC2 6 +#elif defined(CONFIG_OMAP34XX) /* OMAP3 */ +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_ONE_NAND 3 +#define BOOT_DEVICE_MMC2 5 /*emmc*/ +#define BOOT_DEVICE_MMC1 6 +#define BOOT_DEVICE_XIPWAIT 7 +#endif /* Boot type */ #define MMCSD_MODE_UNDEFINED 0 #define MMCSD_MODE_RAW 1 #define MMCSD_MODE_FAT 2 +#define NAND_MODE_HW_ECC 3 + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; +}; + +extern struct spl_image_info spl_image; u32 omap_boot_device(void); u32 omap_boot_mode(void); + +/* SPL common function s*/ +void spl_parse_image_header(const struct image_header *header); + +/* NAND SPL functions */ +void spl_nand_load_image(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + #endif /* _OMAP_COMMON_H_ */ diff --git a/board/Marvell/gplugd/gplugd.c b/board/Marvell/gplugd/gplugd.c index dc7d89d..b4f7f81 100644 --- a/board/Marvell/gplugd/gplugd.c +++ b/board/Marvell/gplugd/gplugd.c @@ -32,6 +32,13 @@ #include <mvmfp.h> #include <asm/arch/mfp.h> #include <asm/arch/armada100.h> +#include <asm/gpio.h> +#include <miiphy.h> + +#ifdef CONFIG_ARMADA100_FEC +#include <net.h> +#include <netdev.h> +#endif /* CONFIG_ARMADA100_FEC */ DECLARE_GLOBAL_DATA_PTR; @@ -45,6 +52,26 @@ int board_early_init_f(void) /* Enable Console on UART3 */ MFPO8_UART3_TXD, MFPO9_UART3_RXD, + + /* Ethernet PHY Interface */ + MFP086_ETH_TXCLK, + MFP087_ETH_TXEN, + MFP088_ETH_TXDQ3, + MFP089_ETH_TXDQ2, + MFP090_ETH_TXDQ1, + MFP091_ETH_TXDQ0, + MFP092_ETH_CRS, + MFP093_ETH_COL, + MFP094_ETH_RXCLK, + MFP095_ETH_RXER, + MFP096_ETH_RXDQ3, + MFP097_ETH_RXDQ2, + MFP098_ETH_RXDQ1, + MFP099_ETH_RXDQ0, + MFP100_ETH_MDC, + MFP101_ETH_MDIO, + MFP103_ETH_RXDV, + MFP_EOC /*End of configuration*/ }; /* configure MFP's */ @@ -58,5 +85,49 @@ int board_init(void) gd->bd->bi_arch_number = MACH_TYPE_SHEEVAD; /* adress of boot parameters */ gd->bd->bi_boot_params = armd1_sdram_base(0) + 0x100; + /* Assert PHY_RST# */ + gpio_direction_output(CONFIG_SYS_GPIO_PHY_RST, GPIO_LOW); + udelay(10); + /* Deassert PHY_RST# */ + gpio_set_value(CONFIG_SYS_GPIO_PHY_RST, GPIO_HIGH); return 0; } + +#ifdef CONFIG_ARMADA100_FEC +int board_eth_init(bd_t *bis) +{ + struct armd1apmu_registers *apmu_regs = + (struct armd1apmu_registers *)ARMD1_APMU_BASE; + + /* Enable clock of ethernet controller */ + writel(FE_CLK_RST | FE_CLK_ENA, &apmu_regs->fecrc); + + return armada100_fec_register(ARMD1_FEC_BASE); +} + +#ifdef CONFIG_RESET_PHY_R +/* Configure and initialize PHY chip 88E3015 */ +void reset_phy(void) +{ + u16 phy_adr; + const char *name = "armd-fec0"; + + if (miiphy_set_current_dev(name)) + return; + + /* command to read PHY dev address */ + if (miiphy_read(name, 0xff, 0xff, &phy_adr)) { + printf("Err..%s could not read PHY dev address\n", __func__); + return; + } + + /* Set Ethernet LED in TX blink mode */ + miiphy_write(name, phy_adr, PHY_LED_MAN_REG, 0x00); + miiphy_write(name, phy_adr, PHY_LED_PAR_SEL_REG, PHY_LED_VAL); + + /* reset the phy */ + miiphy_reset(name, phy_adr); + debug("88E3015 Initialized on %s\n", name); +} +#endif /* CONFIG_RESET_PHY_R */ +#endif /* CONFIG_ARMADA100_FEC */ diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c index 5be1f6c..0c4e24b 100644 --- a/board/efikamx/efikamx.c +++ b/board/efikamx/efikamx.c @@ -62,10 +62,13 @@ void efikamx_toggle_led(uint32_t mask); #define EFIKAMX_BOARD_REV_13 0x3 #define EFIKAMX_BOARD_REV_14 0x4 +#define EFIKASB_BOARD_REV_13 0x1 +#define EFIKASB_BOARD_REV_20 0x2 + /* * Board identification */ -u32 get_efika_rev(void) +u32 get_efikamx_rev(void) { u32 rev = 0; /* @@ -97,6 +100,31 @@ u32 get_efika_rev(void) return (~rev & 0x7) + 1; } +inline u32 get_efikasb_rev(void) +{ + u32 rev = 0; + + mxc_request_iomux(MX51_PIN_EIM_CS3, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_EIM_CS3, PAD_CTL_100K_PU); + gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_EIM_CS3)); + rev |= (!!gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS3))) << 0; + + mxc_request_iomux(MX51_PIN_EIM_CS4, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_EIM_CS4, PAD_CTL_100K_PU); + gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_EIM_CS4)); + rev |= (!!gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS4))) << 1; + + return rev; +} + +inline uint32_t get_efika_rev(void) +{ + if (machine_is_efikamx()) + return get_efikamx_rev(); + else + return get_efikasb_rev(); +} + u32 get_board_rev(void) { return get_cpu_rev() | (get_efika_rev() << 8); @@ -268,25 +296,36 @@ struct fsl_esdhc_cfg esdhc_cfg[2] = { {MMC_SDHC2_BASE_ADDR, 1}, }; +static inline uint32_t efika_mmc_cd(void) +{ + if (machine_is_efikamx()) + return MX51_PIN_GPIO1_0; + else + return MX51_PIN_EIM_CS2; +} + int board_mmc_getcd(u8 *absent, struct mmc *mmc) { struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + uint32_t cd = efika_mmc_cd(); if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) - *absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0)); + *absent = gpio_get_value(IOMUX_TO_GPIO(cd)); else *absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8)); return 0; } + int board_mmc_init(bd_t *bis) { int ret; + uint32_t cd = efika_mmc_cd(); /* SDHC1 is used on all revisions, setup control pins first */ - mxc_request_iomux(MX51_PIN_GPIO1_0, + mxc_request_iomux(cd, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION); - mxc_iomux_set_pad(MX51_PIN_GPIO1_0, + mxc_iomux_set_pad(cd, PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | @@ -298,11 +337,12 @@ int board_mmc_init(bd_t *bis) PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_SRE_FAST); - gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0)); + gpio_direction_input(IOMUX_TO_GPIO(cd)); gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_GPIO1_1)); /* Internal SDHC1 IOMUX + SDHC2 IOMUX on old boards */ - if (get_efika_rev() < EFIKAMX_BOARD_REV_12) { + if (machine_is_efikasb() || (machine_is_efikamx() && + (get_efika_rev() < EFIKAMX_BOARD_REV_12))) { /* SDHC1 IOMUX */ mxc_request_iomux(MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION); @@ -414,6 +454,7 @@ int board_mmc_init(bd_t *bis) ret = fsl_esdhc_initialize(bis, &esdhc_cfg[0]); } + return ret; } #endif @@ -493,27 +534,44 @@ static inline void setup_iomux_ata(void) { } */ void setup_iomux_led(void) { - /* Blue LED */ - mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0); - - /* Green LED */ - mxc_request_iomux(MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT3); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), 0); - - /* Red LED */ - mxc_request_iomux(MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT3); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), 0); + if (machine_is_efikamx()) { + /* Blue LED */ + mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0); + + /* Green LED */ + mxc_request_iomux(MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT3); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), 0); + + /* Red LED */ + mxc_request_iomux(MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT3); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), 0); + } else { + /* CAPS-LOCK LED */ + mxc_request_iomux(MX51_PIN_EIM_CS0, IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_CS0), 0); + + /* ALARM-LED LED */ + mxc_request_iomux(MX51_PIN_GPIO1_3, IOMUX_CONFIG_GPIO); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_GPIO1_3), 0); + } } void efikamx_toggle_led(uint32_t mask) { - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), - mask & EFIKAMX_LED_BLUE); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), - mask & EFIKAMX_LED_GREEN); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), - mask & EFIKAMX_LED_RED); + if (machine_is_efikamx()) { + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), + mask & EFIKAMX_LED_BLUE); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), + mask & EFIKAMX_LED_GREEN); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), + mask & EFIKAMX_LED_RED); + } else { + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS0), + mask & EFIKAMX_LED_BLUE); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_3), + !(mask & EFIKAMX_LED_GREEN)); + } } /* @@ -607,7 +665,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX51_EFIKAMX; gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; return 0; @@ -629,7 +686,24 @@ int board_late_init(void) int checkboard(void) { - puts("Board: Efika MX\n"); + u32 rev = get_efika_rev(); + + if (machine_is_efikamx()) { + printf("Board: Efika MX, rev1.%i\n", rev & 0xf); + return 0; + } else { + switch (rev) { + case EFIKASB_BOARD_REV_13: + printf("Board: Efika SB rev1.3\n"); + break; + case EFIKASB_BOARD_REV_20: + printf("Board: Efika SB rev2.0\n"); + break; + default: + printf("Board: Efika SB, rev Unknown\n"); + break; + } + } return 0; } diff --git a/board/efikamx/imximage.cfg b/board/efikamx/imximage_mx.cfg index 6fe0ff9..6fe0ff9 100644 --- a/board/efikamx/imximage.cfg +++ b/board/efikamx/imximage_mx.cfg diff --git a/board/efikamx/imximage_sb.cfg b/board/efikamx/imximage_sb.cfg new file mode 100644 index 0000000..878146f --- /dev/null +++ b/board/efikamx/imximage_sb.cfg @@ -0,0 +1,122 @@ +# +# Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> +# +# BASED ON: imx51evk +# +# (C) Copyright 2009 +# Stefano Babic DENX Software Engineering sbabic@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. 51 Franklin Street Fifth Floor Boston, +# MA 02110-1301 USA +# +# Refer docs/README.imxmage for more details about how-to configure +# and create imximage boot image +# +# The syntax is taken as close as possible with the kwbimage + +# Boot Device : one of +# spi, sd (the board has no nand neither onenand) +BOOT_FROM spi + +# Device Configuration Data (DCD) +# +# Each entry must have the format: +# Addr-type Address Value +# +# where: +# Addr-type register length (1,2 or 4 bytes) +# Address absolute address of the register +# value value to be stored in the register + +# Setting IOMUXC +DATA 4 0x73fa88a0 0x200 +DATA 4 0x73fa850c 0x20c3 +DATA 4 0x73fa8510 0x20c3 +DATA 4 0x73fa883c 0x2 +DATA 4 0x73fa8848 0x2 +DATA 4 0x73fa84b8 0xe7 +DATA 4 0x73fa84bc 0x45 +DATA 4 0x73fa84c0 0x45 +DATA 4 0x73fa84c4 0x45 +DATA 4 0x73fa84c8 0x45 +DATA 4 0x73fa8820 0x0 +DATA 4 0x73fa84a4 0x5 +DATA 4 0x73fa84a8 0x5 +DATA 4 0x73fa84ac 0xe3 +DATA 4 0x73fa84b0 0xe3 +DATA 4 0x73fa84b4 0xe3 +DATA 4 0x73fa84cc 0xe3 +DATA 4 0x73fa84d0 0xe2 + +DATA 4 0x73fa882c 0x4 +DATA 4 0x73fa88a4 0x4 +DATA 4 0x73fa88ac 0x4 +DATA 4 0x73fa88b8 0x4 + +# Setting DDR for micron +# 13 Rows, 10 Cols, 32 bit, SREF=4 Micron Model +# CAS=3 BL=4 +# ESDCTL_ESDCTL0 +DATA 4 0x83fd9000 0x82a20000 +# ESDCTL_ESDCTL1 +DATA 4 0x83fd9008 0x82a20000 +# ESDCTL_ESDMISC +DATA 4 0x83fd9010 0xcaaaf6d0 +# ESDCTL_ESDCFG0 +DATA 4 0x83fd9004 0x333574aa +# ESDCTL_ESDCFG1 +DATA 4 0x83fd900c 0x333574aa + +# Init DRAM on CS0 +# ESDCTL_ESDSCR +DATA 4 0x83fd9014 0x04008008 +DATA 4 0x83fd9014 0x0000801a +DATA 4 0x83fd9014 0x0000801b +DATA 4 0x83fd9014 0x00448019 +DATA 4 0x83fd9014 0x07328018 +DATA 4 0x83fd9014 0x04008008 +DATA 4 0x83fd9014 0x00008010 +DATA 4 0x83fd9014 0x00008010 +DATA 4 0x83fd9014 0x06328018 +DATA 4 0x83fd9014 0x03808019 +DATA 4 0x83fd9014 0x00408019 +DATA 4 0x83fd9014 0x00008000 + +# Init DRAM on CS1 +DATA 4 0x83fd9014 0x0400800c +DATA 4 0x83fd9014 0x0000801e +DATA 4 0x83fd9014 0x0000801f +DATA 4 0x83fd9014 0x0000801d +DATA 4 0x83fd9014 0x0732801c +DATA 4 0x83fd9014 0x0400800c +DATA 4 0x83fd9014 0x00008014 +DATA 4 0x83fd9014 0x00008014 +DATA 4 0x83fd9014 0x0632801c +DATA 4 0x83fd9014 0x0380801d +DATA 4 0x83fd9014 0x0040801d +DATA 4 0x83fd9014 0x00008004 + +# Write to CTL0 +DATA 4 0x83fd9000 0xb2a20000 +# Write to CTL1 +DATA 4 0x83fd9008 0xb2a20000 +# ESDMISC +DATA 4 0x83fd9010 0xcaaaf6d0 +#ESDCTL_ESDCDLYGD +DATA 4 0x83fd9034 0x90000000 +DATA 4 0x83fd9014 0x00000000 diff --git a/board/freescale/mx25pdk/Makefile b/board/freescale/mx25pdk/Makefile new file mode 100644 index 0000000..4d45ae3 --- /dev/null +++ b/board/freescale/mx25pdk/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> +# +# (C) Copyright 2011 Freescale Semiconductor, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS := mx25pdk.o +SOBJS := lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/mx25pdk/imximage.cfg b/board/freescale/mx25pdk/imximage.cfg new file mode 100644 index 0000000..f7af7ff --- /dev/null +++ b/board/freescale/mx25pdk/imximage.cfg @@ -0,0 +1,73 @@ +# +# (C) Copyright 2009 +# Stefano Babic DENX Software Engineering sbabic@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. +# +# Refer docs/README.imxmage for more details about how-to configure +# and create imximage boot image +# +# The syntax is taken as close as possible with the kwbimage + +# Boot Device : one of +# spi, sd (the board has no nand neither onenand) + +BOOT_FROM sd + +# Device Configuration Data (DCD) +# +# Each entry must have the format: +# Addr-type Address Value +# +# where: +# Addr-type register length (1,2 or 4 bytes) +# Address absolute address of the register +# value value to be stored in the register + +# EIM config-CS5 init -- CPLD +DATA 4 0xB8002050 0x0000D843 +DATA 4 0xB8002054 0x22252521 +DATA 4 0xB8002058 0x22220A00 + +# DDR2 init +DATA 4 0xB8001004 0x0076E83A +DATA 4 0xB8001010 0x00000204 +DATA 4 0xB8001000 0x92210000 +DATA 4 0x80000f00 0x12344321 +DATA 4 0xB8001000 0xB2210000 +DATA 1 0x82000000 0xda +DATA 1 0x83000000 0xda +DATA 1 0x81000400 0xda +DATA 1 0x80000333 0xda + +DATA 4 0xB8001000 0x92210000 +DATA 1 0x80000400 0x12345678 + +DATA 4 0xB8001000 0xA2210000 +DATA 4 0x80000000 0x87654321 +DATA 4 0x80000000 0x87654321 + +DATA 4 0xB8001000 0xB2210000 +DATA 1 0x80000233 0xda +DATA 1 0x81000780 0xda +DATA 1 0x81000400 0xda +DATA 4 0xB8001000 0x82216080 +DATA 4 0x43FAC454 0x00001000 + +DATA 4 0x53F80008 0x20034000 + +# Enable the clocks +DATA 4 0x53f8000c 0x1fffffff +DATA 4 0x53f80010 0xffffffff +DATA 4 0x53f80014 0xfdfff diff --git a/board/freescale/mx25pdk/lowlevel_init.S b/board/freescale/mx25pdk/lowlevel_init.S new file mode 100644 index 0000000..6e6810f --- /dev/null +++ b/board/freescale/mx25pdk/lowlevel_init.S @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Freescale Semiconductor + * + * 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. + */ + +.globl lowlevel_init +lowlevel_init: + + mov pc, lr diff --git a/board/freescale/mx25pdk/mx25pdk.c b/board/freescale/mx25pdk/mx25pdk.c new file mode 100644 index 0000000..4a8352f --- /dev/null +++ b/board/freescale/mx25pdk/mx25pdk.c @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2011 Freescale Semiconductor, Inc. + * + * Author: Fabio Estevam <fabio.estevam@freescale.com> + * + * 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. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/imx25-pinmux.h> +#include <asm/arch/sys_proto.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, + PHYS_SDRAM_1_SIZE); + return 0; +} + +int board_early_init_f(void) +{ + mx25_uart1_init_pins(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + return 0; +} + +int checkboard(void) +{ + puts("Board: MX25PDK\n"); + + return 0; +} diff --git a/board/freescale/mx31ads/mx31ads.c b/board/freescale/mx31ads/mx31ads.c index 7637c92..4dd1e63 100644 --- a/board/freescale/mx31ads/mx31ads.c +++ b/board/freescale/mx31ads/mx31ads.c @@ -36,12 +36,6 @@ int dram_init(void) return 0; } -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; -} - int board_early_init_f(void) { int i; @@ -105,7 +99,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX31ADS; /* board id for linux */ gd->bd->bi_boot_params = 0x80000100; /* adress of boot parameters */ return 0; diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c index f6e190a..276d451 100644 --- a/board/freescale/mx31pdk/mx31pdk.c +++ b/board/freescale/mx31pdk/mx31pdk.c @@ -47,12 +47,6 @@ int dram_init(void) return 0; } -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; -} - int board_early_init_f(void) { /* CS5: CPLD incl. network controller */ @@ -69,7 +63,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX31_3DS; /* board id for linux */ /* adress of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 94ea1f2..8da1ee8 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -403,7 +403,6 @@ int board_init(void) { system_rev = get_cpu_rev(); - gd->bd->bi_arch_number = MACH_TYPE_MX51_BABBAGE; /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/freescale/mx53ard/mx53ard.c b/board/freescale/mx53ard/mx53ard.c index 6e3360b..c89da13 100644 --- a/board/freescale/mx53ard/mx53ard.c +++ b/board/freescale/mx53ard/mx53ard.c @@ -278,7 +278,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX53_ARD; /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c index 81857ff..fd821c0 100644 --- a/board/freescale/mx53evk/mx53evk.c +++ b/board/freescale/mx53evk/mx53evk.c @@ -355,7 +355,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX53_EVK; /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c index ade1006..156f8b5 100644 --- a/board/freescale/mx53loco/mx53loco.c +++ b/board/freescale/mx53loco/mx53loco.c @@ -288,7 +288,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX53_LOCO; gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; return 0; diff --git a/board/freescale/mx53smd/mx53smd.c b/board/freescale/mx53smd/mx53smd.c index 4a7ee55..776784f 100644 --- a/board/freescale/mx53smd/mx53smd.c +++ b/board/freescale/mx53smd/mx53smd.c @@ -214,7 +214,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX53_SMD; /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; diff --git a/board/isee/igep0020/igep0020.c b/board/isee/igep0020/igep0020.c index 2279cc0..6a3777e 100644 --- a/board/isee/igep0020/igep0020.c +++ b/board/isee/igep0020/igep0020.c @@ -29,6 +29,7 @@ #include <asm/arch/mmc_host_def.h> #include <asm/arch/mux.h> #include <asm/arch/sys_proto.h> +#include <asm/arch/omap_gpmc.h> #include <asm/mach-types.h> #include "igep0020.h" diff --git a/board/isee/igep0020/igep0020.h b/board/isee/igep0020/igep0020.h index c08d758..3d6e15f 100644 --- a/board/isee/igep0020/igep0020.h +++ b/board/isee/igep0020/igep0020.h @@ -29,15 +29,6 @@ const omap3_sysinfo sysinfo = { "ONENAND", }; -/* GPMC CS 5 connected to an SMSC LAN9221 ethernet controller */ -#define NET_LAN9221_GPMC_CONFIG1 0x00001000 -#define NET_LAN9221_GPMC_CONFIG2 0x00080701 -#define NET_LAN9221_GPMC_CONFIG3 0x00020201 -#define NET_LAN9221_GPMC_CONFIG4 0x08030703 -#define NET_LAN9221_GPMC_CONFIG5 0x00060908 -#define NET_LAN9221_GPMC_CONFIG6 0x87030000 -#define NET_LAN9221_GPMC_CONFIG7 0x00000f6c - static void setup_net_chip(void); /* diff --git a/board/karo/tx25/tx25.c b/board/karo/tx25/tx25.c index ce75468..307ffd0 100644 --- a/board/karo/tx25/tx25.c +++ b/board/karo/tx25/tx25.c @@ -29,6 +29,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/imx25-pinmux.h> #include <asm/gpio.h> +#include <asm/arch/sys_proto.h> static void mdelay(int n) { @@ -142,8 +143,6 @@ void tx25_fec_init(void) int board_init() { #ifdef CONFIG_MXC_UART - extern void mx25_uart1_init_pins(void); - mx25_uart1_init_pins(); #endif /* board id for linux */ diff --git a/board/logicpd/imx31_litekit/imx31_litekit.c b/board/logicpd/imx31_litekit/imx31_litekit.c index 09cc9c5..7214008 100644 --- a/board/logicpd/imx31_litekit/imx31_litekit.c +++ b/board/logicpd/imx31_litekit/imx31_litekit.c @@ -37,12 +37,6 @@ int dram_init(void) return 0; } -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; -} - int board_early_init_f(void) { __REG(CSCR_U(0)) = 0x0000cf03; /* CS0: Nor Flash */ @@ -76,7 +70,6 @@ int board_early_init_f(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_MX31LITE; /* board id for linux */ gd->bd->bi_boot_params = (0x80000100); /* adress of boot parameters */ return 0; diff --git a/board/overo/overo.c b/board/overo/overo.c index 4bbe1b8..850dfee 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -36,6 +36,7 @@ #include <asm/arch/mux.h> #include <asm/arch/mem.h> #include <asm/arch/sys_proto.h> +#include <asm/arch/omap_gpmc.h> #include <asm/gpio.h> #include <asm/mach-types.h> #include "overo.h" diff --git a/board/overo/overo.h b/board/overo/overo.h index 68e1243..d394f90 100644 --- a/board/overo/overo.h +++ b/board/overo/overo.h @@ -33,15 +33,6 @@ const omap3_sysinfo sysinfo = { #endif }; -/* GPMC CS 5 connected to an SMSC LAN9221 ethernet controller */ -#define NET_LAN9221_GPMC_CONFIG1 0x00001000 -#define NET_LAN9221_GPMC_CONFIG2 0x00080701 -#define NET_LAN9221_GPMC_CONFIG3 0x00020201 -#define NET_LAN9221_GPMC_CONFIG4 0x08030703 -#define NET_LAN9221_GPMC_CONFIG5 0x00060908 -#define NET_LAN9221_GPMC_CONFIG6 0x87030000 -#define NET_LAN9221_GPMC_CONFIG7 0x00000f6c - /* * IEN - Input Enable * IDIS - Input Disable @@ -128,7 +119,7 @@ const omap3_sysinfo sysinfo = { MUX_VAL(CP(GPMC_NCS6), (IEN | PTD | DIS | M0)) /*GPMC_nCS6*/\ MUX_VAL(CP(GPMC_NCS7), (IEN | PTU | EN | M0)) /*GPMC_nCS7*/\ MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /*GPMC_nCS3*/\ - MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)) /*GPMC_CLK*/\ + MUX_VAL(CP(GPMC_CLK), (IEN | PTU | EN | M0)) /*GPMC_CLK*/\ MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_nADV_ALE*/\ MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_nOE*/\ MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_nWE*/\ diff --git a/board/syteco/zmx25/zmx25.c b/board/syteco/zmx25/zmx25.c index 893adc6..a89ee1a 100644 --- a/board/syteco/zmx25/zmx25.c +++ b/board/syteco/zmx25/zmx25.c @@ -117,8 +117,6 @@ int board_init() writel(input_select1, &inputselect->i2c3_ipp_sda_in); /* I2C3 SDA */ writel(input_select2, &inputselect->i2c3_ipp_scl_in); /* I2C3 SCL */ - /* board id for linux */ - gd->bd->bi_arch_number = MACH_TYPE_ZMX25; gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; return 0; @@ -188,9 +186,3 @@ int dram_init(void) PHYS_SDRAM_SIZE); return 0; } - -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM; - gd->bd->bi_dram[0].size = gd->ram_size; -} diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 533af5a..f50d113 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -128,7 +128,7 @@ int board_mmc_init(bd_t *bis) } #endif -#ifdef CONFIG_DRIVER_DM9000 +#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) /* * Routine: board_eth_init * Description: Setting up the Ethernet hardware. diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c index 17a2558..ebca7b6 100644 --- a/board/ttcontrol/vision2/vision2.c +++ b/board/ttcontrol/vision2/vision2.c @@ -653,7 +653,6 @@ void lcd_enable(void) int board_init(void) { - gd->bd->bi_arch_number = MACH_TYPE_TTC_VISION2; /* board id for linux */ /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -144,6 +144,8 @@ rd6281a arm arm926ejs - Marvell sheevaplug arm arm926ejs - Marvell kirkwood dockstar arm arm926ejs - Seagate kirkwood jadecpu arm arm926ejs jadecpu syteco mb86r0x +mx25pdk arm arm926ejs mx25pdk freescale mx25 mx25pdk:IMX_CONFIG=board/freescale/mx25pdk/imximage.cfg +tx25 arm arm926ejs tx25 karo mx25 zmx25 arm arm926ejs zmx25 syteco mx25 imx27lite arm arm926ejs imx27lite logicpd mx27 magnesium arm arm926ejs imx27lite logicpd mx27 @@ -155,7 +157,8 @@ dkb arm arm926ejs - Marvell pantheon integratorap_cm946es arm arm946es integrator armltd - integratorap integratorcp_cm946es arm arm946es integrator armltd - integratorcp ca9x4_ct_vxp arm armv7 vexpress armltd -efikamx arm armv7 efikamx - mx5 efikamx:IMX_CONFIG=board/efikamx/imximage.cfg +efikamx arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg +efikasb arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg mx51evk arm armv7 mx51evk freescale mx5 mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg mx53ard arm armv7 mx53ard freescale mx5 mx53ard:IMX_CONFIG=board/freescale/mx53ard/imximage_dd3.cfg mx53evk arm armv7 mx53evk freescale mx5 mx53evk:IMX_CONFIG=board/freescale/mx53evk/imximage.cfg diff --git a/doc/README.SPL b/doc/README.SPL index 30624a5..d53ef9c 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -60,3 +60,5 @@ CONFIG_SPL_SPI_FLASH_SUPPORT (drivers/mtd/spi/libspi_flash.o) CONFIG_SPL_SPI_SUPPORT (drivers/spi/libspi.o) CONFIG_SPL_FAT_SUPPORT (fs/fat/libfat.o) CONFIG_SPL_LIBGENERIC_SUPPORT (lib/libgeneric.o) +CONFIG_SPL_POWER_SUPPORT (drivers/power/libpower.o) +CONFIG_SPL_NAND_SUPPORT (drivers/mtd/nand/libnand.o) diff --git a/doc/README.davinci b/doc/README.davinci index 0204372..5f1bdc8 100644 --- a/doc/README.davinci +++ b/doc/README.davinci @@ -139,3 +139,12 @@ http://www.spectrumdigital.com/product_info.php?cPath=37&products_id=214 7) TI DA850 EVM http://focus.ti.com/docs/prod/folders/print/omap-l138.html http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit + +Davinci special defines +======================= + +CONFIG_SYS_DV_NOR_BOOT_CFG: AM18xx based boards, booting in NOR Boot mode + need a "NOR Boot Configuration Word" stored + in the NOR Flash. This define adds this. + More Info about this, see: + spraba5a.pdf chapter 3.1 diff --git a/drivers/block/mxc_ata.c b/drivers/block/mxc_ata.c index f22f4f4..35bc656 100644 --- a/drivers/block/mxc_ata.c +++ b/drivers/block/mxc_ata.c @@ -96,7 +96,6 @@ static uint16_t pio_tA[NR_PIO_SPECS] = { 50, 50, 50, 50, 50 }; #define REG2OFF(reg) ((((uint32_t)reg) & 0x3) * 8) static void set_ata_bus_timing(unsigned char mode) { - uint32_t val; uint32_t T = 1000000000 / mxc_get_clock(MXC_IPG_CLK); struct mxc_ata_config_regs *ata_regs; @@ -106,22 +105,19 @@ static void set_ata_bus_timing(unsigned char mode) return; /* Write TIME_OFF/ON/1/2W */ - val = (3 << REG2OFF(&ata_regs->time_off)) | - (3 << REG2OFF(&ata_regs->time_on)) | - (((pio_t1[mode] + T) / T) << REG2OFF(&ata_regs->time_1)) | - (((pio_t2_8[mode] + T) / T) << REG2OFF(&ata_regs->time_2w)); - writel(val, &ata_regs->time_off); + writeb(3, &ata_regs->time_off); + writeb(3, &ata_regs->time_on); + writeb((pio_t1[mode] + T) / T, &ata_regs->time_1); + writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2w); /* Write TIME_2R/AX/RDX/4 */ - val = (((pio_t2_8[mode] + T) / T) << REG2OFF(&ata_regs->time_2r)) | - (((pio_tA[mode] + T) / T + 2) << REG2OFF(&ata_regs->time_ax)) | - (1 << REG2OFF(&ata_regs->time_pio_rdx)) | - (((pio_t4[mode] + T) / T) << REG2OFF(&ata_regs->time_4)); - writel(val, &ata_regs->time_2r); + writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2r); + writeb((pio_tA[mode] + T) / T + 2, &ata_regs->time_ax); + writeb(1, &ata_regs->time_pio_rdx); + writeb((pio_t4[mode] + T) / T, &ata_regs->time_4); /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */ - val = (((pio_t9[mode] + T) / T) << REG2OFF(&ata_regs->time_9)); - writel(val, &ata_regs->time_9); + writeb((pio_t9[mode] + T) / T, &ata_regs->time_9); } int ide_preinit(void) diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 62ec97d..beca1da 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -27,6 +27,7 @@ LIB := $(obj)libgpio.o COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o +COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o COBJS-$(CONFIG_PCA953X) += pca953x.o diff --git a/drivers/gpio/mvgpio.c b/drivers/gpio/mvgpio.c new file mode 100644 index 0000000..276f206 --- /dev/null +++ b/drivers/gpio/mvgpio.c @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2011 + * eInfochips Ltd. <www.einfochips.com> + * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> + * + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include "mvgpio.h" +#include <asm/gpio.h> + +#ifndef MV_MAX_GPIO +#define MV_MAX_GPIO 128 +#endif + +int gpio_request(int gp, const char *label) +{ + if (gp >= MV_MAX_GPIO) { + printf("%s: Invalid GPIO requested %d\n", __func__, gp); + return -EINVAL; + } + return 0; +} + +void gpio_free(int gp) +{ +} + +void gpio_toggle_value(int gp) +{ + gpio_set_value(gp, !gpio_get_value(gp)); +} + +int gpio_direction_input(int gp) +{ + struct gpio_reg *gpio_reg_bank; + + if (gp >= MV_MAX_GPIO) { + printf("%s: Invalid GPIO %d\n", __func__, gp); + return -EINVAL; + } + + gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp)); + writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr); + return 0; +} + +int gpio_direction_output(int gp, int value) +{ + struct gpio_reg *gpio_reg_bank; + + if (gp >= MV_MAX_GPIO) { + printf("%s: Invalid GPIO %d\n", __func__, gp); + return -EINVAL; + } + + gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp)); + writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gsdr); + gpio_set_value(gp, value); + return 0; +} + +int gpio_get_value(int gp) +{ + struct gpio_reg *gpio_reg_bank; + u32 gp_val; + + if (gp >= MV_MAX_GPIO) { + printf("%s: Invalid GPIO %d\n", __func__, gp); + return -EINVAL; + } + + gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp)); + gp_val = readl(&gpio_reg_bank->gplr); + + return GPIO_VAL(gp, gp_val); +} + +void gpio_set_value(int gp, int value) +{ + struct gpio_reg *gpio_reg_bank; + + if (gp >= MV_MAX_GPIO) { + printf("%s: Invalid GPIO %d\n", __func__, gp); + return; + } + + gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp)); + if (value) + writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gpsr); + else + writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gpcr); +} diff --git a/drivers/gpio/mvgpio.h b/drivers/gpio/mvgpio.h new file mode 100644 index 0000000..9688797 --- /dev/null +++ b/drivers/gpio/mvgpio.h @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2011 + * eInfochips Ltd. <www.einfochips.com> + * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> + * + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __MVGPIO_H__ +#define __MVGPIO_H__ + +#include <common.h> + +#ifdef CONFIG_SHEEVA_88SV331xV5 +/* + * GPIO Register map for SHEEVA 88SV331xV5 + */ +struct gpio_reg { + u32 gplr; /* Pin Level Register - 0x0000 */ + u32 pad0[2]; + u32 gpdr; /* Pin Direction Register - 0x000C */ + u32 pad1[2]; + u32 gpsr; /* Pin Output Set Register - 0x0018 */ + u32 pad2[2]; + u32 gpcr; /* Pin Output Clear Register - 0x0024 */ + u32 pad3[2]; + u32 grer; /* Rising-Edge Detect Enable Register - 0x0030 */ + u32 pad4[2]; + u32 gfer; /* Falling-Edge Detect Enable Register - 0x003C */ + u32 pad5[2]; + u32 gedr; /* Edge Detect Status Register - 0x0048 */ + u32 pad6[2]; + u32 gsdr; /* Bitwise Set of GPIO Direction Register - 0x0054 */ + u32 pad7[2]; + u32 gcdr; /* Bitwise Clear of GPIO Direction Register - 0x0060 */ + u32 pad8[2]; + u32 gsrer; /* Bitwise Set of Rising-Edge Detect Enable + Register - 0x006C */ + u32 pad9[2]; + u32 gcrer; /* Bitwise Clear of Rising-Edge Detect Enable + Register - 0x0078 */ + u32 pad10[2]; + u32 gsfer; /* Bitwise Set of Falling-Edge Detect Enable + Register - 0x0084 */ + u32 pad11[2]; + u32 gcfer; /* Bitwise Clear of Falling-Edge Detect Enable + Register - 0x0090 */ + u32 pad12[2]; + u32 apmask; /* Bitwise Mask of Edge Detect Register - 0x009C */ +}; +#else +#error "CPU core subversion not defined" +#endif + +#endif /* __MVGPIO_H__ */ diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index eee1cbd..5e3406d 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -119,6 +119,11 @@ void i2c_init(int speed, int slaveadd) udelay(1000); } +int i2c_set_bus_speed(unsigned int speed) +{ + i2c_init(speed, CONFIG_SYS_I2C_SLAVE); + return 0; +} int i2c_probe(u_int8_t chip) { diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index ebde3c5..a805bf6 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -1,7 +1,15 @@ /* - * i2c driver for Freescale mx31 + * i2c driver for Freescale i.MX series * * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * (c) 2011 Marek Vasut <marek.vasut@gmail.com> + * + * Based on i2c-imx.c from linux kernel: + * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de> + * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de> + * Copyright (C) 2007 RightHand Technologies, Inc. + * Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt> + * * * See file CREDITS for list of people who contributed to this * project. @@ -30,11 +38,13 @@ #include <asm/arch/clock.h> #include <asm/arch/imx-regs.h> -#define IADR 0x00 -#define IFDR 0x04 -#define I2CR 0x08 -#define I2SR 0x0c -#define I2DR 0x10 +struct mxc_i2c_regs { + uint32_t iadr; + uint32_t ifdr; + uint32_t i2cr; + uint32_t i2sr; + uint32_t i2dr; +}; #define I2CR_IEN (1 << 7) #define I2CR_IIEN (1 << 6) @@ -68,215 +78,361 @@ #endif #define I2C_MAX_TIMEOUT 10000 -#define I2C_MAX_RETRIES 3 -static u16 div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144, - 160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960, - 1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840}; +static u16 i2c_clk_div[50][2] = { + { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 }, + { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 }, + { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 }, + { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B }, + { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, + { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 }, + { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, + { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 }, + { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 }, + { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, + { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E }, + { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, + { 3072, 0x1E }, { 3840, 0x1F } +}; + +static u8 clk_idx; -static inline void i2c_reset(void) -{ - writew(0, I2C_BASE + I2CR); /* Reset module */ - writew(0, I2C_BASE + I2SR); - writew(I2CR_IEN, I2C_BASE + I2CR); -} - -void i2c_init(int speed, int unused) +/* + * Calculate and set proper clock divider + */ +static void i2c_imx_set_clk(unsigned int rate) { - int freq; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + unsigned int i2c_clk_rate; + unsigned int div; int i; #if defined(CONFIG_MX31) struct clock_control_regs *sc_regs = (struct clock_control_regs *)CCM_BASE; + /* start the required I2C clock */ writel(readl(&sc_regs->cgr0) | (3 << I2C_CLK_OFFSET), &sc_regs->cgr0); #endif - freq = mxc_get_clock(MXC_IPG_PERCLK); - for (i = 0; i < 0x1f; i++) - if (freq / div[i] <= speed) - break; + /* Divider value calculation */ + i2c_clk_rate = mxc_get_clock(MXC_IPG_PERCLK); + div = (i2c_clk_rate + rate - 1) / rate; + if (div < i2c_clk_div[0][0]) + i = 0; + else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0]) + i = ARRAY_SIZE(i2c_clk_div) - 1; + else + for (i = 0; i2c_clk_div[i][0] < div; i++) + ; + + /* Store divider value */ + clk_idx = i2c_clk_div[i][1]; + writeb(clk_idx, &i2c_regs->ifdr); +} - debug("%s: speed: %d\n", __func__, speed); +/* + * Reset I2C Controller + */ +void i2c_reset(void) +{ + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + + writeb(0, &i2c_regs->i2cr); /* Reset module */ + writeb(0, &i2c_regs->i2sr); +} - writew(i, I2C_BASE + IFDR); +/* + * Init I2C Bus + */ +void i2c_init(int speed, int unused) +{ + i2c_imx_set_clk(speed); i2c_reset(); } -static int wait_idle(void) +/* + * Wait for bus to be busy (or free if for_busy = 0) + * + * for_busy = 1: Wait for IBB to be asserted + * for_busy = 0: Wait for IBB to be de-asserted + */ +int i2c_imx_bus_busy(int for_busy) { + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + unsigned int temp; + int timeout = I2C_MAX_TIMEOUT; - while ((readw(I2C_BASE + I2SR) & I2SR_IBB) && --timeout) { - writew(0, I2C_BASE + I2SR); + while (timeout--) { + temp = readb(&i2c_regs->i2sr); + + if (for_busy && (temp & I2SR_IBB)) + return 0; + if (!for_busy && !(temp & I2SR_IBB)) + return 0; + udelay(1); } - return timeout ? timeout : (!(readw(I2C_BASE + I2SR) & I2SR_IBB)); + + return 1; } -static int wait_busy(void) +/* + * Wait for transaction to complete + */ +int i2c_imx_trx_complete(void) { + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; int timeout = I2C_MAX_TIMEOUT; - while (!(readw(I2C_BASE + I2SR) & I2SR_IBB) && --timeout) + while (timeout--) { + if (readb(&i2c_regs->i2sr) & I2SR_IIF) { + writeb(0, &i2c_regs->i2sr); + return 0; + } + udelay(1); - writew(0, I2C_BASE + I2SR); /* clear interrupt */ + } - return timeout; + return 1; } -static int wait_complete(void) +/* + * Check if the transaction was ACKed + */ +int i2c_imx_acked(void) { - int timeout = I2C_MAX_TIMEOUT; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; - while ((!(readw(I2C_BASE + I2SR) & I2SR_ICF)) && (--timeout)) { - writew(0, I2C_BASE + I2SR); - udelay(1); - } - udelay(200); + return readb(&i2c_regs->i2sr) & I2SR_RX_NO_AK; +} - writew(0, I2C_BASE + I2SR); /* clear interrupt */ +/* + * Start the controller + */ +int i2c_imx_start(void) +{ + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + unsigned int temp = 0; + int result; - return timeout; -} + writeb(clk_idx, &i2c_regs->ifdr); + /* Enable I2C controller */ + writeb(0, &i2c_regs->i2sr); + writeb(I2CR_IEN, &i2c_regs->i2cr); -static int tx_byte(u8 byte) -{ - writew(byte, I2C_BASE + I2DR); + /* Wait controller to be stable */ + udelay(50); + + /* Start I2C transaction */ + temp = readb(&i2c_regs->i2cr); + temp |= I2CR_MSTA; + writeb(temp, &i2c_regs->i2cr); + + result = i2c_imx_bus_busy(1); + if (result) + return result; + + temp |= I2CR_MTX | I2CR_TX_NO_AK; + writeb(temp, &i2c_regs->i2cr); - if (!wait_complete() || readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK) - return -1; return 0; } -static int rx_byte(int last) +/* + * Stop the controller + */ +void i2c_imx_stop(void) { - if (!wait_complete()) - return -1; + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + unsigned int temp = 0; + + /* Stop I2C transaction */ + temp = readb(&i2c_regs->i2cr); + temp |= ~(I2CR_MSTA | I2CR_MTX); + writeb(temp, &i2c_regs->i2cr); - if (last) - writew(I2CR_IEN, I2C_BASE + I2CR); + i2c_imx_bus_busy(0); - return readw(I2C_BASE + I2DR); + /* Disable I2C controller */ + writeb(0, &i2c_regs->i2cr); } -int i2c_probe(uchar chip) +/* + * Set chip address and access mode + * + * read = 1: READ access + * read = 0: WRITE access + */ +int i2c_imx_set_chip_addr(uchar chip, int read) { + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; int ret; - writew(0, I2C_BASE + I2CR); /* Reset module */ - writew(I2CR_IEN, I2C_BASE + I2CR); + writeb((chip << 1) | read, &i2c_regs->i2dr); + + ret = i2c_imx_trx_complete(); + if (ret) + return ret; - writew(I2CR_IEN | I2CR_MSTA | I2CR_MTX, I2C_BASE + I2CR); - ret = tx_byte(chip << 1); - writew(I2CR_IEN | I2CR_MTX, I2C_BASE + I2CR); + ret = i2c_imx_acked(); + if (ret) + return ret; return ret; } -static int i2c_addr(uchar chip, uint addr, int alen) +/* + * Write register address + */ +int i2c_imx_set_reg_addr(uint addr, int alen) { - int i, retry = 0; - for (retry = 0; retry < 3; retry++) { - if (wait_idle()) + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + int ret; + int i; + + for (i = 0; i < (8 * alen); i += 8) { + writeb((addr >> i) & 0xff, &i2c_regs->i2dr); + + ret = i2c_imx_trx_complete(); + if (ret) break; - i2c_reset(); - for (i = 0; i < I2C_MAX_TIMEOUT; i++) - udelay(1); - } - if (retry >= I2C_MAX_RETRIES) { - debug("%s:bus is busy(%x)\n", - __func__, readw(I2C_BASE + I2SR)); - return -1; - } - writew(I2CR_IEN | I2CR_MSTA | I2CR_MTX, I2C_BASE + I2CR); - if (!wait_busy()) { - debug("%s:trigger start fail(%x)\n", - __func__, readw(I2C_BASE + I2SR)); - return -1; + ret = i2c_imx_acked(); + if (ret) + break; } - if (tx_byte(chip << 1) || (readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) { - debug("%s:chip address cycle fail(%x)\n", - __func__, readw(I2C_BASE + I2SR)); - return -1; - } - while (alen--) - if (tx_byte((addr >> (alen * 8)) & 0xff) || - (readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) { - debug("%s:device address cycle fail(%x)\n", - __func__, readw(I2C_BASE + I2SR)); - return -1; - } - return 0; + return ret; } -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +/* + * Try if a chip add given address responds (probe the chip) + */ +int i2c_probe(uchar chip) { - int timeout = I2C_MAX_TIMEOUT; int ret; - debug("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n", - __func__, chip, addr, alen, len); + ret = i2c_imx_start(); + if (ret) + return ret; - if (i2c_addr(chip, addr, alen)) { - printf("i2c_addr failed\n"); - return -1; - } + ret = i2c_imx_set_chip_addr(chip, 0); + if (ret) + return ret; - writew(I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA, I2C_BASE + I2CR); + i2c_imx_stop(); - if (tx_byte(chip << 1 | 1)) - return -1; + return ret; +} - writew(I2CR_IEN | I2CR_MSTA | - ((len == 1) ? I2CR_TX_NO_AK : 0), - I2C_BASE + I2CR); +/* + * Read data from I2C device + */ +int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + int ret; + unsigned int temp; + int i; - ret = readw(I2C_BASE + I2DR); + ret = i2c_imx_start(); + if (ret) + return ret; + + /* write slave address */ + ret = i2c_imx_set_chip_addr(chip, 0); + if (ret) + return ret; + + ret = i2c_imx_set_reg_addr(addr, alen); + if (ret) + return ret; + + temp = readb(&i2c_regs->i2cr); + temp |= I2CR_RSTA; + writeb(temp, &i2c_regs->i2cr); + + ret = i2c_imx_set_chip_addr(chip, 1); + if (ret) + return ret; + + /* setup bus to read data */ + temp = readb(&i2c_regs->i2cr); + temp &= ~(I2CR_MTX | I2CR_TX_NO_AK); + if (len == 1) + temp |= I2CR_TX_NO_AK; + writeb(temp, &i2c_regs->i2cr); + readb(&i2c_regs->i2dr); + + /* read data */ + for (i = 0; i < len; i++) { + ret = i2c_imx_trx_complete(); + if (ret) + return ret; + + /* + * It must generate STOP before read I2DR to prevent + * controller from generating another clock cycle + */ + if (i == (len - 1)) { + temp = readb(&i2c_regs->i2cr); + temp &= ~(I2CR_MSTA | I2CR_MTX); + writeb(temp, &i2c_regs->i2cr); + i2c_imx_bus_busy(0); + } else if (i == (len - 2)) { + temp = readb(&i2c_regs->i2cr); + temp |= I2CR_TX_NO_AK; + writeb(temp, &i2c_regs->i2cr); + } - while (len--) { - ret = rx_byte(len == 0); - if (ret < 0) - return -1; - *buf++ = ret; - if (len <= 1) - writew(I2CR_IEN | I2CR_MSTA | - I2CR_TX_NO_AK, - I2C_BASE + I2CR); + buf[i] = readb(&i2c_regs->i2dr); } - writew(I2CR_IEN, I2C_BASE + I2CR); - - while (readw(I2C_BASE + I2SR) & I2SR_IBB && --timeout) - udelay(1); + i2c_imx_stop(); - return 0; + return ret; } +/* + * Write data to I2C device + */ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) { - int timeout = I2C_MAX_TIMEOUT; - debug("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n", - __func__, chip, addr, alen, len); + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; + int ret; + int i; - if (i2c_addr(chip, addr, alen)) - return -1; + ret = i2c_imx_start(); + if (ret) + return ret; - while (len--) - if (tx_byte(*buf++)) - return -1; + /* write slave address */ + ret = i2c_imx_set_chip_addr(chip, 0); + if (ret) + return ret; - writew(I2CR_IEN, I2C_BASE + I2CR); + ret = i2c_imx_set_reg_addr(addr, alen); + if (ret) + return ret; - while (readw(I2C_BASE + I2SR) & I2SR_IBB && --timeout) - udelay(1); + for (i = 0; i < len; i++) { + writeb(buf[i], &i2c_regs->i2dr); - return 0; -} + ret = i2c_imx_trx_complete(); + if (ret) + return ret; + + ret = i2c_imx_acked(); + if (ret) + return ret; + } + i2c_imx_stop(); + + return ret; +} #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/misc/fsl_pmic.c b/drivers/misc/fsl_pmic.c index ef80ad9..23255a5 100644 --- a/drivers/misc/fsl_pmic.c +++ b/drivers/misc/fsl_pmic.c @@ -230,6 +230,6 @@ int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( pmic, CONFIG_SYS_MAXARGS, 1, do_pmic, "Freescale PMIC (Atlas)", - "dump [numregs] dump registers\n" + "dump [numregs] - dump registers\n" "pmic write <reg> <value> - write register" ); diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index ef12ecd..5d4cf51 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -28,6 +28,7 @@ #include <part.h> #include <i2c.h> #include <twl4030.h> +#include <twl6030.h> #include <asm/io.h> #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> @@ -38,7 +39,27 @@ static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size); static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int siz); static struct mmc hsmmc_dev[2]; -unsigned char mmc_board_init(hsmmc_t *mmc_base) + +#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) +static void omap4_vmmc_pbias_config(struct mmc *mmc) +{ + u32 value = 0; + struct omap4_sys_ctrl_regs *const ctrl = + (struct omap4_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE; + + + value = readl(&ctrl->control_pbiaslite); + value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ); + writel(value, &ctrl->control_pbiaslite); + /* set VMMC to 3V */ + twl6030_power_mmc_init(); + value = readl(&ctrl->control_pbiaslite); + value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ; + writel(value, &ctrl->control_pbiaslite); +} +#endif + +unsigned char mmc_board_init(struct mmc *mmc) { #if defined(CONFIG_TWL4030_POWER) twl4030_power_mmc_init(); @@ -67,7 +88,11 @@ unsigned char mmc_board_init(hsmmc_t *mmc_base) &prcm_base->iclken1_core); #endif -/* TODO add appropriate OMAP4 init - none currently necessary */ +#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) + /* PBIAS config needed for MMC1 only */ + if (mmc->block_dev.dev == 0) + omap4_vmmc_pbias_config(mmc); +#endif return 0; } @@ -108,7 +133,7 @@ static int mmc_init_setup(struct mmc *mmc) unsigned int dsor; ulong start; - mmc_board_init(mmc_base); + mmc_board_init(mmc); writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, &mmc_base->sysconfig); @@ -461,7 +486,8 @@ int omap_mmc_init(int dev_index) return 1; } mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS; + mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS | + MMC_MODE_HC; mmc->f_min = 400000; mmc->f_max = 52000000; diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 8b598f6..b6a7886 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -26,12 +26,18 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnand.o ifdef CONFIG_CMD_NAND +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_NAND_SIMPLE +COBJS-y += nand_spl_simple.o +endif +else COBJS-y += nand.o -COBJS-y += nand_base.o COBJS-y += nand_bbt.o -COBJS-y += nand_ecc.o COBJS-y += nand_ids.o COBJS-y += nand_util.o +endif +COBJS-y += nand_ecc.o +COBJS-y += nand_base.o COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1a95a91..e7dfcb1 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -213,7 +213,7 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) * * Default read function for 8bit buswith */ -static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; struct nand_chip *chip = mtd->priv; @@ -269,7 +269,7 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) * * Default read function for 16bit buswith */ -static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) +void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) { int i; struct nand_chip *chip = mtd->priv; diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c new file mode 100644 index 0000000..71491d4 --- /dev/null +++ b/drivers/mtd/nand/nand_spl_simple.c @@ -0,0 +1,245 @@ +/* + * (C) Copyright 2006-2008 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * 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 <nand.h> +#include <asm/io.h> + +static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS; +static nand_info_t mtd; +static struct nand_chip nand_chip; + +#if (CONFIG_SYS_NAND_PAGE_SIZE <= 512) +/* + * NAND command for small page NAND devices (512) + */ +static int nand_command(int block, int page, uint32_t offs, + u8 cmd) +{ + struct nand_chip *this = mtd.priv; + int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + + while (!this->dev_ready(&mtd)) + ; + + /* Begin command latch cycle */ + this->cmd_ctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE); + /* Set ALE and clear CLE to start address cycle */ + /* Column address */ + this->cmd_ctrl(&mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE); + this->cmd_ctrl(&mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */ + this->cmd_ctrl(&mtd, (page_addr >> 8) & 0xff, + NAND_CTRL_ALE); /* A[24:17] */ +#ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE + /* One more address cycle for devices > 32MiB */ + this->cmd_ctrl(&mtd, (page_addr >> 16) & 0x0f, + NAND_CTRL_ALE); /* A[28:25] */ +#endif + /* Latch in address */ + this->cmd_ctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + + /* + * Wait a while for the data to be ready + */ + while (!this->dev_ready(&mtd)) + ; + + return 0; +} +#else +/* + * NAND command for large page NAND devices (2k) + */ +static int nand_command(int block, int page, uint32_t offs, + u8 cmd) +{ + struct nand_chip *this = mtd.priv; + int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + void (*hwctrl)(struct mtd_info *mtd, int cmd, + unsigned int ctrl) = this->cmd_ctrl; + + while (!this->dev_ready(&mtd)) + ; + + /* Emulate NAND_CMD_READOOB */ + if (cmd == NAND_CMD_READOOB) { + offs += CONFIG_SYS_NAND_PAGE_SIZE; + cmd = NAND_CMD_READ0; + } + + /* Shift the offset from byte addressing to word addressing. */ + if (this->options & NAND_BUSWIDTH_16) + offs >>= 1; + + /* Begin command latch cycle */ + hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE); + /* Set ALE and clear CLE to start address cycle */ + /* Column address */ + hwctrl(&mtd, offs & 0xff, + NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */ + hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */ + /* Row address */ + hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */ + hwctrl(&mtd, ((page_addr >> 8) & 0xff), + NAND_CTRL_ALE); /* A[27:20] */ +#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE + /* One more address cycle for devices > 128MiB */ + hwctrl(&mtd, (page_addr >> 16) & 0x0f, + NAND_CTRL_ALE); /* A[31:28] */ +#endif + /* Latch in address */ + hwctrl(&mtd, NAND_CMD_READSTART, + NAND_CTRL_CLE | NAND_CTRL_CHANGE); + hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + + /* + * Wait a while for the data to be ready + */ + while (!this->dev_ready(&mtd)) + ; + + return 0; +} +#endif + +static int nand_is_bad_block(int block) +{ + struct nand_chip *this = mtd.priv; + + nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS, + NAND_CMD_READOOB); + + /* + * Read one byte (or two if it's a 16 bit chip). + */ + if (this->options & NAND_BUSWIDTH_16) { + if (readw(this->IO_ADDR_R) != 0xffff) + return 1; + } else { + if (readb(this->IO_ADDR_R) != 0xff) + return 1; + } + + return 0; +} + +static int nand_read_page(int block, int page, void *dst) +{ + struct nand_chip *this = mtd.priv; + u_char *ecc_calc; + u_char *ecc_code; + u_char *oob_data; + int i; + int eccsize = CONFIG_SYS_NAND_ECCSIZE; + int eccbytes = CONFIG_SYS_NAND_ECCBYTES; + int eccsteps = CONFIG_SYS_NAND_ECCSTEPS; + uint8_t *p = dst; + int stat; + + nand_command(block, page, 0, NAND_CMD_READ0); + + /* No malloc available for now, just use some temporary locations + * in SDRAM + */ + ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000); + ecc_code = ecc_calc + 0x100; + oob_data = ecc_calc + 0x200; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + this->ecc.hwctl(&mtd, NAND_ECC_READ); + this->read_buf(&mtd, p, eccsize); + this->ecc.calculate(&mtd, p, &ecc_calc[i]); + } + this->read_buf(&mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE); + + /* Pick the ECC bytes out of the oob data */ + for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++) + ecc_code[i] = oob_data[nand_ecc_pos[i]]; + + eccsteps = CONFIG_SYS_NAND_ECCSTEPS; + p = dst; + + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + /* No chance to do something with the possible error message + * from correct_data(). We just hope that all possible errors + * are corrected by this routine. + */ + stat = this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]); + } + + return 0; +} + +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) +{ + unsigned int block, lastblock; + unsigned int page; + + /* + * offs has to be aligned to a page address! + */ + block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; + lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; + page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; + + while (block <= lastblock) { + if (!nand_is_bad_block(block)) { + /* + * Skip bad blocks + */ + while (page < CONFIG_SYS_NAND_PAGE_COUNT) { + nand_read_page(block, page, dst); + dst += CONFIG_SYS_NAND_PAGE_SIZE; + page++; + } + + page = 0; + } else { + lastblock++; + } + + block++; + } + + return 0; +} + +/* nand_init() - initialize data to make nand usable by SPL */ +void nand_init(void) +{ + /* + * Init board specific nand support + */ + mtd.priv = &nand_chip; + nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W = + (void __iomem *)CONFIG_SYS_NAND_BASE; + nand_chip.options = 0; + board_nand_init(&nand_chip); + + if (nand_chip.select_chip) + nand_chip.select_chip(&mtd, 0); +} + +/* Unselect after operation */ +void nand_deselect(void) +{ + if (nand_chip.select_chip) + nand_chip.select_chip(&mtd, -1); +} diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 99b9cef..5bbec48 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -61,6 +61,14 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd, writeb(cmd, this->IO_ADDR_W); } +#ifdef CONFIG_SPL_BUILD +/* Check wait pin as dev ready indicator */ +int omap_spl_dev_ready(struct mtd_info *mtd) +{ + return gpmc_cfg->status & (1 << 8); +} +#endif + /* * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in * GPMC controller @@ -224,6 +232,7 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode) } } +#ifndef CONFIG_SPL_BUILD /* * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc. * The default is to come up on s/w ecc @@ -280,6 +289,7 @@ void omap_nand_switch_ecc(int32_t hardware) nand->options &= ~NAND_OWN_BUFFERS; } +#endif /* CONFIG_SPL_BUILD */ /* * Board-specific NAND initialization. The following members of the @@ -338,7 +348,24 @@ int board_nand_init(struct nand_chip *nand) nand->chip_delay = 100; /* Default ECC mode */ +#ifndef CONFIG_SPL_BUILD nand->ecc.mode = NAND_ECC_SOFT; +#else + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &hw_nand_oob; + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.hwctl = omap_enable_hwecc; + nand->ecc.correct = omap_correct_data; + nand->ecc.calculate = omap_calculate_ecc; + omap_hwecc_init(nand); + + if (nand->options & NAND_BUSWIDTH_16) + nand->read_buf = nand_read_buf16; + else + nand->read_buf = nand_read_buf; + nand->dev_ready = omap_spl_dev_ready; +#endif return 0; } diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 819b197..34b4322 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libnet.o COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o COBJS-$(CONFIG_ALTERA_TSE) += altera_tse.o +COBJS-$(CONFIG_ARMADA100_FEC) += armada100_fec.o COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o COBJS-$(CONFIG_BCM570x) += bcm570x.o diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c new file mode 100644 index 0000000..fbf9763 --- /dev/null +++ b/drivers/net/armada100_fec.c @@ -0,0 +1,736 @@ +/* + * (C) Copyright 2011 + * eInfochips Ltd. <www.einfochips.com> + * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> + * + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * Contributor: Mahavir Jain <mjain@marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <net.h> +#include <malloc.h> +#include <miiphy.h> +#include <netdev.h> +#include <asm/types.h> +#include <asm/byteorder.h> +#include <linux/err.h> +#include <linux/mii.h> +#include <asm/io.h> +#include <asm/arch/armada100.h> +#include "armada100_fec.h" + +#define PHY_ADR_REQ 0xFF /* Magic number to read/write PHY address */ + +#ifdef DEBUG +static int eth_dump_regs(struct eth_device *dev) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + unsigned int i = 0; + + printf("\noffset: phy_adr, value: 0x%x\n", readl(®s->phyadr)); + printf("offset: smi, value: 0x%x\n", readl(®s->smi)); + for (i = 0x400; i <= 0x4e4; i += 4) + printf("offset: 0x%x, value: 0x%x\n", + i, readl(ARMD1_FEC_BASE + i)); + return 0; +} +#endif + +static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond) +{ + u32 timeout = PHY_WAIT_ITERATIONS; + u32 reg_val; + + while (--timeout) { + reg_val = readl(reg); + if (cond && (reg_val & flag)) + break; + else if (!cond && !(reg_val & flag)) + break; + udelay(PHY_WAIT_MICRO_SECONDS); + } + return !timeout; +} + +static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg, + u16 *value) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + u32 val; + + if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) { + val = readl(®s->phyadr); + *value = val & 0x1f; + return 0; + } + + /* check parameters */ + if (phy_addr > PHY_MASK) { + printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n", + __func__, phy_addr); + return -EINVAL; + } + if (phy_reg > PHY_MASK) { + printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n", + __func__, phy_reg); + return -EINVAL; + } + + /* wait for the SMI register to become available */ + if (armdfec_phy_timeout(®s->smi, SMI_BUSY, FALSE)) { + printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__); + return -1; + } + + writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, ®s->smi); + + /* now wait for the data to be valid */ + if (armdfec_phy_timeout(®s->smi, SMI_R_VALID, TRUE)) { + val = readl(®s->smi); + printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n", + __func__, val); + return -1; + } + val = readl(®s->smi); + *value = val & 0xffff; + + return 0; +} + +static int smi_reg_write(const char *devname, + u8 phy_addr, u8 phy_reg, u16 value) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + + if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) { + clrsetbits_le32(®s->phyadr, 0x1f, value & 0x1f); + return 0; + } + + /* check parameters */ + if (phy_addr > PHY_MASK) { + printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__); + return -EINVAL; + } + if (phy_reg > PHY_MASK) { + printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__); + return -EINVAL; + } + + /* wait for the SMI register to become available */ + if (armdfec_phy_timeout(®s->smi, SMI_BUSY, FALSE)) { + printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__); + return -1; + } + + writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_W | (value & 0xffff), + ®s->smi); + return 0; +} + +/* + * Abort any transmit and receive operations and put DMA + * in idle state. AT and AR bits are cleared upon entering + * in IDLE state. So poll those bits to verify operation. + */ +static void abortdma(struct eth_device *dev) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + int delay; + int maxretries = 40; + u32 tmp; + + while (--maxretries) { + writel(SDMA_CMD_AR | SDMA_CMD_AT, ®s->sdma_cmd); + udelay(100); + + delay = 10; + while (--delay) { + tmp = readl(®s->sdma_cmd); + if (!(tmp & (SDMA_CMD_AR | SDMA_CMD_AT))) + break; + udelay(10); + } + if (delay) + break; + } + + if (!maxretries) + printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__); +} + +static inline u32 nibble_swapping_32_bit(u32 x) +{ + return ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4); +} + +static inline u32 nibble_swapping_16_bit(u32 x) +{ + return ((x & 0x0000f0f0) >> 4) | ((x & 0x00000f0f) << 4); +} + +static inline u32 flip_4_bits(u32 x) +{ + return ((x & 0x01) << 3) | ((x & 0x002) << 1) + | ((x & 0x04) >> 1) | ((x & 0x008) >> 3); +} + +/* + * This function will calculate the hash function of the address. + * depends on the hash mode and hash size. + * Inputs + * mach - the 2 most significant bytes of the MAC address. + * macl - the 4 least significant bytes of the MAC address. + * Outputs + * return the calculated entry. + */ +static u32 hash_function(u32 mach, u32 macl) +{ + u32 hashresult; + u32 addrh; + u32 addrl; + u32 addr0; + u32 addr1; + u32 addr2; + u32 addr3; + u32 addrhswapped; + u32 addrlswapped; + + addrh = nibble_swapping_16_bit(mach); + addrl = nibble_swapping_32_bit(macl); + + addrhswapped = flip_4_bits(addrh & 0xf) + + ((flip_4_bits((addrh >> 4) & 0xf)) << 4) + + ((flip_4_bits((addrh >> 8) & 0xf)) << 8) + + ((flip_4_bits((addrh >> 12) & 0xf)) << 12); + + addrlswapped = flip_4_bits(addrl & 0xf) + + ((flip_4_bits((addrl >> 4) & 0xf)) << 4) + + ((flip_4_bits((addrl >> 8) & 0xf)) << 8) + + ((flip_4_bits((addrl >> 12) & 0xf)) << 12) + + ((flip_4_bits((addrl >> 16) & 0xf)) << 16) + + ((flip_4_bits((addrl >> 20) & 0xf)) << 20) + + ((flip_4_bits((addrl >> 24) & 0xf)) << 24) + + ((flip_4_bits((addrl >> 28) & 0xf)) << 28); + + addrh = addrhswapped; + addrl = addrlswapped; + + addr0 = (addrl >> 2) & 0x03f; + addr1 = (addrl & 0x003) | (((addrl >> 8) & 0x7f) << 2); + addr2 = (addrl >> 15) & 0x1ff; + addr3 = ((addrl >> 24) & 0x0ff) | ((addrh & 1) << 8); + + hashresult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3); + hashresult = hashresult & 0x07ff; + return hashresult; +} + +/* + * This function will add an entry to the address table. + * depends on the hash mode and hash size that was initialized. + * Inputs + * mach - the 2 most significant bytes of the MAC address. + * macl - the 4 least significant bytes of the MAC address. + * skip - if 1, skip this address. + * rd - the RD field in the address table. + * Outputs + * address table entry is added. + * 0 if success. + * -ENOSPC if table full + */ +static int add_del_hash_entry(struct armdfec_device *darmdfec, u32 mach, + u32 macl, u32 rd, u32 skip, int del) +{ + struct addr_table_entry_t *entry, *start; + u32 newhi; + u32 newlo; + u32 i; + + newlo = (((mach >> 4) & 0xf) << 15) + | (((mach >> 0) & 0xf) << 11) + | (((mach >> 12) & 0xf) << 7) + | (((mach >> 8) & 0xf) << 3) + | (((macl >> 20) & 0x1) << 31) + | (((macl >> 16) & 0xf) << 27) + | (((macl >> 28) & 0xf) << 23) + | (((macl >> 24) & 0xf) << 19) + | (skip << HTESKIP) | (rd << HTERDBIT) + | HTEVALID; + + newhi = (((macl >> 4) & 0xf) << 15) + | (((macl >> 0) & 0xf) << 11) + | (((macl >> 12) & 0xf) << 7) + | (((macl >> 8) & 0xf) << 3) + | (((macl >> 21) & 0x7) << 0); + + /* + * Pick the appropriate table, start scanning for free/reusable + * entries at the index obtained by hashing the specified MAC address + */ + start = (struct addr_table_entry_t *)(darmdfec->htpr); + entry = start + hash_function(mach, macl); + for (i = 0; i < HOP_NUMBER; i++) { + if (!(entry->lo & HTEVALID)) { + break; + } else { + /* if same address put in same position */ + if (((entry->lo & 0xfffffff8) == (newlo & 0xfffffff8)) + && (entry->hi == newhi)) + break; + } + if (entry == start + 0x7ff) + entry = start; + else + entry++; + } + + if (((entry->lo & 0xfffffff8) != (newlo & 0xfffffff8)) && + (entry->hi != newhi) && del) + return 0; + + if (i == HOP_NUMBER) { + if (!del) { + printf("ARMD100 FEC: (%s) table section is full\n", + __func__); + return -ENOSPC; + } else { + return 0; + } + } + + /* + * Update the selected entry + */ + if (del) { + entry->hi = 0; + entry->lo = 0; + } else { + entry->hi = newhi; + entry->lo = newlo; + } + + return 0; +} + +/* + * Create an addressTable entry from MAC address info + * found in the specifed net_device struct + * + * Input : pointer to ethernet interface network device structure + * Output : N/A + */ +static void update_hash_table_mac_address(struct armdfec_device *darmdfec, + u8 *oaddr, u8 *addr) +{ + u32 mach; + u32 macl; + + /* Delete old entry */ + if (oaddr) { + mach = (oaddr[0] << 8) | oaddr[1]; + macl = (oaddr[2] << 24) | (oaddr[3] << 16) | + (oaddr[4] << 8) | oaddr[5]; + add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_DELETE); + } + + /* Add new entry */ + mach = (addr[0] << 8) | addr[1]; + macl = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; + add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_ADD); +} + +/* Address Table Initialization */ +static void init_hashtable(struct eth_device *dev) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + memset(darmdfec->htpr, 0, HASH_ADDR_TABLE_SIZE); + writel((u32)darmdfec->htpr, ®s->htpr); +} + +/* + * This detects PHY chip from address 0-31 by reading PHY status + * registers. PHY chip can be connected at any of this address. + */ +static int ethernet_phy_detect(struct eth_device *dev) +{ + u32 val; + u16 tmp, mii_status; + u8 addr; + + for (addr = 0; addr < 32; addr++) { + if (miiphy_read(dev->name, addr, MII_BMSR, &mii_status) != 0) + /* try next phy */ + continue; + + /* invalid MII status. More validation required here... */ + if (mii_status == 0 || mii_status == 0xffff) + /* try next phy */ + continue; + + if (miiphy_read(dev->name, addr, MII_PHYSID1, &tmp) != 0) + /* try next phy */ + continue; + + val = tmp << 16; + if (miiphy_read(dev->name, addr, MII_PHYSID2, &tmp) != 0) + /* try next phy */ + continue; + + val |= tmp; + + if ((val & 0xfffffff0) != 0) + return addr; + } + return -1; +} + +static void armdfec_init_rx_desc_ring(struct armdfec_device *darmdfec) +{ + struct rx_desc *p_rx_desc; + int i; + + /* initialize the Rx descriptors ring */ + p_rx_desc = darmdfec->p_rxdesc; + for (i = 0; i < RINGSZ; i++) { + p_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; + p_rx_desc->buf_size = PKTSIZE_ALIGN; + p_rx_desc->byte_cnt = 0; + p_rx_desc->buf_ptr = darmdfec->p_rxbuf + i * PKTSIZE_ALIGN; + if (i == (RINGSZ - 1)) { + p_rx_desc->nxtdesc_p = darmdfec->p_rxdesc; + } else { + p_rx_desc->nxtdesc_p = (struct rx_desc *) + ((u32)p_rx_desc + ARMDFEC_RXQ_DESC_ALIGNED_SIZE); + p_rx_desc = p_rx_desc->nxtdesc_p; + } + } + darmdfec->p_rxdesc_curr = darmdfec->p_rxdesc; +} + +static int armdfec_init(struct eth_device *dev, bd_t *bd) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + int phy_adr; + + armdfec_init_rx_desc_ring(darmdfec); + + /* Disable interrupts */ + writel(0, ®s->im); + writel(0, ®s->ic); + /* Write to ICR to clear interrupts. */ + writel(0, ®s->iwc); + + /* + * Abort any transmit and receive operations and put DMA + * in idle state. + */ + abortdma(dev); + + /* Initialize address hash table */ + init_hashtable(dev); + + /* SDMA configuration */ + writel(SDCR_BSZ8 | /* Burst size = 32 bytes */ + SDCR_RIFB | /* Rx interrupt on frame */ + SDCR_BLMT | /* Little endian transmit */ + SDCR_BLMR | /* Little endian receive */ + SDCR_RC_MAX_RETRANS, /* Max retransmit count */ + ®s->sdma_conf); + /* Port Configuration */ + writel(PCR_HS, ®s->pconf); /* Hash size is 1/2kb */ + + /* Set extended port configuration */ + writel(PCXR_2BSM | /* Two byte suffix aligns IP hdr */ + PCXR_DSCP_EN | /* Enable DSCP in IP */ + PCXR_MFL_1536 | /* Set MTU = 1536 */ + PCXR_FLP | /* do not force link pass */ + PCXR_TX_HIGH_PRI, /* Transmit - high priority queue */ + ®s->pconf_ext); + + update_hash_table_mac_address(darmdfec, NULL, dev->enetaddr); + + /* Update TX and RX queue descriptor register */ + writel((u32)darmdfec->p_txdesc, ®s->txcdp[TXQ]); + writel((u32)darmdfec->p_rxdesc, ®s->rxfdp[RXQ]); + writel((u32)darmdfec->p_rxdesc_curr, ®s->rxcdp[RXQ]); + + /* Enable Interrupts */ + writel(ALL_INTS, ®s->im); + + /* Enable Ethernet Port */ + setbits_le32(®s->pconf, PCR_EN); + + /* Enable RX DMA engine */ + setbits_le32(®s->sdma_cmd, SDMA_CMD_ERD); + +#ifdef DEBUG + eth_dump_regs(dev); +#endif + +#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) + +#if defined(CONFIG_PHY_BASE_ADR) + miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, CONFIG_PHY_BASE_ADR); +#else + /* Search phy address from range 0-31 */ + phy_adr = ethernet_phy_detect(dev); + if (phy_adr < 0) { + printf("ARMD100 FEC: PHY not detected at address range 0-31\n"); + return -1; + } else { + debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr); + miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr); + } +#endif + +#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) + /* Wait up to 5s for the link status */ + for (i = 0; i < 5; i++) { + u16 phy_adr; + + miiphy_read(dev->name, 0xFF, 0xFF, &phy_adr); + /* Return if we get link up */ + if (miiphy_link(dev->name, phy_adr)) + return 0; + udelay(1000000); + } + + printf("ARMD100 FEC: No link on %s\n", dev->name); + return -1; +#endif +#endif + return 0; +} + +static void armdfec_halt(struct eth_device *dev) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + + /* Stop RX DMA */ + clrbits_le32(®s->sdma_cmd, SDMA_CMD_ERD); + + /* + * Abort any transmit and receive operations and put DMA + * in idle state. + */ + abortdma(dev); + + /* Disable interrupts */ + writel(0, ®s->im); + writel(0, ®s->ic); + writel(0, ®s->iwc); + + /* Disable Port */ + clrbits_le32(®s->pconf, PCR_EN); +} + +static int armdfec_send(struct eth_device *dev, volatile void *dataptr, + int datasize) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct armdfec_reg *regs = darmdfec->regs; + struct tx_desc *p_txdesc = darmdfec->p_txdesc; + void *p = (void *)dataptr; + int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS; + u32 cmd_sts; + + /* Copy buffer if it's misaligned */ + if ((u32)dataptr & 0x07) { + if (datasize > PKTSIZE_ALIGN) { + printf("ARMD100 FEC: Non-aligned data too large (%d)\n", + datasize); + return -1; + } + memcpy(darmdfec->p_aligned_txbuf, p, datasize); + p = darmdfec->p_aligned_txbuf; + } + + p_txdesc->cmd_sts = TX_ZERO_PADDING | TX_GEN_CRC; + p_txdesc->cmd_sts |= TX_FIRST_DESC | TX_LAST_DESC; + p_txdesc->cmd_sts |= BUF_OWNED_BY_DMA; + p_txdesc->cmd_sts |= TX_EN_INT; + p_txdesc->buf_ptr = p; + p_txdesc->byte_cnt = datasize; + + /* Apply send command using high priority TX queue */ + writel((u32)p_txdesc, ®s->txcdp[TXQ]); + writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, ®s->sdma_cmd); + + /* + * wait for packet xmit completion + */ + cmd_sts = readl(&p_txdesc->cmd_sts); + while (cmd_sts & BUF_OWNED_BY_DMA) { + /* return fail if error is detected */ + if ((cmd_sts & (TX_ERROR | TX_LAST_DESC)) == + (TX_ERROR | TX_LAST_DESC)) { + printf("ARMD100 FEC: (%s) in xmit packet\n", __func__); + return -1; + } + cmd_sts = readl(&p_txdesc->cmd_sts); + if (!(retry--)) { + printf("ARMD100 FEC: (%s) xmit packet timeout!\n", + __func__); + return -1; + } + } + + return 0; +} + +static int armdfec_recv(struct eth_device *dev) +{ + struct armdfec_device *darmdfec = to_darmdfec(dev); + struct rx_desc *p_rxdesc_curr = darmdfec->p_rxdesc_curr; + u32 cmd_sts; + u32 timeout = 0; + + /* wait untill rx packet available or timeout */ + do { + if (timeout < PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS) { + timeout++; + } else { + debug("ARMD100 FEC: %s time out...\n", __func__); + return -1; + } + } while (readl(&p_rxdesc_curr->cmd_sts) & BUF_OWNED_BY_DMA); + + if (p_rxdesc_curr->byte_cnt != 0) { + debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x" + "(cmd_sts= %08x)\n", __func__, + (u32)p_rxdesc_curr->byte_cnt, + (u32)p_rxdesc_curr->buf_ptr, + (u32)p_rxdesc_curr->cmd_sts); + } + + /* + * In case received a packet without first/last bits on + * OR the error summary bit is on, + * the packets needs to be dropeed. + */ + cmd_sts = readl(&p_rxdesc_curr->cmd_sts); + + if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != + (RX_FIRST_DESC | RX_LAST_DESC)) { + printf("ARMD100 FEC: (%s) Dropping packet spread on" + " multiple descriptors\n", __func__); + } else if (cmd_sts & RX_ERROR) { + printf("ARMD100 FEC: (%s) Dropping packet with errors\n", + __func__); + } else { + /* !!! call higher layer processing */ + debug("ARMD100 FEC: (%s) Sending Received packet to" + " upper layer (NetReceive)\n", __func__); + + /* + * let the upper layer handle the packet, subtract offset + * as two dummy bytes are added in received buffer see + * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit. + */ + NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), + (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); + } + /* + * free these descriptors and point next in the ring + */ + p_rxdesc_curr->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; + p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; + p_rxdesc_curr->byte_cnt = 0; + + writel((u32)p_rxdesc_curr->nxtdesc_p, (u32)&darmdfec->p_rxdesc_curr); + + return 0; +} + +int armada100_fec_register(unsigned long base_addr) +{ + struct armdfec_device *darmdfec; + struct eth_device *dev; + + darmdfec = malloc(sizeof(struct armdfec_device)); + if (!darmdfec) + goto error; + + memset(darmdfec, 0, sizeof(struct armdfec_device)); + + darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE); + if (!darmdfec->htpr) + goto error1; + + darmdfec->p_rxdesc = memalign(PKTALIGN, + ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1); + + if (!darmdfec->p_rxdesc) + goto error1; + + darmdfec->p_rxbuf = memalign(PKTALIGN, RINGSZ * PKTSIZE_ALIGN + 1); + if (!darmdfec->p_rxbuf) + goto error1; + + darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN); + if (!darmdfec->p_aligned_txbuf) + goto error1; + + darmdfec->p_txdesc = memalign(PKTALIGN, sizeof(struct tx_desc) + 1); + if (!darmdfec->p_txdesc) + goto error1; + + dev = &darmdfec->dev; + /* Assign ARMADA100 Fast Ethernet Controller Base Address */ + darmdfec->regs = (void *)base_addr; + + /* must be less than NAMESIZE (16) */ + strcpy(dev->name, "armd-fec0"); + + dev->init = armdfec_init; + dev->halt = armdfec_halt; + dev->send = armdfec_send; + dev->recv = armdfec_recv; + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, smi_reg_read, smi_reg_write); +#endif + return 0; + +error1: + free(darmdfec->p_aligned_txbuf); + free(darmdfec->p_rxbuf); + free(darmdfec->p_rxdesc); + free(darmdfec->htpr); +error: + free(darmdfec); + printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__); + return -1; +} diff --git a/drivers/net/armada100_fec.h b/drivers/net/armada100_fec.h new file mode 100644 index 0000000..e2df4fc --- /dev/null +++ b/drivers/net/armada100_fec.h @@ -0,0 +1,232 @@ +/* + * (C) Copyright 2011 + * eInfochips Ltd. <www.einfochips.com> + * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> + * + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * Contributor: Mahavir Jain <mjain@marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __ARMADA100_FEC_H__ +#define __ARMADA100_FEC_H__ + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define PORT_NUM 0x0 + +/* RX & TX descriptor command */ +#define BUF_OWNED_BY_DMA (1<<31) + +/* RX descriptor status */ +#define RX_EN_INT (1<<23) +#define RX_FIRST_DESC (1<<17) +#define RX_LAST_DESC (1<<16) +#define RX_ERROR (1<<15) + +/* TX descriptor command */ +#define TX_EN_INT (1<<23) +#define TX_GEN_CRC (1<<22) +#define TX_ZERO_PADDING (1<<18) +#define TX_FIRST_DESC (1<<17) +#define TX_LAST_DESC (1<<16) +#define TX_ERROR (1<<15) + +/* smi register */ +#define SMI_BUSY (1<<28) /* 0 - Write, 1 - Read */ +#define SMI_R_VALID (1<<27) /* 0 - Write, 1 - Read */ +#define SMI_OP_W (0<<26) /* Write operation */ +#define SMI_OP_R (1<<26) /* Read operation */ + +#define HASH_ADD 0 +#define HASH_DELETE 1 +#define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */ +#define HOP_NUMBER 12 + +#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */ +#define PHY_WAIT_MICRO_SECONDS 10 + +#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ +#define ETH_EXTRA_HEADER (6+6+2+4) + /* dest+src addr+protocol id+crc */ +#define MAX_PKT_SIZE 1536 + + +/* Bit definitions of the SDMA Config Reg */ +#define SDCR_BSZ_OFF 12 +#define SDCR_BSZ8 (3<<SDCR_BSZ_OFF) +#define SDCR_BSZ4 (2<<SDCR_BSZ_OFF) +#define SDCR_BSZ2 (1<<SDCR_BSZ_OFF) +#define SDCR_BSZ1 (0<<SDCR_BSZ_OFF) +#define SDCR_BLMR (1<<6) +#define SDCR_BLMT (1<<7) +#define SDCR_RIFB (1<<9) +#define SDCR_RC_OFF 2 +#define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF) + +/* SDMA_CMD */ +#define SDMA_CMD_AT (1<<31) +#define SDMA_CMD_TXDL (1<<24) +#define SDMA_CMD_TXDH (1<<23) +#define SDMA_CMD_AR (1<<15) +#define SDMA_CMD_ERD (1<<7) + + +/* Bit definitions of the Port Config Reg */ +#define PCR_HS (1<<12) +#define PCR_EN (1<<7) +#define PCR_PM (1<<0) + +/* Bit definitions of the Port Config Extend Reg */ +#define PCXR_2BSM (1<<28) +#define PCXR_DSCP_EN (1<<21) +#define PCXR_MFL_1518 (0<<14) +#define PCXR_MFL_1536 (1<<14) +#define PCXR_MFL_2048 (2<<14) +#define PCXR_MFL_64K (3<<14) +#define PCXR_FLP (1<<11) +#define PCXR_PRIO_TX_OFF 3 +#define PCXR_TX_HIGH_PRI (7<<PCXR_PRIO_TX_OFF) + +/* + * * Bit definitions of the Interrupt Cause Reg + * * and Interrupt MASK Reg is the same + * */ +#define ICR_RXBUF (1<<0) +#define ICR_TXBUF_H (1<<2) +#define ICR_TXBUF_L (1<<3) +#define ICR_TXEND_H (1<<6) +#define ICR_TXEND_L (1<<7) +#define ICR_RXERR (1<<8) +#define ICR_TXERR_H (1<<10) +#define ICR_TXERR_L (1<<11) +#define ICR_TX_UDR (1<<13) +#define ICR_MII_CH (1<<28) + +#define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\ + ICR_TXERR_H | ICR_TXERR_L |\ + ICR_TXEND_H | ICR_TXEND_L |\ + ICR_RXBUF | ICR_RXERR | ICR_MII_CH) + +#define PHY_MASK 0x0000001f + +#define to_darmdfec(_kd) container_of(_kd, struct armdfec_device, dev) +/* Size of a Tx/Rx descriptor used in chain list data structure */ +#define ARMDFEC_RXQ_DESC_ALIGNED_SIZE \ + (((sizeof(struct rx_desc) / PKTALIGN) + 1) * PKTALIGN) + +#define RX_BUF_OFFSET 0x2 +#define RXQ 0x0 /* RX Queue 0 */ +#define TXQ 0x1 /* TX Queue 1 */ + +struct addr_table_entry_t { + u32 lo; + u32 hi; +}; + +/* Bit fields of a Hash Table Entry */ +enum hash_table_entry { + HTEVALID = 1, + HTESKIP = 2, + HTERD = 4, + HTERDBIT = 2 +}; + +struct tx_desc { + u32 cmd_sts; /* Command/status field */ + u16 reserved; + u16 byte_cnt; /* buffer byte count */ + u8 *buf_ptr; /* pointer to buffer for this descriptor */ + struct tx_desc *nextdesc_p; /* Pointer to next descriptor */ +}; + +struct rx_desc { + u32 cmd_sts; /* Descriptor command status */ + u16 byte_cnt; /* Descriptor buffer byte count */ + u16 buf_size; /* Buffer size */ + u8 *buf_ptr; /* Descriptor buffer pointer */ + struct rx_desc *nxtdesc_p; /* Next descriptor pointer */ +}; + +/* + * Armada100 Fast Ethernet controller Registers + * Refer Datasheet Appendix A.22 + */ +struct armdfec_reg { + u32 phyadr; /* PHY Address */ + u32 pad1[3]; + u32 smi; /* SMI */ + u32 pad2[0xFB]; + u32 pconf; /* Port configuration */ + u32 pad3; + u32 pconf_ext; /* Port configuration extend */ + u32 pad4; + u32 pcmd; /* Port Command */ + u32 pad5; + u32 pstatus; /* Port Status */ + u32 pad6; + u32 spar; /* Serial Parameters */ + u32 pad7; + u32 htpr; /* Hash table pointer */ + u32 pad8; + u32 fcsal; /* Flow control source address low */ + u32 pad9; + u32 fcsah; /* Flow control source address high */ + u32 pad10; + u32 sdma_conf; /* SDMA configuration */ + u32 pad11; + u32 sdma_cmd; /* SDMA command */ + u32 pad12; + u32 ic; /* Interrupt cause */ + u32 iwc; /* Interrupt write to clear */ + u32 im; /* Interrupt mask */ + u32 pad13; + u32 *eth_idscpp[4]; /* Eth0 IP Differentiated Services Code + Point to Priority 0 Low */ + u32 eth_vlan_p; /* Eth0 VLAN Priority Tag to Priority */ + u32 pad14[3]; + struct rx_desc *rxfdp[4]; /* Ethernet First Rx Descriptor + Pointer */ + u32 pad15[4]; + struct rx_desc *rxcdp[4]; /* Ethernet Current Rx Descriptor + Pointer */ + u32 pad16[0x0C]; + struct tx_desc *txcdp[2]; /* Ethernet Current Tx Descriptor + Pointer */ +}; + +struct armdfec_device { + struct eth_device dev; + struct armdfec_reg *regs; + struct tx_desc *p_txdesc; + struct rx_desc *p_rxdesc; + struct rx_desc *p_rxdesc_curr; + u8 *p_rxbuf; + u8 *p_aligned_txbuf; + u8 *htpr; /* hash pointer */ +}; + +#endif /* __ARMADA100_FEC_H__ */ diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index c0b8929..a8905b8 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -680,6 +680,9 @@ int davinci_emac_initialize(void) davinci_eth_mdio_enable(); + /* let the EMAC detect the PHYs */ + udelay(5000); + for (i = 0; i < 256; i++) { if (readl(&adap_mdio->ALIVE)) break; @@ -711,6 +714,13 @@ int davinci_emac_initialize(void) phy_id |= tmp & 0x0000ffff; switch (phy_id) { + case PHY_KSZ8873: + sprintf(phy.name, "KSZ8873 @ 0x%02x", active_phy_addr); + phy.init = ksz8873_init_phy; + phy.is_phy_connected = ksz8873_is_phy_connected; + phy.get_link_speed = ksz8873_get_link_speed; + phy.auto_negotiate = ksz8873_auto_negotiate; + break; case PHY_LXT972: sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr); phy.init = lxt972_init_phy; @@ -740,7 +750,7 @@ int davinci_emac_initialize(void) phy.auto_negotiate = gen_auto_negotiate; } - printf("Ethernet PHY: %s\n", phy.name); + debug("Ethernet PHY: %s\n", phy.name); miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write); return(1); diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index ab90afa..cfe2176 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -38,6 +38,10 @@ DECLARE_GLOBAL_DATA_PTR; #error "CONFIG_MII has to be defined!" #endif +#ifndef CONFIG_FEC_XCV_TYPE +#define CONFIG_FEC_XCV_TYPE MII100 +#endif + #undef DEBUG struct nbuf { @@ -47,18 +51,6 @@ struct nbuf { uint8_t head[16]; /**< MAC header(6 + 6 + 2) + 2(aligned) */ }; -struct fec_priv gfec = { - .eth = (struct ethernet_regs *)IMX_FEC_BASE, - .xcv_type = MII100, - .rbd_base = NULL, - .rbd_index = 0, - .tbd_base = NULL, - .tbd_index = 0, - .bd = NULL, - .rdb_ptr = NULL, - .base_ptr = NULL, -}; - /* * MII-interface related functions */ @@ -67,6 +59,7 @@ static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr, { struct eth_device *edev = eth_get_dev_by_name(dev); struct fec_priv *fec = (struct fec_priv *)edev->priv; + struct ethernet_regs *eth = fec->eth; uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ @@ -76,18 +69,18 @@ static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr, * reading from any PHY's register is done by properly * programming the FEC's MII data register. */ - writel(FEC_IEVENT_MII, &fec->eth->ievent); + writel(FEC_IEVENT_MII, ð->ievent); reg = regAddr << FEC_MII_DATA_RA_SHIFT; phy = phyAddr << FEC_MII_DATA_PA_SHIFT; writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | - phy | reg, &fec->eth->mii_data); + phy | reg, ð->mii_data); /* * wait for the related interrupt */ start = get_timer(0); - while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) { + while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { printf("Read MDIO failed...\n"); return -1; @@ -97,12 +90,12 @@ static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr, /* * clear mii interrupt bit */ - writel(FEC_IEVENT_MII, &fec->eth->ievent); + writel(FEC_IEVENT_MII, ð->ievent); /* * it's now safe to read the PHY's register */ - *retVal = readl(&fec->eth->mii_data); + *retVal = readl(ð->mii_data); debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr, regAddr, *retVal); return 0; @@ -117,13 +110,14 @@ static void fec_mii_setspeed(struct fec_priv *fec) writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1, &fec->eth->mii_speed); debug("fec_init: mii_speed %#lx\n", - fec->eth->mii_speed); + readl(&fec->eth->mii_speed)); } static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr, uint16_t data) { struct eth_device *edev = eth_get_dev_by_name(dev); struct fec_priv *fec = (struct fec_priv *)edev->priv; + struct ethernet_regs *eth = fec->eth; uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ @@ -133,13 +127,13 @@ static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr, phy = phyAddr << FEC_MII_DATA_PA_SHIFT; writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | - FEC_MII_DATA_TA | phy | reg | data, &fec->eth->mii_data); + FEC_MII_DATA_TA | phy | reg | data, ð->mii_data); /* * wait for the MII interrupt */ start = get_timer(0); - while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) { + while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { printf("Write MDIO failed...\n"); return -1; @@ -149,7 +143,7 @@ static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr, /* * clear MII interrupt bit */ - writel(FEC_IEVENT_MII, &fec->eth->ievent); + writel(FEC_IEVENT_MII, ð->ievent); debug("fec_miiphy_write: phy: %02x reg:%02x val:%#x\n", phyAddr, regAddr, data); @@ -158,33 +152,40 @@ static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr, static int miiphy_restart_aneg(struct eth_device *dev) { + struct fec_priv *fec = (struct fec_priv *)dev->priv; + int ret = 0; + /* * Wake up from sleep if necessary * Reset PHY, then delay 300ns */ #ifdef CONFIG_MX27 - miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_DCOUNTER, 0x00FF); + miiphy_write(dev->name, fec->phy_id, MII_DCOUNTER, 0x00FF); #endif - miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_BMCR, + miiphy_write(dev->name, fec->phy_id, MII_BMCR, BMCR_RESET); udelay(1000); /* * Set the auto-negotiation advertisement register bits */ - miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_ADVERTISE, + miiphy_write(dev->name, fec->phy_id, MII_ADVERTISE, LPA_100FULL | LPA_100HALF | LPA_10FULL | LPA_10HALF | PHY_ANLPAR_PSB_802_3); - miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_BMCR, + miiphy_write(dev->name, fec->phy_id, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); - return 0; + if (fec->mii_postcall) + ret = fec->mii_postcall(fec->phy_id); + + return ret; } static int miiphy_wait_aneg(struct eth_device *dev) { uint32_t start; uint16_t status; + struct fec_priv *fec = (struct fec_priv *)dev->priv; /* * Wait for AN completion @@ -196,7 +197,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) return -1; } - if (miiphy_read(dev->name, CONFIG_FEC_MXC_PHYADDR, + if (miiphy_read(dev->name, fec->phy_id, MII_BMSR, &status)) { printf("%s: Autonegotiation failed. status: 0x%04x\n", dev->name, status); @@ -384,8 +385,8 @@ static int fec_open(struct eth_device *edev) #endif miiphy_wait_aneg(edev); - miiphy_speed(edev->name, CONFIG_FEC_MXC_PHYADDR); - miiphy_duplex(edev->name, CONFIG_FEC_MXC_PHYADDR); + miiphy_speed(edev->name, fec->phy_id); + miiphy_duplex(edev->name, fec->phy_id); /* * Enable SmartDMA receive task @@ -400,6 +401,9 @@ static int fec_init(struct eth_device *dev, bd_t* bd) { uint32_t base; struct fec_priv *fec = (struct fec_priv *)dev->priv; + uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; + uint32_t rcntrl; + int i; /* Initialize MAC address */ fec_set_hwaddr(dev); @@ -442,19 +446,21 @@ static int fec_init(struct eth_device *dev, bd_t* bd) /* * Set FEC-Lite receive control register(R_CNTRL): */ - if (fec->xcv_type == SEVENWIRE) { - /* - * Frame length=1518; 7-wire mode - */ - writel(0x05ee0020, &fec->eth->r_cntrl); /* FIXME 0x05ee0000 */ - } else { - /* - * Frame length=1518; MII mode; - */ - writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */ + /* Start with frame length = 1518, common for all modes. */ + rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT; + if (fec->xcv_type == SEVENWIRE) + rcntrl |= FEC_RCNTRL_FCE; + else if (fec->xcv_type == RMII) + rcntrl |= FEC_RCNTRL_RMII; + else /* MII mode */ + rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE; + + writel(rcntrl, &fec->eth->r_cntrl); + + if (fec->xcv_type == MII10 || fec->xcv_type == MII100) fec_mii_setspeed(fec); - } + /* * Set Opcode/Pause Duration Register */ @@ -468,9 +474,8 @@ static int fec_init(struct eth_device *dev, bd_t* bd) /* clear MIB RAM */ - long *mib_ptr = (long *)(IMX_FEC_BASE + 0x200); - while (mib_ptr <= (long *)(IMX_FEC_BASE + 0x2FC)) - *mib_ptr++ = 0; + for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) + writel(0, i); /* FIFO receive start register */ writel(0x520, &fec->eth->r_fstart); @@ -504,7 +509,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) */ static void fec_halt(struct eth_device *dev) { - struct fec_priv *fec = &gfec; + struct fec_priv *fec = (struct fec_priv *)dev->priv; int counter = 0xffff; /* @@ -685,19 +690,32 @@ static int fec_recv(struct eth_device *dev) return len; } -static int fec_probe(bd_t *bd) +static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr) { struct eth_device *edev; - struct fec_priv *fec = &gfec; + struct fec_priv *fec; unsigned char ethaddr[6]; + uint32_t start; + int ret = 0; /* create and fill edev struct */ edev = (struct eth_device *)malloc(sizeof(struct eth_device)); if (!edev) { - puts("fec_mxc: not enough malloc memory\n"); - return -ENOMEM; + puts("fec_mxc: not enough malloc memory for eth_device\n"); + ret = -ENOMEM; + goto err1; + } + + fec = (struct fec_priv *)malloc(sizeof(struct fec_priv)); + if (!fec) { + puts("fec_mxc: not enough malloc memory for fec_priv\n"); + ret = -ENOMEM; + goto err2; } + memset(edev, 0, sizeof(*edev)); + memset(fec, 0, sizeof(*fec)); + edev->priv = fec; edev->init = fec_init; edev->send = fec_send; @@ -705,15 +723,21 @@ static int fec_probe(bd_t *bd) edev->halt = fec_halt; edev->write_hwaddr = fec_set_hwaddr; - fec->eth = (struct ethernet_regs *)IMX_FEC_BASE; + fec->eth = (struct ethernet_regs *)base_addr; fec->bd = bd; - fec->xcv_type = MII100; + fec->xcv_type = CONFIG_FEC_XCV_TYPE; /* Reset chip. */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl); - while (readl(&fec->eth->ecntrl) & 1) + start = get_timer(0); + while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) { + if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { + printf("FEC MXC: Timeout reseting chip\n"); + goto err3; + } udelay(10); + } /* * Set interrupt mask register @@ -731,29 +755,63 @@ static int fec_probe(bd_t *bd) /* * Frame length=1518; MII mode; */ - writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */ + writel((PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT) | FEC_RCNTRL_FCE | + FEC_RCNTRL_MII_MODE, &fec->eth->r_cntrl); fec_mii_setspeed(fec); - sprintf(edev->name, "FEC"); + if (dev_id == -1) { + sprintf(edev->name, "FEC"); + fec->dev_id = 0; + } else { + sprintf(edev->name, "FEC%i", dev_id); + fec->dev_id = dev_id; + } + fec->phy_id = phy_id; miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write); eth_register(edev); if (fec_get_hwaddr(edev, ethaddr) == 0) { - printf("got MAC address from fuse: %pM\n", ethaddr); + debug("got MAC address from fuse: %pM\n", ethaddr); memcpy(edev->enetaddr, ethaddr, 6); } - return 0; + return ret; + +err3: + free(fec); +err2: + free(edev); +err1: + return ret; } +#ifndef CONFIG_FEC_MXC_MULTI int fecmxc_initialize(bd_t *bd) { int lout = 1; debug("eth_init: fec_probe(bd)\n"); - lout = fec_probe(bd); + lout = fec_probe(bd, -1, CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); return lout; } +#endif + +int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) +{ + int lout = 1; + + debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr); + lout = fec_probe(bd, dev_id, phy_id, addr); + + return lout; +} + +int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + fec->mii_postcall = cb; + return 0; +} diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 1ba5161..8b26645 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -32,6 +32,8 @@ #ifndef __FEC_MXC_H #define __FEC_MXC_H +void imx_get_mac_from_fuse(unsigned char *mac); + /** * Layout description of the FEC */ @@ -194,6 +196,7 @@ struct ethernet_regs { #define FEC_RCNTRL_PROM 0x00000008 #define FEC_RCNTRL_BC_REJ 0x00000010 #define FEC_RCNTRL_FCE 0x00000020 +#define FEC_RCNTRL_RMII 0x00000100 #define FEC_TCNTRL_GTS 0x00000001 #define FEC_TCNTRL_HBC 0x00000002 @@ -257,7 +260,8 @@ struct fec_bd { enum xceiver_type { SEVENWIRE, /* 7-wire */ MII10, /* MII 10Mbps */ - MII100 /* MII 100Mbps */ + MII100, /* MII 100Mbps */ + RMII /* RMII */ }; /** @@ -273,6 +277,9 @@ struct fec_priv { bd_t *bd; void *rdb_ptr; void *base_ptr; + int dev_id; + int phy_id; + int (*mii_postcall)(int); }; /** diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c index fef57b4..c5a0038 100644 --- a/drivers/power/twl6030.c +++ b/drivers/power/twl6030.c @@ -182,6 +182,13 @@ void twl6030_init_battery_charging(void) return; } +void twl6030_power_mmc_init() +{ + /* set voltage to 3.0 and turnon for APP */ + twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x15, VMMC_CFG_VOLTATE); + twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VMMC_CFG_STATE); +} + void twl6030_usb_device_settings() { u8 data = 0; diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ca27745..df440c6 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -30,6 +30,7 @@ LIB = $(obj)librtc.o COBJS-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o COBJS-$(CONFIG_RTC_BFIN) += bfin_rtc.o COBJS-y += date.o +COBJS-$(CONFIG_RTC_DAVINCI) += davinci.o COBJS-$(CONFIG_RTC_DS12887) += ds12887.o COBJS-$(CONFIG_RTC_DS1302) += ds1302.o COBJS-$(CONFIG_RTC_DS1306) += ds1306.o diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c new file mode 100644 index 0000000..8436cbf --- /dev/null +++ b/drivers/rtc/davinci.c @@ -0,0 +1,125 @@ +/* + * (C) Copyright 2011 DENX Software Engineering GmbH + * Heiko Schocher <hs@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 + */ +#include <common.h> +#include <command.h> +#include <rtc.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +#if defined(CONFIG_CMD_DATE) +struct davinci_rtc { + u_int32_t second; + u_int32_t minutes; + u_int32_t hours; + u_int32_t day; + u_int32_t month; /* 0x10 */ + u_int32_t year; + u_int32_t dotw; + u_int32_t resv1; + u_int32_t alarmsecond; /* 0x20 */ + u_int32_t alarmminute; + u_int32_t alarmhour; + u_int32_t alarmday; + u_int32_t alarmmonth; /* 0x30 */ + u_int32_t alarmyear; + u_int32_t resv2[2]; + u_int32_t ctrl; /* 0x40 */ + u_int32_t status; + u_int32_t irq; +}; + +#define RTC_STATE_BUSY 0x01 +#define RTC_STATE_RUN 0x02 + +#define davinci_rtc_base ((struct davinci_rtc *)DAVINCI_RTC_BASE) + +int rtc_get(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = davinci_rtc_base; + unsigned long sec, min, hour, mday, wday, mon_cent, year; + unsigned long status; + + status = readl(&rtc->status); + if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { + printf("RTC doesn't run\n"); + return -1; + } + if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) + udelay(20); + + sec = readl(&rtc->second); + min = readl(&rtc->minutes); + hour = readl(&rtc->hours); + mday = readl(&rtc->day); + wday = readl(&rtc->dotw); + mon_cent = readl(&rtc->month); + year = readl(&rtc->year); + + debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx " + "hr: %02lx min: %02lx sec: %02lx\n", + year, mon_cent, mday, wday, + hour, min, sec); + + tmp->tm_sec = bcd2bin(sec & 0x7F); + tmp->tm_min = bcd2bin(min & 0x7F); + tmp->tm_hour = bcd2bin(hour & 0x3F); + tmp->tm_mday = bcd2bin(mday & 0x3F); + tmp->tm_mon = bcd2bin(mon_cent & 0x1F); + tmp->tm_year = bcd2bin(year) + 2000; + tmp->tm_wday = bcd2bin(wday & 0x07); + tmp->tm_yday = 0; + tmp->tm_isdst = 0; + + debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; +} + +int rtc_set(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = davinci_rtc_base; + + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + writel(bin2bcd(tmp->tm_year % 100), &rtc->year); + writel(bin2bcd(tmp->tm_mon), &rtc->month); + + writel(bin2bcd(tmp->tm_wday), &rtc->dotw); + writel(bin2bcd(tmp->tm_mday), &rtc->day); + writel(bin2bcd(tmp->tm_hour), &rtc->hours); + writel(bin2bcd(tmp->tm_min), &rtc->minutes); + writel(bin2bcd(tmp->tm_sec), &rtc->second); + return 0; +} + +void rtc_reset(void) +{ + struct davinci_rtc *rtc = davinci_rtc_base; + + /* run RTC counter */ + writel(0x01, &rtc->ctrl); +} +#endif diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 710092d..fbcbdb3 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -181,7 +181,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "loadaddr=0x82000000\0" \ - "console=ttyS2,115200n8\0" \ + "console=ttyO2,115200n8\0" \ "mmcdev=0\0" \ "vram=12M\0" \ "dvimode=1024x768MR-16@60\0" \ @@ -308,4 +308,50 @@ CONFIG_SYS_INIT_RAM_SIZE - \ GENERATED_GBL_DATA_SIZE) +/* SRAM config */ +#define CONFIG_SYS_SRAM_START 0x40200000 +#define CONFIG_SYS_SRAM_SIZE 0x10000 + +/* Defines for SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_NAND_SIMPLE + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_POWER_SUPPORT +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds" + +#define CONFIG_SPL_TEXT_BASE 0x40200000 /*CONFIG_SYS_SRAM_START*/ +#define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ +#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK + +#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 + +/* NAND boot config */ +#define CONFIG_SYS_NAND_PAGE_COUNT 64 +#define CONFIG_SYS_NAND_PAGE_SIZE 2048 +#define CONFIG_SYS_NAND_OOBSIZE 64 +#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0 +#define CONFIG_SYS_NAND_ECCPOS {2, 3, 4, 5, 6, 7, 8, 9,\ + 10, 11, 12, 13} + +#define CONFIG_SYS_NAND_ECCSIZE 512 +#define CONFIG_SYS_NAND_ECCBYTES 3 + +#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \ + CONFIG_SYS_NAND_ECCSIZE) +#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \ + CONFIG_SYS_NAND_ECCSTEPS) + +#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 +#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000 + #endif /* __CONFIG_H */ diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h index b90e342..54f48e4 100644 --- a/include/configs/efikamx.h +++ b/include/configs/efikamx.h @@ -31,6 +31,10 @@ */ /* An i.MX51 CPU */ #define CONFIG_MX51 + +#define machine_is_efikamx() (CONFIG_MACH_TYPE == MACH_TYPE_MX51_EFIKAMX) +#define machine_is_efikasb() (CONFIG_MACH_TYPE == MACH_TYPE_MX51_EFIKASB) + #include <asm/arch/imx-regs.h> #define CONFIG_SYS_MX5_HCLK 24000000 @@ -230,6 +234,6 @@ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) #define CONFIG_SYS_DDR_CLKSEL 0 -#define CONFIG_SYS_CLKTL_CBCDR 0x59E35100 +#define CONFIG_SYS_CLKTL_CBCDR 0x59E35145 #endif diff --git a/include/configs/gplugd.h b/include/configs/gplugd.h index cc14f49..5f72163 100644 --- a/include/configs/gplugd.h +++ b/include/configs/gplugd.h @@ -62,8 +62,34 @@ #define CONFIG_CMD_I2C #define CONFIG_CMD_AUTOSCRIPT #undef CONFIG_CMD_FPGA -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_NFS + +/* Disable DCACHE */ +#define CONFIG_SYS_DCACHE_OFF + +/* Network configuration */ +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_PING +#define CONFIG_NET_MULTI +#define CONFIG_ARMADA100_FEC + +/* DHCP Support */ +#define CONFIG_CMD_DHCP +#define CONFIG_BOOTP_DHCP_REQUEST_DELAY 50000 +#endif /* CONFIG_CMD_NET */ + +/* GPIO Support */ +#define CONFIG_MARVELL_GPIO + +/* PHY configuration */ +#define CONFIG_MII +#define CONFIG_CMD_MII +#define CONFIG_RESET_PHY_R +/* 88E3015 register definition */ +#define PHY_LED_PAR_SEL_REG 22 +#define PHY_LED_MAN_REG 25 +#define PHY_LED_VAL 0x5b /* LINK LED1, ACT LED2 */ +/* GPIO Configuration for PHY */ +#define CONFIG_SYS_GPIO_PHY_RST 104 /* GPIO104 */ /* * mv-common.h should be defined after CMD configs since it used them diff --git a/include/configs/imx31_litekit.h b/include/configs/imx31_litekit.h index b7f1cb3..5e976bc 100644 --- a/include/configs/imx31_litekit.h +++ b/include/configs/imx31_litekit.h @@ -41,6 +41,8 @@ #define CONFIG_SYS_TEXT_BASE 0xa0000000 +#define CONFIG_MACH_TYPE MACH_TYPE_MX31LITE + /* Temporarily disabled */ #if 0 #define CONFIG_OF_LIBFDT 1 @@ -150,7 +152,7 @@ #define PHYS_SDRAM_1_SIZE (128 * 1024 * 1024) #define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_SYS_SDRAM_BASE CSD0_BASE +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 #define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR #define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h new file mode 100644 index 0000000..0afae24 --- /dev/null +++ b/include/configs/mx25pdk.h @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ + +#define CONFIG_MX25_CLK32 32768 /* OSC32K frequency */ +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_TEXT_BASE 0x81200000 + +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG + +#define CONFIG_MACH_TYPE MACH_TYPE_MX25_3DS + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) + +/* Physical Memory Map */ + +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM_1 0x80000000 +#define PHYS_SDRAM_1_SIZE (64 * 1024 * 1024) + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - \ + GENERATED_GBL_DATA_SIZE) + +/* Memory Test */ +#define CONFIG_SYS_MEMTEST_START (PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE/2) +#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) + +/* Stack sizes */ +#define CONFIG_STACKSIZE (128 * 1024) /* regular stack */ + +/* Serial Info */ +#define CONFIG_MXC_UART +#define CONFIG_SYS_MX25_UART1 +#define CONFIG_CONS_INDEX 1 /* use UART0 for console */ +#define CONFIG_BAUDRATE 115200 /* Default baud rate */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* No NOR flash present */ +#define CONFIG_ENV_OFFSET (6 * 64 * 1024) +#define CONFIG_ENV_SIZE (8 * 1024) +#define CONFIG_ENV_IS_NOWHERE + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_SYS_64BIT_VSPRINTF + +/* U-Boot general configuration */ +#define CONFIG_SYS_PROMPT "MX25PDK U-Boot > " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print buffer sz */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_CMDLINE_EDITING +#define CONFIG_SYS_LONGHELP + +/* U-Boot commands */ +#include <config_cmd_default.h> +#define CONFIG_CMD_CACHE + +/* Ethernet */ +#define CONFIG_FEC_MXC +#define CONFIG_FEC_MXC_PHYADDR 0x1f +#define CONFIG_MII +#define CONFIG_CMD_NET +#define CONFIG_NET_MULTI +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_LOADADDR 0x81000000 /* loadaddr env var */ +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "script=boot.scr\0" \ + "uimage=uImage\0" \ + "netargs=setenv bootargs console=ttymxc0,${baudrate} " \ + "root=/dev/nfs " \ + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ + "bootcmd=run netargs; dhcp ${uimage}; bootm\0" \ + +#endif /* __CONFIG_H */ diff --git a/include/configs/mx31ads.h b/include/configs/mx31ads.h index adb2ee1..0bea858 100644 --- a/include/configs/mx31ads.h +++ b/include/configs/mx31ads.h @@ -35,6 +35,8 @@ #define CONFIG_SYS_TEXT_BASE 0xA0000000 +#define CONFIG_MACH_TYPE MACH_TYPE_MX31ADS + /* * Disabled for now due to build problems under Debian and a significant increase * in the final file size: 144260 vs. 109536 Bytes. diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h index 1a5bdd1..cd156d8 100644 --- a/include/configs/mx31pdk.h +++ b/include/configs/mx31pdk.h @@ -45,6 +45,8 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG +#define CONFIG_MACH_TYPE MACH_TYPE_MX31_3DS + #if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CONFIG_SKIP_LOWLEVEL_INIT #endif @@ -124,7 +126,7 @@ * Miscellaneous configurable options */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ -#define CONFIG_SYS_PROMPT "uboot> " +#define CONFIG_SYS_PROMPT "MX31PDK U-Boot > " #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ /* Print Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h index 7d05dc8..d62a4f2 100644 --- a/include/configs/mx51evk.h +++ b/include/configs/mx51evk.h @@ -48,6 +48,7 @@ #define CONFIG_OF_LIBFDT 1 +#define CONFIG_MACH_TYPE MACH_TYPE_MX51_BABBAGE /* * Size of malloc() pool */ diff --git a/include/configs/mx53ard.h b/include/configs/mx53ard.h index c0b8d6a..26fc219 100644 --- a/include/configs/mx53ard.h +++ b/include/configs/mx53ard.h @@ -29,6 +29,8 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MACH_TYPE MACH_TYPE_MX53_ARD + #include <asm/arch/imx-regs.h> #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h index 7fb1d9a..b127b06 100644 --- a/include/configs/mx53evk.h +++ b/include/configs/mx53evk.h @@ -29,6 +29,8 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MACH_TYPE MACH_TYPE_MX53_EVK + #include <asm/arch/imx-regs.h> #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h index cfb38a5..4091703 100644 --- a/include/configs/mx53loco.h +++ b/include/configs/mx53loco.h @@ -30,6 +30,8 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MACH_TYPE MACH_TYPE_MX53_LOCO + #include <asm/arch/imx-regs.h> #define CONFIG_CMDLINE_TAG diff --git a/include/configs/mx53smd.h b/include/configs/mx53smd.h index 49f8c6e..261f0bc 100644 --- a/include/configs/mx53smd.h +++ b/include/configs/mx53smd.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2011 Freescale Semiconductor, Inc. * - * Configuration settings for the MX53-SMDFreescale board. + * Configuration settings for the MX53SMD Freescale board. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,6 +29,8 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MACH_TYPE MACH_TYPE_MX53_SMD + #include <asm/arch/imx-regs.h> #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h index fdc861d..7af30c2 100644 --- a/include/configs/omap3_evm.h +++ b/include/configs/omap3_evm.h @@ -200,7 +200,7 @@ "loadaddr=0x82000000\0" \ "usbtty=cdc_acm\0" \ "mmcdev=0\0" \ - "console=ttyS2,115200n8\0" \ + "console=ttyO0,115200n8\0" \ "mmcargs=setenv bootargs console=${console} " \ "root=/dev/mmcblk0p2 rw " \ "rootfstype=ext3 rootwait\0" \ diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h index d8ac8c0..228eac5 100644 --- a/include/configs/omap4_common.h +++ b/include/configs/omap4_common.h @@ -98,7 +98,9 @@ #define CONFIG_I2C_MULTI_BUS 1 /* TWL6030 */ +#ifndef CONFIG_SPL_BUILD #define CONFIG_TWL6030_POWER 1 +#endif /* MMC */ #define CONFIG_GENERIC_MMC 1 diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index 39d7154..9e03291 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -37,7 +37,9 @@ #include <configs/omap4_common.h> /* Battery Charger */ +#ifndef CONFIG_SPL_BUILD #define CONFIG_CMD_BAT 1 +#endif /* ENV related config options */ #define CONFIG_ENV_IS_IN_MMC 1 diff --git a/include/configs/vision2.h b/include/configs/vision2.h index b5c7357..d95c0ba 100644 --- a/include/configs/vision2.h +++ b/include/configs/vision2.h @@ -41,6 +41,8 @@ #define CONFIG_INITRD_TAG #define BOARD_LATE_INIT +#define CONFIG_MACH_TYPE MACH_TYPE_TTC_VISION2 + /* * Size of malloc() pool */ diff --git a/include/configs/zmx25.h b/include/configs/zmx25.h index 374c88a..ab7f30f 100644 --- a/include/configs/zmx25.h +++ b/include/configs/zmx25.h @@ -32,6 +32,7 @@ #define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_TEXT_BASE 0xA0000000 +#define CONFIG_MACH_TYPE MACH_TYPE_ZMX25 /* * Environment settings */ diff --git a/include/nand.h b/include/nand.h index 8d94b5c..b4140794 100644 --- a/include/nand.h +++ b/include/nand.h @@ -132,6 +132,12 @@ int nand_lock( nand_info_t *meminfo, int tight ); int nand_unlock( nand_info_t *meminfo, ulong start, ulong length ); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); +void nand_deselect(void); + +void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len); +void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len); + #ifdef CONFIG_SYS_NAND_SELECT_DEVICE void board_nand_select_device(struct nand_chip *nand, int chip); #endif diff --git a/include/netdev.h b/include/netdev.h index 96c7b9b..480453e 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -61,8 +61,8 @@ int ep93xx_eth_initialize(u8 dev_num, int base_addr); int eth_3com_initialize (bd_t * bis); int ethoc_initialize(u8 dev_num, int base_addr); int fec_initialize (bd_t *bis); -int fecmxc_initialize (bd_t *bis); int fecmxc_initialize(bd_t *bis); +int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr); int ftgmac100_initialize(bd_t *bits); int ftmac100_initialize(bd_t *bits); int greth_initialize(bd_t *bis); @@ -94,6 +94,7 @@ int smc911x_initialize(u8 dev_num, int base_addr); int tsi108_eth_initialize(bd_t *bis); int uec_standard_init(bd_t *bis); int uli526x_initialize(bd_t *bis); +int armada100_fec_register(unsigned long base_addr); int xilinx_emaclite_initialize (bd_t *bis, int base_addr); /* Boards with PCI network controllers can call this from their board_eth_init() @@ -185,4 +186,9 @@ struct mv88e61xx_config { int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig); #endif /* CONFIG_MV88E61XX_SWITCH */ +/* + * Allow FEC to fine-tune MII configuration on boards which require this. + */ +int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)); + #endif /* _NETDEV_H_ */ diff --git a/include/twl6030.h b/include/twl6030.h index 6ed68a0..a9fcadb 100644 --- a/include/twl6030.h +++ b/include/twl6030.h @@ -33,6 +33,8 @@ #define TWL6030_CHIP_PWM 0x49 /* Slave Address 0x48 */ +#define VMMC_CFG_STATE 0x9A +#define VMMC_CFG_VOLTATE 0x9B #define VUSB_CFG_STATE 0xA2 #define MISC1 0xE4 @@ -130,3 +132,4 @@ void twl6030_start_usb_charging(void); void twl6030_stop_usb_charging(void); int twl6030_get_battery_voltage(void); int twl6030_get_battery_current(void); +void twl6030_power_mmc_init(void); diff --git a/nand_spl/board/freescale/mx31pdk/Makefile b/nand_spl/board/freescale/mx31pdk/Makefile index e6ec10a..87784d2 100644 --- a/nand_spl/board/freescale/mx31pdk/Makefile +++ b/nand_spl/board/freescale/mx31pdk/Makefile @@ -1,7 +1,7 @@ CONFIG_NAND_SPL = y +PAD_TO := 2048 include $(TOPDIR)/config.mk -include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk nandobj := $(OBJTREE)/nand_spl/ diff --git a/nand_spl/board/freescale/mx31pdk/config.mk b/nand_spl/board/freescale/mx31pdk/config.mk deleted file mode 100644 index 68afbf1..0000000 --- a/nand_spl/board/freescale/mx31pdk/config.mk +++ /dev/null @@ -1 +0,0 @@ -PAD_TO := 2048 diff --git a/spl/Makefile b/spl/Makefile index 95ecce1..b44e84d 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -46,6 +46,8 @@ LIBS-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/libspi_flash.o LIBS-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/libspi.o LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o +LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o +LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o ifeq ($(SOC),omap3) LIBS-y += $(CPUDIR)/omap-common/libomap-common.o |