From ea00e59be08989dae905076f4acf3eb297fce552 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 5 Sep 2012 20:16:36 +0000 Subject: MX: set a common place to share code for Freescale i.MX Up now only MX5 and MX6 can share code, because they have a common source directory in cpu/armv7. Other not armv7 i.MX can profit of the same shared code. Move these files into a directory accessible for all, similar to plat-mxc in linux. Signed-off-by: Stefano Babic --- arch/arm/cpu/armv7/imx-common/Makefile | 50 ---------- arch/arm/cpu/armv7/imx-common/cmd_bmode.c | 119 ------------------------ arch/arm/cpu/armv7/imx-common/cpu.c | 140 ---------------------------- arch/arm/cpu/armv7/imx-common/i2c.c | 99 -------------------- arch/arm/cpu/armv7/imx-common/iomux-v3.c | 70 -------------- arch/arm/cpu/armv7/imx-common/speed.c | 45 --------- arch/arm/cpu/armv7/imx-common/timer.c | 149 ------------------------------ arch/arm/imx-common/Makefile | 52 +++++++++++ arch/arm/imx-common/cmd_bmode.c | 119 ++++++++++++++++++++++++ arch/arm/imx-common/cpu.c | 140 ++++++++++++++++++++++++++++ arch/arm/imx-common/i2c-mxv7.c | 99 ++++++++++++++++++++ arch/arm/imx-common/iomux-v3.c | 70 ++++++++++++++ arch/arm/imx-common/speed.c | 45 +++++++++ arch/arm/imx-common/timer.c | 149 ++++++++++++++++++++++++++++++ 14 files changed, 674 insertions(+), 672 deletions(-) delete mode 100644 arch/arm/cpu/armv7/imx-common/Makefile delete mode 100644 arch/arm/cpu/armv7/imx-common/cmd_bmode.c delete mode 100644 arch/arm/cpu/armv7/imx-common/cpu.c delete mode 100644 arch/arm/cpu/armv7/imx-common/i2c.c delete mode 100644 arch/arm/cpu/armv7/imx-common/iomux-v3.c delete mode 100644 arch/arm/cpu/armv7/imx-common/speed.c delete mode 100644 arch/arm/cpu/armv7/imx-common/timer.c create mode 100644 arch/arm/imx-common/Makefile create mode 100644 arch/arm/imx-common/cmd_bmode.c create mode 100644 arch/arm/imx-common/cpu.c create mode 100644 arch/arm/imx-common/i2c-mxv7.c create mode 100644 arch/arm/imx-common/iomux-v3.c create mode 100644 arch/arm/imx-common/speed.c create mode 100644 arch/arm/imx-common/timer.c (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile deleted file mode 100644 index 16fba8da93..0000000000 --- a/arch/arm/cpu/armv7/imx-common/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2011 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 $(TOPDIR)/config.mk - -LIB = $(obj)libimx-common.o - -COBJS-y = iomux-v3.o timer.o cpu.o speed.o -COBJS-$(CONFIG_I2C_MXC) += i2c.o -COBJS-$(CONFIG_CMD_BMODE) += cmd_bmode.o -COBJS := $(sort $(COBJS-y)) - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) - -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/armv7/imx-common/cmd_bmode.c b/arch/arm/cpu/armv7/imx-common/cmd_bmode.c deleted file mode 100644 index 02fe72ed7f..0000000000 --- a/arch/arm/cpu/armv7/imx-common/cmd_bmode.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2012 Boundary Devices 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 -#include -#include -#include -#include - -static const struct boot_mode *modes[2]; - -static const struct boot_mode *search_modes(char *arg) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(modes); i++) { - const struct boot_mode *p = modes[i]; - if (p) { - while (p->name) { - if (!strcmp(p->name, arg)) - return p; - p++; - } - } - } - return NULL; -} - -static int create_usage(char *dest) -{ - int i; - int size = 0; - - for (i = 0; i < ARRAY_SIZE(modes); i++) { - const struct boot_mode *p = modes[i]; - if (p) { - while (p->name) { - int len = strlen(p->name); - if (dest) { - memcpy(dest, p->name, len); - dest += len; - *dest++ = '|'; - } - size += len + 1; - p++; - } - } - } - if (dest) - memcpy(dest - 1, " [noreset]", 11); /* include trailing 0 */ - size += 10; - return size; -} - -static int do_boot_mode(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - const struct boot_mode *p; - int reset_requested = 1; - - if (argc < 2) - return CMD_RET_USAGE; - p = search_modes(argv[1]); - if (!p) - return CMD_RET_USAGE; - if (argc == 3) { - if (strcmp(argv[2], "noreset")) - return CMD_RET_USAGE; - reset_requested = 0; - } - - boot_mode_apply(p->cfg_val); - if (reset_requested && p->cfg_val) - do_reset(NULL, 0, 0, NULL); - return 0; -} - -U_BOOT_CMD( - bmode, 3, 0, do_boot_mode, - NULL, - ""); - -void add_board_boot_modes(const struct boot_mode *p) -{ - int size; - char *dest; - - if (__u_boot_cmd_bmode.usage) { - free(__u_boot_cmd_bmode.usage); - __u_boot_cmd_bmode.usage = NULL; - } - - modes[0] = p; - modes[1] = soc_boot_modes; - size = create_usage(NULL); - dest = malloc(size); - if (dest) { - create_usage(dest); - __u_boot_cmd_bmode.usage = dest; - } -} diff --git a/arch/arm/cpu/armv7/imx-common/cpu.c b/arch/arm/cpu/armv7/imx-common/cpu.c deleted file mode 100644 index fa1d468041..0000000000 --- a/arch/arm/cpu/armv7/imx-common/cpu.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 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 -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_FSL_ESDHC -#include -#endif - -char *get_reset_cause(void) -{ - u32 cause; - struct src *src_regs = (struct src *)SRC_BASE_ADDR; - - cause = readl(&src_regs->srsr); - writel(cause, &src_regs->srsr); - - switch (cause) { - case 0x00001: - case 0x00011: - return "POR"; - case 0x00004: - return "CSU"; - case 0x00008: - return "IPP USER"; - case 0x00010: - return "WDOG"; - case 0x00020: - return "JTAG HIGH-Z"; - case 0x00040: - return "JTAG SW"; - case 0x10000: - return "WARM BOOT"; - default: - return "unknown reset"; - } -} - -#if defined(CONFIG_DISPLAY_CPUINFO) - -static const char *get_imx_type(u32 imxtype) -{ - switch (imxtype) { - case 0x63: - return "6Q"; /* Quad-core version of the mx6 */ - case 0x61: - return "6DS"; /* Dual/Solo version of the mx6 */ - case 0x60: - return "6SL"; /* Solo-Lite version of the mx6 */ - case 0x51: - return "51"; - case 0x53: - return "53"; - default: - return "??"; - } -} - -int print_cpuinfo(void) -{ - u32 cpurev; - - cpurev = get_cpu_rev(); - - printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", - get_imx_type((cpurev & 0xFF000) >> 12), - (cpurev & 0x000F0) >> 4, - (cpurev & 0x0000F) >> 0, - mxc_get_clock(MXC_ARM_CLK) / 1000000); - printf("Reset cause: %s\n", get_reset_cause()); - return 0; -} -#endif - -int cpu_eth_init(bd_t *bis) -{ - int rc = -ENODEV; - -#if defined(CONFIG_FEC_MXC) - rc = fecmxc_initialize(bis); -#endif - - return rc; -} - -#ifdef CONFIG_FSL_ESDHC -/* - * Initializes on-chip MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init(bd_t *bis) -{ - return fsl_esdhc_mmc_init(bis); -} -#endif - -void reset_cpu(ulong addr) -{ - __raw_writew(4, WDOG1_BASE_ADDR); -} - -u32 get_ahb_clk(void) -{ - struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg, ahb_podf; - - reg = __raw_readl(&imx_ccm->cbcdr); - reg &= MXC_CCM_CBCDR_AHB_PODF_MASK; - ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET; - - return get_periph_clk() / (ahb_podf + 1); -} diff --git a/arch/arm/cpu/armv7/imx-common/i2c.c b/arch/arm/cpu/armv7/imx-common/i2c.c deleted file mode 100644 index da2b26f43f..0000000000 --- a/arch/arm/cpu/armv7/imx-common/i2c.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2012 Boundary Devices 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 -#include -#include -#include -#include -#include -#include - -static int force_idle_bus(void *priv) -{ - int i; - int sda, scl; - ulong elapsed, start_time; - struct i2c_pads_info *p = (struct i2c_pads_info *)priv; - int ret = 0; - - gpio_direction_input(p->sda.gp); - gpio_direction_input(p->scl.gp); - - imx_iomux_v3_setup_pad(p->sda.gpio_mode); - imx_iomux_v3_setup_pad(p->scl.gpio_mode); - - sda = gpio_get_value(p->sda.gp); - scl = gpio_get_value(p->scl.gp); - if ((sda & scl) == 1) - goto exit; /* Bus is idle already */ - - printf("%s: sda=%d scl=%d sda.gp=0x%x scl.gp=0x%x\n", __func__, - sda, scl, p->sda.gp, p->scl.gp); - /* Send high and low on the SCL line */ - for (i = 0; i < 9; i++) { - gpio_direction_output(p->scl.gp, 0); - udelay(50); - gpio_direction_input(p->scl.gp); - udelay(50); - } - start_time = get_timer(0); - for (;;) { - sda = gpio_get_value(p->sda.gp); - scl = gpio_get_value(p->scl.gp); - if ((sda & scl) == 1) - break; - WATCHDOG_RESET(); - elapsed = get_timer(start_time); - if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ - ret = -EBUSY; - printf("%s: failed to clear bus, sda=%d scl=%d\n", - __func__, sda, scl); - break; - } - } -exit: - imx_iomux_v3_setup_pad(p->sda.i2c_mode); - imx_iomux_v3_setup_pad(p->scl.i2c_mode); - return ret; -} - -static void * const i2c_bases[] = { - (void *)I2C1_BASE_ADDR, - (void *)I2C2_BASE_ADDR, -#ifdef I2C3_BASE_ADDR - (void *)I2C3_BASE_ADDR, -#endif -}; - -/* i2c_index can be from 0 - 2 */ -void setup_i2c(unsigned i2c_index, int speed, int slave_addr, - struct i2c_pads_info *p) -{ - if (i2c_index >= ARRAY_SIZE(i2c_bases)) - return; - /* Enable i2c clock */ - enable_i2c_clk(1, i2c_index); - /* Make sure bus is idle */ - force_idle_bus(p); - bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, - force_idle_bus, p); -} diff --git a/arch/arm/cpu/armv7/imx-common/iomux-v3.c b/arch/arm/cpu/armv7/imx-common/iomux-v3.c deleted file mode 100644 index da093fbe14..0000000000 --- a/arch/arm/cpu/armv7/imx-common/iomux-v3.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Based on the iomux-v3.c from Linux kernel: - * Copyright (C) 2008 by Sascha Hauer - * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, - * - * - * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include -#include -#include -#include - -static void *base = (void *)IOMUXC_BASE_ADDR; - -/* - * configures a single pad in the iomuxer - */ -int imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad) -{ - u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT; - u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT; - u32 sel_input_ofs = - (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT; - u32 sel_input = - (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT; - u32 pad_ctrl_ofs = - (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT; - u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; - - if (mux_ctrl_ofs) - __raw_writel(mux_mode, base + mux_ctrl_ofs); - - if (sel_input_ofs) - __raw_writel(sel_input, base + sel_input_ofs); - - if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - __raw_writel(pad_ctrl, base + pad_ctrl_ofs); - - return 0; -} - -int imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count) -{ - iomux_v3_cfg_t *p = pad_list; - int i; - int ret; - - for (i = 0; i < count; i++) { - ret = imx_iomux_v3_setup_pad(*p); - if (ret) - return ret; - p++; - } - return 0; -} diff --git a/arch/arm/cpu/armv7/imx-common/speed.c b/arch/arm/cpu/armv7/imx-common/speed.c deleted file mode 100644 index 80989c4983..0000000000 --- a/arch/arm/cpu/armv7/imx-common/speed.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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 -#include -#include - -#ifdef CONFIG_FSL_ESDHC -DECLARE_GLOBAL_DATA_PTR; -#endif - -int get_clocks(void) -{ -#ifdef CONFIG_FSL_ESDHC -#ifdef CONFIG_FSL_USDHC - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); -#else - gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); -#endif -#endif - return 0; -} diff --git a/arch/arm/cpu/armv7/imx-common/timer.c b/arch/arm/cpu/armv7/imx-common/timer.c deleted file mode 100644 index e2725e1a64..0000000000 --- a/arch/arm/cpu/armv7/imx-common/timer.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 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 -#include -#include -#include - -/* General purpose timers registers */ -struct mxc_gpt { - unsigned int control; - unsigned int prescaler; - unsigned int status; - unsigned int nouse[6]; - unsigned int counter; -}; - -static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; - -/* General purpose timers bitfields */ -#define GPTCR_SWR (1 << 15) /* Software reset */ -#define GPTCR_FRR (1 << 9) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ -#define GPTCR_TEN 1 /* Timer enable */ -#define CLK_32KHZ 32768 /* 32Khz input */ - -DECLARE_GLOBAL_DATA_PTR; - -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, CLK_32KHZ); - - return tick; -} - -static inline unsigned long long us_to_tick(unsigned long long usec) -{ - usec = usec * CLK_32KHZ + 999999; - do_div(usec, 1000000); - - return usec; -} - -int timer_init(void) -{ - int i; - ulong val; - - /* setup GP Timer 1 */ - __raw_writel(GPTCR_SWR, &cur_gpt->control); - - /* We have no udelay by now */ - for (i = 0; i < 100; i++) - __raw_writel(0, &cur_gpt->control); - - __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ - - /* Freerun Mode, PERCLK1 input */ - i = __raw_readl(&cur_gpt->control); - __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); - - val = __raw_readl(&cur_gpt->counter); - lastinc = val / (CLK_32KHZ / CONFIG_SYS_HZ); - timestamp = 0; - - return 0; -} - -unsigned long long get_ticks(void) -{ - ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */ - - if (now >= lastinc) { - /* - * normal mode (non roll) - * move stamp forward with absolut diff ticks - */ - timestamp += (now - lastinc); - } else { - /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - } - lastinc = now; - return timestamp; -} - -ulong get_timer_masked(void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds AND preserve advance timstamp value */ -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CLK_32KHZ; -} diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile new file mode 100644 index 0000000000..b3e608e9db --- /dev/null +++ b/arch/arm/imx-common/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2011 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 $(TOPDIR)/config.mk + +LIB = $(obj)libimx-common.o + +ifeq ($(SOC),$(filter $(SOC),mx5 mx6)) +COBJS-y = iomux-v3.o timer.o cpu.o speed.o +COBJS-$(CONFIG_I2C_MXC) += i2c-mxv7.o +endif +COBJS-$(CONFIG_CMD_BMODE) += cmd_bmode.o +COBJS := $(sort $(COBJS-y)) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +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/imx-common/cmd_bmode.c b/arch/arm/imx-common/cmd_bmode.c new file mode 100644 index 0000000000..02fe72ed7f --- /dev/null +++ b/arch/arm/imx-common/cmd_bmode.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2012 Boundary Devices 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 +#include +#include +#include +#include + +static const struct boot_mode *modes[2]; + +static const struct boot_mode *search_modes(char *arg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(modes); i++) { + const struct boot_mode *p = modes[i]; + if (p) { + while (p->name) { + if (!strcmp(p->name, arg)) + return p; + p++; + } + } + } + return NULL; +} + +static int create_usage(char *dest) +{ + int i; + int size = 0; + + for (i = 0; i < ARRAY_SIZE(modes); i++) { + const struct boot_mode *p = modes[i]; + if (p) { + while (p->name) { + int len = strlen(p->name); + if (dest) { + memcpy(dest, p->name, len); + dest += len; + *dest++ = '|'; + } + size += len + 1; + p++; + } + } + } + if (dest) + memcpy(dest - 1, " [noreset]", 11); /* include trailing 0 */ + size += 10; + return size; +} + +static int do_boot_mode(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct boot_mode *p; + int reset_requested = 1; + + if (argc < 2) + return CMD_RET_USAGE; + p = search_modes(argv[1]); + if (!p) + return CMD_RET_USAGE; + if (argc == 3) { + if (strcmp(argv[2], "noreset")) + return CMD_RET_USAGE; + reset_requested = 0; + } + + boot_mode_apply(p->cfg_val); + if (reset_requested && p->cfg_val) + do_reset(NULL, 0, 0, NULL); + return 0; +} + +U_BOOT_CMD( + bmode, 3, 0, do_boot_mode, + NULL, + ""); + +void add_board_boot_modes(const struct boot_mode *p) +{ + int size; + char *dest; + + if (__u_boot_cmd_bmode.usage) { + free(__u_boot_cmd_bmode.usage); + __u_boot_cmd_bmode.usage = NULL; + } + + modes[0] = p; + modes[1] = soc_boot_modes; + size = create_usage(NULL); + dest = malloc(size); + if (dest) { + create_usage(dest); + __u_boot_cmd_bmode.usage = dest; + } +} diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c new file mode 100644 index 0000000000..fa1d468041 --- /dev/null +++ b/arch/arm/imx-common/cpu.c @@ -0,0 +1,140 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 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 +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_FSL_ESDHC +#include +#endif + +char *get_reset_cause(void) +{ + u32 cause; + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + + cause = readl(&src_regs->srsr); + writel(cause, &src_regs->srsr); + + switch (cause) { + case 0x00001: + case 0x00011: + return "POR"; + case 0x00004: + return "CSU"; + case 0x00008: + return "IPP USER"; + case 0x00010: + return "WDOG"; + case 0x00020: + return "JTAG HIGH-Z"; + case 0x00040: + return "JTAG SW"; + case 0x10000: + return "WARM BOOT"; + default: + return "unknown reset"; + } +} + +#if defined(CONFIG_DISPLAY_CPUINFO) + +static const char *get_imx_type(u32 imxtype) +{ + switch (imxtype) { + case 0x63: + return "6Q"; /* Quad-core version of the mx6 */ + case 0x61: + return "6DS"; /* Dual/Solo version of the mx6 */ + case 0x60: + return "6SL"; /* Solo-Lite version of the mx6 */ + case 0x51: + return "51"; + case 0x53: + return "53"; + default: + return "??"; + } +} + +int print_cpuinfo(void) +{ + u32 cpurev; + + cpurev = get_cpu_rev(); + + printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", + get_imx_type((cpurev & 0xFF000) >> 12), + (cpurev & 0x000F0) >> 4, + (cpurev & 0x0000F) >> 0, + mxc_get_clock(MXC_ARM_CLK) / 1000000); + printf("Reset cause: %s\n", get_reset_cause()); + return 0; +} +#endif + +int cpu_eth_init(bd_t *bis) +{ + int rc = -ENODEV; + +#if defined(CONFIG_FEC_MXC) + rc = fecmxc_initialize(bis); +#endif + + return rc; +} + +#ifdef CONFIG_FSL_ESDHC +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +void reset_cpu(ulong addr) +{ + __raw_writew(4, WDOG1_BASE_ADDR); +} + +u32 get_ahb_clk(void) +{ + struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg, ahb_podf; + + reg = __raw_readl(&imx_ccm->cbcdr); + reg &= MXC_CCM_CBCDR_AHB_PODF_MASK; + ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET; + + return get_periph_clk() / (ahb_podf + 1); +} diff --git a/arch/arm/imx-common/i2c-mxv7.c b/arch/arm/imx-common/i2c-mxv7.c new file mode 100644 index 0000000000..da2b26f43f --- /dev/null +++ b/arch/arm/imx-common/i2c-mxv7.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012 Boundary Devices 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 +#include +#include +#include +#include +#include +#include + +static int force_idle_bus(void *priv) +{ + int i; + int sda, scl; + ulong elapsed, start_time; + struct i2c_pads_info *p = (struct i2c_pads_info *)priv; + int ret = 0; + + gpio_direction_input(p->sda.gp); + gpio_direction_input(p->scl.gp); + + imx_iomux_v3_setup_pad(p->sda.gpio_mode); + imx_iomux_v3_setup_pad(p->scl.gpio_mode); + + sda = gpio_get_value(p->sda.gp); + scl = gpio_get_value(p->scl.gp); + if ((sda & scl) == 1) + goto exit; /* Bus is idle already */ + + printf("%s: sda=%d scl=%d sda.gp=0x%x scl.gp=0x%x\n", __func__, + sda, scl, p->sda.gp, p->scl.gp); + /* Send high and low on the SCL line */ + for (i = 0; i < 9; i++) { + gpio_direction_output(p->scl.gp, 0); + udelay(50); + gpio_direction_input(p->scl.gp); + udelay(50); + } + start_time = get_timer(0); + for (;;) { + sda = gpio_get_value(p->sda.gp); + scl = gpio_get_value(p->scl.gp); + if ((sda & scl) == 1) + break; + WATCHDOG_RESET(); + elapsed = get_timer(start_time); + if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ + ret = -EBUSY; + printf("%s: failed to clear bus, sda=%d scl=%d\n", + __func__, sda, scl); + break; + } + } +exit: + imx_iomux_v3_setup_pad(p->sda.i2c_mode); + imx_iomux_v3_setup_pad(p->scl.i2c_mode); + return ret; +} + +static void * const i2c_bases[] = { + (void *)I2C1_BASE_ADDR, + (void *)I2C2_BASE_ADDR, +#ifdef I2C3_BASE_ADDR + (void *)I2C3_BASE_ADDR, +#endif +}; + +/* i2c_index can be from 0 - 2 */ +void setup_i2c(unsigned i2c_index, int speed, int slave_addr, + struct i2c_pads_info *p) +{ + if (i2c_index >= ARRAY_SIZE(i2c_bases)) + return; + /* Enable i2c clock */ + enable_i2c_clk(1, i2c_index); + /* Make sure bus is idle */ + force_idle_bus(p); + bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr, + force_idle_bus, p); +} diff --git a/arch/arm/imx-common/iomux-v3.c b/arch/arm/imx-common/iomux-v3.c new file mode 100644 index 0000000000..da093fbe14 --- /dev/null +++ b/arch/arm/imx-common/iomux-v3.c @@ -0,0 +1,70 @@ +/* + * Based on the iomux-v3.c from Linux kernel: + * Copyright (C) 2008 by Sascha Hauer + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, + * + * + * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include +#include + +static void *base = (void *)IOMUXC_BASE_ADDR; + +/* + * configures a single pad in the iomuxer + */ +int imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad) +{ + u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT; + u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT; + u32 sel_input_ofs = + (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT; + u32 sel_input = + (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT; + u32 pad_ctrl_ofs = + (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT; + u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; + + if (mux_ctrl_ofs) + __raw_writel(mux_mode, base + mux_ctrl_ofs); + + if (sel_input_ofs) + __raw_writel(sel_input, base + sel_input_ofs); + + if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) + __raw_writel(pad_ctrl, base + pad_ctrl_ofs); + + return 0; +} + +int imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count) +{ + iomux_v3_cfg_t *p = pad_list; + int i; + int ret; + + for (i = 0; i < count; i++) { + ret = imx_iomux_v3_setup_pad(*p); + if (ret) + return ret; + p++; + } + return 0; +} diff --git a/arch/arm/imx-common/speed.c b/arch/arm/imx-common/speed.c new file mode 100644 index 0000000000..80989c4983 --- /dev/null +++ b/arch/arm/imx-common/speed.c @@ -0,0 +1,45 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 +#include +#include + +#ifdef CONFIG_FSL_ESDHC +DECLARE_GLOBAL_DATA_PTR; +#endif + +int get_clocks(void) +{ +#ifdef CONFIG_FSL_ESDHC +#ifdef CONFIG_FSL_USDHC + gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); +#else + gd->sdhc_clk = mxc_get_clock(MXC_IPG_PERCLK); +#endif +#endif + return 0; +} diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c new file mode 100644 index 0000000000..e2725e1a64 --- /dev/null +++ b/arch/arm/imx-common/timer.c @@ -0,0 +1,149 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 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 +#include +#include +#include + +/* General purpose timers registers */ +struct mxc_gpt { + unsigned int control; + unsigned int prescaler; + unsigned int status; + unsigned int nouse[6]; + unsigned int counter; +}; + +static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_FRR (1 << 9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ +#define GPTCR_TEN 1 /* Timer enable */ +#define CLK_32KHZ 32768 /* 32Khz input */ + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp (gd->tbl) +#define lastinc (gd->lastinc) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, CLK_32KHZ); + + return tick; +} + +static inline unsigned long long us_to_tick(unsigned long long usec) +{ + usec = usec * CLK_32KHZ + 999999; + do_div(usec, 1000000); + + return usec; +} + +int timer_init(void) +{ + int i; + ulong val; + + /* setup GP Timer 1 */ + __raw_writel(GPTCR_SWR, &cur_gpt->control); + + /* We have no udelay by now */ + for (i = 0; i < 100; i++) + __raw_writel(0, &cur_gpt->control); + + __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ + + /* Freerun Mode, PERCLK1 input */ + i = __raw_readl(&cur_gpt->control); + __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); + + val = __raw_readl(&cur_gpt->counter); + lastinc = val / (CLK_32KHZ / CONFIG_SYS_HZ); + timestamp = 0; + + return 0; +} + +unsigned long long get_ticks(void) +{ + ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */ + + if (now >= lastinc) { + /* + * normal mode (non roll) + * move stamp forward with absolut diff ticks + */ + timestamp += (now - lastinc); + } else { + /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + } + lastinc = now; + return timestamp; +} + +ulong get_timer_masked(void) +{ + /* + * get_ticks() returns a long long (64 bit), it wraps in + * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in + * 5 * 10^6 days - long enough. + */ + return tick_to_time(get_ticks()); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds AND preserve advance timstamp value */ +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CLK_32KHZ; +} -- cgit