diff options
Diffstat (limited to 'arch/arm')
59 files changed, 1685 insertions, 944 deletions
diff --git a/arch/arm/cpu/arm1136/mx31/devices.c b/arch/arm/cpu/arm1136/mx31/devices.c index 1f4ca7e..1e7d48f 100644 --- a/arch/arm/cpu/arm1136/mx31/devices.c +++ b/arch/arm/cpu/arm1136/mx31/devices.c @@ -24,8 +24,8 @@ */ #include <common.h> -#include <asm/arch/mx31-regs.h> -#include <asm/arch/mx31.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> #ifdef CONFIG_SYS_MX31_UART1 void mx31_uart1_hw_init(void) diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index 8bd23ee..18572b9 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -22,7 +22,7 @@ */ #include <common.h> -#include <asm/arch/mx31-regs.h> +#include <asm/arch/imx-regs.h> #include <asm/io.h> static u32 mx31_decode_pll(u32 reg, u32 infreq) @@ -106,11 +106,64 @@ void mx31_set_pad(enum iomux_pins pin, u32 config) } +struct mx3_cpu_type mx31_cpu_type[] = { + { .srev = 0x00, .v = "1.0" }, + { .srev = 0x10, .v = "1.1" }, + { .srev = 0x11, .v = "1.1" }, + { .srev = 0x12, .v = "1.15" }, + { .srev = 0x13, .v = "1.15" }, + { .srev = 0x14, .v = "1.2" }, + { .srev = 0x15, .v = "1.2" }, + { .srev = 0x28, .v = "2.0" }, + { .srev = 0x29, .v = "2.0" }, +}; + +char *get_cpu_rev(void) +{ + u32 i, srev; + + /* read SREV register from IIM module */ + struct iim_regs *iim = (struct iim_regs *)MX31_IIM_BASE_ADDR; + srev = readl(&iim->iim_srev); + + for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) + if (srev == mx31_cpu_type[i].srev) + return mx31_cpu_type[i].v; + return "unknown"; +} + +char *get_reset_cause(void) +{ + /* read RCSR register from CCM module */ + struct clock_control_regs *ccm = + (struct clock_control_regs *)CCM_BASE; + + u32 cause = readl(&ccm->rcsr) & 0x07; + + switch (cause) { + case 0x0000: + return "POR"; + break; + case 0x0001: + return "RST"; + break; + case 0x0002: + return "WDOG"; + break; + case 0x0006: + return "JTAG"; + break; + default: + return "unknown reset"; + } +} + #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo (void) { - printf("CPU: Freescale i.MX31 at %d MHz\n", - mx31_get_mcu_main_clk() / 1000000); + printf("CPU: Freescale i.MX31 rev %s at %d MHz.", + get_cpu_rev(), mx31_get_mcu_main_clk() / 1000000); + printf("Reset cause: %s\n", get_reset_cause()); return 0; } #endif diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index f6be3b9..c4bc3b3 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -22,8 +22,10 @@ */ #include <common.h> -#include <asm/arch/mx31-regs.h> +#include <asm/arch/imx-regs.h> #include <div64.h> +#include <watchdog.h> +#include <asm/io.h> #define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ @@ -165,5 +167,39 @@ void __udelay (unsigned long usec) void reset_cpu (ulong addr) { - __REG16(WDOG_BASE) = 4; + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE; + wdog->wcr = WDOG_ENABLE; + while (1) + ; } + +#ifdef CONFIG_HW_WATCHDOG +void mxc_hw_watchdog_enable(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE; + u16 secs; + + /* + * The timer watchdog can be set between + * 0.5 and 128 Seconds. If not defined + * in configuration file, sets 64 Seconds + */ +#ifdef CONFIG_SYS_WD_TIMER_SECS + secs = (CONFIG_SYS_WD_TIMER_SECS << 1) & 0xFF; + if (!secs) secs = 1; +#else + secs = 64; +#endif + writew(readw(&wdog->wcr) | (secs << WDOG_WT_SHIFT) | WDOG_ENABLE, + &wdog->wcr); +} + + +void mxc_hw_watchdog_reset(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE; + + writew(0x5555, &wdog->wsr); + writew(0xAAAA, &wdog->wsr); +} +#endif diff --git a/arch/arm/cpu/arm920t/a320/Makefile b/arch/arm/cpu/arm920t/a320/Makefile index 31da706..50eb265 100644 --- a/arch/arm/cpu/arm920t/a320/Makefile +++ b/arch/arm/cpu/arm920t/a320/Makefile @@ -27,7 +27,6 @@ LIB = $(obj)lib$(SOC).o SOBJS += reset.o COBJS += timer.o -COBJS += ftsmc020.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/arm920t/a320/ftsmc020.c b/arch/arm/cpu/arm920t/a320/ftsmc020.c deleted file mode 100644 index 7646537..0000000 --- a/arch/arm/cpu/arm920t/a320/ftsmc020.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <config.h> -#include <common.h> -#include <asm/io.h> -#include <asm/arch/ftsmc020.h> - -struct ftsmc020_config { - unsigned int config; - unsigned int timing; -}; - -static struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS; - -static struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE; - -static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg) -{ - if (bank > 3) { - printf("bank # %u invalid\n", bank); - return; - } - - writel(cfg->config, &smc->bank[bank].cr); - writel(cfg->timing, &smc->bank[bank].tpr); -} - -void ftsmc020_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(config); i++) - ftsmc020_setup_bank(i, &config[i]); -} diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c index d2e316f..95cb8fd 100644 --- a/arch/arm/cpu/arm920t/a320/timer.c +++ b/arch/arm/cpu/arm920t/a320/timer.c @@ -19,21 +19,19 @@ #include <common.h> #include <asm/io.h> -#include <asm/arch/ftpmu010.h> -#include <asm/arch/fttmr010.h> +#include <faraday/ftpmu010.h> +#include <faraday/fttmr010.h> static ulong timestamp; static ulong lastdec; static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; -static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE; #define TIMER_CLOCK 32768 #define TIMER_LOAD_VAL 0xffffffff int timer_init(void) { - unsigned int oscc; unsigned int cr; debug("%s()\n", __func__); @@ -41,23 +39,8 @@ int timer_init(void) /* disable timers */ writel(0, &tmr->cr); - /* - * use 32768Hz oscillator for RTC, WDT, TIMER - */ - - /* enable the 32768Hz oscillator */ - oscc = readl(&pmu->OSCC); - oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI); - writel(oscc, &pmu->OSCC); - - /* wait until ready */ - while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE)) - ; - - /* select 32768Hz oscillator */ - oscc = readl(&pmu->OSCC); - oscc |= FTPMU010_OSCC_OSCL_RTCLSEL; - writel(oscc, &pmu->OSCC); + /* use 32768Hz oscillator for RTC, WDT, TIMER */ + ftpmu010_32768osc_enable(); /* setup timer */ writel(TIMER_LOAD_VAL, &tmr->timer3_load); diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c index 62aa175..c21938e 100644 --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c @@ -62,6 +62,16 @@ int arch_cpu_init(void) /* Enable GPIO clock */ writel(APBC_APBCLK, &apb1clkres->gpio); +#ifdef CONFIG_I2C_MV + /* Enable general I2C clock */ + writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0); + writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0); + + /* Enable power I2C clock */ + writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1); + writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1); +#endif + /* * Enable Functional and APB clock at 14.7456MHz * for configured UART console @@ -90,3 +100,9 @@ int print_cpuinfo(void) return 0; } #endif + +#ifdef CONFIG_I2C_MV +void i2c_clk_enable(void) +{ +} +#endif diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c index c6e1146..76e4b5c 100644 --- a/arch/arm/cpu/arm926ejs/mx25/generic.c +++ b/arch/arm/cpu/arm926ejs/mx25/generic.c @@ -145,7 +145,7 @@ int cpu_mmc_init (bd_t * bis) } #ifdef CONFIG_MXC_UART -void mx25_uart_init_pins (void) +void mx25_uart1_init_pins(void) { struct iomuxc_mux_ctl *muxctl; struct iomuxc_pad_ctl *padctl; diff --git a/arch/arm/cpu/arm926ejs/orion5x/Makefile b/arch/arm/cpu/arm926ejs/orion5x/Makefile index e5a9994..a4298b4 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/Makefile +++ b/arch/arm/cpu/arm926ejs/orion5x/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> +# Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> # # Based on original Kirkwood support which is # (C) Copyright 2009 diff --git a/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/arch/arm/cpu/arm926ejs/orion5x/cpu.c index 1894b52..05bd45c 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/cpu.c +++ b/arch/arm/cpu/arm926ejs/orion5x/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirkwood support which is * (C) Copyright 2009 diff --git a/arch/arm/cpu/arm926ejs/orion5x/dram.c b/arch/arm/cpu/arm926ejs/orion5x/dram.c index b749282..3e1ff7d 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/dram.c +++ b/arch/arm/cpu/arm926ejs/orion5x/dram.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirkwood support which is * (C) Copyright 2009 @@ -38,7 +38,7 @@ u32 orion5x_sdram_bar(enum memory_bank bank) { struct orion5x_ddr_addr_decode_registers *winregs = (struct orion5x_ddr_addr_decode_registers *) - ORION5X_CPU_WIN_BASE; + ORION5X_DRAM_BASE; u32 result = 0; u32 enable = 0x01 & winregs[bank].size; diff --git a/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S b/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S index 0523bd4..a2de3cf 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S +++ b/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * (C) Copyright 2009 * Marvell Semiconductor <www.marvell.com> diff --git a/arch/arm/cpu/arm926ejs/orion5x/timer.c b/arch/arm/cpu/arm926ejs/orion5x/timer.c index bbab226..9d45260 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/timer.c +++ b/arch/arm/cpu/arm926ejs/orion5x/timer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirkwood support which is * Copyright (C) Marvell International Ltd. and its affiliates diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c index 9ddc77c..8b2eafa 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c @@ -59,6 +59,12 @@ int arch_cpu_init(void) /* Enable GPIO clock */ writel(APBC_APBCLK, &apbclkres->gpio); +#ifdef CONFIG_I2C_MV + /* Enable I2C clock */ + writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi); + writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi); +#endif + icache_enable(); return 0; @@ -76,3 +82,9 @@ int print_cpuinfo(void) return 0; } #endif + +#ifdef CONFIG_I2C_MV +void i2c_clk_enable(void) +{ +} +#endif diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index fefcfa2..0940937 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -10,7 +10,7 @@ * 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.aribaud@free.fr> + * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> * * See file CREDITS for list of people who contributed to this * project. diff --git a/arch/arm/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S index 00914f4..0054b22 100644 --- a/arch/arm/cpu/arm946es/start.S +++ b/arch/arm/cpu/arm946es/start.S @@ -10,7 +10,7 @@ * 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.aribaud@free.fr> + * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> * * See file CREDITS for list of people who contributed to this * project. diff --git a/arch/arm/cpu/armv7/mx5/soc.c b/arch/arm/cpu/armv7/mx5/soc.c index 09500b3..6f4e8db 100644 --- a/arch/arm/cpu/armv7/mx5/soc.c +++ b/arch/arm/cpu/armv7/mx5/soc.c @@ -77,6 +77,33 @@ u32 get_cpu_rev(void) return system_rev; } +static 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: + 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) int print_cpuinfo(void) @@ -89,6 +116,7 @@ int print_cpuinfo(void) (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, mxc_get_clock(MXC_ARM_CLK) / 1000000); + printf("Reset cause: %s\n", get_reset_cause()); return 0; } #endif diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c index 2238c52..3d38d08 100644 --- a/arch/arm/cpu/armv7/omap3/clock.c +++ b/arch/arm/cpu/armv7/omap3/clock.c @@ -278,6 +278,25 @@ static void dpll4_init_34xx(u32 sil_index, u32 clk_index) wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); } +static void dpll5_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_per2_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* PER2 DPLL (DPLL5) */ + sr32(&prcm_base->clken2_pll, 0, 3, PLL_STOP); + wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY); + sr32(&prcm_base->clksel5_pll, 0, 5, ptr->m2); /* set M2 (usbtll_fck) */ + sr32(&prcm_base->clksel4_pll, 8, 11, ptr->m); /* set m (11-bit multiplier) */ + sr32(&prcm_base->clksel4_pll, 0, 7, ptr->n); /* set n (7-bit divider)*/ + sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel); /* FREQSEL */ + sr32(&prcm_base->clken2_pll, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY); +} + static void mpu_init_34xx(u32 sil_index, u32 clk_index) { struct prcm *prcm_base = (struct prcm *)PRCM_BASE; @@ -587,6 +606,7 @@ void prcm_init(void) dpll3_init_34xx(sil_index, clk_index); dpll4_init_34xx(sil_index, clk_index); + dpll5_init_34xx(sil_index, clk_index); iva_init_34xx(sil_index, clk_index); mpu_init_34xx(sil_index, clk_index); diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S index 109481e..1458072 100644 --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S @@ -360,6 +360,28 @@ get_per_dpll_param: adr r0, per_dpll_param mov pc, lr +/* PER2 DPLL values */ +per2_dpll_param: +/* 12MHz */ +.word PER2_M_12, PER2_N_12, PER2_FSEL_12, PER2_M2_12 + +/* 13MHz */ +.word PER2_M_13, PER2_N_13, PER2_FSEL_13, PER2_M2_13 + +/* 19.2MHz */ +.word PER2_M_19P2, PER2_N_19P2, PER2_FSEL_19P2, PER2_M2_19P2 + +/* 26MHz */ +.word PER2_M_26, PER2_N_26, PER2_FSEL_26, PER2_M2_26 + +/* 38.4MHz */ +.word PER2_M_38P4, PER2_N_38P4, PER2_FSEL_38P4, PER2_M2_38P4 + +.globl get_per2_dpll_param +get_per2_dpll_param: + adr r0, per2_dpll_param + mov pc, lr + /* * Tables for 36XX/37XX devices * diff --git a/arch/arm/cpu/armv7/omap3/mem.c b/arch/arm/cpu/armv7/omap3/mem.c index bd914b0..a01c303 100644 --- a/arch/arm/cpu/armv7/omap3/mem.c +++ b/arch/arm/cpu/armv7/omap3/mem.c @@ -31,16 +31,6 @@ #include <asm/arch/sys_proto.h> #include <command.h> -/* - * Only One NAND allowed on board at a time. - * The GPMC CS Base for the same - */ -unsigned int boot_flash_base; -unsigned int boot_flash_off; -unsigned int boot_flash_sec; -unsigned int boot_flash_type; -volatile unsigned int boot_flash_env_addr; - struct gpmc *gpmc_cfg; #if defined(CONFIG_CMD_NAND) @@ -134,10 +124,6 @@ void gpmc_init(void) const u32 *gpmc_config = NULL; u32 base = 0; u32 size = 0; -#if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND) - u32 f_off = CONFIG_SYS_MONITOR_LEN; - u32 f_sec = 0; -#endif #endif u32 config = 0; @@ -162,15 +148,6 @@ void gpmc_init(void) base = PISMO1_NAND_BASE; size = PISMO1_NAND_SIZE; enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); -#if defined(CONFIG_ENV_IS_IN_NAND) - f_off = SMNAND_ENV_OFFSET; - f_sec = (128 << 10); /* 128 KiB */ - /* env setup */ - boot_flash_base = base; - boot_flash_off = f_off; - boot_flash_sec = f_sec; - boot_flash_env_addr = f_off; -#endif #endif #if defined(CONFIG_CMD_ONENAND) @@ -178,14 +155,5 @@ void gpmc_init(void) base = PISMO1_ONEN_BASE; size = PISMO1_ONEN_SIZE; enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); -#if defined(CONFIG_ENV_IS_IN_ONENAND) - f_off = ONENAND_ENV_OFFSET; - f_sec = (128 << 10); /* 128 KiB */ - /* env setup */ - boot_flash_base = base; - boot_flash_off = f_off; - boot_flash_sec = f_sec; - boot_flash_env_addr = f_off; -#endif #endif } diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index d83d501..2929fc7 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -70,6 +70,18 @@ _end_vect: _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE +#ifdef CONFIG_TEGRA2 +/* + * Tegra2 uses 2 separate CPUs - the AVP (ARM7TDMI) and the CPU (dual A9s). + * U-Boot runs on the AVP first, setting things up for the CPU (PLLs, + * muxes, clocks, clamps, etc.). Then the AVP halts, and expects the CPU + * to pick up its reset vector, which points here. + */ +.globl _armboot_start +_armboot_start: + .word _start +#endif + /* * These are defined in the board-specific linker script. */ @@ -115,7 +127,7 @@ reset: orr r0, r0, #0xd3 msr cpsr,r0 -#if (CONFIG_OMAP34XX) +#if defined(CONFIG_OMAP34XX) /* Copy vectors to mask ROM indirect addr */ adr r0, _start @ r0 <- current position of code add r0, r0, #4 @ skip reset vector diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index 687c887..f1ea915 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := board.o sys_info.o timer.o +COBJS := ap20.o board.o sys_info.o timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c new file mode 100644 index 0000000..60dd5df --- /dev/null +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -0,0 +1,358 @@ +/* +* (C) Copyright 2010-2011 +* NVIDIA Corporation <www.nvidia.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 "ap20.h" +#include <asm/io.h> +#include <asm/arch/tegra2.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/pmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/scu.h> +#include <common.h> + +u32 s_first_boot = 1; + +void init_pllx(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + /* If PLLX is already enabled, just return */ + reg = readl(&clkrst->crc_pllx_base); + if (reg & PLL_ENABLE) + return; + + /* Set PLLX_MISC */ + reg = CPCON; /* CPCON[11:8] = 0001 */ + writel(reg, &clkrst->crc_pllx_misc); + + /* Use 12MHz clock here */ + reg = (PLL_BYPASS | PLL_DIVM); + reg |= (1000 << 8); /* DIVN = 0x3E8 */ + writel(reg, &clkrst->crc_pllx_base); + + reg |= PLL_ENABLE; + writel(reg, &clkrst->crc_pllx_base); + + reg &= ~PLL_BYPASS; + writel(reg, &clkrst->crc_pllx_base); +} + +static void enable_cpu_clock(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg, clk; + + /* + * NOTE: + * Regardless of whether the request is to enable or disable the CPU + * clock, every processor in the CPU complex except the master (CPU 0) + * will have it's clock stopped because the AVP only talks to the + * master. The AVP does not know (nor does it need to know) that there + * are multiple processors in the CPU complex. + */ + + if (enable) { + /* Initialize PLLX */ + init_pllx(); + + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + } + + /* Fetch the register containing the main CPU complex clock enable */ + reg = readl(&clkrst->crc_clk_out_enb_l); + reg |= CLK_ENB_CPU; + + /* + * Read the register containing the individual CPU clock enables and + * always stop the clock to CPU 1. + */ + clk = readl(&clkrst->crc_clk_cpu_cmplx); + clk |= CPU1_CLK_STP; + + if (enable) { + /* Unstop the CPU clock */ + clk &= ~CPU0_CLK_STP; + } else { + /* Stop the CPU clock */ + clk |= CPU0_CLK_STP; + } + + writel(clk, &clkrst->crc_clk_cpu_cmplx); + writel(reg, &clkrst->crc_clk_out_enb_l); +} + +static int is_cpu_powered(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; +} + +static void remove_cpu_io_clamps(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Remove the clamps on the CPU I/O signals */ + reg = readl(&pmc->pmc_remove_clamping); + reg |= CPU_CLMP; + writel(reg, &pmc->pmc_remove_clamping); + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); +} + +static void powerup_cpu(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + int timeout = IO_STABILIZATION_DELAY; + + if (!is_cpu_powered()) { + /* Toggle the CPU power state (OFF -> ON) */ + reg = readl(&pmc->pmc_pwrgate_toggle); + reg &= PARTID_CP; + reg |= START_CP; + writel(reg, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_cpu_powered()) { + if (timeout-- == 0) + printf("CPU failed to power up!\n"); + else + udelay(10); + } + + /* + * Remove the I/O clamps from CPU power partition. + * Recommended only on a Warm boot, if the CPU partition gets + * power gated. Shouldn't cause any harm when called after a + * cold boot according to HW, probably just redundant. + */ + remove_cpu_io_clamps(); + } +} + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* + * The TI PMU65861C needs a 3.75ms delay between enabling + * the power rail and enabling the CPU clock. This delay + * between SM1EN and SM1 is for switching time + the ramp + * up of the voltage to the CPU (VDD_CPU from PMU). + */ + udelay(3750); +} + +static void reset_A9_cpu(int reset) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg, cpu; + + /* + * NOTE: Regardless of whether the request is to hold the CPU in reset + * or take it out of reset, every processor in the CPU complex + * except the master (CPU 0) will be held in reset because the + * AVP only talks to the master. The AVP does not know that there + * are multiple processors in the CPU complex. + */ + + /* Hold CPU 1 in reset */ + cpu = SET_DBGRESET1 | SET_DERESET1 | SET_CPURESET1; + writel(cpu, &clkrst->crc_cpu_cmplx_set); + + reg = readl(&clkrst->crc_rst_dev_l); + if (reset) { + /* Now place CPU0 into reset */ + cpu |= SET_DBGRESET0 | SET_DERESET0 | SET_CPURESET0; + writel(cpu, &clkrst->crc_cpu_cmplx_set); + + /* Enable master CPU reset */ + reg |= SWR_CPU_RST; + } else { + /* Take CPU0 out of reset */ + cpu = CLR_DBGRESET0 | CLR_DERESET0 | CLR_CPURESET0; + writel(cpu, &clkrst->crc_cpu_cmplx_clr); + + /* Disable master CPU reset */ + reg &= ~SWR_CPU_RST; + } + + writel(reg, &clkrst->crc_rst_dev_l); +} + +static void clock_enable_coresight(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 rst, clk, src; + + rst = readl(&clkrst->crc_rst_dev_u); + clk = readl(&clkrst->crc_clk_out_enb_u); + + if (enable) { + rst &= ~SWR_CSITE_RST; + clk |= CLK_ENB_CSITE; + } else { + rst |= SWR_CSITE_RST; + clk &= ~CLK_ENB_CSITE; + } + + writel(clk, &clkrst->crc_clk_out_enb_u); + writel(rst, &clkrst->crc_rst_dev_u); + + if (enable) { + /* + * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by + * 1.5, giving an effective frequency of 144MHz. + * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor + * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) + */ + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); + writel(src, &clkrst->crc_clk_src_csite); + + /* Unlock the CPU CoreSight interfaces */ + rst = 0xC5ACCE55; + writel(rst, CSITE_CPU_DBG0_LAR); + writel(rst, CSITE_CPU_DBG1_LAR); + } +} + +void start_cpu(u32 reset_vector) +{ + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + /* Hold the CPUs in reset */ + reset_A9_cpu(1); + + /* Disable the CPU clock */ + enable_cpu_clock(0); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* + * Set the entry point for CPU execution from reset, + * if it's a non-zero value. + */ + if (reset_vector) + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Enable the CPU clock */ + enable_cpu_clock(1); + + /* If the CPU doesn't already have power, power it up */ + powerup_cpu(); + + /* Take the CPU out of reset */ + reset_A9_cpu(0); +} + + +void halt_avp(void) +{ + for (;;) { + writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ + | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)), + FLOW_CTLR_HALT_COP_EVENTS); + } +} + +void enable_scu(void) +{ + struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; + u32 reg; + + /* If SCU already setup/enabled, return */ + if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) + return; + + /* Invalidate all ways for all processors */ + writel(0xFFFF, &scu->scu_inv_all); + + /* Enable SCU - bit 0 */ + reg = readl(&scu->scu_ctrl); + reg |= SCU_CTRL_ENABLE; + writel(reg, &scu->scu_ctrl); +} + +void init_pmc_scratch(void) +{ + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + int i; + + /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ + for (i = 0; i < 23; i++) + writel(0, &pmc->pmc_scratch1+i); + + /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ + writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20); +} + +void cpu_start(void) +{ + struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + + /* enable JTAG */ + writel(0xC0, &pmt->pmt_cfg_ctl); + + if (s_first_boot) { + /* + * Need to set this before cold-booting, + * otherwise we'll end up in an infinite loop. + */ + s_first_boot = 0; + cold_boot(); + } +} + +void tegra2_start() +{ + if (s_first_boot) { + /* Init Debug UART Port (115200 8n1) */ + uart_init(); + + /* Init PMC scratch memory */ + init_pmc_scratch(); + } + +#ifdef CONFIG_ENABLE_CORTEXA9 + /* take the mpcore out of reset */ + cpu_start(); + + /* configure cache */ + cache_configure(); +#endif +} diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h b/arch/arm/cpu/armv7/tegra2/ap20.h new file mode 100644 index 0000000..49fe340 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra2/ap20.h @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2010-2011 + * NVIDIA Corporation <www.nvidia.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 <asm/types.h> + +/* Stabilization delays, in usec */ +#define PLL_STABILIZATION_DELAY (300) +#define IO_STABILIZATION_DELAY (1000) + +#define NVBL_PLLP_KHZ (216000) + +#define PLLX_ENABLED (1 << 30) +#define CCLK_BURST_POLICY 0x20008888 +#define SUPER_CCLK_DIVIDER 0x80000000 + +/* Calculate clock fractional divider value from ref and target frequencies */ +#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) + +/* Calculate clock frequency value from reference and clock divider value */ +#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) + +/* AVP/CPU ID */ +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ +#define PG_UP_TAG_0 0x0 + +#define CORESIGHT_UNLOCK 0xC5ACCE55; + +/* AP20-Specific Base Addresses */ + +/* AP20 Base physical address of SDRAM. */ +#define AP20_BASE_PA_SDRAM 0x00000000 +/* AP20 Base physical address of internal SRAM. */ +#define AP20_BASE_PA_SRAM 0x40000000 +/* AP20 Size of internal SRAM (256KB). */ +#define AP20_BASE_PA_SRAM_SIZE 0x00040000 +/* AP20 Base physical address of flash. */ +#define AP20_BASE_PA_NOR_FLASH 0xD0000000 +/* AP20 Base physical address of boot information table. */ +#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM + +/* + * Super-temporary stacks for EXTREMELY early startup. The values chosen for + * these addresses must be valid on ALL SOCs because this value is used before + * we are able to differentiate between the SOC types. + * + * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its + * stack is placed below the AVP stack. Once the CPU stack has been moved, + * the AVP is free to use the IRAM the CPU stack previously occupied if + * it should need to do so. + * + * NOTE: In multi-processor CPU complex configurations, each processor will have + * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a + * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a + * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous + * CPU. + */ + +/* Common AVP early boot stack limit */ +#define AVP_EARLY_BOOT_STACK_LIMIT \ + (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) +/* Common AVP early boot stack size */ +#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 +/* Common CPU early boot stack limit */ +#define CPU_EARLY_BOOT_STACK_LIMIT \ + (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) +/* Common CPU early boot stack size */ +#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 + +#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) +#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) +#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) + +#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) +#define FLOW_MODE_STOP 2 +#define HALT_COP_EVENT_JTAG (1 << 28) +#define HALT_COP_EVENT_IRQ_1 (1 << 11) +#define HALT_COP_EVENT_FIQ_1 (1 << 9) + +/* Prototypes */ + +void tegra2_start(void); +void uart_init(void); +void udelay(unsigned long); +void cold_boot(void); +void cache_configure(void); diff --git a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S index 7f15746..f24a2ff 100644 --- a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S +++ b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S @@ -26,6 +26,7 @@ #include <config.h> #include <version.h> + _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE @ sdram load addr from config file @@ -58,8 +59,101 @@ lowlevel_init: mov pc, lr @ back to arch calling code + +.globl startup_cpu +startup_cpu: + @ Initialize the AVP, clocks, and memory controller + @ SDRAM is guaranteed to be on at this point + + ldr r0, =cold_boot @ R0 = reset vector for CPU + bl start_cpu @ start the CPU + + @ Transfer control to the AVP code + bl halt_avp + + @ Should never get here +_loop_forever2: + b _loop_forever2 + +.globl cache_configure +cache_configure: + stmdb r13!,{r14} + @ invalidate instruction cache + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 + + @ invalidate the i&d tlb entries + mcr p15, 0, r1, c8, c5, 0 + mcr p15, 0, r1, c8, c6, 0 + + @ enable instruction cache + mrc p15, 0, r1, c1, c0, 0 + orr r1, r1, #(1<<12) + mcr p15, 0, r1, c1, c0, 0 + + bl enable_scu + + @ enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #0x41 + mcr p15, 0, r0, c1, c0, 1 + + @ Now flush the Dcache + mov r0, #0 + @ 256 cache lines + mov r1, #256 + +invalidate_loop: + add r1, r1, #-1 + mov r0, r1, lsl #5 + @ invalidate d-cache using line (way0) + mcr p15, 0, r0, c7, c6, 2 + + orr r2, r0, #(1<<30) + @ invalidate d-cache using line (way1) + mcr p15, 0, r2, c7, c6, 2 + + orr r2, r0, #(2<<30) + @ invalidate d-cache using line (way2) + mcr p15, 0, r2, c7, c6, 2 + + orr r2, r0, #(3<<30) + @ invalidate d-cache using line (way3) + mcr p15, 0, r2, c7, c6, 2 + cmp r1, #0 + bne invalidate_loop + + @ FIXME: should have ap20's L2 disabled too? +invalidate_done: + ldmia r13!,{pc} + +.globl cold_boot +cold_boot: + msr cpsr_c, #0xD3 + @ Check current processor: CPU or AVP? + @ If CPU, go to CPU boot code, else continue on AVP path + + ldr r0, =NV_PA_PG_UP_BASE + ldr r1, [r0] + ldr r2, =PG_UP_TAG_AVP + + @ are we the CPU? + ldr sp, CPU_STACK + cmp r1, r2 + @ yep, we are the CPU + bne _armboot_start + + @ AVP initialization follows this path + ldr sp, AVP_STACK + @ Init AVP and start CPU + b startup_cpu + @ the literal pools origin .ltorg SRAM_STACK: .word LOW_LEVEL_SRAM_STACK +AVP_STACK: + .word EARLY_AVP_STACK +CPU_STACK: + .word EARLY_CPU_STACK diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile index 49a6ed3..e8b59a3 100644 --- a/arch/arm/cpu/pxa/Makefile +++ b/arch/arm/cpu/pxa/Makefile @@ -28,7 +28,6 @@ LIB = $(obj)lib$(CPU).o START = start.o COBJS += cpu.o -COBJS += i2c.o COBJS += pxafb.o COBJS += timer.o COBJS += usb.o diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c index 7d49cbb..9970a4b 100644 --- a/arch/arm/cpu/pxa/cpu.c +++ b/arch/arm/cpu/pxa/cpu.c @@ -318,3 +318,13 @@ int arch_cpu_init(void) pxa_clock_setup(); return 0; } + +void i2c_clk_enable(void) +{ + /* set the global I2C clock on */ +#ifdef CONFIG_CPU_MONAHANS + writel(readl(CKENB) | (CKENB_4_I2C), CKENB); +#else + writel(readl(CKEN) | CKEN14_I2C, CKEN); +#endif +} diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c deleted file mode 100644 index 7aa49ae..0000000 --- a/arch/arm/cpu/pxa/i2c.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * (C) Copyright 2000 - * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it - * - * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * (C) Copyright 2003 Pengutronix e.K. - * Robert Schwebel <r.schwebel@pengutronix.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 - * - * Back ported to the 8xx platform (from the 8260 platform) by - * Murray.Jensen@cmst.csiro.au, 27-Jan-01. - */ - -/* FIXME: this file is PXA255 specific! What about other XScales? */ - -#include <common.h> -#include <asm/io.h> - -#ifdef CONFIG_HARD_I2C - -/* - * - CONFIG_SYS_I2C_SPEED - * - I2C_PXA_SLAVE_ADDR - */ - -#include <asm/arch/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <i2c.h> - -/*#define DEBUG_I2C 1 /###* activate local debugging output */ -#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ - -#if (CONFIG_SYS_I2C_SPEED == 400000) -#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) -#else -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) -#endif - -#define I2C_ISR_INIT 0x7FF - -#ifdef DEBUG_I2C -#define PRINTD(x) printf x -#else -#define PRINTD(x) -#endif - - -/* Shall the current transfer have a start/stop condition? */ -#define I2C_COND_NORMAL 0 -#define I2C_COND_START 1 -#define I2C_COND_STOP 2 - -/* Shall the current transfer be ack/nacked or being waited for it? */ -#define I2C_ACKNAK_WAITACK 1 -#define I2C_ACKNAK_SENDACK 2 -#define I2C_ACKNAK_SENDNAK 4 - -/* Specify who shall transfer the data (master or slave) */ -#define I2C_READ 0 -#define I2C_WRITE 1 - -/* All transfers are described by this data structure */ -struct i2c_msg { - u8 condition; - u8 acknack; - u8 direction; - u8 data; -}; - - -/** - * i2c_pxa_reset: - reset the host controller - * - */ - -static void i2c_reset( void ) -{ - writel(readl(ICR) & ~ICR_IUE, ICR); /* disable unit */ - writel(readl(ICR) | ICR_UR, ICR); /* reset the unit */ - udelay(100); - writel(readl(ICR) & ~ICR_IUE, ICR); /* disable unit */ -#ifdef CONFIG_CPU_MONAHANS - /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ - writel(readl(CKENB) | (CKENB_4_I2C), CKENB); -#else /* CONFIG_CPU_MONAHANS */ - /* set the global I2C clock on */ - writel(readl(CKEN) | CKEN14_I2C, CKEN); -#endif - writel(I2C_PXA_SLAVE_ADDR, ISAR); /* set our slave address */ - writel(I2C_ICR_INIT, ICR); /* set control reg values */ - writel(I2C_ISR_INIT, ISR); /* set clear interrupt bits */ - writel(readl(ICR) | ICR_IUE, ICR); /* enable unit */ - udelay(100); -} - - -/** - * i2c_isr_set_cleared: - wait until certain bits of the I2C status register - * are set and cleared - * - * @return: 1 in case of success, 0 means timeout (no match within 10 ms). - */ -static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask ) -{ - int timeout = 10000; - - while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){ - udelay( 10 ); - if( timeout-- < 0 ) return 0; - } - - return 1; -} - - -/** - * i2c_transfer: - Transfer one byte over the i2c bus - * - * This function can tranfer a byte over the i2c bus in both directions. - * It is used by the public API functions. - * - * @return: 0: transfer successful - * -1: message is empty - * -2: transmit timeout - * -3: ACK missing - * -4: receive timeout - * -5: illegal parameters - * -6: bus is busy and couldn't be aquired - */ -int i2c_transfer(struct i2c_msg *msg) -{ - int ret; - - if (!msg) - goto transfer_error_msg_empty; - - switch(msg->direction) { - - case I2C_WRITE: - - /* check if bus is not busy */ - if (!i2c_isr_set_cleared(0,ISR_IBB)) - goto transfer_error_bus_busy; - - /* start transmission */ - writel(readl(ICR) & ~ICR_START, ICR); - writel(readl(ICR) & ~ICR_STOP, ICR); - writel(msg->data, IDBR); - if (msg->condition == I2C_COND_START) - writel(readl(ICR) | ICR_START, ICR); - if (msg->condition == I2C_COND_STOP) - writel(readl(ICR) | ICR_STOP, ICR); - if (msg->acknack == I2C_ACKNAK_SENDNAK) - writel(readl(ICR) | ICR_ACKNAK, ICR); - if (msg->acknack == I2C_ACKNAK_SENDACK) - writel(readl(ICR) & ~ICR_ACKNAK, ICR); - writel(readl(ICR) & ~ICR_ALDIE, ICR); - writel(readl(ICR) | ICR_TB, ICR); - - /* transmit register empty? */ - if (!i2c_isr_set_cleared(ISR_ITE,0)) - goto transfer_error_transmit_timeout; - - /* clear 'transmit empty' state */ - writel(readl(ISR) | ISR_ITE, ISR); - - /* wait for ACK from slave */ - if (msg->acknack == I2C_ACKNAK_WAITACK) - if (!i2c_isr_set_cleared(0,ISR_ACKNAK)) - goto transfer_error_ack_missing; - break; - - case I2C_READ: - - /* check if bus is not busy */ - if (!i2c_isr_set_cleared(0,ISR_IBB)) - goto transfer_error_bus_busy; - - /* start receive */ - writel(readl(ICR) & ~ICR_START, ICR); - writel(readl(ICR) & ~ICR_STOP, ICR); - if (msg->condition == I2C_COND_START) - writel(readl(ICR) | ICR_START, ICR); - if (msg->condition == I2C_COND_STOP) - writel(readl(ICR) | ICR_STOP, ICR); - if (msg->acknack == I2C_ACKNAK_SENDNAK) - writel(readl(ICR) | ICR_ACKNAK, ICR); - if (msg->acknack == I2C_ACKNAK_SENDACK) - writel(readl(ICR) & ~ICR_ACKNAK, ICR); - writel(readl(ICR) & ~ICR_ALDIE, ICR); - writel(readl(ICR) | ICR_TB, ICR); - - /* receive register full? */ - if (!i2c_isr_set_cleared(ISR_IRF,0)) - goto transfer_error_receive_timeout; - - msg->data = readl(IDBR); - - /* clear 'receive empty' state */ - writel(readl(ISR) | ISR_IRF, ISR); - - break; - - default: - - goto transfer_error_illegal_param; - - } - - return 0; - -transfer_error_msg_empty: - PRINTD(("i2c_transfer: error: 'msg' is empty\n")); - ret = -1; goto i2c_transfer_finish; - -transfer_error_transmit_timeout: - PRINTD(("i2c_transfer: error: transmit timeout\n")); - ret = -2; goto i2c_transfer_finish; - -transfer_error_ack_missing: - PRINTD(("i2c_transfer: error: ACK missing\n")); - ret = -3; goto i2c_transfer_finish; - -transfer_error_receive_timeout: - PRINTD(("i2c_transfer: error: receive timeout\n")); - ret = -4; goto i2c_transfer_finish; - -transfer_error_illegal_param: - PRINTD(("i2c_transfer: error: illegal parameters\n")); - ret = -5; goto i2c_transfer_finish; - -transfer_error_bus_busy: - PRINTD(("i2c_transfer: error: bus is busy\n")); - ret = -6; goto i2c_transfer_finish; - -i2c_transfer_finish: - PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR)); - i2c_reset(); - return ret; - -} - -/* ------------------------------------------------------------------------ */ -/* API Functions */ -/* ------------------------------------------------------------------------ */ - -void i2c_init(int speed, int slaveaddr) -{ -#ifdef CONFIG_SYS_I2C_INIT_BOARD - /* call board specific i2c bus reset routine before accessing the */ - /* environment, which might be in a chip on that bus. For details */ - /* about this problem see doc/I2C_Edge_Conditions. */ - i2c_init_board(); -#endif -} - - -/** - * i2c_probe: - Test if a chip answers for a given i2c address - * - * @chip: address of the chip which is searched for - * @return: 0 if a chip was found, -1 otherwhise - */ - -int i2c_probe(uchar chip) -{ - struct i2c_msg msg; - - i2c_reset(); - - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1) + 1; - if (i2c_transfer(&msg)) return -1; - - msg.condition = I2C_COND_STOP; - msg.acknack = I2C_ACKNAK_SENDNAK; - msg.direction = I2C_READ; - msg.data = 0x00; - if (i2c_transfer(&msg)) return -1; - - return 0; -} - - -/** - * i2c_read: - Read multiple bytes from an i2c device - * - * The higher level routines take into account that this function is only - * called with len < page length of the device (see configuration file) - * - * @chip: address of the chip which is to be read - * @addr: i2c data address within the chip - * @alen: length of the i2c data address (1..2 bytes) - * @buffer: where to write the data - * @len: how much byte do we want to read - * @return: 0 in case of success - */ - -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - int ret; - - PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); - - i2c_reset(); - - /* dummy chip address write */ - PRINTD(("i2c_read: dummy chip address write\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data &= 0xFE; - if ((ret=i2c_transfer(&msg))) return -1; - - /* - * send memory address bytes; - * alen defines how much bytes we have to send. - */ - /*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */ - addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); - - while (--alen >= 0) { - - PRINTD(("i2c_read: send memory word address byte %1d\n",alen)); - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = addr_bytes[alen]; - if ((ret=i2c_transfer(&msg))) return -1; - } - - - /* start read sequence */ - PRINTD(("i2c_read: start read sequence\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data |= 0x01; - if ((ret=i2c_transfer(&msg))) return -1; - - /* read bytes; send NACK at last byte */ - while (len--) { - - if (len==0) { - msg.condition = I2C_COND_STOP; - msg.acknack = I2C_ACKNAK_SENDNAK; - } else { - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_SENDACK; - } - - msg.direction = I2C_READ; - msg.data = 0x00; - if ((ret=i2c_transfer(&msg))) return -1; - - *buffer = msg.data; - PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); - buffer++; - - } - - i2c_reset(); - - return 0; -} - - -/** - * i2c_write: - Write multiple bytes to an i2c device - * - * The higher level routines take into account that this function is only - * called with len < page length of the device (see configuration file) - * - * @chip: address of the chip which is to be written - * @addr: i2c data address within the chip - * @alen: length of the i2c data address (1..2 bytes) - * @buffer: where to find the data to be written - * @len: how much byte do we want to read - * @return: 0 in case of success - */ - -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - - PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); - - i2c_reset(); - - /* chip address write */ - PRINTD(("i2c_write: chip address write\n")); - msg.condition = I2C_COND_START; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = (chip << 1); - msg.data &= 0xFE; - if (i2c_transfer(&msg)) return -1; - - /* - * send memory address bytes; - * alen defines how much bytes we have to send. - */ - addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); - - while (--alen >= 0) { - - PRINTD(("i2c_write: send memory word address\n")); - msg.condition = I2C_COND_NORMAL; - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = addr_bytes[alen]; - if (i2c_transfer(&msg)) return -1; - } - - /* write bytes; send NACK at last byte */ - while (len--) { - - PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); - - if (len==0) - msg.condition = I2C_COND_STOP; - else - msg.condition = I2C_COND_NORMAL; - - msg.acknack = I2C_ACKNAK_WAITACK; - msg.direction = I2C_WRITE; - msg.data = *(buffer++); - - if (i2c_transfer(&msg)) return -1; - - } - - i2c_reset(); - - return 0; - -} - -#endif /* CONFIG_HARD_I2C */ diff --git a/arch/arm/include/asm/arch-a320/ftsdmc020.h b/arch/arm/include/asm/arch-a320/ftsdmc020.h deleted file mode 100644 index 0699772..0000000 --- a/arch/arm/include/asm/arch-a320/ftsdmc020.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * SDRAM Controller - */ -#ifndef __FTSDMC020_H -#define __FTSDMC020_H - -#define FTSDMC020_OFFSET_TP0 0x00 -#define FTSDMC020_OFFSET_TP1 0x04 -#define FTSDMC020_OFFSET_CR 0x08 -#define FTSDMC020_OFFSET_BANK0_BSR 0x0C -#define FTSDMC020_OFFSET_BANK1_BSR 0x10 -#define FTSDMC020_OFFSET_BANK2_BSR 0x14 -#define FTSDMC020_OFFSET_BANK3_BSR 0x18 -#define FTSDMC020_OFFSET_BANK4_BSR 0x1C -#define FTSDMC020_OFFSET_BANK5_BSR 0x20 -#define FTSDMC020_OFFSET_BANK6_BSR 0x24 -#define FTSDMC020_OFFSET_BANK7_BSR 0x28 -#define FTSDMC020_OFFSET_ACR 0x34 - -/* - * Timing Parametet 0 Register - */ -#define FTSDMC020_TP0_TCL(x) ((x) & 0x3) -#define FTSDMC020_TP0_TWR(x) (((x) & 0x3) << 4) -#define FTSDMC020_TP0_TRF(x) (((x) & 0xf) << 8) -#define FTSDMC020_TP0_TRCD(x) (((x) & 0x7) << 12) -#define FTSDMC020_TP0_TRP(x) (((x) & 0xf) << 16) -#define FTSDMC020_TP0_TRAS(x) (((x) & 0xf) << 20) - -/* - * Timing Parametet 1 Register - */ -#define FTSDMC020_TP1_REF_INTV(x) ((x) & 0xffff) -#define FTSDMC020_TP1_INI_REFT(x) (((x) & 0xf) << 16) -#define FTSDMC020_TP1_INI_PREC(x) (((x) & 0xf) << 20) - -/* - * Configuration Register - */ -#define FTSDMC020_CR_SREF (1 << 0) -#define FTSDMC020_CR_PWDN (1 << 1) -#define FTSDMC020_CR_ISMR (1 << 2) -#define FTSDMC020_CR_IREF (1 << 3) -#define FTSDMC020_CR_IPREC (1 << 4) -#define FTSDMC020_CR_REFTYPE (1 << 5) - -/* - * SDRAM External Bank Base/Size Register - */ -#define FTSDMC020_BANK_ENABLE (1 << 28) - -#define FTSDMC020_BANK_BASE(addr) (((addr) >> 20) << 16) - -#define FTSDMC020_BANK_DDW_X4 (0 << 12) -#define FTSDMC020_BANK_DDW_X8 (1 << 12) -#define FTSDMC020_BANK_DDW_X16 (2 << 12) -#define FTSDMC020_BANK_DDW_X32 (3 << 12) - -#define FTSDMC020_BANK_DSZ_16M (0 << 8) -#define FTSDMC020_BANK_DSZ_64M (1 << 8) -#define FTSDMC020_BANK_DSZ_128M (2 << 8) -#define FTSDMC020_BANK_DSZ_256M (3 << 8) - -#define FTSDMC020_BANK_MBW_8 (0 << 4) -#define FTSDMC020_BANK_MBW_16 (1 << 4) -#define FTSDMC020_BANK_MBW_32 (2 << 4) - -#define FTSDMC020_BANK_SIZE_1M 0x0 -#define FTSDMC020_BANK_SIZE_2M 0x1 -#define FTSDMC020_BANK_SIZE_4M 0x2 -#define FTSDMC020_BANK_SIZE_8M 0x3 -#define FTSDMC020_BANK_SIZE_16M 0x4 -#define FTSDMC020_BANK_SIZE_32M 0x5 -#define FTSDMC020_BANK_SIZE_64M 0x6 -#define FTSDMC020_BANK_SIZE_128M 0x7 -#define FTSDMC020_BANK_SIZE_256M 0x8 - -/* - * Arbiter Control Register - */ -#define FTSDMC020_ACR_TOC(x) ((x) & 0x1f) -#define FTSDMC020_ACR_TOE (1 << 8) - -#endif /* __FTSDMC020_H */ diff --git a/arch/arm/include/asm/arch-a320/ftsmc020.h b/arch/arm/include/asm/arch-a320/ftsmc020.h deleted file mode 100644 index 95d9500..0000000 --- a/arch/arm/include/asm/arch-a320/ftsmc020.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Static Memory Controller - */ -#ifndef __FTSMC020_H -#define __FTSMC020_H - -#ifndef __ASSEMBLY__ - -struct ftsmc020 { - struct { - unsigned int cr; /* 0x00, 0x08, 0x10, 0x18 */ - unsigned int tpr; /* 0x04, 0x0c, 0x14, 0x1c */ - } bank[4]; - unsigned int pad[8]; /* 0x20 - 0x3c */ - unsigned int ssr; /* 0x40 */ -}; - -void ftsmc020_init(void); - -#endif /* __ASSEMBLY__ */ - -/* - * Memory Bank Configuration Register - */ -#define FTSMC020_BANK_ENABLE (1 << 28) -#define FTSMC020_BANK_BASE(x) ((x) & 0x0fff1000) - -#define FTSMC020_BANK_WPROT (1 << 11) - -#define FTSMC020_BANK_SIZE_32K (0xb << 4) -#define FTSMC020_BANK_SIZE_64K (0xc << 4) -#define FTSMC020_BANK_SIZE_128K (0xd << 4) -#define FTSMC020_BANK_SIZE_256K (0xe << 4) -#define FTSMC020_BANK_SIZE_512K (0xf << 4) -#define FTSMC020_BANK_SIZE_1M (0x0 << 4) -#define FTSMC020_BANK_SIZE_2M (0x1 << 4) -#define FTSMC020_BANK_SIZE_4M (0x2 << 4) -#define FTSMC020_BANK_SIZE_8M (0x3 << 4) -#define FTSMC020_BANK_SIZE_16M (0x4 << 4) -#define FTSMC020_BANK_SIZE_32M (0x5 << 4) - -#define FTSMC020_BANK_MBW_8 (0x0 << 0) -#define FTSMC020_BANK_MBW_16 (0x1 << 0) -#define FTSMC020_BANK_MBW_32 (0x2 << 0) - -/* - * Memory Bank Timing Parameter Register - */ -#define FTSMC020_TPR_ETRNA(x) (((x) & 0xf) << 28) -#define FTSMC020_TPR_EATI(x) (((x) & 0xf) << 24) -#define FTSMC020_TPR_RBE (1 << 20) -#define FTSMC020_TPR_AST(x) (((x) & 0x3) << 18) -#define FTSMC020_TPR_CTW(x) (((x) & 0x3) << 16) -#define FTSMC020_TPR_ATI(x) (((x) & 0xf) << 12) -#define FTSMC020_TPR_AT2(x) (((x) & 0x3) << 8) -#define FTSMC020_TPR_WTC(x) (((x) & 0x3) << 6) -#define FTSMC020_TPR_AHT(x) (((x) & 0x3) << 4) -#define FTSMC020_TPR_TRNA(x) (((x) & 0xf) << 0) - -#endif /* __FTSMC020_H */ diff --git a/arch/arm/include/asm/arch-a320/fttmr010.h b/arch/arm/include/asm/arch-a320/fttmr010.h deleted file mode 100644 index 72abcb3..0000000 --- a/arch/arm/include/asm/arch-a320/fttmr010.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Timer - */ -#ifndef __FTTMR010_H -#define __FTTMR010_H - -struct fttmr010 { - unsigned int timer1_counter; /* 0x00 */ - unsigned int timer1_load; /* 0x04 */ - unsigned int timer1_match1; /* 0x08 */ - unsigned int timer1_match2; /* 0x0c */ - unsigned int timer2_counter; /* 0x10 */ - unsigned int timer2_load; /* 0x14 */ - unsigned int timer2_match1; /* 0x18 */ - unsigned int timer2_match2; /* 0x1c */ - unsigned int timer3_counter; /* 0x20 */ - unsigned int timer3_load; /* 0x24 */ - unsigned int timer3_match1; /* 0x28 */ - unsigned int timer3_match2; /* 0x2c */ - unsigned int cr; /* 0x30 */ - unsigned int interrupt_state; /* 0x34 */ - unsigned int interrupt_mask; /* 0x38 */ -}; - -/* - * Timer Control Register - */ -#define FTTMR010_TM3_UPDOWN (1 << 11) -#define FTTMR010_TM2_UPDOWN (1 << 10) -#define FTTMR010_TM1_UPDOWN (1 << 9) -#define FTTMR010_TM3_OFENABLE (1 << 8) -#define FTTMR010_TM3_CLOCK (1 << 7) -#define FTTMR010_TM3_ENABLE (1 << 6) -#define FTTMR010_TM2_OFENABLE (1 << 5) -#define FTTMR010_TM2_CLOCK (1 << 4) -#define FTTMR010_TM2_ENABLE (1 << 3) -#define FTTMR010_TM1_OFENABLE (1 << 2) -#define FTTMR010_TM1_CLOCK (1 << 1) -#define FTTMR010_TM1_ENABLE (1 << 0) - -/* - * Timer Interrupt State & Mask Registers - */ -#define FTTMR010_TM3_OVERFLOW (1 << 8) -#define FTTMR010_TM3_MATCH2 (1 << 7) -#define FTTMR010_TM3_MATCH1 (1 << 6) -#define FTTMR010_TM2_OVERFLOW (1 << 5) -#define FTTMR010_TM2_MATCH2 (1 << 4) -#define FTTMR010_TM2_MATCH1 (1 << 3) -#define FTTMR010_TM1_OVERFLOW (1 << 2) -#define FTTMR010_TM1_MATCH2 (1 << 1) -#define FTTMR010_TM1_MATCH1 (1 << 0) - -#endif /* __FTTMR010_H */ diff --git a/arch/arm/include/asm/arch-armada100/config.h b/arch/arm/include/asm/arch-armada100/config.h index d804002..1126b38 100644 --- a/arch/arm/include/asm/arch-armada100/config.h +++ b/arch/arm/include/asm/arch-armada100/config.h @@ -40,5 +40,17 @@ #define MV_UART_CONSOLE_BASE ARMD1_UART1_BASE #define CONFIG_SYS_NS16550_IER (1 << 6) /* Bit 6 in UART_IER register represents UART Unit Enable */ +/* + * I2C definition + */ +#ifdef CONFIG_CMD_I2C +#define CONFIG_I2C_MV 1 +#define CONFIG_MV_I2C_NUM 2 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_MV_I2C_REG {0xd4011000, 0xd4025000} +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 0 +#define CONFIG_SYS_I2C_SLAVE 0xfe +#endif #endif /* _ARMD1_CONFIG_H */ diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h index d21a79f..73783a7 100644 --- a/arch/arm/include/asm/arch-armada100/mfp.h +++ b/arch/arm/include/asm/arch-armada100/mfp.h @@ -37,28 +37,32 @@ * offset, pull,pF, drv,dF, edge,eF ,afn,aF */ /* UART1 */ -#define MFP107_UART1_TXD MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST -#define MFP107_UART1_RXD MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST -#define MFP108_UART1_RXD MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST -#define MFP108_UART1_TXD MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST -#define MFP109_UART1_CTS MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM -#define MFP109_UART1_RTS MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM -#define MFP110_UART1_RTS MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM -#define MFP110_UART1_CTS MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM -#define MFP111_UART1_RI MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM -#define MFP111_UART1_DSR MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM -#define MFP112_UART1_DTR MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM -#define MFP112_UART1_DCD MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM +#define MFP107_UART1_TXD (MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST) +#define MFP107_UART1_RXD (MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST) +#define MFP108_UART1_RXD (MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST) +#define MFP108_UART1_TXD (MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST) +#define MFP109_UART1_CTS (MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM) +#define MFP109_UART1_RTS (MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFP110_UART1_RTS (MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM) +#define MFP110_UART1_CTS (MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFP111_UART1_RI (MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM) +#define MFP111_UART1_DSR (MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFP112_UART1_DTR (MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM) +#define MFP112_UART1_DCD (MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM) /* UART2 */ -#define MFP47_UART2_RXD MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM -#define MFP48_UART2_TXD MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM -#define MFP88_UART2_RXD MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM -#define MFP89_UART2_TXD MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM +#define MFP47_UART2_RXD (MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM) +#define MFP48_UART2_TXD (MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM) +#define MFP88_UART2_RXD (MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFP89_UART2_TXD (MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM) /* UART3 */ -#define MFPO8_UART3_RXD MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM -#define MFPO9_UART3_TXD MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM +#define MFPO8_UART3_RXD (MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFPO9_UART3_TXD (MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM) + +/* I2c */ +#define MFP105_CI2C_SDA (MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM) +#define MFP106_CI2C_SCL (MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM) /* More macros can be defined here... */ diff --git a/arch/arm/include/asm/arch-mx31/mx31.h b/arch/arm/include/asm/arch-mx31/clock.h index a755212..8dc6e82 100644 --- a/arch/arm/include/asm/arch-mx31/mx31.h +++ b/arch/arm/include/asm/arch-mx31/clock.h @@ -21,8 +21,8 @@ * MA 02111-1307 USA */ -#ifndef __ASM_ARCH_MX31_H -#define __ASM_ARCH_MX31_H +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H extern u32 mx31_get_ipg_clk(void); #define imx_get_uartclk mx31_get_ipg_clk @@ -32,4 +32,4 @@ extern void mx31_set_pad(enum iomux_pins pin, u32 config); void mx31_uart1_hw_init(void); void mx31_spi2_hw_init(void); -#endif /* __ASM_ARCH_MX31_H */ +#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/include/asm/arch-mx31/mx31-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h index 105f7d8..c830a03 100644 --- a/arch/arm/include/asm/arch-mx31/mx31-regs.h +++ b/arch/arm/include/asm/arch-mx31/imx-regs.h @@ -21,8 +21,8 @@ * MA 02111-1307 USA */ -#ifndef __ASM_ARCH_MX31_REGS_H -#define __ASM_ARCH_MX31_REGS_H +#ifndef __ASM_ARCH_MX31_IMX_REGS_H +#define __ASM_ARCH_MX31_IMX_REGS_H #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> @@ -75,6 +75,39 @@ struct cspi_regs { u32 test; }; +/* Watchdog Timer (WDOG) registers */ +#define WDOG_ENABLE (1 << 2) +#define WDOG_WT_SHIFT 8 +struct wdog_regs { + u16 wcr; /* Control */ + u16 wsr; /* Service */ + u16 wrsr; /* Reset Status */ +}; + +/* IIM Control Registers */ +struct iim_regs { + u32 iim_stat; + u32 iim_statm; + u32 iim_err; + u32 iim_emask; + u32 iim_fctl; + u32 iim_ua; + u32 iim_la; + u32 iim_sdat; + u32 iim_prev; + u32 iim_srev; + u32 iim_prog_p; + u32 iim_scs0; + u32 iim_scs1; + u32 iim_scs2; + u32 iim_scs3; +}; + +struct mx3_cpu_type { + u8 srev; + char *v; +}; + #define IOMUX_PADNUM_MASK 0x1ff #define IOMUX_PIN(gpionum, padnum) ((padnum) & IOMUX_PADNUM_MASK) @@ -470,6 +503,8 @@ enum iomux_pins { #define CCMR_FPM (1 << 1) #define CCMR_CKIH (2 << 1) +#define MX31_IIM_BASE_ADDR 0x5001C000 + #define PDR0_CSI_PODF(x) (((x) & 0x1ff) << 23) #define PDR0_PER_PODF(x) (((x) & 0x1f) << 16) #define PDR0_HSP_PODF(x) (((x) & 0x7) << 11) @@ -739,4 +774,4 @@ enum iomux_pins { #define MXC_EHCI_IPPUE_DOWN (1 << 8) #define MXC_EHCI_IPPUE_UP (1 << 9) -#endif /* __ASM_ARCH_MX31_REGS_H */ +#endif /* __ASM_ARCH_MX31_IMX_REGS_H */ diff --git a/arch/arm/include/asm/arch-omap3/clocks.h b/arch/arm/include/asm/arch-omap3/clocks.h index 40f80ba..bed0002 100644 --- a/arch/arm/include/asm/arch-omap3/clocks.h +++ b/arch/arm/include/asm/arch-omap3/clocks.h @@ -68,6 +68,7 @@ extern dpll_param *get_mpu_dpll_param(void); extern dpll_param *get_iva_dpll_param(void); extern dpll_param *get_core_dpll_param(void); extern dpll_param *get_per_dpll_param(void); +extern dpll_param *get_per2_dpll_param(void); extern dpll_param *get_36x_mpu_dpll_param(void); extern dpll_param *get_36x_iva_dpll_param(void); diff --git a/arch/arm/include/asm/arch-omap3/clocks_omap3.h b/arch/arm/include/asm/arch-omap3/clocks_omap3.h index 30ef690..ef600dd 100644 --- a/arch/arm/include/asm/arch-omap3/clocks_omap3.h +++ b/arch/arm/include/asm/arch-omap3/clocks_omap3.h @@ -282,6 +282,32 @@ #define PER_FSEL_38P4 0x07 #define PER_M2_38P4 0x09 +/* PER2 DPLL */ +#define PER2_M_12 0x78 +#define PER2_N_12 0x0B +#define PER2_FSEL_12 0x03 +#define PER2_M2_12 0x01 + +#define PER2_M_13 0x78 +#define PER2_N_13 0x0C +#define PER2_FSEL_13 0x03 +#define PER2_M2_13 0x01 + +#define PER2_M_19P2 0x2EE +#define PER2_N_19P2 0x0B +#define PER2_FSEL_19P2 0x06 +#define PER2_M2_19P2 0x0A + +#define PER2_M_26 0x78 +#define PER2_N_26 0x0C +#define PER2_FSEL_26 0x03 +#define PER2_M2_26 0x01 + +#define PER2_M_38P4 0x2EE +#define PER2_N_38P4 0x0B +#define PER2_FSEL_38P4 0x06 +#define PER2_M2_38P4 0x0A + /* 36XX PER DPLL */ #define PER_36XX_M_12 0x1B0 diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h index 962d6d4..e944de7 100644 --- a/arch/arm/include/asm/arch-omap3/cpu.h +++ b/arch/arm/include/asm/arch-omap3/cpu.h @@ -347,10 +347,13 @@ struct prcm { u32 clksel2_pll_mpu; /* 0x944 */ u8 res6[0xb8]; u32 fclken1_core; /* 0xa00 */ - u8 res7[0xc]; + u32 res_fclken2_core; + u32 fclken3_core; /* 0xa08 */ + u8 res7[0x4]; u32 iclken1_core; /* 0xa10 */ u32 iclken2_core; /* 0xa14 */ - u8 res8[0x28]; + u32 iclken3_core; /* 0xa18 */ + u8 res8[0x24]; u32 clksel_core; /* 0xa40 */ u8 res9[0xbc]; u32 fclken_gfx; /* 0xb00 */ @@ -368,13 +371,17 @@ struct prcm { u32 clksel_wkup; /* 0xc40 */ u8 res16[0xbc]; u32 clken_pll; /* 0xd00 */ - u8 res17[0x1c]; + u32 clken2_pll; /* 0xd04 */ + u8 res17[0x18]; u32 idlest_ckgen; /* 0xd20 */ - u8 res18[0x1c]; + u32 idlest2_ckgen; /* 0xd24 */ + u8 res18[0x18]; u32 clksel1_pll; /* 0xd40 */ u32 clksel2_pll; /* 0xd44 */ u32 clksel3_pll; /* 0xd48 */ - u8 res19[0xb4]; + u32 clksel4_pll; /* 0xd4c */ + u32 clksel5_pll; /* 0xd50 */ + u8 res19[0xac]; u32 fclken_dss; /* 0xe00 */ u8 res20[0xc]; u32 iclken_dss; /* 0xe10 */ @@ -394,6 +401,10 @@ struct prcm { u32 clksel_per; /* 0x1040 */ u8 res28[0xfc]; u32 clksel1_emu; /* 0x1140 */ + u8 res29[0x2bc]; + u32 fclken_usbhost; /* 0x1400 */ + u8 res30[0xc]; + u32 iclken_usbhost; /* 0x1410 */ }; #else /* __ASSEMBLY__ */ #define CM_CLKSEL_CORE 0x48004a40 diff --git a/arch/arm/include/asm/arch-omap3/ehci_omap3.h b/arch/arm/include/asm/arch-omap3/ehci_omap3.h new file mode 100644 index 0000000..cd01f50 --- /dev/null +++ b/arch/arm/include/asm/arch-omap3/ehci_omap3.h @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2011 + * Alexander Holler <holler@ahsoftware.de> + * + * Based on "drivers/usb/host/ehci-omap.c" from Linux 2.6.37 + * + * See there for additional Copyrights. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +#ifndef _EHCI_OMAP3_H_ +#define _EHCI_OMAP3_H_ + +/* USB/EHCI registers */ +#define OMAP3_USBTLL_BASE 0x48062000UL +#define OMAP3_UHH_BASE 0x48064000UL +#define OMAP3_EHCI_BASE 0x48064800UL + +/* TLL Register Set */ +#define OMAP_USBTLL_SYSCONFIG (0x10) +#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) +#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) +#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) +#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) + +#define OMAP_USBTLL_SYSSTATUS (0x14) +#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) + +/* UHH Register Set */ +#define OMAP_UHH_SYSCONFIG (0x10) +#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) +#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) +#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) +#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) +#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) + +#define OMAP_UHH_HOSTCONFIG (0x40) +#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) +#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) +#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) + +#endif /* _EHCI_OMAP3_H_ */ diff --git a/arch/arm/include/asm/arch-omap3/omap3-regs.h b/arch/arm/include/asm/arch-omap3/omap3-regs.h new file mode 100644 index 0000000..818214f --- /dev/null +++ b/arch/arm/include/asm/arch-omap3/omap3-regs.h @@ -0,0 +1,95 @@ +/* + * (c) 2011 Comelit Group SpA, Luca Ceresoli <luca.ceresoli@comelit.it> + * + * 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 _OMAP3_REGS_H +#define _OMAP3_REGS_H + +/* + * Register definitions for OMAP3 processors. + */ + +/* + * GPMC_CONFIG1 - GPMC_CONFIG7 + */ + +/* Values for GPMC_CONFIG1 - signal control parameters */ +#define WRAPBURST (1 << 31) +#define READMULTIPLE (1 << 30) +#define READTYPE (1 << 29) +#define WRITEMULTIPLE (1 << 28) +#define WRITETYPE (1 << 27) +#define CLKACTIVATIONTIME(x) (((x) & 3) << 25) +#define ATTACHEDDEVICEPAGELENGTH(x) (((x) & 3) << 23) +#define WAITREADMONITORING (1 << 22) +#define WAITWRITEMONITORING (1 << 21) +#define WAITMONITORINGTIME(x) (((x) & 3) << 18) +#define WAITPINSELECT(x) (((x) & 3) << 16) +#define DEVICESIZE(x) (((x) & 3) << 12) +#define DEVICESIZE_8BIT DEVICESIZE(0) +#define DEVICESIZE_16BIT DEVICESIZE(1) +#define DEVICETYPE(x) (((x) & 3) << 10) +#define DEVICETYPE_NOR DEVICETYPE(0) +#define DEVICETYPE_NAND DEVICETYPE(2) +#define MUXADDDATA (1 << 9) +#define TIMEPARAGRANULARITY (1 << 4) +#define GPMCFCLKDIVIDER(x) (((x) & 3) << 0) + +/* Values for GPMC_CONFIG2 - CS timing */ +#define CSWROFFTIME(x) (((x) & 0x1f) << 16) +#define CSRDOFFTIME(x) (((x) & 0x1f) << 8) +#define CSEXTRADELAY (1 << 7) +#define CSONTIME(x) (((x) & 0xf) << 0) + +/* Values for GPMC_CONFIG3 - nADV timing */ +#define ADVWROFFTIME(x) (((x) & 0x1f) << 16) +#define ADVRDOFFTIME(x) (((x) & 0x1f) << 8) +#define ADVEXTRADELAY (1 << 7) +#define ADVONTIME(x) (((x) & 0xf) << 0) + +/* Values for GPMC_CONFIG4 - nWE and nOE timing */ +#define WEOFFTIME(x) (((x) & 0x1f) << 24) +#define WEEXTRADELAY (1 << 23) +#define WEONTIME(x) (((x) & 0xf) << 16) +#define OEOFFTIME(x) (((x) & 0x1f) << 8) +#define OEEXTRADELAY (1 << 7) +#define OEONTIME(x) (((x) & 0xf) << 0) + +/* Values for GPMC_CONFIG5 - RdAccessTime and CycleTime timing */ +#define PAGEBURSTACCESSTIME(x) (((x) & 0xf) << 24) +#define RDACCESSTIME(x) (((x) & 0x1f) << 16) +#define WRCYCLETIME(x) (((x) & 0x1f) << 8) +#define RDCYCLETIME(x) (((x) & 0x1f) << 0) + +/* Values for GPMC_CONFIG6 - misc timings */ +#define WRACCESSTIME(x) (((x) & 0x1f) << 24) +#define WRDATAONADMUXBUS(x) (((x) & 0xf) << 16) +#define CYCLE2CYCLEDELAY(x) (((x) & 0xf) << 8) +#define CYCLE2CYCLESAMECSEN (1 << 7) +#define CYCLE2CYCLEDIFFCSEN (1 << 6) +#define BUSTURNAROUND(x) (((x) & 0xf) << 0) + +/* Values for GPMC_CONFIG7 - CS address mapping configuration */ +#define MASKADDRESS(x) (((x) & 0xf) << 8) +#define CSVALID (1 << 6) +#define BASEADDRESS(x) (((x) & 0x3f) << 0) + +#endif /* _OMAP3_REGS_H */ diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h index 3957c79..cc2b541 100644 --- a/arch/arm/include/asm/arch-omap3/omap3.h +++ b/arch/arm/include/asm/arch-omap3/omap3.h @@ -50,6 +50,20 @@ /* CONTROL */ #define OMAP34XX_CTRL_BASE (OMAP34XX_L4_IO_BASE + 0x2000) +#ifndef __ASSEMBLY__ +/* Signal Integrity Parameter Control Registers */ +struct control_prog_io { + unsigned char res[0x408]; + unsigned int io2; /* 0x408 */ + unsigned char res2[0x38]; + unsigned int io0; /* 0x444 */ + unsigned int io1; /* 0x448 */ +}; +#endif /* __ASSEMBLY__ */ + +/* Bit definition for CONTROL_PROG_IO1 */ +#define PRG_I2C2_PULLUPRESX 0x00000001 + /* UART */ #define OMAP34XX_UART1 (OMAP34XX_L4_IO_BASE + 0x6a000) #define OMAP34XX_UART2 (OMAP34XX_L4_IO_BASE + 0x6c000) diff --git a/arch/arm/include/asm/arch-orion5x/cpu.h b/arch/arm/include/asm/arch-orion5x/cpu.h index c84efaf..2f52ca8 100644 --- a/arch/arm/include/asm/arch-orion5x/cpu.h +++ b/arch/arm/include/asm/arch-orion5x/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirorion5x_ood support which is * (C) Copyright 2009 diff --git a/arch/arm/include/asm/arch-orion5x/mv88f5182.h b/arch/arm/include/asm/arch-orion5x/mv88f5182.h index 86ba08d..0b46aef 100644 --- a/arch/arm/include/asm/arch-orion5x/mv88f5182.h +++ b/arch/arm/include/asm/arch-orion5x/mv88f5182.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirkwood 88F6182 support which is * (C) Copyright 2009 diff --git a/arch/arm/include/asm/arch-orion5x/orion5x.h b/arch/arm/include/asm/arch-orion5x/orion5x.h index e3d3f76..9aeef88 100644 --- a/arch/arm/include/asm/arch-orion5x/orion5x.h +++ b/arch/arm/include/asm/arch-orion5x/orion5x.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr> + * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net> * * Based on original Kirkwood support which is * (C) Copyright 2009 @@ -42,6 +42,7 @@ #define ORION5X_REGISTER(x) (ORION5X_REGS_PHY_BASE + x) /* Documented registers */ +#define ORION5X_DRAM_BASE (ORION5X_REGISTER(0x01500)) #define ORION5X_TWSI_BASE (ORION5X_REGISTER(0x11000)) #define ORION5X_UART0_BASE (ORION5X_REGISTER(0x12000)) #define ORION5X_UART1_BASE (ORION5X_REGISTER(0x12100)) diff --git a/arch/arm/include/asm/arch-pantheon/config.h b/arch/arm/include/asm/arch-pantheon/config.h index 710b386..5658592 100644 --- a/arch/arm/include/asm/arch-pantheon/config.h +++ b/arch/arm/include/asm/arch-pantheon/config.h @@ -34,5 +34,15 @@ #define MV_UART_CONSOLE_BASE PANTHEON_UART1_BASE #define CONFIG_SYS_NS16550_IER (1 << 6) /* Bit 6 in UART_IER register represents UART Unit Enable */ +/* + * I2C definition + */ +#ifdef CONFIG_CMD_I2C +#define CONFIG_I2C_MV 1 +#define CONFIG_MV_I2C_REG 0xd4011000 +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 0 +#define CONFIG_SYS_I2C_SLAVE 0xfe +#endif #endif /* _PANTHEON_CONFIG_H */ diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h index 30f4393..60955c5 100644 --- a/arch/arm/include/asm/arch-pantheon/cpu.h +++ b/arch/arm/include/asm/arch-pantheon/cpu.h @@ -50,7 +50,9 @@ struct panthapb_registers { u32 uart0; /*0x000*/ u32 uart1; /*0x004*/ u32 gpio; /*0x008*/ - u8 pad0[0x034 - 0x08 - 4]; + u8 pad0[0x02c - 0x08 - 4]; + u32 twsi; /*0x02c*/ + u8 pad1[0x034 - 0x2c - 4]; u32 timers; /*0x034*/ }; diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h index fb291cf..e939196 100644 --- a/arch/arm/include/asm/arch-pantheon/mfp.h +++ b/arch/arm/include/asm/arch-pantheon/mfp.h @@ -32,8 +32,10 @@ * offset, pull,pF, drv,dF, edge,eF ,afn,aF */ /* UART2 */ -#define MFP47_UART2_RXD MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM -#define MFP48_UART2_TXD MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM +#define MFP47_UART2_RXD (MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM) +#define MFP48_UART2_TXD (MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM) +#define MFP53_CI2C_SCL (MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM) +#define MFP54_CI2C_SDA (MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM) /* More macros can be defined here... */ diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h index 65a387f..109fdc0 100644 --- a/arch/arm/include/asm/arch-pxa/pxa-regs.h +++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h @@ -456,62 +456,6 @@ typedef void (*ExcpHndlr) (void) ; IrSR_XMITIR_IR_MODE) /* - * I2C registers - */ -#define IBMR 0x40301680 /* I2C Bus Monitor Register - IBMR */ -#define IDBR 0x40301688 /* I2C Data Buffer Register - IDBR */ -#define ICR 0x40301690 /* I2C Control Register - ICR */ -#define ISR 0x40301698 /* I2C Status Register - ISR */ -#define ISAR 0x403016A0 /* I2C Slave Address Register - ISAR */ - -#ifdef CONFIG_CPU_MONAHANS -#define PWRIBMR 0x40f500C0 /* Power I2C Bus Monitor Register-IBMR */ -#define PWRIDBR 0x40f500C4 /* Power I2C Data Buffer Register-IDBR */ -#define PWRICR 0x40f500C8 /* Power I2C Control Register - ICR */ -#define PWRISR 0x40f500CC /* Power I2C Status Register - ISR */ -#define PWRISAR 0x40f500D0 /* Power I2C Slave Address Register-ISAR */ -#else -#define PWRIBMR 0x40f00180 /* Power I2C Bus Monitor Register-IBMR */ -#define PWRIDBR 0x40f00188 /* Power I2C Data Buffer Register-IDBR */ -#define PWRICR 0x40f00190 /* Power I2C Control Register - ICR */ -#define PWRISR 0x40f00198 /* Power I2C Status Register - ISR */ -#define PWRISAR 0x40f001A0 /* Power I2C Slave Address Register-ISAR */ -#endif - -/* ----- Control register bits ---------------------------------------- */ - -#define ICR_START 0x1 /* start bit */ -#define ICR_STOP 0x2 /* stop bit */ -#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */ -#define ICR_TB 0x8 /* transfer byte bit */ -#define ICR_MA 0x10 /* master abort */ -#define ICR_SCLE 0x20 /* master clock enable, mona SCLEA */ -#define ICR_IUE 0x40 /* unit enable */ -#define ICR_GCD 0x80 /* general call disable */ -#define ICR_ITEIE 0x100 /* enable tx interrupts */ -#define ICR_IRFIE 0x200 /* enable rx interrupts, mona: DRFIE */ -#define ICR_BEIE 0x400 /* enable bus error ints */ -#define ICR_SSDIE 0x800 /* slave STOP detected int enable */ -#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */ -#define ICR_SADIE 0x2000 /* slave address detected int enable */ -#define ICR_UR 0x4000 /* unit reset */ -#define ICR_FM 0x8000 /* Fast Mode */ - -/* ----- Status register bits ----------------------------------------- */ - -#define ISR_RWM 0x1 /* read/write mode */ -#define ISR_ACKNAK 0x2 /* ack/nak status */ -#define ISR_UB 0x4 /* unit busy */ -#define ISR_IBB 0x8 /* bus busy */ -#define ISR_SSD 0x10 /* slave stop detected */ -#define ISR_ALD 0x20 /* arbitration loss detected */ -#define ISR_ITE 0x40 /* tx buffer empty */ -#define ISR_IRF 0x80 /* rx buffer full */ -#define ISR_GCAD 0x100 /* general call address detected */ -#define ISR_SAD 0x200 /* slave address detected */ -#define ISR_BED 0x400 /* bus error no ACK/NAK */ - -/* * Serial Audio Controller */ /* FIXME the audio defines collide w/ the SA1111 defines. I don't like these diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h index 6d573bf..bd8ad2c 100644 --- a/arch/arm/include/asm/arch-tegra2/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h @@ -149,6 +149,9 @@ struct clk_rst_ctlr { uint crc_clk_src_csite; /*_CSITE_0, 0x1D4 */ uint crc_reserved19[9]; /* 0x1D8-1F8 */ uint crc_clk_src_osc; /*_OSC_0, 0x1FC */ + uint crc_reserved20[80]; /* 0x200-33C */ + uint crc_cpu_cmplx_set; /* _CPU_CMPLX_SET_0, 0x340 */ + uint crc_cpu_cmplx_clr; /* _CPU_CMPLX_CLR_0, 0x344 */ }; #define PLL_BYPASS (1 << 31) @@ -157,9 +160,35 @@ struct clk_rst_ctlr { #define PLL_DIVP (1 << 20) /* post divider, b22:20 */ #define PLL_DIVM 0x0C /* input divider, b4:0 */ -#define SWR_UARTD_RST (1 << 2) -#define CLK_ENB_UARTD (1 << 2) +#define SWR_UARTD_RST (1 << 1) +#define CLK_ENB_UARTD (1 << 1) #define SWR_UARTA_RST (1 << 6) #define CLK_ENB_UARTA (1 << 6) +#define SWR_CPU_RST (1 << 0) +#define CLK_ENB_CPU (1 << 0) +#define SWR_CSITE_RST (1 << 9) +#define CLK_ENB_CSITE (1 << 9) + +#define SET_CPURESET0 (1 << 0) +#define SET_DERESET0 (1 << 4) +#define SET_DBGRESET0 (1 << 12) + +#define SET_CPURESET1 (1 << 1) +#define SET_DERESET1 (1 << 5) +#define SET_DBGRESET1 (1 << 13) + +#define CLR_CPURESET0 (1 << 0) +#define CLR_DERESET0 (1 << 4) +#define CLR_DBGRESET0 (1 << 12) + +#define CLR_CPURESET1 (1 << 1) +#define CLR_DERESET1 (1 << 5) +#define CLR_DBGRESET1 (1 << 13) + +#define CPU0_CLK_STP (1 << 8) +#define CPU1_CLK_STP (1 << 9) + +#define CPCON (1 << 8) + #endif /* CLK_RST_H */ diff --git a/arch/arm/include/asm/arch-tegra2/gpio.h b/arch/arm/include/asm/arch-tegra2/gpio.h new file mode 100644 index 0000000..0fb8f0d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/gpio.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011, Google Inc. All rights reserved. + * 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 _TEGRA2_GPIO_H_ +#define _TEGRA2_GPIO_H_ + +/* + * The Tegra 2x GPIO controller has 222 GPIOs arranged in 8 banks of 4 ports, + * each with 8 GPIOs. + */ +#define TEGRA_GPIO_PORTS 4 /* The number of ports per bank */ +#define TEGRA_GPIO_BANKS 8 /* The number of banks */ + +/* GPIO Controller registers for a single bank */ +struct gpio_ctlr_bank { + uint gpio_config[TEGRA_GPIO_PORTS]; + uint gpio_dir_out[TEGRA_GPIO_PORTS]; + uint gpio_out[TEGRA_GPIO_PORTS]; + uint gpio_in[TEGRA_GPIO_PORTS]; + uint gpio_int_status[TEGRA_GPIO_PORTS]; + uint gpio_int_enable[TEGRA_GPIO_PORTS]; + uint gpio_int_level[TEGRA_GPIO_PORTS]; + uint gpio_int_clear[TEGRA_GPIO_PORTS]; +}; + +struct gpio_ctlr { + struct gpio_ctlr_bank gpio_bank[TEGRA_GPIO_BANKS]; +}; + +#define GPIO_BANK(x) ((x) >> 5) +#define GPIO_PORT(x) (((x) >> 3) & 0x3) +#define GPIO_BIT(x) ((x) & 0x7) + +/* + * GPIO_PI3 = Port I = 8, bit = 3. + * Seaboard: used for UART/SPI selection + * Harmony: not used + */ +#define GPIO_PI3 ((8 << 3) | 3) + +#endif /* TEGRA2_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra2/pmc.h b/arch/arm/include/asm/arch-tegra2/pmc.h index 7ec9eeb..b1d47cd 100644 --- a/arch/arm/include/asm/arch-tegra2/pmc.h +++ b/arch/arm/include/asm/arch-tegra2/pmc.h @@ -121,4 +121,12 @@ struct pmc_ctlr { uint pmc_gate; /* _GATE_0, offset 15C */ }; +#define CPU_PWRED 1 +#define CPU_CLMP 1 + +#define PARTID_CP 0xFFFFFFF8 +#define START_CP (1 << 8) + +#define CPUPWRREQ_OE (1 << 16) + #endif /* PMC_H */ diff --git a/arch/arm/include/asm/arch-tegra2/scu.h b/arch/arm/include/asm/arch-tegra2/scu.h new file mode 100644 index 0000000..787ded0 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/scu.h @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2010,2011 + * NVIDIA Corporation <www.nvidia.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 + */ + +#ifndef _SCU_H_ +#define _SCU_H_ + +/* ARM Snoop Control Unit (SCU) registers */ +struct scu_ctlr { + uint scu_ctrl; /* SCU Control Register, offset 00 */ + uint scu_cfg; /* SCU Config Register, offset 04 */ + uint scu_cpu_pwr_stat; /* SCU CPU Power Status Register, offset 08 */ + uint scu_inv_all; /* SCU Invalidate All Register, offset 0C */ + uint scu_reserved0[12]; /* reserved, offset 10-3C */ + uint scu_filt_start; /* SCU Filtering Start Address Reg, offset 40 */ + uint scu_filt_end; /* SCU Filtering End Address Reg, offset 44 */ + uint scu_reserved1[2]; /* reserved, offset 48-4C */ + uint scu_acc_ctl; /* SCU Access Control Register, offset 50 */ + uint scu_ns_acc_ctl; /* SCU Non-secure Access Cntrl Reg, offset 54 */ +}; + +#define SCU_CTRL_ENABLE (1 << 0) + +#endif /* SCU_H */ diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h index 9001b68..742a75a 100644 --- a/arch/arm/include/asm/arch-tegra2/tegra2.h +++ b/arch/arm/include/asm/arch-tegra2/tegra2.h @@ -25,8 +25,13 @@ #define _TEGRA2_H_ #define NV_PA_SDRAM_BASE 0x00000000 +#define NV_PA_ARM_PERIPHBASE 0x50040000 +#define NV_PA_PG_UP_BASE 0x60000000 #define NV_PA_TMRUS_BASE 0x60005010 #define NV_PA_CLK_RST_BASE 0x60006000 +#define NV_PA_FLOW_BASE 0x60007000 +#define NV_PA_GPIO_BASE 0x6000D000 +#define NV_PA_EVP_BASE 0x6000F000 #define NV_PA_APB_MISC_BASE 0x70000000 #define NV_PA_APB_UARTA_BASE (NV_PA_APB_MISC_BASE + 0x6000) #define NV_PA_APB_UARTB_BASE (NV_PA_APB_MISC_BASE + 0x6040) @@ -34,9 +39,13 @@ #define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300) #define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) #define NV_PA_PMC_BASE 0x7000E400 +#define NV_PA_CSITE_BASE 0x70040000 #define TEGRA2_SDRC_CS0 NV_PA_SDRAM_BASE #define LOW_LEVEL_SRAM_STACK 0x4000FFFC +#define EARLY_AVP_STACK (NV_PA_SDRAM_BASE + 0x20000) +#define EARLY_CPU_STACK (EARLY_AVP_STACK - 4096) +#define PG_UP_TAG_AVP 0xAAAAAAAA #ifndef __ASSEMBLY__ struct timerus { diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h new file mode 100644 index 0000000..5e4789b --- /dev/null +++ b/arch/arm/include/asm/assembler.h @@ -0,0 +1,60 @@ +/* + * arch/arm/include/asm/assembler.h + * + * Copyright (C) 1996-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains arm architecture specific defines + * for the different processors. + * + * Do not include any C declarations in this file - it is included by + * assembler source. + */ + +/* + * Endian independent macros for shifting bytes within registers. + */ +#ifndef __ARMEB__ +#define pull lsr +#define push lsl +#define get_byte_0 lsl #0 +#define get_byte_1 lsr #8 +#define get_byte_2 lsr #16 +#define get_byte_3 lsr #24 +#define put_byte_0 lsl #0 +#define put_byte_1 lsl #8 +#define put_byte_2 lsl #16 +#define put_byte_3 lsl #24 +#else +#define pull lsl +#define push lsr +#define get_byte_0 lsr #24 +#define get_byte_1 lsr #16 +#define get_byte_2 lsr #8 +#define get_byte_3 lsl #0 +#define put_byte_0 lsl #24 +#define put_byte_1 lsl #16 +#define put_byte_2 lsl #8 +#define put_byte_3 lsl #0 +#endif + +/* + * Data preload for architectures that support it + */ +#if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__) +#define PLD(code...) code +#else +#define PLD(code...) +#endif + +/* + * Cache alligned + */ +#define CALGN(code...) code diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index c3ea582..c6dfb25 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARM_STRING_H #define __ASM_ARM_STRING_H +#include <config.h> + /* * We don't do inline string functions, since the * optimised inline asm versions are not small. @@ -12,7 +14,9 @@ extern char * strrchr(const char * s, int c); #undef __HAVE_ARCH_STRCHR extern char * strchr(const char * s, int c); -#undef __HAVE_ARCH_MEMCPY +#ifdef CONFIG_USE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMCPY +#endif extern void * memcpy(void *, const void *, __kernel_size_t); #undef __HAVE_ARCH_MEMMOVE @@ -22,7 +26,9 @@ extern void * memmove(void *, const void *, __kernel_size_t); extern void * memchr(const void *, int, __kernel_size_t); #undef __HAVE_ARCH_MEMZERO -#undef __HAVE_ARCH_MEMSET +#ifdef CONFIG_USE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +#endif extern void * memset(void *, int, __kernel_size_t); #if 0 diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 454440c..03b1b5e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,8 @@ COBJS-y += cache-cp15.o endif COBJS-y += interrupts.o COBJS-y += reset.o +SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o +SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index dc46e21..1a784a1 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -356,9 +356,13 @@ void board_init_f (ulong bootflag) #endif /* CONFIG_VFD */ #ifdef CONFIG_LCD +#ifdef CONFIG_FB_ADDR + gd->fb_base = CONFIG_FB_ADDR; +#else /* reserve memory for LCD display (always full pages) */ addr = lcd_setmem (addr); gd->fb_base = addr; +#endif /* CONFIG_FB_ADDR */ #endif /* CONFIG_LCD */ /* @@ -399,7 +403,7 @@ void board_init_f (ulong bootflag) CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); #endif /* leave 3 words for abort-stack */ - addr_sp -= 3; + addr_sp -= 12; /* 8-byte alignment for ABI compliance */ addr_sp &= ~0x07; diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S new file mode 100644 index 0000000..40db90e --- /dev/null +++ b/arch/arm/lib/memcpy.S @@ -0,0 +1,241 @@ +/* + * linux/arch/arm/lib/memcpy.S + * + * Author: Nicolas Pitre + * Created: Sep 28, 2005 + * Copyright: MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <asm/assembler.h> + +#define W(instr) instr + +#define LDR1W_SHIFT 0 +#define STR1W_SHIFT 0 + + .macro ldr1w ptr reg abort + W(ldr) \reg, [\ptr], #4 + .endm + + .macro ldr4w ptr reg1 reg2 reg3 reg4 abort + ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4} + .endm + + .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort + ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8} + .endm + + .macro ldr1b ptr reg cond=al abort + ldr\cond\()b \reg, [\ptr], #1 + .endm + + .macro str1w ptr reg abort + W(str) \reg, [\ptr], #4 + .endm + + .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort + stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8} + .endm + + .macro str1b ptr reg cond=al abort + str\cond\()b \reg, [\ptr], #1 + .endm + + .macro enter reg1 reg2 + stmdb sp!, {r0, \reg1, \reg2} + .endm + + .macro exit reg1 reg2 + ldmfd sp!, {r0, \reg1, \reg2} + .endm + + .text + +/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */ + +.globl memcpy +memcpy: + + enter r4, lr + + subs r2, r2, #4 + blt 8f + ands ip, r0, #3 + PLD( pld [r1, #0] ) + bne 9f + ands ip, r1, #3 + bne 10f + +1: subs r2, r2, #(28) + stmfd sp!, {r5 - r8} + blt 5f + + CALGN( ands ip, r0, #31 ) + CALGN( rsb r3, ip, #32 ) + CALGN( sbcnes r4, r3, r2 ) @ C is always set here + CALGN( bcs 2f ) + CALGN( adr r4, 6f ) + CALGN( subs r2, r2, r3 ) @ C gets set + CALGN( add pc, r4, ip ) + + PLD( pld [r1, #0] ) +2: PLD( subs r2, r2, #96 ) + PLD( pld [r1, #28] ) + PLD( blt 4f ) + PLD( pld [r1, #60] ) + PLD( pld [r1, #92] ) + +3: PLD( pld [r1, #124] ) +4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f + subs r2, r2, #32 + str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f + bge 3b + PLD( cmn r2, #96 ) + PLD( bge 4b ) + +5: ands ip, r2, #28 + rsb ip, ip, #32 +#if LDR1W_SHIFT > 0 + lsl ip, ip, #LDR1W_SHIFT +#endif + addne pc, pc, ip @ C is always clear here + b 7f +6: + .rept (1 << LDR1W_SHIFT) + W(nop) + .endr + ldr1w r1, r3, abort=20f + ldr1w r1, r4, abort=20f + ldr1w r1, r5, abort=20f + ldr1w r1, r6, abort=20f + ldr1w r1, r7, abort=20f + ldr1w r1, r8, abort=20f + ldr1w r1, lr, abort=20f + +#if LDR1W_SHIFT < STR1W_SHIFT + lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT +#elif LDR1W_SHIFT > STR1W_SHIFT + lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT +#endif + add pc, pc, ip + nop + .rept (1 << STR1W_SHIFT) + W(nop) + .endr + str1w r0, r3, abort=20f + str1w r0, r4, abort=20f + str1w r0, r5, abort=20f + str1w r0, r6, abort=20f + str1w r0, r7, abort=20f + str1w r0, r8, abort=20f + str1w r0, lr, abort=20f + + CALGN( bcs 2b ) + +7: ldmfd sp!, {r5 - r8} + +8: movs r2, r2, lsl #31 + ldr1b r1, r3, ne, abort=21f + ldr1b r1, r4, cs, abort=21f + ldr1b r1, ip, cs, abort=21f + str1b r0, r3, ne, abort=21f + str1b r0, r4, cs, abort=21f + str1b r0, ip, cs, abort=21f + + exit r4, pc + +9: rsb ip, ip, #4 + cmp ip, #2 + ldr1b r1, r3, gt, abort=21f + ldr1b r1, r4, ge, abort=21f + ldr1b r1, lr, abort=21f + str1b r0, r3, gt, abort=21f + str1b r0, r4, ge, abort=21f + subs r2, r2, ip + str1b r0, lr, abort=21f + blt 8b + ands ip, r1, #3 + beq 1b + +10: bic r1, r1, #3 + cmp ip, #2 + ldr1w r1, lr, abort=21f + beq 17f + bgt 18f + + + .macro forward_copy_shift pull push + + subs r2, r2, #28 + blt 14f + + CALGN( ands ip, r0, #31 ) + CALGN( rsb ip, ip, #32 ) + CALGN( sbcnes r4, ip, r2 ) @ C is always set here + CALGN( subcc r2, r2, ip ) + CALGN( bcc 15f ) + +11: stmfd sp!, {r5 - r9} + + PLD( pld [r1, #0] ) + PLD( subs r2, r2, #96 ) + PLD( pld [r1, #28] ) + PLD( blt 13f ) + PLD( pld [r1, #60] ) + PLD( pld [r1, #92] ) + +12: PLD( pld [r1, #124] ) +13: ldr4w r1, r4, r5, r6, r7, abort=19f + mov r3, lr, pull #\pull + subs r2, r2, #32 + ldr4w r1, r8, r9, ip, lr, abort=19f + orr r3, r3, r4, push #\push + mov r4, r4, pull #\pull + orr r4, r4, r5, push #\push + mov r5, r5, pull #\pull + orr r5, r5, r6, push #\push + mov r6, r6, pull #\pull + orr r6, r6, r7, push #\push + mov r7, r7, pull #\pull + orr r7, r7, r8, push #\push + mov r8, r8, pull #\pull + orr r8, r8, r9, push #\push + mov r9, r9, pull #\pull + orr r9, r9, ip, push #\push + mov ip, ip, pull #\pull + orr ip, ip, lr, push #\push + str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f + bge 12b + PLD( cmn r2, #96 ) + PLD( bge 13b ) + + ldmfd sp!, {r5 - r9} + +14: ands ip, r2, #28 + beq 16f + +15: mov r3, lr, pull #\pull + ldr1w r1, lr, abort=21f + subs ip, ip, #4 + orr r3, r3, lr, push #\push + str1w r0, r3, abort=21f + bgt 15b + CALGN( cmp r2, #0 ) + CALGN( bge 11b ) + +16: sub r1, r1, #(\push / 8) + b 8b + + .endm + + + forward_copy_shift pull=8 push=24 + +17: forward_copy_shift pull=16 push=16 + +18: forward_copy_shift pull=24 push=8 + diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S new file mode 100644 index 0000000..0cdf895 --- /dev/null +++ b/arch/arm/lib/memset.S @@ -0,0 +1,126 @@ +/* + * linux/arch/arm/lib/memset.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ASM optimised string functions + */ +#include <asm/assembler.h> + + .text + .align 5 + .word 0 + +1: subs r2, r2, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r1, [r0], #1 @ 1 + strleb r1, [r0], #1 @ 1 + strb r1, [r0], #1 @ 1 + add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memset again. + */ + +.globl memset +memset: + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * we know that the pointer in r0 is aligned to a word boundary. + */ + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + mov r3, r1 + cmp r2, #16 + blt 4f + +#if ! CALGN(1)+0 + +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! + mov ip, r1 + mov lr, r1 + +2: subs r2, r2, #64 + stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + bgt 2b + ldmeqfd sp!, {pc} @ Now <64 bytes to go. +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r2, #32 + stmneia r0!, {r1, r3, ip, lr} + stmneia r0!, {r1, r3, ip, lr} + tst r2, #16 + stmneia r0!, {r1, r3, ip, lr} + ldr lr, [sp], #4 + +#else + +/* + * This version aligns the destination pointer in order to write + * whole cache lines at once. + */ + + stmfd sp!, {r4-r7, lr} + mov r4, r1 + mov r5, r1 + mov r6, r1 + mov r7, r1 + mov ip, r1 + mov lr, r1 + + cmp r2, #96 + tstgt r0, #31 + ble 3f + + and ip, r0, #31 + rsb ip, ip, #32 + sub r2, r2, ip + movs ip, ip, lsl #(32 - 4) + stmcsia r0!, {r4, r5, r6, r7} + stmmiia r0!, {r4, r5} + tst ip, #(1 << 30) + mov ip, r1 + strne r1, [r0], #4 + +3: subs r2, r2, #64 + stmgeia r0!, {r1, r3-r7, ip, lr} + stmgeia r0!, {r1, r3-r7, ip, lr} + bgt 3b + ldmeqfd sp!, {r4-r7, pc} + + tst r2, #32 + stmneia r0!, {r1, r3-r7, ip, lr} + tst r2, #16 + stmneia r0!, {r4-r7} + ldmfd sp!, {r4-r7, lr} + +#endif + +4: tst r2, #8 + stmneia r0!, {r1, r3} + tst r2, #4 + strne r1, [r0], #4 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r2, #2 + strneb r1, [r0], #1 + strneb r1, [r0], #1 + tst r2, #1 + strneb r1, [r0], #1 + mov pc, lr |