diff options
Diffstat (limited to 'arch')
50 files changed, 1746 insertions, 514 deletions
diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index e3a4d1b808..c6def5df9b 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 c05a39d084..717a2b72bd 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 3183e6a656..0310957f89 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 0000000000..1ea4a9ffce --- /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 b705dfd318..02819f6f74 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 0000000000..634eda0a02 --- /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 8b1734c8e1..c7bf7a5ad2 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 76e4b5c397..8e60a262eb 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 d164d6d6ca..5e30745057 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 00610a0d59..0769a645c3 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 ea9f8ec491..0b96b4789f 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 d1776522b7..c76fea6188 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 0000000000..1d1e50c3c4 --- /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 0000000000..af02a59557 --- /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 0448bc93ff..1b3ef69a99 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 0000000000..b34fa6417b --- /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 67e8ceb55a..a308ebdb6a 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 2a7970b4d0..0dd1955431 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 bdb151d7f6..22887aec05 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 309b244ad2..8584fdd590 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 d5d125a963..c449d4e639 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 0000000000..9e5e7b9b11 --- /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 d6e0494b7e..da76b58405 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 0000000000..0bc7f76f1c --- /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 0000000000..1b9430ce6b --- /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 4a4ee04229..294a9a88ed 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 29dcccf195..ef65ffbb9f 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 692d50755a..b6a3209ff9 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 0000000000..53c961e8da --- /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 9e30f7c2bc..eece138b45 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 0000000000..6a01a7b04c --- /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 b4b2fe61a6..83ab216665 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 2064870f44..0dcd9fe7eb 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 e741fb0bc6..0c566f27c2 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 4ed8eb31c8..fcc0e36fa5 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 a4e680b8d3..d069209b58 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 f165949f87..8e28f775df 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 bd22bce837..800e4ee4a2 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 995e7cb57e..7b60051344 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 a6e1e42e22..fc9c555d26 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 d3cb857282..66d6b71c1a 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/arch/blackfin/cpu/serial.c b/arch/blackfin/cpu/serial.c index 030160f418..6603dc099a 100644 --- a/arch/blackfin/cpu/serial.c +++ b/arch/blackfin/cpu/serial.c @@ -38,6 +38,7 @@ */ #include <common.h> +#include <post.h> #include <watchdog.h> #include <serial.h> #include <linux/compiler.h> @@ -153,6 +154,30 @@ static int uart_getc(uint32_t uart_base) return uart_rbr_val; } +#if CONFIG_POST & CONFIG_SYS_POST_UART +# define LOOP(x) x +#else +# define LOOP(x) +#endif + +LOOP( +static void uart_loop(uint32_t uart_base, int state) +{ + u16 mcr; + + /* Drain the TX fifo first so bytes don't come back */ + while (!(uart_lsr_read(uart_base) & TEMT)) + continue; + + mcr = bfin_read(&pUART->mcr); + if (state) + mcr |= LOOP_ENA | MRTS; + else + mcr &= ~(LOOP_ENA | MRTS); + bfin_write(&pUART->mcr, mcr); +} +) + #ifdef CONFIG_SYS_BFIN_UART static void uart_puts(uint32_t uart_base, const char *s) @@ -202,6 +227,13 @@ static void uart##n##_puts(const char *s) \ uart_puts(MMR_UART(n), s); \ } \ \ +LOOP( \ +static void uart##n##_loop(int state) \ +{ \ + uart_loop(MMR_UART(n), state); \ +} \ +) \ +\ struct serial_device bfin_serial##n##_device = { \ .name = "bfin_uart"#n, \ .init = uart##n##_init, \ @@ -211,6 +243,7 @@ struct serial_device bfin_serial##n##_device = { \ .tstc = uart##n##_tstc, \ .putc = uart##n##_putc, \ .puts = uart##n##_puts, \ + LOOP(.loop = uart##n##_loop) \ }; #ifdef UART0_DLL @@ -307,6 +340,13 @@ void serial_puts(const char *s) serial_putc(*s++); } +LOOP( +void serial_loop(int state) +{ + uart_loop(UART_DLL, state); +} +) + #endif #endif diff --git a/arch/blackfin/include/asm/config.h b/arch/blackfin/include/asm/config.h index bc3c25215f..53af310ecf 100644 --- a/arch/blackfin/include/asm/config.h +++ b/arch/blackfin/include/asm/config.h @@ -169,4 +169,22 @@ # define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } #endif +/* Blackfin POST tests */ +#ifdef CONFIG_POST_BSPEC1_GPIO_LEDS +# define CONFIG_POST_BSPEC1 \ + { \ + "LED test", "led", "This test verifies LEDs on the board.", \ + POST_MEM | POST_ALWAYS, &led_post_test, NULL, NULL, \ + CONFIG_SYS_POST_BSPEC1, \ + } +#endif +#ifdef CONFIG_POST_BSPEC2_GPIO_BUTTONS +# define CONFIG_POST_BSPEC2 \ + { \ + "Button test", "button", "This test verifies buttons on the board.", \ + POST_MEM | POST_ALWAYS, &button_post_test, NULL, NULL, \ + CONFIG_SYS_POST_BSPEC2, \ + } +#endif + #endif diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile index 4a227665aa..37e0663a32 100644 --- a/arch/blackfin/lib/Makefile +++ b/arch/blackfin/lib/Makefile @@ -46,7 +46,7 @@ COBJS-y += clocks.o COBJS-$(CONFIG_CMD_CACHE_DUMP) += cmd_cache_dump.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o COBJS-y += muldi3.o -COBJS-$(CONFIG_POST_ALT_LIST) += tests.o +COBJS-$(CONFIG_HAS_POST) += post.o COBJS-y += string.o SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) diff --git a/arch/blackfin/lib/post.c b/arch/blackfin/lib/post.c new file mode 100644 index 0000000000..b3c5fab576 --- /dev/null +++ b/arch/blackfin/lib/post.c @@ -0,0 +1,85 @@ +/* + * Blackfin POST code + * + * Copyright (c) 2005-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <config.h> +#include <post.h> + +#include <asm/gpio.h> + +#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1 +int led_post_test(int flags) +{ + unsigned leds[] = { CONFIG_POST_BSPEC1_GPIO_LEDS }; + int i; + + /* First turn them all off */ + for (i = 0; i < ARRAY_SIZE(leds); ++i) { + if (gpio_request(leds[i], "post")) { + printf("could not request gpio %u\n", leds[i]); + continue; + } + gpio_direction_output(leds[i], 0); + } + + /* Now turn them on one by one */ + for (i = 0; i < ARRAY_SIZE(leds); ++i) { + printf("LED%i on", i + 1); + gpio_set_value(leds[i], 1); + udelay(1000000); + printf("\b\b\b\b\b\b\b"); + gpio_free(leds[i]); + } + + return 0; +} +#endif + +#if CONFIG_POST & CONFIG_SYS_POST_BSPEC2 +int button_post_test(int flags) +{ + unsigned buttons[] = { CONFIG_POST_BSPEC2_GPIO_BUTTONS }; + unsigned int sws[] = { CONFIG_POST_BSPEC2_GPIO_NAMES }; + int i, delay = 5; + unsigned short value = 0; + int result = 0; + + for (i = 0; i < ARRAY_SIZE(buttons); ++i) { + if (gpio_request(buttons[i], "post")) { + printf("could not request gpio %u\n", buttons[i]); + continue; + } + gpio_direction_input(buttons[i]); + + delay = 5; + printf("\n--------Press SW%i: %2d ", sws[i], delay); + while (delay--) { + int j; + for (j = 0; j < 100; j++) { + value = gpio_get_value(buttons[i]); + if (value != 0) + break; + udelay(10000); + } + printf("\b\b\b%2d ", delay); + } + if (value != 0) + puts("\b\bOK"); + else { + result = -1; + puts("\b\bfailed"); + } + + gpio_free(buttons[i]); + } + + puts("\n"); + + return result; +} +#endif diff --git a/arch/blackfin/lib/tests.c b/arch/blackfin/lib/tests.c deleted file mode 100644 index bf7fba00c1..0000000000 --- a/arch/blackfin/lib/tests.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@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 - * - * Be sure to mark tests to be run before relocation as such with the - * CONFIG_SYS_POST_PREREL flag so that logging is done correctly if the - * logbuffer support is enabled. - */ - -#include <common.h> -#include <config.h> - -#include <post.h> -#define CONFIG_SYS_POST_FLASH 0x00004000 -#define CONFIG_SYS_POST_LED 0x00008000 -#define CONFIG_SYS_POST_BUTTON 0x00010000 - -extern int cache_post_test(int flags); -extern int watchdog_post_test(int flags); -extern int i2c_post_test(int flags); -extern int rtc_post_test(int flags); -extern int memory_post_test(int flags); -extern int cpu_post_test(int flags); -extern int uart_post_test(int flags); -extern int ether_post_test(int flags); -extern int spi_post_test(int flags); -extern int usb_post_test(int flags); -extern int spr_post_test(int flags); -extern int sysmon_post_test(int flags); -extern int dsp_post_test(int flags); -extern int codec_post_test(int flags); - -extern int sysmon_init_f(void); - -extern void sysmon_reloc(void); - -extern int flash_post_test(int flags); -extern int led_post_test(int flags); -extern int button_post_test(int flags); - -struct post_test post_list[] = { -#if CONFIG_POST & CONFIG_SYS_POST_CACHE - { - "Cache test", - "cache", - "This test verifies the CPU cache operation.", - POST_RAM | POST_ALWAYS, - &cache_post_test, - NULL, - NULL, - CONFIG_SYS_POST_CACHE}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_WATCHDOG - { - "Watchdog timer test", - "watchdog", - "This test checks the watchdog timer.", - POST_RAM | POST_POWERON | POST_SLOWTEST | POST_MANUAL | POST_REBOOT, - &watchdog_post_test, - NULL, - NULL, - CONFIG_SYS_POST_WATCHDOG}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_I2C - { - "I2C test", - "i2c", - "This test verifies the I2C operation.", - POST_RAM | POST_ALWAYS, - &i2c_post_test, - NULL, - NULL, - CONFIG_SYS_POST_I2C}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_RTC - { - "RTC test", - "rtc", - "This test verifies the RTC operation.", - POST_RAM | POST_SLOWTEST | POST_MANUAL, - &rtc_post_test, - NULL, - NULL, - CONFIG_SYS_POST_RTC}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_MEMORY - { - "Memory test", - "memory", - "This test checks RAM.", - POST_ROM | POST_POWERON | POST_SLOWTEST | POST_PREREL, - &memory_post_test, - NULL, - NULL, - CONFIG_SYS_POST_MEMORY}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_CPU - { - "CPU test", - "cpu", - "This test verifies the arithmetic logic unit of" " CPU.", - POST_RAM | POST_ALWAYS, - &cpu_post_test, - NULL, - NULL, - CONFIG_SYS_POST_CPU}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_UART - { - "UART test", - "uart", - "This test verifies the UART operation.", - POST_RAM | POST_SLOWTEST | POST_MANUAL, - &uart_post_test, - NULL, - NULL, - CONFIG_SYS_POST_UART}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_ETHER - { - "ETHERNET test", - "ethernet", - "This test verifies the ETHERNET operation.", - POST_RAM | POST_ALWAYS | POST_MANUAL, - ðer_post_test, - NULL, - NULL, - CONFIG_SYS_POST_ETHER}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_SPI - { - "SPI test", - "spi", - "This test verifies the SPI operation.", - POST_RAM | POST_ALWAYS | POST_MANUAL, - &spi_post_test, - NULL, - NULL, - CONFIG_SYS_POST_SPI}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_USB - { - "USB test", - "usb", - "This test verifies the USB operation.", - POST_RAM | POST_ALWAYS | POST_MANUAL, - &usb_post_test, - NULL, - NULL, - CONFIG_SYS_POST_USB}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_SPR - { - "SPR test", - "spr", - "This test checks SPR contents.", - POST_ROM | POST_ALWAYS | POST_PREREL, - &spr_post_test, - NULL, - NULL, - CONFIG_SYS_POST_SPR}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_SYSMON - { - "SYSMON test", - "sysmon", - "This test monitors system hardware.", - POST_RAM | POST_ALWAYS, - &sysmon_post_test, - &sysmon_init_f, - &sysmon_reloc, - CONFIG_SYS_POST_SYSMON}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_DSP - { - "DSP test", - "dsp", - "This test checks any connected DSP(s).", - POST_RAM | POST_MANUAL, - &dsp_post_test, - NULL, - NULL, - CONFIG_SYS_POST_DSP}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_CODEC - { - "CODEC test", - "codec", - "This test checks any connected codec(s).", - POST_RAM | POST_MANUAL, - &codec_post_test, - NULL, - NULL, - CONFIG_SYS_POST_CODEC}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_FLASH - { - "FLASH test", - "flash", - "This test checks flash.", - POST_RAM | POST_ALWAYS | POST_MANUAL, - &flash_post_test, - NULL, - NULL, - CONFIG_SYS_POST_FLASH}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_LED - { - "LED test", - "LED", - "This test checks LED ", - POST_RAM | POST_ALWAYS | POST_MANUAL, - &led_post_test, - NULL, - NULL, - CONFIG_SYS_POST_LED}, -#endif -#if CONFIG_POST & CONFIG_SYS_POST_BUTTON - { - "Button test", - "button", - "This test checks Button ", - POST_RAM | POST_ALWAYS | POST_MANUAL, - &button_post_test, - NULL, - NULL, - CONFIG_SYS_POST_BUTTON}, -#endif - -}; - -unsigned int post_list_size = sizeof(post_list) / sizeof(struct post_test); diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 93a9efdf10..9077f742ce 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -30,6 +30,13 @@ .text .global _start _start: + /* + * reserve registers: + * r10: Stores little/big endian offset for vectors + * r2: Stores imm opcode + * r3: Stores brai opcode + */ + mts rmsr, r0 /* disable cache */ addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET addi r1, r1, -4 /* Decrement SP to top of memory */ @@ -44,52 +51,34 @@ _start: * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3 */ addik r6, r0, 0x2 /* BIG/LITTLE endian offset */ - swi r6, r0, 0 - lbui r10, r0, 0 - swi r6, r0, 0x40 - swi r10, r0, 0x50 - - /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/ - addi r6, r0, 0xb0000000 /* hex b000 opcode imm */ - swi r6, r0, 0x0 /* reset address */ - swi r6, r0, 0x8 /* user vector exception */ - swi r6, r0, 0x10 /* interrupt */ - swi r6, r0, 0x20 /* hardware exception */ - - addi r6, r0, 0xb8080000 /* hew b808 opcode brai*/ - swi r6, r0, 0x4 /* reset address */ - swi r6, r0, 0xC /* user vector exception */ - swi r6, r0, 0x14 /* interrupt */ - swi r6, r0, 0x24 /* hardware exception */ + lwi r7, r0, 0x28 + swi r6, r0, 0x28 /* used first unused MB vector */ + lbui r10, r0, 0x28 /* used first unused MB vector */ + swi r7, r0, 0x28 + + /* add opcode instruction for 32bit jump - 2 instruction imm & brai */ + addi r2, r0, 0xb0000000 /* hex b000 opcode imm */ + addi r3, r0, 0xb8080000 /* hew b808 opcode brai */ #ifdef CONFIG_SYS_RESET_ADDRESS /* reset address */ + swi r2, r0, 0x0 /* reset address - imm opcode */ + swi r3, r0, 0x4 /* reset address - brai opcode */ + addik r6, r0, CONFIG_SYS_RESET_ADDRESS sw r6, r1, r0 - lhu r7, r1, r0 - shi r7, r0, 0x2 - shi r6, r0, 0x6 -/* - * Copy U-Boot code to CONFIG_SYS_TEXT_BASE - * solve problem with sbrk_base - */ -#if (CONFIG_SYS_RESET_ADDRESS != CONFIG_SYS_TEXT_BASE) - addi r4, r0, __end - addi r5, r0, __text_start - rsub r4, r5, r4 /* size = __end - __text_start */ - addi r6, r0, CONFIG_SYS_RESET_ADDRESS /* source address */ - addi r7, r0, 0 /* counter */ -4: - lw r8, r6, r7 - sw r8, r5, r7 - addi r7, r7, 0x4 - cmp r8, r4, r7 - blti r8, 4b -#endif + lhu r7, r1, r10 + rsubi r8, r10, 0x2 + sh r7, r0, r8 + rsubi r8, r10, 0x6 + sh r6, r0, r8 #endif #ifdef CONFIG_SYS_USR_EXCEP /* user_vector_exception */ + swi r2, r0, 0x8 /* user vector exception - imm opcode */ + swi r3, r0, 0xC /* user vector exception - brai opcode */ + addik r6, r0, _exception_handler sw r6, r1, r0 /* @@ -121,6 +110,9 @@ _start: #ifdef CONFIG_SYS_INTC_0 /* interrupt_handler */ + swi r2, r0, 0x10 /* interrupt - imm opcode */ + swi r3, r0, 0x14 /* interrupt - brai opcode */ + addik r6, r0, _interrupt_handler sw r6, r1, r0 lhu r7, r1, r10 @@ -131,6 +123,9 @@ _start: #endif /* hardware exception */ + swi r2, r0, 0x20 /* hardware exception - imm opcode */ + swi r3, r0, 0x24 /* hardware exception - brai opcode */ + addik r6, r0, _hw_exception_handler sw r6, r1, r0 lhu r7, r1, r10 diff --git a/arch/powerpc/cpu/mpc5xxx/i2c.c b/arch/powerpc/cpu/mpc5xxx/i2c.c index 9fb330f82f..f9d293b7ce 100644 --- a/arch/powerpc/cpu/mpc5xxx/i2c.c +++ b/arch/powerpc/cpu/mpc5xxx/i2c.c @@ -332,8 +332,7 @@ static int mpc_get_fdr(int speed) if (gd->flags & GD_FLG_RELOC) { fdr = divider; } else { - if (gd->have_console) - printf("%ld kHz, ", best_speed / 1000); + printf("%ld kHz, ", best_speed / 1000); return divider; } } @@ -374,34 +373,29 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) xaddr[3] = addr & 0xFF; if (wait_for_bb()) { - if (gd->have_console) - printf("i2c_read: bus is busy\n"); + printf("i2c_read: bus is busy\n"); goto Done; } mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); if (do_address(chip, 0)) { - if (gd->have_console) - printf("i2c_read: failed to address chip\n"); + printf("i2c_read: failed to address chip\n"); goto Done; } if (send_bytes(chip, &xaddr[4-alen], alen)) { - if (gd->have_console) - printf("i2c_read: send_bytes failed\n"); + printf("i2c_read: send_bytes failed\n"); goto Done; } mpc_reg_out(®s->mcr, I2C_RSTA, I2C_RSTA); if (do_address(chip, 1)) { - if (gd->have_console) - printf("i2c_read: failed to address chip\n"); + printf("i2c_read: failed to address chip\n"); goto Done; } if (receive_bytes(chip, (char *)buf, len)) { - if (gd->have_console) - printf("i2c_read: receive_bytes failed\n"); + printf("i2c_read: receive_bytes failed\n"); goto Done; } @@ -423,27 +417,23 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) xaddr[3] = addr & 0xFF; if (wait_for_bb()) { - if (gd->have_console) - printf("i2c_write: bus is busy\n"); + printf("i2c_write: bus is busy\n"); goto Done; } mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); if (do_address(chip, 0)) { - if (gd->have_console) - printf("i2c_write: failed to address chip\n"); + printf("i2c_write: failed to address chip\n"); goto Done; } if (send_bytes(chip, &xaddr[4-alen], alen)) { - if (gd->have_console) - printf("i2c_write: send_bytes failed\n"); + printf("i2c_write: send_bytes failed\n"); goto Done; } if (send_bytes(chip, (char *)buf, len)) { - if (gd->have_console) - printf("i2c_write: send_bytes failed\n"); + printf("i2c_write: send_bytes failed\n"); goto Done; } diff --git a/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c index c82958db1b..b05f5762e5 100644 --- a/arch/powerpc/cpu/mpc8260/ether_fcc.c +++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c @@ -687,7 +687,7 @@ eth_loopback_test (void) immr->im_cpmux.cmx_fcr = CMXFCR_RF1CS_CLK10|CMXFCR_TF1CS_CLK11|\ CMXFCR_RF2CS_CLK13|CMXFCR_TF2CS_CLK14|\ CMXFCR_RF3CS_CLK15|CMXFCR_TF3CS_CLK16; -#elif defined(CONFIG_SBC8260) || defined(CONFIG_SACSng) +#elif defined(CONFIG_SACSng) /* * Attention: this is board-specific * 1, FCC2 diff --git a/arch/powerpc/cpu/mpc8xx/i2c.c b/arch/powerpc/cpu/mpc8xx/i2c.c index 338cababe8..1ca51fddef 100644 --- a/arch/powerpc/cpu/mpc8xx/i2c.c +++ b/arch/powerpc/cpu/mpc8xx/i2c.c @@ -633,22 +633,19 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { - if (gd->have_console) - printf("i2c_read: i2c_send failed (%d)\n", rc); + printf("i2c_read: i2c_send failed (%d)\n", rc); return 1; } rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { - if (gd->have_console) - printf("i2c_read: i2c_receive failed (%d)\n", rc); + printf("i2c_read: i2c_receive failed (%d)\n", rc); return 1; } rc = i2c_doio(&state); if (rc != 0) { - if (gd->have_console) - printf("i2c_read: i2c_doio failed (%d)\n", rc); + printf("i2c_read: i2c_doio failed (%d)\n", rc); return 1; } return 0; @@ -683,22 +680,19 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]); if (rc != 0) { - if (gd->have_console) - printf("i2c_write: first i2c_send failed (%d)\n", rc); + printf("i2c_write: first i2c_send failed (%d)\n", rc); return 1; } rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { - if (gd->have_console) - printf("i2c_write: second i2c_send failed (%d)\n", rc); + printf("i2c_write: second i2c_send failed (%d)\n", rc); return 1; } rc = i2c_doio(&state); if (rc != 0) { - if (gd->have_console) - printf("i2c_write: i2c_doio failed (%d)\n", rc); + printf("i2c_write: i2c_doio failed (%d)\n", rc); return 1; } return 0; |