diff options
author | Otavio Salvador <otavio@ossystems.com.br> | 2012-08-05 09:05:29 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-09-01 14:58:17 +0200 |
commit | 3a0398d7b916eed6ae80427626f0434690ca0da0 (patch) | |
tree | 6df395fa52909a8977f38df93533a1a5a701df9d /arch/arm/cpu/arm926ejs/mx28 | |
parent | d369d53d9c438a5d0df157586dcd072de48d9631 (diff) | |
download | u-boot-imx-3a0398d7b916eed6ae80427626f0434690ca0da0.zip u-boot-imx-3a0398d7b916eed6ae80427626f0434690ca0da0.tar.gz u-boot-imx-3a0398d7b916eed6ae80427626f0434690ca0da0.tar.bz2 |
mxs: reorganize source directory for easy sharing of code in i.MXS SoCs
Most code can be shared between i.MX23 and i.MX28 as both are from
i.MXS family; this source directory structure makes easy to share code
among them.
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Acked-by: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'arch/arm/cpu/arm926ejs/mx28')
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/Makefile | 50 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/clock.c | 339 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/iomux.c | 109 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/mx28.c | 342 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/mx28_init.h | 45 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 135 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c | 86 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c | 250 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 1007 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/start.S | 247 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/timer.c | 156 | ||||
-rw-r--r-- | arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds | 87 |
12 files changed, 0 insertions, 2853 deletions
diff --git a/arch/arm/cpu/arm926ejs/mx28/Makefile b/arch/arm/cpu/arm926ejs/mx28/Makefile deleted file mode 100644 index 674a3af..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# 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 -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(SOC).o - -COBJS = clock.o mx28.o iomux.o timer.o - -ifdef CONFIG_SPL_BUILD -COBJS += spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o -endif - -SRCS := $(START:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(call cmd_link_o_target, $(OBJS)) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/arch/arm/cpu/arm926ejs/mx28/clock.c b/arch/arm/cpu/arm926ejs/mx28/clock.c deleted file mode 100644 index 0439f9c..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/clock.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Freescale i.MX28 clock setup code - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * Based on code from LTIB: - * Copyright (C) 2010 Freescale Semiconductor, Inc. - * - * 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/errno.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> - -/* The PLL frequency is always 480MHz, see section 10.2 in iMX28 datasheet. */ -#define PLL_FREQ_KHZ 480000 -#define PLL_FREQ_COEF 18 -/* The XTAL frequency is always 24MHz, see section 10.2 in iMX28 datasheet. */ -#define XTAL_FREQ_KHZ 24000 - -#define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000) -#define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000) - -static uint32_t mx28_get_pclk(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - uint32_t clkctrl, clkseq, div; - uint8_t clkfrac, frac; - - clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu); - - /* No support of fractional divider calculation */ - if (clkctrl & - (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) { - return 0; - } - - clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); - - /* XTAL Path */ - if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) { - div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >> - CLKCTRL_CPU_DIV_XTAL_OFFSET; - return XTAL_FREQ_MHZ / div; - } - - /* REF Path */ - clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]); - frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; - div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK; - return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; -} - -static uint32_t mx28_get_hclk(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - uint32_t div; - uint32_t clkctrl; - - clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus); - - /* No support of fractional divider calculation */ - if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN) - return 0; - - div = clkctrl & CLKCTRL_HBUS_DIV_MASK; - return mx28_get_pclk() / div; -} - -static uint32_t mx28_get_emiclk(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - uint32_t clkctrl, clkseq, div; - uint8_t clkfrac, frac; - - clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); - clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi); - - /* XTAL Path */ - if (clkseq & CLKCTRL_CLKSEQ_BYPASS_EMI) { - div = (clkctrl & CLKCTRL_EMI_DIV_XTAL_MASK) >> - CLKCTRL_EMI_DIV_XTAL_OFFSET; - return XTAL_FREQ_MHZ / div; - } - - /* REF Path */ - clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]); - frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; - div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK; - return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; -} - -static uint32_t mx28_get_gpmiclk(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - uint32_t clkctrl, clkseq, div; - uint8_t clkfrac, frac; - - clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); - clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi); - - /* XTAL Path */ - if (clkseq & CLKCTRL_CLKSEQ_BYPASS_GPMI) { - div = clkctrl & CLKCTRL_GPMI_DIV_MASK; - return XTAL_FREQ_MHZ / div; - } - - /* REF Path */ - clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]); - frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; - div = clkctrl & CLKCTRL_GPMI_DIV_MASK; - return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; -} - -/* - * Set IO clock frequency, in kHz - */ -void mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - uint32_t div; - int io_reg; - - if (freq == 0) - return; - - if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) - return; - - div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq; - - if (div < 18) - div = 18; - - if (div > 35) - div = 35; - - io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ - writeb(CLKCTRL_FRAC_CLKGATE, - &clkctrl_regs->hw_clkctrl_frac0_set[io_reg]); - writeb(CLKCTRL_FRAC_CLKGATE | (div & CLKCTRL_FRAC_FRAC_MASK), - &clkctrl_regs->hw_clkctrl_frac0[io_reg]); - writeb(CLKCTRL_FRAC_CLKGATE, - &clkctrl_regs->hw_clkctrl_frac0_clr[io_reg]); -} - -/* - * Get IO clock, returns IO clock in kHz - */ -static uint32_t mx28_get_ioclk(enum mxs_ioclock io) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - uint8_t ret; - int io_reg; - - if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) - return 0; - - io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ - - ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) & - CLKCTRL_FRAC_FRAC_MASK; - - return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret; -} - -/* - * Configure SSP clock frequency, in kHz - */ -void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - uint32_t clk, clkreg; - - if (ssp > MXC_SSPCLK3) - return; - - clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + - (ssp * sizeof(struct mx28_register_32)); - - clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE); - while (readl(clkreg) & CLKCTRL_SSP_CLKGATE) - ; - - if (xtal) - clk = XTAL_FREQ_KHZ; - else - clk = mx28_get_ioclk(ssp >> 1); - - if (freq > clk) - return; - - /* Calculate the divider and cap it if necessary */ - clk /= freq; - if (clk > CLKCTRL_SSP_DIV_MASK) - clk = CLKCTRL_SSP_DIV_MASK; - - clrsetbits_le32(clkreg, CLKCTRL_SSP_DIV_MASK, clk); - while (readl(clkreg) & CLKCTRL_SSP_BUSY) - ; - - if (xtal) - writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, - &clkctrl_regs->hw_clkctrl_clkseq_set); - else - writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, - &clkctrl_regs->hw_clkctrl_clkseq_clr); -} - -/* - * Return SSP frequency, in kHz - */ -static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - uint32_t clkreg; - uint32_t clk, tmp; - - if (ssp > MXC_SSPCLK3) - return 0; - - tmp = readl(&clkctrl_regs->hw_clkctrl_clkseq); - if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp)) - return XTAL_FREQ_KHZ; - - clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + - (ssp * sizeof(struct mx28_register_32)); - - tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK; - - if (tmp == 0) - return 0; - - clk = mx28_get_ioclk(ssp >> 1); - - return clk / tmp; -} - -/* - * Set SSP/MMC bus frequency, in kHz) - */ -void mx28_set_ssp_busclock(unsigned int bus, uint32_t freq) -{ - struct mx28_ssp_regs *ssp_regs; - const uint32_t sspclk = mx28_get_sspclk(bus); - uint32_t reg; - uint32_t divide, rate, tgtclk; - - ssp_regs = (struct mx28_ssp_regs *)(MXS_SSP0_BASE + (bus * 0x2000)); - - /* - * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)), - * CLOCK_DIVIDE has to be an even value from 2 to 254, and - * CLOCK_RATE could be any integer from 0 to 255. - */ - for (divide = 2; divide < 254; divide += 2) { - rate = sspclk / freq / divide; - if (rate <= 256) - break; - } - - tgtclk = sspclk / divide / rate; - while (tgtclk > freq) { - rate++; - tgtclk = sspclk / divide / rate; - } - if (rate > 256) - rate = 256; - - /* Always set timeout the maximum */ - reg = SSP_TIMING_TIMEOUT_MASK | - (divide << SSP_TIMING_CLOCK_DIVIDE_OFFSET) | - ((rate - 1) << SSP_TIMING_CLOCK_RATE_OFFSET); - writel(reg, &ssp_regs->hw_ssp_timing); - - debug("SPI%d: Set freq rate to %d KHz (requested %d KHz)\n", - bus, tgtclk, freq); -} - -uint32_t mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return mx28_get_pclk() * 1000000; - case MXC_GPMI_CLK: - return mx28_get_gpmiclk() * 1000000; - case MXC_AHB_CLK: - case MXC_IPG_CLK: - return mx28_get_hclk() * 1000000; - case MXC_EMI_CLK: - return mx28_get_emiclk(); - case MXC_IO0_CLK: - return mx28_get_ioclk(MXC_IOCLK0); - case MXC_IO1_CLK: - return mx28_get_ioclk(MXC_IOCLK1); - case MXC_SSP0_CLK: - return mx28_get_sspclk(MXC_SSPCLK0); - case MXC_SSP1_CLK: - return mx28_get_sspclk(MXC_SSPCLK1); - case MXC_SSP2_CLK: - return mx28_get_sspclk(MXC_SSPCLK2); - case MXC_SSP3_CLK: - return mx28_get_sspclk(MXC_SSPCLK3); - } - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mx28/iomux.c b/arch/arm/cpu/arm926ejs/mx28/iomux.c deleted file mode 100644 index 12916b6..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/iomux.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, - * <armlinux@phytec.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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <common.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/iomux.h> -#include <asm/arch/imx-regs.h> - -#if defined(CONFIG_MX23) -#define DRIVE_OFFSET 0x200 -#define PULL_OFFSET 0x400 -#elif defined(CONFIG_MX28) -#define DRIVE_OFFSET 0x300 -#define PULL_OFFSET 0x600 -#else -#error "Please select CONFIG_MX23 or CONFIG_MX28" -#endif - -/* - * configures a single pad in the iomuxer - */ -int mxs_iomux_setup_pad(iomux_cfg_t pad) -{ - u32 reg, ofs, bp, bm; - void *iomux_base = (void *)MXS_PINCTRL_BASE; - struct mx28_register_32 *mxs_reg; - - /* muxsel */ - ofs = 0x100; - ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10; - bp = PAD_PIN(pad) % 16 * 2; - bm = 0x3 << bp; - reg = readl(iomux_base + ofs); - reg &= ~bm; - reg |= PAD_MUXSEL(pad) << bp; - writel(reg, iomux_base + ofs); - - /* drive */ - ofs = DRIVE_OFFSET; - ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10; - /* mA */ - if (PAD_MA_VALID(pad)) { - bp = PAD_PIN(pad) % 8 * 4; - bm = 0x3 << bp; - reg = readl(iomux_base + ofs); - reg &= ~bm; - reg |= PAD_MA(pad) << bp; - writel(reg, iomux_base + ofs); - } - /* vol */ - if (PAD_VOL_VALID(pad)) { - bp = PAD_PIN(pad) % 8 * 4 + 2; - mxs_reg = (struct mx28_register_32 *)(iomux_base + ofs); - if (PAD_VOL(pad)) - writel(1 << bp, &mxs_reg->reg_set); - else - writel(1 << bp, &mxs_reg->reg_clr); - } - - /* pull */ - if (PAD_PULL_VALID(pad)) { - ofs = PULL_OFFSET; - ofs += PAD_BANK(pad) * 0x10; - bp = PAD_PIN(pad); - mxs_reg = (struct mx28_register_32 *)(iomux_base + ofs); - if (PAD_PULL(pad)) - writel(1 << bp, &mxs_reg->reg_set); - else - writel(1 << bp, &mxs_reg->reg_clr); - } - - return 0; -} - -int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count) -{ - const iomux_cfg_t *p = pad_list; - int i; - int ret; - - for (i = 0; i < count; i++) { - ret = mxs_iomux_setup_pad(*p); - if (ret) - return ret; - p++; - } - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28.c b/arch/arm/cpu/arm926ejs/mx28/mx28.c deleted file mode 100644 index cf7a50f..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/mx28.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Freescale i.MX28 common code - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * Based on code from LTIB: - * Copyright (C) 2010 Freescale Semiconductor, Inc. - * - * 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/errno.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/dma.h> -#include <asm/arch/gpio.h> -#include <asm/arch/iomux.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/sys_proto.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* 1 second delay should be plenty of time for block reset. */ -#define RESET_MAX_TIMEOUT 1000000 - -#define MX28_BLOCK_SFTRST (1 << 31) -#define MX28_BLOCK_CLKGATE (1 << 30) - -/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} - -void reset_cpu(ulong ignored) __attribute__((noreturn)); - -void reset_cpu(ulong ignored) -{ - struct mx28_rtc_regs *rtc_regs = - (struct mx28_rtc_regs *)MXS_RTC_BASE; - struct mx28_lcdif_regs *lcdif_regs = - (struct mx28_lcdif_regs *)MXS_LCDIF_BASE; - - /* - * Shut down the LCD controller as it interferes with BootROM boot mode - * pads sampling. - */ - writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr); - - /* Wait 1 uS before doing the actual watchdog reset */ - writel(1, &rtc_regs->hw_rtc_watchdog); - writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set); - - /* Endless loop, reset will exit from here */ - for (;;) - ; -} - -void enable_caches(void) -{ -#ifndef CONFIG_SYS_ICACHE_OFF - icache_enable(); -#endif -#ifndef CONFIG_SYS_DCACHE_OFF - dcache_enable(); -#endif -} - -int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == mask) - break; - udelay(1); - } - - return !timeout; -} - -int mx28_wait_mask_clr(struct mx28_register_32 *reg, uint32_t mask, int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == 0) - break; - udelay(1); - } - - return !timeout; -} - -int mx28_reset_block(struct mx28_register_32 *reg) -{ - /* Clear SFTRST */ - writel(MX28_BLOCK_SFTRST, ®->reg_clr); - - if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MX28_BLOCK_CLKGATE, ®->reg_clr); - - /* Set SFTRST */ - writel(MX28_BLOCK_SFTRST, ®->reg_set); - - /* Wait for CLKGATE being set */ - if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear SFTRST */ - writel(MX28_BLOCK_SFTRST, ®->reg_clr); - - if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MX28_BLOCK_CLKGATE, ®->reg_clr); - - if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - return 0; -} - -void mx28_fixup_vt(uint32_t start_addr) -{ - uint32_t *vt = (uint32_t *)0x20; - int i; - - for (i = 0; i < 8; i++) - vt[i] = start_addr + (4 * i); -} - -#ifdef CONFIG_ARCH_MISC_INIT -int arch_misc_init(void) -{ - mx28_fixup_vt(gd->relocaddr); - return 0; -} -#endif - -int arch_cpu_init(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - extern uint32_t _start; - - mx28_fixup_vt((uint32_t)&_start); - - /* - * Enable NAND clock - */ - /* Clear bypass bit */ - writel(CLKCTRL_CLKSEQ_BYPASS_GPMI, - &clkctrl_regs->hw_clkctrl_clkseq_set); - - /* Set GPMI clock to ref_gpmi / 12 */ - clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi, - CLKCTRL_GPMI_CLKGATE | CLKCTRL_GPMI_DIV_MASK, 1); - - udelay(1000); - - /* - * Configure GPIO unit - */ - mxs_gpio_init(); - -#ifdef CONFIG_APBH_DMA - /* Start APBH DMA */ - mxs_dma_init(); -#endif - - return 0; -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -static const char *get_cpu_type(void) -{ - struct mx28_digctl_regs *digctl_regs = - (struct mx28_digctl_regs *)MXS_DIGCTL_BASE; - - switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { - case HW_DIGCTL_CHIPID_MX28: - return "28"; - default: - return "??"; - } -} - -static const char *get_cpu_rev(void) -{ - struct mx28_digctl_regs *digctl_regs = - (struct mx28_digctl_regs *)MXS_DIGCTL_BASE; - uint8_t rev = readl(&digctl_regs->hw_digctl_chipid) & 0x000000FF; - - switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { - case HW_DIGCTL_CHIPID_MX28: - switch (rev) { - case 0x1: - return "1.2"; - default: - return "??"; - } - default: - return "??"; - } -} - -int print_cpuinfo(void) -{ - struct mx28_spl_data *data = (struct mx28_spl_data *) - ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf); - - printf("CPU: Freescale i.MX%s rev%s at %d MHz\n", - get_cpu_type(), - get_cpu_rev(), - mxc_get_clock(MXC_ARM_CLK) / 1000000); - printf("BOOT: %s\n", mx28_boot_modes[data->boot_mode_idx].mode); - return 0; -} -#endif - -int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) -{ - printf("CPU: %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000); - printf("BUS: %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000); - printf("EMI: %3d MHz\n", mxc_get_clock(MXC_EMI_CLK)); - printf("GPMI: %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000); - return 0; -} - -/* - * Initializes on-chip ethernet controllers. - */ -#ifdef CONFIG_CMD_NET -int cpu_eth_init(bd_t *bis) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - /* Turn on ENET clocks */ - clrbits_le32(&clkctrl_regs->hw_clkctrl_enet, - CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE); - - /* Set up ENET PLL for 50 MHz */ - /* Power on ENET PLL */ - writel(CLKCTRL_PLL2CTRL0_POWER, - &clkctrl_regs->hw_clkctrl_pll2ctrl0_set); - - udelay(10); - - /* Gate on ENET PLL */ - writel(CLKCTRL_PLL2CTRL0_CLKGATE, - &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr); - - /* Enable pad output */ - setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN); - - return 0; -} -#endif - -static void __mx28_adjust_mac(int dev_id, unsigned char *mac) -{ - mac[0] = 0x00; - mac[1] = 0x04; /* Use FSL vendor MAC address by default */ - - if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */ - mac[5] += 1; -} - -void mx28_adjust_mac(int dev_id, unsigned char *mac) - __attribute__((weak, alias("__mx28_adjust_mac"))); - -#ifdef CONFIG_MX28_FEC_MAC_IN_OCOTP - -#define MXS_OCOTP_MAX_TIMEOUT 1000000 -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) -{ - struct mx28_ocotp_regs *ocotp_regs = - (struct mx28_ocotp_regs *)MXS_OCOTP_BASE; - uint32_t data; - - memset(mac, 0, 6); - - writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set); - - if (mx28_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY, - MXS_OCOTP_MAX_TIMEOUT)) { - printf("MXS FEC: Can't get MAC from OCOTP\n"); - return; - } - - data = readl(&ocotp_regs->hw_ocotp_cust0); - - mac[2] = (data >> 24) & 0xff; - mac[3] = (data >> 16) & 0xff; - mac[4] = (data >> 8) & 0xff; - mac[5] = data & 0xff; - mx28_adjust_mac(dev_id, mac); -} -#else -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) -{ - memset(mac, 0, 6); -} -#endif - -int mx28_dram_init(void) -{ - struct mx28_spl_data *data = (struct mx28_spl_data *) - ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf); - - if (data->mem_dram_size == 0) { - printf("MX28:\n" - "Error, the RAM size passed up from SPL is 0!\n"); - hang(); - } - - gd->ram_size = data->mem_dram_size; - return 0; -} - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28_init.h b/arch/arm/cpu/arm926ejs/mx28/mx28_init.h deleted file mode 100644 index e3a4493..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/mx28_init.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Freescale i.MX28 SPL functions - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 __M28_INIT_H__ -#define __M28_INIT_H__ - -void early_delay(int delay); - -void mx28_power_init(void); - -#ifdef CONFIG_SPL_MX28_PSWITCH_WAIT -void mx28_power_wait_pswitch(void); -#else -static inline void mx28_power_wait_pswitch(void) { } -#endif - -void mx28_mem_init(void); -uint32_t mx28_mem_get_size(void); - -void mx28_lradc_init(void); -void mx28_lradc_enable_batt_measurement(void); - -#endif /* __M28_INIT_H__ */ diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_boot.c b/arch/arm/cpu/arm926ejs/mx28/spl_boot.c deleted file mode 100644 index a6dfca3..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/spl_boot.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Freescale i.MX28 Boot setup - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 <config.h> -#include <asm/io.h> -#include <asm/arch/iomux-mx28.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/sys_proto.h> -#include <asm/gpio.h> - -#include "mx28_init.h" - -/* - * This delay function is intended to be used only in early stage of boot, where - * clock are not set up yet. The timer used here is reset on every boot and - * takes a few seconds to roll. The boot doesn't take that long, so to keep the - * code simple, it doesn't take rolling into consideration. - */ -#define HW_DIGCTRL_MICROSECONDS 0x8001c0c0 -void early_delay(int delay) -{ - uint32_t st = readl(HW_DIGCTRL_MICROSECONDS); - st += delay; - while (st > readl(HW_DIGCTRL_MICROSECONDS)) - ; -} - -#define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) -const iomux_cfg_t iomux_boot[] = { - MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, -}; - -uint8_t mx28_get_bootmode_index(void) -{ - uint8_t bootmode = 0; - int i; - uint8_t masked; - - /* Setup IOMUX of bootmode pads to GPIO */ - mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot)); - - /* Setup bootmode pins as GPIO input */ - gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0); - gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1); - gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2); - gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3); - gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4); - gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5); - - /* Read bootmode pads */ - bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; - - for (i = 0; i < ARRAY_SIZE(mx28_boot_modes); i++) { - masked = bootmode & mx28_boot_modes[i].boot_mask; - if (masked == mx28_boot_modes[i].boot_pads) - break; - } - - return i; -} - -void mx28_common_spl_init(const iomux_cfg_t *iomux_setup, - const unsigned int iomux_size) -{ - struct mx28_spl_data *data = (struct mx28_spl_data *) - ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf); - uint8_t bootmode = mx28_get_bootmode_index(); - - mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size); - mx28_power_init(); - - mx28_mem_init(); - data->mem_dram_size = mx28_mem_get_size(); - - data->boot_mode_idx = bootmode; - - mx28_power_wait_pswitch(); -} - -/* Support aparatus */ -inline void board_init_f(unsigned long bootflag) -{ - for (;;) - ; -} - -inline void board_init_r(gd_t *id, ulong dest_addr) -{ - for (;;) - ; -} - -#ifndef CONFIG_SPL_SERIAL_SUPPORT -void serial_putc(const char c) {} -void serial_puts(const char *s) {} -#endif -void hang(void) __attribute__ ((noreturn)); -void hang(void) -{ - for (;;) - ; -} diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c deleted file mode 100644 index 88a603c..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Freescale i.MX28 Battery measurement init - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 <config.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> - -#include "mx28_init.h" - -void mx28_lradc_init(void) -{ - struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE; - - writel(LRADC_CTRL0_SFTRST, ®s->hw_lradc_ctrl0_clr); - writel(LRADC_CTRL0_CLKGATE, ®s->hw_lradc_ctrl0_clr); - writel(LRADC_CTRL0_ONCHIP_GROUNDREF, ®s->hw_lradc_ctrl0_clr); - - clrsetbits_le32(®s->hw_lradc_ctrl3, - LRADC_CTRL3_CYCLE_TIME_MASK, - LRADC_CTRL3_CYCLE_TIME_6MHZ); - - clrsetbits_le32(®s->hw_lradc_ctrl4, - LRADC_CTRL4_LRADC7SELECT_MASK | - LRADC_CTRL4_LRADC6SELECT_MASK, - LRADC_CTRL4_LRADC7SELECT_CHANNEL7 | - LRADC_CTRL4_LRADC6SELECT_CHANNEL10); -} - -void mx28_lradc_enable_batt_measurement(void) -{ - struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE; - - /* Check if the channel is present at all. */ - if (!(readl(®s->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) - return; - - writel(LRADC_CTRL1_LRADC7_IRQ_EN, ®s->hw_lradc_ctrl1_clr); - writel(LRADC_CTRL1_LRADC7_IRQ, ®s->hw_lradc_ctrl1_clr); - - clrsetbits_le32(®s->hw_lradc_conversion, - LRADC_CONVERSION_SCALE_FACTOR_MASK, - LRADC_CONVERSION_SCALE_FACTOR_LI_ION); - writel(LRADC_CONVERSION_AUTOMATIC, ®s->hw_lradc_conversion_set); - - /* Configure the channel. */ - writel((1 << 7) << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, - ®s->hw_lradc_ctrl2_clr); - writel(0xffffffff, ®s->hw_lradc_ch7_clr); - clrbits_le32(®s->hw_lradc_ch7, LRADC_CH_NUM_SAMPLES_MASK); - writel(LRADC_CH_ACCUMULATE, ®s->hw_lradc_ch7_clr); - - /* Schedule the channel. */ - writel(1 << 7, ®s->hw_lradc_ctrl0_set); - - /* Start the channel sampling. */ - writel(((1 << 7) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) | - ((1 << 3) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) | - 100, ®s->hw_lradc_delay3); - - writel(0xffffffff, ®s->hw_lradc_ch7_clr); - - writel(LRADC_DELAY_KICK, ®s->hw_lradc_delay3_set); -} diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c deleted file mode 100644 index cca1316..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Freescale i.MX28 RAM init - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 <config.h> -#include <asm/io.h> -#include <asm/arch/iomux-mx28.h> -#include <asm/arch/imx-regs.h> - -#include "mx28_init.h" - -static uint32_t mx28_dram_vals[] = { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000100, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00010101, 0x01010101, - 0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101, - 0x00000100, 0x00000100, 0x00000000, 0x00000002, - 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8, - 0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612, - 0x02030202, 0x00c8001c, 0x00000000, 0x00000000, - 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, - 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, - 0x00000003, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000612, 0x01000F02, - 0x06120612, 0x00000200, 0x00020007, 0xf5014b27, - 0xf5014b27, 0xf5014b27, 0xf5014b27, 0x07000300, - 0x07000300, 0x07000300, 0x07000300, 0x00000006, - 0x00000000, 0x00000000, 0x01000000, 0x01020408, - 0x08040201, 0x000f1133, 0x00000000, 0x00001f04, - 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, - 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00010000, 0x00020304, - 0x00000004, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x01010000, - 0x01000000, 0x03030000, 0x00010303, 0x01020202, - 0x00000000, 0x02040303, 0x21002103, 0x00061200, - 0x06120612, 0x04320432, 0x04320432, 0x00040004, - 0x00040004, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00010001 -}; - -void __mx28_adjust_memory_params(uint32_t *dram_vals) -{ -} -void mx28_adjust_memory_params(uint32_t *dram_vals) - __attribute__((weak, alias("__mx28_adjust_memory_params"))); - -void init_mx28_200mhz_ddr2(void) -{ - int i; - - mx28_adjust_memory_params(mx28_dram_vals); - - for (i = 0; i < ARRAY_SIZE(mx28_dram_vals); i++) - writel(mx28_dram_vals[i], MXS_DRAM_BASE + (4 * i)); -} - -void mx28_mem_init_clock(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - /* Gate EMI clock */ - writeb(CLKCTRL_FRAC_CLKGATE, - &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]); - - /* Set fractional divider for ref_emi to 480 * 18 / 21 = 411MHz */ - writeb(CLKCTRL_FRAC_CLKGATE | (21 & CLKCTRL_FRAC_FRAC_MASK), - &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]); - - /* Ungate EMI clock */ - writeb(CLKCTRL_FRAC_CLKGATE, - &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]); - - early_delay(11000); - - /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */ - writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) | - (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET), - &clkctrl_regs->hw_clkctrl_emi); - - /* Unbypass EMI */ - writel(CLKCTRL_CLKSEQ_BYPASS_EMI, - &clkctrl_regs->hw_clkctrl_clkseq_clr); - - early_delay(10000); -} - -void mx28_mem_setup_cpu_and_hbus(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz - * and ungate CPU clock */ - writeb(19 & CLKCTRL_FRAC_FRAC_MASK, - (uint8_t *)&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]); - - /* Set CPU bypass */ - writel(CLKCTRL_CLKSEQ_BYPASS_CPU, - &clkctrl_regs->hw_clkctrl_clkseq_set); - - /* HBUS = 151MHz */ - writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set); - writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK, - &clkctrl_regs->hw_clkctrl_hbus_clr); - - early_delay(10000); - - /* CPU clock divider = 1 */ - clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu, - CLKCTRL_CPU_DIV_CPU_MASK, 1); - - /* Disable CPU bypass */ - writel(CLKCTRL_CLKSEQ_BYPASS_CPU, - &clkctrl_regs->hw_clkctrl_clkseq_clr); - - early_delay(15000); -} - -void mx28_mem_setup_vdda(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - writel((0xc << POWER_VDDACTRL_TRG_OFFSET) | - (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) | - POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW, - &power_regs->hw_power_vddactrl); -} - -void mx28_mem_setup_vddd(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - writel((0x1c << POWER_VDDDCTRL_TRG_OFFSET) | - (0x7 << POWER_VDDDCTRL_BO_OFFSET_OFFSET) | - POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW, - &power_regs->hw_power_vdddctrl); -} - -uint32_t mx28_mem_get_size(void) -{ - uint32_t sz, da; - uint32_t *vt = (uint32_t *)0x20; - /* The following is "subs pc, r14, #4", used as return from DABT. */ - const uint32_t data_abort_memdetect_handler = 0xe25ef004; - - /* Replace the DABT handler. */ - da = vt[4]; - vt[4] = data_abort_memdetect_handler; - - sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); - - /* Restore the old DABT handler. */ - vt[4] = da; - - return sz; -} - -void mx28_mem_init(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - struct mx28_pinctrl_regs *pinctrl_regs = - (struct mx28_pinctrl_regs *)MXS_PINCTRL_BASE; - - /* Set DDR2 mode */ - writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2, - &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set); - - /* Power up PLL0 */ - writel(CLKCTRL_PLL0CTRL0_POWER, - &clkctrl_regs->hw_clkctrl_pll0ctrl0_set); - - early_delay(11000); - - mx28_mem_init_clock(); - - mx28_mem_setup_vdda(); - - /* - * Configure the DRAM registers - */ - - /* Clear START bit from DRAM_CTL16 */ - clrbits_le32(MXS_DRAM_BASE + 0x40, 1); - - init_mx28_200mhz_ddr2(); - - /* Clear SREFRESH bit from DRAM_CTL17 */ - clrbits_le32(MXS_DRAM_BASE + 0x44, 1); - - /* Set START bit in DRAM_CTL16 */ - setbits_le32(MXS_DRAM_BASE + 0x40, 1); - - /* Wait for bit 20 (DRAM init complete) in DRAM_CTL58 */ - while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20))) - ; - - mx28_mem_setup_vddd(); - - early_delay(10000); - - mx28_mem_setup_cpu_and_hbus(); -} diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c deleted file mode 100644 index 4b09b0c..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * Freescale i.MX28 Boot PMIC init - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 <config.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> - -#include "mx28_init.h" - -void mx28_power_clock2xtal(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - /* Set XTAL as CPU reference clock */ - writel(CLKCTRL_CLKSEQ_BYPASS_CPU, - &clkctrl_regs->hw_clkctrl_clkseq_set); -} - -void mx28_power_clock2pll(void) -{ - struct mx28_clkctrl_regs *clkctrl_regs = - (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE; - - setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0, - CLKCTRL_PLL0CTRL0_POWER); - early_delay(100); - setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq, - CLKCTRL_CLKSEQ_BYPASS_CPU); -} - -void mx28_power_clear_auto_restart(void) -{ - struct mx28_rtc_regs *rtc_regs = - (struct mx28_rtc_regs *)MXS_RTC_BASE; - - writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr); - while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST) - ; - - writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr); - while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE) - ; - - /* - * Due to the hardware design bug of mx28 EVK-A - * we need to set the AUTO_RESTART bit. - */ - if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART) - return; - - while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) - ; - - setbits_le32(&rtc_regs->hw_rtc_persistent0, - RTC_PERSISTENT0_AUTO_RESTART); - writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set); - writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr); - while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) - ; - while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK) - ; -} - -void mx28_power_set_linreg(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* Set linear regulator 25mV below switching converter */ - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_LINREG_OFFSET_MASK, - POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); - - clrsetbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_LINREG_OFFSET_MASK, - POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW); - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_LINREG_OFFSET_MASK, - POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); -} - -int mx28_get_batt_volt(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t volt = readl(&power_regs->hw_power_battmonitor); - volt &= POWER_BATTMONITOR_BATT_VAL_MASK; - volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET; - volt *= 8; - return volt; -} - -int mx28_is_batt_ready(void) -{ - return (mx28_get_batt_volt() >= 3600); -} - -int mx28_is_batt_good(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t volt = mx28_get_batt_volt(); - - if ((volt >= 2400) && (volt <= 4300)) - return 1; - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); - writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, - &power_regs->hw_power_5vctrl_clr); - - clrsetbits_le32(&power_regs->hw_power_charge, - POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, - POWER_CHARGE_STOP_ILIMIT_10MA | 0x3); - - writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr); - writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, - &power_regs->hw_power_5vctrl_clr); - - early_delay(500000); - - volt = mx28_get_batt_volt(); - - if (volt >= 3500) - return 0; - - if (volt >= 2400) - return 1; - - writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, - &power_regs->hw_power_charge_clr); - writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set); - - return 0; -} - -void mx28_power_setup_5v_detect(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* Start 5V detection */ - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_VBUSVALID_TRSH_MASK, - POWER_5VCTRL_VBUSVALID_TRSH_4V4 | - POWER_5VCTRL_PWRUP_VBUS_CMPS); -} - -void mx28_src_power_init(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* Improve efficieny and reduce transient ripple */ - writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST | - POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set); - - clrsetbits_le32(&power_regs->hw_power_dclimits, - POWER_DCLIMITS_POSLIMIT_BUCK_MASK, - 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET); - - setbits_le32(&power_regs->hw_power_battmonitor, - POWER_BATTMONITOR_EN_BATADJ); - - /* Increase the RCSCALE level for quick DCDC response to dynamic load */ - clrsetbits_le32(&power_regs->hw_power_loopctrl, - POWER_LOOPCTRL_EN_RCSCALE_MASK, - POWER_LOOPCTRL_RCSCALE_THRESH | - POWER_LOOPCTRL_EN_RCSCALE_8X); - - clrsetbits_le32(&power_regs->hw_power_minpwr, - POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); - - /* 5V to battery handoff ... FIXME */ - setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); - early_delay(30); - clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); -} - -void mx28_power_init_4p2_params(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* Setup 4P2 parameters */ - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, - POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_HEADROOM_ADJ_MASK, - 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); - - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_DROPOUT_CTRL_MASK, - POWER_DCDC4P2_DROPOUT_CTRL_100MV | - POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); -} - -void mx28_enable_4p2_dcdc_input(int xfer) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo; - uint32_t prev_5v_brnout, prev_5v_droop; - - prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) & - POWER_5VCTRL_PWDN_5VBRNOUT; - prev_5v_droop = readl(&power_regs->hw_power_ctrl) & - POWER_CTRL_ENIRQ_VDD5V_DROOP; - - clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); - writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, - &power_regs->hw_power_reset); - - clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP); - - if (xfer && (readl(&power_regs->hw_power_5vctrl) & - POWER_5VCTRL_ENABLE_DCDC)) { - return; - } - - /* - * Recording orignal values that will be modified temporarlily - * to handle a chip bug. See chip errata for CQ ENGR00115837 - */ - tmp = readl(&power_regs->hw_power_5vctrl); - vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK; - vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT; - - pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO; - - /* - * Disable mechanisms that get erroneously tripped by when setting - * the DCDC4P2 EN_DCDC - */ - clrbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_VBUSVALID_5VDETECT | - POWER_5VCTRL_VBUSVALID_TRSH_MASK); - - writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set); - - if (xfer) { - setbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_DCDC_XFER); - early_delay(20); - clrbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_DCDC_XFER); - - setbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_ENABLE_DCDC); - } else { - setbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC); - } - - early_delay(25); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh); - - if (vbus_5vdetect) - writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set); - - if (!pwd_bo) - clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO); - - while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) - writel(POWER_CTRL_VBUS_VALID_IRQ, - &power_regs->hw_power_ctrl_clr); - - if (prev_5v_brnout) { - writel(POWER_5VCTRL_PWDN_5VBRNOUT, - &power_regs->hw_power_5vctrl_set); - writel(POWER_RESET_UNLOCK_KEY, - &power_regs->hw_power_reset); - } else { - writel(POWER_5VCTRL_PWDN_5VBRNOUT, - &power_regs->hw_power_5vctrl_clr); - writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, - &power_regs->hw_power_reset); - } - - while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ) - writel(POWER_CTRL_VDD5V_DROOP_IRQ, - &power_regs->hw_power_ctrl_clr); - - if (prev_5v_droop) - clrbits_le32(&power_regs->hw_power_ctrl, - POWER_CTRL_ENIRQ_VDD5V_DROOP); - else - setbits_le32(&power_regs->hw_power_ctrl, - POWER_CTRL_ENIRQ_VDD5V_DROOP); -} - -void mx28_power_init_4p2_regulator(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t tmp, tmp2; - - setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); - - writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set); - - writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - &power_regs->hw_power_5vctrl_clr); - clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK); - - /* Power up the 4p2 rail and logic/control */ - writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, - &power_regs->hw_power_5vctrl_clr); - - /* - * Start charging up the 4p2 capacitor. We ramp of this charge - * gradually to avoid large inrush current from the 5V cable which can - * cause transients/problems - */ - mx28_enable_4p2_dcdc_input(0); - - if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { - /* - * If we arrived here, we were unable to recover from mx23 chip - * errata 5837. 4P2 is disabled and sufficient battery power is - * not present. Exiting to not enable DCDC power during 5V - * connected state. - */ - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC); - writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, - &power_regs->hw_power_5vctrl_set); - hang(); - } - - /* - * Here we set the 4p2 brownout level to something very close to 4.2V. - * We then check the brownout status. If the brownout status is false, - * the voltage is already close to the target voltage of 4.2V so we - * can go ahead and set the 4P2 current limit to our max target limit. - * If the brownout status is true, we need to ramp us the current limit - * so that we don't cause large inrush current issues. We step up the - * current limit until the brownout status is false or until we've - * reached our maximum defined 4p2 current limit. - */ - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_BO_MASK, - 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */ - - if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) { - setbits_le32(&power_regs->hw_power_5vctrl, - 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); - } else { - tmp = (readl(&power_regs->hw_power_5vctrl) & - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >> - POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; - while (tmp < 0x3f) { - if (!(readl(&power_regs->hw_power_sts) & - POWER_STS_DCDC_4P2_BO)) { - tmp = readl(&power_regs->hw_power_5vctrl); - tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; - early_delay(100); - writel(tmp, &power_regs->hw_power_5vctrl); - break; - } else { - tmp++; - tmp2 = readl(&power_regs->hw_power_5vctrl); - tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; - tmp2 |= tmp << - POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; - writel(tmp2, &power_regs->hw_power_5vctrl); - early_delay(100); - } - } - } - - clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); - writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); -} - -void mx28_power_init_dcdc_4p2_source(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - if (!(readl(&power_regs->hw_power_dcdc4p2) & - POWER_DCDC4P2_ENABLE_DCDC)) { - hang(); - } - - mx28_enable_4p2_dcdc_input(1); - - if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC); - writel(POWER_5VCTRL_ENABLE_DCDC, - &power_regs->hw_power_5vctrl_clr); - writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, - &power_regs->hw_power_5vctrl_set); - } -} - -void mx28_power_enable_4p2(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t vdddctrl, vddactrl, vddioctrl; - uint32_t tmp; - - vdddctrl = readl(&power_regs->hw_power_vdddctrl); - vddactrl = readl(&power_regs->hw_power_vddactrl); - vddioctrl = readl(&power_regs->hw_power_vddioctrl); - - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | - POWER_VDDDCTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | - POWER_VDDACTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); - - mx28_power_init_4p2_params(); - mx28_power_init_4p2_regulator(); - - /* Shutdown battery (none present) */ - if (!mx28_is_batt_ready()) { - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_BO_MASK); - writel(POWER_CTRL_DCDC4P2_BO_IRQ, - &power_regs->hw_power_ctrl_clr); - writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, - &power_regs->hw_power_ctrl_clr); - } - - mx28_power_init_dcdc_4p2_source(); - - writel(vdddctrl, &power_regs->hw_power_vdddctrl); - early_delay(20); - writel(vddactrl, &power_regs->hw_power_vddactrl); - early_delay(20); - writel(vddioctrl, &power_regs->hw_power_vddioctrl); - - /* - * Check if FET is enabled on either powerout and if so, - * disable load. - */ - tmp = 0; - tmp |= !(readl(&power_regs->hw_power_vdddctrl) & - POWER_VDDDCTRL_DISABLE_FET); - tmp |= !(readl(&power_regs->hw_power_vddactrl) & - POWER_VDDACTRL_DISABLE_FET); - tmp |= !(readl(&power_regs->hw_power_vddioctrl) & - POWER_VDDIOCTRL_DISABLE_FET); - if (tmp) - writel(POWER_CHARGE_ENABLE_LOAD, - &power_regs->hw_power_charge_clr); -} - -void mx28_boot_valid_5v(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* - * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V - * disconnect event. FIXME - */ - writel(POWER_5VCTRL_VBUSVALID_5VDETECT, - &power_regs->hw_power_5vctrl_set); - - /* Configure polarity to check for 5V disconnection. */ - writel(POWER_CTRL_POLARITY_VBUSVALID | - POWER_CTRL_POLARITY_VDD5V_GT_VDDIO, - &power_regs->hw_power_ctrl_clr); - - writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ, - &power_regs->hw_power_ctrl_clr); - - mx28_power_enable_4p2(); -} - -void mx28_powerdown(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset); - writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, - &power_regs->hw_power_reset); -} - -void mx28_batt_boot(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); - clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC); - - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2); - writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr); - - /* 5V to battery handoff. */ - setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); - early_delay(30); - clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); - - writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr); - - clrsetbits_le32(&power_regs->hw_power_minpwr, - POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); - - mx28_power_set_linreg(); - - clrbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG); - - clrbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG); - - clrbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_DISABLE_FET); - - setbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_PWD_CHARGE_4P2_MASK); - - setbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_ENABLE_DCDC); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); -} - -void mx28_handle_5v_conflict(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t tmp; - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_BO_OFFSET_MASK); - - for (;;) { - tmp = readl(&power_regs->hw_power_sts); - - if (tmp & POWER_STS_VDDIO_BO) { - mx28_powerdown(); - break; - } - - if (tmp & POWER_STS_VDD5V_GT_VDDIO) { - mx28_boot_valid_5v(); - break; - } else { - mx28_powerdown(); - break; - } - - if (tmp & POWER_STS_PSWITCH_MASK) { - mx28_batt_boot(); - break; - } - } -} - -void mx28_5v_boot(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* - * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID, - * but their implementation always returns 1 so we omit it here. - */ - if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { - mx28_boot_valid_5v(); - return; - } - - early_delay(1000); - if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { - mx28_boot_valid_5v(); - return; - } - - mx28_handle_5v_conflict(); -} - -void mx28_init_batt_bo(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - /* Brownout at 3V */ - clrsetbits_le32(&power_regs->hw_power_battmonitor, - POWER_BATTMONITOR_BRWNOUT_LVL_MASK, - 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET); - - writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr); - writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr); -} - -void mx28_switch_vddd_to_dcdc_source(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_LINREG_OFFSET_MASK, - POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); - - clrbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | - POWER_VDDDCTRL_DISABLE_STEPPING); -} - -void mx28_power_configure_power_source(void) -{ - int batt_ready, batt_good; - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - struct mx28_lradc_regs *lradc_regs = - (struct mx28_lradc_regs *)MXS_LRADC_BASE; - - mx28_src_power_init(); - - batt_ready = mx28_is_batt_ready(); - - if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { - batt_good = mx28_is_batt_good(); - if (batt_ready) { - /* 5V source detected, good battery detected. */ - mx28_batt_boot(); - } else { - if (batt_good) { - /* 5V source detected, low battery detceted. */ - } else { - /* 5V source detected, bad battery detected. */ - writel(LRADC_CONVERSION_AUTOMATIC, - &lradc_regs->hw_lradc_conversion_clr); - clrbits_le32(&power_regs->hw_power_battmonitor, - POWER_BATTMONITOR_BATT_VAL_MASK); - } - mx28_5v_boot(); - } - } else { - /* 5V not detected, booting from battery. */ - mx28_batt_boot(); - } - - mx28_power_clock2pll(); - - mx28_init_batt_bo(); - - mx28_switch_vddd_to_dcdc_source(); -} - -void mx28_enable_output_rail_protection(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | - POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr); - - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_PWDN_BRNOUT); -} - -int mx28_get_vddio_power_source_off(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t tmp; - - if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { - tmp = readl(&power_regs->hw_power_vddioctrl); - if (tmp & POWER_VDDIOCTRL_DISABLE_FET) { - if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == - POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { - return 1; - } - } - - if (!(readl(&power_regs->hw_power_5vctrl) & - POWER_5VCTRL_ENABLE_DCDC)) { - if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == - POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { - return 1; - } - } - } - - return 0; - -} - -int mx28_get_vddd_power_source_off(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t tmp; - - tmp = readl(&power_regs->hw_power_vdddctrl); - if (tmp & POWER_VDDDCTRL_DISABLE_FET) { - if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == - POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { - return 1; - } - } - - if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { - if (!(readl(&power_regs->hw_power_5vctrl) & - POWER_5VCTRL_ENABLE_DCDC)) { - return 1; - } - } - - if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) { - if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == - POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) { - return 1; - } - } - - return 0; -} - -void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t cur_target, diff, bo_int = 0; - uint32_t powered_by_linreg = 0; - - new_brownout = new_target - new_brownout; - - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ - - powered_by_linreg = mx28_get_vddio_power_source_off(); - if (new_target > cur_target) { - - if (powered_by_linreg) { - bo_int = readl(&power_regs->hw_power_vddioctrl); - clrbits_le32(&power_regs->hw_power_vddioctrl, - POWER_CTRL_ENIRQ_VDDIO_BO); - } - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_BO_OFFSET_MASK); - do { - if (new_target - cur_target > 100) - diff = cur_target + 100; - else - diff = new_target; - - diff -= 2800; - diff /= 50; - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_TRG_MASK, diff); - - if (powered_by_linreg || - (readl(&power_regs->hw_power_sts) & - POWER_STS_VDD5V_GT_VDDIO)) - early_delay(500); - else { - while (!(readl(&power_regs->hw_power_sts) & - POWER_STS_DC_OK)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ - } while (new_target > cur_target); - - if (powered_by_linreg) { - writel(POWER_CTRL_VDDIO_BO_IRQ, - &power_regs->hw_power_ctrl_clr); - if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO) - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_CTRL_ENIRQ_VDDIO_BO); - } - } else { - do { - if (cur_target - new_target > 100) - diff = cur_target - 100; - else - diff = new_target; - - diff -= 2800; - diff /= 50; - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_TRG_MASK, diff); - - if (powered_by_linreg || - (readl(&power_regs->hw_power_sts) & - POWER_STS_VDD5V_GT_VDDIO)) - early_delay(500); - else { - while (!(readl(&power_regs->hw_power_sts) & - POWER_STS_DC_OK)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vddioctrl); - cur_target &= POWER_VDDIOCTRL_TRG_MASK; - cur_target *= 50; /* 50 mV step*/ - cur_target += 2800; /* 2800 mV lowest */ - } while (new_target < cur_target); - } - - clrsetbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDDCTRL_BO_OFFSET_MASK, - new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET); -} - -void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - uint32_t cur_target, diff, bo_int = 0; - uint32_t powered_by_linreg = 0; - - new_brownout = new_target - new_brownout; - - cur_target = readl(&power_regs->hw_power_vdddctrl); - cur_target &= POWER_VDDDCTRL_TRG_MASK; - cur_target *= 25; /* 25 mV step*/ - cur_target += 800; /* 800 mV lowest */ - - powered_by_linreg = mx28_get_vddd_power_source_off(); - if (new_target > cur_target) { - if (powered_by_linreg) { - bo_int = readl(&power_regs->hw_power_vdddctrl); - clrbits_le32(&power_regs->hw_power_vdddctrl, - POWER_CTRL_ENIRQ_VDDD_BO); - } - - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_BO_OFFSET_MASK); - - do { - if (new_target - cur_target > 100) - diff = cur_target + 100; - else - diff = new_target; - - diff -= 800; - diff /= 25; - - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_TRG_MASK, diff); - - if (powered_by_linreg || - (readl(&power_regs->hw_power_sts) & - POWER_STS_VDD5V_GT_VDDIO)) - early_delay(500); - else { - while (!(readl(&power_regs->hw_power_sts) & - POWER_STS_DC_OK)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vdddctrl); - cur_target &= POWER_VDDDCTRL_TRG_MASK; - cur_target *= 25; /* 25 mV step*/ - cur_target += 800; /* 800 mV lowest */ - } while (new_target > cur_target); - - if (powered_by_linreg) { - writel(POWER_CTRL_VDDD_BO_IRQ, - &power_regs->hw_power_ctrl_clr); - if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO) - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_CTRL_ENIRQ_VDDD_BO); - } - } else { - do { - if (cur_target - new_target > 100) - diff = cur_target - 100; - else - diff = new_target; - - diff -= 800; - diff /= 25; - - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_TRG_MASK, diff); - - if (powered_by_linreg || - (readl(&power_regs->hw_power_sts) & - POWER_STS_VDD5V_GT_VDDIO)) - early_delay(500); - else { - while (!(readl(&power_regs->hw_power_sts) & - POWER_STS_DC_OK)) - ; - - } - - cur_target = readl(&power_regs->hw_power_vdddctrl); - cur_target &= POWER_VDDDCTRL_TRG_MASK; - cur_target *= 25; /* 25 mV step*/ - cur_target += 800; /* 800 mV lowest */ - } while (new_target < cur_target); - } - - clrsetbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_BO_OFFSET_MASK, - new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET); -} - -void mx28_setup_batt_detect(void) -{ - mx28_lradc_init(); - mx28_lradc_enable_batt_measurement(); - early_delay(10); -} - -void mx28_power_init(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - mx28_power_clock2xtal(); - mx28_power_clear_auto_restart(); - mx28_power_set_linreg(); - mx28_power_setup_5v_detect(); - - mx28_setup_batt_detect(); - - mx28_power_configure_power_source(); - mx28_enable_output_rail_protection(); - - mx28_power_set_vddio(3300, 3150); - - mx28_power_set_vddd(1350, 1200); - - writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | - POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | - POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ | - POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); - - writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); - - early_delay(1000); -} - -#ifdef CONFIG_SPL_MX28_PSWITCH_WAIT -void mx28_power_wait_pswitch(void) -{ - struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE; - - while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK)) - ; -} -#endif diff --git a/arch/arm/cpu/arm926ejs/mx28/start.S b/arch/arm/cpu/arm926ejs/mx28/start.S deleted file mode 100644 index e572b78..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/start.S +++ /dev/null @@ -1,247 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Groger <mag@sysgo.de> - * Copyright (c) 2002 Alex Zupke <azu@sysgo.de> - * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> - * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> - * Copyright (c) 2003 Kshitij <kshitij@ti.com> - * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> - * - * Change to support call back into iMX28 bootrom - * Copyright (c) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * 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 <asm-offsets.h> -#include <config.h> -#include <common.h> -#include <version.h> - -/* - ************************************************************************* - * - * Jump vector table as in table 3.1 in [1] - * - ************************************************************************* - */ - - -.globl _start -_start: - b reset - b undefined_instruction - b software_interrupt - b prefetch_abort - b data_abort - b not_used - b irq - b fiq - -/* - * Vector table, located at address 0x20. - * This table allows the code running AFTER SPL, the U-Boot, to install it's - * interrupt handlers here. The problem is that the U-Boot is loaded into RAM, - * including it's interrupt vectoring table and the table at 0x0 is still the - * SPLs. So if interrupt happens in U-Boot, the SPLs interrupt vectoring table - * is still used. - */ -_vt_reset: - .word _reset -_vt_undefined_instruction: - .word _hang -_vt_software_interrupt: - .word _hang -_vt_prefetch_abort: - .word _hang -_vt_data_abort: - .word _hang -_vt_not_used: - .word _reset -_vt_irq: - .word _hang -_vt_fiq: - .word _hang - -reset: - ldr pc, _vt_reset -undefined_instruction: - ldr pc, _vt_undefined_instruction -software_interrupt: - ldr pc, _vt_software_interrupt -prefetch_abort: - ldr pc, _vt_prefetch_abort -data_abort: - ldr pc, _vt_data_abort -not_used: - ldr pc, _vt_not_used -irq: - ldr pc, _vt_irq -fiq: - ldr pc, _vt_fiq - - .balignl 16,0xdeadbeef - -/* - ************************************************************************* - * - * Startup Code (reset vector) - * - * do important init only if we don't start from memory! - * setup Memory and board specific bits prior to relocation. - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -.globl _TEXT_BASE -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE - -/* - * These are defined in the board-specific linker script. - * Subtracting _start from them lets the linker put their - * relative position in the executable instead of leaving - * them null. - */ -.globl _bss_start_ofs -_bss_start_ofs: - .word __bss_start - _start - -.globl _bss_end_ofs -_bss_end_ofs: - .word __bss_end__ - _start - -.globl _end_ofs -_end_ofs: - .word _end - _start - -#ifdef CONFIG_USE_IRQ -/* IRQ stack memory (calculated at run-time) */ -.globl IRQ_STACK_START -IRQ_STACK_START: - .word 0x0badc0de - -/* IRQ stack memory (calculated at run-time) */ -.globl FIQ_STACK_START -FIQ_STACK_START: - .word 0x0badc0de -#endif - -/* IRQ stack memory (calculated at run-time) + 8 bytes */ -.globl IRQ_STACK_START_IN -IRQ_STACK_START_IN: - .word 0x0badc0de - -/* - * the actual reset code - */ - -_reset: - /* - * Store all registers on old stack pointer, this will allow us later to - * return to the BootROM and let the BootROM load U-Boot into RAM. - */ - push {r0-r12,r14} - - /* save control register c1 */ - mrc p15, 0, r0, c1, c0, 0 - push {r0} - - /* - * set the cpu to SVC32 mode and store old CPSR register content - */ - mrs r0,cpsr - push {r0} - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* - * we do sys-critical inits only at reboot, - * not when booting from ram! - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - bl cpu_init_crit -#endif - - bl board_init_ll - - /* - * restore bootrom's cpu mode (especially FIQ) - */ - pop {r0} - msr cpsr,r0 - - /* - * restore c1 register - * (especially set exception vector location back to - * bootrom space which is required by bootrom for USB boot) - */ - pop {r0} - mcr p15, 0, r0, c1, c0, 0 - - pop {r0-r12,r14} - bx lr - -/* - ************************************************************************* - * - * CPU_init_critical registers - * - * setup important registers - * setup memory timing - * - ************************************************************************* - */ -#ifndef CONFIG_SKIP_LOWLEVEL_INIT -cpu_init_crit: - /* - * flush v4 I/D caches - */ - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ - bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ - orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ - orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ - mcr p15, 0, r0, c1, c0, 0 - - mov pc, lr /* back to my caller */ - - .align 5 -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ - -_hang: - ldr sp, _TEXT_BASE /* switch to abort stack */ -1: - bl 1b /* hang and never return */ diff --git a/arch/arm/cpu/arm926ejs/mx28/timer.c b/arch/arm/cpu/arm926ejs/mx28/timer.c deleted file mode 100644 index 5b73f4a..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/timer.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Freescale i.MX28 timer driver - * - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * Based on code from LTIB: - * (C) Copyright 2009-2010 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/sys_proto.h> - -/* Maximum fixed count */ -#define TIMER_LOAD_VAL 0xffffffff - -DECLARE_GLOBAL_DATA_PTR; - -#define timestamp (gd->tbl) -#define lastdec (gd->lastinc) - -/* - * This driver uses 1kHz clock source. - */ -#define MX28_INCREMENTER_HZ 1000 - -static inline unsigned long tick_to_time(unsigned long tick) -{ - return tick / (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ); -} - -static inline unsigned long time_to_tick(unsigned long time) -{ - return time * (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ); -} - -/* Calculate how many ticks happen in "us" microseconds */ -static inline unsigned long us_to_tick(unsigned long us) -{ - return (us * MX28_INCREMENTER_HZ) / 1000000; -} - -int timer_init(void) -{ - struct mx28_timrot_regs *timrot_regs = - (struct mx28_timrot_regs *)MXS_TIMROT_BASE; - - /* Reset Timers and Rotary Encoder module */ - mx28_reset_block(&timrot_regs->hw_timrot_rotctrl_reg); - - /* Set fixed_count to 0 */ - writel(0, &timrot_regs->hw_timrot_fixed_count0); - - /* Set UPDATE bit and 1Khz frequency */ - writel(TIMROT_TIMCTRLn_UPDATE | TIMROT_TIMCTRLn_RELOAD | - TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL, - &timrot_regs->hw_timrot_timctrl0); - - /* Set fixed_count to maximal value */ - writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0); - - return 0; -} - -unsigned long long get_ticks(void) -{ - struct mx28_timrot_regs *timrot_regs = - (struct mx28_timrot_regs *)MXS_TIMROT_BASE; - - /* Current tick value */ - uint32_t now = readl(&timrot_regs->hw_timrot_running_count0); - - if (lastdec >= now) { - /* - * normal mode (non roll) - * move stamp forward with absolut diff ticks - */ - timestamp += (lastdec - now); - } else { - /* we have rollover of decrementer */ - timestamp += (TIMER_LOAD_VAL - now) + lastdec; - - } - lastdec = now; - - return timestamp; -} - -ulong get_timer_masked(void) -{ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */ -#define MX28_HW_DIGCTL_MICROSECONDS 0x8001c0c0 - -void __udelay(unsigned long usec) -{ - uint32_t old, new, incr; - uint32_t counter = 0; - - old = readl(MX28_HW_DIGCTL_MICROSECONDS); - - while (counter < usec) { - new = readl(MX28_HW_DIGCTL_MICROSECONDS); - - /* Check if the timer wrapped. */ - if (new < old) { - incr = 0xffffffff - old; - incr += new; - } else { - incr = new - old; - } - - /* - * Check if we are close to the maximum time and the counter - * would wrap if incremented. If that's the case, break out - * from the loop as the requested delay time passed. - */ - if (counter + incr < counter) - break; - - counter += incr; - old = new; - } -} - -ulong get_tbclk(void) -{ - return MX28_INCREMENTER_HZ; -} diff --git a/arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds deleted file mode 100644 index 0fccd52..0000000 --- a/arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> - * on behalf of DENX Software Engineering GmbH - * - * January 2004 - Changed to support H4 device - * Copyright (c) 2004-2008 Texas Instruments - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, <garyj@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 - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - arch/arm/cpu/arm926ejs/mx28/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { - *(.data) - } - - . = ALIGN(4); - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - - .rel.dyn : { - __rel_dyn_start = .; - *(.rel*) - __rel_dyn_end = .; - } - - .dynsym : { - __dynsym_start = .; - *(.dynsym) - } - - .bss : { - . = ALIGN(4); - __bss_start = .; - *(.bss*) - . = ALIGN(4); - __bss_end__ = .; - } - - _end = .; - - /DISCARD/ : { *(.dynstr*) } - /DISCARD/ : { *(.dynsym*) } - /DISCARD/ : { *(.dynamic*) } - /DISCARD/ : { *(.hash*) } - /DISCARD/ : { *(.plt*) } - /DISCARD/ : { *(.interp*) } - /DISCARD/ : { *(.gnu*) } -} |