X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farm926ejs%2Fmxs%2Fmxs.c;h=365542fe0bb29e1a7c2cc4ff4d35c83adb41d37b;hb=6297872cd5de4705b6318778261b1f3f64a34c11;hp=6ce8019b835ef832a2dfdab056f8bc7215b73aec;hpb=5fb29f3c48d26981b117b08286bc16ec99d4ca0b;p=oweals%2Fu-boot.git diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index 6ce8019b83..365542fe0b 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -1,5 +1,5 @@ /* - * Freescale i.MX28 common code + * Freescale i.MX23/i.MX28 common code * * Copyright (C) 2011 Marek Vasut * on behalf of DENX Software Engineering GmbH @@ -7,43 +7,22 @@ * 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 + * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include -#include +#include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; -/* 1 second delay should be plenty of time for block reset. */ -#define RESET_MAX_TIMEOUT 1000000 - -#define MXS_BLOCK_SFTRST (1 << 31) -#define MXS_BLOCK_CLKGATE (1 << 30) - /* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {} @@ -81,70 +60,32 @@ void enable_caches(void) #endif } -int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned - int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == mask) - break; - udelay(1); - } - - return !timeout; -} - -int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned - int timeout) -{ - while (--timeout) { - if ((readl(®->reg) & mask) == 0) - break; - udelay(1); - } - - return !timeout; -} - -int mxs_reset_block(struct mxs_register_32 *reg) -{ - /* Clear SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MXS_BLOCK_CLKGATE, ®->reg_clr); - - /* Set SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_set); - - /* Wait for CLKGATE being set */ - if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear SFTRST */ - writel(MXS_BLOCK_SFTRST, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) - return 1; - - /* Clear CLKGATE */ - writel(MXS_BLOCK_CLKGATE, ®->reg_clr); - - if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) - return 1; - - return 0; -} - +/* + * This function will craft a jumptable at 0x0 which will redirect interrupt + * vectoring to proper location of U-Boot in RAM. + * + * The structure of the jumptable will be as follows: + * ldr pc, [pc, #0x18] ..... for each vector, thus repeated 8 times + * ... for each previous ldr, thus also repeated 8 times + * + * The "ldr pc, [pc, #0x18]" instruction above loads address from memory at + * offset 0x18 from current value of PC register. Note that PC is already + * incremented by 4 when computing the offset, so the effective offset is + * actually 0x20, this the associated . Loading the PC + * register with an address performs a jump to that address. + */ void mx28_fixup_vt(uint32_t start_addr) { - uint32_t *vt = (uint32_t *)0x20; + /* ldr pc, [pc, #0x18] */ + const uint32_t ldr_pc = 0xe59ff018; + /* Jumptable location is 0x0 */ + uint32_t *vt = (uint32_t *)0x0; int i; - for (i = 0; i < 8; i++) - vt[i] = start_addr + (4 * i); + for (i = 0; i < 8; i++) { + vt[i] = ldr_pc; + vt[i + 8] = start_addr + (4 * i); + } } #ifdef CONFIG_ARCH_MISC_INIT @@ -196,6 +137,8 @@ static const char *get_cpu_type(void) (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { + case HW_DIGCTL_CHIPID_MX23: + return "23"; case HW_DIGCTL_CHIPID_MX28: return "28"; default: @@ -210,6 +153,21 @@ static const char *get_cpu_rev(void) 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_MX23: + switch (rev) { + case 0x0: + return "1.0"; + case 0x1: + return "1.1"; + case 0x2: + return "1.2"; + case 0x3: + return "1.3"; + case 0x4: + return "1.4"; + default: + return "??"; + } case HW_DIGCTL_CHIPID_MX28: switch (rev) { case 0x1: @@ -276,7 +234,7 @@ int cpu_eth_init(bd_t *bis) } #endif -static void __mx28_adjust_mac(int dev_id, unsigned char *mac) +__weak void mx28_adjust_mac(int dev_id, unsigned char *mac) { mac[0] = 0x00; mac[1] = 0x04; /* Use FSL vendor MAC address by default */ @@ -285,9 +243,6 @@ static void __mx28_adjust_mac(int dev_id, unsigned char *mac) 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