diff options
Diffstat (limited to 'arch')
257 files changed, 10057 insertions, 5916 deletions
diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index 86916d1edb..b006b6015d 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -115,13 +115,13 @@ unsigned long long get_ticks(void) { ulong now = GPTCNT; /* current tick value */ - if (now >= gd->lastinc) /* normal mode (non roll) */ + if (now >= gd->arch.lastinc) /* normal mode (non roll) */ /* move stamp forward with absolut diff ticks */ - gd->tbl += (now - gd->lastinc); + gd->arch.tbl += (now - gd->arch.lastinc); else /* we have rollover of incrementer */ - gd->tbl += (0xFFFFFFFF - gd->lastinc) + now; - gd->lastinc = now; - return gd->tbl; + gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; + gd->arch.lastinc = now; + return gd->arch.tbl; } ulong get_timer_masked(void) diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c index 295a98ea4b..d11e6f6270 100644 --- a/arch/arm/cpu/arm1136/mx35/generic.c +++ b/arch/arm/cpu/arm1136/mx35/generic.c @@ -478,11 +478,11 @@ int get_clocks(void) { #ifdef CONFIG_FSL_ESDHC #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); #else - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); #endif #endif return 0; diff --git a/arch/arm/cpu/arm1136/mx35/timer.c b/arch/arm/cpu/arm1136/mx35/timer.c index 9680b7fde7..584ad15135 100644 --- a/arch/arm/cpu/arm1136/mx35/timer.c +++ b/arch/arm/cpu/arm1136/mx35/timer.c @@ -32,8 +32,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) /* General purpose timers bitfields */ #define GPTCR_SWR (1<<15) /* Software reset */ diff --git a/arch/arm/cpu/arm1136/omap24xx/timer.c b/arch/arm/cpu/arm1136/omap24xx/timer.c index e929ae45bb..53015cb77d 100644 --- a/arch/arm/cpu/arm1136/omap24xx/timer.c +++ b/arch/arm/cpu/arm1136/omap24xx/timer.c @@ -51,8 +51,8 @@ int timer_init (void) *((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */ /* reset time */ - gd->lastinc = READ_TIMER; /* capture current incrementer value */ - gd->tbl = 0; /* start "advancing" time stamp */ + gd->arch.lastinc = READ_TIMER; /* capture current incrementer value */ + gd->arch.tbl = 0; /* start "advancing" time stamp */ return(0); } @@ -81,8 +81,8 @@ void __udelay (unsigned long usec) tmp = get_timer (0); /* get current timestamp */ if ((tmo + tmp + 1) < tmp) { /* if setting this forward will roll */ /* time stamp, then reset time */ - gd->lastinc = READ_TIMER; /* capture incrementer value */ - gd->tbl = 0; /* start time stamp */ + gd->arch.lastinc = READ_TIMER; /* capture incrementer value */ + gd->arch.tbl = 0; /* start time stamp */ } else { tmo += tmp; /* else, set advancing stamp wake up time */ } @@ -94,12 +94,15 @@ ulong get_timer_masked (void) { ulong now = READ_TIMER; /* current tick value */ - if (now >= gd->lastinc) /* normal mode (non roll) */ - gd->tbl += (now - gd->lastinc); /* move stamp fordward with absoulte diff ticks */ - else /* we have rollover of incrementer */ - gd->tbl += (0xFFFFFFFF - gd->lastinc) + now; - gd->lastinc = now; - return gd->tbl; + if (now >= gd->arch.lastinc) { /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + gd->arch.tbl += (now - gd->arch.lastinc); + } else { + /* we have rollover of incrementer */ + gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; + } + gd->arch.lastinc = now; + return gd->arch.tbl; } /* waits specified delay value and resets timestamp */ diff --git a/arch/arm/cpu/arm720t/tegra-common/Makefile b/arch/arm/cpu/arm720t/tegra-common/Makefile index febd2e301f..6cbc6adaa1 100644 --- a/arch/arm/cpu/arm720t/tegra-common/Makefile +++ b/arch/arm/cpu/arm720t/tegra-common/Makefile @@ -28,6 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libtegra-common.o COBJS-$(CONFIG_SPL_BUILD) += spl.o +COBJS-y += cpu.o SRCS := $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.c b/arch/arm/cpu/arm720t/tegra-common/cpu.c new file mode 100644 index 0000000000..119342e957 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra-common/cpu.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/gp_padctrl.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/scu.h> +#include "cpu.h" + +int get_num_cpus(void) +{ + struct apb_misc_gp_ctlr *gp; + uint rev; + + gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; + + switch (rev) { + case CHIPID_TEGRA20: + return 2; + break; + case CHIPID_TEGRA30: + case CHIPID_TEGRA114: + default: + return 4; + break; + } +} + +/* + * Timing tables for each SOC for all four oscillator options. + */ +struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { + /* T20: 1 GHz */ + /* n, m, p, cpcon */ + {{ 1000, 13, 0, 12}, /* OSC 13M */ + { 625, 12, 0, 8}, /* OSC 19.2M */ + { 1000, 12, 0, 12}, /* OSC 12M */ + { 1000, 26, 0, 12}, /* OSC 26M */ + }, + + /* T25: 1.2 GHz */ + {{ 923, 10, 0, 12}, + { 750, 12, 0, 8}, + { 600, 6, 0, 12}, + { 600, 13, 0, 12}, + }, + + /* T30: 1.4 GHz */ + {{ 862, 8, 0, 8}, + { 583, 8, 0, 4}, + { 700, 6, 0, 8}, + { 700, 13, 0, 8}, + }, + + /* T114: 1.4 GHz */ + {{ 862, 8, 0, 8}, + { 583, 8, 0, 4}, + { 696, 12, 0, 8}, + { 700, 13, 0, 8}, + }, +}; + +void adjust_pllp_out_freqs(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH]; + u32 reg; + + /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ + reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */ + reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR + | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR; + writel(reg, &pll->pll_out[0]); + + reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */ + reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR + | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR; + writel(reg, &pll->pll_out[1]); +} + +int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, + u32 divp, u32 cpcon) +{ + u32 reg; + + /* If PLLX is already enabled, just return */ + if (readl(&pll->pll_base) & PLL_ENABLE_MASK) { + debug("pllx_set_rate: PLLX already enabled, returning\n"); + return 0; + } + + debug(" pllx_set_rate entry\n"); + + /* Set BYPASS, m, n and p to PLLX_BASE */ + reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT); + reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT)); + writel(reg, &pll->pll_base); + + /* Set cpcon to PLLX_MISC */ + reg = (cpcon << PLL_CPCON_SHIFT); + + /* Set dccon to PLLX_MISC if freq > 600MHz */ + if (divn > 600) + reg |= (1 << PLL_DCCON_SHIFT); + writel(reg, &pll->pll_misc); + + /* Enable PLLX */ + reg = readl(&pll->pll_base); + reg |= PLL_ENABLE_MASK; + + /* Disable BYPASS */ + reg &= ~PLL_BYPASS_MASK; + writel(reg, &pll->pll_base); + + /* Set lock_enable to PLLX_MISC */ + reg = readl(&pll->pll_misc); + reg |= PLL_LOCK_ENABLE_MASK; + writel(reg, &pll->pll_misc); + + return 0; +} + +void init_pllx(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX]; + int chip_type; + enum clock_osc_freq osc; + struct clk_pll_table *sel; + + debug("init_pllx entry\n"); + + /* get chip type */ + chip_type = tegra_get_chip_type(); + debug(" init_pllx: chip_type = %d\n", chip_type); + + /* get osc freq */ + osc = clock_get_osc_freq(); + debug(" init_pllx: osc = %d\n", osc); + + /* set pllx */ + sel = &tegra_pll_x_table[chip_type][osc]; + pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); + + /* adjust PLLP_out1-4 on T30/T114 */ + if (chip_type == TEGRA_SOC_T30 || chip_type == TEGRA_SOC_T114) { + debug(" init_pllx: adjusting PLLP out freqs\n"); + adjust_pllp_out_freqs(); + } +} + +void enable_cpu_clock(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 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. + */ + + 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); + } + + /* + * Read the register containing the individual CPU clock enables and + * always stop the clocks to CPUs > 0. + */ + clk = readl(&clkrst->crc_clk_cpu_cmplx); + clk |= 1 << CPU1_CLK_STP_SHIFT; + if (get_num_cpus() == 4) + clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT); + + /* Stop/Unstop the CPU clock */ + clk &= ~CPU0_CLK_STP_MASK; + clk |= !enable << CPU0_CLK_STP_SHIFT; + writel(clk, &clkrst->crc_clk_cpu_cmplx); + + clock_enable(PERIPH_ID_CPU); +} + +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); +} + +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(); + } +} + +void reset_A9_cpu(int reset) +{ + /* + * 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. + */ + int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; + int num_cpus = get_num_cpus(); + int cpu; + + debug("reset_a9_cpu entry\n"); + /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ + for (cpu = 1; cpu < num_cpus; cpu++) + reset_cmplx_set_enable(cpu, mask, 1); + reset_cmplx_set_enable(0, mask, reset); + + /* Enable/Disable master CPU reset */ + reset_set_enable(PERIPH_ID_CPU, reset); +} + +void clock_enable_coresight(int enable) +{ + u32 rst, src = 2; + int chip; + + debug("clock_enable_coresight entry\n"); + clock_set_enable(PERIPH_ID_CORESIGHT, enable); + reset_set_enable(PERIPH_ID_CORESIGHT, !enable); + + 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) + * + * Clock divider request for 204MHz would setup CSITE clock as + * 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz + */ + chip = tegra_get_chip_type(); + if (chip == TEGRA_SOC_T30 || chip == TEGRA_SOC_T114) + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000); + else if (chip == TEGRA_SOC_T20 || chip == TEGRA_SOC_T25) + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); + else + printf("%s: Unknown chip type %X!\n", __func__, chip); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); + + /* Unlock the CPU CoreSight interfaces */ + rst = CORESIGHT_UNLOCK; + writel(rst, CSITE_CPU_DBG0_LAR); + writel(rst, CSITE_CPU_DBG1_LAR); + if (get_num_cpus() == 4) { + writel(rst, CSITE_CPU_DBG2_LAR); + writel(rst, CSITE_CPU_DBG3_LAR); + } + } +} + +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); + } +} diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h index 6804cd7a3d..e8e05d77aa 100644 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.h +++ b/arch/arm/cpu/arm720t/tegra-common/cpu.h @@ -26,7 +26,13 @@ #define PLL_STABILIZATION_DELAY (300) #define IO_STABILIZATION_DELAY (1000) +#if defined(CONFIG_TEGRA20) #define NVBL_PLLP_KHZ (216000) +#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) +#define NVBL_PLLP_KHZ (408000) +#else +#error "Unknown Tegra chip!" +#endif #define PLLX_ENABLED (1 << 30) #define CCLK_BURST_POLICY 0x20008888 @@ -44,50 +50,11 @@ #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 CSITE_CPU_DBG2_LAR (NV_PA_CSITE_BASE + 0x14FB0) +#define CSITE_CPU_DBG3_LAR (NV_PA_CSITE_BASE + 0x16FB0) #define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) #define FLOW_MODE_STOP 2 @@ -95,6 +62,23 @@ #define HALT_COP_EVENT_IRQ_1 (1 << 11) #define HALT_COP_EVENT_FIQ_1 (1 << 9) -void start_cpu(u32 reset_vector); -int ap20_cpu_is_cortexa9(void); +#define FLOW_MODE_NONE 0 + +#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) + +struct clk_pll_table { + u16 n; + u16 m; + u8 p; + u8 cpcon; +}; + +void clock_enable_coresight(int enable); +void enable_cpu_clock(int enable); void halt_avp(void) __attribute__ ((noreturn)); +void init_pllx(void); +void powerup_cpu(void); +void reset_A9_cpu(int reset); +void start_cpu(u32 reset_vector); +int tegra_get_chip_type(void); +void adjust_pllp_out_freqs(void); diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c index c280ab7d0f..a9a1c39c73 100644 --- a/arch/arm/cpu/arm720t/tegra-common/spl.c +++ b/arch/arm/cpu/arm720t/tegra-common/spl.c @@ -23,7 +23,6 @@ * MA 02111-1307 USA */ #include <common.h> -#include "cpu.h" #include <spl.h> #include <asm/io.h> @@ -32,7 +31,7 @@ #include <asm/arch/tegra.h> #include <asm/arch-tegra/board.h> #include <asm/arch/spl.h> - +#include "cpu.h" void spl_board_init(void) { diff --git a/arch/arm/cpu/arm720t/tegra114/Makefile b/arch/arm/cpu/arm720t/tegra114/Makefile new file mode 100644 index 0000000000..6cf7fe9da9 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra114/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +#COBJS-y += cpu.o t11x.o +COBJS-y += cpu.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/tegra114/config.mk b/arch/arm/cpu/arm720t/tegra114/config.mk new file mode 100644 index 0000000000..7947b50fd0 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra114/config.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# +USE_PRIVATE_LIBGCC = yes diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c b/arch/arm/cpu/arm720t/tegra114/cpu.c new file mode 100644 index 0000000000..5962e15b4f --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra114/cpu.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/flow.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/pmc.h> +#include "../tegra-common/cpu.h" + +/* Tegra114-specific CPU init code */ +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("enable_cpu_power_rail entry\n"); + + /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ + pinmux_tristate_disable(PINGRP_PWR_I2C_SCL); + pinmux_tristate_disable(PINGRP_PWR_I2C_SDA); + + /* + * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), + * set it for 25ms (102MHz * .025) + */ + reg = 0x26E8F0; + writel(reg, &pmc->pmc_cpupwrgood_timer); + + /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ + clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); + setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); + + /* + * Set CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0_CAR2PMC_CPU_ACK_WIDTH + * to 408 to satisfy the requirement of having at least 16 CPU clock + * cycles before clamp removal. + */ + + clrbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 0xFFF); + setbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 408); +} + +static void enable_cpu_clocks(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("enable_cpu_clocks entry\n"); + + /* Wait for PLL-X to lock */ + do { + reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + } while ((reg & (1 << 27)) == 0); + + /* 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); + + /* Always enable the main CPU complex clocks */ + clock_enable(PERIPH_ID_CPU); + clock_enable(PERIPH_ID_CPULP); + clock_enable(PERIPH_ID_CPUG); +} + +static void remove_cpu_resets(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("remove_cpu_resets entry\n"); + /* Take the slow non-CPU partition out of reset */ + reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); + writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr); + + /* Take the fast non-CPU partition out of reset */ + reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); + writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpug_cmplx_clr); + + /* Clear the SW-controlled reset of the slow cluster */ + reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); + reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); + writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); + + /* Clear the SW-controlled reset of the fast cluster */ + reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); + reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); + reg |= (CLR_CPURESET1+CLR_DBGRESET1+CLR_CORERESET1+CLR_CXRESET1); + reg |= (CLR_CPURESET2+CLR_DBGRESET2+CLR_CORERESET2+CLR_CXRESET2); + reg |= (CLR_CPURESET3+CLR_DBGRESET3+CLR_CORERESET3+CLR_CXRESET3); + writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); +} + +/** + * The T114 requires some special clock initialization, including setting up + * the DVC I2C, turning on MSELECT and selecting the G CPU cluster + */ +void t114_init_clocks(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + u32 val; + + debug("t114_init_clocks entry\n"); + + /* Set active CPU cluster to G */ + clrbits_le32(&flow->cluster_control, 1); + + /* + * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run + * at 108 MHz. This is glitch free as only the source is changed, no + * special precaution needed. + */ + val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | + (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); + writel(val, &clkrst->crc_sclk_brst_pol); + + writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); + + debug("Setting up PLLX\n"); + init_pllx(); + + val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Enable clocks to required peripherals. TBD - minimize this list */ + debug("Enabling clocks\n"); + + clock_set_enable(PERIPH_ID_CACHE2, 1); + clock_set_enable(PERIPH_ID_GPIO, 1); + clock_set_enable(PERIPH_ID_TMR, 1); + clock_set_enable(PERIPH_ID_RTC, 1); + clock_set_enable(PERIPH_ID_CPU, 1); + clock_set_enable(PERIPH_ID_EMC, 1); + clock_set_enable(PERIPH_ID_I2C5, 1); + clock_set_enable(PERIPH_ID_FUSE, 1); + clock_set_enable(PERIPH_ID_PMC, 1); + clock_set_enable(PERIPH_ID_APBDMA, 1); + clock_set_enable(PERIPH_ID_MEM, 1); + clock_set_enable(PERIPH_ID_IRAMA, 1); + clock_set_enable(PERIPH_ID_IRAMB, 1); + clock_set_enable(PERIPH_ID_IRAMC, 1); + clock_set_enable(PERIPH_ID_IRAMD, 1); + clock_set_enable(PERIPH_ID_CORESIGHT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_EMC1, 1); + clock_set_enable(PERIPH_ID_MC1, 1); + clock_set_enable(PERIPH_ID_DVFS, 1); + + /* Switch MSELECT clock to PLLP (00) */ + clock_ll_set_source(PERIPH_ID_MSELECT, 0); + + /* + * Clock divider request for 102MHz would setup MSELECT clock as + * 102MHz for PLLP base 408MHz + */ + clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, + (NVBL_PLLP_KHZ/102000)); + + /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ + clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); + + /* Give clocks time to stabilize */ + udelay(1000); + + /* Take required peripherals out of reset */ + debug("Taking periphs out of reset\n"); + reset_set_enable(PERIPH_ID_CACHE2, 0); + reset_set_enable(PERIPH_ID_GPIO, 0); + reset_set_enable(PERIPH_ID_TMR, 0); + reset_set_enable(PERIPH_ID_COP, 0); + reset_set_enable(PERIPH_ID_EMC, 0); + reset_set_enable(PERIPH_ID_I2C5, 0); + reset_set_enable(PERIPH_ID_FUSE, 0); + reset_set_enable(PERIPH_ID_APBDMA, 0); + reset_set_enable(PERIPH_ID_MEM, 0); + reset_set_enable(PERIPH_ID_CORESIGHT, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); + reset_set_enable(PERIPH_ID_EMC1, 0); + reset_set_enable(PERIPH_ID_MC1, 0); + + debug("t114_init_clocks exit\n"); +} + +static int is_partition_powered(u32 mask) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Get power gate status */ + reg = readl(&pmc->pmc_pwrgate_status); + return (reg & mask) == mask; +} + +static int is_clamp_enabled(u32 mask) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Get clamp status. TODO: Add pmc_clamp_status alias to pmc.h */ + reg = readl(&pmc->pmc_pwrgate_timer_on); + return (reg & mask) == mask; +} + +static void power_partition(u32 status, u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("%s: status = %08X, part ID = %08X\n", __func__, status, partid); + /* Is the partition already on? */ + if (!is_partition_powered(status)) { + /* No, toggle the partition power state (OFF -> ON) */ + debug("power_partition, toggling state\n"); + clrbits_le32(&pmc->pmc_pwrgate_toggle, 0x1F); + setbits_le32(&pmc->pmc_pwrgate_toggle, partid); + setbits_le32(&pmc->pmc_pwrgate_toggle, START_CP); + + /* Wait for the power to come up */ + while (!is_partition_powered(status)) + ; + + /* Wait for the clamp status to be cleared */ + while (is_clamp_enabled(status)) + ; + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + } +} + +void powerup_cpus(void) +{ + debug("powerup_cpus entry\n"); + + /* We boot to the fast cluster */ + debug("powerup_cpus entry: G cluster\n"); + /* Power up the fast cluster rail partition */ + power_partition(CRAIL, CRAILID); + + /* Power up the fast cluster non-CPU partition */ + power_partition(C0NC, C0NCID); + + /* Power up the fast cluster CPU0 partition */ + power_partition(CE0, CE0ID); +} + +void start_cpu(u32 reset_vector) +{ + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + + t114_init_clocks(); + + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + /* Get the CPU(s) running */ + enable_cpu_clocks(); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* Take CPU(s) out of reset */ + remove_cpu_resets(); + + /* + * 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); + + /* If the CPU(s) don't already have power, power 'em up */ + powerup_cpus(); +} diff --git a/arch/arm/cpu/arm720t/tegra20/cpu.c b/arch/arm/cpu/arm720t/tegra20/cpu.c index ef7f375e79..253389955f 100644 --- a/arch/arm/cpu/arm720t/tegra20/cpu.c +++ b/arch/arm/cpu/arm720t/tegra20/cpu.c @@ -1,160 +1,25 @@ /* -* (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 -*/ + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ #include <common.h> #include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/pinmux.h> #include <asm/arch/tegra.h> -#include <asm/arch-tegra/clk_rst.h> #include <asm/arch-tegra/pmc.h> -#include <asm/arch-tegra/scu.h> #include "../tegra-common/cpu.h" -/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ -int ap20_cpu_is_cortexa9(void) -{ - u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0); - return id == (PG_UP_TAG_0_PID_CPU & 0xff); -} - -void init_pllx(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU]; - u32 reg; - - /* If PLLX is already enabled, just return */ - if (readl(&pll->pll_base) & PLL_ENABLE_MASK) - return; - - /* Set PLLX_MISC */ - writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc); - - /* Use 12MHz clock here */ - reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT); - reg |= 1000 << PLL_DIVN_SHIFT; - writel(reg, &pll->pll_base); - - reg |= PLL_ENABLE_MASK; - writel(reg, &pll->pll_base); - - reg &= ~PLL_BYPASS_MASK; - writel(reg, &pll->pll_base); -} - -static void enable_cpu_clock(int enable) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 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); - } - - /* - * 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 |= 1 << CPU1_CLK_STP_SHIFT; - - /* Stop/Unstop the CPU clock */ - clk &= ~CPU0_CLK_STP_MASK; - clk |= !enable << CPU0_CLK_STP_SHIFT; - writel(clk, &clkrst->crc_clk_cpu_cmplx); - - clock_enable(PERIPH_ID_CPU); -} - -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; @@ -173,49 +38,6 @@ static void enable_cpu_power_rail(void) udelay(3750); } -static void reset_A9_cpu(int reset) -{ - /* - * 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, and CPU 0 if asked */ - reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1); - reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug, - reset); - - /* Enable/Disable master CPU reset */ - reset_set_enable(PERIPH_ID_CPU, reset); -} - -static void clock_enable_coresight(int enable) -{ - u32 rst, src; - - clock_set_enable(PERIPH_ID_CORESIGHT, enable); - reset_set_enable(PERIPH_ID_CORESIGHT, !enable); - - 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); - clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); - - /* 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 */ @@ -246,13 +68,3 @@ void start_cpu(u32 reset_vector) /* 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); - } -} diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/arm720t/tegra30/Makefile new file mode 100644 index 0000000000..bd969976e9 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS-y += cpu.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/tegra30/config.mk b/arch/arm/cpu/arm720t/tegra30/config.mk new file mode 100644 index 0000000000..2388c56db7 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/config.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# +USE_PRIVATE_LIBGCC = yes diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c new file mode 100644 index 0000000000..dedcdd9b08 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra30/cpu.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/flow.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include "../tegra-common/cpu.h" + +/* Tegra30-specific CPU init code */ +void tegra_i2c_ll_write_addr(uint addr, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(config, ®->cnfg); +} + +void tegra_i2c_ll_write_data(uint data, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(data, ®->cmd_data1); + writel(config, ®->cnfg); +} + +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2300 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) +#define I2C_SEND_2_BYTES 0x0A02 + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + debug("enable_cpu_power_rail entry\n"); + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.4V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} + +/** + * The T30 requires some special clock initialization, including setting up + * the dvc i2c, turning on mselect and selecting the G CPU cluster + */ +void t30_init_clocks(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + u32 val; + + debug("t30_init_clocks entry\n"); + /* Set active CPU cluster to G */ + clrbits_le32(flow->cluster_control, 1 << 0); + + /* + * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run + * at 108 MHz. This is glitch free as only the source is changed, no + * special precaution needed. + */ + val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | + (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | + (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); + writel(val, &clkrst->crc_sclk_brst_pol); + + writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); + + val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | + (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | + (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | + (0 << CLK_SYS_RATE_APB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Put i2c, mselect in reset and enable clocks */ + reset_set_enable(PERIPH_ID_DVC_I2C, 1); + clock_set_enable(PERIPH_ID_DVC_I2C, 1); + reset_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + + /* Switch MSELECT clock to PLLP (00) */ + clock_ll_set_source(PERIPH_ID_MSELECT, 0); + + /* + * Our high-level clock routines are not available prior to + * relocation. We use the low-level functions which require a + * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) + */ + clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); + + /* + * Give clocks time to stabilize, then take i2c and mselect out of + * reset + */ + udelay(1000); + reset_set_enable(PERIPH_ID_DVC_I2C, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); +} + +static void set_cpu_running(int run) +{ + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + + debug("set_cpu_running entry, run = %d\n", run); + writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events); +} + +void start_cpu(u32 reset_vector) +{ + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + t30_init_clocks(); + + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + set_cpu_running(0); + + /* 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); + + set_cpu_running(1); +} diff --git a/arch/arm/cpu/arm920t/a320/timer.c b/arch/arm/cpu/arm920t/a320/timer.c index 4bfcef2379..512fb9d73d 100644 --- a/arch/arm/cpu/arm920t/a320/timer.c +++ b/arch/arm/cpu/arm920t/a320/timer.c @@ -31,14 +31,14 @@ DECLARE_GLOBAL_DATA_PTR; static inline unsigned long long tick_to_time(unsigned long long tick) { tick *= CONFIG_SYS_HZ; - do_div(tick, gd->timer_rate_hz); + do_div(tick, gd->arch.timer_rate_hz); return tick; } static inline unsigned long long usec_to_tick(unsigned long long usec) { - usec *= gd->timer_rate_hz; + usec *= gd->arch.timer_rate_hz; do_div(usec, 1000000); return usec; @@ -74,8 +74,8 @@ int timer_init(void) cr |= FTTMR010_TM3_ENABLE; writel(cr, &tmr->cr); - gd->timer_rate_hz = TIMER_CLOCK; - gd->tbu = gd->tbl = 0; + gd->arch.timer_rate_hz = TIMER_CLOCK; + gd->arch.tbu = gd->arch.tbl = 0; return 0; } @@ -89,10 +89,10 @@ unsigned long long get_ticks(void) ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter); /* increment tbu if tbl has rolled over */ - if (now < gd->tbl) - gd->tbu++; - gd->tbl = now; - return (((unsigned long long)gd->tbu) << 32) | gd->tbl; + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; } void __udelay(unsigned long usec) @@ -126,5 +126,5 @@ ulong get_timer(ulong base) */ ulong get_tbclk(void) { - return gd->timer_rate_hz; + return gd->arch.timer_rate_hz; } diff --git a/arch/arm/cpu/arm920t/at91/clock.c b/arch/arm/cpu/arm920t/at91/clock.c index 09d2799831..696200d04a 100644 --- a/arch/arm/cpu/arm920t/at91/clock.c +++ b/arch/arm/cpu/arm920t/at91/clock.c @@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css) case AT91_PMC_MCKR_CSS_SLOW: return CONFIG_SYS_AT91_SLOW_CLOCK; case AT91_PMC_MCKR_CSS_MAIN: - return gd->main_clk_rate_hz; + return gd->arch.main_clk_rate_hz; case AT91_PMC_MCKR_CSS_PLLA: - return gd->plla_rate_hz; + return gd->arch.plla_rate_hz; case AT91_PMC_MCKR_CSS_PLLB: - return gd->pllb_rate_hz; + return gd->arch.pllb_rate_hz; } return 0; @@ -124,10 +124,10 @@ int at91_clock_init(unsigned long main_clock) main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); } #endif - gd->main_clk_rate_hz = main_clock; + gd->arch.main_clk_rate_hz = main_clock; /* report if PLLA is more than mildly overclocked */ - gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); #ifdef CONFIG_USB_ATMEL /* @@ -136,9 +136,10 @@ int at91_clock_init(unsigned long main_clock) * * REVISIT: assumes MCK doesn't derive from PLLB! */ - gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_PLLBR_USBDIV_2; - gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init); + gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, + gd->arch.at91_pllb_usb_init); #endif /* @@ -146,13 +147,14 @@ int at91_clock_init(unsigned long main_clock) * For now, assume this parentage won't change. */ mckr = readl(&pmc->mckr); - gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = gd->mck_rate_hz; + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ /* mdiv */ - gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); - gd->cpu_clk_rate_hz = freq; + gd->arch.mck_rate_hz = freq / + (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + gd->arch.cpu_clk_rate_hz = freq; return 0; } diff --git a/arch/arm/cpu/arm920t/at91/timer.c b/arch/arm/cpu/arm920t/at91/timer.c index 91607b525e..8ce75843a0 100644 --- a/arch/arm/cpu/arm920t/at91/timer.c +++ b/arch/arm/cpu/arm920t/at91/timer.c @@ -63,8 +63,8 @@ int timer_init(void) writel(TIMER_LOAD_VAL, &tc->tc[0].rc); writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); - gd->lastinc = 0; - gd->tbl = 0; + gd->arch.lastinc = 0; + gd->arch.tbl = 0; return 0; } @@ -89,16 +89,16 @@ ulong get_timer_raw(void) now = readl(&tc->tc[0].cv) & 0x0000ffff; - if (now >= gd->lastinc) { + if (now >= gd->arch.lastinc) { /* normal mode */ - gd->tbl += now - gd->lastinc; + gd->arch.tbl += now - gd->arch.lastinc; } else { /* we have an overflow ... */ - gd->tbl += now + TIMER_LOAD_VAL - gd->lastinc; + gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc; } - gd->lastinc = now; + gd->arch.lastinc = now; - return gd->tbl; + return gd->arch.tbl; } ulong get_timer_masked(void) diff --git a/arch/arm/cpu/arm920t/s3c24x0/timer.c b/arch/arm/cpu/arm920t/s3c24x0/timer.c index d8668bec5e..d76bf186b6 100644 --- a/arch/arm/cpu/arm920t/s3c24x0/timer.c +++ b/arch/arm/cpu/arm920t/s3c24x0/timer.c @@ -45,25 +45,25 @@ int timer_init(void) /* use PWM Timer 4 because it has no output */ /* prescaler for Timer 4 is 16 */ writel(0x0f00, &timers->tcfg0); - if (gd->tbu == 0) { + if (gd->arch.tbu == 0) { /* * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 * (default) and prescaler = 16. Should be 10390 * @33.25MHz and 15625 @ 50 MHz */ - gd->tbu = get_PCLK() / (2 * 16 * 100); - gd->timer_rate_hz = get_PCLK() / (2 * 16); + gd->arch.tbu = get_PCLK() / (2 * 16 * 100); + gd->arch.timer_rate_hz = get_PCLK() / (2 * 16); } /* load value for 10 ms timeout */ - writel(gd->tbu, &timers->tcntb4); + writel(gd->arch.tbu, &timers->tcntb4); /* auto load, manual update of timer 4 */ tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000; writel(tmr, &timers->tcon); /* auto load, start timer 4 */ tmr = (tmr & ~0x0700000) | 0x0500000; writel(tmr, &timers->tcon); - gd->lastinc = 0; - gd->tbl = 0; + gd->arch.lastinc = 0; + gd->arch.tbl = 0; return 0; } @@ -82,7 +82,7 @@ void __udelay (unsigned long usec) ulong start = get_ticks(); tmo = usec / 1000; - tmo *= (gd->tbu * 100); + tmo *= (gd->arch.tbu * 100); tmo /= 1000; while ((ulong) (get_ticks() - start) < tmo) @@ -93,7 +93,7 @@ ulong get_timer_masked(void) { ulong tmr = get_ticks(); - return tmr / (gd->timer_rate_hz / CONFIG_SYS_HZ); + return tmr / (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); } void udelay_masked(unsigned long usec) @@ -104,10 +104,10 @@ void udelay_masked(unsigned long usec) if (usec >= 1000) { tmo = usec / 1000; - tmo *= (gd->tbu * 100); + tmo *= (gd->arch.tbu * 100); tmo /= 1000; } else { - tmo = usec * (gd->tbu * 100); + tmo = usec * (gd->arch.tbu * 100); tmo /= (1000 * 1000); } @@ -128,16 +128,16 @@ unsigned long long get_ticks(void) struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); ulong now = readl(&timers->tcnto4) & 0xffff; - if (gd->lastinc >= now) { + if (gd->arch.lastinc >= now) { /* normal mode */ - gd->tbl += gd->lastinc - now; + gd->arch.tbl += gd->arch.lastinc - now; } else { /* we have an overflow ... */ - gd->tbl += gd->lastinc + gd->tbu - now; + gd->arch.tbl += gd->arch.lastinc + gd->arch.tbu - now; } - gd->lastinc = now; + gd->arch.lastinc = now; - return gd->tbl; + return gd->arch.tbl; } /* diff --git a/arch/arm/cpu/arm926ejs/armada100/timer.c b/arch/arm/cpu/arm926ejs/armada100/timer.c index 355cd6d1d8..948607f8c0 100644 --- a/arch/arm/cpu/arm926ejs/armada100/timer.c +++ b/arch/arm/cpu/arm926ejs/armada100/timer.c @@ -61,7 +61,7 @@ struct armd1tmr_registers { #define COUNT_RD_REQ 0x1 DECLARE_GLOBAL_DATA_PTR; -/* Using gd->tbu from timestamp and gd->tbl for lastdec */ +/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */ /* For preventing risk of instability in reading counter value, * first set read request to register cvwr and then read same @@ -82,16 +82,16 @@ ulong get_timer_masked(void) { ulong now = read_timer(); - if (now >= gd->tbl) { + if (now >= gd->arch.tbl) { /* normal mode */ - gd->tbu += now - gd->tbl; + gd->arch.tbu += now - gd->arch.tbl; } else { /* we have an overflow ... */ - gd->tbu += now + TIMER_LOAD_VAL - gd->tbl; + gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl; } - gd->tbl = now; + gd->arch.tbl = now; - return gd->tbu; + return gd->arch.tbu; } ulong get_timer(ulong base) @@ -135,9 +135,9 @@ int timer_init(void) /* Enable timer 0 */ writel(0x1, &armd1timers->cer); - /* init the gd->tbu and gd->tbl value */ - gd->tbl = read_timer(); - gd->tbu = 0; + /* init the gd->arch.tbu and gd->arch.tbl value */ + gd->arch.tbl = read_timer(); + gd->arch.tbu = 0; return 0; } diff --git a/arch/arm/cpu/arm926ejs/at91/clock.c b/arch/arm/cpu/arm926ejs/at91/clock.c index dc5c6c4b0b..f825388ae9 100644 --- a/arch/arm/cpu/arm926ejs/at91/clock.c +++ b/arch/arm/cpu/arm926ejs/at91/clock.c @@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css) case AT91_PMC_MCKR_CSS_SLOW: return CONFIG_SYS_AT91_SLOW_CLOCK; case AT91_PMC_MCKR_CSS_MAIN: - return gd->main_clk_rate_hz; + return gd->arch.main_clk_rate_hz; case AT91_PMC_MCKR_CSS_PLLA: - return gd->plla_rate_hz; + return gd->arch.plla_rate_hz; case AT91_PMC_MCKR_CSS_PLLB: - return gd->pllb_rate_hz; + return gd->arch.pllb_rate_hz; } return 0; @@ -132,10 +132,10 @@ int at91_clock_init(unsigned long main_clock) main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); } #endif - gd->main_clk_rate_hz = main_clock; + gd->arch.main_clk_rate_hz = main_clock; /* report if PLLA is more than mildly overclocked */ - gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); #ifdef CONFIG_USB_ATMEL /* @@ -144,9 +144,10 @@ int at91_clock_init(unsigned long main_clock) * * REVISIT: assumes MCK doesn't derive from PLLB! */ - gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_PLLBR_USBDIV_2; - gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init); + gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, + gd->arch.at91_pllb_usb_init); #endif /* @@ -157,15 +158,15 @@ int at91_clock_init(unsigned long main_clock) #if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ || defined(CONFIG_AT91SAM9X5) /* plla divisor by 2 */ - gd->plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); + gd->arch.plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); #endif - gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = gd->mck_rate_hz; + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ #if defined(CONFIG_AT91SAM9G20) /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ - gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? + gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; if (mckr & AT91_PMC_MCKR_MDIV_MASK) freq /= 2; /* processor clock division */ @@ -177,14 +178,15 @@ int at91_clock_init(unsigned long main_clock) * 2 <==> 4 * 3 <==> 3 */ - gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == + gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) ? freq / 3 : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); #else - gd->mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + gd->arch.mck_rate_hz = freq / + (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); #endif - gd->cpu_clk_rate_hz = freq; + gd->arch.cpu_clk_rate_hz = freq; return 0; } diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c index f70ce83f08..4443fefb64 100644 --- a/arch/arm/cpu/arm926ejs/at91/timer.c +++ b/arch/arm/cpu/arm926ejs/at91/timer.c @@ -52,14 +52,14 @@ DECLARE_GLOBAL_DATA_PTR; static inline unsigned long long tick_to_time(unsigned long long tick) { tick *= CONFIG_SYS_HZ; - do_div(tick, gd->timer_rate_hz); + do_div(tick, gd->arch.timer_rate_hz); return tick; } static inline unsigned long long usec_to_tick(unsigned long long usec) { - usec *= gd->timer_rate_hz; + usec *= gd->arch.timer_rate_hz; do_div(usec, 1000000); return usec; @@ -79,8 +79,8 @@ int timer_init(void) /* Enable PITC */ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); - gd->timer_rate_hz = gd->mck_rate_hz / 16; - gd->tbu = gd->tbl = 0; + gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16; + gd->arch.tbu = gd->arch.tbl = 0; return 0; } @@ -95,10 +95,10 @@ unsigned long long get_ticks(void) ulong now = readl(&pit->piir); /* increment tbu if tbl has rolled over */ - if (now < gd->tbl) - gd->tbu++; - gd->tbl = now; - return (((unsigned long long)gd->tbu) << 32) | gd->tbl; + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; } void __udelay(unsigned long usec) @@ -132,5 +132,5 @@ ulong get_timer(ulong base) */ ulong get_tbclk(void) { - return gd->timer_rate_hz; + return gd->arch.timer_rate_hz; } diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c index 93c9e60b79..4142932d08 100644 --- a/arch/arm/cpu/arm926ejs/davinci/timer.c +++ b/arch/arm/cpu/arm926ejs/davinci/timer.c @@ -60,8 +60,8 @@ int timer_init(void) writel(0x0, &timer->tim34); writel(TIMER_LOAD_VAL, &timer->prd34); writel(2 << 22, &timer->tcr); - gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; - gd->timer_reset_value = 0; + gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; + gd->arch.timer_reset_value = 0; return(0); } @@ -74,27 +74,28 @@ unsigned long long get_ticks(void) unsigned long now = readl(&timer->tim34); /* increment tbu if tbl has rolled over */ - if (now < gd->tbl) - gd->tbu++; - gd->tbl = now; + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; - return (((unsigned long long)gd->tbu) << 32) | gd->tbl; + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; } ulong get_timer(ulong base) { unsigned long long timer_diff; - timer_diff = get_ticks() - gd->timer_reset_value; + timer_diff = get_ticks() - gd->arch.timer_reset_value; - return lldiv(timer_diff, (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base; + return lldiv(timer_diff, + (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base; } void __udelay(unsigned long usec) { unsigned long long endtime; - endtime = lldiv((unsigned long long)usec * gd->timer_rate_hz, + endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, 1000000UL); endtime += get_ticks(); @@ -108,7 +109,7 @@ void __udelay(unsigned long usec) */ ulong get_tbclk(void) { - return gd->timer_rate_hz; + return gd->arch.timer_rate_hz; } #ifdef CONFIG_HW_WATCHDOG diff --git a/arch/arm/cpu/arm926ejs/kirkwood/timer.c b/arch/arm/cpu/arm926ejs/kirkwood/timer.c index f5d0160397..85e81e3f44 100644 --- a/arch/arm/cpu/arm926ejs/kirkwood/timer.c +++ b/arch/arm/cpu/arm926ejs/kirkwood/timer.c @@ -86,8 +86,8 @@ struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE; DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc ulong get_timer_masked(void) { diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/timer.c b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c index 75314b91b3..c6486c13eb 100644 --- a/arch/arm/cpu/arm926ejs/mb86r0x/timer.c +++ b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c @@ -35,8 +35,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc static inline unsigned long long tick_to_time(unsigned long long tick) { diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c index b9914186b1..679273b2b4 100644 --- a/arch/arm/cpu/arm926ejs/mx25/generic.c +++ b/arch/arm/cpu/arm926ejs/mx25/generic.c @@ -229,9 +229,9 @@ int get_clocks(void) { #ifdef CONFIG_FSL_ESDHC #if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); #else - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); #endif #endif return 0; diff --git a/arch/arm/cpu/arm926ejs/mx25/timer.c b/arch/arm/cpu/arm926ejs/mx25/timer.c index 4dc4041c08..f8bebccd63 100644 --- a/arch/arm/cpu/arm926ejs/mx25/timer.c +++ b/arch/arm/cpu/arm926ejs/mx25/timer.c @@ -44,8 +44,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) /* * "time" is measured in 1 / CONFIG_SYS_HZ seconds, diff --git a/arch/arm/cpu/arm926ejs/mx27/timer.c b/arch/arm/cpu/arm926ejs/mx27/timer.c index a5dd68425a..07e132ad2f 100644 --- a/arch/arm/cpu/arm926ejs/mx27/timer.c +++ b/arch/arm/cpu/arm926ejs/mx27/timer.c @@ -45,8 +45,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) /* * "time" is measured in 1 / CONFIG_SYS_HZ seconds, diff --git a/arch/arm/cpu/arm926ejs/mxs/timer.c b/arch/arm/cpu/arm926ejs/mxs/timer.c index 4ed75e604c..373841180f 100644 --- a/arch/arm/cpu/arm926ejs/mxs/timer.c +++ b/arch/arm/cpu/arm926ejs/mxs/timer.c @@ -36,8 +36,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->tbl) -#define lastdec (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastdec (gd->arch.lastinc) /* * This driver uses 1kHz clock source. diff --git a/arch/arm/cpu/arm926ejs/omap/timer.c b/arch/arm/cpu/arm926ejs/omap/timer.c index 390c9c8abb..34ec7b2b1c 100644 --- a/arch/arm/cpu/arm926ejs/omap/timer.c +++ b/arch/arm/cpu/arm926ejs/omap/timer.c @@ -44,8 +44,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc int timer_init (void) { diff --git a/arch/arm/cpu/arm926ejs/orion5x/timer.c b/arch/arm/cpu/arm926ejs/orion5x/timer.c index 8a8aaf15d9..f7233512cd 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/timer.c +++ b/arch/arm/cpu/arm926ejs/orion5x/timer.c @@ -92,8 +92,8 @@ static inline ulong read_timer(void) DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc ulong get_timer_masked(void) { diff --git a/arch/arm/cpu/arm926ejs/pantheon/timer.c b/arch/arm/cpu/arm926ejs/pantheon/timer.c index 28aadada70..2d9ddbad24 100644 --- a/arch/arm/cpu/arm926ejs/pantheon/timer.c +++ b/arch/arm/cpu/arm926ejs/pantheon/timer.c @@ -60,7 +60,7 @@ struct panthtmr_registers { #define COUNT_RD_REQ 0x1 DECLARE_GLOBAL_DATA_PTR; -/* Using gd->tbu from timestamp and gd->tbl for lastdec */ +/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */ /* * For preventing risk of instability in reading counter value, @@ -90,16 +90,16 @@ ulong get_timer_masked(void) { ulong now = read_timer(); - if (now >= gd->tbl) { + if (now >= gd->arch.tbl) { /* normal mode */ - gd->tbu += now - gd->tbl; + gd->arch.tbu += now - gd->arch.tbl; } else { /* we have an overflow ... */ - gd->tbu += now + TIMER_LOAD_VAL - gd->tbl; + gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl; } - gd->tbl = now; + gd->arch.tbl = now; - return gd->tbu; + return gd->arch.tbu; } ulong get_timer(ulong base) @@ -144,9 +144,9 @@ int timer_init(void) /* Enable timer 0 */ writel(0x1, &panthtimers->cer); - /* init the gd->tbu and gd->tbl value */ - gd->tbl = read_timer(); - gd->tbu = 0; + /* init the gd->arch.tbu and gd->arch.tbl value */ + gd->arch.tbl = read_timer(); + gd->arch.tbu = 0; return 0; } diff --git a/arch/arm/cpu/arm926ejs/spear/timer.c b/arch/arm/cpu/arm926ejs/spear/timer.c index 1dc78600c2..de4ba7b213 100644 --- a/arch/arm/cpu/arm926ejs/spear/timer.c +++ b/arch/arm/cpu/arm926ejs/spear/timer.c @@ -38,8 +38,8 @@ static struct misc_regs *const misc_regs_p = DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc int timer_init(void) { diff --git a/arch/arm/cpu/arm926ejs/versatile/timer.c b/arch/arm/cpu/arm926ejs/versatile/timer.c index f58e151662..b36d6d93a5 100644 --- a/arch/arm/cpu/arm926ejs/versatile/timer.c +++ b/arch/arm/cpu/arm926ejs/versatile/timer.c @@ -44,8 +44,8 @@ DECLARE_GLOBAL_DATA_PTR; -#define timestamp gd->tbl -#define lastdec gd->lastinc +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc #define TIMER_ENABLE (1 << 7) #define TIMER_MODE_MSK (1 << 6) diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4bc0..ee8c2b3fa5 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -32,7 +32,7 @@ COBJS += cache_v7.o COBJS += cpu.o COBJS += syslib.o -ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA),) SOBJS += lowlevel_init.o endif diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 2b584e0a53..1c8b6177dd 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -55,6 +55,9 @@ void spl_board_init(void) #ifdef CONFIG_SPL_NAND_SUPPORT gpmc_init(); #endif +#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT) + arch_misc_init(); +#endif } int board_mmc_init(bd_t *bis) diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c index 9f8bc93447..36bea5f94c 100644 --- a/arch/arm/cpu/armv7/omap-common/timer.c +++ b/arch/arm/cpu/armv7/omap-common/timer.c @@ -56,8 +56,9 @@ int timer_init(void) &timer_base->tclr); /* reset time, capture current incrementer value time */ - gd->lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - gd->tbl = 0; /* start "advancing" time stamp from 0 */ + gd->arch.lastinc = readl(&timer_base->tcrr) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + gd->arch.tbl = 0; /* start "advancing" time stamp from 0 */ return 0; } @@ -91,14 +92,15 @@ ulong get_timer_masked(void) /* current tick value */ ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - if (now >= gd->lastinc) /* normal mode (non roll) */ + if (now >= gd->arch.lastinc) { /* normal mode (non roll) */ /* move stamp fordward with absoulte diff ticks */ - gd->tbl += (now - gd->lastinc); - else /* we have rollover of incrementer */ - gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) - - gd->lastinc) + now; - gd->lastinc = now; - return gd->tbl; + gd->arch.tbl += (now - gd->arch.lastinc); + } else { /* we have rollover of incrementer */ + gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / + CONFIG_SYS_HZ)) - gd->arch.lastinc) + now; + } + gd->arch.lastinc = now; + return gd->arch.tbl; } /* diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c index bb0e795e66..e78c716d3f 100644 --- a/arch/arm/cpu/armv7/s5p-common/timer.c +++ b/arch/arm/cpu/armv7/s5p-common/timer.c @@ -105,8 +105,8 @@ void reset_timer_masked(void) struct s5p_timer *const timer = s5p_get_base_timer(); /* reset time */ - gd->lastinc = readl(&timer->tcnto4); - gd->tbl = 0; + gd->arch.lastinc = readl(&timer->tcnto4); + gd->arch.tbl = 0; } unsigned long get_timer_masked(void) @@ -123,14 +123,14 @@ unsigned long get_current_tick(void) unsigned long now = readl(&timer->tcnto4); unsigned long count_value = readl(&timer->tcntb4); - if (gd->lastinc >= now) - gd->tbl += gd->lastinc - now; + if (gd->arch.lastinc >= now) + gd->arch.tbl += gd->arch.lastinc - now; else - gd->tbl += gd->lastinc + count_value - now; + gd->arch.tbl += gd->arch.lastinc + count_value - now; - gd->lastinc = now; + gd->arch.lastinc = now; - return gd->tbl; + return gd->arch.tbl; } /* diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c index 321e9b4181..efa28c2ae9 100644 --- a/arch/arm/cpu/armv7/socfpga/timer.c +++ b/arch/arm/cpu/armv7/socfpga/timer.c @@ -80,16 +80,16 @@ ulong get_timer_masked(void) { /* current tick value */ ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ); - if (gd->lastinc >= now) { + if (gd->arch.lastinc >= now) { /* normal mode (non roll) */ /* move stamp forward with absolute diff ticks */ - gd->tbl += gd->lastinc - now; + gd->arch.tbl += gd->arch.lastinc - now; } else { /* we have overflow of the count down timer */ - gd->tbl += TIMER_LOAD_VAL - gd->lastinc + now; + gd->arch.tbl += TIMER_LOAD_VAL - gd->arch.lastinc + now; } - gd->lastinc = now; - return gd->tbl; + gd->arch.lastinc = now; + return gd->arch.tbl; } /* @@ -98,7 +98,8 @@ ulong get_timer_masked(void) void reset_timer(void) { /* capture current decrementer value time */ - gd->lastinc = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ); + gd->arch.lastinc = read_timer() / + (CONFIG_TIMER_CLOCK_KHZ / CONFIG_SYS_HZ); /* start "advancing" time stamp from 0 */ - gd->tbl = 0; + gd->arch.tbl = 0; } diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index dcc1f831bc..6b59529d5d 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -251,12 +251,12 @@ ENTRY(c_runtime_cpu_setup) /* * Move vector table */ -#if !defined(CONFIG_TEGRA20) +#if !defined(CONFIG_TEGRA) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif /* !Tegra20 */ +#endif /* !Tegra */ bx lr diff --git a/arch/arm/cpu/armv7/tegra114/Makefile b/arch/arm/cpu/armv7/tegra114/Makefile new file mode 100644 index 0000000000..eb98c8ea17 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra114/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/tegra114/config.mk b/arch/arm/cpu/armv7/tegra114/config.mk new file mode 100644 index 0000000000..cb1a19da82 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra114/config.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# +CONFIG_ARCH_DEVICE_TREE := tegra114 diff --git a/arch/arm/cpu/armv7/tegra30/Makefile b/arch/arm/cpu/armv7/tegra30/Makefile new file mode 100644 index 0000000000..04adb52994 --- /dev/null +++ b/arch/arm/cpu/armv7/tegra30/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/tegra30/config.mk b/arch/arm/cpu/armv7/tegra30/config.mk new file mode 100644 index 0000000000..719ca8192e --- /dev/null +++ b/arch/arm/cpu/armv7/tegra30/config.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# +CONFIG_ARCH_DEVICE_TREE := tegra30 diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c index 79aad9983a..a4b88f3815 100644 --- a/arch/arm/cpu/armv7/u8500/timer.c +++ b/arch/arm/cpu/armv7/u8500/timer.c @@ -100,12 +100,14 @@ ulong get_timer_masked(void) /* current tick value */ ulong now = TICKS_TO_HZ(READ_TIMER()); - if (now >= gd->lastinc) /* normal (non rollover) */ - gd->tbl += (now - gd->lastinc); - else /* rollover */ - gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now; - gd->lastinc = now; - return gd->tbl; + if (now >= gd->arch.lastinc) { /* normal (non rollover) */ + gd->arch.tbl += (now - gd->arch.lastinc); + } else { /* rollover */ + gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - + gd->arch.lastinc) + now; + } + gd->arch.lastinc = now; + return gd->arch.tbl; } /* Delay x useconds */ @@ -132,7 +134,7 @@ ulong get_timer(ulong base) /* * Emulation of Power architecture long long timebase. * - * TODO: Support gd->tbu for real long long timebase. + * TODO: Support gd->arch.tbu for real long long timebase. */ unsigned long long get_ticks(void) { diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile index 499ace4a62..388085dc2a 100644 --- a/arch/arm/cpu/armv7/zynq/Makefile +++ b/arch/arm/cpu/armv7/zynq/Makefile @@ -30,6 +30,7 @@ LIB = $(obj)lib$(SOC).o COBJS-y := timer.o COBJS-y += cpu.o +COBJS-y += slcr.o COBJS := $(COBJS-y) diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/cpu/armv7/zynq/cpu.c index ab615cc7d4..e8f4c19d49 100644 --- a/arch/arm/cpu/armv7/zynq/cpu.c +++ b/arch/arm/cpu/armv7/zynq/cpu.c @@ -21,11 +21,37 @@ * MA 02111-1307 USA */ #include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/hardware.h> -inline void lowlevel_init(void) {} +void lowlevel_init(void) +{ + zynq_slcr_unlock(); + /* remap DDR to zero, FILTERSTART */ + writel(0, &scu_base->filter_start); + + /* Device config APB, unlock the PCAP */ + writel(0x757BDF0D, &devcfg_base->unlock); + writel(0xFFFFFFFF, &devcfg_base->rom_shadow); + + /* OCM_CFG, Mask out the ROM, map ram into upper addresses */ + writel(0x1F, &slcr_base->ocm_cfg); + /* FPGA_RST_CTRL, clear resets on AXI fabric ports */ + writel(0x0, &slcr_base->fpga_rst_ctrl); + /* TZ_DDR_RAM, Set DDR trust zone non-secure */ + writel(0xFFFFFFFF, &slcr_base->trust_zone); + /* Set urgent bits with register */ + writel(0x0, &slcr_base->ddr_urgent_sel); + /* Urgent write, ports S2/S3 */ + writel(0xC, &slcr_base->ddr_urgent); + + zynq_slcr_lock(); +} void reset_cpu(ulong addr) { + zynq_slcr_cpu_reset(); while (1) ; } diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c new file mode 100644 index 0000000000..788a8fd14f --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013 Xilinx Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <malloc.h> +#include <asm/arch/hardware.h> + +#define SLCR_LOCK_MAGIC 0x767B +#define SLCR_UNLOCK_MAGIC 0xDF0D + +static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ + +void zynq_slcr_lock(void) +{ + if (!slcr_lock) + writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); +} + +void zynq_slcr_unlock(void) +{ + if (slcr_lock) + writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); +} + +/* Reset the entire system */ +void zynq_slcr_cpu_reset(void) +{ + /* + * Unlock the SLCR then reset the system. + * Note that this seems to require raw i/o + * functions or there's a lockup? + */ + zynq_slcr_unlock(); + + /* + * Clear 0x0F000000 bits of reboot status register to workaround + * the FSBL not loading the bitstream after soft-reboot + * This is a temporary solution until we know more. + */ + clrbits_le32(&slcr_base->reboot_status, 0xF000000); + + writel(1, &slcr_base->pss_rst_ctrl); +} diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c index 323e7b5a49..45b405a4ba 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -83,9 +83,9 @@ int timer_init(void) emask); /* Reset time */ - gd->lastinc = readl(&timer_base->counter) / + gd->arch.lastinc = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ); - gd->tbl = 0; + gd->arch.tbl = 0; return 0; } @@ -100,16 +100,16 @@ ulong get_timer_masked(void) now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ); - if (gd->lastinc >= now) { + if (gd->arch.lastinc >= now) { /* Normal mode */ - gd->tbl += gd->lastinc - now; + gd->arch.tbl += gd->arch.lastinc - now; } else { /* We have an overflow ... */ - gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now; + gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now; } - gd->lastinc = now; + gd->arch.lastinc = now; - return gd->tbl; + return gd->arch.tbl; } void __udelay(unsigned long usec) diff --git a/arch/arm/cpu/ixp/timer.c b/arch/arm/cpu/ixp/timer.c index 087ddf80ef..663d989089 100644 --- a/arch/arm/cpu/ixp/timer.c +++ b/arch/arm/cpu/ixp/timer.c @@ -70,23 +70,23 @@ unsigned long long get_ticks(void) if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) { /* rollover of timestamp timer register */ - gd->timestamp += (0xFFFFFFFF - gd->lastinc) + now + 1; + gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1; writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST); } else { /* move stamp forward with absolut diff ticks */ - gd->timestamp += (now - gd->lastinc); + gd->arch.timestamp += (now - gd->arch.lastinc); } - gd->lastinc = now; - return gd->timestamp; + gd->arch.lastinc = now; + return gd->arch.timestamp; } void reset_timer_masked(void) { /* capture current timestamp counter */ - gd->lastinc = readl(IXP425_OSTS_B); + gd->arch.lastinc = readl(IXP425_OSTS_B); /* start "advancing" time stamp from 0 */ - gd->timestamp = 0; + gd->arch.timestamp = 0; } ulong get_timer_masked(void) diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index a8f7462c1b..212b31eb68 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -31,8 +31,8 @@ DECLARE_GLOBAL_DATA_PTR; #define TIMER_LOAD_VAL 0xffffffff -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) #define TIMER_FREQ_HZ 3250000 diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile index 38e90d3143..8e95c7ee1d 100644 --- a/arch/arm/cpu/tegra-common/Makefile +++ b/arch/arm/cpu/tegra-common/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libcputegra-common.o SOBJS += lowlevel_init.o -COBJS-y += ap.o board.o sys_info.o timer.o +COBJS-y += ap.o board.o sys_info.o timer.o clock.o SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c index c4eb137480..236cda8419 100644 --- a/arch/arm/cpu/tegra-common/ap.c +++ b/arch/arm/cpu/tegra-common/ap.c @@ -20,13 +20,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + +/* Tegra AP (Application Processor) code */ + #include <common.h> #include <asm/io.h> #include <asm/arch/gp_padctrl.h> #include <asm/arch-tegra/ap.h> +#include <asm/arch-tegra/clock.h> #include <asm/arch-tegra/fuse.h> #include <asm/arch-tegra/pmc.h> #include <asm/arch-tegra/scu.h> +#include <asm/arch-tegra/tegra.h> #include <asm/arch-tegra/warmboot.h> int tegra_get_chip_type(void) @@ -38,7 +43,7 @@ int tegra_get_chip_type(void) /* * This is undocumented, Chip ID is bits 15:8 of the register * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for - * Tegra30 + * Tegra30, and 0x35 for T114. */ gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; @@ -58,6 +63,18 @@ int tegra_get_chip_type(void) return TEGRA_SOC_T25; } break; + case CHIPID_TEGRA30: + switch (tegra_sku_id) { + case SKU_ID_T30: + return TEGRA_SOC_T30; + } + break; + case CHIPID_TEGRA114: + switch (tegra_sku_id) { + case SKU_ID_T114_ENG: + return TEGRA_SOC_T114; + } + break; } /* unknown sku id */ return TEGRA_SOC_UNKNOWN; @@ -93,7 +110,7 @@ static u32 get_odmdata(void) u32 bct_start, odmdata; - bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); + bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); return odmdata; @@ -127,5 +144,5 @@ void s_init(void) "orr r0, r0, #0x41\n" "mcr p15, 0, r0, c1, c0, 1\n"); - /* FIXME: should have ap20's L2 disabled too? */ + /* FIXME: should have SoC's L2 disabled too? */ } diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c index b2e10c6db8..58ea6289d3 100644 --- a/arch/arm/cpu/tegra-common/board.c +++ b/arch/arm/cpu/tegra-common/board.c @@ -37,8 +37,10 @@ enum { /* UARTs which we can enable */ UARTA = 1 << 0, UARTB = 1 << 1, + UARTC = 1 << 2, UARTD = 1 << 3, - UART_COUNT = 4, + UARTE = 1 << 4, + UART_COUNT = 5, }; /* @@ -54,16 +56,37 @@ unsigned int query_sdram_size(void) reg = readl(&pmc->pmc_scratch20); debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg); - /* bits 31:28 in OdmData are used for RAM size */ +#if defined(CONFIG_TEGRA20) + /* bits 30:28 in OdmData are used for RAM size on T20 */ + reg &= 0x70000000; + switch ((reg) >> 28) { case 1: return 0x10000000; /* 256 MB */ + case 0: case 2: default: return 0x20000000; /* 512 MB */ case 3: return 0x40000000; /* 1GB */ } +#else /* Tegra30/Tegra114 */ + /* bits 31:28 in OdmData are used for RAM size on T30 */ + switch ((reg) >> 28) { + case 0: + case 1: + default: + return 0x10000000; /* 256 MB */ + case 2: + return 0x20000000; /* 512 MB */ + case 3: + return 0x30000000; /* 768 MB */ + case 4: + return 0x40000000; /* 1GB */ + case 8: + return 0x7ff00000; /* 2GB - 1MB */ + } +#endif } int dram_init(void) @@ -82,19 +105,33 @@ int checkboard(void) #endif /* CONFIG_DISPLAY_BOARDINFO */ static int uart_configs[] = { -#if defined(CONFIG_TEGRA_UARTA_UAA_UAB) +#if defined(CONFIG_TEGRA20) + #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) FUNCMUX_UART1_UAA_UAB, -#elif defined(CONFIG_TEGRA_UARTA_GPU) + #elif defined(CONFIG_TEGRA_UARTA_GPU) FUNCMUX_UART1_GPU, -#elif defined(CONFIG_TEGRA_UARTA_SDIO1) + #elif defined(CONFIG_TEGRA_UARTA_SDIO1) FUNCMUX_UART1_SDIO1, -#else + #else FUNCMUX_UART1_IRRX_IRTX, #endif - FUNCMUX_UART2_IRDA, + FUNCMUX_UART2_UAD, -1, FUNCMUX_UART4_GMC, -1, +#elif defined(CONFIG_TEGRA30) + FUNCMUX_UART1_ULPI, /* UARTA */ + -1, + -1, + -1, + -1, +#else /* Tegra114 */ + -1, + -1, + -1, + FUNCMUX_UART4_GMI, /* UARTD */ + -1, +#endif }; /** @@ -109,6 +146,7 @@ static void setup_uarts(int uart_ids) PERIPH_ID_UART2, PERIPH_ID_UART3, PERIPH_ID_UART4, + PERIPH_ID_UART5, }; size_t i; @@ -132,9 +170,15 @@ void board_init_uart_f(void) #ifdef CONFIG_TEGRA_ENABLE_UARTB uart_ids |= UARTB; #endif +#ifdef CONFIG_TEGRA_ENABLE_UARTC + uart_ids |= UARTC; +#endif #ifdef CONFIG_TEGRA_ENABLE_UARTD uart_ids |= UARTD; #endif +#ifdef CONFIG_TEGRA_ENABLE_UARTE + uart_ids |= UARTE; +#endif setup_uarts(uart_ids); } diff --git a/arch/arm/cpu/tegra-common/clock.c b/arch/arm/cpu/tegra-common/clock.c new file mode 100644 index 0000000000..49a06334cb --- /dev/null +++ b/arch/arm/cpu/tegra-common/clock.c @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra SoC common clock control functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/timer.h> +#include <div64.h> +#include <fdtdec.h> + +/* + * This is our record of the current clock rate of each clock. We don't + * fill all of these in since we are only really interested in clocks which + * we use as parents. + */ +static unsigned pll_rate[CLOCK_ID_COUNT]; + +/* + * The oscillator frequency is fixed to one of four set values. Based on this + * the other clocks are set up appropriately. + */ +static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { + 13000000, + 19200000, + 12000000, + 26000000, +}; + +/* return 1 if a peripheral ID is in range */ +#define clock_type_id_isvalid(id) ((id) >= 0 && \ + (id) < CLOCK_TYPE_COUNT) + +char pllp_valid = 1; /* PLLP is set up correctly */ + +/* return 1 if a periphc_internal_id is in range */ +#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ + (id) < PERIPHC_COUNT) + +/* number of clock outputs of a PLL */ +static const u8 pll_num_clkouts[] = { + 1, /* PLLC */ + 1, /* PLLM */ + 4, /* PLLP */ + 1, /* PLLA */ + 0, /* PLLU */ + 0, /* PLLD */ +}; + +int clock_get_osc_bypass(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; +} + +/* Returns a pointer to the registers of the given pll */ +static struct clk_pll *get_pll(enum clock_id clkid) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + assert(clock_id_is_pll(clkid)); + return &clkrst->crc_pll[clkid]; +} + +int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, + u32 *divp, u32 *cpcon, u32 *lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + assert(clkid != CLOCK_ID_USB); + + /* Safety check, adds to code size but is small */ + if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) + return -1; + data = readl(&pll->pll_base); + *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; + *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + data = readl(&pll->pll_misc); + *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; + *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; + + return 0; +} + +unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + /* + * We cheat by treating all PLL (except PLLU) in the same fashion. + * This works only because: + * - same fields are always mapped at same offsets, except DCCON + * - DCCON is always 0, doesn't conflict + * - M,N, P of PLLP values are ignored for PLLP + */ + data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); + writel(data, &pll->pll_misc); + + data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | + (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); + + if (clkid == CLOCK_ID_USB) + data |= divp << PLLU_VCO_FREQ_SHIFT; + else + data |= divp << PLL_DIVP_SHIFT; + writel(data, &pll->pll_base); + + /* calculate the stable time */ + return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; +} + +void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, + unsigned divisor) +{ + u32 *reg = get_periph_source_reg(periph_id); + u32 value; + + value = readl(reg); + + value &= ~OUT_CLK_SOURCE_MASK; + value |= source << OUT_CLK_SOURCE_SHIFT; + + value &= ~OUT_CLK_DIVISOR_MASK; + value |= divisor << OUT_CLK_DIVISOR_SHIFT; + + writel(value, reg); +} + +void clock_ll_set_source(enum periph_id periph_id, unsigned source) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); +} + +/** + * Given the parent's rate and the required rate for the children, this works + * out the peripheral clock divider to use, in 7.1 binary format. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @return divider which should be used + */ +static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate) +{ + u64 divider = parent_rate * 2; + unsigned max_divider = 1 << divider_bits; + + divider += rate - 1; + do_div(divider, rate); + + if ((s64)divider - 2 < 0) + return 0; + + if ((s64)divider - 2 >= max_divider) + return -1; + + return divider - 2; +} + +int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) +{ + struct clk_pll *pll = get_pll(clkid); + int data = 0, div = 0, offset = 0; + + if (!clock_id_is_pll(clkid)) + return -1; + + if (pllout + 1 > pll_num_clkouts[clkid]) + return -1; + + div = clk_get_divider(8, pll_rate[clkid], rate); + + if (div < 0) + return -1; + + /* out2 and out4 are in the high part of the register */ + if (pllout == PLL_OUT2 || pllout == PLL_OUT4) + offset = 16; + + data = (div << PLL_OUT_RATIO_SHIFT) | + PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; + clrsetbits_le32(&pll->pll_out[pllout >> 1], + PLL_OUT_RATIO_MASK << offset, data << offset); + + return 0; +} + +/** + * Given the parent's rate and the divider in 7.1 format, this works out the + * resulting peripheral clock rate. + * + * @param parent_rate clock rate of parent clock in Hz + * @param divider which should be used in 7.1 format + * @return effective clock rate of peripheral + */ +static unsigned long get_rate_from_divider(unsigned long parent_rate, + int divider) +{ + u64 rate; + + rate = (u64)parent_rate * 2; + do_div(rate, divider + 2); + return rate; +} + +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent) +{ + u32 *reg = get_periph_source_reg(periph_id); + + return get_rate_from_divider(pll_rate[parent], + (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); +} + +/** + * Find the best available 7.1 format divisor given a parent clock rate and + * required child clock rate. This function assumes that a second-stage + * divisor is available which can divide by powers of 2 from 1 to 256. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @param extra_div value for the second-stage divisor (not set if this + * function returns -1. + * @return divider which should be used, or -1 if nothing is valid + * + */ +static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate, int *extra_div) +{ + int shift; + int best_divider = -1; + int best_error = rate; + + /* try dividers from 1 to 256 and find closest match */ + for (shift = 0; shift <= 8 && best_error > 0; shift++) { + unsigned divided_parent = parent_rate >> shift; + int divider = clk_get_divider(divider_bits, divided_parent, + rate); + unsigned effective_rate = get_rate_from_divider(divided_parent, + divider); + int error = rate - effective_rate; + + /* Given a valid divider, look for the lowest error */ + if (divider != -1 && error < best_error) { + best_error = error; + *extra_div = 1 << shift; + best_divider = divider; + } + } + + /* return what we found - *extra_div will already be set */ + return best_divider; +} + +/** + * Adjust peripheral PLL to use the given divider and source. + * + * @param periph_id peripheral to adjust + * @param source Source number (0-3 or 0-7) + * @param mux_bits Number of mux bits (2 or 4) + * @param divider Required divider in 7.1 or 15.1 format + * @return 0 if ok, -1 on error (requesting a parent clock which is not valid + * for this peripheral) + */ +static int adjust_periph_pll(enum periph_id periph_id, int source, + int mux_bits, unsigned divider) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, + divider << OUT_CLK_DIVISOR_SHIFT); + udelay(1); + + /* work out the source clock and set it */ + if (source < 0) + return -1; + if (mux_bits == 4) { + clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK, + source << OUT_CLK_SOURCE4_SHIFT); + } else { + clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, + source << OUT_CLK_SOURCE_SHIFT); + } + udelay(2); + return 0; +} + +unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, + enum clock_id parent, unsigned rate, int *extra_div) +{ + unsigned effective_rate; + int mux_bits, divider_bits, source; + int divider; + + /* work out the source clock and set it */ + source = get_periph_clock_source(periph_id, parent, &mux_bits, + ÷r_bits); + + if (extra_div) + divider = find_best_divider(divider_bits, pll_rate[parent], + rate, extra_div); + else + divider = clk_get_divider(divider_bits, pll_rate[parent], + rate); + assert(divider >= 0); + if (adjust_periph_pll(periph_id, source, mux_bits, divider)) + return -1U; + debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, + get_periph_source_reg(periph_id), + readl(get_periph_source_reg(periph_id))); + + /* Check what we ended up with. This shouldn't matter though */ + effective_rate = clock_get_periph_rate(periph_id, parent); + if (extra_div) + effective_rate /= *extra_div; + if (rate != effective_rate) + debug("Requested clock rate %u not honored (got %u)\n", + rate, effective_rate); + return effective_rate; +} + +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate) +{ + unsigned effective_rate; + + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + + effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, + NULL); + + reset_set_enable(periph_id, 0); + return effective_rate; +} + +void clock_enable(enum periph_id clkid) +{ + clock_set_enable(clkid, 1); +} + +void clock_disable(enum periph_id clkid) +{ + clock_set_enable(clkid, 0); +} + +void reset_periph(enum periph_id periph_id, int us_delay) +{ + /* Put peripheral into reset */ + reset_set_enable(periph_id, 1); + udelay(us_delay); + + /* Remove reset */ + reset_set_enable(periph_id, 0); + + udelay(us_delay); +} + +void reset_cmplx_set_enable(int cpu, int which, int reset) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 mask; + + /* Form the mask, which depends on the cpu chosen (2 or 4) */ + assert(cpu >= 0 && cpu < MAX_NUM_CPU); + mask = which << cpu; + + /* either enable or disable those reset for that CPU */ + if (reset) + writel(mask, &clkrst->crc_cpu_cmplx_set); + else + writel(mask, &clkrst->crc_cpu_cmplx_clr); +} + +unsigned clock_get_rate(enum clock_id clkid) +{ + struct clk_pll *pll; + u32 base; + u32 divm; + u64 parent_rate; + u64 rate; + + parent_rate = osc_freq[clock_get_osc_freq()]; + if (clkid == CLOCK_ID_OSC) + return parent_rate; + + pll = get_pll(clkid); + base = readl(&pll->pll_base); + + /* Oh for bf_unpack()... */ + rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); + divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + if (clkid == CLOCK_ID_USB) + divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; + else + divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + do_div(rate, divm); + return rate; +} + +/** + * Set the output frequency you want for each PLL clock. + * PLL output frequencies are programmed by setting their N, M and P values. + * The governing equations are: + * VCO = (Fi / m) * n, Fo = VCO / (2^p) + * where Fo is the output frequency from the PLL. + * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) + * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 + * Please see Tegra TRM section 5.3 to get the detail for PLL Programming + * + * @param n PLL feedback divider(DIVN) + * @param m PLL input divider(DIVN) + * @param p post divider(DIVP) + * @param cpcon base PLL charge pump(CPCON) + * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot + * be overriden), 1 if PLL is already correct + */ +int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) +{ + u32 base_reg; + u32 misc_reg; + struct clk_pll *pll; + + pll = get_pll(clkid); + + base_reg = readl(&pll->pll_base); + + /* Set BYPASS, m, n and p to PLL_BASE */ + base_reg &= ~PLL_DIVM_MASK; + base_reg |= m << PLL_DIVM_SHIFT; + + base_reg &= ~PLL_DIVN_MASK; + base_reg |= n << PLL_DIVN_SHIFT; + + base_reg &= ~PLL_DIVP_MASK; + base_reg |= p << PLL_DIVP_SHIFT; + + if (clkid == CLOCK_ID_PERIPH) { + /* + * If the PLL is already set up, check that it is correct + * and record this info for clock_verify() to check. + */ + if (base_reg & PLL_BASE_OVRRIDE_MASK) { + base_reg |= PLL_ENABLE_MASK; + if (base_reg != readl(&pll->pll_base)) + pllp_valid = 0; + return pllp_valid ? 1 : -1; + } + base_reg |= PLL_BASE_OVRRIDE_MASK; + } + + base_reg |= PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + /* Set cpcon to PLL_MISC */ + misc_reg = readl(&pll->pll_misc); + misc_reg &= ~PLL_CPCON_MASK; + misc_reg |= cpcon << PLL_CPCON_SHIFT; + writel(misc_reg, &pll->pll_misc); + + /* Enable PLL */ + base_reg |= PLL_ENABLE_MASK; + writel(base_reg, &pll->pll_base); + + /* Disable BYPASS */ + base_reg &= ~PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + return 0; +} + +void clock_ll_start_uart(enum periph_id periph_id) +{ + /* Assert UART reset and enable clock */ + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ + + /* wait for 2us */ + udelay(2); + + /* De-assert reset to UART */ + reset_set_enable(periph_id, 0); +} + +#ifdef CONFIG_OF_CONTROL +int clock_decode_periph_id(const void *blob, int node) +{ + enum periph_id id; + u32 cell[2]; + int err; + + err = fdtdec_get_int_array(blob, node, "clocks", cell, + ARRAY_SIZE(cell)); + if (err) + return -1; + id = clk_id_to_periph_id(cell[1]); + assert(clock_periph_id_isvalid(id)); + return id; +} +#endif /* CONFIG_OF_CONTROL */ + +int clock_verify(void) +{ + struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); + u32 reg = readl(&pll->pll_base); + + if (!pllp_valid) { + printf("Warning: PLLP %x is not correct\n", reg); + return -1; + } + debug("PLLP %x is correct\n", reg); + return 0; +} + +void clock_init(void) +{ + pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); + pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); + pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); + pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); + pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; + pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU); + debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); + debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); + debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); + debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]); + debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]); +} diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c index 1a0bb561a7..4632f15d5b 100644 --- a/arch/arm/cpu/tegra-common/sys_info.c +++ b/arch/arm/cpu/tegra-common/sys_info.c @@ -22,12 +22,26 @@ */ #include <common.h> +#include <linux/ctype.h> #ifdef CONFIG_DISPLAY_CPUINFO +void upstring(char *s) +{ + while (*s) { + *s = toupper(*s); + s++; + } +} + /* Print CPU information */ int print_cpuinfo(void) { - puts("TEGRA20\n"); + char soc_name[10]; + + strncpy(soc_name, CONFIG_SYS_SOC, 10); + upstring(soc_name); + puts(soc_name); + puts("\n"); /* TBD: Add printf of major/minor rev info, stepping, etc. */ return 0; diff --git a/arch/arm/cpu/tegra-common/timer.c b/arch/arm/cpu/tegra-common/timer.c index 034ea5ad28..51902e9544 100644 --- a/arch/arm/cpu/tegra-common/timer.c +++ b/arch/arm/cpu/tegra-common/timer.c @@ -75,14 +75,14 @@ ulong get_timer_masked(void) /* current tick value */ now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ); - if (now >= gd->lastinc) /* normal mode (non roll) */ + if (now >= gd->arch.lastinc) /* normal mode (non roll) */ /* move stamp forward with absolute diff ticks */ - gd->tbl += (now - gd->lastinc); + gd->arch.tbl += (now - gd->arch.lastinc); else /* we have rollover of incrementer */ - gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ)) - - gd->lastinc) + now; - gd->lastinc = now; - return gd->tbl; + gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ)) + - gd->arch.lastinc) + now; + gd->arch.lastinc = now; + return gd->arch.tbl; } /* diff --git a/arch/arm/cpu/tegra114-common/Makefile b/arch/arm/cpu/tegra114-common/Makefile new file mode 100644 index 0000000000..5b53a71ba3 --- /dev/null +++ b/arch/arm/cpu/tegra114-common/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC)-common.o + +COBJS-y += clock.o funcmux.o pinmux.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/tegra114-common/clock.c b/arch/arm/cpu/tegra114-common/clock.c new file mode 100644 index 0000000000..9b29ce1dd2 --- /dev/null +++ b/arch/arm/cpu/tegra114-common/clock.c @@ -0,0 +1,655 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 Clock control functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/timer.h> +#include <div64.h> +#include <fdtdec.h> + +/* + * Clock types that we can use as a source. The Tegra114 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCMT16, + CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +enum { + MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */ + MASK_BITS_31_29, + MASK_BITS_29_28, +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_29_28} +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_I2C5, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x38h */ /* Jumps to reg offset 0x3B0h */ + TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), + + /* 0x40 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x48 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x50 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RTC), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(RESERVED16), + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 24 */ + PERIPHC_G3D, + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(RESERVED39), + + /* 40 */ + NONE(KFUSE), + NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, + PERIPHC_I2C5, + + /* 48 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + NONE(CSI), + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + PERIPHC_SPEEDO, + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(DTV), + + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 88 */ + NONE(CRAM2), + NONE(RESERVED89), + NONE(MDOUBLER), + NONE(RESERVED91), + NONE(SUSOUT), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(RESERVED95), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + PERIPHC_G3D2, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 08 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 16 */ + NONE(ATOMICS), + NONE(RESERVED17), + NONE(RESERVED18), + NONE(RESERVED19), + NONE(RESERVED20), + NONE(RESERVED21), + NONE(RESERVED22), + PERIPHC_ACTMON, + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + NONE(RESERVED26), + NONE(RESERVED27), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(RESERVED30), + NONE(RESERVED31), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(RESERVED1_SATACOLD), + NONE(RESERVED2_PCIERX0), + NONE(RESERVED3_PCIERX1), + NONE(RESERVED4_PCIERX2), + NONE(RESERVED5_PCIERX3), + NONE(RESERVED6_PCIERX4), + NONE(RESERVED7_PCIERX5), + + /* 40 */ + NONE(CEC), + NONE(PCIE2_IOBIST), + NONE(EMC_IOBIST), + NONE(HDMI_IOBIST), + NONE(SATA_IOBIST), + NONE(MIPI_IOBIST), + NONE(EMC1_IOBIST), + NONE(XUSB), + + /* 48 */ + NONE(CILAB), + NONE(CILCD), + NONE(CILE), + NONE(DSIA_LP), + NONE(DSIB_LP), + NONE(RESERVED21_ENTROPY), + NONE(RESERVED22_W), + NONE(RESERVED23_W), + + /* 56 */ + NONE(RESERVED24_W), + NONE(AMX0), + NONE(ADX0), + NONE(DVFS), + NONE(XUSB_SS), + NONE(EMC_DLL), + NONE(MC1), + NONE(EMC1), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. Note that T30/T114 support 3 new higher freqs, but we map back + * to the old T20 freqs. Support for the higher oscillators is TBD. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + if (reg & 1) /* one of the newer freqs */ + printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); + + return reg >> 2; /* Map to most common (T20) freqs */ +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else + return &clkrst->crc_clk_src[internal_id]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + if (type == CLOCK_TYPE_PCMT16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra114 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED3: + case PERIPH_ID_RESERVED16: + case PERIPH_ID_RESERVED24: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED43: + case PERIPH_ID_RESERVED45: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED89: + case PERIPH_ID_RESERVED91: + case PERIPH_ID_RESERVED93: + case PERIPH_ID_RESERVED94: + case PERIPH_ID_RESERVED95: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + /* + * PLLP output frequency set to 408Mhz + * PLLC output frequency set to 600Mhz + * PLLD output frequency set to 925Mhz + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } + + /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ + writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); + + /* PLLC_MISC: Set LOCK_ENABLE */ + writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); + udelay(2); + + /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ + writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); + udelay(2); +} diff --git a/arch/arm/cpu/tegra114-common/funcmux.c b/arch/arm/cpu/tegra114-common/funcmux.c new file mode 100644 index 0000000000..5af755034d --- /dev/null +++ b/arch/arm/cpu/tegra114-common/funcmux.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 high-level function multiplexing */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART4: + switch (config) { + case FUNCMUX_UART4_GMI: + pinmux_set_func(PINGRP_GMI_A16, PMUX_FUNC_UARTD); + pinmux_set_func(PINGRP_GMI_A17, PMUX_FUNC_UARTD); + pinmux_set_func(PINGRP_GMI_A18, PMUX_FUNC_UARTD); + pinmux_set_func(PINGRP_GMI_A19, PMUX_FUNC_UARTD); + + pinmux_set_io(PINGRP_GMI_A16, PMUX_PIN_OUTPUT); + pinmux_set_io(PINGRP_GMI_A17, PMUX_PIN_INPUT); + pinmux_set_io(PINGRP_GMI_A18, PMUX_PIN_INPUT); + pinmux_set_io(PINGRP_GMI_A19, PMUX_PIN_OUTPUT); + + pinmux_tristate_disable(PINGRP_GMI_A16); + pinmux_tristate_disable(PINGRP_GMI_A17); + pinmux_tristate_disable(PINGRP_GMI_A18); + pinmux_tristate_disable(PINGRP_GMI_A19); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/cpu/tegra114-common/pinmux.c b/arch/arm/cpu/tegra114-common/pinmux.c new file mode 100644 index 0000000000..52b3ec47aa --- /dev/null +++ b/arch/arm/cpu/tegra114-common/pinmux.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 pin multiplexing functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra.h> +#include <asm/arch/pinmux.h> + +struct tegra_pingroup_desc { + const char *name; + enum pmux_func funcs[4]; + enum pmux_func func_safe; + enum pmux_vddio vddio; + enum pmux_pin_io io; +}; + +#define PMUX_MUXCTL_SHIFT 0 +#define PMUX_PULL_SHIFT 2 +#define PMUX_TRISTATE_SHIFT 4 +#define PMUX_TRISTATE_MASK (1 << PMUX_TRISTATE_SHIFT) +#define PMUX_IO_SHIFT 5 +#define PMUX_OD_SHIFT 6 +#define PMUX_LOCK_SHIFT 7 +#define PMUX_IO_RESET_SHIFT 8 + +/* Convenient macro for defining pin group properties */ +#define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \ + { \ + .vddio = PMUX_VDDIO_ ## vdd, \ + .funcs = { \ + PMUX_FUNC_ ## f0, \ + PMUX_FUNC_ ## f1, \ + PMUX_FUNC_ ## f2, \ + PMUX_FUNC_ ## f3, \ + }, \ + .func_safe = PMUX_FUNC_RSVD1, \ + .io = PMUX_PIN_ ## iod, \ + } + +/* Input and output pins */ +#define PINI(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, INPUT) +#define PINO(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT) + +const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { + /* NAME VDD f0 f1 f2 f3 */ + PINI(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_CLK, BB, SPI1, SPI5, UARTD, ULPI), + PINI(ULPI_DIR, BB, SPI1, SPI5, UARTD, ULPI), + PINI(ULPI_NXT, BB, SPI1, SPI5, UARTD, ULPI), + PINI(ULPI_STP, BB, SPI1, SPI5, UARTD, ULPI), + PINI(DAP3_FS, BB, I2S2, SPI5, DISPA, DISPB), + PINI(DAP3_DIN, BB, I2S2, SPI5, DISPA, DISPB), + PINI(DAP3_DOUT, BB, I2S2, SPI5, DISPA, DISPB), + PINI(DAP3_SCLK, BB, I2S2, SPI5, DISPA, DISPB), + PINI(GPIO_PV0, BB, USB, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PV1, BB, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC1_CLK, SDMMC1, SDMMC1, CLK12, RSVD3, RSVD4), + PINI(SDMMC1_CMD, SDMMC1, SDMMC1, SPDIF, SPI4, UARTA), + PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, SPDIF, SPI4, UARTA), + PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, PWM0, SPI4, UARTA), + PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, PWM1, SPI4, UARTA), + PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD2, SPI4, UARTA), + PINI(GPIO_PV2, BB, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PV3, BB, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD2, RSVD3, RSVD4), + PINI(CLK2_REQ, SDMMC1, DAP, RSVD2, RSVD3, RSVD4), + PINO(LCD_PWR1, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_PWR2, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_SDIN, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_SDOUT, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_WR_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_CS0_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_DC0, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_SCK, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_PWR0, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_PCLK, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_DE, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_HSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_VSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D0, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D1, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D2, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D3, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D4, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D5, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D6, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D7, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D8, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D9, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D10, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D11, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D12, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D13, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D14, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D15, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D16, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D17, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D18, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D19, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D20, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D21, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D22, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_D23, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_CS1_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_M1, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINO(LCD_DC1, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(HDMI_INT, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(DDC_SCL, LCD, I2C4, RSVD2, RSVD3, RSVD4), + PINI(DDC_SDA, LCD, I2C4, RSVD2, RSVD3, RSVD4), + PINI(CRT_HSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(CRT_VSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D0, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D1, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D2, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D3, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D4, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D5, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D6, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D7, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D8, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D9, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D10, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_D11, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_PCLK, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_MCLK, VI, RSVD1, RSVD3, RSVD3, RSVD4), + PINI(VI_VSYNC, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(VI_HSYNC, VI, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(UART2_RXD, UART, UARTB, SPDIF, UARTA, SPI4), + PINI(UART2_TXD, UART, UARTB, SPDIF, UARTA, SPI4), + PINI(UART2_RTS_N, UART, UARTA, UARTB, RSVD3, SPI4), + PINI(UART2_CTS_N, UART, UARTA, UARTB, RSVD3, SPI4), + PINI(UART3_TXD, UART, UARTC, RSVD2, RSVD3, SPI4), + PINI(UART3_RXD, UART, UARTC, RSVD2, RSVD3, SPI4), + PINI(UART3_CTS_N, UART, UARTC, SDMMC1, DTV, SPI4), + PINI(UART3_RTS_N, UART, UARTC, PWM0, DTV, DISPA), + PINI(GPIO_PU0, UART, OWR, UARTA, RSVD3, RSVD4), + PINI(GPIO_PU1, UART, RSVD1, UARTA, RSVD3, RSVD4), + PINI(GPIO_PU2, UART, RSVD1, UARTA, RSVD3, RSVD4), + PINI(GPIO_PU3, UART, PWM0, UARTA, DISPA, DISPB), + PINI(GPIO_PU4, UART, PWM1, UARTA, DISPA, DISPB), + PINI(GPIO_PU5, UART, PWM2, UARTA, DISPA, DISPB), + PINI(GPIO_PU6, UART, PWM3, UARTA, USB, DISPB), + PINI(GEN1_I2C_SDA, UART, I2C1, RSVD2, RSVD3, RSVD4), + PINI(GEN1_I2C_SCL, UART, I2C1, RSVD2, RSVD3, RSVD4), + PINI(DAP4_FS, UART, I2S3, RSVD2, DTV, RSVD4), + PINI(DAP4_DIN, UART, I2S3, RSVD2, RSVD3, RSVD4), + PINI(DAP4_DOUT, UART, I2S3, RSVD2, DTV, RSVD4), + PINI(DAP4_SCLK, UART, I2S3, RSVD2, RSVD3, RSVD4), + PINI(CLK3_OUT, UART, EXTPERIPH3, RSVD2, RSVD3, RSVD4), + PINI(CLK3_REQ, UART, DEV3, RSVD2, RSVD3, RSVD4), + PINI(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT), + PINI(GMI_IORDY, GMI, SDMMC2, RSVD2, GMI, TRACE), + PINI(GMI_WAIT, GMI, SPI4, NAND, GMI, DTV), + PINI(GMI_ADV_N, GMI, RSVD1, NAND, GMI, TRACE), + PINI(GMI_CLK, GMI, SDMMC2, NAND, GMI, TRACE), + PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, USB), + PINI(GMI_CS1_N, GMI, RSVD1, NAND, GMI, SOC), + PINI(GMI_CS2_N, GMI, SDMMC2, NAND, GMI, TRACE), + PINI(GMI_CS3_N, GMI, SDMMC2, NAND, GMI, GMI_ALT), + PINI(GMI_CS4_N, GMI, USB, NAND, GMI, TRACE), + PINI(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SPI4), + PINI(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, SDMMC2), + PINI(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD5, GMI, RSVD1, NAND, GMI, SPI4), + PINI(GMI_AD6, GMI, RSVD1, NAND, GMI, SPI4), + PINI(GMI_AD7, GMI, RSVD1, NAND, GMI, SPI4), + PINI(GMI_AD8, GMI, PWM0, NAND, GMI, DTV), + PINI(GMI_AD9, GMI, PWM1, NAND, GMI, CLDVFS), + PINI(GMI_AD10, GMI, PWM2, NAND, GMI, CLDVFS), + PINI(GMI_AD11, GMI, PWM3, NAND, GMI, USB), + PINI(GMI_AD12, GMI, SDMMC2, NAND, GMI, RSVD4), + PINI(GMI_AD13, GMI, SDMMC2, NAND, GMI, RSVD4), + PINI(GMI_AD14, GMI, SDMMC2, NAND, GMI, DTV), + PINI(GMI_AD15, GMI, SDMMC2, NAND, GMI, DTV), + PINI(GMI_A16, GMI, UARTD, TRACE, GMI, GMI_ALT), + PINI(GMI_A17, GMI, UARTD, RSVD2, GMI, TRACE), + PINI(GMI_A18, GMI, UARTD, RSVD2, GMI, TRACE), + PINI(GMI_A19, GMI, UARTD, SPI4, GMI, TRACE), + PINI(GMI_WR_N, GMI, RSVD1, NAND, GMI, SPI4), + PINI(GMI_OE_N, GMI, RSVD1, NAND, GMI, SOC), + PINI(GMI_DQS, GMI, SDMMC2, NAND, GMI, TRACE), + PINI(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD4), + PINI(GEN2_I2C_SCL, GMI, I2C2, RSVD2, GMI, RSVD4), + PINI(GEN2_I2C_SDA, GMI, I2C2, RSVD2, GMI, RSVD4), + PINI(SDMMC4_CLK, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4), + PINI(SDMMC4_CMD, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4), + PINI(SDMMC4_DAT0, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT1, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT2, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT3, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT4, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT5, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT6, SDMMC4, SDMMC4, SPI3, GMI, RSVD4), + PINI(SDMMC4_DAT7, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4), + PINI(SDMMC4_RST_N, SDMMC4, RSVD1, RSVD2, RSVD3, SDMMC4), + PINI(CAM_MCLK, CAM, VI, VI_ALT1, VI_ALT2, RSVD4), + PINI(GPIO_PCC1, CAM, I2S4, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PBB0, CAM, I2S4, VI, VI_ALT1, VI_ALT3), + PINI(CAM_I2C_SCL, CAM, VGP1, I2C3, RSVD3, RSVD4), + PINI(CAM_I2C_SDA, CAM, VGP2, I2C3, RSVD3, RSVD4), + PINI(GPIO_PBB3, CAM, VGP3, DISPA, DISPB, RSVD4), + PINI(GPIO_PBB4, CAM, VGP4, DISPA, DISPB, RSVD4), + PINI(GPIO_PBB5, CAM, VGP5, DISPA, DISPB, RSVD4), + PINI(GPIO_PBB6, CAM, VGP6, DISPA, DISPB, RSVD4), + PINI(GPIO_PBB7, CAM, I2S4, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PCC2, CAM, I2S4, RSVD2, RSVD3, RSVD4), + PINI(JTAG_RTCK, SYS, RTCK, RSVD2, RSVD3, RSVD4), + PINI(PWR_I2C_SCL, SYS, I2CPWR, RSVD2, RSVD3, RSVD4), + PINI(PWR_I2C_SDA, SYS, I2CPWR, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW0, SYS, KBC, RSVD2, DTV, RSVD4), + PINI(KB_ROW1, SYS, KBC, RSVD2, DTV, RSVD4), + PINI(KB_ROW2, SYS, KBC, RSVD2, DTV, SOC), + PINI(KB_ROW3, SYS, KBC, DISPA, RSVD3, DISPB), + PINI(KB_ROW4, SYS, KBC, DISPA, SPI2, DISPB), + PINI(KB_ROW5, SYS, KBC, DISPA, SPI2, DISPB), + PINI(KB_ROW6, SYS, KBC, DISPA, RSVD3, DISPB), + PINI(KB_ROW7, SYS, KBC, RSVD2, CLDVFS, UARTA), + PINI(KB_ROW8, SYS, KBC, RSVD2, RSVD3, UARTA), + PINI(KB_ROW9, SYS, KBC, RSVD2, RSVD3, UARTA), + PINI(KB_ROW10, SYS, KBC, RSVD2, RSVD3, UARTA), + PINI(KB_ROW11, SYS, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW12, SYS, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW13, SYS, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW14, SYS, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW15, SYS, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(KB_COL0, SYS, KBC, USB, SPI2, EMC_DLL), + PINI(KB_COL1, SYS, KBC, RSVD2, SPI2, EMC_DLL), + PINI(KB_COL2, SYS, KBC, RSVD2, SPI2, RSVD4), + PINI(KB_COL3, SYS, KBC, DISPA, PWM2, UARTA), + PINI(KB_COL4, SYS, KBC, OWR, SDMMC3, UARTA), + PINI(KB_COL5, SYS, KBC, RSVD2, SDMMC1, RSVD4), + PINI(KB_COL6, SYS, KBC, RSVD2, SPI2, RSVD4), + PINI(KB_COL7, SYS, KBC, RSVD2, SPI2, RSVD4), + PINI(CLK_32K_OUT, SYS, BLINK, SOC, RSVD3, RSVD4), + PINI(SYS_CLK_REQ, SYS, SYSCLK, RSVD2, RSVD3, RSVD4), + PINI(CORE_PWR_REQ, SYS, PWRON, RSVD2, RSVD3, RSVD4), + PINI(CPU_PWR_REQ, SYS, CPU, RSVD2, RSVD3, RSVD4), + PINI(PWR_INT_N, SYS, PMI, RSVD2, RSVD3, RSVD4), + PINI(CLK_32K_IN, SYS, CLK, RSVD2, RSVD3, RSVD4), + PINI(OWR, SYS, OWR, RSVD2, RSVD3, RSVD4), + PINI(DAP1_FS, AUDIO, I2S0, HDA, GMI, RSVD4), + PINI(DAP1_DIN, AUDIO, I2S0, HDA, GMI, RSVD4), + PINI(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, RSVD4), + PINI(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, RSVD4), + PINI(CLK1_REQ, AUDIO, DAP, DAP1, RSVD3, RSVD4), + PINI(CLK1_OUT, AUDIO, EXTPERIPH1, DAP2, RSVD3, RSVD4), + PINI(SPDIF_IN, AUDIO, SPDIF, USB, RSVD3, RSVD4), + PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD2, RSVD3, RSVD4), + PINI(DAP2_FS, AUDIO, I2S1, HDA, RSVD3, RSVD4), + PINI(DAP2_DIN, AUDIO, I2S1, HDA, RSVD3, RSVD4), + PINI(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD3, RSVD4), + PINI(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD3, RSVD4), + PINI(SPI2_MOSI, AUDIO, SPI6, CLDVFS, RSVD3, RSVD4), + PINI(SPI2_MISO, AUDIO, SPI6, RSVD2, RSVD3, RSVD4), + PINI(SPI2_CS0_N, AUDIO, SPI6, SPI1, RSVD3, RSVD4), + PINI(SPI2_SCK, AUDIO, SPI6, CLDVFS, RSVD3, RSVD4), + PINI(SPI1_MOSI, AUDIO, RSVD1, SPI1, SPI2, DAP2), + PINI(SPI1_SCK, AUDIO, RSVD1, SPI1, SPI2, RSVD4), + PINI(SPI1_CS0_N, AUDIO, SPI6, SPI1, SPI2, RSVD4), + PINI(SPI1_MISO, AUDIO, RSVD1, SPI1, SPI2, RSVD4), + PINI(SPI2_CS1_N, AUDIO, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SPI2_CS2_N, AUDIO, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC3_CLK, SDMMC3, SDMMC3, RSVD2, RSVD3, SPI3), + PINI(SDMMC3_CMD, SDMMC3, SDMMC3, PWM3, UARTA, SPI3), + PINI(SDMMC3_DAT0, SDMMC3, SDMMC3, RSVD2, RSVD3, SPI3), + PINI(SDMMC3_DAT1, SDMMC3, SDMMC3, PWM2, UARTA, SPI3), + PINI(SDMMC3_DAT2, SDMMC3, SDMMC3, PWM1, DISPA, SPI3), + PINI(SDMMC3_DAT3, SDMMC3, SDMMC3, PWM0, DISPB, SPI3), + PINI(SDMMC3_DAT4, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC3_DAT5, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC3_DAT6, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC3_DAT7, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(HDMI_CEC, SYS, CEC, SDMMC3, RSVD3, SOC), + PINI(SDMMC1_WP_N, SDMMC1, SDMMC1, CLK12, SPI4, UARTA), + PINI(SDMMC3_CD_N, SDMMC3, SDMMC3, OWR, RSVD3, RSVD4), + PINI(SPI1_CS1_N, AUDIO, SPI6, RSVD2, SPI2, I2C1), + PINI(SPI1_CS2_N, AUDIO, SPI6, SPI1, SPI2, I2C1), + PINI(USB_VBUS_EN0, SYS, USB, RSVD2, RSVD3, RSVD4), + PINI(USB_VBUS_EN1, SYS, USB, RSVD2, RSVD3, RSVD4), + PINI(SDMMC3_CLK_LB_IN, SDMMC3, SDMMC3, RSVD2, RSVD3, RSVD4), + PINO(SDMMC3_CLK_LB_OUT, SDMMC3, SDMMC3, RSVD2, RSVD3, RSVD4), + PINO(NAND_GMI_CLK_LB, GMI, SDMMC2, NAND, GMI, RSVD4), + PINO(RESET_OUT_N, SYS, RSVD1, RSVD2, RSVD3, RESET_OUT_N), +}; + +void pinmux_set_tristate(enum pmux_pingrp pin, int enable) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *tri = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin */ + assert(pmux_pingrp_isvalid(pin)); + + reg = readl(tri); + if (enable) + reg |= PMUX_TRISTATE_MASK; + else + reg &= ~PMUX_TRISTATE_MASK; + writel(reg, tri); +} + +void pinmux_tristate_enable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 1); +} + +void pinmux_tristate_disable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 0); +} + +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pull = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and pupd */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_pupd_isvalid(pupd)); + + reg = readl(pull); + reg &= ~(0x3 << PMUX_PULL_SHIFT); + reg |= (pupd << PMUX_PULL_SHIFT); + writel(reg, pull); +} + +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *muxctl = &pmt->pmt_ctl[pin]; + int i, mux = -1; + u32 reg; + + /* Error check on pin and func */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_func_isvalid(func)); + + /* Handle special values */ + if (func == PMUX_FUNC_SAFE) + func = tegra_soc_pingroups[pin].func_safe; + + if (func & PMUX_FUNC_RSVD1) { + mux = func & 0x3; + } else { + /* Search for the appropriate function */ + for (i = 0; i < 4; i++) { + if (tegra_soc_pingroups[pin].funcs[i] == func) { + mux = i; + break; + } + } + } + assert(mux != -1); + + reg = readl(muxctl); + reg &= ~(0x3 << PMUX_MUXCTL_SHIFT); + reg |= (mux << PMUX_MUXCTL_SHIFT); + writel(reg, muxctl); + +} + +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_io = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and io */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_io_isvalid(io)); + + reg = readl(pin_io); + reg &= ~(0x1 << PMUX_IO_SHIFT); + reg |= (io & 0x1) << PMUX_IO_SHIFT; + writel(reg, pin_io); +} + +static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_lock = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and lock */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_lock_isvalid(lock)); + + if (lock == PMUX_PIN_LOCK_DEFAULT) + return 0; + + reg = readl(pin_lock); + reg &= ~(0x1 << PMUX_LOCK_SHIFT); + if (lock == PMUX_PIN_LOCK_ENABLE) + reg |= (0x1 << PMUX_LOCK_SHIFT); + else { + /* lock == DISABLE, which isn't possible */ + printf("%s: Warning: lock == %d, DISABLE is not allowed!\n", + __func__, lock); + } + writel(reg, pin_lock); + + return 0; +} + +static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_od = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and od */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_od_isvalid(od)); + + if (od == PMUX_PIN_OD_DEFAULT) + return 0; + + reg = readl(pin_od); + reg &= ~(0x1 << PMUX_OD_SHIFT); + if (od == PMUX_PIN_OD_ENABLE) + reg |= (0x1 << PMUX_OD_SHIFT); + writel(reg, pin_od); + + return 0; +} + +static int pinmux_set_ioreset(enum pmux_pingrp pin, + enum pmux_pin_ioreset ioreset) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_ioreset = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and ioreset */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_ioreset_isvalid(ioreset)); + + if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) + return 0; + + reg = readl(pin_ioreset); + reg &= ~(0x1 << PMUX_IO_RESET_SHIFT); + if (ioreset == PMUX_PIN_IO_RESET_ENABLE) + reg |= (0x1 << PMUX_IO_RESET_SHIFT); + writel(reg, pin_ioreset); + + return 0; +} + +void pinmux_config_pingroup(struct pingroup_config *config) +{ + enum pmux_pingrp pin = config->pingroup; + + pinmux_set_func(pin, config->func); + pinmux_set_pullupdown(pin, config->pull); + pinmux_set_tristate(pin, config->tristate); + pinmux_set_io(pin, config->io); + pinmux_set_lock(pin, config->lock); + pinmux_set_od(pin, config->od); + pinmux_set_ioreset(pin, config->ioreset); +} + +void pinmux_config_table(struct pingroup_config *config, int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_pingroup(&config[i]); +} diff --git a/arch/arm/cpu/tegra20-common/clock.c b/arch/arm/cpu/tegra20-common/clock.c index 12987a6893..ec93894f48 100644 --- a/arch/arm/cpu/tegra20-common/clock.c +++ b/arch/arm/cpu/tegra20-common/clock.c @@ -31,24 +31,6 @@ #include <fdtdec.h> /* - * This is our record of the current clock rate of each clock. We don't - * fill all of these in since we are only really interested in clocks which - * we use as parents. - */ -static unsigned pll_rate[CLOCK_ID_COUNT]; - -/* - * The oscillator frequency is fixed to one of four set values. Based on this - * the other clocks are set up appropriately. - */ -static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { - 13000000, - 19200000, - 12000000, - 26000000, -}; - -/* * Clock types that we can use as a source. The Tegra20 has muxes for the * peripheral clocks, and in most cases there are four options for the clock * source. This gives us a clock 'type' and exploits what commonality exists @@ -76,12 +58,6 @@ enum clock_type_id { CLOCK_TYPE_NONE = -1, /* invalid clock type */ }; -/* return 1 if a peripheral ID is in range */ -#define clock_type_id_isvalid(id) ((id) >= 0 && \ - (id) < CLOCK_TYPE_COUNT) - -char pllp_valid = 1; /* PLLP is set up correctly */ - enum { CLOCK_MAX_MUX = 4 /* number of source options for each clock */ }; @@ -192,10 +168,6 @@ enum periphc_internal_id { PERIPHC_NONE = -1, }; -/* return 1 if a periphc_internal_id is in range */ -#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ - (id) < PERIPHC_COUNT) - /* * Clock type for each peripheral clock source. We put the name in each * record just so it is easy to match things up @@ -396,19 +368,9 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { NONE(CRAM2), }; -/* number of clock outputs of a PLL */ -static const u8 pll_num_clkouts[] = { - 1, /* PLLC */ - 1, /* PLLM */ - 4, /* PLLP */ - 1, /* PLLA */ - 0, /* PLLU */ - 0, /* PLLD */ -}; - /* * Get the oscillator frequency, from the corresponding hardware configuration - * field. + * field. T20 has 4 frequencies that it supports. */ enum clock_osc_freq clock_get_osc_freq(void) { @@ -420,110 +382,8 @@ enum clock_osc_freq clock_get_osc_freq(void) return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } -int clock_get_osc_bypass(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; -} - -/* Returns a pointer to the registers of the given pll */ -static struct clk_pll *get_pll(enum clock_id clkid) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - - assert(clock_id_is_pll(clkid)); - return &clkrst->crc_pll[clkid]; -} - -int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, - u32 *divp, u32 *cpcon, u32 *lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - assert(clkid != CLOCK_ID_USB); - - /* Safety check, adds to code size but is small */ - if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) - return -1; - data = readl(&pll->pll_base); - *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; - *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - data = readl(&pll->pll_misc); - *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; - *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; - - return 0; -} - -unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, - u32 divp, u32 cpcon, u32 lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - /* - * We cheat by treating all PLL (except PLLU) in the same fashion. - * This works only because: - * - same fields are always mapped at same offsets, except DCCON - * - DCCON is always 0, doesn't conflict - * - M,N, P of PLLP values are ignored for PLLP - */ - data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); - writel(data, &pll->pll_misc); - - data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | - (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); - - if (clkid == CLOCK_ID_USB) - data |= divp << PLLU_VCO_FREQ_SHIFT; - else - data |= divp << PLL_DIVP_SHIFT; - writel(data, &pll->pll_base); - - /* calculate the stable time */ - return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; -} - -/* return 1 if a peripheral ID is in range and valid */ -static int clock_periph_id_isvalid(enum periph_id id) -{ - if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT) - printf("Peripheral id %d out of range\n", id); - else { - switch (id) { - case PERIPH_ID_RESERVED1: - case PERIPH_ID_RESERVED2: - case PERIPH_ID_RESERVED30: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED56: - case PERIPH_ID_RESERVED74: - case PERIPH_ID_RESERVED76: - case PERIPH_ID_RESERVED77: - case PERIPH_ID_RESERVED78: - case PERIPH_ID_RESERVED79: - case PERIPH_ID_RESERVED80: - case PERIPH_ID_RESERVED81: - case PERIPH_ID_RESERVED82: - case PERIPH_ID_RESERVED83: - case PERIPH_ID_RESERVED91: - printf("Peripheral id %d is reserved\n", id); - break; - default: - return 1; - } - } - return 0; -} - /* Returns a pointer to the clock source register for a peripheral */ -static u32 *get_periph_source_reg(enum periph_id periph_id) +u32 *get_periph_source_reg(enum periph_id periph_id) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; @@ -535,154 +395,6 @@ static u32 *get_periph_source_reg(enum periph_id periph_id) return &clkrst->crc_clk_src[internal_id]; } -void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, - unsigned divisor) -{ - u32 *reg = get_periph_source_reg(periph_id); - u32 value; - - value = readl(reg); - - value &= ~OUT_CLK_SOURCE_MASK; - value |= source << OUT_CLK_SOURCE_SHIFT; - - value &= ~OUT_CLK_DIVISOR_MASK; - value |= divisor << OUT_CLK_DIVISOR_SHIFT; - - writel(value, reg); -} - -void clock_ll_set_source(enum periph_id periph_id, unsigned source) -{ - u32 *reg = get_periph_source_reg(periph_id); - - clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, - source << OUT_CLK_SOURCE_SHIFT); -} - -/** - * Given the parent's rate and the required rate for the children, this works - * out the peripheral clock divider to use, in 7.1 binary format. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @return divider which should be used - */ -static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate) -{ - u64 divider = parent_rate * 2; - unsigned max_divider = 1 << divider_bits; - - divider += rate - 1; - do_div(divider, rate); - - if ((s64)divider - 2 < 0) - return 0; - - if ((s64)divider - 2 >= max_divider) - return -1; - - return divider - 2; -} - -/** - * Given the parent's rate and the divider in 7.1 format, this works out the - * resulting peripheral clock rate. - * - * @param parent_rate clock rate of parent clock in Hz - * @param divider which should be used in 7.1 format - * @return effective clock rate of peripheral - */ -static unsigned long get_rate_from_divider(unsigned long parent_rate, - int divider) -{ - u64 rate; - - rate = (u64)parent_rate * 2; - do_div(rate, divider + 2); - return rate; -} - -unsigned long clock_get_periph_rate(enum periph_id periph_id, - enum clock_id parent) -{ - u32 *reg = get_periph_source_reg(periph_id); - - return get_rate_from_divider(pll_rate[parent], - (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); -} - -int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) -{ - struct clk_pll *pll = get_pll(clkid); - int data = 0, div = 0, offset = 0; - - if (!clock_id_is_pll(clkid)) - return -1; - - if (pllout + 1 > pll_num_clkouts[clkid]) - return -1; - - div = clk_get_divider(8, pll_rate[clkid], rate); - - if (div < 0) - return -1; - - /* out2 and out4 are in the high part of the register */ - if (pllout == PLL_OUT2 || pllout == PLL_OUT4) - offset = 16; - - data = (div << PLL_OUT_RATIO_SHIFT) | - PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; - clrsetbits_le32(&pll->pll_out[pllout >> 1], - PLL_OUT_RATIO_MASK << offset, data << offset); - - return 0; -} - -/** - * Find the best available 7.1 format divisor given a parent clock rate and - * required child clock rate. This function assumes that a second-stage - * divisor is available which can divide by powers of 2 from 1 to 256. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @param extra_div value for the second-stage divisor (not set if this - * function returns -1. - * @return divider which should be used, or -1 if nothing is valid - * - */ -static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate, int *extra_div) -{ - int shift; - int best_divider = -1; - int best_error = rate; - - /* try dividers from 1 to 256 and find closest match */ - for (shift = 0; shift <= 8 && best_error > 0; shift++) { - unsigned divided_parent = parent_rate >> shift; - int divider = clk_get_divider(divider_bits, divided_parent, - rate); - unsigned effective_rate = get_rate_from_divider(divided_parent, - divider); - int error = rate - effective_rate; - - /* Given a valid divider, look for the lowest error */ - if (divider != -1 && error < best_error) { - best_error = error; - *extra_div = 1 << shift; - best_divider = divider; - } - } - - /* return what we found - *extra_div will already be set */ - return best_divider; -} - /** * Given a peripheral ID and the required source clock, this returns which * value should be programmed into the source mux for that peripheral. @@ -695,7 +407,7 @@ static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, * @param divider_bits Set to number of divider bits (8 or 16) * @return mux value (0-4, or -1 if not found) */ -static int get_periph_clock_source(enum periph_id periph_id, +int get_periph_clock_source(enum periph_id periph_id, enum clock_id parent, int *mux_bits, int *divider_bits) { enum clock_type_id type; @@ -743,88 +455,6 @@ static int get_periph_clock_source(enum periph_id periph_id, return -1; } -/** - * Adjust peripheral PLL to use the given divider and source. - * - * @param periph_id peripheral to adjust - * @param source Source number (0-3 or 0-7) - * @param mux_bits Number of mux bits (2 or 4) - * @param divider Required divider in 7.1 or 15.1 format - * @return 0 if ok, -1 on error (requesting a parent clock which is not valid - * for this peripheral) - */ -static int adjust_periph_pll(enum periph_id periph_id, int source, - int mux_bits, unsigned divider) -{ - u32 *reg = get_periph_source_reg(periph_id); - - clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, - divider << OUT_CLK_DIVISOR_SHIFT); - udelay(1); - - /* work out the source clock and set it */ - if (source < 0) - return -1; - if (mux_bits == 4) { - clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK, - source << OUT_CLK_SOURCE4_SHIFT); - } else { - clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK, - source << OUT_CLK_SOURCE_SHIFT); - } - udelay(2); - return 0; -} - -unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, - enum clock_id parent, unsigned rate, int *extra_div) -{ - unsigned effective_rate; - int mux_bits, divider_bits, source; - int divider; - - /* work out the source clock and set it */ - source = get_periph_clock_source(periph_id, parent, &mux_bits, - ÷r_bits); - - if (extra_div) - divider = find_best_divider(divider_bits, pll_rate[parent], - rate, extra_div); - else - divider = clk_get_divider(divider_bits, pll_rate[parent], - rate); - assert(divider >= 0); - if (adjust_periph_pll(periph_id, source, mux_bits, divider)) - return -1U; - debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, - get_periph_source_reg(periph_id), - readl(get_periph_source_reg(periph_id))); - - /* Check what we ended up with. This shouldn't matter though */ - effective_rate = clock_get_periph_rate(periph_id, parent); - if (extra_div) - effective_rate /= *extra_div; - if (rate != effective_rate) - debug("Requested clock rate %u not honored (got %u)\n", - rate, effective_rate); - return effective_rate; -} - -unsigned clock_start_periph_pll(enum periph_id periph_id, - enum clock_id parent, unsigned rate) -{ - unsigned effective_rate; - - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - - effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, - NULL); - - reset_set_enable(periph_id, 0); - return effective_rate; -} - void clock_set_enable(enum periph_id periph_id, int enable) { struct clk_rst_ctlr *clkrst = @@ -842,16 +472,6 @@ void clock_set_enable(enum periph_id periph_id, int enable) writel(reg, clk); } -void clock_enable(enum periph_id clkid) -{ - clock_set_enable(clkid, 1); -} - -void clock_disable(enum periph_id clkid) -{ - clock_set_enable(clkid, 0); -} - void reset_set_enable(enum periph_id periph_id, int enable) { struct clk_rst_ctlr *clkrst = @@ -869,146 +489,6 @@ void reset_set_enable(enum periph_id periph_id, int enable) writel(reg, reset); } -void reset_periph(enum periph_id periph_id, int us_delay) -{ - /* Put peripheral into reset */ - reset_set_enable(periph_id, 1); - udelay(us_delay); - - /* Remove reset */ - reset_set_enable(periph_id, 0); - - udelay(us_delay); -} - -void reset_cmplx_set_enable(int cpu, int which, int reset) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 mask; - - /* Form the mask, which depends on the cpu chosen. Tegra20 has 2 */ - assert(cpu >= 0 && cpu < 2); - mask = which << cpu; - - /* either enable or disable those reset for that CPU */ - if (reset) - writel(mask, &clkrst->crc_cpu_cmplx_set); - else - writel(mask, &clkrst->crc_cpu_cmplx_clr); -} - -unsigned clock_get_rate(enum clock_id clkid) -{ - struct clk_pll *pll; - u32 base; - u32 divm; - u64 parent_rate; - u64 rate; - - parent_rate = osc_freq[clock_get_osc_freq()]; - if (clkid == CLOCK_ID_OSC) - return parent_rate; - - pll = get_pll(clkid); - base = readl(&pll->pll_base); - - /* Oh for bf_unpack()... */ - rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); - divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - if (clkid == CLOCK_ID_USB) - divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; - else - divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - do_div(rate, divm); - return rate; -} - -/** - * Set the output frequency you want for each PLL clock. - * PLL output frequencies are programmed by setting their N, M and P values. - * The governing equations are: - * VCO = (Fi / m) * n, Fo = VCO / (2^p) - * where Fo is the output frequency from the PLL. - * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) - * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 - * Please see Tegra TRM section 5.3 to get the detail for PLL Programming - * - * @param n PLL feedback divider(DIVN) - * @param m PLL input divider(DIVN) - * @param p post divider(DIVP) - * @param cpcon base PLL charge pump(CPCON) - * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot - * be overriden), 1 if PLL is already correct - */ -static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) -{ - u32 base_reg; - u32 misc_reg; - struct clk_pll *pll; - - pll = get_pll(clkid); - - base_reg = readl(&pll->pll_base); - - /* Set BYPASS, m, n and p to PLL_BASE */ - base_reg &= ~PLL_DIVM_MASK; - base_reg |= m << PLL_DIVM_SHIFT; - - base_reg &= ~PLL_DIVN_MASK; - base_reg |= n << PLL_DIVN_SHIFT; - - base_reg &= ~PLL_DIVP_MASK; - base_reg |= p << PLL_DIVP_SHIFT; - - if (clkid == CLOCK_ID_PERIPH) { - /* - * If the PLL is already set up, check that it is correct - * and record this info for clock_verify() to check. - */ - if (base_reg & PLL_BASE_OVRRIDE_MASK) { - base_reg |= PLL_ENABLE_MASK; - if (base_reg != readl(&pll->pll_base)) - pllp_valid = 0; - return pllp_valid ? 1 : -1; - } - base_reg |= PLL_BASE_OVRRIDE_MASK; - } - - base_reg |= PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - /* Set cpcon to PLL_MISC */ - misc_reg = readl(&pll->pll_misc); - misc_reg &= ~PLL_CPCON_MASK; - misc_reg |= cpcon << PLL_CPCON_SHIFT; - writel(misc_reg, &pll->pll_misc); - - /* Enable PLL */ - base_reg |= PLL_ENABLE_MASK; - writel(base_reg, &pll->pll_base); - - /* Disable BYPASS */ - base_reg &= ~PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - return 0; -} - -void clock_ll_start_uart(enum periph_id periph_id) -{ - /* Assert UART reset and enable clock */ - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ - - /* wait for 2us */ - udelay(2); - - /* De-assert reset to UART */ - reset_set_enable(periph_id, 0); -} - #ifdef CONFIG_OF_CONTROL /* * Convert a device tree clock ID to our peripheral ID. They are mostly @@ -1018,67 +498,34 @@ void clock_ll_start_uart(enum periph_id periph_id) * @param clk_id Clock ID according to tegra20 device tree binding * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid */ -static enum periph_id clk_id_to_periph_id(int clk_id) +enum periph_id clk_id_to_periph_id(int clk_id) { - if (clk_id > 95) + if (clk_id > PERIPH_ID_COUNT) return PERIPH_ID_NONE; switch (clk_id) { - case 1: - case 2: - case 7: - case 10: - case 20: - case 30: - case 35: - case 49: - case 56: - case 74: - case 76: - case 77: - case 78: - case 79: - case 80: - case 81: - case 82: - case 83: - case 91: - case 95: + case PERIPH_ID_RESERVED1: + case PERIPH_ID_RESERVED2: + case PERIPH_ID_RESERVED30: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_RESERVED74: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED79: + case PERIPH_ID_RESERVED80: + case PERIPH_ID_RESERVED81: + case PERIPH_ID_RESERVED82: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED91: return PERIPH_ID_NONE; default: return clk_id; } } - -int clock_decode_periph_id(const void *blob, int node) -{ - enum periph_id id; - u32 cell[2]; - int err; - - err = fdtdec_get_int_array(blob, node, "clocks", cell, - ARRAY_SIZE(cell)); - if (err) - return -1; - id = clk_id_to_periph_id(cell[1]); - assert(clock_periph_id_isvalid(id)); - return id; -} #endif /* CONFIG_OF_CONTROL */ -int clock_verify(void) -{ - struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); - u32 reg = readl(&pll->pll_base); - - if (!pllp_valid) { - printf("Warning: PLLP %x is not correct\n", reg); - return -1; - } - debug("PLLX %x is correct\n", reg); - return 0; -} - void clock_early_init(void) { /* @@ -1112,15 +559,3 @@ void clock_early_init(void) break; } } - -void clock_init(void) -{ - pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); - pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); - pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); - pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); - pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; - debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); - debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); - debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); -} diff --git a/arch/arm/cpu/tegra20-common/funcmux.c b/arch/arm/cpu/tegra20-common/funcmux.c index ece7ad9ec9..80a9bd9e28 100644 --- a/arch/arm/cpu/tegra20-common/funcmux.c +++ b/arch/arm/cpu/tegra20-common/funcmux.c @@ -98,8 +98,8 @@ int funcmux_select(enum periph_id id, int config) break; case PERIPH_ID_UART2: - if (config == FUNCMUX_UART2_IRDA) { - pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); + if (config == FUNCMUX_UART2_UAD) { + pinmux_set_func(PINGRP_UAD, PMUX_FUNC_UARTB); pinmux_tristate_disable(PINGRP_UAD); } break; diff --git a/arch/arm/cpu/tegra20-common/pinmux.c b/arch/arm/cpu/tegra20-common/pinmux.c index a2a09169e5..5ad2121c5d 100644 --- a/arch/arm/cpu/tegra20-common/pinmux.c +++ b/arch/arm/cpu/tegra20-common/pinmux.c @@ -390,7 +390,7 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { PIN(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS), PIN(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS), PIN(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4), - PIN(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF), + PIN(UAD, UART, UARTB, SPDIF, UARTA, SPI4, SPDIF), PIN(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4), PIN(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4), diff --git a/arch/arm/cpu/tegra20-common/warmboot.c b/arch/arm/cpu/tegra20-common/warmboot.c index 157b9abc45..0d472cfe33 100644 --- a/arch/arm/cpu/tegra20-common/warmboot.c +++ b/arch/arm/cpu/tegra20-common/warmboot.c @@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; * This is the place in SRAM where the SDRAM parameters are stored. There * are 4 blocks, one for each RAM code */ -#define SDRAM_PARAMS_BASE (AP20_BASE_PA_SRAM + 0x188) +#define SDRAM_PARAMS_BASE (NV_PA_BASE_SRAM + 0x188) /* TODO: If we later add support for the Misc GP controller, refactor this */ union xm2cfga_reg { diff --git a/arch/arm/cpu/tegra30-common/Makefile b/arch/arm/cpu/tegra30-common/Makefile new file mode 100644 index 0000000000..75fef32b0d --- /dev/null +++ b/arch/arm/cpu/tegra30-common/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +# + +include $(TOPDIR)/config.mk + +# The AVP is ARMv4T architecture so we must use special compiler +# flags for any startup files it might use. + +LIB = $(obj)lib$(SOC)-common.o + +COBJS-y += clock.o funcmux.o pinmux.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/tegra30-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c new file mode 100644 index 0000000000..a93f2c9434 --- /dev/null +++ b/arch/arm/cpu/tegra30-common/clock.c @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 Clock control functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/timer.h> +#include <div64.h> +#include <fdtdec.h> + +/* + * Clock types that we can use as a source. The Tegra30 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCMT16, + CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +enum { + MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */ + MASK_BITS_31_29, + MASK_BITS_29_28, +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_29_28} +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x38h */ /* Jumps to reg offset 0x3B0h - new for T30 */ + TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), + + /* 0x40 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x48 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x50 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RESERVED4), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(RESERVED16), + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 24 */ + PERIPHC_G3D, + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(RESERVED39), + + /* 40 */ + NONE(KFUSE), + PERIPHC_SBC1, + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, + PERIPHC_DVC_I2C, + + /* 48 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + NONE(CSI), + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + PERIPHC_SPEEDO, + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(DTV), + + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 88 */ + NONE(CRAM2), + NONE(RESERVED89), + NONE(MDOUBLER), + NONE(RESERVED91), + NONE(SUSOUT), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(RESERVED95), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + PERIPHC_G3D2, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 08 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 16 */ + NONE(ATOMICS), + NONE(RESERVED17), + NONE(RESERVED18), + NONE(RESERVED19), + NONE(RESERVED20), + NONE(RESERVED21), + NONE(RESERVED22), + PERIPHC_ACTMON, + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + NONE(RESERVED26), + NONE(RESERVED27), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(RESERVED30), + NONE(RESERVED31), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(SATACOLD), + NONE(RESERVED0_PCIERX0), + NONE(RESERVED1_PCIERX1), + NONE(RESERVED2_PCIERX2), + NONE(RESERVED3_PCIERX3), + NONE(RESERVED4_PCIERX4), + NONE(RESERVED5_PCIERX5), + + /* 40 */ + NONE(CEC), + NONE(RESERVED6_PCIE2), + NONE(RESERVED7_EMC), + NONE(RESERVED8_HDMI), + NONE(RESERVED9_SATA), + NONE(RESERVED10_MIPI), + NONE(EX_RESERVED46), + NONE(EX_RESERVED47), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. Note that T30 supports 3 new higher freqs, but we map back + * to the old T20 freqs. Support for the higher oscillators is TBD. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + if (reg & 1) /* one of the newer freqs */ + printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); + + return reg >> 2; /* Map to most common (T20) freqs */ +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else + return &clkrst->crc_clk_src[internal_id]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + if (type == CLOCK_TYPE_PCMT16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra30 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED3: + case PERIPH_ID_RESERVED4: + case PERIPH_ID_RESERVED16: + case PERIPH_ID_RESERVED24: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED43: + case PERIPH_ID_RESERVED45: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED89: + case PERIPH_ID_RESERVED91: + case PERIPH_ID_RESERVED93: + case PERIPH_ID_RESERVED94: + case PERIPH_ID_RESERVED95: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + /* + * PLLP output frequency set to 408Mhz + * PLLC output frequency set to 228Mhz + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } +} diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c new file mode 100644 index 0000000000..e24c57efbd --- /dev/null +++ b/arch/arm/cpu/tegra30-common/funcmux.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 high-level function multiplexing */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART1: + switch (config) { + case FUNCMUX_UART1_ULPI: + pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_ULPI_DATA0); + pinmux_tristate_disable(PINGRP_ULPI_DATA1); + pinmux_tristate_disable(PINGRP_ULPI_DATA2); + pinmux_tristate_disable(PINGRP_ULPI_DATA3); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c new file mode 100644 index 0000000000..122665fd3c --- /dev/null +++ b/arch/arm/cpu/tegra30-common/pinmux.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 pin multiplexing functions */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/tegra.h> +#include <asm/arch/pinmux.h> + +struct tegra_pingroup_desc { + const char *name; + enum pmux_func funcs[4]; + enum pmux_func func_safe; + enum pmux_vddio vddio; + enum pmux_pin_io io; +}; + +#define PMUX_MUXCTL_SHIFT 0 +#define PMUX_PULL_SHIFT 2 +#define PMUX_TRISTATE_SHIFT 4 +#define PMUX_TRISTATE_MASK (1 << PMUX_TRISTATE_SHIFT) +#define PMUX_IO_SHIFT 5 +#define PMUX_OD_SHIFT 6 +#define PMUX_LOCK_SHIFT 7 +#define PMUX_IO_RESET_SHIFT 8 + +/* Convenient macro for defining pin group properties */ +#define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \ + { \ + .vddio = PMUX_VDDIO_ ## vdd, \ + .funcs = { \ + PMUX_FUNC_ ## f0, \ + PMUX_FUNC_ ## f1, \ + PMUX_FUNC_ ## f2, \ + PMUX_FUNC_ ## f3, \ + }, \ + .func_safe = PMUX_FUNC_RSVD1, \ + .io = PMUX_PIN_ ## iod, \ + } + +/* Input and output pins */ +#define PINI(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, INPUT) +#define PINO(pg_name, vdd, f0, f1, f2, f3) \ + PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT) + +const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { + /* NAME VDD f0 f1 f2 f3 */ + PINI(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI), + PINI(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI), + PINI(ULPI_CLK, BB, SPI1, RSVD2, UARTD, ULPI), + PINI(ULPI_DIR, BB, SPI1, RSVD2, UARTD, ULPI), + PINI(ULPI_NXT, BB, SPI1, RSVD2, UARTD, ULPI), + PINI(ULPI_STP, BB, SPI1, RSVD2, UARTD, ULPI), + PINI(DAP3_FS, BB, I2S2, RSVD2, DISPA, DISPB), + PINI(DAP3_DIN, BB, I2S2, RSVD2, DISPA, DISPB), + PINI(DAP3_DOUT, BB, I2S2, RSVD2, DISPA, DISPB), + PINI(DAP3_SCLK, BB, I2S2, RSVD2, DISPA, DISPB), + PINI(GPIO_PV0, BB, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PV1, BB, RSVD1, RSVD2, RSVD3, RSVD4), + PINI(SDMMC1_CLK, SDMMC1, SDMMC1, RSVD2, RSVD3, UARTA), + PINI(SDMMC1_CMD, SDMMC1, SDMMC1, RSVD2, RSVD3, UARTA), + PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA), + PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA), + PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA), + PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA), + PINI(GPIO_PV2, SDMMC1, OWR, RSVD2, RSVD3, RSVD4), + PINI(GPIO_PV3, SDMMC1, CLK_12M_OUT, RSVD2, RSVD3, RSVD4), + PINI(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD2, RSVD3, RSVD4), + PINI(CLK2_REQ, SDMMC1, DAP, RSVD2, RSVD3, RSVD4), + PINO(LCD_PWR1, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_PWR2, LCD, DISPA, DISPB, SPI5, HDCP), + PINO(LCD_SDIN, LCD, DISPA, DISPB, SPI5, RSVD4), + PINO(LCD_SDOUT, LCD, DISPA, DISPB, SPI5, HDCP), + PINO(LCD_WR_N, LCD, DISPA, DISPB, SPI5, HDCP), + PINO(LCD_CS0_N, LCD, DISPA, DISPB, SPI5, RSVD4), + PINO(LCD_DC0, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_SCK, LCD, DISPA, DISPB, SPI5, HDCP), + PINO(LCD_PWR0, LCD, DISPA, DISPB, SPI5, HDCP), + PINO(LCD_PCLK, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_DE, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_HSYNC, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_VSYNC, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D0, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D1, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D2, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D3, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D4, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D5, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D6, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D7, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D8, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D9, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D10, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D11, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D12, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D13, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D14, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D15, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D16, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D17, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D18, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D19, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D20, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D21, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D22, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_D23, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_CS1_N, LCD, DISPA, DISPB, SPI5, RSVD4), + PINO(LCD_M1, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINO(LCD_DC1, LCD, DISPA, DISPB, RSVD3, RSVD4), + PINI(HDMI_INT, LCD, HDMI, RSVD2, RSVD3, RSVD4), + PINI(DDC_SCL, LCD, I2C4, RSVD2, RSVD3, RSVD4), + PINI(DDC_SDA, LCD, I2C4, RSVD2, RSVD3, RSVD4), + PINI(CRT_HSYNC, LCD, CRT, RSVD2, RSVD3, RSVD4), + PINI(CRT_VSYNC, LCD, CRT, RSVD2, RSVD3, RSVD4), + PINI(VI_D0, VI, DDR, RSVD2, VI, RSVD4), + PINI(VI_D1, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D2, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D3, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D4, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D5, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D6, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D7, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D8, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D9, VI, DDR, SDMMC2, VI, RSVD4), + PINI(VI_D10, VI, DDR, RSVD2, VI, RSVD4), + PINI(VI_D11, VI, DDR, RSVD2, VI, RSVD4), + PINI(VI_PCLK, VI, RSVD1, SDMMC2, VI, RSVD4), + PINI(VI_MCLK, VI, VI, VI, VI, VI), + PINI(VI_VSYNC, VI, DDR, RSVD2, VI, RSVD4), + PINI(VI_HSYNC, VI, DDR, RSVD2, VI, RSVD4), + PINI(UART2_RXD, UART, UARTB, SPDIF, UARTA, SPI4), + PINI(UART2_TXD, UART, UARTB, SPDIF, UARTA, SPI4), + PINI(UART2_RTS_N, UART, UARTA, UARTB, GMI, SPI4), + PINI(UART2_CTS_N, UART, UARTA, UARTB, GMI, SPI4), + PINI(UART3_TXD, UART, UARTC, RSVD2, GMI, RSVD4), + PINI(UART3_RXD, UART, UARTC, RSVD2, GMI, RSVD4), + PINI(UART3_CTS_N, UART, UARTC, RSVD2, GMI, RSVD4), + PINI(UART3_RTS_N, UART, UARTC, PWM0, GMI, RSVD4), + PINI(GPIO_PU0, UART, OWR, UARTA, GMI, RSVD4), + PINI(GPIO_PU1, UART, RSVD1, UARTA, GMI, RSVD4), + PINI(GPIO_PU2, UART, RSVD1, UARTA, GMI, RSVD4), + PINI(GPIO_PU3, UART, PWM0, UARTA, GMI, RSVD4), + PINI(GPIO_PU4, UART, PWM1, UARTA, GMI, RSVD4), + PINI(GPIO_PU5, UART, PWM2, UARTA, GMI, RSVD4), + PINI(GPIO_PU6, UART, PWM3, UARTA, GMI, RSVD4), + PINI(GEN1_I2C_SDA, UART, I2C1, RSVD2, RSVD3, RSVD4), + PINI(GEN1_I2C_SCL, UART, I2C1, RSVD2, RSVD3, RSVD4), + PINI(DAP4_FS, UART, I2S3, RSVD2, GMI, RSVD4), + PINI(DAP4_DIN, UART, I2S3, RSVD2, GMI, RSVD4), + PINI(DAP4_DOUT, UART, I2S3, RSVD2, GMI, RSVD4), + PINI(DAP4_SCLK, UART, I2S3, RSVD2, GMI, RSVD4), + PINI(CLK3_OUT, UART, EXTPERIPH3, RSVD2, RSVD3, RSVD4), + PINI(CLK3_REQ, UART, DEV3, RSVD2, RSVD3, RSVD4), + PINI(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT), + PINI(GMI_IORDY, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_WAIT, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_ADV_N, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_CLK, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, DTV), + PINI(GMI_CS1_N, GMI, RSVD1, NAND, GMI, DTV), + PINI(GMI_CS2_N, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_CS3_N, GMI, RSVD1, NAND, GMI, GMI_ALT), + PINI(GMI_CS4_N, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SATA), + PINI(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, GMI_ALT), + PINI(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD5, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD6, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD7, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD8, GMI, PWM0, NAND, GMI, RSVD4), + PINI(GMI_AD9, GMI, PWM1, NAND, GMI, RSVD4), + PINI(GMI_AD10, GMI, PWM2, NAND, GMI, RSVD4), + PINI(GMI_AD11, GMI, PWM3, NAND, GMI, RSVD4), + PINI(GMI_AD12, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD13, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD14, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_AD15, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_A16, GMI, UARTD, SPI4, GMI, GMI_ALT), + PINI(GMI_A17, GMI, UARTD, SPI4, GMI, DTV), + PINI(GMI_A18, GMI, UARTD, SPI4, GMI, DTV), + PINI(GMI_A19, GMI, UARTD, SPI4, GMI, RSVD4), + PINI(GMI_WR_N, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_OE_N, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_DQS, GMI, RSVD1, NAND, GMI, RSVD4), + PINI(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD4), + PINI(GEN2_I2C_SCL, GMI, I2C2, HDCP, GMI, RSVD4), + PINI(GEN2_I2C_SDA, GMI, I2C2, HDCP, GMI, RSVD4), + PINI(SDMMC4_CLK, SDMMC4, RSVD1, NAND, GMI, SDMMC4), + PINI(SDMMC4_CMD, SDMMC4, I2C3, NAND, GMI, SDMMC4), + PINI(SDMMC4_DAT0, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT1, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT2, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT3, SDMMC4, UARTE, SPI3, GMI, SDMMC4), + PINI(SDMMC4_DAT4, SDMMC4, I2C3, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT5, SDMMC4, VGP3, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT6, SDMMC4, VGP4, I2S4, GMI, SDMMC4), + PINI(SDMMC4_DAT7, SDMMC4, VGP5, I2S4, GMI, SDMMC4), + PINI(SDMMC4_RST_N, SDMMC4, VGP6, RSVD2, RSVD3, SDMMC4), + PINI(CAM_MCLK, CAM, VI, RSVD2, VI_ALT2, SDMMC4), + PINI(GPIO_PCC1, CAM, I2S4, RSVD2, RSVD3, SDMMC4), + PINI(GPIO_PBB0, CAM, I2S4, RSVD2, RSVD3, SDMMC4), + PINI(CAM_I2C_SCL, CAM, VGP1, I2C3, RSVD3, SDMMC4), + PINI(CAM_I2C_SDA, CAM, VGP2, I2C3, RSVD3, SDMMC4), + PINI(GPIO_PBB3, CAM, VGP3, DISPA, DISPB, SDMMC4), + PINI(GPIO_PBB4, CAM, VGP4, DISPA, DISPB, SDMMC4), + PINI(GPIO_PBB5, CAM, VGP5, DISPA, DISPB, SDMMC4), + PINI(GPIO_PBB6, CAM, VGP6, DISPA, DISPB, SDMMC4), + PINI(GPIO_PBB7, CAM, I2S4, RSVD2, RSVD3, SDMMC4), + PINI(GPIO_PCC2, CAM, I2S4, RSVD2, RSVD3, RSVD4), + PINI(JTAG_RTCK, SYS, RTCK, RSVD2, RSVD3, RSVD4), + PINI(PWR_I2C_SCL, SYS, I2CPWR, RSVD2, RSVD3, RSVD4), + PINI(PWR_I2C_SDA, SYS, I2CPWR, RSVD2, RSVD3, RSVD4), + PINI(KB_ROW0, SYS, KBC, NAND, RSVD3, RSVD4), + PINI(KB_ROW1, SYS, KBC, NAND, RSVD3, RSVD4), + PINI(KB_ROW2, SYS, KBC, NAND, RSVD3, RSVD4), + PINI(KB_ROW3, SYS, KBC, NAND, RSVD3, RSVD4), + PINI(KB_ROW4, SYS, KBC, NAND, TRACE, RSVD4), + PINI(KB_ROW5, SYS, KBC, NAND, TRACE, OWR), + PINI(KB_ROW6, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW7, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW8, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW9, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW10, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW11, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW12, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW13, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW14, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_ROW15, SYS, KBC, NAND, SDMMC2, MIO), + PINI(KB_COL0, SYS, KBC, NAND, TRACE, TEST), + PINI(KB_COL1, SYS, KBC, NAND, TRACE, TEST), + PINI(KB_COL2, SYS, KBC, NAND, TRACE, RSVD4), + PINI(KB_COL3, SYS, KBC, NAND, TRACE, RSVD4), + PINI(KB_COL4, SYS, KBC, NAND, TRACE, RSVD4), + PINI(KB_COL5, SYS, KBC, NAND, TRACE, RSVD4), + PINI(KB_COL6, SYS, KBC, NAND, TRACE, MIO), + PINI(KB_COL7, SYS, KBC, NAND, TRACE, MIO), + PINI(CLK_32K_OUT, SYS, BLINK, RSVD2, RSVD3, RSVD4), + PINI(SYS_CLK_REQ, SYS, SYSCLK, RSVD2, RSVD3, RSVD4), + PINI(CORE_PWR_REQ, SYS, CORE_PWR_REQ, RSVD2, RSVD3, RSVD4), + PINI(CPU_PWR_REQ, SYS, CPU_PWR_REQ, RSVD2, RSVD3, RSVD4), + PINI(PWR_INT_N, SYS, PWR_INT_N, RSVD2, RSVD3, RSVD4), + PINI(CLK_32K_IN, SYS, CLK_32K_IN, RSVD2, RSVD3, RSVD4), + PINI(OWR, SYS, OWR, CEC, RSVD3, RSVD4), + PINI(DAP1_FS, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_DIN, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, SDMMC2), + PINI(CLK1_REQ, AUDIO, DAP, HDA, RSVD3, RSVD4), + PINI(CLK1_OUT, AUDIO, EXTPERIPH1, RSVD2, RSVD3, RSVD4), + PINI(SPDIF_IN, AUDIO, SPDIF, HDA, I2C1, SDMMC2), + PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD2, I2C1, SDMMC2), + PINI(DAP2_FS, AUDIO, I2S1, HDA, RSVD3, GMI), + PINI(DAP2_DIN, AUDIO, I2S1, HDA, RSVD3, GMI), + PINI(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD3, GMI), + PINI(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD3, GMI), + PINI(SPI2_MOSI, AUDIO, SPI6, SPI2, GMI, GMI), + PINI(SPI2_MISO, AUDIO, SPI6, SPI2, GMI, GMI), + PINI(SPI2_CS0_N, AUDIO, SPI6, SPI2, GMI, GMI), + PINI(SPI2_SCK, AUDIO, SPI6, SPI2, GMI, GMI), + PINI(SPI1_MOSI, AUDIO, SPI2, SPI1, SPI2_ALT, GMI), + PINI(SPI1_SCK, AUDIO, SPI2, SPI1, SPI2_ALT, GMI), + PINI(SPI1_CS0_N, AUDIO, SPI2, SPI1, SPI2_ALT, GMI), + PINI(SPI1_MISO, AUDIO, SPI3, SPI1, SPI2_ALT, RSVD4), + PINI(SPI2_CS1_N, AUDIO, SPI3, SPI2, SPI2_ALT, I2C1), + PINI(SPI2_CS2_N, AUDIO, SPI3, SPI2, SPI2_ALT, I2C1), + PINI(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDMMC3, SPI3), + PINI(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDMMC3, SPI2), + PINI(SDMMC3_DAT0, SDMMC3, RSVD1, RSVD2, SDMMC3, SPI3), + PINI(SDMMC3_DAT1, SDMMC3, RSVD1, RSVD2, SDMMC3, SPI3), + PINI(SDMMC3_DAT2, SDMMC3, RSVD1, PWM1, SDMMC3, SPI3), + PINI(SDMMC3_DAT3, SDMMC3, RSVD1, PWM0, SDMMC3, SPI3), + PINI(SDMMC3_DAT4, SDMMC3, PWM1, SPI4, SDMMC3, SPI2), + PINI(SDMMC3_DAT5, SDMMC3, PWM0, SPI4, SDMMC3, SPI2), + PINI(SDMMC3_DAT6, SDMMC3, SPDIF, SPI4, SDMMC3, SPI2), + PINI(SDMMC3_DAT7, SDMMC3, SPDIF, SPI4, SDMMC3, SPI2), + PINI(PEX_L0_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L0_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L0_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_WAKE_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L1_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L1_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L1_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L2_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L2_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(PEX_L2_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4), + PINI(HDMI_CEC, SYS, CEC, RSVD2, RSVD3, RSVD4), +}; + +void pinmux_set_tristate(enum pmux_pingrp pin, int enable) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *tri = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin */ + assert(pmux_pingrp_isvalid(pin)); + + reg = readl(tri); + if (enable) + reg |= PMUX_TRISTATE_MASK; + else + reg &= ~PMUX_TRISTATE_MASK; + writel(reg, tri); +} + +void pinmux_tristate_enable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 1); +} + +void pinmux_tristate_disable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, 0); +} + +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pull = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and pupd */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_pupd_isvalid(pupd)); + + reg = readl(pull); + reg &= ~(0x3 << PMUX_PULL_SHIFT); + reg |= (pupd << PMUX_PULL_SHIFT); + writel(reg, pull); +} + +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *muxctl = &pmt->pmt_ctl[pin]; + int i, mux = -1; + u32 reg; + + /* Error check on pin and func */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_func_isvalid(func)); + + /* Handle special values */ + if (func == PMUX_FUNC_SAFE) + func = tegra_soc_pingroups[pin].func_safe; + + if (func & PMUX_FUNC_RSVD1) { + mux = func & 0x3; + } else { + /* Search for the appropriate function */ + for (i = 0; i < 4; i++) { + if (tegra_soc_pingroups[pin].funcs[i] == func) { + mux = i; + break; + } + } + } + assert(mux != -1); + + reg = readl(muxctl); + reg &= ~(0x3 << PMUX_MUXCTL_SHIFT); + reg |= (mux << PMUX_MUXCTL_SHIFT); + writel(reg, muxctl); + +} + +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_io = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and io */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_io_isvalid(io)); + + reg = readl(pin_io); + reg &= ~(0x1 << PMUX_IO_SHIFT); + reg |= (io & 0x1) << PMUX_IO_SHIFT; + writel(reg, pin_io); +} + +static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_lock = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and lock */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_lock_isvalid(lock)); + + if (lock == PMUX_PIN_LOCK_DEFAULT) + return 0; + + reg = readl(pin_lock); + reg &= ~(0x1 << PMUX_LOCK_SHIFT); + if (lock == PMUX_PIN_LOCK_ENABLE) + reg |= (0x1 << PMUX_LOCK_SHIFT); + else { + /* lock == DISABLE, which isn't possible */ + printf("%s: Warning: lock == %d, DISABLE is not allowed!\n", + __func__, lock); + } + writel(reg, pin_lock); + + return 0; +} + +static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_od = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and od */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_od_isvalid(od)); + + if (od == PMUX_PIN_OD_DEFAULT) + return 0; + + reg = readl(pin_od); + reg &= ~(0x1 << PMUX_OD_SHIFT); + if (od == PMUX_PIN_OD_ENABLE) + reg |= (0x1 << PMUX_OD_SHIFT); + writel(reg, pin_od); + + return 0; +} + +static int pinmux_set_ioreset(enum pmux_pingrp pin, + enum pmux_pin_ioreset ioreset) +{ + struct pmux_tri_ctlr *pmt = + (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 *pin_ioreset = &pmt->pmt_ctl[pin]; + u32 reg; + + /* Error check on pin and ioreset */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_ioreset_isvalid(ioreset)); + + if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) + return 0; + + reg = readl(pin_ioreset); + reg &= ~(0x1 << PMUX_IO_RESET_SHIFT); + if (ioreset == PMUX_PIN_IO_RESET_ENABLE) + reg |= (0x1 << PMUX_IO_RESET_SHIFT); + writel(reg, pin_ioreset); + + return 0; +} + +void pinmux_config_pingroup(struct pingroup_config *config) +{ + enum pmux_pingrp pin = config->pingroup; + + pinmux_set_func(pin, config->func); + pinmux_set_pullupdown(pin, config->pull); + pinmux_set_tristate(pin, config->tristate); + pinmux_set_io(pin, config->io); + pinmux_set_lock(pin, config->lock); + pinmux_set_od(pin, config->od); + pinmux_set_ioreset(pin, config->ioreset); +} + +void pinmux_config_table(struct pingroup_config *config, int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_pingroup(&config[i]); +} diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi new file mode 100644 index 0000000000..d06cd126dd --- /dev/null +++ b/arch/arm/dts/tegra114.dtsi @@ -0,0 +1,5 @@ +/include/ "skeleton.dtsi" + +/ { + compatible = "nvidia,tegra114"; +}; diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi index 636ec2c1fe..9a8968522e 100644 --- a/arch/arm/dts/tegra20.dtsi +++ b/arch/arm/dts/tegra20.dtsi @@ -4,19 +4,101 @@ compatible = "nvidia,tegra20"; interrupt-parent = <&intc>; - tegra_car: clock@60006000 { - compatible = "nvidia,tegra20-car"; - reg = <0x60006000 0x1000>; - #clock-cells = <1>; - }; + host1x { + compatible = "nvidia,tegra20-host1x", "simple-bus"; + reg = <0x50000000 0x00024000>; + interrupts = <0 65 0x04 /* mpcore syncpt */ + 0 67 0x04>; /* mpcore general */ + status = "disabled"; - clocks { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; + + ranges = <0x54000000 0x54000000 0x04000000>; + + /* video-encoding/decoding */ + mpe { + reg = <0x54040000 0x00040000>; + interrupts = <0 68 0x04>; + status = "disabled"; + }; + + /* video input */ + vi { + reg = <0x54080000 0x00040000>; + interrupts = <0 69 0x04>; + status = "disabled"; + }; + + /* EPP */ + epp { + reg = <0x540c0000 0x00040000>; + interrupts = <0 70 0x04>; + status = "disabled"; + }; + + /* ISP */ + isp { + reg = <0x54100000 0x00040000>; + interrupts = <0 71 0x04>; + status = "disabled"; + }; + + /* 2D engine */ + gr2d { + reg = <0x54140000 0x00040000>; + interrupts = <0 72 0x04>; + status = "disabled"; + }; + + /* 3D engine */ + gr3d { + reg = <0x54180000 0x00040000>; + status = "disabled"; + }; + + /* display controllers */ + dc@54200000 { + compatible = "nvidia,tegra20-dc"; + reg = <0x54200000 0x00040000>; + interrupts = <0 73 0x04>; + status = "disabled"; + + rgb { + status = "disabled"; + }; + }; + + dc@54240000 { + compatible = "nvidia,tegra20-dc"; + reg = <0x54240000 0x00040000>; + interrupts = <0 74 0x04>; + status = "disabled"; + + rgb { + status = "disabled"; + }; + }; + + /* outputs */ + hdmi { + compatible = "nvidia,tegra20-hdmi"; + reg = <0x54280000 0x00040000>; + interrupts = <0 75 0x04>; + status = "disabled"; + }; - osc: clock { - compatible = "fixed-clock"; - #clock-cells = <0>; + tvo { + compatible = "nvidia,tegra20-tvo"; + reg = <0x542c0000 0x00040000>; + interrupts = <0 76 0x04>; + status = "disabled"; + }; + + dsi { + compatible = "nvidia,tegra20-dsi"; + reg = <0x54300000 0x00040000>; + status = "disabled"; }; }; @@ -28,44 +110,54 @@ < 0x50040100 0x0100 >; }; - i2c@7000c000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C000 0x100>; - interrupts = < 70 >; - /* PERIPH_ID_I2C1, PLL_P_OUT3 */ - clocks = <&tegra_car 12>, <&tegra_car 124>; + tegra_car: clock@60006000 { + compatible = "nvidia,tegra20-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; }; - i2c@7000c400 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C400 0x100>; - interrupts = < 116 >; - /* PERIPH_ID_I2C2, PLL_P_OUT3 */ - clocks = <&tegra_car 54>, <&tegra_car 124>; + apbdma: dma { + compatible = "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1200>; + interrupts = <0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04>; }; - i2c@7000c500 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C500 0x100>; - interrupts = < 124 >; - /* PERIPH_ID_I2C3, PLL_P_OUT3 */ - clocks = <&tegra_car 67>, <&tegra_car 124>; + gpio: gpio@6000d000 { + compatible = "nvidia,tegra20-gpio"; + reg = < 0x6000d000 0x1000 >; + interrupts = < 64 65 66 67 87 119 121 >; + #gpio-cells = <2>; + gpio-controller; }; - i2c@7000d000 { + pinmux: pinmux@70000000 { + compatible = "nvidia,tegra20-pinmux"; + reg = < 0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8 >; /* Pad control registers */ + }; + + das@70000c00 { #address-cells = <1>; #size-cells = <0>; - compatible = "nvidia,tegra20-i2c-dvc"; - reg = <0x7000D000 0x200>; - interrupts = < 85 >; - /* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */ - clocks = <&tegra_car 47>, <&tegra_car 124>; + compatible = "nvidia,tegra20-das"; + reg = <0x70000c00 0x80>; }; i2s@70002800 { @@ -86,29 +178,6 @@ dma-channel = < 1 >; }; - das@70000c00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-das"; - reg = <0x70000c00 0x80>; - }; - - gpio: gpio@6000d000 { - compatible = "nvidia,tegra20-gpio"; - reg = < 0x6000d000 0x1000 >; - interrupts = < 64 65 66 67 87 119 121 >; - #gpio-cells = <2>; - gpio-controller; - }; - - pinmux: pinmux@70000000 { - compatible = "nvidia,tegra20-pinmux"; - reg = < 0x70000014 0x10 /* Tri-state registers */ - 0x70000080 0x20 /* Mux registers */ - 0x700000a0 0x14 /* Pull-up/down registers */ - 0x70000868 0xa8 >; /* Pad control registers */ - }; - serial@70006000 { compatible = "nvidia,tegra20-uart"; reg = <0x70006000 0x40>; @@ -144,28 +213,81 @@ interrupts = < 123 >; }; - sdhci@c8000000 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000000 0x200>; - interrupts = < 46 >; + nand: nand-controller@70008000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-nand"; + reg = <0x70008000 0x100>; }; - sdhci@c8000200 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000200 0x200>; - interrupts = < 47 >; + pwm: pwm@7000a000 { + compatible = "nvidia,tegra20-pwm"; + reg = <0x7000a000 0x100>; + #pwm-cells = <2>; }; - sdhci@c8000400 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000400 0x200>; - interrupts = < 51 >; + i2c@7000c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C000 0x100>; + interrupts = < 70 >; + /* PERIPH_ID_I2C1, PLL_P_OUT3 */ + clocks = <&tegra_car 12>, <&tegra_car 124>; }; - sdhci@c8000600 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000600 0x200>; - interrupts = < 63 >; + spi@7000c380 { + compatible = "nvidia,tegra20-sflash"; + reg = <0x7000c380 0x80>; + interrupts = <0 39 0x04>; + nvidia,dma-request-selector = <&apbdma 11>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SPI1, PLLP_OUT0 */ + clocks = <&tegra_car 43>; + }; + + i2c@7000c400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C400 0x100>; + interrupts = < 116 >; + /* PERIPH_ID_I2C2, PLL_P_OUT3 */ + clocks = <&tegra_car 54>, <&tegra_car 124>; + }; + + i2c@7000c500 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C500 0x100>; + interrupts = < 124 >; + /* PERIPH_ID_I2C3, PLL_P_OUT3 */ + clocks = <&tegra_car 67>, <&tegra_car 124>; + }; + + i2c@7000d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c-dvc"; + reg = <0x7000D000 0x200>; + interrupts = < 85 >; + /* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */ + clocks = <&tegra_car 47>, <&tegra_car 124>; + }; + + kbc@7000e200 { + compatible = "nvidia,tegra20-kbc"; + reg = <0x7000e200 0x0078>; + }; + + emc@7000f400 { + #address-cells = < 1 >; + #size-cells = < 0 >; + compatible = "nvidia,tegra20-emc"; + reg = <0x7000f400 0x200>; }; usb@c5000000 { @@ -193,127 +315,27 @@ clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */ }; - emc@7000f400 { - #address-cells = < 1 >; - #size-cells = < 0 >; - compatible = "nvidia,tegra20-emc"; - reg = <0x7000f400 0x200>; - }; - - kbc@7000e200 { - compatible = "nvidia,tegra20-kbc"; - reg = <0x7000e200 0x0078>; + sdhci@c8000000 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000000 0x200>; + interrupts = < 46 >; }; - nand: nand-controller@70008000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-nand"; - reg = <0x70008000 0x100>; + sdhci@c8000200 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000200 0x200>; + interrupts = < 47 >; }; - pwm: pwm@7000a000 { - compatible = "nvidia,tegra20-pwm"; - reg = <0x7000a000 0x100>; - #pwm-cells = <2>; + sdhci@c8000400 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000400 0x200>; + interrupts = < 51 >; }; - host1x { - compatible = "nvidia,tegra20-host1x", "simple-bus"; - reg = <0x50000000 0x00024000>; - interrupts = <0 65 0x04 /* mpcore syncpt */ - 0 67 0x04>; /* mpcore general */ - status = "disabled"; - - #address-cells = <1>; - #size-cells = <1>; - - ranges = <0x54000000 0x54000000 0x04000000>; - - /* video-encoding/decoding */ - mpe { - reg = <0x54040000 0x00040000>; - interrupts = <0 68 0x04>; - status = "disabled"; - }; - - /* video input */ - vi { - reg = <0x54080000 0x00040000>; - interrupts = <0 69 0x04>; - status = "disabled"; - }; - - /* EPP */ - epp { - reg = <0x540c0000 0x00040000>; - interrupts = <0 70 0x04>; - status = "disabled"; - }; - - /* ISP */ - isp { - reg = <0x54100000 0x00040000>; - interrupts = <0 71 0x04>; - status = "disabled"; - }; - - /* 2D engine */ - gr2d { - reg = <0x54140000 0x00040000>; - interrupts = <0 72 0x04>; - status = "disabled"; - }; - - /* 3D engine */ - gr3d { - reg = <0x54180000 0x00040000>; - status = "disabled"; - }; - - /* display controllers */ - dc@54200000 { - compatible = "nvidia,tegra20-dc"; - reg = <0x54200000 0x00040000>; - interrupts = <0 73 0x04>; - status = "disabled"; - - rgb { - status = "disabled"; - }; - }; - - dc@54240000 { - compatible = "nvidia,tegra20-dc"; - reg = <0x54240000 0x00040000>; - interrupts = <0 74 0x04>; - status = "disabled"; - - rgb { - status = "disabled"; - }; - }; - - /* outputs */ - hdmi { - compatible = "nvidia,tegra20-hdmi"; - reg = <0x54280000 0x00040000>; - interrupts = <0 75 0x04>; - status = "disabled"; - }; - - tvo { - compatible = "nvidia,tegra20-tvo"; - reg = <0x542c0000 0x00040000>; - interrupts = <0 76 0x04>; - status = "disabled"; - }; - - dsi { - compatible = "nvidia,tegra20-dsi"; - reg = <0x54300000 0x00040000>; - status = "disabled"; - }; + sdhci@c8000600 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000600 0x200>; + interrupts = < 63 >; }; - }; diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi new file mode 100644 index 0000000000..7b8126f7cc --- /dev/null +++ b/arch/arm/dts/tegra30.dtsi @@ -0,0 +1,165 @@ +/include/ "skeleton.dtsi" + +/ { + compatible = "nvidia,tegra30"; + + tegra_car: clock@60006000 { + compatible = "nvidia,tegra30-car", "nvidia,tegra20-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + }; + + apbdma: dma { + compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1400>; + interrupts = <0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 + 0 128 0x04 + 0 129 0x04 + 0 130 0x04 + 0 131 0x04 + 0 132 0x04 + 0 133 0x04 + 0 134 0x04 + 0 135 0x04 + 0 136 0x04 + 0 137 0x04 + 0 138 0x04 + 0 139 0x04 + 0 140 0x04 + 0 141 0x04 + 0 142 0x04 + 0 143 0x04>; + }; + + i2c@7000c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000C000 0x100>; + /* PERIPH_ID_I2C1, CLK_M */ + clocks = <&tegra_car 12>; + }; + + i2c@7000c400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000C400 0x100>; + /* PERIPH_ID_I2C2, CLK_M */ + clocks = <&tegra_car 54>; + }; + + i2c@7000c500 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000C500 0x100>; + /* PERIPH_ID_I2C3, CLK_M */ + clocks = <&tegra_car 67>; + }; + + i2c@7000c700 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000C700 0x100>; + /* PERIPH_ID_I2C4, CLK_M */ + clocks = <&tegra_car 103>; + }; + + i2c@7000d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000D000 0x100>; + /* PERIPH_ID_I2C_DVC, CLK_M */ + clocks = <&tegra_car 47>; + }; + + spi@7000d400 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d400 0x200>; + interrupts = <0 59 0x04>; + nvidia,dma-request-selector = <&apbdma 15>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC1, PLLP_OUT0 */ + clocks = <&tegra_car 41>; + }; + + spi@7000d600 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d600 0x200>; + interrupts = <0 82 0x04>; + nvidia,dma-request-selector = <&apbdma 16>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC2, PLLP_OUT0 */ + clocks = <&tegra_car 44>; + }; + + spi@7000d800 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000d480 0x200>; + interrupts = <0 83 0x04>; + nvidia,dma-request-selector = <&apbdma 17>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC3, PLLP_OUT0 */ + clocks = <&tegra_car 46>; + }; + + spi@7000da00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000da00 0x200>; + interrupts = <0 93 0x04>; + nvidia,dma-request-selector = <&apbdma 18>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC4, PLLP_OUT0 */ + clocks = <&tegra_car 68>; + }; + + spi@7000dc00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000dc00 0x200>; + interrupts = <0 94 0x04>; + nvidia,dma-request-selector = <&apbdma 27>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC5, PLLP_OUT0 */ + clocks = <&tegra_car 104>; + }; + + spi@7000de00 { + compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; + reg = <0x7000de00 0x200>; + interrupts = <0 79 0x04>; + nvidia,dma-request-selector = <&apbdma 28>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + /* PERIPH_ID_SBC6, PLLP_OUT0 */ + clocks = <&tegra_car 105>; + }; +}; diff --git a/arch/arm/imx-common/speed.c b/arch/arm/imx-common/speed.c index fbf4de3b30..638ee1aa75 100644 --- a/arch/arm/imx-common/speed.c +++ b/arch/arm/imx-common/speed.c @@ -37,23 +37,23 @@ int get_clocks(void) #ifdef CONFIG_FSL_ESDHC #ifdef CONFIG_FSL_USDHC #if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); #elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC4_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); #else - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); #endif #else #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC4_BASE_ADDR - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); #else - gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); #endif #endif #endif diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index b021903d9b..ab37d641ec 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -48,8 +48,8 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->tbl) -#define lastinc (gd->lastinc) +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) static inline unsigned long long tick_to_time(unsigned long long tick) { diff --git a/arch/arm/include/asm/arch-am33xx/ddr_defs.h b/arch/arm/include/asm/arch-am33xx/ddr_defs.h index 8e69fb67b1..ae43ef8778 100644 --- a/arch/arm/include/asm/arch-am33xx/ddr_defs.h +++ b/arch/arm/include/asm/arch-am33xx/ddr_defs.h @@ -65,6 +65,40 @@ #define MT41J128MJT125_PHY_FIFO_WE 0x100 #define MT41J128MJT125_IOCTRL_VALUE 0x18B +/* Micron MT41J256M8HX-15E */ +#define MT41J256M8HX15E_EMIF_READ_LATENCY 0x06 +#define MT41J256M8HX15E_EMIF_TIM1 0x0888A39B +#define MT41J256M8HX15E_EMIF_TIM2 0x26337FDA +#define MT41J256M8HX15E_EMIF_TIM3 0x501F830F +#define MT41J256M8HX15E_EMIF_SDCFG 0x61C04B32 +#define MT41J256M8HX15E_EMIF_SDREF 0x0000093B +#define MT41J256M8HX15E_ZQ_CFG 0x50074BE4 +#define MT41J256M8HX15E_DLL_LOCK_DIFF 0x1 +#define MT41J256M8HX15E_RATIO 0x40 +#define MT41J256M8HX15E_INVERT_CLKOUT 0x1 +#define MT41J256M8HX15E_RD_DQS 0x3B +#define MT41J256M8HX15E_WR_DQS 0x85 +#define MT41J256M8HX15E_PHY_WR_DATA 0xC1 +#define MT41J256M8HX15E_PHY_FIFO_WE 0x100 +#define MT41J256M8HX15E_IOCTRL_VALUE 0x18B + +/* Micron MT41J512M8RH-125 on EVM v1.5 */ +#define MT41J512M8RH125_EMIF_READ_LATENCY 0x06 +#define MT41J512M8RH125_EMIF_TIM1 0x0888A39B +#define MT41J512M8RH125_EMIF_TIM2 0x26517FDA +#define MT41J512M8RH125_EMIF_TIM3 0x501F84EF +#define MT41J512M8RH125_EMIF_SDCFG 0x61C04BB2 +#define MT41J512M8RH125_EMIF_SDREF 0x0000093B +#define MT41J512M8RH125_ZQ_CFG 0x50074BE4 +#define MT41J512M8RH125_DLL_LOCK_DIFF 0x1 +#define MT41J512M8RH125_RATIO 0x80 +#define MT41J512M8RH125_INVERT_CLKOUT 0x0 +#define MT41J512M8RH125_RD_DQS 0x3B +#define MT41J512M8RH125_WR_DQS 0x3C +#define MT41J512M8RH125_PHY_FIFO_WE 0xA5 +#define MT41J512M8RH125_PHY_WR_DATA 0x74 +#define MT41J512M8RH125_IOCTRL_VALUE 0x18B + /** * Configure SDRAM */ diff --git a/arch/arm/include/asm/arch-am33xx/mux.h b/arch/arm/include/asm/arch-am33xx/mux.h index aed6b00cc6..460ac1c02d 100644 --- a/arch/arm/include/asm/arch-am33xx/mux.h +++ b/arch/arm/include/asm/arch-am33xx/mux.h @@ -25,7 +25,8 @@ /* PAD Control Fields */ #define SLEWCTRL (0x1 << 6) #define RXACTIVE (0x1 << 5) -#define PULLUP_EN (0x1 << 4) /* Pull UP Selection */ +#define PULLDOWN_EN (0x0 << 4) /* Pull Down Selection */ +#define PULLUP_EN (0x1 << 4) /* Pull Up Selection */ #define PULLUDEN (0x0 << 3) /* Pull up enabled */ #define PULLUDDIS (0x1 << 3) /* Pull up disabled */ #define MODE(val) val /* used for Readability */ diff --git a/arch/arm/include/asm/arch-am33xx/spl.h b/arch/arm/include/asm/arch-am33xx/spl.h index 644ff353fe..e961ce0578 100644 --- a/arch/arm/include/asm/arch-am33xx/spl.h +++ b/arch/arm/include/asm/arch-am33xx/spl.h @@ -29,6 +29,7 @@ #define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ #define BOOT_DEVICE_SPI 11 #define BOOT_DEVICE_UART 65 +#define BOOT_DEVICE_USBETH 68 #define BOOT_DEVICE_CPGMAC 70 #define BOOT_DEVICE_MMC2_2 0xFF #endif diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h index 1e8522b839..d4852a38c1 100644 --- a/arch/arm/include/asm/arch-at91/clk.h +++ b/arch/arm/include/asm/arch-at91/clk.h @@ -31,37 +31,37 @@ static inline unsigned long get_cpu_clk_rate(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->cpu_clk_rate_hz; + return gd->arch.cpu_clk_rate_hz; } static inline unsigned long get_main_clk_rate(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->main_clk_rate_hz; + return gd->arch.main_clk_rate_hz; } static inline unsigned long get_mck_clk_rate(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->mck_rate_hz; + return gd->arch.mck_rate_hz; } static inline unsigned long get_plla_clk_rate(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->plla_rate_hz; + return gd->arch.plla_rate_hz; } static inline unsigned long get_pllb_clk_rate(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->pllb_rate_hz; + return gd->arch.pllb_rate_hz; } static inline u32 get_pllb_init(void) { DECLARE_GLOBAL_DATA_PTR; - return gd->at91_pllb_usb_init; + return gd->arch.at91_pllb_usb_init; } static inline unsigned long get_macb_pclk_rate(unsigned int dev_id) diff --git a/arch/arm/include/asm/arch-davinci/gpio.h b/arch/arm/include/asm/arch-davinci/gpio.h index ef65ffbb9f..fbbb1f33c3 100644 --- a/arch/arm/include/asm/arch-davinci/gpio.h +++ b/arch/arm/include/asm/arch-davinci/gpio.h @@ -67,7 +67,11 @@ struct davinci_gpio_bank { #define gpio_status() gpio_info() #define GPIO_NAME_SIZE 20 +#if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850) +#define MAX_NUM_GPIOS 128 +#else #define MAX_NUM_GPIOS 144 +#endif #define GPIO_BANK(gp) (davinci_gpio_bank01 + ((gp) >> 5)) #define GPIO_BIT(gp) ((gp) & 0x1F) diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h index 70d94c5041..73dfd394d8 100644 --- a/arch/arm/include/asm/arch-tegra/ap.h +++ b/arch/arm/include/asm/arch-tegra/ap.h @@ -23,67 +23,27 @@ #include <asm/types.h> /* Stabilization delays, in usec */ -#define PLL_STABILIZATION_DELAY (300) +#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) +#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)) +#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 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 +/* AP base physical address of internal SRAM */ +#define NV_PA_BASE_SRAM 0x40000000 #define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) #define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h index be6bf25f0b..3db0d93b89 100644 --- a/arch/arm/include/asm/arch-tegra/board.h +++ b/arch/arm/include/asm/arch-tegra/board.h @@ -41,8 +41,9 @@ void gpio_early_init(void); /* overrideable GPIO config */ * an empty stub function will be called. */ -void pin_mux_usb(void); /* overrideable USB pinmux setup */ -void pin_mux_spi(void); /* overrideable SPI pinmux setup */ -void pin_mux_nand(void); /* overrideable NAND pinmux setup */ +void pin_mux_usb(void); /* overrideable USB pinmux setup */ +void pin_mux_spi(void); /* overrideable SPI pinmux setup */ +void pin_mux_nand(void); /* overrideable NAND pinmux setup */ +void pin_mux_display(void); /* overrideable DISPLAY pinmux setup */ #endif diff --git a/arch/arm/include/asm/arch-tegra/clk_rst.h b/arch/arm/include/asm/arch-tegra/clk_rst.h index 7b548c2298..c754ec753b 100644 --- a/arch/arm/include/asm/arch-tegra/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra/clk_rst.h @@ -21,8 +21,8 @@ * MA 02111-1307 USA */ -#ifndef _CLK_RST_H_ -#define _CLK_RST_H_ +#ifndef _TEGRA_CLK_RST_H_ +#define _TEGRA_CLK_RST_H_ /* PLL registers - there are several PLLs in the clock controller */ struct clk_pll { @@ -37,6 +37,12 @@ struct clk_pll_simple { uint pll_misc; /* other misc things */ }; +/* RST_DEV_(L,H,U,V,W)_(SET,CLR) and CLK_ENB_(L,H,U,V,W)_(SET,CLR) */ +struct clk_set_clr { + uint set; + uint clr; +}; + /* * Most PLLs use the clk_pll structure, but some have a simpler two-member * structure for which we use clk_pll_simple. The reason for this non- @@ -45,8 +51,10 @@ struct clk_pll_simple { enum { TEGRA_CLK_PLLS = 6, /* Number of normal PLLs */ TEGRA_CLK_SIMPLE_PLLS = 3, /* Number of simple PLLs */ - TEGRA_CLK_REGS = 3, /* Number of clock enable registers */ - TEGRA_CLK_SOURCES = 64, /* Number of peripheral clock sources */ + TEGRA_CLK_REGS = 3, /* Number of clock enable regs L/H/U */ + TEGRA_CLK_SOURCES = 64, /* Number of ppl clock sources L/H/U */ + TEGRA_CLK_REGS_VW = 2, /* Number of clock enable regs V/W */ + TEGRA_CLK_SOURCES_VW = 32, /* Number of ppl clock sources V/W*/ }; /* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */ @@ -82,14 +90,80 @@ struct clk_rst_ctlr { uint crc_reserved11; /* _reserved_11, 0xFC */ uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */ - 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 */ + + uint crc_reserved20[64]; /* _reserved_20, 0x200-2fc */ + + /* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */ + struct clk_set_clr crc_rst_dev_ex[TEGRA_CLK_REGS]; + + uint crc_reserved30[2]; /* _reserved_30, 0x318, 0x31c */ + + /* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */ + struct clk_set_clr crc_clk_enb_ex[TEGRA_CLK_REGS]; + + uint crc_reserved31[2]; /* _reserved_31, 0x338, 0x33c */ + + uint crc_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */ + uint crc_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */ + + /* Additional (T30) registers */ + uint crc_clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */ + uint crc_clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */ + + uint crc_reserved32[2]; /* _reserved_32, 0x350,0x354 */ + + uint crc_rst_dev_vw[TEGRA_CLK_REGS_VW]; /* _RST_DEVICES_V/W_0 */ + uint crc_clk_out_enb_vw[TEGRA_CLK_REGS_VW]; /* _CLK_OUT_ENB_V/W_0 */ + uint crc_cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */ + uint crc_super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36C */ + uint crc_cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */ + uint crc_super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */ + uint crc_clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */ + uint crc_clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37C */ + uint crc_cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */ + uint crc_cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTR1L_0, 0x384 */ + uint crc_cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */ + uint crc_reserved33[9]; /* _reserved_33, 0x38c-3ac */ + uint crc_clk_src_vw[TEGRA_CLK_SOURCES_VW]; /* _G3D2_0..., 0x3b0-0x42c */ + /* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */ + struct clk_set_clr crc_rst_dev_ex_vw[TEGRA_CLK_REGS_VW]; + /* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */ + struct clk_set_clr crc_clk_enb_ex_vw[TEGRA_CLK_REGS_VW]; + /* Additional (T114) registers */ + uint crc_rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */ + uint crc_rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */ + uint crc_rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */ + uint crc_rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45C */ + uint crc_clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */ + uint crc_clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */ + uint crc_clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */ + uint crc_clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46C */ + uint crc_cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */ + uint crc_reserved40[1]; /* _reserved_40, 0x474 */ + uint crc_intstatus; /* __INTSTATUS_0, 0x478 */ + uint crc_intmask; /* __INTMASK_0, 0x47C */ + uint crc_utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */ + uint crc_utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */ + uint crc_utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */ + + uint crc_plle_aux; /* _PLLE_AUX_0, 0x48C */ + uint crc_sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */ + uint crc_sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */ + uint crc_pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */ + + uint crc_prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49C */ + uint crc_audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4A0 */ + uint crc_audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4A4 */ + uint crc_audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4A8 */ + uint crc_audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4AC */ + uint crc_audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4B0 */ + uint crc_audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4B4 */ }; /* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */ +#define CPU3_CLK_STP_SHIFT 11 +#define CPU2_CLK_STP_SHIFT 10 #define CPU1_CLK_STP_SHIFT 9 - #define CPU0_CLK_STP_SHIFT 8 #define CPU0_CLK_STP_MASK (1U << CPU0_CLK_STP_SHIFT) @@ -120,6 +194,12 @@ struct clk_rst_ctlr { #define PLL_OUT_RATIO_MASK (0xffU << PLL_OUT_RATIO_SHIFT) /* CLK_RST_CONTROLLER_PLLx_MISC_0 */ +#define PLL_DCCON_SHIFT 20 +#define PLL_DCCON_MASK (1U << PLL_DCCON_SHIFT) + +#define PLL_LOCK_ENABLE_SHIFT 18 +#define PLL_LOCK_ENABLE_MASK (1U << PLL_LOCK_ENABLE_SHIFT) + #define PLL_CPCON_SHIFT 8 #define PLL_CPCON_MASK (15U << PLL_CPCON_SHIFT) @@ -129,9 +209,23 @@ struct clk_rst_ctlr { #define PLLU_VCO_FREQ_SHIFT 20 #define PLLU_VCO_FREQ_MASK (1U << PLLU_VCO_FREQ_SHIFT) +#define PLLP_OUT1_OVR (1 << 2) +#define PLLP_OUT2_OVR (1 << 18) +#define PLLP_OUT3_OVR (1 << 2) +#define PLLP_OUT4_OVR (1 << 18) +#define PLLP_OUT1_RATIO 8 +#define PLLP_OUT2_RATIO 24 +#define PLLP_OUT3_RATIO 8 +#define PLLP_OUT4_RATIO 24 + +enum { + IN_408_OUT_204_DIVISOR = 2, + IN_408_OUT_102_DIVISOR = 6, + IN_408_OUT_48_DIVISOR = 15, + IN_408_OUT_9_6_DIVISOR = 83, +}; + /* CLK_RST_CONTROLLER_OSC_CTRL_0 */ -#define OSC_FREQ_SHIFT 30 -#define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT) #define OSC_XOBP_SHIFT 1 #define OSC_XOBP_MASK (1U << OSC_XOBP_SHIFT) @@ -151,4 +245,84 @@ struct clk_rst_ctlr { #define OUT_CLK_SOURCE4_SHIFT 28 #define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_SHIFT) -#endif /* CLK_RST_H */ +/* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */ +#define SCLK_SYS_STATE_SHIFT 28U +#define SCLK_SYS_STATE_MASK (15U << SCLK_SYS_STATE_SHIFT) +enum { + SCLK_SYS_STATE_STDBY, + SCLK_SYS_STATE_IDLE, + SCLK_SYS_STATE_RUN, + SCLK_SYS_STATE_IRQ = 4U, + SCLK_SYS_STATE_FIQ = 8U, +}; +#define SCLK_COP_FIQ_MASK (1 << 27) +#define SCLK_CPU_FIQ_MASK (1 << 26) +#define SCLK_COP_IRQ_MASK (1 << 25) +#define SCLK_CPU_IRQ_MASK (1 << 24) + +#define SCLK_SWAKEUP_FIQ_SOURCE_SHIFT 12 +#define SCLK_SWAKEUP_FIQ_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_IRQ_SOURCE_SHIFT 8 +#define SCLK_SWAKEUP_IRQ_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_RUN_SOURCE_SHIFT 4 +#define SCLK_SWAKEUP_RUN_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +#define SCLK_SWAKEUP_IDLE_SOURCE_SHIFT 0 + +#define SCLK_SWAKEUP_IDLE_SOURCE_MASK \ + (7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) +enum { + SCLK_SOURCE_CLKM, + SCLK_SOURCE_PLLC_OUT1, + SCLK_SOURCE_PLLP_OUT4, + SCLK_SOURCE_PLLP_OUT3, + SCLK_SOURCE_PLLP_OUT2, + SCLK_SOURCE_CLKD, + SCLK_SOURCE_CLKS, + SCLK_SOURCE_PLLM_OUT1, +}; +#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 (7 << 12) +#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 (7 << 8) +#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1 (7 << 4) +#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 (7 << 0) + +/* CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER */ +#define SUPER_SCLK_ENB_SHIFT 31U +#define SUPER_SCLK_ENB_MASK (1U << 31) +#define SUPER_SCLK_DIVIDEND_SHIFT 8 +#define SUPER_SCLK_DIVIDEND_MASK (0xff << SUPER_SCLK_DIVIDEND_SHIFT) +#define SUPER_SCLK_DIVISOR_SHIFT 0 +#define SUPER_SCLK_DIVISOR_MASK (0xff << SUPER_SCLK_DIVISOR_SHIFT) + +/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE */ +#define CLK_SYS_RATE_HCLK_DISABLE_SHIFT 7 +#define CLK_SYS_RATE_HCLK_DISABLE_MASK (1 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) +#define CLK_SYS_RATE_AHB_RATE_SHIFT 4 +#define CLK_SYS_RATE_AHB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT) +#define CLK_SYS_RATE_PCLK_DISABLE_SHIFT 3 +#define CLK_SYS_RATE_PCLK_DISABLE_MASK (1 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) +#define CLK_SYS_RATE_APB_RATE_SHIFT 0 +#define CLK_SYS_RATE_APB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT) + +/* CLK_RST_CONTROLLER_RST_CPUxx_CMPLX_CLR */ +#define CLR_CPURESET0 (1 << 0) +#define CLR_CPURESET1 (1 << 1) +#define CLR_CPURESET2 (1 << 2) +#define CLR_CPURESET3 (1 << 3) +#define CLR_DBGRESET0 (1 << 12) +#define CLR_DBGRESET1 (1 << 13) +#define CLR_DBGRESET2 (1 << 14) +#define CLR_DBGRESET3 (1 << 15) +#define CLR_CORERESET0 (1 << 16) +#define CLR_CORERESET1 (1 << 17) +#define CLR_CORERESET2 (1 << 18) +#define CLR_CORERESET3 (1 << 19) +#define CLR_CXRESET0 (1 << 20) +#define CLR_CXRESET1 (1 << 21) +#define CLR_CXRESET2 (1 << 22) +#define CLR_CXRESET3 (1 << 23) +#define CLR_NONCPURESET (1 << 29) + +#endif /* _TEGRA_CLK_RST_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index eac1dc2662..c8677bdd76 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -21,8 +21,8 @@ /* Tegra clock control functions */ -#ifndef _CLOCK_H -#define _CLOCK_H +#ifndef _TEGRA_CLOCK_H_ +#define _TEGRA_CLOCK_H_ /* Set of oscillator frequencies supported in the internal API. */ enum clock_osc_freq { @@ -82,7 +82,7 @@ int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, * @returns 0 if ok, -1 on error (invalid clock id) */ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, - u32 *divp, u32 *cpcon, u32 *lfcon); + u32 *divp, u32 *cpcon, u32 *lfcon); /* * Enable a clock @@ -136,7 +136,7 @@ enum crc_reset_id { /** * Put parts of the CPU complex into or out of reset.\ * - * @param cpu cpu number (0 or 1 on Tegra2) + * @param cpu cpu number (0 or 1 on Tegra2, 0-3 on Tegra3) * @param which which parts of the complex to affect (OR of crc_reset_id) * @param reset 1 to assert reset, 0 to de-assert */ @@ -262,4 +262,59 @@ void clock_init(void); /* Initialize the PLLs */ void clock_early_init(void); -#endif /* _CLOCK_H_ */ +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id); + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits); + +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra30 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id); + +/** + * Set the output frequency you want for each PLL clock. + * PLL output frequencies are programmed by setting their N, M and P values. + * The governing equations are: + * VCO = (Fi / m) * n, Fo = VCO / (2^p) + * where Fo is the output frequency from the PLL. + * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) + * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 + * Please see Tegra TRM section 5.3 to get the detail for PLL Programming + * + * @param n PLL feedback divider(DIVN) + * @param m PLL input divider(DIVN) + * @param p post divider(DIVP) + * @param cpcon base PLL charge pump(CPCON) + * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot + * be overriden), 1 if PLL is already correct + */ +int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon); + +/* return 1 if a peripheral ID is in range */ +#define clock_type_id_isvalid(id) ((id) >= 0 && \ + (id) < CLOCK_TYPE_COUNT) + +/* return 1 if a periphc_internal_id is in range */ +#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ + (id) < PERIPHC_COUNT) + +#endif /* _TEGRA_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/funcmux.h b/arch/arm/include/asm/arch-tegra/funcmux.h new file mode 100644 index 0000000000..f101e5ef6a --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/funcmux.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra high-level function multiplexing */ + +#ifndef _TEGRA_FUNCMUX_H_ +#define _TEGRA_FUNCMUX_H_ + +/** + * Select a config for a particular peripheral. + * + * Each peripheral can operate through a number of configurations, + * which are sets of pins that it uses to bring out its signals. + * The basic config is 0, and higher numbers indicate different + * pinmux settings to bring the peripheral out on other pins, + * + * This function also disables tristate for the function's pins, + * so that they operate in normal mode. + * + * @param id Peripheral id + * @param config Configuration to use (FUNCMUX_...), 0 for default + * @return 0 if ok, -1 on error (e.g. incorrect id or config) + */ +int funcmux_select(enum periph_id id, int config); + +#endif /* _TEGRA_FUNCMUX_H_ */ diff --git a/arch/x86/include/asm/realmode.h b/arch/arm/include/asm/arch-tegra/gp_padctrl.h index 0f12a893b4..209abf160a 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/arm/include/asm/arch-tegra/gp_padctrl.h @@ -1,6 +1,6 @@ /* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * (C) Copyright 2010-2012 + * NVIDIA Corporation <www.nvidia.com> * * See file CREDITS for list of people who contributed to this * project. @@ -21,16 +21,20 @@ * MA 02111-1307 USA */ -#ifndef __ASM_REALMODE_H_ -#define __ASM_REALMODE_H_ -#include <asm/ptrace.h> +#ifndef _TEGRA_GP_PADCTRL_H_ +#define _TEGRA_GP_PADCTRL_H_ -extern ulong __realmode_start; -extern ulong __realmode_size; -extern char realmode_enter; +#define GP_HIDREV 0x804 -int bios_setup(void); -int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out); -int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out); +/* bit fields definitions for APB_MISC_GP_HIDREV register */ +#define HIDREV_CHIPID_SHIFT 8 +#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) +#define HIDREV_MAJORPREV_SHIFT 4 +#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT) -#endif +/* CHIPID field returned from APB_MISC_GP_HIDREV register */ +#define CHIPID_TEGRA20 0x20 +#define CHIPID_TEGRA30 0x30 +#define CHIPID_TEGRA114 0x35 + +#endif /* _TEGRA_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/pmc.h b/arch/arm/include/asm/arch-tegra/pmc.h index b1d47cd2e3..1bcdcf8eec 100644 --- a/arch/arm/include/asm/arch-tegra/pmc.h +++ b/arch/arm/include/asm/arch-tegra/pmc.h @@ -128,5 +128,13 @@ struct pmc_ctlr { #define START_CP (1 << 8) #define CPUPWRREQ_OE (1 << 16) +#define CPUPWRREQ_POL (1 << 15) + +#define CRAILID (0) +#define CE0ID (14) +#define C0NCID (15) +#define CRAIL (1 << CRAILID) +#define CE0 (1 << CE0ID) +#define C0NC (1 << C0NCID) #endif /* PMC_H */ diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h index 6d2e62f559..bf7229d8ac 100644 --- a/arch/arm/include/asm/arch-tegra/tegra.h +++ b/arch/arm/include/asm/arch-tegra/tegra.h @@ -40,6 +40,12 @@ #define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400) #define NV_PA_NAND_BASE (NV_PA_APB_MISC_BASE + 0x8000) #define NV_PA_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380) +#define NV_PA_SLINK1_BASE (NV_PA_APB_MISC_BASE + 0xD400) +#define NV_PA_SLINK2_BASE (NV_PA_APB_MISC_BASE + 0xD600) +#define NV_PA_SLINK3_BASE (NV_PA_APB_MISC_BASE + 0xD800) +#define NV_PA_SLINK4_BASE (NV_PA_APB_MISC_BASE + 0xDA00) +#define NV_PA_SLINK5_BASE (NV_PA_APB_MISC_BASE + 0xDC00) +#define NV_PA_SLINK6_BASE (NV_PA_APB_MISC_BASE + 0xDE00) #define TEGRA_DVC_BASE (NV_PA_APB_MISC_BASE + 0xD000) #define NV_PA_PMC_BASE (NV_PA_APB_MISC_BASE + 0xE400) #define NV_PA_EMC_BASE (NV_PA_APB_MISC_BASE + 0xF400) @@ -72,14 +78,23 @@ enum { SKU_ID_T25 = 0x18, SKU_ID_AP25E = 0x1b, SKU_ID_T25E = 0x1c, + SKU_ID_T30 = 0x81, /* Cardhu value */ + SKU_ID_T114_ENG = 0x00, /* Dalmore value, unfused */ }; -/* These are the SOC categories that affect clocking */ +/* + * These are used to distinguish SOC types for setting up clocks. Mostly + * we can tell the clocking required by looking at the SOC sku_id, but + * for T30 it is a user option as to whether to run PLLP in fast or slow + * mode, so we have two options there. + */ enum { TEGRA_SOC_T20, TEGRA_SOC_T25, + TEGRA_SOC_T30, + TEGRA_SOC_T114, - TEGRA_SOC_COUNT, + TEGRA_SOC_CNT, TEGRA_SOC_UNKNOWN = -1, }; diff --git a/arch/arm/include/asm/arch-tegra/tegra_slink.h b/arch/arm/include/asm/arch-tegra/tegra_slink.h new file mode 100644 index 0000000000..74804b5465 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_slink.h @@ -0,0 +1,84 @@ +/* + * NVIDIA Tegra SPI-SLINK controller + * + * Copyright 2010-2013 NVIDIA Corporation + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * 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 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 _TEGRA_SLINK_H_ +#define _TEGRA_SLINK_H_ + +#include <asm/types.h> + +struct slink_tegra { + u32 command; /* SLINK_COMMAND_0 register */ + u32 command2; /* SLINK_COMMAND2_0 reg */ + u32 status; /* SLINK_STATUS_0 register */ + u32 reserved; /* Reserved offset 0C */ + u32 mas_data; /* SLINK_MAS_DATA_0 reg */ + u32 slav_data; /* SLINK_SLAVE_DATA_0 reg */ + u32 dma_ctl; /* SLINK_DMA_CTL_0 register */ + u32 status2; /* SLINK_STATUS2_0 reg */ + u32 rsvd[56]; /* 0x20 to 0xFF reserved */ + u32 tx_fifo; /* SLINK_TX_FIFO_0 reg off 100h */ + u32 rsvd2[31]; /* 0x104 to 0x17F reserved */ + u32 rx_fifo; /* SLINK_RX_FIFO_0 reg off 180h */ +}; + +/* COMMAND */ +#define SLINK_CMD_ENB (1 << 31) +#define SLINK_CMD_GO (1 << 30) +#define SLINK_CMD_M_S (1 << 28) +#define SLINK_CMD_CK_SDA (1 << 21) +#define SLINK_CMD_CS_POL (1 << 13) +#define SLINK_CMD_CS_VAL (1 << 12) +#define SLINK_CMD_CS_SOFT (1 << 11) +#define SLINK_CMD_BIT_LENGTH (1 << 4) +#define SLINK_CMD_BIT_LENGTH_MASK 0x0000001F +/* COMMAND2 */ +#define SLINK_CMD2_TXEN (1 << 30) +#define SLINK_CMD2_RXEN (1 << 31) +#define SLINK_CMD2_SS_EN (1 << 18) +#define SLINK_CMD2_SS_EN_SHIFT 18 +#define SLINK_CMD2_SS_EN_MASK 0x000C0000 +#define SLINK_CMD2_CS_ACTIVE_BETWEEN (1 << 17) +/* STATUS */ +#define SLINK_STAT_BSY (1 << 31) +#define SLINK_STAT_RDY (1 << 30) +#define SLINK_STAT_ERR (1 << 29) +#define SLINK_STAT_RXF_FLUSH (1 << 27) +#define SLINK_STAT_TXF_FLUSH (1 << 26) +#define SLINK_STAT_RXF_OVF (1 << 25) +#define SLINK_STAT_TXF_UNR (1 << 24) +#define SLINK_STAT_RXF_EMPTY (1 << 23) +#define SLINK_STAT_RXF_FULL (1 << 22) +#define SLINK_STAT_TXF_EMPTY (1 << 21) +#define SLINK_STAT_TXF_FULL (1 << 20) +#define SLINK_STAT_TXF_OVF (1 << 19) +#define SLINK_STAT_RXF_UNR (1 << 18) +#define SLINK_STAT_CUR_BLKCNT (1 << 15) +/* STATUS2 */ +#define SLINK_STAT2_RXF_FULL_CNT (1 << 16) +#define SLINK_STAT2_TXF_FULL_CNT (1 << 0) + +#define SPI_TIMEOUT 1000 +#define TEGRA_SPI_MAX_FREQ 52000000 + +#endif /* _TEGRA_SLINK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/clock-tables.h b/arch/arm/include/asm/arch-tegra114/clock-tables.h new file mode 100644 index 0000000000..d8fa0e1d2c --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/clock-tables.h @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 clock PLL tables */ + +#ifndef _TEGRA114_CLOCK_TABLES_H_ +#define _TEGRA114_CLOCK_TABLES_H_ + +/* The PLLs supported by the hardware */ +enum clock_id { + CLOCK_ID_FIRST, + CLOCK_ID_CGENERAL = CLOCK_ID_FIRST, + CLOCK_ID_MEMORY, + CLOCK_ID_PERIPH, + CLOCK_ID_AUDIO, + CLOCK_ID_USB, + CLOCK_ID_DISPLAY, + + /* now the simple ones */ + CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_EPCI, + CLOCK_ID_SFROM32KHZ, + + /* These are the base clocks (inputs to the Tegra SOC) */ + CLOCK_ID_32KHZ, + CLOCK_ID_OSC, + + CLOCK_ID_COUNT, /* number of PLLs */ + CLOCK_ID_DISPLAY2, /* placeholder */ + CLOCK_ID_NONE = -1, +}; + +/* The clocks supported by the hardware */ +enum periph_id { + PERIPH_ID_FIRST, + + /* Low word: 31:0 (DEVICES_L) */ + PERIPH_ID_CPU = PERIPH_ID_FIRST, + PERIPH_ID_COP, + PERIPH_ID_TRIGSYS, + PERIPH_ID_RESERVED3, + PERIPH_ID_RTC, + PERIPH_ID_TMR, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + + /* 8 */ + PERIPH_ID_GPIO, + PERIPH_ID_SDMMC2, + PERIPH_ID_SPDIF, + PERIPH_ID_I2S1, + PERIPH_ID_I2C1, + PERIPH_ID_NDFLASH, + PERIPH_ID_SDMMC1, + PERIPH_ID_SDMMC4, + + /* 16 */ + PERIPH_ID_RESERVED16, + PERIPH_ID_PWM, + PERIPH_ID_I2S2, + PERIPH_ID_EPP, + PERIPH_ID_VI, + PERIPH_ID_2D, + PERIPH_ID_USBD, + PERIPH_ID_ISP, + + /* 24 */ + PERIPH_ID_3D, + PERIPH_ID_RESERVED24, + PERIPH_ID_DISP2, + PERIPH_ID_DISP1, + PERIPH_ID_HOST1X, + PERIPH_ID_VCP, + PERIPH_ID_I2S0, + PERIPH_ID_CACHE2, + + /* Middle word: 63:32 (DEVICES_H) */ + PERIPH_ID_MEM, + PERIPH_ID_AHBDMA, + PERIPH_ID_APBDMA, + PERIPH_ID_RESERVED35, + PERIPH_ID_KBC, + PERIPH_ID_STAT_MON, + PERIPH_ID_PMC, + PERIPH_ID_FUSE, + + /* 40 */ + PERIPH_ID_KFUSE, + PERIPH_ID_SBC1, + PERIPH_ID_SNOR, + PERIPH_ID_RESERVED43, + PERIPH_ID_SBC2, + PERIPH_ID_RESERVED45, + PERIPH_ID_SBC3, + PERIPH_ID_I2C5, + + /* 48 */ + PERIPH_ID_DSI, + PERIPH_ID_TVO, + PERIPH_ID_MIPI, + PERIPH_ID_HDMI, + PERIPH_ID_CSI, + PERIPH_ID_TVDAC, + PERIPH_ID_I2C2, + PERIPH_ID_UART3, + + /* 56 */ + PERIPH_ID_RESERVED56, + PERIPH_ID_EMC, + PERIPH_ID_USB2, + PERIPH_ID_USB3, + PERIPH_ID_MPE, + PERIPH_ID_VDE, + PERIPH_ID_BSEA, + PERIPH_ID_BSEV, + + /* Upper word 95:64 (DEVICES_U) */ + PERIPH_ID_SPEEDO, + PERIPH_ID_UART4, + PERIPH_ID_UART5, + PERIPH_ID_I2C3, + PERIPH_ID_SBC4, + PERIPH_ID_SDMMC3, + PERIPH_ID_PCIE, + PERIPH_ID_OWR, + + /* 72 */ + PERIPH_ID_AFI, + PERIPH_ID_CORESIGHT, + PERIPH_ID_PCIEXCLK, + PERIPH_ID_AVPUCQ, + PERIPH_ID_RESERVED76, + PERIPH_ID_RESERVED77, + PERIPH_ID_RESERVED78, + PERIPH_ID_DTV, + + /* 80 */ + PERIPH_ID_NANDSPEED, + PERIPH_ID_I2CSLOW, + PERIPH_ID_DSIB, + PERIPH_ID_RESERVED83, + PERIPH_ID_IRAMA, + PERIPH_ID_IRAMB, + PERIPH_ID_IRAMC, + PERIPH_ID_IRAMD, + + /* 88 */ + PERIPH_ID_CRAM2, + PERIPH_ID_RESERVED89, + PERIPH_ID_MDOUBLER, + PERIPH_ID_RESERVED91, + PERIPH_ID_SUSOUT, + PERIPH_ID_RESERVED93, + PERIPH_ID_RESERVED94, + PERIPH_ID_RESERVED95, + + PERIPH_ID_VW_FIRST, + /* V word: 31:0 */ + PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST, + PERIPH_ID_CPULP, + PERIPH_ID_3D2, + PERIPH_ID_MSELECT, + PERIPH_ID_TSENSOR, + PERIPH_ID_I2S3, + PERIPH_ID_I2S4, + PERIPH_ID_I2C4, + + /* 104 */ + PERIPH_ID_SBC5, + PERIPH_ID_SBC6, + PERIPH_ID_AUDIO, + PERIPH_ID_APBIF, + PERIPH_ID_DAM0, + PERIPH_ID_DAM1, + PERIPH_ID_DAM2, + PERIPH_ID_HDA2CODEC2X, + + /* 112 */ + PERIPH_ID_ATOMICS, + PERIPH_ID_EX_RESERVED17, + PERIPH_ID_EX_RESERVED18, + PERIPH_ID_EX_RESERVED19, + PERIPH_ID_EX_RESERVED20, + PERIPH_ID_EX_RESERVED21, + PERIPH_ID_EX_RESERVED22, + PERIPH_ID_ACTMON, + + /* 120 */ + PERIPH_ID_EX_RESERVED24, + PERIPH_ID_EX_RESERVED25, + PERIPH_ID_EX_RESERVED26, + PERIPH_ID_EX_RESERVED27, + PERIPH_ID_SATA, + PERIPH_ID_HDA, + PERIPH_ID_EX_RESERVED30, + PERIPH_ID_EX_RESERVED31, + + /* W word: 31:0 */ + PERIPH_ID_HDA2HDMICODEC, + PERIPH_ID_RESERVED1_SATACOLD, + PERIPH_ID_RESERVED2_PCIERX0, + PERIPH_ID_RESERVED3_PCIERX1, + PERIPH_ID_RESERVED4_PCIERX2, + PERIPH_ID_RESERVED5_PCIERX3, + PERIPH_ID_RESERVED6_PCIERX4, + PERIPH_ID_RESERVED7_PCIERX5, + + /* 136 */ + PERIPH_ID_CEC, + PERIPH_ID_PCIE2_IOBIST, + PERIPH_ID_EMC_IOBIST, + PERIPH_ID_HDMI_IOBIST, + PERIPH_ID_SATA_IOBIST, + PERIPH_ID_MIPI_IOBIST, + PERIPH_ID_EMC1_IOBIST, + PERIPH_ID_XUSB, + + /* 144 */ + PERIPH_ID_CILAB, + PERIPH_ID_CILCD, + PERIPH_ID_CILE, + PERIPH_ID_DSIA_LP, + PERIPH_ID_DSIB_LP, + PERIPH_ID_RESERVED21_ENTROPY, + PERIPH_ID_RESERVED22_W, + PERIPH_ID_RESERVED23_W, + + /* 152 */ + PERIPH_ID_RESERVED24_W, + PERIPH_ID_AMX0, + PERIPH_ID_ADX0, + PERIPH_ID_DVFS, + PERIPH_ID_XUSB_SS, + PERIPH_ID_EMC_DLL, + PERIPH_ID_MC1, + PERIPH_ID_EMC1, + + PERIPH_ID_COUNT, + PERIPH_ID_NONE = -1, +}; + +enum pll_out_id { + PLL_OUT1, + PLL_OUT2, + PLL_OUT3, + PLL_OUT4 +}; + +/* + * Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want + * callers to use the PERIPH_ID for all access to peripheral clocks to avoid + * confusion bewteen PERIPH_ID_... and PERIPHC_... + * + * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be + * confusing. + */ +enum periphc_internal_id { + /* 0x00 */ + PERIPHC_I2S1, + PERIPHC_I2S2, + PERIPHC_SPDIF_OUT, + PERIPHC_SPDIF_IN, + PERIPHC_PWM, + PERIPHC_05h, + PERIPHC_SBC2, + PERIPHC_SBC3, + + /* 0x08 */ + PERIPHC_08h, + PERIPHC_I2C1, + PERIPHC_I2C5, + PERIPHC_0bh, + PERIPHC_0ch, + PERIPHC_SBC1, + PERIPHC_DISP1, + PERIPHC_DISP2, + + /* 0x10 */ + PERIPHC_CVE, + PERIPHC_11h, + PERIPHC_VI, + PERIPHC_13h, + PERIPHC_SDMMC1, + PERIPHC_SDMMC2, + PERIPHC_G3D, + PERIPHC_G2D, + + /* 0x18 */ + PERIPHC_NDFLASH, + PERIPHC_SDMMC4, + PERIPHC_VFIR, + PERIPHC_EPP, + PERIPHC_MPE, + PERIPHC_MIPI, + PERIPHC_UART1, + PERIPHC_UART2, + + /* 0x20 */ + PERIPHC_HOST1X, + PERIPHC_21h, + PERIPHC_TVO, + PERIPHC_HDMI, + PERIPHC_24h, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_EMC, + + /* 0x28 */ + PERIPHC_UART3, + PERIPHC_29h, + PERIPHC_VI_SENSOR, + PERIPHC_2bh, + PERIPHC_2ch, + PERIPHC_SBC4, + PERIPHC_I2C3, + PERIPHC_SDMMC3, + + /* 0x30 */ + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_VDE, + PERIPHC_OWR, + PERIPHC_NOR, + PERIPHC_CSITE, + PERIPHC_I2S0, + PERIPHC_37h, + + PERIPHC_VW_FIRST, + /* 0x38 */ + PERIPHC_G3D2 = PERIPHC_VW_FIRST, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + PERIPHC_SBC5, + PERIPHC_SBC6, + + /* 0x40 */ + PERIPHC_AUDIO, + PERIPHC_41h, + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + PERIPHC_ACTMON, + PERIPHC_EXTPERIPH1, + + /* 0x48 */ + PERIPHC_EXTPERIPH2, + PERIPHC_EXTPERIPH3, + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + PERIPHC_SYS, + PERIPHC_SPEEDO, + PERIPHC_4eh, + PERIPHC_4fh, + + /* 0x50 */ + PERIPHC_50h, + PERIPHC_51h, + PERIPHC_52h, + PERIPHC_53h, + PERIPHC_SATAOOB, + PERIPHC_SATA, + PERIPHC_HDA, + + PERIPHC_COUNT, + + PERIPHC_NONE = -1, +}; + +/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */ +#define PERIPH_REG(id) \ + (id < PERIPH_ID_VW_FIRST) ? \ + ((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 5) + +/* Mask value for a clock (within PERIPH_REG(id)) */ +#define PERIPH_MASK(id) (1 << ((id) & 0x1f)) + +/* return 1 if a PLL ID is in range */ +#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT) + +/* return 1 if a peripheral ID is in range */ +#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \ + (id) < PERIPH_ID_COUNT) + +#endif /* _TEGRA114_CLOCK_TABLES_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/clock.h b/arch/arm/include/asm/arch-tegra114/clock.h new file mode 100644 index 0000000000..abbefcd0e4 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/clock.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 clock control functions */ + +#ifndef _TEGRA114_CLOCK_H_ +#define _TEGRA114_CLOCK_H_ + +#include <asm/arch-tegra/clock.h> + +/* CLK_RST_CONTROLLER_OSC_CTRL_0 */ +#define OSC_FREQ_SHIFT 28 +#define OSC_FREQ_MASK (0xF << OSC_FREQ_SHIFT) + +#endif /* _TEGRA114_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/flow.h b/arch/arm/include/asm/arch-tegra114/flow.h new file mode 100644 index 0000000000..c7eb051c77 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/flow.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_FLOW_H_ +#define _TEGRA114_FLOW_H_ + +struct flow_ctlr { + u32 halt_cpu_events; + u32 halt_cop_events; + u32 cpu_csr; + u32 cop_csr; + u32 xrq_events; + u32 halt_cpu1_events; + u32 cpu1_csr; + u32 halt_cpu2_events; + u32 cpu2_csr; + u32 halt_cpu3_events; + u32 cpu3_csr; + u32 cluster_control; +}; + +#endif /* _TEGRA114_FLOW_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/funcmux.h b/arch/arm/include/asm/arch-tegra114/funcmux.h new file mode 100644 index 0000000000..7f48f2510f --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/funcmux.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra114 high-level function multiplexing */ + +#ifndef _TEGRA114_FUNCMUX_H_ +#define _TEGRA114_FUNCMUX_H_ + +#include <asm/arch-tegra/funcmux.h> + +/* Configs supported by the func mux */ +enum { + FUNCMUX_DEFAULT = 0, /* default config */ + + /* UART configs */ + FUNCMUX_UART4_GMI = 0, +}; +#endif /* _TEGRA114_FUNCMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/gp_padctrl.h b/arch/arm/include/asm/arch-tegra114/gp_padctrl.h new file mode 100644 index 0000000000..c538bdd052 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/gp_padctrl.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_GP_PADCTRL_H_ +#define _TEGRA114_GP_PADCTRL_H_ + +#include <asm/arch-tegra/gp_padctrl.h> + +/* APB_MISC_GP and padctrl registers */ +struct apb_misc_gp_ctlr { + u32 modereg; /* 0x00: APB_MISC_GP_MODEREG */ + u32 hidrev; /* 0x04: APB_MISC_GP_HIDREV */ + u32 reserved0[22]; /* 0x08 - 0x5C: */ + u32 emu_revid; /* 0x60: APB_MISC_GP_EMU_REVID */ + u32 xactor_scratch; /* 0x64: APB_MISC_GP_XACTOR_SCRATCH */ + u32 aocfg1; /* 0x68: APB_MISC_GP_AOCFG1PADCTRL */ + u32 aocfg2; /* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */ + u32 atcfg1; /* 0x70: APB_MISC_GP_ATCFG1PADCTRL */ + u32 atcfg2; /* 0x74: APB_MISC_GP_ATCFG2PADCTRL */ + u32 atcfg3; /* 0x78: APB_MISC_GP_ATCFG3PADCTRL */ + u32 atcfg4; /* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */ + u32 atcfg5; /* 0x80: APB_MISC_GP_ATCFG5PADCTRL */ + u32 cdev1cfg; /* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */ + u32 cdev2cfg; /* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */ + u32 csuscfg; /* 0x8C: APB_MISC_GP_CSUSCFGPADCTRL */ + u32 dap1cfg; /* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */ + u32 dap2cfg; /* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */ + u32 dap3cfg; /* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */ + u32 dap4cfg; /* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */ + u32 dbgcfg; /* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */ + u32 lcdcfg1; /* 0xA4: APB_MISC_GP_LCDCFG1PADCTRL */ + u32 lcdcfg2; /* 0xA8: APB_MISC_GP_LCDCFG2PADCTRL */ + u32 sdio2cfg; /* 0xAC: APB_MISC_GP_SDIO2CFGPADCTRL */ + u32 sdio3cfg; /* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */ + u32 spicfg; /* 0xB4: APB_MISC_GP_SPICFGPADCTRL */ + u32 uaacfg; /* 0xB8: APB_MISC_GP_UAACFGPADCTRL */ + u32 uabcfg; /* 0xBC: APB_MISC_GP_UABCFGPADCTRL */ + u32 uart2cfg; /* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */ + u32 uart3cfg; /* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */ + u32 vicfg1; /* 0xC8: APB_MISC_GP_VICFG1PADCTRL */ + u32 vivttgen; /* 0xCC: APB_MISC_GP_VIVTTGENPADCTRL */ + u32 reserved1[7]; /* 0xD0-0xE8: */ + u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */ +}; + +#endif /* _TEGRA114_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/gpio.h b/arch/arm/include/asm/arch-tegra114/gpio.h new file mode 100644 index 0000000000..21853b6eb5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/gpio.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_GPIO_H_ +#define _TEGRA114_GPIO_H_ + +/* + * The Tegra114 GPIO controller has 246 GPIOS in 8 banks of 4 ports, + * each with 8 GPIOs. + */ +#define TEGRA_GPIO_PORTS 4 /* number of ports per bank */ +#define TEGRA_GPIO_BANKS 8 /* number of banks */ + +#include <asm/arch-tegra/gpio.h> +#include <asm/arch-tegra30/gpio.h> + +#endif /* _TEGRA114_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/hardware.h b/arch/arm/include/asm/arch-tegra114/hardware.h new file mode 100644 index 0000000000..c21fbb6259 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/hardware.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_HARDWARE_H_ +#define _TEGRA114_HARDWARE_H_ + +/* include tegra specific hardware definitions */ + +#endif /* _TEGRA114_HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/pinmux.h b/arch/arm/include/asm/arch-tegra114/pinmux.h new file mode 100644 index 0000000000..fd2293039d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/pinmux.h @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_PINMUX_H_ +#define _TEGRA114_PINMUX_H_ + +/* + * Pin groups which we adjust. There are three basic attributes of each pin + * group which use this enum: + * + * - function + * - pullup / pulldown + * - tristate or normal + */ +enum pmux_pingrp { + PINGRP_ULPI_DATA0 = 0, /* offset 0x3000 */ + PINGRP_ULPI_DATA1, + PINGRP_ULPI_DATA2, + PINGRP_ULPI_DATA3, + PINGRP_ULPI_DATA4, + PINGRP_ULPI_DATA5, + PINGRP_ULPI_DATA6, + PINGRP_ULPI_DATA7, + PINGRP_ULPI_CLK, + PINGRP_ULPI_DIR, + PINGRP_ULPI_NXT, + PINGRP_ULPI_STP, + PINGRP_DAP3_FS, + PINGRP_DAP3_DIN, + PINGRP_DAP3_DOUT, + PINGRP_DAP3_SCLK, + PINGRP_GPIO_PV0, + PINGRP_GPIO_PV1, + PINGRP_SDMMC1_CLK, + PINGRP_SDMMC1_CMD, + PINGRP_SDMMC1_DAT3, + PINGRP_SDMMC1_DAT2, + PINGRP_SDMMC1_DAT1, + PINGRP_SDMMC1_DAT0, + PINGRP_GPIO_PV2, + PINGRP_GPIO_PV3, + PINGRP_CLK2_OUT, + PINGRP_CLK2_REQ, + PINGRP_LCD_PWR1, + PINGRP_LCD_PWR2, + PINGRP_LCD_SDIN, + PINGRP_LCD_SDOUT, + PINGRP_LCD_WR_N, + PINGRP_LCD_CS0_N, + PINGRP_LCD_DC0, + PINGRP_LCD_SCK, + PINGRP_LCD_PWR0, + PINGRP_LCD_PCLK, + PINGRP_LCD_DE, + PINGRP_LCD_HSYNC, + PINGRP_LCD_VSYNC, + PINGRP_LCD_D0, + PINGRP_LCD_D1, + PINGRP_LCD_D2, + PINGRP_LCD_D3, + PINGRP_LCD_D4, + PINGRP_LCD_D5, + PINGRP_LCD_D6, + PINGRP_LCD_D7, + PINGRP_LCD_D8, + PINGRP_LCD_D9, + PINGRP_LCD_D10, + PINGRP_LCD_D11, + PINGRP_LCD_D12, + PINGRP_LCD_D13, + PINGRP_LCD_D14, + PINGRP_LCD_D15, + PINGRP_LCD_D16, + PINGRP_LCD_D17, + PINGRP_LCD_D18, + PINGRP_LCD_D19, + PINGRP_LCD_D20, + PINGRP_LCD_D21, + PINGRP_LCD_D22, + PINGRP_LCD_D23, + PINGRP_LCD_CS1_N, + PINGRP_LCD_M1, + PINGRP_LCD_DC1, + PINGRP_HDMI_INT, + PINGRP_DDC_SCL, + PINGRP_DDC_SDA, + PINGRP_CRT_HSYNC, + PINGRP_CRT_VSYNC, + PINGRP_VI_D0, + PINGRP_VI_D1, + PINGRP_VI_D2, + PINGRP_VI_D3, + PINGRP_VI_D4, + PINGRP_VI_D5, + PINGRP_VI_D6, + PINGRP_VI_D7, + PINGRP_VI_D8, + PINGRP_VI_D9, + PINGRP_VI_D10, + PINGRP_VI_D11, + PINGRP_VI_PCLK, + PINGRP_VI_MCLK, + PINGRP_VI_VSYNC, + PINGRP_VI_HSYNC, + PINGRP_UART2_RXD, + PINGRP_UART2_TXD, + PINGRP_UART2_RTS_N, + PINGRP_UART2_CTS_N, + PINGRP_UART3_TXD, + PINGRP_UART3_RXD, + PINGRP_UART3_CTS_N, + PINGRP_UART3_RTS_N, + PINGRP_GPIO_PU0, + PINGRP_GPIO_PU1, + PINGRP_GPIO_PU2, + PINGRP_GPIO_PU3, + PINGRP_GPIO_PU4, + PINGRP_GPIO_PU5, + PINGRP_GPIO_PU6, + PINGRP_GEN1_I2C_SDA, + PINGRP_GEN1_I2C_SCL, + PINGRP_DAP4_FS, + PINGRP_DAP4_DIN, + PINGRP_DAP4_DOUT, + PINGRP_DAP4_SCLK, + PINGRP_CLK3_OUT, + PINGRP_CLK3_REQ, + PINGRP_GMI_WP_N, + PINGRP_GMI_IORDY, + PINGRP_GMI_WAIT, + PINGRP_GMI_ADV_N, + PINGRP_GMI_CLK, + PINGRP_GMI_CS0_N, + PINGRP_GMI_CS1_N, + PINGRP_GMI_CS2_N, + PINGRP_GMI_CS3_N, + PINGRP_GMI_CS4_N, + PINGRP_GMI_CS6_N, + PINGRP_GMI_CS7_N, + PINGRP_GMI_AD0, + PINGRP_GMI_AD1, + PINGRP_GMI_AD2, + PINGRP_GMI_AD3, + PINGRP_GMI_AD4, + PINGRP_GMI_AD5, + PINGRP_GMI_AD6, + PINGRP_GMI_AD7, + PINGRP_GMI_AD8, + PINGRP_GMI_AD9, + PINGRP_GMI_AD10, + PINGRP_GMI_AD11, + PINGRP_GMI_AD12, + PINGRP_GMI_AD13, + PINGRP_GMI_AD14, + PINGRP_GMI_AD15, + PINGRP_GMI_A16, + PINGRP_GMI_A17, + PINGRP_GMI_A18, + PINGRP_GMI_A19, + PINGRP_GMI_WR_N, + PINGRP_GMI_OE_N, + PINGRP_GMI_DQS, + PINGRP_GMI_RST_N, + PINGRP_GEN2_I2C_SCL, + PINGRP_GEN2_I2C_SDA, + PINGRP_SDMMC4_CLK, + PINGRP_SDMMC4_CMD, + PINGRP_SDMMC4_DAT0, + PINGRP_SDMMC4_DAT1, + PINGRP_SDMMC4_DAT2, + PINGRP_SDMMC4_DAT3, + PINGRP_SDMMC4_DAT4, + PINGRP_SDMMC4_DAT5, + PINGRP_SDMMC4_DAT6, + PINGRP_SDMMC4_DAT7, + PINGRP_SDMMC4_RST_N, + PINGRP_CAM_MCLK, + PINGRP_GPIO_PCC1, + PINGRP_GPIO_PBB0, + PINGRP_CAM_I2C_SCL, + PINGRP_CAM_I2C_SDA, + PINGRP_GPIO_PBB3, + PINGRP_GPIO_PBB4, + PINGRP_GPIO_PBB5, + PINGRP_GPIO_PBB6, + PINGRP_GPIO_PBB7, + PINGRP_GPIO_PCC2, + PINGRP_JTAG_RTCK, + PINGRP_PWR_I2C_SCL, + PINGRP_PWR_I2C_SDA, + PINGRP_KB_ROW0, + PINGRP_KB_ROW1, + PINGRP_KB_ROW2, + PINGRP_KB_ROW3, + PINGRP_KB_ROW4, + PINGRP_KB_ROW5, + PINGRP_KB_ROW6, + PINGRP_KB_ROW7, + PINGRP_KB_ROW8, + PINGRP_KB_ROW9, + PINGRP_KB_ROW10, + PINGRP_KB_ROW11, + PINGRP_KB_ROW12, + PINGRP_KB_ROW13, + PINGRP_KB_ROW14, + PINGRP_KB_ROW15, + PINGRP_KB_COL0, + PINGRP_KB_COL1, + PINGRP_KB_COL2, + PINGRP_KB_COL3, + PINGRP_KB_COL4, + PINGRP_KB_COL5, + PINGRP_KB_COL6, + PINGRP_KB_COL7, + PINGRP_CLK_32K_OUT, + PINGRP_SYS_CLK_REQ, + PINGRP_CORE_PWR_REQ, + PINGRP_CPU_PWR_REQ, + PINGRP_PWR_INT_N, + PINGRP_CLK_32K_IN, + PINGRP_OWR, + PINGRP_DAP1_FS, + PINGRP_DAP1_DIN, + PINGRP_DAP1_DOUT, + PINGRP_DAP1_SCLK, + PINGRP_CLK1_REQ, + PINGRP_CLK1_OUT, + PINGRP_SPDIF_IN, + PINGRP_SPDIF_OUT, + PINGRP_DAP2_FS, + PINGRP_DAP2_DIN, + PINGRP_DAP2_DOUT, + PINGRP_DAP2_SCLK, + PINGRP_SPI2_MOSI, + PINGRP_SPI2_MISO, + PINGRP_SPI2_CS0_N, + PINGRP_SPI2_SCK, + PINGRP_SPI1_MOSI, + PINGRP_SPI1_SCK, + PINGRP_SPI1_CS0_N, + PINGRP_SPI1_MISO, + PINGRP_SPI2_CS1_N, + PINGRP_SPI2_CS2_N, + PINGRP_SDMMC3_CLK, + PINGRP_SDMMC3_CMD, + PINGRP_SDMMC3_DAT0, + PINGRP_SDMMC3_DAT1, + PINGRP_SDMMC3_DAT2, + PINGRP_SDMMC3_DAT3, + PINGRP_SDMMC3_DAT4, + PINGRP_SDMMC3_DAT5, + PINGRP_SDMMC3_DAT6, + PINGRP_SDMMC3_DAT7, + PINGRP_PEX_L0_PRSNT_N, + PINGRP_PEX_L0_RST_N, + PINGRP_PEX_L0_CLKREQ_N, + PINGRP_PEX_WAKE_N, + PINGRP_PEX_L1_PRSNT_N, + PINGRP_PEX_L1_RST_N, + PINGRP_PEX_L1_CLKREQ_N, + PINGRP_PEX_L2_PRSNT_N, + PINGRP_PEX_L2_RST_N, + PINGRP_PEX_L2_CLKREQ_N, + PINGRP_HDMI_CEC, /* offset 0x33e0 */ + PINGRP_SDMMC1_WP_N, + PINGRP_SDMMC3_CD_N, + PINGRP_SPI1_CS1_N, + PINGRP_SPI1_CS2_N, + PINGRP_USB_VBUS_EN0, /* offset 0x33f4 */ + PINGRP_USB_VBUS_EN1, + PINGRP_SDMMC3_CLK_LB_IN, + PINGRP_SDMMC3_CLK_LB_OUT, + PINGRP_NAND_GMI_CLK_LB, + PINGRP_RESET_OUT_N, + PINGRP_COUNT, +}; + +enum pdrive_pingrp { + PDRIVE_PINGROUP_AO1 = 0, /* offset 0x868 */ + PDRIVE_PINGROUP_AO2, + PDRIVE_PINGROUP_AT1, + PDRIVE_PINGROUP_AT2, + PDRIVE_PINGROUP_AT3, + PDRIVE_PINGROUP_AT4, + PDRIVE_PINGROUP_AT5, + PDRIVE_PINGROUP_CDEV1, + PDRIVE_PINGROUP_CDEV2, + PDRIVE_PINGROUP_CSUS, + PDRIVE_PINGROUP_DAP1, + PDRIVE_PINGROUP_DAP2, + PDRIVE_PINGROUP_DAP3, + PDRIVE_PINGROUP_DAP4, + PDRIVE_PINGROUP_DBG, + PDRIVE_PINGROUP_LCD1, + PDRIVE_PINGROUP_LCD2, + PDRIVE_PINGROUP_SDIO2, + PDRIVE_PINGROUP_SDIO3, + PDRIVE_PINGROUP_SPI, + PDRIVE_PINGROUP_UAA, + PDRIVE_PINGROUP_UAB, + PDRIVE_PINGROUP_UART2, + PDRIVE_PINGROUP_UART3, + PDRIVE_PINGROUP_VI1 = 24, /* offset 0x8c8 */ + PDRIVE_PINGROUP_SDIO1 = 33, /* offset 0x8ec */ + PDRIVE_PINGROUP_CRT = 36, /* offset 0x8f8 */ + PDRIVE_PINGROUP_DDC, + PDRIVE_PINGROUP_GMA, + PDRIVE_PINGROUP_GMB, + PDRIVE_PINGROUP_GMC, + PDRIVE_PINGROUP_GMD, + PDRIVE_PINGROUP_GME, + PDRIVE_PINGROUP_GMF, + PDRIVE_PINGROUP_GMG, + PDRIVE_PINGROUP_GMH, + PDRIVE_PINGROUP_OWR, + PDRIVE_PINGROUP_UAD, + PDRIVE_PINGROUP_GPV, + PDRIVE_PINGROUP_DEV3 = 49, /* offset 0x92c */ + PDRIVE_PINGROUP_CEC = 52, /* offset 0x938 */ + PDRIVE_PINGROUP_AT6, + PDRIVE_PINGROUP_DAP5, + PDRIVE_PINGROUP_VBUS, + PDRIVE_PINGROUP_COUNT, +}; + +/* + * Functions which can be assigned to each of the pin groups. The values here + * bear no relation to the values programmed into pinmux registers and are + * purely a convenience. The translation is done through a table search. + */ +enum pmux_func { + PMUX_FUNC_AHB_CLK, + PMUX_FUNC_APB_CLK, + PMUX_FUNC_AUDIO_SYNC, + PMUX_FUNC_CRT, + PMUX_FUNC_DAP1, + PMUX_FUNC_DAP2, + PMUX_FUNC_DAP3, + PMUX_FUNC_DAP4, + PMUX_FUNC_DAP5, + PMUX_FUNC_DISPA, + PMUX_FUNC_DISPB, + PMUX_FUNC_EMC_TEST0_DLL, + PMUX_FUNC_EMC_TEST1_DLL, + PMUX_FUNC_GMI, + PMUX_FUNC_GMI_INT, + PMUX_FUNC_HDMI, + PMUX_FUNC_I2C1, + PMUX_FUNC_I2C2, + PMUX_FUNC_I2C3, + PMUX_FUNC_IDE, + PMUX_FUNC_KBC, + PMUX_FUNC_MIO, + PMUX_FUNC_MIPI_HS, + PMUX_FUNC_NAND, + PMUX_FUNC_OSC, + PMUX_FUNC_OWR, + PMUX_FUNC_PCIE, + PMUX_FUNC_PLLA_OUT, + PMUX_FUNC_PLLC_OUT1, + PMUX_FUNC_PLLM_OUT1, + PMUX_FUNC_PLLP_OUT2, + PMUX_FUNC_PLLP_OUT3, + PMUX_FUNC_PLLP_OUT4, + PMUX_FUNC_PWM, + PMUX_FUNC_PWR_INTR, + PMUX_FUNC_PWR_ON, + PMUX_FUNC_RTCK, + PMUX_FUNC_SDMMC1, + PMUX_FUNC_SDMMC2, + PMUX_FUNC_SDMMC3, + PMUX_FUNC_SDMMC4, + PMUX_FUNC_SFLASH, + PMUX_FUNC_SPDIF, + PMUX_FUNC_SPI1, + PMUX_FUNC_SPI2, + PMUX_FUNC_SPI2_ALT, + PMUX_FUNC_SPI3, + PMUX_FUNC_SPI4, + PMUX_FUNC_TRACE, + PMUX_FUNC_TWC, + PMUX_FUNC_UARTA, + PMUX_FUNC_UARTB, + PMUX_FUNC_UARTC, + PMUX_FUNC_UARTD, + PMUX_FUNC_UARTE, + PMUX_FUNC_ULPI, + PMUX_FUNC_VI, + PMUX_FUNC_VI_SENSOR_CLK, + PMUX_FUNC_XIO, + PMUX_FUNC_BLINK, + PMUX_FUNC_CEC, + PMUX_FUNC_CLK12, + PMUX_FUNC_DAP, + PMUX_FUNC_DAPSDMMC2, + PMUX_FUNC_DDR, + PMUX_FUNC_DEV3, + PMUX_FUNC_DTV, + PMUX_FUNC_VI_ALT1, + PMUX_FUNC_VI_ALT2, + PMUX_FUNC_VI_ALT3, + PMUX_FUNC_EMC_DLL, + PMUX_FUNC_EXTPERIPH1, + PMUX_FUNC_EXTPERIPH2, + PMUX_FUNC_EXTPERIPH3, + PMUX_FUNC_GMI_ALT, + PMUX_FUNC_HDA, + PMUX_FUNC_HSI, + PMUX_FUNC_I2C4, + PMUX_FUNC_I2C5, + PMUX_FUNC_I2CPWR, + PMUX_FUNC_I2S0, + PMUX_FUNC_I2S1, + PMUX_FUNC_I2S2, + PMUX_FUNC_I2S3, + PMUX_FUNC_I2S4, + PMUX_FUNC_NAND_ALT, + PMUX_FUNC_POPSDIO4, + PMUX_FUNC_POPSDMMC4, + PMUX_FUNC_PWM0, + PMUX_FUNC_PWM1, + PMUX_FUNC_PWM2, + PMUX_FUNC_PWM3, + PMUX_FUNC_SATA, + PMUX_FUNC_SPI5, + PMUX_FUNC_SPI6, + PMUX_FUNC_SYSCLK, + PMUX_FUNC_VGP1, + PMUX_FUNC_VGP2, + PMUX_FUNC_VGP3, + PMUX_FUNC_VGP4, + PMUX_FUNC_VGP5, + PMUX_FUNC_VGP6, + + PMUX_FUNC_USB, + PMUX_FUNC_SOC, + PMUX_FUNC_CPU, + PMUX_FUNC_CLK, + PMUX_FUNC_PWRON, + PMUX_FUNC_PMI, + PMUX_FUNC_CLDVFS, + PMUX_FUNC_RESET_OUT_N, + + PMUX_FUNC_SAFE, + PMUX_FUNC_MAX, + + PMUX_FUNC_RSVD1 = 0x8000, + PMUX_FUNC_RSVD2 = 0x8001, + PMUX_FUNC_RSVD3 = 0x8002, + PMUX_FUNC_RSVD4 = 0x8003, +}; + +/* return 1 if a pmux_func is in range */ +#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \ + || (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4))) + +/* return 1 if a pingrp is in range */ +#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT)) + +/* The pullup/pulldown state of a pin group */ +enum pmux_pull { + PMUX_PULL_NORMAL = 0, + PMUX_PULL_DOWN, + PMUX_PULL_UP, +}; +/* return 1 if a pin_pupd_is in range */ +#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \ + ((pupd) <= PMUX_PULL_UP)) + +/* Defines whether a pin group is tristated or in normal operation */ +enum pmux_tristate { + PMUX_TRI_NORMAL = 0, + PMUX_TRI_TRISTATE = 1, +}; +/* return 1 if a pin_tristate_is in range */ +#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \ + && ((tristate) <= PMUX_TRI_TRISTATE)) + +enum pmux_pin_io { + PMUX_PIN_OUTPUT = 0, + PMUX_PIN_INPUT = 1, +}; +/* return 1 if a pin_io_is in range */ +#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \ + ((io) <= PMUX_PIN_INPUT)) + +enum pmux_pin_lock { + PMUX_PIN_LOCK_DEFAULT = 0, + PMUX_PIN_LOCK_DISABLE, + PMUX_PIN_LOCK_ENABLE, +}; +/* return 1 if a pin_lock is in range */ +#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \ + ((lock) <= PMUX_PIN_LOCK_ENABLE)) + +enum pmux_pin_od { + PMUX_PIN_OD_DEFAULT = 0, + PMUX_PIN_OD_DISABLE, + PMUX_PIN_OD_ENABLE, +}; +/* return 1 if a pin_od is in range */ +#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \ + ((od) <= PMUX_PIN_OD_ENABLE)) + +enum pmux_pin_ioreset { + PMUX_PIN_IO_RESET_DEFAULT = 0, + PMUX_PIN_IO_RESET_DISABLE, + PMUX_PIN_IO_RESET_ENABLE, +}; +/* return 1 if a pin_ioreset_is in range */ +#define pmux_pin_ioreset_isvalid(ioreset) \ + (((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \ + ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) + +/* Available power domains used by pin groups */ +enum pmux_vddio { + PMUX_VDDIO_BB = 0, + PMUX_VDDIO_LCD, + PMUX_VDDIO_VI, + PMUX_VDDIO_UART, + PMUX_VDDIO_DDR, + PMUX_VDDIO_NAND, + PMUX_VDDIO_SYS, + PMUX_VDDIO_AUDIO, + PMUX_VDDIO_SD, + PMUX_VDDIO_CAM, + PMUX_VDDIO_GMI, + PMUX_VDDIO_PEXCTL, + PMUX_VDDIO_SDMMC1, + PMUX_VDDIO_SDMMC3, + PMUX_VDDIO_SDMMC4, + + PMUX_VDDIO_NONE +}; + +/* T114 pin drive group and pin mux registers */ +#define PDRIVE_PINGROUP_OFFSET (0x868 >> 2) +#define PMUX_OFFSET ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \ + PDRIVE_PINGROUP_COUNT) +struct pmux_tri_ctlr { + uint pmt_reserved0; /* ABP_MISC_PP_ reserved offset 00 */ + uint pmt_reserved1; /* ABP_MISC_PP_ reserved offset 04 */ + uint pmt_strap_opt_a; /* _STRAPPING_OPT_A_0, offset 08 */ + uint pmt_reserved2; /* ABP_MISC_PP_ reserved offset 0C */ + uint pmt_reserved3; /* ABP_MISC_PP_ reserved offset 10 */ + uint pmt_reserved4[4]; /* _TRI_STATE_REG_A/B/C/D in t20 */ + uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */ + + uint pmt_reserved[528]; /* ABP_MISC_PP_ reserved offs 28-864 */ + + uint pmt_drive[PDRIVE_PINGROUP_COUNT]; /* pin drive grps offs 868 */ + uint pmt_reserved5[PMUX_OFFSET]; + uint pmt_ctl[PINGRP_COUNT]; /* mux/pupd/tri regs, offset 0x3000 */ +}; + +/* + * This defines the configuration for a pin, including the function assigned, + * pull up/down settings and tristate settings. Having set up one of these + * you can call pinmux_config_pingroup() to configure a pin in one step. Also + * available is pinmux_config_table() to configure a list of pins. + */ +struct pingroup_config { + enum pmux_pingrp pingroup; /* pin group PINGRP_... */ + enum pmux_func func; /* function to assign FUNC_... */ + enum pmux_pull pull; /* pull up/down/normal PMUX_PULL_...*/ + enum pmux_tristate tristate; /* tristate or normal PMUX_TRI_... */ + enum pmux_pin_io io; /* input or output PMUX_PIN_... */ + enum pmux_pin_lock lock; /* lock enable/disable PMUX_PIN... */ + enum pmux_pin_od od; /* open-drain or push-pull driver */ + enum pmux_pin_ioreset ioreset; /* input/output reset PMUX_PIN... */ +}; + +/* Set a pin group to tristate */ +void pinmux_tristate_enable(enum pmux_pingrp pin); + +/* Set a pin group to normal (non tristate) */ +void pinmux_tristate_disable(enum pmux_pingrp pin); + +/* Set the pull up/down feature for a pin group */ +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd); + +/* Set the mux function for a pin group */ +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func); + +/* Set the complete configuration for a pin group */ +void pinmux_config_pingroup(struct pingroup_config *config); + +/* Set a pin group to tristate or normal */ +void pinmux_set_tristate(enum pmux_pingrp pin, int enable); + +/* Set a pin group as input or output */ +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io); + +/** + * Configure a list of pin groups + * + * @param config List of config items + * @param len Number of config items in list + */ +void pinmux_config_table(struct pingroup_config *config, int len); + +/* Set a group of pins from a table */ +void pinmux_init(void); + +#endif /* _TEGRA114_PINMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/pmu.h b/arch/arm/include/asm/arch-tegra114/pmu.h new file mode 100644 index 0000000000..c6e2381011 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/pmu.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_PMU_H_ +#define _TEGRA114_PMU_H_ + +/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void); + +#endif /* _TEGRA114_PMU_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/spl.h b/arch/arm/include/asm/arch-tegra114/spl.h new file mode 100644 index 0000000000..ebb16fe1dd --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/spl.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_ARCH_SPL_H_ + +#define BOOT_DEVICE_RAM 1 + +#endif diff --git a/arch/arm/include/asm/arch-tegra114/tegra.h b/arch/arm/include/asm/arch-tegra114/tegra.h new file mode 100644 index 0000000000..a3d12d6cd0 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/tegra.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA114_H_ +#define _TEGRA114_H_ + +#define NV_PA_SDRAM_BASE 0x80000000 /* 0x80000000 for real T114 */ + +#include <asm/arch-tegra/tegra.h> + +#define BCT_ODMDATA_OFFSET 1752 /* offset to ODMDATA word */ + +#undef NVBOOTINFOTABLE_BCTSIZE +#undef NVBOOTINFOTABLE_BCTPTR +#define NVBOOTINFOTABLE_BCTSIZE 0x48 /* BCT size in BIT in IRAM */ +#define NVBOOTINFOTABLE_BCTPTR 0x4C /* BCT pointer in BIT in IRAM */ + +#define MAX_NUM_CPU 4 + +#endif /* TEGRA114_H */ diff --git a/arch/arm/include/asm/arch-tegra20/clock-tables.h b/arch/arm/include/asm/arch-tegra20/clock-tables.h index 53708e0477..6ec5ccb936 100644 --- a/arch/arm/include/asm/arch-tegra20/clock-tables.h +++ b/arch/arm/include/asm/arch-tegra20/clock-tables.h @@ -193,4 +193,8 @@ enum pll_out_id { #define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && \ (id) < CLOCK_ID_FIRST_SIMPLE) +/* return 1 if a peripheral ID is in range */ +#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \ + (id) < PERIPH_ID_COUNT) + #endif /* _CLOCK_TABLES_H_ */ diff --git a/arch/arm/include/asm/arch-tegra20/clock.h b/arch/arm/include/asm/arch-tegra20/clock.h index f592b9550e..491c02c026 100644 --- a/arch/arm/include/asm/arch-tegra20/clock.h +++ b/arch/arm/include/asm/arch-tegra20/clock.h @@ -26,4 +26,8 @@ #include <asm/arch-tegra/clock.h> +/* CLK_RST_CONTROLLER_OSC_CTRL_0 */ +#define OSC_FREQ_SHIFT 30 +#define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT) + #endif /* _TEGRA20_CLOCK_H */ diff --git a/arch/arm/include/asm/arch-tegra20/funcmux.h b/arch/arm/include/asm/arch-tegra20/funcmux.h index c986b93b40..7f15bceafa 100644 --- a/arch/arm/include/asm/arch-tegra20/funcmux.h +++ b/arch/arm/include/asm/arch-tegra20/funcmux.h @@ -21,8 +21,10 @@ /* Tegra20 high-level function multiplexing */ -#ifndef __FUNCMUX_H -#define __FUNCMUX_H +#ifndef _TEGRA20_FUNCMUX_H_ +#define _TEGRA20_FUNCMUX_H_ + +#include <asm/arch-tegra/funcmux.h> /* Configs supported by the func mux */ enum { @@ -33,7 +35,7 @@ enum { FUNCMUX_UART1_UAA_UAB, FUNCMUX_UART1_GPU, FUNCMUX_UART1_SDIO1, - FUNCMUX_UART2_IRDA = 0, + FUNCMUX_UART2_UAD = 0, FUNCMUX_UART4_GMC = 0, /* I2C configs */ @@ -62,22 +64,4 @@ enum { FUNCMUX_NDFLASH_ATC = 0, FUNCMUX_NDFLASH_KBC_8_BIT, }; - -/** - * Select a config for a particular peripheral. - * - * Each peripheral can operate through a number of configurations, - * which are sets of pins that it uses to bring out its signals. - * The basic config is 0, and higher numbers indicate different - * pinmux settings to bring the peripheral out on other pins, - * - * This function also disables tristate for the function's pins, - * so that they operate in normal mode. - * - * @param id Peripheral id - * @param config Configuration to use (FUNCMUX_...), 0 for default - * @return 0 if ok, -1 on error (e.g. incorrect id or config) - */ -int funcmux_select(enum periph_id id, int config); - -#endif +#endif /* _TEGRA20_FUNCMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra20/gp_padctrl.h b/arch/arm/include/asm/arch-tegra20/gp_padctrl.h index 865af5bc79..eaaf903bf9 100644 --- a/arch/arm/include/asm/arch-tegra20/gp_padctrl.h +++ b/arch/arm/include/asm/arch-tegra20/gp_padctrl.h @@ -21,8 +21,10 @@ * MA 02111-1307 USA */ -#ifndef _GP_PADCTRL_H_ -#define _GP_PADCTRL_H_ +#ifndef _TEGRA20_GP_PADCTRL_H_ +#define _TEGRA20_GP_PADCTRL_H_ + +#include <asm/arch-tegra/gp_padctrl.h> /* APB_MISC_GP and padctrl registers */ struct apb_misc_gp_ctlr { @@ -61,13 +63,4 @@ struct apb_misc_gp_ctlr { u32 memcomp; /* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */ }; -/* bit fields definitions for APB_MISC_GP_HIDREV register */ -#define HIDREV_CHIPID_SHIFT 8 -#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT) -#define HIDREV_MAJORPREV_SHIFT 4 -#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT) - -/* CHIPID field returned from APB_MISC_GP_HIDREV register */ -#define CHIPID_TEGRA20 0x20 - -#endif +#endif /* _TEGRA20_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra20/pinmux.h b/arch/arm/include/asm/arch-tegra20/pinmux.h index 797e158e68..a9b4edaf26 100644 --- a/arch/arm/include/asm/arch-tegra20/pinmux.h +++ b/arch/arm/include/asm/arch-tegra20/pinmux.h @@ -204,7 +204,6 @@ enum pmux_func { PMUX_FUNC_I2C2, PMUX_FUNC_I2C3, PMUX_FUNC_IDE, - PMUX_FUNC_IRDA, PMUX_FUNC_KBC, PMUX_FUNC_MIO, PMUX_FUNC_MIPI_HS, diff --git a/arch/arm/include/asm/arch-tegra20/tegra.h b/arch/arm/include/asm/arch-tegra20/tegra.h index ca98733262..e1de0447ff 100644 --- a/arch/arm/include/asm/arch-tegra20/tegra.h +++ b/arch/arm/include/asm/arch-tegra20/tegra.h @@ -33,4 +33,6 @@ #define BCT_ODMDATA_OFFSET 4068 /* 12 bytes from end of BCT */ +#define MAX_NUM_CPU 2 + #endif /* TEGRA20_H */ diff --git a/arch/arm/include/asm/arch-tegra30/clock-tables.h b/arch/arm/include/asm/arch-tegra30/clock-tables.h new file mode 100644 index 0000000000..cb619f1f2d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clock-tables.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 clock PLL tables */ + +#ifndef _TEGRA30_CLOCK_TABLES_H_ +#define _TEGRA30_CLOCK_TABLES_H_ + +/* The PLLs supported by the hardware */ +enum clock_id { + CLOCK_ID_FIRST, + CLOCK_ID_CGENERAL = CLOCK_ID_FIRST, + CLOCK_ID_MEMORY, + CLOCK_ID_PERIPH, + CLOCK_ID_AUDIO, + CLOCK_ID_USB, + CLOCK_ID_DISPLAY, + + /* now the simple ones */ + CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_EPCI, + CLOCK_ID_SFROM32KHZ, + + /* These are the base clocks (inputs to the Tegra SOC) */ + CLOCK_ID_32KHZ, + CLOCK_ID_OSC, + + CLOCK_ID_COUNT, /* number of PLLs */ + CLOCK_ID_DISPLAY2, /* Tegra3, placeholder */ + CLOCK_ID_NONE = -1, +}; + +/* The clocks supported by the hardware */ +enum periph_id { + PERIPH_ID_FIRST, + + /* Low word: 31:0 */ + PERIPH_ID_CPU = PERIPH_ID_FIRST, + PERIPH_ID_COP, + PERIPH_ID_TRIGSYS, + PERIPH_ID_RESERVED3, + PERIPH_ID_RESERVED4, + PERIPH_ID_TMR, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + + /* 8 */ + PERIPH_ID_GPIO, + PERIPH_ID_SDMMC2, + PERIPH_ID_SPDIF, + PERIPH_ID_I2S1, + PERIPH_ID_I2C1, + PERIPH_ID_NDFLASH, + PERIPH_ID_SDMMC1, + PERIPH_ID_SDMMC4, + + /* 16 */ + PERIPH_ID_RESERVED16, + PERIPH_ID_PWM, + PERIPH_ID_I2S2, + PERIPH_ID_EPP, + PERIPH_ID_VI, + PERIPH_ID_2D, + PERIPH_ID_USBD, + PERIPH_ID_ISP, + + /* 24 */ + PERIPH_ID_3D, + PERIPH_ID_RESERVED24, + PERIPH_ID_DISP2, + PERIPH_ID_DISP1, + PERIPH_ID_HOST1X, + PERIPH_ID_VCP, + PERIPH_ID_I2S0, + PERIPH_ID_CACHE2, + + /* Middle word: 63:32 */ + PERIPH_ID_MEM, + PERIPH_ID_AHBDMA, + PERIPH_ID_APBDMA, + PERIPH_ID_RESERVED35, + PERIPH_ID_KBC, + PERIPH_ID_STAT_MON, + PERIPH_ID_PMC, + PERIPH_ID_FUSE, + + /* 40 */ + PERIPH_ID_KFUSE, + PERIPH_ID_SBC1, + PERIPH_ID_SNOR, + PERIPH_ID_RESERVED43, + PERIPH_ID_SBC2, + PERIPH_ID_RESERVED45, + PERIPH_ID_SBC3, + PERIPH_ID_DVC_I2C, + + /* 48 */ + PERIPH_ID_DSI, + PERIPH_ID_TVO, + PERIPH_ID_MIPI, + PERIPH_ID_HDMI, + PERIPH_ID_CSI, + PERIPH_ID_TVDAC, + PERIPH_ID_I2C2, + PERIPH_ID_UART3, + + /* 56 */ + PERIPH_ID_RESERVED56, + PERIPH_ID_EMC, + PERIPH_ID_USB2, + PERIPH_ID_USB3, + PERIPH_ID_MPE, + PERIPH_ID_VDE, + PERIPH_ID_BSEA, + PERIPH_ID_BSEV, + + /* Upper word 95:64 */ + PERIPH_ID_SPEEDO, + PERIPH_ID_UART4, + PERIPH_ID_UART5, + PERIPH_ID_I2C3, + PERIPH_ID_SBC4, + PERIPH_ID_SDMMC3, + PERIPH_ID_PCIE, + PERIPH_ID_OWR, + + /* 72 */ + PERIPH_ID_AFI, + PERIPH_ID_CORESIGHT, + PERIPH_ID_PCIEXCLK, + PERIPH_ID_AVPUCQ, + PERIPH_ID_RESERVED76, + PERIPH_ID_RESERVED77, + PERIPH_ID_RESERVED78, + PERIPH_ID_DTV, + + /* 80 */ + PERIPH_ID_NANDSPEED, + PERIPH_ID_I2CSLOW, + PERIPH_ID_DSIB, + PERIPH_ID_RESERVED83, + PERIPH_ID_IRAMA, + PERIPH_ID_IRAMB, + PERIPH_ID_IRAMC, + PERIPH_ID_IRAMD, + + /* 88 */ + PERIPH_ID_CRAM2, + PERIPH_ID_RESERVED89, + PERIPH_ID_MDOUBLER, + PERIPH_ID_RESERVED91, + PERIPH_ID_SUSOUT, + PERIPH_ID_RESERVED93, + PERIPH_ID_RESERVED94, + PERIPH_ID_RESERVED95, + + PERIPH_ID_VW_FIRST, + /* V word: 31:0 */ + PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST, + PERIPH_ID_CPULP, + PERIPH_ID_3D2, + PERIPH_ID_MSELECT, + PERIPH_ID_TSENSOR, + PERIPH_ID_I2S3, + PERIPH_ID_I2S4, + PERIPH_ID_I2C4, + + /* 08 */ + PERIPH_ID_SBC5, + PERIPH_ID_SBC6, + PERIPH_ID_AUDIO, + PERIPH_ID_APBIF, + PERIPH_ID_DAM0, + PERIPH_ID_DAM1, + PERIPH_ID_DAM2, + PERIPH_ID_HDA2CODEC2X, + + /* 16 */ + PERIPH_ID_ATOMICS, + PERIPH_ID_EX_RESERVED17, + PERIPH_ID_EX_RESERVED18, + PERIPH_ID_EX_RESERVED19, + PERIPH_ID_EX_RESERVED20, + PERIPH_ID_EX_RESERVED21, + PERIPH_ID_EX_RESERVED22, + PERIPH_ID_ACTMON, + + /* 24 */ + PERIPH_ID_EX_RESERVED24, + PERIPH_ID_EX_RESERVED25, + PERIPH_ID_EX_RESERVED26, + PERIPH_ID_EX_RESERVED27, + PERIPH_ID_SATA, + PERIPH_ID_HDA, + PERIPH_ID_EX_RESERVED30, + PERIPH_ID_EX_RESERVED31, + + /* W word: 31:0 */ + PERIPH_ID_HDA2HDMICODEC, + PERIPH_ID_SATACOLD, + PERIPH_ID_RESERVED0_PCIERX0, + PERIPH_ID_RESERVED1_PCIERX1, + PERIPH_ID_RESERVED2_PCIERX2, + PERIPH_ID_RESERVED3_PCIERX3, + PERIPH_ID_RESERVED4_PCIERX4, + PERIPH_ID_RESERVED5_PCIERX5, + + /* 40 */ + PERIPH_ID_CEC, + PERIPH_ID_RESERVED6_PCIE2, + PERIPH_ID_RESERVED7_EMC, + PERIPH_ID_RESERVED8_HDMI, + PERIPH_ID_RESERVED9_SATA, + PERIPH_ID_RESERVED10_MIPI, + PERIPH_ID_EX_RESERVED46, + PERIPH_ID_EX_RESERVED47, + + PERIPH_ID_COUNT, + PERIPH_ID_NONE = -1, +}; + +enum pll_out_id { + PLL_OUT1, + PLL_OUT2, + PLL_OUT3, + PLL_OUT4 +}; + +/* + * Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want + * callers to use the PERIPH_ID for all access to peripheral clocks to avoid + * confusion bewteen PERIPH_ID_... and PERIPHC_... + * + * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be + * confusing. + */ +enum periphc_internal_id { + /* 0x00 */ + PERIPHC_I2S1, + PERIPHC_I2S2, + PERIPHC_SPDIF_OUT, + PERIPHC_SPDIF_IN, + PERIPHC_PWM, + PERIPHC_05h, + PERIPHC_SBC2, + PERIPHC_SBC3, + + /* 0x08 */ + PERIPHC_08h, + PERIPHC_I2C1, + PERIPHC_DVC_I2C, + PERIPHC_0bh, + PERIPHC_0ch, + PERIPHC_SBC1, + PERIPHC_DISP1, + PERIPHC_DISP2, + + /* 0x10 */ + PERIPHC_CVE, + PERIPHC_11h, + PERIPHC_VI, + PERIPHC_13h, + PERIPHC_SDMMC1, + PERIPHC_SDMMC2, + PERIPHC_G3D, + PERIPHC_G2D, + + /* 0x18 */ + PERIPHC_NDFLASH, + PERIPHC_SDMMC4, + PERIPHC_VFIR, + PERIPHC_EPP, + PERIPHC_MPE, + PERIPHC_MIPI, + PERIPHC_UART1, + PERIPHC_UART2, + + /* 0x20 */ + PERIPHC_HOST1X, + PERIPHC_21h, + PERIPHC_TVO, + PERIPHC_HDMI, + PERIPHC_24h, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_EMC, + + /* 0x28 */ + PERIPHC_UART3, + PERIPHC_29h, + PERIPHC_VI_SENSOR, + PERIPHC_2bh, + PERIPHC_2ch, + PERIPHC_SBC4, + PERIPHC_I2C3, + PERIPHC_SDMMC3, + + /* 0x30 */ + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_VDE, + PERIPHC_OWR, + PERIPHC_NOR, + PERIPHC_CSITE, + PERIPHC_I2S0, + PERIPHC_37h, + + PERIPHC_VW_FIRST, + /* 0x38 */ + PERIPHC_G3D2 = PERIPHC_VW_FIRST, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + PERIPHC_SBC5, + PERIPHC_SBC6, + + /* 0x40 */ + PERIPHC_AUDIO, + PERIPHC_41h, + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + PERIPHC_ACTMON, + PERIPHC_EXTPERIPH1, + + /* 0x48 */ + PERIPHC_EXTPERIPH2, + PERIPHC_EXTPERIPH3, + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + PERIPHC_SYS, + PERIPHC_SPEEDO, + PERIPHC_4eh, + PERIPHC_4fh, + + /* 0x50 */ + PERIPHC_50h, + PERIPHC_51h, + PERIPHC_52h, + PERIPHC_53h, + PERIPHC_SATAOOB, + PERIPHC_SATA, + PERIPHC_HDA, + + PERIPHC_COUNT, + + PERIPHC_NONE = -1, +}; + +/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */ +#define PERIPH_REG(id) \ + (id < PERIPH_ID_VW_FIRST) ? \ + ((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 5) + +/* Mask value for a clock (within PERIPH_REG(id)) */ +#define PERIPH_MASK(id) (1 << ((id) & 0x1f)) + +/* return 1 if a PLL ID is in range */ +#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT) + +/* return 1 if a peripheral ID is in range */ +#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \ + (id) < PERIPH_ID_COUNT) + +#endif /* _TEGRA30_CLOCK_TABLES_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/clock.h b/arch/arm/include/asm/arch-tegra30/clock.h new file mode 100644 index 0000000000..2f24a75cc4 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/clock.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 clock control functions */ + +#ifndef _TEGRA30_CLOCK_H_ +#define _TEGRA30_CLOCK_H_ + +#include <asm/arch-tegra/clock.h> + +/* CLK_RST_CONTROLLER_OSC_CTRL_0 */ +#define OSC_FREQ_SHIFT 28 +#define OSC_FREQ_MASK (0xF << OSC_FREQ_SHIFT) + +#endif /* _TEGRA30_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/flow.h b/arch/arm/include/asm/arch-tegra30/flow.h new file mode 100644 index 0000000000..f5966a8074 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/flow.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_FLOW_H_ +#define _TEGRA30_FLOW_H_ + +struct flow_ctlr { + u32 halt_cpu_events; + u32 halt_cop_events; + u32 cpu_csr; + u32 cop_csr; + u32 xrq_events; + u32 halt_cpu1_events; + u32 cpu1_csr; + u32 halt_cpu2_events; + u32 cpu2_csr; + u32 halt_cpu3_events; + u32 cpu3_csr; + u32 cluster_control; +}; + +#endif /* _TEGRA30_FLOW_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/funcmux.h b/arch/arm/include/asm/arch-tegra30/funcmux.h new file mode 100644 index 0000000000..24b2bca03a --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/funcmux.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +/* Tegra30 high-level function multiplexing */ + +#ifndef _TEGRA30_FUNCMUX_H_ +#define _TEGRA30_FUNCMUX_H_ + +#include <asm/arch-tegra/funcmux.h> + +/* Configs supported by the func mux */ +enum { + FUNCMUX_DEFAULT = 0, /* default config */ + + /* UART configs */ + FUNCMUX_UART1_ULPI = 0, +}; +#endif /* _TEGRA30_FUNCMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/gp_padctrl.h b/arch/arm/include/asm/arch-tegra30/gp_padctrl.h new file mode 100644 index 0000000000..9b383d0e74 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gp_padctrl.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_GP_PADCTRL_H_ +#define _TEGRA30_GP_PADCTRL_H_ + +#include <asm/arch-tegra/gp_padctrl.h> + +/* APB_MISC_GP and padctrl registers */ +struct apb_misc_gp_ctlr { + u32 modereg; /* 0x00: APB_MISC_GP_MODEREG */ + u32 hidrev; /* 0x04: APB_MISC_GP_HIDREV */ + u32 reserved0[22]; /* 0x08 - 0x5C: */ + u32 emu_revid; /* 0x60: APB_MISC_GP_EMU_REVID */ + u32 xactor_scratch; /* 0x64: APB_MISC_GP_XACTOR_SCRATCH */ + u32 aocfg1; /* 0x68: APB_MISC_GP_AOCFG1PADCTRL */ + u32 aocfg2; /* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */ + u32 atcfg1; /* 0x70: APB_MISC_GP_ATCFG1PADCTRL */ + u32 atcfg2; /* 0x74: APB_MISC_GP_ATCFG2PADCTRL */ + u32 atcfg3; /* 0x78: APB_MISC_GP_ATCFG3PADCTRL */ + u32 atcfg4; /* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */ + u32 atcfg5; /* 0x80: APB_MISC_GP_ATCFG5PADCTRL */ + u32 cdev1cfg; /* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */ + u32 cdev2cfg; /* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */ + u32 csuscfg; /* 0x8C: APB_MISC_GP_CSUSCFGPADCTRL */ + u32 dap1cfg; /* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */ + u32 dap2cfg; /* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */ + u32 dap3cfg; /* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */ + u32 dap4cfg; /* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */ + u32 dbgcfg; /* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */ + u32 lcdcfg1; /* 0xA4: APB_MISC_GP_LCDCFG1PADCTRL */ + u32 lcdcfg2; /* 0xA8: APB_MISC_GP_LCDCFG2PADCTRL */ + u32 sdio2cfg; /* 0xAC: APB_MISC_GP_SDIO2CFGPADCTRL */ + u32 sdio3cfg; /* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */ + u32 spicfg; /* 0xB4: APB_MISC_GP_SPICFGPADCTRL */ + u32 uaacfg; /* 0xB8: APB_MISC_GP_UAACFGPADCTRL */ + u32 uabcfg; /* 0xBC: APB_MISC_GP_UABCFGPADCTRL */ + u32 uart2cfg; /* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */ + u32 uart3cfg; /* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */ + u32 vicfg1; /* 0xC8: APB_MISC_GP_VICFG1PADCTRL */ + u32 vivttgen; /* 0xCC: APB_MISC_GP_VIVTTGENPADCTRL */ + u32 reserved1[7]; /* 0xD0-0xE8: */ + u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */ +}; + +#endif /* _TEGRA30_GP_PADCTRL_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/gpio.h b/arch/arm/include/asm/arch-tegra30/gpio.h new file mode 100644 index 0000000000..f1c89f5a86 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/gpio.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_GPIO_H_ +#define _TEGRA30_GPIO_H_ + +/* + * The Tegra 3x GPIO controller has 246 GPIOS in 8 banks of 4 ports, + * each with 8 GPIOs. + */ +#define TEGRA_GPIO_PORTS 4 /* number of ports per bank */ +#define TEGRA_GPIO_BANKS 8 /* number of banks */ + +#include <asm/arch-tegra/gpio.h> + +/* 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]; + uint gpio_masked_config[TEGRA_GPIO_PORTS]; + uint gpio_masked_dir_out[TEGRA_GPIO_PORTS]; + uint gpio_masked_out[TEGRA_GPIO_PORTS]; + uint gpio_masked_in[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_status[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_enable[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_level[TEGRA_GPIO_PORTS]; + uint gpio_masked_int_clear[TEGRA_GPIO_PORTS]; +}; + +struct gpio_ctlr { + struct gpio_ctlr_bank gpio_bank[TEGRA_GPIO_BANKS]; +}; + +enum gpio_pin { + GPIO_PA0 = 0, /* pin 0 */ + GPIO_PA1, + GPIO_PA2, + GPIO_PA3, + GPIO_PA4, + GPIO_PA5, + GPIO_PA6, + GPIO_PA7, + GPIO_PB0, /* pin 8 */ + GPIO_PB1, + GPIO_PB2, + GPIO_PB3, + GPIO_PB4, + GPIO_PB5, + GPIO_PB6, + GPIO_PB7, + GPIO_PC0, /* pin 16 */ + GPIO_PC1, + GPIO_PC2, + GPIO_PC3, + GPIO_PC4, + GPIO_PC5, + GPIO_PC6, + GPIO_PC7, + GPIO_PD0, /* pin 24 */ + GPIO_PD1, + GPIO_PD2, + GPIO_PD3, + GPIO_PD4, + GPIO_PD5, + GPIO_PD6, + GPIO_PD7, + GPIO_PE0, /* pin 32 */ + GPIO_PE1, + GPIO_PE2, + GPIO_PE3, + GPIO_PE4, + GPIO_PE5, + GPIO_PE6, + GPIO_PE7, + GPIO_PF0, /* pin 40 */ + GPIO_PF1, + GPIO_PF2, + GPIO_PF3, + GPIO_PF4, + GPIO_PF5, + GPIO_PF6, + GPIO_PF7, + GPIO_PG0, /* pin 48 */ + GPIO_PG1, + GPIO_PG2, + GPIO_PG3, + GPIO_PG4, + GPIO_PG5, + GPIO_PG6, + GPIO_PG7, + GPIO_PH0, /* pin 56 */ + GPIO_PH1, + GPIO_PH2, + GPIO_PH3, + GPIO_PH4, + GPIO_PH5, + GPIO_PH6, + GPIO_PH7, + GPIO_PI0, /* pin 64 */ + GPIO_PI1, + GPIO_PI2, + GPIO_PI3, + GPIO_PI4, + GPIO_PI5, + GPIO_PI6, + GPIO_PI7, + GPIO_PJ0, /* pin 72 */ + GPIO_PJ1, + GPIO_PJ2, + GPIO_PJ3, + GPIO_PJ4, + GPIO_PJ5, + GPIO_PJ6, + GPIO_PJ7, + GPIO_PK0, /* pin 80 */ + GPIO_PK1, + GPIO_PK2, + GPIO_PK3, + GPIO_PK4, + GPIO_PK5, + GPIO_PK6, + GPIO_PK7, + GPIO_PL0, /* pin 88 */ + GPIO_PL1, + GPIO_PL2, + GPIO_PL3, + GPIO_PL4, + GPIO_PL5, + GPIO_PL6, + GPIO_PL7, + GPIO_PM0, /* pin 96 */ + GPIO_PM1, + GPIO_PM2, + GPIO_PM3, + GPIO_PM4, + GPIO_PM5, + GPIO_PM6, + GPIO_PM7, + GPIO_PN0, /* pin 104 */ + GPIO_PN1, + GPIO_PN2, + GPIO_PN3, + GPIO_PN4, + GPIO_PN5, + GPIO_PN6, + GPIO_PN7, + GPIO_PO0, /* pin 112 */ + GPIO_PO1, + GPIO_PO2, + GPIO_PO3, + GPIO_PO4, + GPIO_PO5, + GPIO_PO6, + GPIO_PO7, + GPIO_PP0, /* pin 120 */ + GPIO_PP1, + GPIO_PP2, + GPIO_PP3, + GPIO_PP4, + GPIO_PP5, + GPIO_PP6, + GPIO_PP7, + GPIO_PQ0, /* pin 128 */ + GPIO_PQ1, + GPIO_PQ2, + GPIO_PQ3, + GPIO_PQ4, + GPIO_PQ5, + GPIO_PQ6, + GPIO_PQ7, + GPIO_PR0, /* pin 136 */ + GPIO_PR1, + GPIO_PR2, + GPIO_PR3, + GPIO_PR4, + GPIO_PR5, + GPIO_PR6, + GPIO_PR7, + GPIO_PS0, /* pin 144 */ + GPIO_PS1, + GPIO_PS2, + GPIO_PS3, + GPIO_PS4, + GPIO_PS5, + GPIO_PS6, + GPIO_PS7, + GPIO_PT0, /* pin 152 */ + GPIO_PT1, + GPIO_PT2, + GPIO_PT3, + GPIO_PT4, + GPIO_PT5, + GPIO_PT6, + GPIO_PT7, + GPIO_PU0, /* pin 160 */ + GPIO_PU1, + GPIO_PU2, + GPIO_PU3, + GPIO_PU4, + GPIO_PU5, + GPIO_PU6, + GPIO_PU7, + GPIO_PV0, /* pin 168 */ + GPIO_PV1, + GPIO_PV2, + GPIO_PV3, + GPIO_PV4, + GPIO_PV5, + GPIO_PV6, + GPIO_PV7, + GPIO_PW0, /* pin 176 */ + GPIO_PW1, + GPIO_PW2, + GPIO_PW3, + GPIO_PW4, + GPIO_PW5, + GPIO_PW6, + GPIO_PW7, + GPIO_PX0, /* pin 184 */ + GPIO_PX1, + GPIO_PX2, + GPIO_PX3, + GPIO_PX4, + GPIO_PX5, + GPIO_PX6, + GPIO_PX7, + GPIO_PY0, /* pin 192 */ + GPIO_PY1, + GPIO_PY2, + GPIO_PY3, + GPIO_PY4, + GPIO_PY5, + GPIO_PY6, + GPIO_PY7, + GPIO_PZ0, /* pin 200 */ + GPIO_PZ1, + GPIO_PZ2, + GPIO_PZ3, + GPIO_PZ4, + GPIO_PZ5, + GPIO_PZ6, + GPIO_PZ7, + GPIO_PAA0, /* pin 208 */ + GPIO_PAA1, + GPIO_PAA2, + GPIO_PAA3, + GPIO_PAA4, + GPIO_PAA5, + GPIO_PAA6, + GPIO_PAA7, + GPIO_PBB0, /* pin 216 */ + GPIO_PBB1, + GPIO_PBB2, + GPIO_PBB3, + GPIO_PBB4, + GPIO_PBB5, + GPIO_PBB6, + GPIO_PBB7, + GPIO_PCC0, /* pin 224 */ + GPIO_PCC1, + GPIO_PCC2, + GPIO_PCC3, + GPIO_PCC4, + GPIO_PCC5, + GPIO_PCC6, + GPIO_PCC7, + GPIO_PDD0, /* pin 232 */ + GPIO_PDD1, + GPIO_PDD2, + GPIO_PDD3, + GPIO_PDD4, + GPIO_PDD5, + GPIO_PDD6, + GPIO_PDD7, + GPIO_PEE0, /* pin 240 */ + GPIO_PEE1, + GPIO_PEE2, + GPIO_PEE3, + GPIO_PEE4, + GPIO_PEE5, + GPIO_PEE6, + GPIO_PEE7, /* pin 247 */ +}; + +#endif /* _TEGRA30_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h new file mode 100644 index 0000000000..b1a5aa9e0e --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/hardware.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_HARDWARE_H_ +#define _TEGRA30_HARDWARE_H_ + +/* include tegra specific hardware definitions */ + +#endif /* _TEGRA30-HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/pinmux.h b/arch/arm/include/asm/arch-tegra30/pinmux.h new file mode 100644 index 0000000000..341951bfcb --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pinmux.h @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_PINMUX_H_ +#define _TEGRA30_PINMUX_H_ + +/* + * Pin groups which we adjust. There are three basic attributes of each pin + * group which use this enum: + * + * - function + * - pullup / pulldown + * - tristate or normal + */ +enum pmux_pingrp { + PINGRP_ULPI_DATA0 = 0, /* offset 0x3000 */ + PINGRP_ULPI_DATA1, + PINGRP_ULPI_DATA2, + PINGRP_ULPI_DATA3, + PINGRP_ULPI_DATA4, + PINGRP_ULPI_DATA5, + PINGRP_ULPI_DATA6, + PINGRP_ULPI_DATA7, + PINGRP_ULPI_CLK, + PINGRP_ULPI_DIR, + PINGRP_ULPI_NXT, + PINGRP_ULPI_STP, + PINGRP_DAP3_FS, + PINGRP_DAP3_DIN, + PINGRP_DAP3_DOUT, + PINGRP_DAP3_SCLK, + PINGRP_GPIO_PV0, + PINGRP_GPIO_PV1, + PINGRP_SDMMC1_CLK, + PINGRP_SDMMC1_CMD, + PINGRP_SDMMC1_DAT3, + PINGRP_SDMMC1_DAT2, + PINGRP_SDMMC1_DAT1, + PINGRP_SDMMC1_DAT0, + PINGRP_GPIO_PV2, + PINGRP_GPIO_PV3, + PINGRP_CLK2_OUT, + PINGRP_CLK2_REQ, + PINGRP_LCD_PWR1, + PINGRP_LCD_PWR2, + PINGRP_LCD_SDIN, + PINGRP_LCD_SDOUT, + PINGRP_LCD_WR_N, + PINGRP_LCD_CS0_N, + PINGRP_LCD_DC0, + PINGRP_LCD_SCK, + PINGRP_LCD_PWR0, + PINGRP_LCD_PCLK, + PINGRP_LCD_DE, + PINGRP_LCD_HSYNC, + PINGRP_LCD_VSYNC, + PINGRP_LCD_D0, + PINGRP_LCD_D1, + PINGRP_LCD_D2, + PINGRP_LCD_D3, + PINGRP_LCD_D4, + PINGRP_LCD_D5, + PINGRP_LCD_D6, + PINGRP_LCD_D7, + PINGRP_LCD_D8, + PINGRP_LCD_D9, + PINGRP_LCD_D10, + PINGRP_LCD_D11, + PINGRP_LCD_D12, + PINGRP_LCD_D13, + PINGRP_LCD_D14, + PINGRP_LCD_D15, + PINGRP_LCD_D16, + PINGRP_LCD_D17, + PINGRP_LCD_D18, + PINGRP_LCD_D19, + PINGRP_LCD_D20, + PINGRP_LCD_D21, + PINGRP_LCD_D22, + PINGRP_LCD_D23, + PINGRP_LCD_CS1_N, + PINGRP_LCD_M1, + PINGRP_LCD_DC1, + PINGRP_HDMI_INT, + PINGRP_DDC_SCL, + PINGRP_DDC_SDA, + PINGRP_CRT_HSYNC, + PINGRP_CRT_VSYNC, + PINGRP_VI_D0, + PINGRP_VI_D1, + PINGRP_VI_D2, + PINGRP_VI_D3, + PINGRP_VI_D4, + PINGRP_VI_D5, + PINGRP_VI_D6, + PINGRP_VI_D7, + PINGRP_VI_D8, + PINGRP_VI_D9, + PINGRP_VI_D10, + PINGRP_VI_D11, + PINGRP_VI_PCLK, + PINGRP_VI_MCLK, + PINGRP_VI_VSYNC, + PINGRP_VI_HSYNC, + PINGRP_UART2_RXD, + PINGRP_UART2_TXD, + PINGRP_UART2_RTS_N, + PINGRP_UART2_CTS_N, + PINGRP_UART3_TXD, + PINGRP_UART3_RXD, + PINGRP_UART3_CTS_N, + PINGRP_UART3_RTS_N, + PINGRP_GPIO_PU0, + PINGRP_GPIO_PU1, + PINGRP_GPIO_PU2, + PINGRP_GPIO_PU3, + PINGRP_GPIO_PU4, + PINGRP_GPIO_PU5, + PINGRP_GPIO_PU6, + PINGRP_GEN1_I2C_SDA, + PINGRP_GEN1_I2C_SCL, + PINGRP_DAP4_FS, + PINGRP_DAP4_DIN, + PINGRP_DAP4_DOUT, + PINGRP_DAP4_SCLK, + PINGRP_CLK3_OUT, + PINGRP_CLK3_REQ, + PINGRP_GMI_WP_N, + PINGRP_GMI_IORDY, + PINGRP_GMI_WAIT, + PINGRP_GMI_ADV_N, + PINGRP_GMI_CLK, + PINGRP_GMI_CS0_N, + PINGRP_GMI_CS1_N, + PINGRP_GMI_CS2_N, + PINGRP_GMI_CS3_N, + PINGRP_GMI_CS4_N, + PINGRP_GMI_CS6_N, + PINGRP_GMI_CS7_N, + PINGRP_GMI_AD0, + PINGRP_GMI_AD1, + PINGRP_GMI_AD2, + PINGRP_GMI_AD3, + PINGRP_GMI_AD4, + PINGRP_GMI_AD5, + PINGRP_GMI_AD6, + PINGRP_GMI_AD7, + PINGRP_GMI_AD8, + PINGRP_GMI_AD9, + PINGRP_GMI_AD10, + PINGRP_GMI_AD11, + PINGRP_GMI_AD12, + PINGRP_GMI_AD13, + PINGRP_GMI_AD14, + PINGRP_GMI_AD15, + PINGRP_GMI_A16, + PINGRP_GMI_A17, + PINGRP_GMI_A18, + PINGRP_GMI_A19, + PINGRP_GMI_WR_N, + PINGRP_GMI_OE_N, + PINGRP_GMI_DQS, + PINGRP_GMI_RST_N, + PINGRP_GEN2_I2C_SCL, + PINGRP_GEN2_I2C_SDA, + PINGRP_SDMMC4_CLK, + PINGRP_SDMMC4_CMD, + PINGRP_SDMMC4_DAT0, + PINGRP_SDMMC4_DAT1, + PINGRP_SDMMC4_DAT2, + PINGRP_SDMMC4_DAT3, + PINGRP_SDMMC4_DAT4, + PINGRP_SDMMC4_DAT5, + PINGRP_SDMMC4_DAT6, + PINGRP_SDMMC4_DAT7, + PINGRP_SDMMC4_RST_N, + PINGRP_CAM_MCLK, + PINGRP_GPIO_PCC1, + PINGRP_GPIO_PBB0, + PINGRP_CAM_I2C_SCL, + PINGRP_CAM_I2C_SDA, + PINGRP_GPIO_PBB3, + PINGRP_GPIO_PBB4, + PINGRP_GPIO_PBB5, + PINGRP_GPIO_PBB6, + PINGRP_GPIO_PBB7, + PINGRP_GPIO_PCC2, + PINGRP_JTAG_RTCK, + PINGRP_PWR_I2C_SCL, + PINGRP_PWR_I2C_SDA, + PINGRP_KB_ROW0, + PINGRP_KB_ROW1, + PINGRP_KB_ROW2, + PINGRP_KB_ROW3, + PINGRP_KB_ROW4, + PINGRP_KB_ROW5, + PINGRP_KB_ROW6, + PINGRP_KB_ROW7, + PINGRP_KB_ROW8, + PINGRP_KB_ROW9, + PINGRP_KB_ROW10, + PINGRP_KB_ROW11, + PINGRP_KB_ROW12, + PINGRP_KB_ROW13, + PINGRP_KB_ROW14, + PINGRP_KB_ROW15, + PINGRP_KB_COL0, + PINGRP_KB_COL1, + PINGRP_KB_COL2, + PINGRP_KB_COL3, + PINGRP_KB_COL4, + PINGRP_KB_COL5, + PINGRP_KB_COL6, + PINGRP_KB_COL7, + PINGRP_CLK_32K_OUT, + PINGRP_SYS_CLK_REQ, + PINGRP_CORE_PWR_REQ, + PINGRP_CPU_PWR_REQ, + PINGRP_PWR_INT_N, + PINGRP_CLK_32K_IN, + PINGRP_OWR, + PINGRP_DAP1_FS, + PINGRP_DAP1_DIN, + PINGRP_DAP1_DOUT, + PINGRP_DAP1_SCLK, + PINGRP_CLK1_REQ, + PINGRP_CLK1_OUT, + PINGRP_SPDIF_IN, + PINGRP_SPDIF_OUT, + PINGRP_DAP2_FS, + PINGRP_DAP2_DIN, + PINGRP_DAP2_DOUT, + PINGRP_DAP2_SCLK, + PINGRP_SPI2_MOSI, + PINGRP_SPI2_MISO, + PINGRP_SPI2_CS0_N, + PINGRP_SPI2_SCK, + PINGRP_SPI1_MOSI, + PINGRP_SPI1_SCK, + PINGRP_SPI1_CS0_N, + PINGRP_SPI1_MISO, + PINGRP_SPI2_CS1_N, + PINGRP_SPI2_CS2_N, + PINGRP_SDMMC3_CLK, + PINGRP_SDMMC3_CMD, + PINGRP_SDMMC3_DAT0, + PINGRP_SDMMC3_DAT1, + PINGRP_SDMMC3_DAT2, + PINGRP_SDMMC3_DAT3, + PINGRP_SDMMC3_DAT4, + PINGRP_SDMMC3_DAT5, + PINGRP_SDMMC3_DAT6, + PINGRP_SDMMC3_DAT7, + PINGRP_PEX_L0_PRSNT_N, + PINGRP_PEX_L0_RST_N, + PINGRP_PEX_L0_CLKREQ_N, + PINGRP_PEX_WAKE_N, + PINGRP_PEX_L1_PRSNT_N, + PINGRP_PEX_L1_RST_N, + PINGRP_PEX_L1_CLKREQ_N, + PINGRP_PEX_L2_PRSNT_N, + PINGRP_PEX_L2_RST_N, + PINGRP_PEX_L2_CLKREQ_N, + PINGRP_HDMI_CEC, /* offset 0x33e0 */ + PINGRP_COUNT, +}; + +enum pdrive_pingrp { + PDRIVE_PINGROUP_AO1 = 0, /* offset 0x868 */ + PDRIVE_PINGROUP_AO2, + PDRIVE_PINGROUP_AT1, + PDRIVE_PINGROUP_AT2, + PDRIVE_PINGROUP_AT3, + PDRIVE_PINGROUP_AT4, + PDRIVE_PINGROUP_AT5, + PDRIVE_PINGROUP_CDEV1, + PDRIVE_PINGROUP_CDEV2, + PDRIVE_PINGROUP_CSUS, + PDRIVE_PINGROUP_DAP1, + PDRIVE_PINGROUP_DAP2, + PDRIVE_PINGROUP_DAP3, + PDRIVE_PINGROUP_DAP4, + PDRIVE_PINGROUP_DBG, + PDRIVE_PINGROUP_LCD1, + PDRIVE_PINGROUP_LCD2, + PDRIVE_PINGROUP_SDIO2, + PDRIVE_PINGROUP_SDIO3, + PDRIVE_PINGROUP_SPI, + PDRIVE_PINGROUP_UAA, + PDRIVE_PINGROUP_UAB, + PDRIVE_PINGROUP_UART2, + PDRIVE_PINGROUP_UART3, + PDRIVE_PINGROUP_VI1 = 24, /* offset 0x8c8 */ + PDRIVE_PINGROUP_SDIO1 = 33, /* offset 0x8ec */ + PDRIVE_PINGROUP_CRT = 36, /* offset 0x8f8 */ + PDRIVE_PINGROUP_DDC, + PDRIVE_PINGROUP_GMA, + PDRIVE_PINGROUP_GMB, + PDRIVE_PINGROUP_GMC, + PDRIVE_PINGROUP_GMD, + PDRIVE_PINGROUP_GME, + PDRIVE_PINGROUP_GMF, + PDRIVE_PINGROUP_GMG, + PDRIVE_PINGROUP_GMH, + PDRIVE_PINGROUP_OWR, + PDRIVE_PINGROUP_UAD, + PDRIVE_PINGROUP_GPV, + PDRIVE_PINGROUP_DEV3 = 49, /* offset 0x92c */ + PDRIVE_PINGROUP_CEC = 52, /* offset 0x938 */ + PDRIVE_PINGROUP_COUNT, +}; + +/* + * Functions which can be assigned to each of the pin groups. The values here + * bear no relation to the values programmed into pinmux registers and are + * purely a convenience. The translation is done through a table search. + */ +enum pmux_func { + PMUX_FUNC_AHB_CLK, + PMUX_FUNC_APB_CLK, + PMUX_FUNC_AUDIO_SYNC, + PMUX_FUNC_CRT, + PMUX_FUNC_DAP1, + PMUX_FUNC_DAP2, + PMUX_FUNC_DAP3, + PMUX_FUNC_DAP4, + PMUX_FUNC_DAP5, + PMUX_FUNC_DISPA, + PMUX_FUNC_DISPB, + PMUX_FUNC_EMC_TEST0_DLL, + PMUX_FUNC_EMC_TEST1_DLL, + PMUX_FUNC_GMI, + PMUX_FUNC_GMI_INT, + PMUX_FUNC_HDMI, + PMUX_FUNC_I2C1, + PMUX_FUNC_I2C2, + PMUX_FUNC_I2C3, + PMUX_FUNC_IDE, + PMUX_FUNC_KBC, + PMUX_FUNC_MIO, + PMUX_FUNC_MIPI_HS, + PMUX_FUNC_NAND, + PMUX_FUNC_OSC, + PMUX_FUNC_OWR, + PMUX_FUNC_PCIE, + PMUX_FUNC_PLLA_OUT, + PMUX_FUNC_PLLC_OUT1, + PMUX_FUNC_PLLM_OUT1, + PMUX_FUNC_PLLP_OUT2, + PMUX_FUNC_PLLP_OUT3, + PMUX_FUNC_PLLP_OUT4, + PMUX_FUNC_PWM, + PMUX_FUNC_PWR_INTR, + PMUX_FUNC_PWR_ON, + PMUX_FUNC_RTCK, + PMUX_FUNC_SDMMC1, + PMUX_FUNC_SDMMC2, + PMUX_FUNC_SDMMC3, + PMUX_FUNC_SDMMC4, + PMUX_FUNC_SFLASH, + PMUX_FUNC_SPDIF, + PMUX_FUNC_SPI1, + PMUX_FUNC_SPI2, + PMUX_FUNC_SPI2_ALT, + PMUX_FUNC_SPI3, + PMUX_FUNC_SPI4, + PMUX_FUNC_TRACE, + PMUX_FUNC_TWC, + PMUX_FUNC_UARTA, + PMUX_FUNC_UARTB, + PMUX_FUNC_UARTC, + PMUX_FUNC_UARTD, + PMUX_FUNC_UARTE, + PMUX_FUNC_ULPI, + PMUX_FUNC_VI, + PMUX_FUNC_VI_SENSOR_CLK, + PMUX_FUNC_XIO, + PMUX_FUNC_BLINK, + PMUX_FUNC_CEC, + PMUX_FUNC_CLK12, + PMUX_FUNC_DAP, + PMUX_FUNC_DAPSDMMC2, + PMUX_FUNC_DDR, + PMUX_FUNC_DEV3, + PMUX_FUNC_DTV, + PMUX_FUNC_VI_ALT1, + PMUX_FUNC_VI_ALT2, + PMUX_FUNC_VI_ALT3, + PMUX_FUNC_EMC_DLL, + PMUX_FUNC_EXTPERIPH1, + PMUX_FUNC_EXTPERIPH2, + PMUX_FUNC_EXTPERIPH3, + PMUX_FUNC_GMI_ALT, + PMUX_FUNC_HDA, + PMUX_FUNC_HSI, + PMUX_FUNC_I2C4, + PMUX_FUNC_I2C5, + PMUX_FUNC_I2CPWR, + PMUX_FUNC_I2S0, + PMUX_FUNC_I2S1, + PMUX_FUNC_I2S2, + PMUX_FUNC_I2S3, + PMUX_FUNC_I2S4, + PMUX_FUNC_NAND_ALT, + PMUX_FUNC_POPSDIO4, + PMUX_FUNC_POPSDMMC4, + PMUX_FUNC_PWM0, + PMUX_FUNC_PWM1, + PMUX_FUNC_PWM2, + PMUX_FUNC_PWM3, + PMUX_FUNC_SATA, + PMUX_FUNC_SPI5, + PMUX_FUNC_SPI6, + PMUX_FUNC_SYSCLK, + PMUX_FUNC_VGP1, + PMUX_FUNC_VGP2, + PMUX_FUNC_VGP3, + PMUX_FUNC_VGP4, + PMUX_FUNC_VGP5, + PMUX_FUNC_VGP6, + PMUX_FUNC_CLK_12M_OUT, + PMUX_FUNC_HDCP, + PMUX_FUNC_TEST, + PMUX_FUNC_CORE_PWR_REQ, + PMUX_FUNC_CPU_PWR_REQ, + PMUX_FUNC_PWR_INT_N, + PMUX_FUNC_CLK_32K_IN, + PMUX_FUNC_SAFE, + + PMUX_FUNC_MAX, + + PMUX_FUNC_RSVD1 = 0x8000, + PMUX_FUNC_RSVD2 = 0x8001, + PMUX_FUNC_RSVD3 = 0x8002, + PMUX_FUNC_RSVD4 = 0x8003, +}; + +/* return 1 if a pmux_func is in range */ +#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \ + || (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4))) + +/* return 1 if a pingrp is in range */ +#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT)) + +/* The pullup/pulldown state of a pin group */ +enum pmux_pull { + PMUX_PULL_NORMAL = 0, + PMUX_PULL_DOWN, + PMUX_PULL_UP, +}; +/* return 1 if a pin_pupd_is in range */ +#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \ + ((pupd) <= PMUX_PULL_UP)) + +/* Defines whether a pin group is tristated or in normal operation */ +enum pmux_tristate { + PMUX_TRI_NORMAL = 0, + PMUX_TRI_TRISTATE = 1, +}; +/* return 1 if a pin_tristate_is in range */ +#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \ + && ((tristate) <= PMUX_TRI_TRISTATE)) + +enum pmux_pin_io { + PMUX_PIN_OUTPUT = 0, + PMUX_PIN_INPUT = 1, +}; +/* return 1 if a pin_io_is in range */ +#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \ + ((io) <= PMUX_PIN_INPUT)) + +enum pmux_pin_lock { + PMUX_PIN_LOCK_DEFAULT = 0, + PMUX_PIN_LOCK_DISABLE, + PMUX_PIN_LOCK_ENABLE, +}; +/* return 1 if a pin_lock is in range */ +#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \ + ((lock) <= PMUX_PIN_LOCK_ENABLE)) + +enum pmux_pin_od { + PMUX_PIN_OD_DEFAULT = 0, + PMUX_PIN_OD_DISABLE, + PMUX_PIN_OD_ENABLE, +}; +/* return 1 if a pin_od is in range */ +#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \ + ((od) <= PMUX_PIN_OD_ENABLE)) + +enum pmux_pin_ioreset { + PMUX_PIN_IO_RESET_DEFAULT = 0, + PMUX_PIN_IO_RESET_DISABLE, + PMUX_PIN_IO_RESET_ENABLE, +}; +/* return 1 if a pin_ioreset_is in range */ +#define pmux_pin_ioreset_isvalid(ioreset) \ + (((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \ + ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) + +/* Available power domains used by pin groups */ +enum pmux_vddio { + PMUX_VDDIO_BB = 0, + PMUX_VDDIO_LCD, + PMUX_VDDIO_VI, + PMUX_VDDIO_UART, + PMUX_VDDIO_DDR, + PMUX_VDDIO_NAND, + PMUX_VDDIO_SYS, + PMUX_VDDIO_AUDIO, + PMUX_VDDIO_SD, + PMUX_VDDIO_CAM, + PMUX_VDDIO_GMI, + PMUX_VDDIO_PEXCTL, + PMUX_VDDIO_SDMMC1, + PMUX_VDDIO_SDMMC3, + PMUX_VDDIO_SDMMC4, + + PMUX_VDDIO_NONE +}; + +/* t30 pin drive group and pin mux registers */ +#define PDRIVE_PINGROUP_OFFSET (0x868 >> 2) +#define PMUX_OFFSET ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \ + PDRIVE_PINGROUP_COUNT) +struct pmux_tri_ctlr { + uint pmt_reserved0; /* ABP_MISC_PP_ reserved offset 00 */ + uint pmt_reserved1; /* ABP_MISC_PP_ reserved offset 04 */ + uint pmt_strap_opt_a; /* _STRAPPING_OPT_A_0, offset 08 */ + uint pmt_reserved2; /* ABP_MISC_PP_ reserved offset 0C */ + uint pmt_reserved3; /* ABP_MISC_PP_ reserved offset 10 */ + uint pmt_reserved4[4]; /* _TRI_STATE_REG_A/B/C/D in t20 */ + uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */ + + uint pmt_reserved[528]; /* ABP_MISC_PP_ reserved offs 28-864 */ + + uint pmt_drive[PDRIVE_PINGROUP_COUNT]; /* pin drive grps offs 868 */ + uint pmt_reserved5[PMUX_OFFSET]; + uint pmt_ctl[PINGRP_COUNT]; /* mux/pupd/tri regs, offset 0x3000 */ +}; + +/* + * This defines the configuration for a pin, including the function assigned, + * pull up/down settings and tristate settings. Having set up one of these + * you can call pinmux_config_pingroup() to configure a pin in one step. Also + * available is pinmux_config_table() to configure a list of pins. + */ +struct pingroup_config { + enum pmux_pingrp pingroup; /* pin group PINGRP_... */ + enum pmux_func func; /* function to assign FUNC_... */ + enum pmux_pull pull; /* pull up/down/normal PMUX_PULL_...*/ + enum pmux_tristate tristate; /* tristate or normal PMUX_TRI_... */ + enum pmux_pin_io io; /* input or output PMUX_PIN_... */ + enum pmux_pin_lock lock; /* lock enable/disable PMUX_PIN... */ + enum pmux_pin_od od; /* open-drain or push-pull driver */ + enum pmux_pin_ioreset ioreset; /* input/output reset PMUX_PIN... */ +}; + +/* Set a pin group to tristate */ +void pinmux_tristate_enable(enum pmux_pingrp pin); + +/* Set a pin group to normal (non tristate) */ +void pinmux_tristate_disable(enum pmux_pingrp pin); + +/* Set the pull up/down feature for a pin group */ +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd); + +/* Set the mux function for a pin group */ +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func); + +/* Set the complete configuration for a pin group */ +void pinmux_config_pingroup(struct pingroup_config *config); + +/* Set a pin group to tristate or normal */ +void pinmux_set_tristate(enum pmux_pingrp pin, int enable); + +/* Set a pin group as input or output */ +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io); + +/** + * Configure a list of pin groups + * + * @param config List of config items + * @param len Number of config items in list + */ +void pinmux_config_table(struct pingroup_config *config, int len); + +/* Set a group of pins from a table */ +void pinmux_init(void); + +#endif /* _TEGRA30_PINMUX_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/pmu.h b/arch/arm/include/asm/arch-tegra30/pmu.h new file mode 100644 index 0000000000..52bea29bbc --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pmu.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_PMU_H_ +#define _TEGRA30_PMU_H_ + +/* Set core and CPU voltages to nominal levels */ +int pmu_set_nominal(void); + +#endif /* _TEGRA30_PMU_H_ */ diff --git a/arch/x86/include/asm/arch-sc520/ssi.h b/arch/arm/include/asm/arch-tegra30/spl.h index bd48eab161..5e453c5cc7 100644 --- a/arch/x86/include/asm/arch-sc520/ssi.h +++ b/arch/arm/include/asm/arch-tegra30/spl.h @@ -1,6 +1,6 @@ /* - * (C) Copyright 2008 - * Graeme Russ <graeme.russ@gmail.com>. + * (C) Copyright 2012 + * NVIDIA Corporation <www.nvidia.com> * * See file CREDITS for list of people who contributed to this * project. @@ -12,7 +12,7 @@ * * 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 + * 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 @@ -20,15 +20,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_ARCH_SPL_H_ -#ifndef _ASM_IC_SSI_H_ -#define _ASM_IC_SSI_H_ 1 - -int ssi_set_interface(int, int, int, int); -void ssi_chip_select(int); -u8 ssi_txrx_byte(u8); -void ssi_tx_byte(u8); -u8 ssi_rx_byte(void); - +#define BOOT_DEVICE_RAM 1 #endif diff --git a/arch/arm/include/asm/arch-tegra30/tegra.h b/arch/arm/include/asm/arch-tegra30/tegra.h new file mode 100644 index 0000000000..decf564d13 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/tegra.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _TEGRA30_H_ +#define _TEGRA30_H_ + +#define NV_PA_SDRAM_BASE 0x80000000 /* 0x80000000 for real T30 */ + +#include <asm/arch-tegra/tegra.h> + +#define BCT_ODMDATA_OFFSET 6116 /* 12 bytes from end of BCT */ + +#define MAX_NUM_CPU 4 + +#endif /* TEGRA30_H */ diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h new file mode 100644 index 0000000000..d0c69da971 --- /dev/null +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013 Xilinx Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ARCH_HARDWARE_H +#define _ASM_ARCH_HARDWARE_H + +#define XPSS_SYS_CTRL_BASEADDR 0xF8000000 +#define XPSS_DEV_CFG_APB_BASEADDR 0xF8007000 +#define XPSS_SCU_BASEADDR 0xF8F00000 + +/* Reflect slcr offsets */ +struct slcr_regs { + u32 scl; /* 0x0 */ + u32 slcr_lock; /* 0x4 */ + u32 slcr_unlock; /* 0x8 */ + u32 reserved1[125]; + u32 pss_rst_ctrl; /* 0x200 */ + u32 reserved2[15]; + u32 fpga_rst_ctrl; /* 0x240 */ + u32 reserved3[5]; + u32 reboot_status; /* 0x258 */ + u32 boot_mode; /* 0x25c */ + u32 reserved4[116]; + u32 trust_zone; /* 0x430 */ /* FIXME */ + u32 reserved5[115]; + u32 ddr_urgent; /* 0x600 */ + u32 reserved6[6]; + u32 ddr_urgent_sel; /* 0x61c */ + u32 reserved7[188]; + u32 ocm_cfg; /* 0x910 */ +}; + +#define slcr_base ((struct slcr_regs *) XPSS_SYS_CTRL_BASEADDR) + +struct devcfg_regs { + u32 ctrl; /* 0x0 */ + u32 lock; /* 0x4 */ + u32 cfg; /* 0x8 */ + u32 int_sts; /* 0xc */ + u32 int_mask; /* 0x10 */ + u32 status; /* 0x14 */ + u32 dma_src_addr; /* 0x18 */ + u32 dma_dst_addr; /* 0x1c */ + u32 dma_src_len; /* 0x20 */ + u32 dma_dst_len; /* 0x24 */ + u32 rom_shadow; /* 0x28 */ + u32 reserved1[2]; + u32 unlock; /* 0x34 */ + u32 reserved2[18]; + u32 mctrl; /* 0x80 */ + u32 reserved3; + u32 write_count; /* 0x88 */ + u32 read_count; /* 0x8c */ +}; + +#define devcfg_base ((struct devcfg_regs *) XPSS_DEV_CFG_APB_BASEADDR) + +struct scu_regs { + u32 reserved1[16]; + u32 filter_start; /* 0x40 */ + u32 filter_end; /* 0x44 */ +}; + +#define scu_base ((struct scu_regs *) XPSS_SCU_BASEADDR) + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/x86/cpu/sc520/sc520_reset.c b/arch/arm/include/asm/arch-zynq/sys_proto.h index 137af978c1..e78890011a 100644 --- a/arch/x86/cpu/sc520/sc520_reset.c +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -1,9 +1,5 @@ /* - * (C) Copyright 2011 - * Graeme Russ, <graeme.russ@gmail.com> - * - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * Copyright (c) 2013 Xilinx Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -15,7 +11,7 @@ * * 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 + * 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 @@ -24,17 +20,11 @@ * MA 02111-1307 USA */ -#include <common.h> -#include <asm/io.h> -#include <asm/arch/sc520.h> - -DECLARE_GLOBAL_DATA_PTR; +#ifndef _SYS_PROTO_H_ +#define _SYS_PROTO_H_ -void reset_cpu(ulong addr) -{ - printf("Resetting using SC520 MMCR\n"); - /* Write a '1' to the SYS_RST of the RESCFG MMCR */ - writeb(0x01, &sc520_mmcr->rescfg); +extern void zynq_slcr_lock(void); +extern void zynq_slcr_unlock(void); +extern void zynq_slcr_cpu_reset(void); - /* NOTREACHED */ -} +#endif /* _SYS_PROTO_H_ */ diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 41a26edfb5..37ac0daa70 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -23,27 +23,11 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory which is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long fb_base; /* base address of frame buffer */ -#ifdef CONFIG_FSL_ESDHC - unsigned long sdhc_clk; +/* Architecture-specific global data */ +struct arch_global_data { +#if defined(CONFIG_FSL_ESDHC) + u32 sdhc_clk; #endif #ifdef CONFIG_AT91FAMILY /* "static data" needed by at91's clock.c */ @@ -54,38 +38,22 @@ typedef struct global_data { unsigned long pllb_rate_hz; unsigned long at91_pllb_usb_init; #endif -#ifdef CONFIG_ARM /* "static data" needed by most of timer.c on ARM platforms */ - unsigned long timer_rate_hz; - unsigned long tbl; - unsigned long tbu; - unsigned long long timer_reset_value; - unsigned long lastinc; -#endif + unsigned long timer_rate_hz; + unsigned long tbu; + unsigned long tbl; + unsigned long lastinc; + unsigned long long timer_reset_value; #ifdef CONFIG_IXP425 - unsigned long timestamp; + unsigned long timestamp; #endif - unsigned long relocaddr; /* Start address of U-Boot in RAM */ - phys_size_t ram_size; /* RAM size */ - unsigned long mon_len; /* monitor len */ - unsigned long irq_sp; /* irq stack pointer */ - unsigned long start_addr_sp; /* start_addr_stackpointer */ - unsigned long reloc_off; #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) - unsigned long tlb_addr; - unsigned long tlb_size; -#endif - const void *fdt_blob; /* Our device tree, NULL if none */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - unsigned long post_log_word; /* Record POST activities */ - unsigned long post_log_res; /* success of POST test */ - unsigned long post_init_f_time; /* When post_init_f started */ + unsigned long tlb_addr; + unsigned long tlb_size; #endif -} gd_t; +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 78ca8e0a6d..1918492eae 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -61,6 +61,12 @@ #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); +#ifdef __ARM_ARCH_7A__ +#define wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#else +#define wfi() +#endif + static inline unsigned int get_cr(void) { unsigned int val; diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index cfe32cc926..162e2cc863 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -355,14 +355,14 @@ void board_init_f(ulong bootflag) #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) /* reserve TLB table */ - gd->tlb_size = 4096 * 4; - addr -= gd->tlb_size; + gd->arch.tlb_size = 4096 * 4; + addr -= gd->arch.tlb_size; /* round down to next 64 kB limit */ addr &= ~(0x10000 - 1); - gd->tlb_addr = addr; - debug("TLB table from %08lx to %08lx\n", addr, addr + gd->tlb_size); + gd->arch.tlb_addr = addr; + debug("TLB table from %08lx to %08lx\n", addr, addr + gd->arch.tlb_size); #endif /* round down to next 4 kB limit */ @@ -488,7 +488,7 @@ static char *failed = "*** failed ***\n"; static int should_load_env(void) { #ifdef CONFIG_OF_CONTROL - return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 0); + return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1); #elif defined CONFIG_DELAY_ENVIRONMENT return 0; #else diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 1bd2730856..f3b30c57a3 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -30,7 +30,6 @@ #include <image.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> -#include <fdt.h> #include <libfdt.h> #include <fdt_support.h> #include <asm/bootm.h> diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 1cab27c226..b6e5e95530 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -46,7 +46,7 @@ static void cp_delay (void) void set_section_dcache(int section, enum dcache_option option) { - u32 *page_table = (u32 *)gd->tlb_addr; + u32 *page_table = (u32 *)gd->arch.tlb_addr; u32 value; value = (section << MMU_SECTION_SHIFT) | (3 << 10); @@ -65,7 +65,7 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop) void mmu_set_region_dcache_behaviour(u32 start, int size, enum dcache_option option) { - u32 *page_table = (u32 *)gd->tlb_addr; + u32 *page_table = (u32 *)gd->arch.tlb_addr; u32 upto, end; end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT; @@ -111,7 +111,7 @@ static inline void mmu_setup(void) /* Copy the page table address to cp15 */ asm volatile("mcr p15, 0, %0, c2, c0, 0" - : : "r" (gd->tlb_addr) : "memory"); + : : "r" (gd->arch.tlb_addr) : "memory"); /* Set the access control to all-supervisor */ asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (~0)); diff --git a/arch/avr32/cpu/cpu.c b/arch/avr32/cpu/cpu.c index 790783767f..9d82ca4ad2 100644 --- a/arch/avr32/cpu/cpu.c +++ b/arch/avr32/cpu/cpu.c @@ -47,7 +47,7 @@ int cpu_init(void) { extern void _evba(void); - gd->cpu_hz = CONFIG_SYS_OSC0_HZ; + gd->arch.cpu_hz = CONFIG_SYS_OSC0_HZ; /* TODO: Move somewhere else, but needs to be run before we * increase the clock frequency. */ @@ -59,7 +59,7 @@ int cpu_init(void) clk_init(); /* Update the CPU speed according to the PLL configuration */ - gd->cpu_hz = get_cpu_clk_rate(); + gd->arch.cpu_hz = get_cpu_clk_rate(); /* Set up the exception handler table and enable exceptions */ sysreg_write(EVBA, (unsigned long)&_evba); diff --git a/arch/avr32/cpu/exception.c b/arch/avr32/cpu/exception.c index b21ef1f928..828fc00a49 100644 --- a/arch/avr32/cpu/exception.c +++ b/arch/avr32/cpu/exception.c @@ -112,11 +112,11 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) printf("CPU Mode: %s\n", cpu_modes[mode]); /* Avoid exception loops */ - if (regs->sp < (gd->stack_end - CONFIG_STACKSIZE) - || regs->sp >= gd->stack_end) + if (regs->sp < (gd->arch.stack_end - CONFIG_STACKSIZE) + || regs->sp >= gd->arch.stack_end) printf("\nStack pointer seems bogus, won't do stack dump\n"); else - dump_mem("\nStack: ", regs->sp, gd->stack_end); + dump_mem("\nStack: ", regs->sp, gd->arch.stack_end); panic("Unhandled exception\n"); } diff --git a/arch/avr32/cpu/interrupts.c b/arch/avr32/cpu/interrupts.c index 49a00f1c8c..d87c6e1166 100644 --- a/arch/avr32/cpu/interrupts.c +++ b/arch/avr32/cpu/interrupts.c @@ -46,7 +46,7 @@ static unsigned long tb_factor; unsigned long get_tbclk(void) { - return gd->cpu_hz; + return gd->arch.cpu_hz; } unsigned long long get_ticks(void) @@ -115,8 +115,8 @@ int timer_init(void) sysreg_write(COUNT, 0); tmp = (u64)CONFIG_SYS_HZ << 32; - tmp += gd->cpu_hz / 2; - do_div(tmp, gd->cpu_hz); + tmp += gd->arch.cpu_hz / 2; + do_div(tmp, gd->arch.cpu_hz); tb_factor = (u32)tmp; if (set_interrupt_handler(0, &timer_interrupt_handler, 3)) diff --git a/arch/avr32/include/asm/global_data.h b/arch/avr32/include/asm/global_data.h index bf661e23be..a71f199b75 100644 --- a/arch/avr32/include/asm/global_data.h +++ b/arch/avr32/include/asm/global_data.h @@ -22,35 +22,13 @@ #ifndef __ASM_GLOBAL_DATA_H__ #define __ASM_GLOBAL_DATA_H__ -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ - -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long stack_end; /* highest stack address */ - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - unsigned long reloc_off; /* Relocation Offset */ - unsigned long env_addr; /* Address of env struct */ - unsigned long env_valid; /* Checksum of env valid? */ - unsigned long cpu_hz; /* cpu core clock frequency */ -#if defined(CONFIG_LCD) - void *fb_base; /* framebuffer address */ -#endif - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { + unsigned long stack_end; /* highest stack address */ + unsigned long cpu_hz; /* cpu core clock frequency */ +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm("r5") diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index e3287c486b..d3c8cb76dd 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -231,7 +231,7 @@ void board_init_f(ulong board_type) /* And finally, a new, bigger stack. */ new_sp = (unsigned long *)addr; - gd->stack_end = addr; + gd->arch.stack_end = addr; *(--new_sp) = 0; *(--new_sp) = 0; diff --git a/arch/avr32/lib/bootm.c b/arch/avr32/lib/bootm.c index 74ebeca058..87f3f9c35d 100644 --- a/arch/avr32/lib/bootm.c +++ b/arch/avr32/lib/bootm.c @@ -109,7 +109,7 @@ static struct tag *setup_clock_tags(struct tag *params) params->hdr.size = tag_size(tag_clock); params->u.clock.clock_id = ACLOCK_BOOTCPU; params->u.clock.clock_flags = 0; - params->u.clock.clock_hz = gd->cpu_hz; + params->u.clock.clock_hz = gd->arch.cpu_hz; #ifdef CONFIG_AT32AP7000 /* diff --git a/arch/blackfin/include/asm/global_data.h b/arch/blackfin/include/asm/global_data.h index d91e5a40d3..c2c4d4d41d 100644 --- a/arch/blackfin/include/asm/global_data.h +++ b/arch/blackfin/include/asm/global_data.h @@ -30,36 +30,11 @@ #include <asm/u-boot.h> -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned long board_type; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - phys_size_t ram_size; /* RAM size */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - unsigned long post_log_word; /* Record POST activities */ - unsigned long post_log_res; /* success of POST test */ - unsigned long post_init_f_time; /* When post_init_f started */ -#endif - - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("P3") diff --git a/arch/m68k/cpu/mcf5227x/cpu.c b/arch/m68k/cpu/mcf5227x/cpu.c index 3a0ab9746b..705bd4428c 100644 --- a/arch/m68k/cpu/mcf5227x/cpu.c +++ b/arch/m68k/cpu/mcf5227x/cpu.c @@ -68,10 +68,10 @@ int checkcpu(void) printf(" CPU CLK %s MHz BUS CLK %s MHz FLB CLK %s MHz\n", strmhz(buf1, gd->cpu_clk), strmhz(buf2, gd->bus_clk), - strmhz(buf3, gd->flb_clk)); + strmhz(buf3, gd->arch.flb_clk)); printf(" INP CLK %s MHz VCO CLK %s MHz\n", - strmhz(buf1, gd->inp_clk), - strmhz(buf2, gd->vco_clk)); + strmhz(buf1, gd->arch.inp_clk), + strmhz(buf2, gd->arch.vco_clk)); } return 0; diff --git a/arch/m68k/cpu/mcf5227x/speed.c b/arch/m68k/cpu/mcf5227x/speed.c index b94a9eda48..98f554aa7f 100644 --- a/arch/m68k/cpu/mcf5227x/speed.c +++ b/arch/m68k/cpu/mcf5227x/speed.c @@ -114,28 +114,28 @@ int get_clocks(void) ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } - gd->vco_clk = vco; /* Vco clock */ + gd->arch.vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; - gd->vco_clk = vco; /* Vco clock */ + gd->arch.vco_clk = vco; /* Vco clock */ } if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { - gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ + gd->arch.inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; - gd->flb_clk = vco / temp; /* flexbus clock */ - gd->bus_clk = gd->flb_clk; + gd->arch.flb_clk = vco / temp; /* flexbus clock */ + gd->bus_clk = gd->arch.flb_clk; } #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif return (0); diff --git a/arch/m68k/cpu/mcf523x/speed.c b/arch/m68k/cpu/mcf523x/speed.c index e2a6ae3a58..ae462579e2 100644 --- a/arch/m68k/cpu/mcf523x/speed.c +++ b/arch/m68k/cpu/mcf523x/speed.c @@ -48,7 +48,7 @@ int get_clocks(void) gd->cpu_clk = (gd->bus_clk * 2); #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif return (0); diff --git a/arch/m68k/cpu/mcf52x2/speed.c b/arch/m68k/cpu/mcf52x2/speed.c index 70abed25c4..ba7dbaa1cf 100644 --- a/arch/m68k/cpu/mcf52x2/speed.c +++ b/arch/m68k/cpu/mcf52x2/speed.c @@ -91,9 +91,9 @@ int get_clocks (void) #endif #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #ifdef CONFIG_SYS_I2C2_OFFSET - gd->i2c2_clk = gd->bus_clk; + gd->arch.i2c2_clk = gd->bus_clk; #endif #endif diff --git a/arch/m68k/cpu/mcf532x/speed.c b/arch/m68k/cpu/mcf532x/speed.c index cfdcc8b807..8efb451dc1 100644 --- a/arch/m68k/cpu/mcf532x/speed.c +++ b/arch/m68k/cpu/mcf532x/speed.c @@ -271,7 +271,7 @@ int get_clocks(void) gd->cpu_clk = (gd->bus_clk * 3); #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif return (0); diff --git a/arch/m68k/cpu/mcf5445x/cpu.c b/arch/m68k/cpu/mcf5445x/cpu.c index b612cdaea1..08930f48d7 100644 --- a/arch/m68k/cpu/mcf5445x/cpu.c +++ b/arch/m68k/cpu/mcf5445x/cpu.c @@ -101,16 +101,16 @@ int checkcpu(void) printf(" CPU CLK %s MHz BUS CLK %s MHz FLB CLK %s MHz\n", strmhz(buf1, gd->cpu_clk), strmhz(buf2, gd->bus_clk), - strmhz(buf3, gd->flb_clk)); + strmhz(buf3, gd->arch.flb_clk)); #ifdef CONFIG_PCI printf(" PCI CLK %s MHz INP CLK %s MHz VCO CLK %s MHz\n", strmhz(buf1, gd->pci_clk), - strmhz(buf2, gd->inp_clk), - strmhz(buf3, gd->vco_clk)); + strmhz(buf2, gd->arch.inp_clk), + strmhz(buf3, gd->arch.vco_clk)); #else printf(" INP CLK %s MHz VCO CLK %s MHz\n", - strmhz(buf1, gd->inp_clk), - strmhz(buf2, gd->vco_clk)); + strmhz(buf1, gd->arch.inp_clk), + strmhz(buf2, gd->arch.vco_clk)); #endif } diff --git a/arch/m68k/cpu/mcf5445x/speed.c b/arch/m68k/cpu/mcf5445x/speed.c index 55d1c488a3..aa73e1f025 100644 --- a/arch/m68k/cpu/mcf5445x/speed.c +++ b/arch/m68k/cpu/mcf5445x/speed.c @@ -233,7 +233,7 @@ void setup_5445x_clocks(void) out_be32(&pll->pcr, pcrvalue); } - gd->vco_clk = vco; /* Vco clock */ + gd->arch.vco_clk = vco; /* Vco clock */ } else if (bootmode == 2) { /* Normal mode */ vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; @@ -244,17 +244,17 @@ void setup_5445x_clocks(void) out_be32(&pll->pcr, pcrvalue); vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } - gd->vco_clk = vco; /* Vco clock */ + gd->arch.vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; - gd->vco_clk = vco; /* Vco clock */ + gd->arch.vco_clk = vco; /* Vco clock */ } if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { - gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ + gd->arch.inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ @@ -263,7 +263,7 @@ void setup_5445x_clocks(void) gd->bus_clk = vco / temp; /* bus clock */ temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; - gd->flb_clk = vco / temp; /* FlexBus clock */ + gd->arch.flb_clk = vco / temp; /* FlexBus clock */ #ifdef CONFIG_PCI if (bPci) { @@ -274,7 +274,7 @@ void setup_5445x_clocks(void) } #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif } #endif @@ -290,7 +290,7 @@ int get_clocks(void) #endif #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif return (0); diff --git a/arch/m68k/cpu/mcf547x_8x/speed.c b/arch/m68k/cpu/mcf547x_8x/speed.c index 31130b5411..41aae9d9eb 100644 --- a/arch/m68k/cpu/mcf547x_8x/speed.c +++ b/arch/m68k/cpu/mcf547x_8x/speed.c @@ -41,7 +41,7 @@ int get_clocks(void) gd->cpu_clk = (gd->bus_clk * 2); #ifdef CONFIG_FSL_I2C - gd->i2c1_clk = gd->bus_clk; + gd->arch.i2c1_clk = gd->bus_clk; #endif return (0); diff --git a/arch/m68k/include/asm/global_data.h b/arch/m68k/include/asm/global_data.h index 0cdb11cf99..3ec298ff4a 100644 --- a/arch/m68k/include/asm/global_data.h +++ b/arch/m68k/include/asm/global_data.h @@ -23,52 +23,21 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long bus_clk; -#ifdef CONFIG_PCI - unsigned long pci_clk; -#endif -#ifdef CONFIG_EXTRA_CLOCK - unsigned long inp_clk; - unsigned long vco_clk; - unsigned long flb_clk; -#endif +/* Architecture-specific global data */ +struct arch_global_data { #ifdef CONFIG_FSL_I2C unsigned long i2c1_clk; unsigned long i2c2_clk; #endif - phys_size_t ram_size; /* RAM size */ - unsigned long reloc_off; /* Relocation Offset */ - unsigned long reset_status; /* reset status register at boot */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif -#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) - unsigned long fb_base; /* Base addr of framebuffer memory */ -#endif -#ifdef CONFIG_BOARD_TYPES - unsigned long board_type; +#ifdef CONFIG_EXTRA_CLOCK + unsigned long inp_clk; + unsigned long vco_clk; + unsigned long flb_clk; #endif - void **jt; /* Standalone app jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #if 0 extern gd_t *global_data; diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index e934cb6c25..c372ae228b 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -349,9 +349,9 @@ board_init_f (ulong bootflag) bd->bi_pcifreq = gd->pci_clk; /* PCI Freq in Hz */ #endif #ifdef CONFIG_EXTRA_CLOCK - bd->bi_inpfreq = gd->inp_clk; /* input Freq in Hz */ - bd->bi_vcofreq = gd->vco_clk; /* vco Freq in Hz */ - bd->bi_flbfreq = gd->flb_clk; /* flexbus Freq in Hz */ + bd->bi_inpfreq = gd->arch.inp_clk; /* input Freq in Hz */ + bd->bi_vcofreq = gd->arch.vco_clk; /* vco Freq in Hz */ + bd->bi_flbfreq = gd->arch.flb_clk; /* flexbus Freq in Hz */ #endif bd->bi_baudrate = gd->baudrate; /* Console Baudrate */ diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h index 2111c7cba2..89dcef7c7e 100644 --- a/arch/microblaze/include/asm/global_data.h +++ b/arch/microblaze/include/asm/global_data.h @@ -24,31 +24,12 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - unsigned long env_addr; /* Address of Environment struct */ - const void *fdt_blob; /* Our device tree, NULL if none */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long fb_base; /* base address of frame buffer */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r31") diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 7730695be4..8d7febd478 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -29,6 +29,7 @@ SOBJS-y += COBJS-y += board.o COBJS-y += bootm.o +COBJS-y += muldi3.o SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/microblaze/lib/muldi3.c b/arch/microblaze/lib/muldi3.c new file mode 100644 index 0000000000..76d7590917 --- /dev/null +++ b/arch/microblaze/lib/muldi3.c @@ -0,0 +1,91 @@ +/* + * U-boot - muldi3.c contains routines for mult and div + * + * + * 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 St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* Generic function got from GNU gcc package, libgcc2.c */ +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) +#define BITS_PER_UNIT 8 + +#if !defined(umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + USItype __x0, __x1, __x2, __x3; \ + USItype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart(u); \ + __uh = __ll_highpart(u); \ + __vl = __ll_lowpart(v); \ + __vh = __ll_highpart(v); \ + \ + __x0 = (USItype) __ul * __vl; \ + __x1 = (USItype) __ul * __vh; \ + __x2 = (USItype) __uh * __vl; \ + __x3 = (USItype) __uh * __vh; \ + \ + __x1 += __ll_highpart(__x0); /* this can't give carry */\ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart(__x1); \ + (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\ + } while (0) +#endif + +#if !defined(__umulsidi3) +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm(__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +typedef unsigned int USItype __attribute__ ((mode(SI))); +typedef int SItype __attribute__ ((mode(SI))); +typedef int DItype __attribute__ ((mode(DI))); +typedef int word_type __attribute__ ((mode(__word__))); + +struct DIstruct { + SItype low, high; +}; +typedef union { + struct DIstruct s; + DItype ll; +} DIunion; + +DItype __muldi3(DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, vv.ll = v; + /* panic("kernel panic for __muldi3"); */ + w.ll = __umulsidi3(uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} diff --git a/arch/mips/config.mk b/arch/mips/config.mk index de9140b67b..aaa94e8be2 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -65,4 +65,5 @@ PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) PLATFORM_CPPFLAGS += -msoft-float PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -LDFLAGS_FINAL += --gc-sections +LDFLAGS_FINAL += --gc-sections -pie +OBJCFLAGS += --remove-section=.dynsym diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index 481e9844db..7399701fe9 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -30,5 +30,11 @@ MIPSFLAGS := -march=mips32r2 PLATFORM_CPPFLAGS += $(MIPSFLAGS) +PLATFORM_CPPFLAGS += -mabi=32 -DCONFIG_32BIT +ifdef CONFIG_SYS_BIG_ENDIAN +PLATFORM_LDFLAGS += -m elf32btsmip +else +PLATFORM_LDFLAGS += -m elf32ltsmip +endif CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 9c1b2f76d0..76abbaa273 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -47,27 +47,16 @@ .set pop .endm - .macro setup_c0_status_reset -#ifdef CONFIG_64BIT - setup_c0_status ST0_KX 0 -#else - setup_c0_status 0 0 -#endif - .endm - -#define RVECENT(f,n) \ - b f; nop -#define XVECENT(f,bev) \ - b f ; \ - li k0,bev - .set noreorder .globl _start .text _start: - RVECENT(reset,0) # U-boot entry point - RVECENT(reset,1) # software reboot + /* U-boot entry point */ + b reset + nop + + .org 0x10 #ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG /* * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to @@ -77,141 +66,39 @@ _start: * device with correct parameters. This config option is board-specific. */ .word CONFIG_SYS_XWAY_EBU_BOOTCFG - .word 0x00000000 -#else - RVECENT(romReserved,2) + .word 0x0 #endif - RVECENT(romReserved,3) - RVECENT(romReserved,4) - RVECENT(romReserved,5) - RVECENT(romReserved,6) - RVECENT(romReserved,7) - RVECENT(romReserved,8) - RVECENT(romReserved,9) - RVECENT(romReserved,10) - RVECENT(romReserved,11) - RVECENT(romReserved,12) - RVECENT(romReserved,13) - RVECENT(romReserved,14) - RVECENT(romReserved,15) - RVECENT(romReserved,16) - RVECENT(romReserved,17) - RVECENT(romReserved,18) - RVECENT(romReserved,19) - RVECENT(romReserved,20) - RVECENT(romReserved,21) - RVECENT(romReserved,22) - RVECENT(romReserved,23) - RVECENT(romReserved,24) - RVECENT(romReserved,25) - RVECENT(romReserved,26) - RVECENT(romReserved,27) - RVECENT(romReserved,28) - RVECENT(romReserved,29) - RVECENT(romReserved,30) - RVECENT(romReserved,31) - RVECENT(romReserved,32) - RVECENT(romReserved,33) - RVECENT(romReserved,34) - RVECENT(romReserved,35) - RVECENT(romReserved,36) - RVECENT(romReserved,37) - RVECENT(romReserved,38) - RVECENT(romReserved,39) - RVECENT(romReserved,40) - RVECENT(romReserved,41) - RVECENT(romReserved,42) - RVECENT(romReserved,43) - RVECENT(romReserved,44) - RVECENT(romReserved,45) - RVECENT(romReserved,46) - RVECENT(romReserved,47) - RVECENT(romReserved,48) - RVECENT(romReserved,49) - RVECENT(romReserved,50) - RVECENT(romReserved,51) - RVECENT(romReserved,52) - RVECENT(romReserved,53) - RVECENT(romReserved,54) - RVECENT(romReserved,55) - RVECENT(romReserved,56) - RVECENT(romReserved,57) - RVECENT(romReserved,58) - RVECENT(romReserved,59) - RVECENT(romReserved,60) - RVECENT(romReserved,61) - RVECENT(romReserved,62) - RVECENT(romReserved,63) - XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector - RVECENT(romReserved,65) - RVECENT(romReserved,66) - RVECENT(romReserved,67) - RVECENT(romReserved,68) - RVECENT(romReserved,69) - RVECENT(romReserved,70) - RVECENT(romReserved,71) - RVECENT(romReserved,72) - RVECENT(romReserved,73) - RVECENT(romReserved,74) - RVECENT(romReserved,75) - RVECENT(romReserved,76) - RVECENT(romReserved,77) - RVECENT(romReserved,78) - RVECENT(romReserved,79) - XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector - RVECENT(romReserved,81) - RVECENT(romReserved,82) - RVECENT(romReserved,83) - RVECENT(romReserved,84) - RVECENT(romReserved,85) - RVECENT(romReserved,86) - RVECENT(romReserved,87) - RVECENT(romReserved,88) - RVECENT(romReserved,89) - RVECENT(romReserved,90) - RVECENT(romReserved,91) - RVECENT(romReserved,92) - RVECENT(romReserved,93) - RVECENT(romReserved,94) - RVECENT(romReserved,95) - XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector - RVECENT(romReserved,97) - RVECENT(romReserved,98) - RVECENT(romReserved,99) - RVECENT(romReserved,100) - RVECENT(romReserved,101) - RVECENT(romReserved,102) - RVECENT(romReserved,103) - RVECENT(romReserved,104) - RVECENT(romReserved,105) - RVECENT(romReserved,106) - RVECENT(romReserved,107) - RVECENT(romReserved,108) - RVECENT(romReserved,109) - RVECENT(romReserved,110) - RVECENT(romReserved,111) - XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector - RVECENT(romReserved,113) - RVECENT(romReserved,114) - RVECENT(romReserved,115) - RVECENT(romReserved,116) - RVECENT(romReserved,116) - RVECENT(romReserved,118) - RVECENT(romReserved,119) - RVECENT(romReserved,120) - RVECENT(romReserved,121) - RVECENT(romReserved,122) - RVECENT(romReserved,123) - RVECENT(romReserved,124) - RVECENT(romReserved,125) - RVECENT(romReserved,126) - RVECENT(romReserved,127) - /* - * We hope there are no more reserved vectors! - * 128 * 8 == 1024 == 0x400 - * so this is address R_VEC+0x400 == 0xbfc00400 - */ + .org 0x200 + /* TLB refill, 32 bit task */ +1: b 1b + nop + + .org 0x280 + /* XTLB refill, 64 bit task */ +1: b 1b + nop + + .org 0x300 + /* Cache error exception */ +1: b 1b + nop + + .org 0x380 + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b + nop + + .org 0x480 + /* EJTAG debug exception */ +1: b 1b + nop + .align 4 reset: @@ -222,7 +109,7 @@ reset: /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE - setup_c0_status_reset + setup_c0_status 0 0 /* Init Timer */ mtc0 zero, CP0_COUNT @@ -258,8 +145,7 @@ reset: #endif /* Set up temporary stack */ - li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET - la sp, 0(t0) + li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET la t9, board_init_f jr t9 @@ -280,58 +166,45 @@ reset: relocate_code: move sp, a0 # set new stack pointer + move s0, a1 # save gd in s0 + move s2, a2 # save destination address in s2 + li t0, CONFIG_SYS_MONITOR_BASE + sub s1, s2, t0 # s1 <-- relocation offset + la t3, in_ram - lw t2, -12(t3) # t2 <-- uboot_end_data + lw t2, -12(t3) # t2 <-- __image_copy_end move t1, a2 - move s2, a2 # s2 <-- destination address - /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t6, gp - sub gp, CONFIG_SYS_MONITOR_BASE - add gp, a2 # gp now adjusted - sub s1, gp, t6 # s1 <-- relocation offset + add gp, s1 # adjust gp /* * t0 = source address * t1 = target address * t2 = source end address */ - - /* - * Save destination address and size for later usage in flush_cache() - */ - move s0, a1 # save gd in s0 - move a0, t1 # a0 <-- destination addr - sub a1, t2, t0 # a1 <-- size - 1: lw t3, 0(t0) sw t3, 0(t1) addu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b addu t1, 4 /* If caches were enabled, we would have to flush them here. */ - - /* a0 & a1 are already set up for flush_cache(start, size) */ + sub a1, t1, s2 # a1 <-- size la t9, flush_cache jalr t9 - nop + move a0, s2 # a0 <-- destination address /* Jump to where we've relocated ourselves */ addi t0, s2, in_ram - _start jr t0 nop - .word _gp + .word __rel_dyn_end + .word __rel_dyn_start + .word __image_copy_end .word _GLOBAL_OFFSET_TABLE_ - .word uboot_end_data - .word uboot_end .word num_got_entries in_ram: @@ -342,10 +215,8 @@ in_ram: * generated by GNU ld. Skip these reserved entries from relocation. */ lw t3, -4(t0) # t3 <-- num_got_entries - lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ - lw t5, -20(t0) # t5 <-- _gp - sub t4, t5 # compute offset - add t4, t4, gp # t4 now holds relocated _G_O_T_ + lw t4, -8(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ + add t4, s1 # t4 now holds relocated _G_O_T_ addi t4, t4, 8 # skipping first two entries li t2, 2 1: @@ -358,17 +229,45 @@ in_ram: blt t2, t3, 1b addi t4, 4 - /* Clear BSS */ - lw t1, -12(t0) # t1 <-- uboot_end_data - lw t2, -8(t0) # t2 <-- uboot_end - add t1, s1 # adjust pointers - add t2, s1 + /* Update dynamic relocations */ + lw t1, -16(t0) # t1 <-- __rel_dyn_start + lw t2, -20(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + addi t1, 8 + +1: + lw t3, -4(t1) # t3 <-- relocation info + + sub t3, 3 + bnez t3, 2f # skip non R_MIPS_REL32 entries + nop + + lw t3, -8(t1) # t3 <-- location to fix up in FLASH + + lw t4, 0(t3) # t4 <-- original pointer + add t4, s1 # t4 <-- adjusted pointer + + add t3, s1 # t3 <-- location to fix up in RAM + sw t4, 0(t3) + +2: + blt t1, t2, 1b + addi t1, 8 # each rel.dyn entry is 8 bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + la t1, __bss_start # t1 <-- __bss_start + la t2, __bss_end # t2 <-- __bss_end - sub t1, 4 1: - addi t1, 4 - bltl t1, t2, 1b - sw zero, 0(t1) + sw zero, 0(t1) + blt t1, t2, 1b + addi t1, 4 move a0, s0 # a0 <-- gd la t9, board_init_r @@ -376,10 +275,3 @@ in_ram: move a1, s2 .end relocate_code - - /* Exception handlers */ -romReserved: - b romReserved - -romExcHandle: - b romExcHandle diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 2b8d531e73..dc7ce07ce7 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -31,6 +31,14 @@ #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #endif +#ifdef CONFIG_SYS_LITTLE_ENDIAN +#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) +#else +#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) +#endif + /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using @@ -52,40 +60,40 @@ .globl _start .text _start: - .org 0x000 + /* U-boot entry point */ b reset nop - .org 0x080 - b romReserved - nop - .org 0x100 - b romReserved - nop - .org 0x180 - b romReserved - nop + .org 0x200 - b romReserved + /* TLB refill, 32 bit task */ +1: b 1b nop + .org 0x280 - b romReserved + /* XTLB refill, 64 bit task */ +1: b 1b nop + .org 0x300 - b romReserved + /* Cache error exception */ +1: b 1b nop + .org 0x380 - b romReserved + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b nop + .org 0x480 - b romReserved + /* EJTAG debug exception */ +1: b 1b nop - /* - * We hope there are no more reserved vectors! - * 128 * 8 == 1024 == 0x400 - * so this is address R_VEC+0x400 == 0xbfc00400 - */ - .org 0x500 .align 4 reset: @@ -137,8 +145,7 @@ reset: #endif /* Set up temporary stack */ - dli t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET - dla sp, 0(t0) + dli sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET dla t9, board_init_f jr t9 @@ -159,58 +166,45 @@ reset: relocate_code: move sp, a0 # set new stack pointer + move s0, a1 # save gd in s0 + move s2, a2 # save destination address in s2 + dli t0, CONFIG_SYS_MONITOR_BASE + dsub s1, s2, t0 # s1 <-- relocation offset + dla t3, in_ram - ld t2, -24(t3) # t2 <-- uboot_end_data + ld t2, -24(t3) # t2 <-- __image_copy_end move t1, a2 - move s2, a2 # s2 <-- destination address - /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t8, gp - dsub gp, CONFIG_SYS_MONITOR_BASE - dadd gp, a2 # gp now adjusted - dsub s1, gp, t8 # s1 <-- relocation offset + dadd gp, s1 # adjust gp /* * t0 = source address * t1 = target address * t2 = source end address */ - - /* - * Save destination address and size for dlater usage in flush_cache() - */ - move s0, a1 # save gd in s0 - move a0, t1 # a0 <-- destination addr - dsub a1, t2, t0 # a1 <-- size - 1: lw t3, 0(t0) sw t3, 0(t1) daddu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b daddu t1, 4 /* If caches were enabled, we would have to flush them here. */ - - /* a0 & a1 are already set up for flush_cache(start, size) */ + dsub a1, t1, s2 # a1 <-- size dla t9, flush_cache jalr t9 - nop + move a0, s2 # a0 <-- destination address /* Jump to where we've relocated ourselves */ daddi t0, s2, in_ram - _start jr t0 nop - .dword _gp + .dword __rel_dyn_end + .dword __rel_dyn_start + .dword __image_copy_end .dword _GLOBAL_OFFSET_TABLE_ - .dword uboot_end_data - .dword uboot_end .dword num_got_entries in_ram: @@ -221,10 +215,8 @@ in_ram: * generated by GNU ld. Skip these reserved entries from relocation. */ ld t3, -8(t0) # t3 <-- num_got_entries - ld t8, -32(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ - ld t9, -40(t0) # t9 <-- _gp - dsub t8, t9 # compute offset - dadd t8, t8, gp # t8 now holds relocated _G_O_T_ + ld t8, -16(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + dadd t8, s1 # t8 now holds relocated _G_O_T_ daddi t8, t8, 16 # skipping first two entries dli t2, 2 1: @@ -237,17 +229,45 @@ in_ram: blt t2, t3, 1b daddi t8, 8 - /* Clear BSS */ - ld t1, -24(t0) # t1 <-- uboot_end_data - ld t2, -16(t0) # t2 <-- uboot_end - dadd t1, s1 # adjust pointers - dadd t2, s1 + /* Update dynamic relocations */ + ld t1, -32(t0) # t1 <-- __rel_dyn_start + ld t2, -40(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + daddi t1, 16 - dsub t1, 8 1: - daddi t1, 8 - bltl t1, t2, 1b - sd zero, 0(t1) + lw t8, -4(t1) # t8 <-- relocation info + + dli t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) + bne t8, t3, 2f # skip non R_MIPS_REL32 entries + nop + + ld t3, -16(t1) # t3 <-- location to fix up in FLASH + + ld t8, 0(t3) # t8 <-- original pointer + dadd t8, s1 # t8 <-- adjusted pointer + + dadd t3, s1 # t3 <-- location to fix up in RAM + sd t8, 0(t3) + +2: + blt t1, t2, 1b + daddi t1, 16 # each rel.dyn entry is 16 bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + dla t1, __bss_start # t1 <-- __bss_start + dla t2, __bss_end # t2 <-- __bss_end + +1: + sd zero, 0(t1) + blt t1, t2, 1b + daddi t1, 8 move a0, s0 # a0 <-- gd dla t9, board_init_r @@ -255,7 +275,3 @@ in_ram: move a1, s2 .end relocate_code - - /* Exception handlers */ -romReserved: - b romReserved diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds new file mode 100644 index 0000000000..10513abd2c --- /dev/null +++ b/arch/mips/cpu/u-boot.lds @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#if defined(CONFIG_64BIT) +#define PTR_COUNT_SHIFT 3 +#else +#define PTR_COUNT_SHIFT 2 +#endif + +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : { + *(.text*) + } + + . = ALIGN(4); + .rodata : { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = .; + _gp = ALIGN(16) + 0x7ff0; + + .got : { + *(.got) + } + + num_got_entries = SIZEOF(.got) >> PTR_COUNT_SHIFT; + + . = ALIGN(4); + .sdata : { + *(.sdata*) + } + + . = ALIGN(4); + .u_boot_list : { + #include <u-boot.lst> + } + + . = ALIGN(4); + __image_copy_end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel.dyn) + __rel_dyn_end = .; + } + + .deadcode : { + /* + * Workaround for a binutils feature (or bug?). + * + * The GNU ld from binutils puts the dynamic relocation + * entries into the .rel.dyn section. Sometimes it + * allocates more dynamic relocation entries than it needs + * and the unused slots are set to R_MIPS_NONE entries. + * + * However the size of the .rel.dyn section in the ELF + * section header does not cover the unused entries, so + * objcopy removes those during stripping. + * + * Create a small section here to avoid that. + */ + LONG(0xffffffff); + } + + .dynsym : { + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.sbss.*) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } + + /DISCARD/ : { + *(.dynbss) + *(.dynstr) + *(.dynamic) + *(.interp) + *(.hash) + *(.gnu.*) + *(.plt) + *(.got.plt) + *(.rel.plt) + } +} diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk index 1536746c97..cf5fa6ab6b 100644 --- a/arch/mips/cpu/xburst/config.mk +++ b/arch/mips/cpu/xburst/config.mk @@ -21,5 +21,11 @@ # PLATFORM_CPPFLAGS += -march=mips32 +PLATFORM_CPPFLAGS += -mabi=32 -DCONFIG_32BIT +ifdef CONFIG_SYS_BIG_ENDIAN +PLATFORM_LDFLAGS += -m elf32btsmip +else +PLATFORM_LDFLAGS += -m elf32ltsmip +endif CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c index c0b9817ab9..b2d8f4d20d 100644 --- a/arch/mips/cpu/xburst/jz4740.c +++ b/arch/mips/cpu/xburst/jz4740.c @@ -201,10 +201,10 @@ void calc_clocks(void) pllout = __cpm_get_pllout(); gd->cpu_clk = pllout / div[__cpm_get_cdiv()]; - gd->sys_clk = pllout / div[__cpm_get_hdiv()]; - gd->per_clk = pllout / div[__cpm_get_pdiv()]; + gd->arch.sys_clk = pllout / div[__cpm_get_hdiv()]; + gd->arch.per_clk = pllout / div[__cpm_get_pdiv()]; gd->mem_clk = pllout / div[__cpm_get_mdiv()]; - gd->dev_clk = CONFIG_SYS_EXTAL; + gd->arch.dev_clk = CONFIG_SYS_EXTAL; } void rtc_init(void) diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S index 3a8280cb0a..d2c064b017 100644 --- a/arch/mips/cpu/xburst/start.S +++ b/arch/mips/cpu/xburst/start.S @@ -64,19 +64,13 @@ relocate_code: move sp, a0 # set new stack pointer li t0, CONFIG_SYS_MONITOR_BASE + sub t6, a2, t0 # t6 <-- relocation offset + la t3, in_ram - lw t2, -12(t3) # t2 <-- uboot_end_data + lw t2, -12(t3) # t2 <-- __image_copy_end move t1, a2 - /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t6, gp - sub gp, CONFIG_SYS_MONITOR_BASE - add gp, a2 # gp now adjusted - sub t6, gp, t6 # t6 <-- relocation offset + add gp, t6 # adjust gp /* * t0 = source address @@ -87,7 +81,7 @@ relocate_code: lw t3, 0(t0) sw t3, 0(t1) addu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b addu t1, 4 /* If caches were enabled, we would have to flush them here. */ @@ -122,10 +116,10 @@ relocate_code: jr t0 nop - .word _gp + .word __rel_dyn_end + .word __rel_dyn_start + .word __image_copy_end .word _GLOBAL_OFFSET_TABLE_ - .word uboot_end_data - .word uboot_end .word num_got_entries in_ram: @@ -136,10 +130,8 @@ in_ram: * generated by GNU ld. Skip these reserved entries from relocation. */ lw t3, -4(t0) # t3 <-- num_got_entries - lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ - lw t5, -20(t0) # t5 <-- _gp - sub t4, t5 # compute offset - add t4, t4, gp # t4 now holds relocated _G_O_T_ + lw t4, -8(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ + add t4, t6 # t4 now holds relocated _G_O_T_ addi t4, t4, 8 # skipping first two entries li t2, 2 1: @@ -152,16 +144,45 @@ in_ram: blt t2, t3, 1b addi t4, 4 - /* Clear BSS */ - lw t1, -12(t0) # t1 <-- uboot_end_data - lw t2, -8(t0) # t2 <-- uboot_end - add t1, t6 # adjust pointers - add t2, t6 + /* Update dynamic relocations */ + lw t1, -16(t0) # t1 <-- __rel_dyn_start + lw t2, -20(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + addi t1, 8 + +1: + lw t3, -4(t1) # t3 <-- relocation info + + sub t3, 3 + bnez t3, 2f # skip non R_MIPS_REL32 entries + nop + + lw t3, -8(t1) # t3 <-- location to fix up in FLASH + + lw t4, 0(t3) # t4 <-- original pointer + add t4, t6 # t4 <-- adjusted pointer + + add t3, t6 # t3 <-- location to fix up in RAM + sw t4, 0(t3) + +2: + blt t1, t2, 1b + addi t1, 8 # each rel.dyn entry is 8 bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + la t1, __bss_start # t1 <-- __bss_start + la t2, __bss_end # t2 <-- __bss_end - sub t1, 4 -1: addi t1, 4 - bltl t1, t2, 1b - sw zero, 0(t1) +1: + sw zero, 0(t1) + blt t1, t2, 1b + addi t1, 4 move a0, a1 # a0 <-- gd la t9, board_init_r diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c index b6b3855ea1..8c33d3ca3c 100644 --- a/arch/mips/cpu/xburst/timer.c +++ b/arch/mips/cpu/xburst/timer.c @@ -34,24 +34,24 @@ static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE; void reset_timer_masked(void) { /* reset time */ - gd->lastinc = readl(&tcu->tcnt0); - gd->tbl = 0; + gd->arch.lastinc = readl(&tcu->tcnt0); + gd->arch.tbl = 0; } ulong get_timer_masked(void) { ulong now = readl(&tcu->tcnt0); - if (gd->lastinc <= now) - gd->tbl += now - gd->lastinc; /* normal mode */ + if (gd->arch.lastinc <= now) + gd->arch.tbl += now - gd->arch.lastinc; /* normal mode */ else { /* we have an overflow ... */ - gd->tbl += TIMER_FDATA + now - gd->lastinc; + gd->arch.tbl += TIMER_FDATA + now - gd->arch.lastinc; } - gd->lastinc = now; + gd->arch.lastinc = now; - return gd->tbl; + return gd->arch.tbl; } void udelay_masked(unsigned long usec) @@ -94,8 +94,8 @@ int timer_init(void) writel(1 << TIMER_CHAN, &tcu->tscr); /* enable timer clock */ writeb(1 << TIMER_CHAN, &tcu->tesr); /* start counting up */ - gd->lastinc = 0; - gd->tbl = 0; + gd->arch.lastinc = 0; + gd->arch.tbl = 0; return 0; } @@ -112,7 +112,7 @@ ulong get_timer(ulong base) void set_timer(ulong t) { - gd->tbl = t; + gd->arch.tbl = t; } void __udelay(unsigned long usec) diff --git a/arch/mips/include/asm/config.h b/arch/mips/include/asm/config.h index 02fbfb3abf..049c44eaf8 100644 --- a/arch/mips/include/asm/config.h +++ b/arch/mips/include/asm/config.h @@ -21,6 +21,4 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ -#define CONFIG_NEEDS_MANUAL_RELOC - #endif diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h index a735a8a2c7..f912428cae 100644 --- a/arch/mips/include/asm/global_data.h +++ b/arch/mips/include/asm/global_data.h @@ -26,42 +26,19 @@ #include <asm/regdef.h> -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ - -typedef struct global_data { - bd_t *bd; - unsigned long flags; +/* Architecture-specific global data */ +struct arch_global_data { #ifdef CONFIG_JZSOC /* There are other clocks in the jz4740 */ - unsigned long cpu_clk; /* CPU core clock */ - unsigned long sys_clk; /* System bus clock */ - unsigned long per_clk; /* Peripheral bus clock */ - unsigned long mem_clk; /* Memory bus clock */ - unsigned long dev_clk; /* Device clock */ - /* "static data" needed by most of timer.c */ - unsigned long tbl; - unsigned long lastinc; -#endif - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ + unsigned long per_clk; /* Peripheral bus clock */ + unsigned long dev_clk; /* Device clock */ + unsigned long sys_clk; + unsigned long tbl; + unsigned long lastinc; #endif - phys_size_t ram_size; /* RAM size */ - unsigned long reloc_off; /* Relocation Offset */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("k0") diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 80eab75e15..3864c804c0 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -254,7 +254,7 @@ out: */ #define __OUT1(s) \ -extern inline void __out##s(unsigned int value, unsigned int port) { +static inline void __out##s(unsigned int value, unsigned int port) { #define __OUT2(m) \ __asm__ __volatile__ ("s" #m "\t%0,%1(%2)" @@ -268,7 +268,7 @@ __OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io SLOW_DOWN_IO; } #define __IN1(t,s) \ -extern __inline__ t __in##s(unsigned int port) { t _v; +static inline t __in##s(unsigned int port) { t _v; /* * Required nops will be inserted by the assembler @@ -283,7 +283,7 @@ __IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SL __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); } #define __INS1(s) \ -extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { +static inline void __ins##s(unsigned int port, void * addr, unsigned long count) { #define __INS2(m) \ if (count) \ @@ -311,7 +311,7 @@ __INS1(s##c) __INS2(m) \ : "$1");} #define __OUTS1(s) \ -extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { +static inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { #define __OUTS2(m) \ if (count) \ diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h index 6f26dfac56..a483166a9c 100644 --- a/arch/mips/include/asm/u-boot-mips.h +++ b/arch/mips/include/asm/u-boot-mips.h @@ -5,7 +5,22 @@ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de */ -extern ulong uboot_end_data; -extern ulong uboot_end; +static inline unsigned long bss_start(void) +{ + extern ulong __bss_start; + return (unsigned long) &__bss_start; +} + +static inline unsigned long bss_end(void) +{ + extern ulong __bss_end; + return (unsigned long) &__bss_end; +} + +static inline unsigned long image_copy_end(void) +{ + extern ulong __image_copy_end; + return (unsigned long) &__image_copy_end; +} extern int incaip_set_cpuclk(void); diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index d79e1837d9..f19f198ae9 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -143,7 +143,7 @@ void board_init_f(ulong bootflag) gd_t gd_data, *id; bd_t *bd; init_fnc_t **init_fnc_ptr; - ulong addr, addr_sp, len = (ulong)&uboot_end - CONFIG_SYS_MONITOR_BASE; + ulong addr, addr_sp, len; ulong *s; /* Pointer is writable since we allocated a register for it. @@ -176,6 +176,7 @@ void board_init_f(ulong bootflag) /* Reserve memory for U-Boot code, data & bss * round down to next 16 kB limit */ + len = bss_end() - CONFIG_SYS_MONITOR_BASE; addr -= len; addr &= ~(16 * 1024 - 1); @@ -249,9 +250,6 @@ void board_init_r(gd_t *id, ulong dest_addr) #ifndef CONFIG_SYS_NO_FLASH ulong size; #endif -#ifndef CONFIG_ENV_IS_NOWHERE - extern char *env_name_spec; -#endif bd_t *bd; gd = id; @@ -261,29 +259,15 @@ void board_init_r(gd_t *id, ulong dest_addr) gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE; - monitor_flash_len = (ulong)&uboot_end_data - dest_addr; + monitor_flash_len = image_copy_end() - dest_addr; serial_initialize(); -#if defined(CONFIG_NEEDS_MANUAL_RELOC) - /* - * We have to relocate the command table manually - */ - fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd), - ll_entry_count(cmd_tbl_t, cmd)); -#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */ - - /* there are some other pointer constants we must deal with */ -#ifndef CONFIG_ENV_IS_NOWHERE - env_name_spec += gd->reloc_off; -#endif - bd = gd->bd; /* The Malloc area is immediately below the monitor copy in DRAM */ mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off - TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); - malloc_bin_reloc(); #ifndef CONFIG_SYS_NO_FLASH /* configure available FLASH banks */ diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 608c1a78db..a36154a892 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -43,27 +43,12 @@ static int linux_env_idx; static void linux_params_init(ulong start, char *commandline); static void linux_env_set(char *env_name, char *env_val); -int do_bootm_linux(int flag, int argc, char * const argv[], - bootm_headers_t *images) +static void boot_prep_linux(bootm_headers_t *images) { - void (*theKernel) (int, char **, char **, int *); char *commandline = getenv("bootargs"); char env_buf[12]; char *cp; - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - /* find kernel entry point */ - theKernel = (void (*)(int, char **, char **, int *))images->ep; - - bootstage_mark(BOOTSTAGE_ID_RUN_OS); - -#ifdef DEBUG - printf("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); -#endif - linux_params_init(UNCACHED_SDRAM(gd->bd->bi_boot_params), commandline); #ifdef CONFIG_MEMSIZE_IN_BYTES @@ -96,11 +81,45 @@ int do_bootm_linux(int flag, int argc, char * const argv[], cp = getenv("eth1addr"); if (cp) linux_env_set("eth1addr", cp); +} + +static void boot_jump_linux(bootm_headers_t *images) +{ + void (*theKernel) (int, char **, char **, int *); + + /* find kernel entry point */ + theKernel = (void (*)(int, char **, char **, int *))images->ep; + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); + + bootstage_mark(BOOTSTAGE_ID_RUN_OS); /* we assume that the kernel is in place */ printf("\nStarting kernel ...\n\n"); theKernel(linux_argc, linux_argv, linux_env, 0); +} + +int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + /* No need for those on MIPS */ + if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & BOOTM_STATE_OS_GO) { + boot_jump_linux(images); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images); /* does not return */ return 1; diff --git a/arch/nds32/include/asm/global_data.h b/arch/nds32/include/asm/global_data.h index b1feb2c0d0..4927d5254b 100644 --- a/arch/nds32/include/asm/global_data.h +++ b/arch/nds32/include/asm/global_data.h @@ -33,39 +33,12 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ - -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ - - unsigned long reloc_off; /* Relocation Offset */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long fb_base; /* base address of frame buffer */ - - unsigned long relocaddr; /* Start address of U-Boot in RAM */ - phys_size_t ram_size; /* RAM size */ - unsigned long mon_len; /* monitor len */ - unsigned long irq_sp; /* irq stack pointer */ - unsigned long start_addr_sp; /* start_addr_stackpointer */ -#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) - unsigned long tlb_addr; -#endif - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #ifdef CONFIG_GLOBAL_DATA_NOT_REG10 extern volatile gd_t g_gd; diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index 91395cabf3..09feaf3733 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -207,17 +207,6 @@ void board_init_f(ulong bootflag) addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; -#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) - /* reserve TLB table */ - addr -= (4096 * 4); - - /* round down to next 64 kB limit */ - addr &= ~(0x10000 - 1); - - gd->tlb_addr = addr; - debug("TLB table at: %08lx\n", addr); -#endif - /* round down to next 4 kB limit */ addr &= ~(4096 - 1); debug("Top of RAM usable for U-Boot at: %08lx\n", addr); diff --git a/arch/nios2/cpu/fdt.c b/arch/nios2/cpu/fdt.c index b1ed9e17f2..f238665915 100644 --- a/arch/nios2/cpu/fdt.c +++ b/arch/nios2/cpu/fdt.c @@ -30,7 +30,6 @@ #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) #include <libfdt.h> -#include <libfdt_env.h> #include <fdt_support.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/nios2/include/asm/global_data.h b/arch/nios2/include/asm/global_data.h index 413b485b61..39c570023b 100644 --- a/arch/nios2/include/asm/global_data.h +++ b/arch/nios2/include/asm/global_data.h @@ -23,28 +23,11 @@ #ifndef __ASM_NIOS2_GLOBALDATA_H_ #define __ASM_NIOS2_GLOBALDATA_H_ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - phys_size_t ram_size; /* RAM size */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid */ -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - unsigned long post_log_word; /* Record POST activities */ - unsigned long post_log_res; /* success of POST test */ - unsigned long post_init_f_time; /* When post_init_f started */ -#endif - void **jt; /* Standalone app jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp") diff --git a/arch/openrisc/include/asm/global_data.h b/arch/openrisc/include/asm/global_data.h index 96f3f1cdbb..d267ccd652 100644 --- a/arch/openrisc/include/asm/global_data.h +++ b/arch/openrisc/include/asm/global_data.h @@ -24,29 +24,12 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long have_console; /* serial_init() was called */ - phys_size_t ram_size; /* RAM size */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long fb_base; /* base address of frame buffer */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> /* OR32 GCC already has r10 set as fixed-use */ #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r10") diff --git a/arch/powerpc/cpu/mpc512x/cpu.c b/arch/powerpc/cpu/mpc512x/cpu.c index a1a3bd4adf..bb03c6d885 100644 --- a/arch/powerpc/cpu/mpc512x/cpu.c +++ b/arch/powerpc/cpu/mpc512x/cpu.c @@ -68,8 +68,8 @@ int checkcpu (void) } printf ("at %s MHz, CSB at %s MHz (RSR=0x%04lx)\n", strmhz(buf1, clock), - strmhz(buf2, gd->csb_clk), - gd->reset_status & 0xffff); + strmhz(buf2, gd->arch.csb_clk), + gd->arch.reset_status & 0xffff); return 0; } diff --git a/arch/powerpc/cpu/mpc512x/cpu_init.c b/arch/powerpc/cpu/mpc512x/cpu_init.c index fe6beaf84d..32ade1b0b9 100644 --- a/arch/powerpc/cpu/mpc512x/cpu_init.c +++ b/arch/powerpc/cpu/mpc512x/cpu_init.c @@ -62,7 +62,7 @@ void cpu_init_f (volatile immap_t * im) #endif /* RSR - Reset Status Register - clear all status */ - gd->reset_status = im->reset.rsr; + gd->arch.reset_status = im->reset.rsr; out_be32(&im->reset.rsr, ~RSR_RES); /* diff --git a/arch/powerpc/cpu/mpc512x/i2c.c b/arch/powerpc/cpu/mpc512x/i2c.c index 0ea12806b9..59040f83c9 100644 --- a/arch/powerpc/cpu/mpc512x/i2c.c +++ b/arch/powerpc/cpu/mpc512x/i2c.c @@ -250,7 +250,7 @@ static int mpc_get_fdr (int speed) {126, 128} }; - ips = gd->ips_clk; + ips = gd->arch.ips_clk; for (i = 7; i >= 0; i--) { for (j = 7; j >= 0; j--) { scl = 2 * (scltap[j].scl2tap + diff --git a/arch/powerpc/cpu/mpc512x/ide.c b/arch/powerpc/cpu/mpc512x/ide.c index dd6b2f4673..7a496734e7 100644 --- a/arch/powerpc/cpu/mpc512x/ide.c +++ b/arch/powerpc/cpu/mpc512x/ide.c @@ -100,7 +100,7 @@ int ide_preinit (void) ide_set_reset(0); /* Init timings : we use PIO mode 0 timings */ - t = 1000000000 / gd->ips_clk; /* period in ns */ + t = 1000000000 / gd->arch.ips_clk; /* period in ns */ cfg.bytes.field1 = 3; cfg.bytes.field2 = 3; cfg.bytes.field3 = (pio_specs.t1 + t) / t; diff --git a/arch/powerpc/cpu/mpc512x/serial.c b/arch/powerpc/cpu/mpc512x/serial.c index 58587fd5bc..3afbe81018 100644 --- a/arch/powerpc/cpu/mpc512x/serial.c +++ b/arch/powerpc/cpu/mpc512x/serial.c @@ -140,7 +140,7 @@ void serial_setbrg_dev(unsigned int idx) } /* calculate divisor for setting PSC CTUR and CTLR registers */ - baseclk = (gd->ips_clk + 8) / 16; + baseclk = (gd->arch.ips_clk + 8) / 16; div = (baseclk + (baudrate / 2)) / baudrate; out_8(&psc->ctur, (div >> 8) & 0xff); diff --git a/arch/powerpc/cpu/mpc512x/speed.c b/arch/powerpc/cpu/mpc512x/speed.c index 9d749f22e4..9a8f315d82 100644 --- a/arch/powerpc/cpu/mpc512x/speed.c +++ b/arch/powerpc/cpu/mpc512x/speed.c @@ -113,9 +113,9 @@ int get_clocks (void) pci_clk = 333333; } - gd->ips_clk = ips_clk; + gd->arch.ips_clk = ips_clk; gd->pci_clk = pci_clk; - gd->csb_clk = csb_clk; + gd->arch.csb_clk = csb_clk; gd->cpu_clk = core_clk; gd->bus_clk = csb_clk; return 0; @@ -128,7 +128,7 @@ int get_clocks (void) *********************************************/ ulong get_bus_freq (ulong dummy) { - return gd->csb_clk; + return gd->arch.csb_clk; } int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) @@ -137,10 +137,13 @@ int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) printf("Clock configuration:\n"); printf(" CPU: %-4s MHz\n", strmhz(buf, gd->cpu_clk)); - printf(" Coherent System Bus: %-4s MHz\n", strmhz(buf, gd->csb_clk)); - printf(" IPS Bus: %-4s MHz\n", strmhz(buf, gd->ips_clk)); + printf(" Coherent System Bus: %-4s MHz\n", + strmhz(buf, gd->arch.csb_clk)); + printf(" IPS Bus: %-4s MHz\n", + strmhz(buf, gd->arch.ips_clk)); printf(" PCI: %-4s MHz\n", strmhz(buf, gd->pci_clk)); - printf(" DDR: %-4s MHz\n", strmhz(buf, 2*gd->csb_clk)); + printf(" DDR: %-4s MHz\n", + strmhz(buf, 2 * gd->arch.csb_clk)); return 0; } diff --git a/arch/powerpc/cpu/mpc5xxx/cpu.c b/arch/powerpc/cpu/mpc5xxx/cpu.c index 0c1eebd4ee..dc021e35f5 100644 --- a/arch/powerpc/cpu/mpc5xxx/cpu.c +++ b/arch/powerpc/cpu/mpc5xxx/cpu.c @@ -36,7 +36,6 @@ #if defined(CONFIG_OF_LIBFDT) #include <libfdt.h> -#include <libfdt_env.h> #include <fdt_support.h> #endif diff --git a/arch/powerpc/cpu/mpc5xxx/i2c.c b/arch/powerpc/cpu/mpc5xxx/i2c.c index b423d2fe34..8d5f47b1bb 100644 --- a/arch/powerpc/cpu/mpc5xxx/i2c.c +++ b/arch/powerpc/cpu/mpc5xxx/i2c.c @@ -310,7 +310,7 @@ static int mpc_get_fdr(int speed) {126, 128} }; - ipb = gd->ipb_clk; + ipb = gd->arch.ipb_clk; for (i = 7; i >= 0; i--) { for (j = 7; j >= 0; j--) { scl = 2 * (scltap[j].scl2tap + diff --git a/arch/powerpc/cpu/mpc5xxx/ide.c b/arch/powerpc/cpu/mpc5xxx/ide.c index d337abb1c9..094f62b6ba 100644 --- a/arch/powerpc/cpu/mpc5xxx/ide.c +++ b/arch/powerpc/cpu/mpc5xxx/ide.c @@ -75,7 +75,7 @@ int ide_preinit (void) psdma->PtdCntrl |= 1; /* Init timings : we use PIO mode 0 timings */ - period = 1000000000 / gd->ipb_clk; /* period in ns */ + period = 1000000000 / gd->arch.ipb_clk; /* period in ns */ t0 = CALC_TIMING (600); t2_8 = CALC_TIMING (290); diff --git a/arch/powerpc/cpu/mpc5xxx/serial.c b/arch/powerpc/cpu/mpc5xxx/serial.c index eb141619b8..1ccb4e35de 100644 --- a/arch/powerpc/cpu/mpc5xxx/serial.c +++ b/arch/powerpc/cpu/mpc5xxx/serial.c @@ -89,7 +89,7 @@ int serial_init_dev (unsigned long dev_base) /* select clock sources */ psc->psc_clock_select = 0; - baseclk = (gd->ipb_clk + 16) / 32; + baseclk = (gd->arch.ipb_clk + 16) / 32; /* switch to UART mode */ psc->sicr = 0; @@ -169,7 +169,7 @@ void serial_setbrg_dev (unsigned long dev_base) volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; unsigned long baseclk, div; - baseclk = (gd->ipb_clk + 16) / 32; + baseclk = (gd->arch.ipb_clk + 16) / 32; /* set up UART divisor */ div = (baseclk + (gd->baudrate/2)) / gd->baudrate; diff --git a/arch/powerpc/cpu/mpc5xxx/speed.c b/arch/powerpc/cpu/mpc5xxx/speed.c index 8027d3e08a..5353e3d535 100644 --- a/arch/powerpc/cpu/mpc5xxx/speed.c +++ b/arch/powerpc/cpu/mpc5xxx/speed.c @@ -66,14 +66,20 @@ int get_clocks (void) val = *(vu_long *)MPC5XXX_CDM_CFG; if (val & (1 << 8)) { - gd->ipb_clk = gd->bus_clk / 2; + gd->arch.ipb_clk = gd->bus_clk / 2; } else { - gd->ipb_clk = gd->bus_clk; + gd->arch.ipb_clk = gd->bus_clk; } switch (val & 3) { - case 0: gd->pci_clk = gd->ipb_clk; break; - case 1: gd->pci_clk = gd->ipb_clk / 2; break; - default: gd->pci_clk = gd->bus_clk / 4; break; + case 0: + gd->pci_clk = gd->arch.ipb_clk; + break; + case 1: + gd->pci_clk = gd->arch.ipb_clk / 2; + break; + default: + gd->pci_clk = gd->bus_clk / 4; + break; } return (0); @@ -85,7 +91,7 @@ int prt_mpc5xxx_clks (void) printf (" Bus %s MHz, IPB %s MHz, PCI %s MHz\n", strmhz(buf1, gd->bus_clk), - strmhz(buf2, gd->ipb_clk), + strmhz(buf2, gd->arch.ipb_clk), strmhz(buf3, gd->pci_clk) ); return (0); diff --git a/arch/powerpc/cpu/mpc8220/fec.c b/arch/powerpc/cpu/mpc8220/fec.c index aaf9be107a..43fa802ca9 100644 --- a/arch/powerpc/cpu/mpc8220/fec.c +++ b/arch/powerpc/cpu/mpc8220/fec.c @@ -288,9 +288,11 @@ static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis) * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock * and do not drop the Preamble. */ - /* tbd - rtm */ - /*fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); */ - /* No MII for 7-wire mode */ + /* + * tbd - rtm + * fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1); + * No MII for 7-wire mode + */ fec->eth->mii_speed = 0x00000030; } diff --git a/arch/powerpc/cpu/mpc8220/speed.c b/arch/powerpc/cpu/mpc8220/speed.c index 62ac845b7a..bb72e5ce12 100644 --- a/arch/powerpc/cpu/mpc8220/speed.c +++ b/arch/powerpc/cpu/mpc8220/speed.c @@ -71,7 +71,7 @@ int get_clocks (void) #error clock measuring not implemented yet - define CONFIG_SYS_MPC8220_CLKIN #endif - gd->inp_clk = CONFIG_SYS_MPC8220_CLKIN; + gd->arch.inp_clk = CONFIG_SYS_MPC8220_CLKIN; /* Read XLB to PCI(INP) clock multiplier */ pci2bus = (*((volatile u32 *)PCI_REG_PCIGSCR) & @@ -85,7 +85,7 @@ int get_clocks (void) /* FlexBus is temporary set as the same as input clock */ /* will do dynamic in the future */ - gd->flb_clk = CONFIG_SYS_MPC8220_CLKIN; + gd->arch.flb_clk = CONFIG_SYS_MPC8220_CLKIN; /* CPU Clock - Read HID1 */ asm volatile ("mfspr %0, 1009":"=r" (hid1):); @@ -97,12 +97,14 @@ int get_clocks (void) for (i = 0; i < size; i++) if (hid1 == bus2core[i].hid1) { gd->cpu_clk = (bus2core[i].multi * gd->bus_clk) >> 1; - gd->vco_clk = CONFIG_SYS_MPC8220_SYSPLL_VCO_MULTIPLIER * (gd->pci_clk * bus2core[i].vco_div)/2; + gd->arch.vco_clk = + CONFIG_SYS_MPC8220_SYSPLL_VCO_MULTIPLIER * + (gd->pci_clk * bus2core[i].vco_div) / 2; break; } /* hardcoded 81MHz for now */ - gd->pev_clk = 81000000; + gd->arch.pev_clk = 81000000; return (0); } @@ -115,7 +117,7 @@ int prt_mpc8220_clks (void) strmhz(buf1, gd->bus_clk), strmhz(buf2, gd->cpu_clk), strmhz(buf3, gd->pci_clk), - strmhz(buf4, gd->vco_clk) + strmhz(buf4, gd->arch.vco_clk) ); return (0); } diff --git a/arch/powerpc/cpu/mpc8260/commproc.c b/arch/powerpc/cpu/mpc8260/commproc.c index 082957ee08..22cef3e983 100644 --- a/arch/powerpc/cpu/mpc8260/commproc.c +++ b/arch/powerpc/cpu/mpc8260/commproc.c @@ -30,8 +30,8 @@ m8260_cpm_reset(void) /* Reclaim the DP memory for our use. */ - gd->dp_alloc_base = CPM_DATAONLY_BASE; - gd->dp_alloc_top = gd->dp_alloc_base + CPM_DATAONLY_SIZE; + gd->arch.dp_alloc_base = CPM_DATAONLY_BASE; + gd->arch.dp_alloc_top = gd->arch.dp_alloc_base + CPM_DATAONLY_SIZE; /* * Reset CPM @@ -60,21 +60,22 @@ m8260_cpm_dpalloc(uint size, uint align) uint savebase; align_mask = align - 1; - savebase = gd->dp_alloc_base; + savebase = gd->arch.dp_alloc_base; - if ((off = (gd->dp_alloc_base & align_mask)) != 0) - gd->dp_alloc_base += (align - off); + off = gd->arch.dp_alloc_base & align_mask; + if (off != 0) + gd->arch.dp_alloc_base += (align - off); if ((off = size & align_mask) != 0) size += align - off; - if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) { - gd->dp_alloc_base = savebase; + if ((gd->arch.dp_alloc_base + size) >= gd->arch.dp_alloc_top) { + gd->arch.dp_alloc_base = savebase; panic("m8260_cpm_dpalloc: ran out of dual port ram!"); } - retloc = gd->dp_alloc_base; - gd->dp_alloc_base += size; + retloc = gd->arch.dp_alloc_base; + gd->arch.dp_alloc_base += size; memset((void *)&immr->im_dprambase[retloc], 0, size); @@ -101,7 +102,7 @@ m8260_cpm_hostalloc(uint size, uint align) * Baud rate clocks are zero-based in the driver code (as that maps * to port numbers). Documentation uses 1-based numbering. */ -#define BRG_INT_CLK gd->brg_clk +#define BRG_INT_CLK gd->arch.brg_clk #define BRG_UART_CLK (BRG_INT_CLK / 16) /* This function is used by UARTs, or anything else that uses a 16x diff --git a/arch/powerpc/cpu/mpc8260/cpu.c b/arch/powerpc/cpu/mpc8260/cpu.c index 220c1e24b1..f8bc5a9834 100644 --- a/arch/powerpc/cpu/mpc8260/cpu.c +++ b/arch/powerpc/cpu/mpc8260/cpu.c @@ -50,7 +50,6 @@ #if defined(CONFIG_OF_LIBFDT) #include <libfdt.h> -#include <libfdt_env.h> #include <fdt_support.h> #endif diff --git a/arch/powerpc/cpu/mpc8260/cpu_init.c b/arch/powerpc/cpu/mpc8260/cpu_init.c index acd48a9f55..3964e607d0 100644 --- a/arch/powerpc/cpu/mpc8260/cpu_init.c +++ b/arch/powerpc/cpu/mpc8260/cpu_init.c @@ -120,7 +120,7 @@ void cpu_init_f (volatile immap_t * immr) memset ((void *) gd, 0, sizeof (gd_t)); /* RSR - Reset Status Register - clear all status (5-4) */ - gd->reset_status = immr->im_clkrst.car_rsr; + gd->arch.reset_status = immr->im_clkrst.car_rsr; immr->im_clkrst.car_rsr = RSR_ALLBITS; /* RMR - Reset Mode Register - contains checkstop reset enable (5-5) */ @@ -274,7 +274,7 @@ int prt_8260_rsr (void) RSR_EHRS, "External Hard"} }; static int n = sizeof bits / sizeof bits[0]; - ulong rsr = gd->reset_status; + ulong rsr = gd->arch.reset_status; int i; char *sep; diff --git a/arch/powerpc/cpu/mpc8260/i2c.c b/arch/powerpc/cpu/mpc8260/i2c.c index 7382cbadc7..b720b1fb88 100644 --- a/arch/powerpc/cpu/mpc8260/i2c.c +++ b/arch/powerpc/cpu/mpc8260/i2c.c @@ -259,7 +259,7 @@ void i2c_init(int speed, int slaveadd) * divide BRGCLK by 1) */ debug("[I2C] Setting rate...\n"); - i2c_setrate(gd->brg_clk, CONFIG_SYS_I2C_SPEED); + i2c_setrate(gd->arch.brg_clk, CONFIG_SYS_I2C_SPEED); /* Set I2C controller in master mode */ i2c->i2c_i2com = 0x01; diff --git a/arch/powerpc/cpu/mpc8260/speed.c b/arch/powerpc/cpu/mpc8260/speed.c index bb50dee960..7841e8a898 100644 --- a/arch/powerpc/cpu/mpc8260/speed.c +++ b/arch/powerpc/cpu/mpc8260/speed.c @@ -135,17 +135,17 @@ int get_clocks (void) (get_pvr () == PVR_8260_HIP7R1) || (get_pvr () == PVR_8260_HIP7RA)) { pllmf = (scmr & SCMR_PLLMF_MSKH7) >> SCMR_PLLMF_SHIFT; - gd->vco_out = clkin * (pllmf + 1); + gd->arch.vco_out = clkin * (pllmf + 1); } else { /* HiP3, HiP4 */ pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT; plldf = (scmr & SCMR_PLLDF) ? 1 : 0; - gd->vco_out = (clkin * 2 * (pllmf + 1)) / (plldf + 1); + gd->arch.vco_out = (clkin * 2 * (pllmf + 1)) / (plldf + 1); } - gd->cpm_clk = gd->vco_out / 2; + gd->arch.cpm_clk = gd->arch.vco_out / 2; gd->bus_clk = clkin; - gd->scc_clk = gd->vco_out / 4; - gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1))); + gd->arch.scc_clk = gd->arch.vco_out / 4; + gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1))); if (cp->b2c_mult > 0) { gd->cpu_clk = (clkin * cp->b2c_mult) / 2; @@ -173,7 +173,7 @@ int get_clocks (void) pci_div = pcidf + 1; } - gd->pci_clk = (gd->cpm_clk * 2) / pci_div; + gd->pci_clk = (gd->arch.cpm_clk * 2) / pci_div; } #endif @@ -231,10 +231,10 @@ int prt_8260_clks (void) plldf, pllmf, pcidf); printf (" - vco_out %10ld, scc_clk %10ld, brg_clk %10ld\n", - gd->vco_out, gd->scc_clk, gd->brg_clk); + gd->arch.vco_out, gd->arch.scc_clk, gd->arch.brg_clk); printf (" - cpu_clk %10ld, cpm_clk %10ld, bus_clk %10ld\n", - gd->cpu_clk, gd->cpm_clk, gd->bus_clk); + gd->cpu_clk, gd->arch.cpm_clk, gd->bus_clk); #ifdef CONFIG_PCI printf (" - pci_clk %10ld\n", gd->pci_clk); #endif diff --git a/arch/powerpc/cpu/mpc83xx/Makefile b/arch/powerpc/cpu/mpc83xx/Makefile index 687f5e90a4..8a470b84b8 100644 --- a/arch/powerpc/cpu/mpc83xx/Makefile +++ b/arch/powerpc/cpu/mpc83xx/Makefile @@ -27,8 +27,22 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).o +MINIMAL= + +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_INIT_MINIMAL +MINIMAL=y +endif +endif + START = start.o +ifdef MINIMAL + +COBJS-y += spl_minimal.o + +else + COBJS-y += traps.o COBJS-y += cpu.o COBJS-y += cpu_init.o @@ -51,6 +65,8 @@ COBJS-y += spd_sdram.o endif COBJS-$(CONFIG_FSL_DDR2) += law.o +endif # not minimal + COBJS := $(COBJS-y) SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) $(addprefix $(obj),$(COBJS_LN-y:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS_LN-y)) diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c index e64b0c3411..cc20234298 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu.c +++ b/arch/powerpc/cpu/mpc83xx/cpu.c @@ -122,7 +122,7 @@ int checkcpu(void) printf(" at %s MHz, ", strmhz(buf, clock)); - printf("CSB: %s MHz\n", strmhz(buf, gd->csb_clk)); + printf("CSB: %s MHz\n", strmhz(buf, gd->arch.csb_clk)); return 0; } diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c index 20d06003e5..5153351962 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c @@ -232,12 +232,12 @@ void cpu_init_f (volatile immap_t * im) clrsetbits_be32(&im->clk.sccr, sccr_mask, sccr_val); /* RSR - Reset Status Register - clear all status (4.6.1.3) */ - gd->reset_status = __raw_readl(&im->reset.rsr); + gd->arch.reset_status = __raw_readl(&im->reset.rsr); __raw_writel(~(RSR_RES), &im->reset.rsr); /* AER - Arbiter Event Register - store status */ - gd->arbiter_event_attributes = __raw_readl(&im->arbiter.aeatr); - gd->arbiter_event_address = __raw_readl(&im->arbiter.aeadr); + gd->arch.arbiter_event_attributes = __raw_readl(&im->arbiter.aeatr); + gd->arch.arbiter_event_address = __raw_readl(&im->arbiter.aeadr); /* * RMR - Reset Mode Register @@ -440,42 +440,44 @@ static int print_83xx_arb_event(int force) "reserved" }; - int etype = (gd->arbiter_event_attributes & AEATR_EVENT) + int etype = (gd->arch.arbiter_event_attributes & AEATR_EVENT) >> AEATR_EVENT_SHIFT; - int mstr_id = (gd->arbiter_event_attributes & AEATR_MSTR_ID) + int mstr_id = (gd->arch.arbiter_event_attributes & AEATR_MSTR_ID) >> AEATR_MSTR_ID_SHIFT; - int tbst = (gd->arbiter_event_attributes & AEATR_TBST) + int tbst = (gd->arch.arbiter_event_attributes & AEATR_TBST) >> AEATR_TBST_SHIFT; - int tsize = (gd->arbiter_event_attributes & AEATR_TSIZE) + int tsize = (gd->arch.arbiter_event_attributes & AEATR_TSIZE) >> AEATR_TSIZE_SHIFT; - int ttype = (gd->arbiter_event_attributes & AEATR_TTYPE) + int ttype = (gd->arch.arbiter_event_attributes & AEATR_TTYPE) >> AEATR_TTYPE_SHIFT; - if (!force && !gd->arbiter_event_address) + if (!force && !gd->arch.arbiter_event_address) return 0; puts("Arbiter Event Status:\n"); - printf(" Event Address: 0x%08lX\n", gd->arbiter_event_address); + printf(" Event Address: 0x%08lX\n", + gd->arch.arbiter_event_address); printf(" Event Type: 0x%1x = %s\n", etype, event[etype]); printf(" Master ID: 0x%02x = %s\n", mstr_id, master[mstr_id]); printf(" Transfer Size: 0x%1x = %d bytes\n", (tbst<<3) | tsize, tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize); printf(" Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]); - return gd->arbiter_event_address; + return gd->arch.arbiter_event_address; } #elif defined(CONFIG_DISPLAY_AER_BRIEF) static int print_83xx_arb_event(int force) { - if (!force && !gd->arbiter_event_address) + if (!force && !gd->arch.arbiter_event_address) return 0; printf("Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n", - gd->arbiter_event_attributes, gd->arbiter_event_address); + gd->arch.arbiter_event_attributes, + gd->arch.arbiter_event_address); - return gd->arbiter_event_address; + return gd->arch.arbiter_event_address; } #endif /* CONFIG_DISPLAY_AER_xxxx */ @@ -499,7 +501,7 @@ int prt_83xx_rsr(void) RSR_HRS, "External/Internal Hard"} }; static int n = sizeof bits / sizeof bits[0]; - ulong rsr = gd->reset_status; + ulong rsr = gd->arch.reset_status; int i; char *sep; diff --git a/arch/powerpc/cpu/mpc83xx/fdt.c b/arch/powerpc/cpu/mpc83xx/fdt.c index 1f54781b7e..fe553a74f0 100644 --- a/arch/powerpc/cpu/mpc83xx/fdt.c +++ b/arch/powerpc/cpu/mpc83xx/fdt.c @@ -118,7 +118,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "bus-frequency", bd->bi_busfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, - "clock-frequency", gd->core_clk, 1); + "clock-frequency", gd->arch.core_clk, 1); do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); do_fixup_by_compat_u32(blob, "fsl,soc", diff --git a/arch/powerpc/cpu/mpc83xx/pcie.c b/arch/powerpc/cpu/mpc83xx/pcie.c index 52d446175a..609b133215 100644 --- a/arch/powerpc/cpu/mpc83xx/pcie.c +++ b/arch/powerpc/cpu/mpc83xx/pcie.c @@ -286,8 +286,8 @@ static void mpc83xx_pcie_init_bus(int bus, struct pci_region *reg) get_clocks(); /* Configure the PCIE controller core clock ratio */ out_le32(hose_cfg_base + PEX_GCLK_RATIO, - (((bus ? gd->pciexp2_clk : gd->pciexp1_clk) / 1000000) * 16) - / 333); + (((bus ? gd->arch.pciexp2_clk : gd->arch.pciexp1_clk) + / 1000000) * 16) / 333); udelay(1000000); /* Do Type 1 bridge configuration */ diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c index b8c05d1592..6be0e3a2ee 100644 --- a/arch/powerpc/cpu/mpc83xx/speed.c +++ b/arch/powerpc/cpu/mpc83xx/speed.c @@ -462,53 +462,53 @@ int get_clocks(void) brg_clk = qe_clk / 2; #endif - gd->csb_clk = csb_clk; + gd->arch.csb_clk = csb_clk; #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) - gd->tsec1_clk = tsec1_clk; - gd->tsec2_clk = tsec2_clk; - gd->usbdr_clk = usbdr_clk; + gd->arch.tsec1_clk = tsec1_clk; + gd->arch.tsec2_clk = tsec2_clk; + gd->arch.usbdr_clk = usbdr_clk; #elif defined(CONFIG_MPC8309) - gd->usbdr_clk = usbdr_clk; + gd->arch.usbdr_clk = usbdr_clk; #endif #if defined(CONFIG_MPC834x) - gd->usbmph_clk = usbmph_clk; + gd->arch.usbmph_clk = usbmph_clk; #endif #if defined(CONFIG_MPC8315) - gd->tdm_clk = tdm_clk; + gd->arch.tdm_clk = tdm_clk; #endif #if defined(CONFIG_FSL_ESDHC) - gd->sdhc_clk = sdhc_clk; + gd->arch.sdhc_clk = sdhc_clk; #endif - gd->core_clk = core_clk; - gd->i2c1_clk = i2c1_clk; + gd->arch.core_clk = core_clk; + gd->arch.i2c1_clk = i2c1_clk; #if !defined(CONFIG_MPC832x) - gd->i2c2_clk = i2c2_clk; + gd->arch.i2c2_clk = i2c2_clk; #endif #if !defined(CONFIG_MPC8309) - gd->enc_clk = enc_clk; + gd->arch.enc_clk = enc_clk; #endif - gd->lbiu_clk = lbiu_clk; - gd->lclk_clk = lclk_clk; + gd->arch.lbiu_clk = lbiu_clk; + gd->arch.lclk_clk = lclk_clk; gd->mem_clk = mem_clk; #if defined(CONFIG_MPC8360) - gd->mem_sec_clk = mem_sec_clk; + gd->arch.mem_sec_clk = mem_sec_clk; #endif #if defined(CONFIG_QE) - gd->qe_clk = qe_clk; - gd->brg_clk = brg_clk; + gd->arch.qe_clk = qe_clk; + gd->arch.brg_clk = brg_clk; #endif #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC837x) - gd->pciexp1_clk = pciexp1_clk; - gd->pciexp2_clk = pciexp2_clk; + gd->arch.pciexp1_clk = pciexp1_clk; + gd->arch.pciexp2_clk = pciexp2_clk; #endif #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) - gd->sata_clk = sata_clk; + gd->arch.sata_clk = sata_clk; #endif gd->pci_clk = pci_sync_in; - gd->cpu_clk = gd->core_clk; - gd->bus_clk = gd->csb_clk; + gd->cpu_clk = gd->arch.core_clk; + gd->bus_clk = gd->arch.csb_clk; return 0; } @@ -519,7 +519,7 @@ int get_clocks(void) *********************************************/ ulong get_bus_freq(ulong dummy) { - return gd->csb_clk; + return gd->arch.csb_clk; } /******************************************** @@ -536,49 +536,69 @@ static int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char buf[32]; printf("Clock configuration:\n"); - printf(" Core: %-4s MHz\n", strmhz(buf, gd->core_clk)); - printf(" Coherent System Bus: %-4s MHz\n", strmhz(buf, gd->csb_clk)); + printf(" Core: %-4s MHz\n", + strmhz(buf, gd->arch.core_clk)); + printf(" Coherent System Bus: %-4s MHz\n", + strmhz(buf, gd->arch.csb_clk)); #if defined(CONFIG_QE) - printf(" QE: %-4s MHz\n", strmhz(buf, gd->qe_clk)); - printf(" BRG: %-4s MHz\n", strmhz(buf, gd->brg_clk)); -#endif - printf(" Local Bus Controller:%-4s MHz\n", strmhz(buf, gd->lbiu_clk)); - printf(" Local Bus: %-4s MHz\n", strmhz(buf, gd->lclk_clk)); + printf(" QE: %-4s MHz\n", + strmhz(buf, gd->arch.qe_clk)); + printf(" BRG: %-4s MHz\n", + strmhz(buf, gd->arch.brg_clk)); +#endif + printf(" Local Bus Controller:%-4s MHz\n", + strmhz(buf, gd->arch.lbiu_clk)); + printf(" Local Bus: %-4s MHz\n", + strmhz(buf, gd->arch.lclk_clk)); printf(" DDR: %-4s MHz\n", strmhz(buf, gd->mem_clk)); #if defined(CONFIG_MPC8360) - printf(" DDR Secondary: %-4s MHz\n", strmhz(buf, gd->mem_sec_clk)); + printf(" DDR Secondary: %-4s MHz\n", + strmhz(buf, gd->arch.mem_sec_clk)); #endif #if !defined(CONFIG_MPC8309) - printf(" SEC: %-4s MHz\n", strmhz(buf, gd->enc_clk)); + printf(" SEC: %-4s MHz\n", + strmhz(buf, gd->arch.enc_clk)); #endif - printf(" I2C1: %-4s MHz\n", strmhz(buf, gd->i2c1_clk)); + printf(" I2C1: %-4s MHz\n", + strmhz(buf, gd->arch.i2c1_clk)); #if !defined(CONFIG_MPC832x) - printf(" I2C2: %-4s MHz\n", strmhz(buf, gd->i2c2_clk)); + printf(" I2C2: %-4s MHz\n", + strmhz(buf, gd->arch.i2c2_clk)); #endif #if defined(CONFIG_MPC8315) - printf(" TDM: %-4s MHz\n", strmhz(buf, gd->tdm_clk)); + printf(" TDM: %-4s MHz\n", + strmhz(buf, gd->arch.tdm_clk)); #endif #if defined(CONFIG_FSL_ESDHC) - printf(" SDHC: %-4s MHz\n", strmhz(buf, gd->sdhc_clk)); + printf(" SDHC: %-4s MHz\n", + strmhz(buf, gd->arch.sdhc_clk)); #endif #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) - printf(" TSEC1: %-4s MHz\n", strmhz(buf, gd->tsec1_clk)); - printf(" TSEC2: %-4s MHz\n", strmhz(buf, gd->tsec2_clk)); - printf(" USB DR: %-4s MHz\n", strmhz(buf, gd->usbdr_clk)); + printf(" TSEC1: %-4s MHz\n", + strmhz(buf, gd->arch.tsec1_clk)); + printf(" TSEC2: %-4s MHz\n", + strmhz(buf, gd->arch.tsec2_clk)); + printf(" USB DR: %-4s MHz\n", + strmhz(buf, gd->arch.usbdr_clk)); #elif defined(CONFIG_MPC8309) - printf(" USB DR: %-4s MHz\n", strmhz(buf, gd->usbdr_clk)); + printf(" USB DR: %-4s MHz\n", + strmhz(buf, gd->arch.usbdr_clk)); #endif #if defined(CONFIG_MPC834x) - printf(" USB MPH: %-4s MHz\n", strmhz(buf, gd->usbmph_clk)); + printf(" USB MPH: %-4s MHz\n", + strmhz(buf, gd->arch.usbmph_clk)); #endif #if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC837x) - printf(" PCIEXP1: %-4s MHz\n", strmhz(buf, gd->pciexp1_clk)); - printf(" PCIEXP2: %-4s MHz\n", strmhz(buf, gd->pciexp2_clk)); + printf(" PCIEXP1: %-4s MHz\n", + strmhz(buf, gd->arch.pciexp1_clk)); + printf(" PCIEXP2: %-4s MHz\n", + strmhz(buf, gd->arch.pciexp2_clk)); #endif #if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) - printf(" SATA: %-4s MHz\n", strmhz(buf, gd->sata_clk)); + printf(" SATA: %-4s MHz\n", + strmhz(buf, gd->arch.sata_clk)); #endif return 0; } diff --git a/arch/powerpc/cpu/mpc83xx/nand_init.c b/arch/powerpc/cpu/mpc83xx/spl_minimal.c index d1648b7810..d1648b7810 100644 --- a/arch/powerpc/cpu/mpc83xx/nand_init.c +++ b/arch/powerpc/cpu/mpc83xx/spl_minimal.c diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S index b70b4ca12c..44a64b7acd 100644 --- a/arch/powerpc/cpu/mpc83xx/start.S +++ b/arch/powerpc/cpu/mpc83xx/start.S @@ -58,7 +58,13 @@ #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) #endif -#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SYS_RAMBOOT) +#if defined(CONFIG_NAND_SPL) || \ + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_INIT_MINIMAL)) +#define MINIMAL_SPL +#endif + +#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_NAND_SPL) && \ + !defined(CONFIG_SYS_RAMBOOT) #define CONFIG_SYS_FLASHBOOT #endif @@ -72,7 +78,7 @@ GOT_ENTRY(__bss_start) GOT_ENTRY(__bss_end__) -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL GOT_ENTRY(_FIXUP_TABLE_) GOT_ENTRY(_start) GOT_ENTRY(_start_of_vectors) @@ -206,7 +212,8 @@ _start: /* time t 0 */ /* Initialise the E300 processor core */ /*------------------------------------------*/ -#ifdef CONFIG_NAND_SPL +#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MPC83XX_WAIT_FOR_NAND)) || \ + defined(CONFIG_NAND_SPL) /* The FCM begins execution after only the first page * is loaded. Wait for the rest before branching * to another flash page. @@ -292,7 +299,7 @@ in_flash: /* NOTREACHED - board_init_f() does not return */ -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL /* * Vector Table */ @@ -467,7 +474,7 @@ int_return: lwz r1,GPR1(r1) SYNC rfi -#endif /* !CONFIG_NAND_SPL */ +#endif /* !MINIMAL_SPL */ /* * This code initialises the E300 processor core @@ -724,7 +731,7 @@ setup_bats: * Note: requires that all cache bits in * HID0 are in the low half word. */ -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL .globl icache_enable icache_enable: mfspr r3, HID0 @@ -753,7 +760,7 @@ icache_status: mfspr r3, HID0 rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31 blr -#endif /* !CONFIG_NAND_SPL */ +#endif /* !MINIMAL_SPL */ .globl dcache_enable dcache_enable: @@ -936,7 +943,7 @@ in_ram: stw r0,0(r3) 2: bdnz 1b -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL /* * Now adjust the fixups and the pointers to the fixups * in case we need to move ourselves again. @@ -991,7 +998,7 @@ clear_bss: mr r4, r10 /* Destination Address */ bl board_init_r -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL /* * Copy exception vector code to low memory * @@ -1061,7 +1068,7 @@ trap_init: mtlr r4 /* restore link register */ blr -#endif /* !CONFIG_NAND_SPL */ +#endif /* !MINIMAL_SPL */ #ifdef CONFIG_SYS_INIT_RAM_LOCK lock_ram_in_cache: @@ -1085,7 +1092,7 @@ lock_ram_in_cache: sync blr -#ifndef CONFIG_NAND_SPL +#ifndef MINIMAL_SPL .globl unlock_ram_in_cache unlock_ram_in_cache: /* invalidate the INIT_RAM section */ @@ -1111,7 +1118,7 @@ unlock_ram_in_cache: sync mtspr HID0, r3 /* no invalidate, unlock */ blr -#endif /* !CONFIG_NAND_SPL */ +#endif /* !MINIMAL_SPL */ #endif /* CONFIG_SYS_INIT_RAM_LOCK */ #ifdef CONFIG_SYS_FLASHBOOT diff --git a/arch/powerpc/cpu/mpc83xx/u-boot-spl.lds b/arch/powerpc/cpu/mpc83xx/u-boot-spl.lds new file mode 100644 index 0000000000..d140453d49 --- /dev/null +++ b/arch/powerpc/cpu/mpc83xx/u-boot-spl.lds @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright 2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SECTIONS +{ + . = 0xfff00000; + .text : { + *(.text*) + . = ALIGN(16); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + . = ALIGN(8); + .data : { + *(.data*) + *(.sdata*) + _GOT2_TABLE_ = .; + KEEP(*(.got2)) + KEEP(*(.got)) + PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4); + } + __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; + + . = ALIGN(8); + __bss_start = .; + .bss (NOLOAD) : { + *(.*bss) + } + __bss_end__ = .; +} +ENTRY(_start) +ASSERT(__bss_end__ <= 0xfff01000, "NAND bootstrap too big"); diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 4c2b1040d4..6776c85e49 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -83,8 +83,10 @@ COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5040) += ddr-gen3.o COBJS-$(CONFIG_PPC_T4240) += ddr-gen3.o +COBJS-$(CONFIG_PPC_B4420) += ddr-gen3.o COBJS-$(CONFIG_PPC_B4860) += ddr-gen3.o COBJS-$(CONFIG_BSC9131) += ddr-gen3.o +COBJS-$(CONFIG_BSC9132) += ddr-gen3.o COBJS-$(CONFIG_CPM2) += ether_fcc.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o @@ -100,6 +102,7 @@ COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o COBJS-$(CONFIG_PPC_P5040) += p5040_ids.o COBJS-$(CONFIG_PPC_T4240) += t4240_ids.o +COBJS-$(CONFIG_PPC_B4420) += b4860_ids.o COBJS-$(CONFIG_PPC_B4860) += b4860_ids.o COBJS-$(CONFIG_QE) += qe_io.o @@ -134,7 +137,9 @@ COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o COBJS-$(CONFIG_PPC_P5040) += p5040_serdes.o COBJS-$(CONFIG_PPC_T4240) += t4240_serdes.o +COBJS-$(CONFIG_PPC_B4420) += b4860_serdes.o COBJS-$(CONFIG_PPC_B4860) += b4860_serdes.o +COBJS-$(CONFIG_BSC9132) += bsc9132_serdes.o COBJS-y += cpu.o COBJS-y += cpu_init.o diff --git a/arch/powerpc/cpu/mpc85xx/b4860_ids.c b/arch/powerpc/cpu/mpc85xx/b4860_ids.c index 7d33731a7b..0f4e82e05b 100644 --- a/arch/powerpc/cpu/mpc85xx/b4860_ids.c +++ b/arch/powerpc/cpu/mpc85xx/b4860_ids.c @@ -55,11 +55,13 @@ struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { }; #endif +#ifdef CONFIG_SYS_SRIO struct srio_liodn_id_table srio_liodn_tbl[] = { SET_SRIO_LIODN_1(1, 307), SET_SRIO_LIODN_1(2, 387), }; int srio_liodn_tbl_sz = ARRAY_SIZE(srio_liodn_tbl); +#endif struct liodn_id_table liodn_tbl[] = { #ifdef CONFIG_SYS_DPAA_QBMAN @@ -76,10 +78,12 @@ struct liodn_id_table liodn_tbl[] = { SET_DMA_LIODN(1, 147), SET_DMA_LIODN(2, 227), +#ifndef CONFIG_PPC_B4420 SET_GUTS_LIODN("fsl,rapidio-delta", 199, rio1liodnr, 0), SET_GUTS_LIODN(NULL, 200, rio2liodnr, 0), SET_GUTS_LIODN(NULL, 201, rio1maintliodnr, 0), SET_GUTS_LIODN(NULL, 202, rio2maintliodnr, 0), +#endif /* SET_NEXUS_LIODN(557), -- not yet implemented */ }; @@ -93,8 +97,10 @@ struct liodn_id_table fman1_liodn_tbl[] = { SET_FMAN_RX_1G_LIODN(1, 3, 91), SET_FMAN_RX_1G_LIODN(1, 4, 92), SET_FMAN_RX_1G_LIODN(1, 5, 93), +#ifndef CONFIG_PPC_B4420 SET_FMAN_RX_10G_LIODN(1, 0, 94), SET_FMAN_RX_10G_LIODN(1, 1, 95), +#endif }; int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); #endif diff --git a/arch/powerpc/cpu/mpc85xx/b4860_serdes.c b/arch/powerpc/cpu/mpc85xx/b4860_serdes.c index 9990202f42..bd3234271a 100644 --- a/arch/powerpc/cpu/mpc85xx/b4860_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/b4860_serdes.c @@ -31,6 +31,7 @@ struct serdes_config { u8 lanes[SRDS_MAX_LANES]; }; +#ifdef CONFIG_PPC_B4860 static struct serdes_config serdes1_cfg_tbl[] = { /* SerDes 1 */ {0x0D, {CPRI8, CPRI7, CPRI6, CPRI5, @@ -41,6 +42,12 @@ static struct serdes_config serdes1_cfg_tbl[] = { CPRI4, CPRI3, CPRI2, CPRI1}}, {0x2a, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}}, + {0x2C, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, + CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}}, + {0x2D, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, + CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}}, + {0x2E, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, + CPRI6, CPRI5, CPRI4, CPRI3, CPRI2, CPRI1}}, {0x30, {AURORA, AURORA, SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, CPRI4, CPRI3, CPRI2, CPRI1}}, @@ -84,6 +91,8 @@ static struct serdes_config serdes2_cfg_tbl[] = { {0x4E, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC3, AURORA, SRIO1, SRIO1, SRIO1, SRIO1}}, + {0x7A, {SRIO2, SRIO2, SRIO2, SRIO2, + SRIO1, SRIO1, SRIO1, SRIO1}}, {0x84, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, SRIO2, SRIO2, AURORA, AURORA, XFI_FM1_MAC9, XFI_FM1_MAC10}}, @@ -94,6 +103,9 @@ static struct serdes_config serdes2_cfg_tbl[] = { SRIO2, SRIO2, SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, XFI_FM1_MAC9, XFI_FM1_MAC10}}, + {0x8D, {SRIO2, SRIO2, SRIO2, SRIO2, + SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, + XFI_FM1_MAC9, XFI_FM1_MAC10}}, {0x93, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, XAUI_FM1_MAC10, XAUI_FM1_MAC10, @@ -111,8 +123,56 @@ static struct serdes_config serdes2_cfg_tbl[] = { {0xC3, {XAUI_FM1_MAC9, XAUI_FM1_MAC9, XAUI_FM1_MAC9, XAUI_FM1_MAC9, SRIO1, SRIO1, SRIO1, SRIO1}}, + {0x98, {XAUI_FM1_MAC9, XAUI_FM1_MAC9, + XAUI_FM1_MAC9, XAUI_FM1_MAC9, + XAUI_FM1_MAC10, XAUI_FM1_MAC10, + XAUI_FM1_MAC10, XAUI_FM1_MAC10}}, {} }; +#endif + +#ifdef CONFIG_PPC_B4420 +static struct serdes_config serdes1_cfg_tbl[] = { + {0x0D, {NONE, NONE, CPRI6, CPRI5, + CPRI4, CPRI3, NONE, NONE} }, + {0x0E, {NONE, NONE, CPRI8, CPRI5, + CPRI4, CPRI3, NONE, NONE} }, + {0x0F, {NONE, NONE, CPRI6, CPRI5, + CPRI4, CPRI3, NONE, NONE} }, + {0x18, {NONE, NONE, + SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, + NONE, NONE, NONE, NONE} }, + {0x1B, {NONE, NONE, + SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, + NONE, NONE, NONE, NONE} }, + {0x1E, {NONE, NONE, AURORA, AURORA, + NONE, NONE, NONE, NONE} }, + {0x21, {NONE, NONE, AURORA, AURORA, + NONE, NONE, NONE, NONE} }, + {0x3E, {NONE, NONE, CPRI6, CPRI5, + CPRI4, CPRI3, NONE, NONE} }, + {} +}; +static struct serdes_config serdes2_cfg_tbl[] = { + {0x49, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, + SGMII_FM1_DTSEC3, AURORA, + NONE, NONE, NONE, NONE} }, + {0x4A, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, + SGMII_FM1_DTSEC3, AURORA, + NONE, NONE, NONE, NONE} }, + {0x6F, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, + AURORA, AURORA, NONE, NONE, NONE, NONE} }, + {0x70, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, + AURORA, AURORA, NONE, NONE, NONE, NONE} }, + {0x9A, {PCIE1, PCIE1, + SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4, + NONE, NONE, NONE, NONE} }, + {0x9E, {PCIE1, PCIE1, PCIE1, PCIE1, + NONE, NONE, NONE, NONE} }, + {} +}; +#endif + static struct serdes_config *serdes_cfg_tbl[] = { serdes1_cfg_tbl, serdes2_cfg_tbl, diff --git a/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c new file mode 100644 index 0000000000..300a4dbcf6 --- /dev/null +++ b/arch/powerpc/cpu/mpc85xx/bsc9132_serdes.c @@ -0,0 +1,96 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * Author: Prabhakar Kushwaha <prabhakar@freescale.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. + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_serdes.h> + +#define SRDS1_MAX_LANES 4 + +static u32 serdes1_prtcl_map; + +static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { + [0] = {NONE, NONE, NONE, NONE}, + [1] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [2] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [3] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [4] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [5] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [6] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [7] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [8] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [9] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [10] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [11] = {PCIE1, PCIE2, SGMII_TSEC1, SGMII_TSEC2}, + [12] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [13] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [14] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [15] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [16] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [17] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [18] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [19] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [20] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [21] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [22] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [23] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [24] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [25] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [26] = {PCIE1, PCIE2, CPRI2, CPRI1}, + [27] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [28] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [29] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [30] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [31] = {PCIE1, PCIE2, SGMII_TSEC1, CPRI1}, + [32] = {PCIE1, PCIE2, SGMII_TSEC1, SGMII_TSEC2}, + [33] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [34] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [35] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [36] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [37] = {PCIE1, SGMII_TSEC2, CPRI2, CPRI1}, + [38] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [39] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [40] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [41] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [42] = {PCIE1, SGMII_TSEC2, SGMII_TSEC1, CPRI1}, + [43] = {SGMII_TSEC1, SGMII_TSEC2, CPRI2, CPRI1}, + [44] = {SGMII_TSEC1, SGMII_TSEC2, CPRI2, CPRI1}, + [45] = {SGMII_TSEC1, SGMII_TSEC2, CPRI2, CPRI1}, + [46] = {SGMII_TSEC1, SGMII_TSEC2, CPRI2, CPRI1}, + [47] = {SGMII_TSEC1, SGMII_TSEC2, CPRI2, CPRI1}, +}; + +int is_serdes_configured(enum srds_prtcl prtcl) +{ + return (1 << prtcl) & serdes1_prtcl_map; +} + +void fsl_serdes_init(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 pordevsr = in_be32(&gur->pordevsr); + u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> + MPC85xx_PORDEVSR_IO_SEL_SHIFT; + int lane; + + debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg); + + if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) { + printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); + return; + } + + for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane]; + serdes1_prtcl_map |= (1 << lane_prtcl); + } +} diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index e5ecf5dae5..5d72f4c342 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -240,6 +240,10 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_FSL_ERRATUM_A_004934 puts("Work-around for Erratum A004934 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A005871 + if (IS_SVR_REV(svr, 1, 0)) + puts("Work-around for Erratum A005871 enabled\n"); +#endif #ifdef CONFIG_SYS_FSL_ERRATUM_A004849 /* This work-around is implemented in PBI, so just check for it */ check_erratum_a4849(svr); diff --git a/arch/powerpc/cpu/mpc85xx/commproc.c b/arch/powerpc/cpu/mpc85xx/commproc.c index 292b723dcd..37e706238b 100644 --- a/arch/powerpc/cpu/mpc85xx/commproc.c +++ b/arch/powerpc/cpu/mpc85xx/commproc.c @@ -43,8 +43,8 @@ m8560_cpm_reset(void) /* Reclaim the DP memory for our use. */ - gd->dp_alloc_base = CPM_DATAONLY_BASE; - gd->dp_alloc_top = gd->dp_alloc_base + CPM_DATAONLY_SIZE; + gd->arch.dp_alloc_base = CPM_DATAONLY_BASE; + gd->arch.dp_alloc_top = gd->arch.dp_alloc_base + CPM_DATAONLY_SIZE; /* * Reset CPM @@ -69,21 +69,22 @@ m8560_cpm_dpalloc(uint size, uint align) uint savebase; align_mask = align - 1; - savebase = gd->dp_alloc_base; + savebase = gd->arch.dp_alloc_base; - if ((off = (gd->dp_alloc_base & align_mask)) != 0) - gd->dp_alloc_base += (align - off); + off = gd->arch.dp_alloc_base & align_mask; + if (off != 0) + gd->arch.dp_alloc_base += (align - off); if ((off = size & align_mask) != 0) size += align - off; - if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) { - gd->dp_alloc_base = savebase; + if ((gd->arch.dp_alloc_base + size) >= gd->arch.dp_alloc_top) { + gd->arch.dp_alloc_base = savebase; panic("m8560_cpm_dpalloc: ran out of dual port ram!"); } - retloc = gd->dp_alloc_base; - gd->dp_alloc_base += size; + retloc = gd->arch.dp_alloc_base; + gd->arch.dp_alloc_base += size; memset((void *)&(cpm->im_dprambase[retloc]), 0, size); @@ -110,7 +111,7 @@ m8560_cpm_hostalloc(uint size, uint align) * Baud rate clocks are zero-based in the driver code (as that maps * to port numbers). Documentation uses 1-based numbering. */ -#define BRG_INT_CLK gd->brg_clk +#define BRG_INT_CLK gd->arch.brg_clk #define BRG_UART_CLK ((BRG_INT_CLK + 15) / 16) /* This function is used by UARTS, or anything else that uses a 16x diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 9b9832cfc3..df2ab6d73c 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -104,7 +104,7 @@ int checkcpu (void) puts("CPU: "); } - cpu = gd->cpu; + cpu = gd->arch.cpu; puts(cpu->name); if (IS_E_PROCESSOR(svr)) diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index d1155e8126..de9d916111 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -312,19 +312,33 @@ int enable_cluster_l2(void) /* Look through the remaining clusters, and set up their caches */ do { + int j, cluster_valid = 0; + l2cache = (void __iomem *)(CONFIG_SYS_FSL_CLUSTER_1_L2 + i * 0x40000); + cluster = in_be32(&gur->tp_cluster[i].lower); - /* set stash ID to (cluster) * 2 + 32 + 1 */ - clrsetbits_be32(&l2cache->l2csr1, 0xff, 32 + i * 2 + 1); + /* check that at least one core/accel is enabled in cluster */ + for (j = 0; j < 4; j++) { + u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK; + u32 type = in_be32(&gur->tp_ityp[idx]); + + if (type & TP_ITYP_AV) + cluster_valid = 1; + } - printf("enable l2 for cluster %d %p\n", i, l2cache); + if (cluster_valid) { + /* set stash ID to (cluster) * 2 + 32 + 1 */ + clrsetbits_be32(&l2cache->l2csr1, 0xff, 32 + i * 2 + 1); - out_be32(&l2cache->l2csr0, L2CSR0_L2FI|L2CSR0_L2LFC); - while ((in_be32(&l2cache->l2csr0) & - (L2CSR0_L2FI|L2CSR0_L2LFC)) != 0) - ; - out_be32(&l2cache->l2csr0, L2CSR0_L2E); + printf("enable l2 for cluster %d %p\n", i, l2cache); + + out_be32(&l2cache->l2csr0, L2CSR0_L2FI|L2CSR0_L2LFC); + while ((in_be32(&l2cache->l2csr0) + & (L2CSR0_L2FI|L2CSR0_L2LFC)) != 0) + ; + out_be32(&l2cache->l2csr0, L2CSR0_L2E); + } i++; } while (!(cluster & TP_CLUSTER_EOC)); @@ -534,6 +548,20 @@ skip_l2: /* needs to be in ram since code uses global static vars */ fsl_serdes_init(); +#ifdef CONFIG_SYS_FSL_ERRATUM_A005871 + if (IS_SVR_REV(svr, 1, 0)) { + int i; + __be32 *p = (void __iomem *)CONFIG_SYS_DCSRBAR + 0xb004c; + + for (i = 0; i < 12; i++) { + p += i + (i > 5 ? 11 : 0); + out_be32(p, 0x2); + } + p = (void __iomem *)CONFIG_SYS_DCSRBAR + 0xb0108; + out_be32(p, 0x34); + } +#endif + #ifdef CONFIG_SYS_SRIO srio_init(); #ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index ab0933076d..24eb9789be 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -100,6 +100,22 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) printf("Failed to reserve memory for bootpg: %s\n", fdt_strerror(off)); } + +#ifndef CONFIG_MPC8xxx_DISABLE_BPTR + /* + * Reserve the default boot page so OSes dont use it. + * The default boot page is always mapped to bootpg above using + * boot page translation. + */ + if (0xfffff000ull < memory_limit) { + off = fdt_add_mem_rsv(blob, 0xfffff000ull, (u64)4096); + if (off < 0) { + printf("Failed to reserve memory for 0xfffff000: %s\n", + fdt_strerror(off)); + } + } +#endif + /* Reserve spin table page */ if (spin_tbl_addr < memory_limit) { off = fdt_add_mem_rsv(blob, @@ -591,6 +607,14 @@ void ft_cpu_setup(void *blob, bd_t *bd) /* delete crypto node if not on an E-processor */ if (!IS_E_PROCESSOR(get_svr())) fdt_fixup_crypto_node(blob, 0); +#if CONFIG_SYS_FSL_SEC_COMPAT >= 4 + else { + ccsr_sec_t __iomem *sec; + + sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; + fdt_fixup_crypto_node(blob, in_be32(&sec->secvid_ms)); + } +#endif fdt_fixup_ethernet(blob); @@ -613,9 +637,9 @@ void ft_cpu_setup(void *blob, bd_t *bd) "bus-frequency", bd->bi_busfreq, 1); do_fixup_by_compat_u32(blob, "fsl,pq3-localbus", - "bus-frequency", gd->lbc_clk, 1); + "bus-frequency", gd->arch.lbc_clk, 1); do_fixup_by_compat_u32(blob, "fsl,elbc", - "bus-frequency", gd->lbc_clk, 1); + "bus-frequency", gd->arch.lbc_clk, 1); #ifdef CONFIG_QE ft_qe_setup(blob); ft_fixup_qe_snum(blob); @@ -787,7 +811,7 @@ int ft_verify_fdt(void *fdt) #ifdef CONFIG_SYS_LBC_ADDR off = fdt_node_offset_by_compatible(fdt, -1, "fsl,elbc"); if (off > 0) { - const u32 *reg = fdt_getprop(fdt, off, "reg", NULL); + const fdt32_t *reg = fdt_getprop(fdt, off, "reg", NULL); if (reg) { uint64_t uaddr = CCSR_VIRT_TO_PHYS(CONFIG_SYS_LBC_ADDR); diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 801ee078c0..297f2ed473 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -391,11 +391,11 @@ int get_clocks (void) gd->cpu_clk = sys_info.freqProcessor[0]; gd->bus_clk = sys_info.freqSystemBus; gd->mem_clk = sys_info.freqDDRBus; - gd->lbc_clk = sys_info.freqLocalBus; + gd->arch.lbc_clk = sys_info.freqLocalBus; #ifdef CONFIG_QE - gd->qe_clk = sys_info.freqQE; - gd->brg_clk = gd->qe_clk / 2; + gd->arch.qe_clk = sys_info.freqQE; + gd->arch.brg_clk = gd->arch.qe_clk / 2; #endif /* * The base clock for I2C depends on the actual SOC. Unfortunately, @@ -406,7 +406,7 @@ int get_clocks (void) */ #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \ defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) - gd->i2c1_clk = sys_info.freqSystemBus; + gd->arch.i2c1_clk = sys_info.freqSystemBus; #elif defined(CONFIG_MPC8544) /* * On the 8544, the I2C clock is the same as the SEC clock. This can be @@ -416,29 +416,29 @@ int get_clocks (void) * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544. */ if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG) - gd->i2c1_clk = sys_info.freqSystemBus / 3; + gd->arch.i2c1_clk = sys_info.freqSystemBus / 3; else - gd->i2c1_clk = sys_info.freqSystemBus / 2; + gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; #else /* Most 85xx SOCs use CCB/2, so this is the default behavior. */ - gd->i2c1_clk = sys_info.freqSystemBus / 2; + gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; #endif - gd->i2c2_clk = gd->i2c1_clk; + gd->arch.i2c2_clk = gd->arch.i2c1_clk; #if defined(CONFIG_FSL_ESDHC) #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\ defined(CONFIG_P1014) - gd->sdhc_clk = gd->bus_clk; + gd->arch.sdhc_clk = gd->bus_clk; #else - gd->sdhc_clk = gd->bus_clk / 2; + gd->arch.sdhc_clk = gd->bus_clk / 2; #endif #endif /* defined(CONFIG_FSL_ESDHC) */ #if defined(CONFIG_CPM2) - gd->vco_out = 2*sys_info.freqSystemBus; - gd->cpm_clk = gd->vco_out / 2; - gd->scc_clk = gd->vco_out / 4; - gd->brg_clk = gd->vco_out / (1 << (2 * (dfbrg + 1))); + gd->arch.vco_out = 2*sys_info.freqSystemBus; + gd->arch.cpm_clk = gd->arch.vco_out / 2; + gd->arch.scc_clk = gd->arch.vco_out / 4; + gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1))); #endif if(gd->cpu_clk != 0) return (0); diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index bb0dc1a653..fb674694e4 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -449,7 +449,7 @@ nexti: mflr r1 /* R1 = our PC */ /* Set the size of the TLB to 4KB */ mfspr r3, MAS1 - li r2, 0xF00 + li r2, 0xF80 andc r3, r3, r2 /* Clear the TSIZE bits */ ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l oris r3, r3, MAS1_IPROT@h diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index f44fadcffd..0dff37f77c 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -66,7 +66,7 @@ void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn, _mas1 = mfspr(MAS1); *valid = (_mas1 & MAS1_VALID); - *tsize = (_mas1 >> 8) & 0xf; + *tsize = (_mas1 >> 7) & 0x1f; *epn = mfspr(MAS2) & MAS2_EPN; *rpn = mfspr(MAS3) & MAS3_RPN; #ifdef CONFIG_ENABLE_36BIT_PHYS @@ -99,7 +99,7 @@ static inline void use_tlb_cam(u8 idx) int i = idx / 32; int bit = idx % 32; - gd->used_tlb_cams[i] |= (1 << bit); + gd->arch.used_tlb_cams[i] |= (1 << bit); } static inline void free_tlb_cam(u8 idx) @@ -107,7 +107,7 @@ static inline void free_tlb_cam(u8 idx) int i = idx / 32; int bit = idx % 32; - gd->used_tlb_cams[i] &= ~(1 << bit); + gd->arch.used_tlb_cams[i] &= ~(1 << bit); } void init_used_tlb_cams(void) @@ -116,7 +116,7 @@ void init_used_tlb_cams(void) unsigned int num_cam = mfspr(SPRN_TLB1CFG) & 0xfff; for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++) - gd->used_tlb_cams[i] = 0; + gd->arch.used_tlb_cams[i] = 0; /* walk all the entries */ for (i = 0; i < num_cam; i++) { @@ -133,7 +133,7 @@ int find_free_tlbcam(void) u32 idx; for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++) { - idx = ffz(gd->used_tlb_cams[i]); + idx = ffz(gd->arch.used_tlb_cams[i]); if (idx != 32) break; @@ -156,6 +156,13 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn, if (tlb == 1) use_tlb_cam(esel); + if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && + tsize & 1) { + printf("%s: bad tsize %d on entry %d at 0x%08x\n", + __func__, tsize, tlb, epn); + return; + } + _mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); _mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); _mas2 = FSL_BOOKE_MAS2(epn, wimge); @@ -251,7 +258,7 @@ setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg) unsigned int tlb_size; unsigned int wimge = MAS2_M; unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE; - unsigned int max_cam; + unsigned int max_cam, tsize_mask; u64 size, memsize = (u64)memsize_in_meg << 20; #ifdef CONFIG_SYS_PPC_DDR_WIMGE @@ -261,15 +268,17 @@ setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg) if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { /* Convert (4^max) kB to (2^max) bytes */ max_cam = ((mfspr(SPRN_TLB1CFG) >> 16) & 0xf) * 2 + 10; + tsize_mask = ~1U; } else { /* Convert (2^max) kB to (2^max) bytes */ max_cam = __ilog2(mfspr(SPRN_TLB1PS)) + 10; + tsize_mask = ~0U; } for (i = 0; size && i < 8; i++) { int ram_tlb_index = find_free_tlbcam(); - u32 camsize = __ilog2_u64(size) & ~1U; - u32 align = __ilog2(ram_tlb_address) & ~1U; + u32 camsize = __ilog2_u64(size) & tsize_mask; + u32 align = __ilog2(ram_tlb_address) & tsize_mask; if (ram_tlb_index == -1) break; @@ -281,7 +290,7 @@ setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg) if (camsize > max_cam) camsize = max_cam; - tlb_size = (camsize - 10) / 2; + tlb_size = camsize - 10; set_tlb(1, ram_tlb_address, p_addr, MAS3_SX|MAS3_SW|MAS3_SR, wimge, diff --git a/arch/powerpc/cpu/mpc86xx/cpu.c b/arch/powerpc/cpu/mpc86xx/cpu.c index d2c8c78e86..c553415b55 100644 --- a/arch/powerpc/cpu/mpc86xx/cpu.c +++ b/arch/powerpc/cpu/mpc86xx/cpu.c @@ -67,7 +67,7 @@ checkcpu(void) } puts("CPU: "); - cpu = gd->cpu; + cpu = gd->arch.cpu; puts(cpu->name); diff --git a/arch/powerpc/cpu/mpc86xx/fdt.c b/arch/powerpc/cpu/mpc86xx/fdt.c index 2f955fe930..26a65c586d 100644 --- a/arch/powerpc/cpu/mpc86xx/fdt.c +++ b/arch/powerpc/cpu/mpc86xx/fdt.c @@ -34,10 +34,10 @@ void ft_cpu_setup(void *blob, bd_t *bd) #if defined(CONFIG_MPC8641) do_fixup_by_compat_u32(blob, "fsl,mpc8641-localbus", - "bus-frequency", gd->lbc_clk, 1); + "bus-frequency", gd->arch.lbc_clk, 1); #endif do_fixup_by_compat_u32(blob, "fsl,elbc", - "bus-frequency", gd->lbc_clk, 1); + "bus-frequency", gd->arch.lbc_clk, 1); fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); diff --git a/arch/powerpc/cpu/mpc86xx/speed.c b/arch/powerpc/cpu/mpc86xx/speed.c index a2d0a8ac6e..18c1eea0c1 100644 --- a/arch/powerpc/cpu/mpc86xx/speed.c +++ b/arch/powerpc/cpu/mpc86xx/speed.c @@ -120,7 +120,7 @@ int get_clocks(void) get_sys_info(&sys_info); gd->cpu_clk = sys_info.freqProcessor; gd->bus_clk = sys_info.freqSystemBus; - gd->lbc_clk = sys_info.freqLocalBus; + gd->arch.lbc_clk = sys_info.freqLocalBus; /* * The base clock for I2C depends on the actual SOC. Unfortunately, @@ -130,11 +130,11 @@ int get_clocks(void) * AN2919. */ #ifdef CONFIG_MPC8610 - gd->i2c1_clk = sys_info.freqSystemBus; + gd->arch.i2c1_clk = sys_info.freqSystemBus; #else - gd->i2c1_clk = sys_info.freqSystemBus / 2; + gd->arch.i2c1_clk = sys_info.freqSystemBus / 2; #endif - gd->i2c2_clk = gd->i2c1_clk; + gd->arch.i2c2_clk = gd->arch.i2c1_clk; if (gd->cpu_clk != 0) return 0; diff --git a/arch/powerpc/cpu/mpc8xx/commproc.c b/arch/powerpc/cpu/mpc8xx/commproc.c index 5fe01fffae..a364782096 100644 --- a/arch/powerpc/cpu/mpc8xx/commproc.c +++ b/arch/powerpc/cpu/mpc8xx/commproc.c @@ -31,8 +31,8 @@ DECLARE_GLOBAL_DATA_PTR; int dpram_init (void) { /* Reclaim the DP memory for our use. */ - gd->dp_alloc_base = CPM_DATAONLY_BASE; - gd->dp_alloc_top = CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE; + gd->arch.dp_alloc_base = CPM_DATAONLY_BASE; + gd->arch.dp_alloc_top = CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE; return (0); } @@ -43,19 +43,19 @@ int dpram_init (void) */ uint dpram_alloc (uint size) { - uint addr = gd->dp_alloc_base; + uint addr = gd->arch.dp_alloc_base; - if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) + if ((gd->arch.dp_alloc_base + size) >= gd->arch.dp_alloc_top) return (CPM_DP_NOSPACE); - gd->dp_alloc_base += size; + gd->arch.dp_alloc_base += size; return addr; } uint dpram_base (void) { - return gd->dp_alloc_base; + return gd->arch.dp_alloc_base; } /* Allocate some memory from the dual ported ram. We may want to @@ -66,12 +66,12 @@ uint dpram_alloc_align (uint size, uint align) { uint addr, mask = align - 1; - addr = (gd->dp_alloc_base + mask) & ~mask; + addr = (gd->arch.dp_alloc_base + mask) & ~mask; - if ((addr + size) >= gd->dp_alloc_top) + if ((addr + size) >= gd->arch.dp_alloc_top) return (CPM_DP_NOSPACE); - gd->dp_alloc_base = addr + size; + gd->arch.dp_alloc_base = addr + size; return addr; } @@ -80,6 +80,6 @@ uint dpram_base_align (uint align) { uint mask = align - 1; - return (gd->dp_alloc_base + mask) & ~mask; + return (gd->arch.dp_alloc_base + mask) & ~mask; } #endif /* CONFIG_SYS_ALLOC_DPRAM */ diff --git a/arch/powerpc/cpu/mpc8xx/cpu.c b/arch/powerpc/cpu/mpc8xx/cpu.c index b3fcfe5626..b6b733d77f 100644 --- a/arch/powerpc/cpu/mpc8xx/cpu.c +++ b/arch/powerpc/cpu/mpc8xx/cpu.c @@ -45,7 +45,6 @@ #if defined(CONFIG_OF_LIBFDT) #include <libfdt.h> -#include <libfdt_env.h> #include <fdt_support.h> #endif diff --git a/arch/powerpc/cpu/mpc8xx/fdt.c b/arch/powerpc/cpu/mpc8xx/fdt.c index 7130983ff2..7edd7e4204 100644 --- a/arch/powerpc/cpu/mpc8xx/fdt.c +++ b/arch/powerpc/cpu/mpc8xx/fdt.c @@ -37,7 +37,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency", bd->bi_intfreq, 1); do_fixup_by_compat_u32(blob, "fsl,cpm-brg", "clock-frequency", - gd->brg_clk, 1); + gd->arch.brg_clk, 1); /* Fixup ethernet MAC addresses */ fdt_fixup_ethernet(blob); diff --git a/arch/powerpc/cpu/mpc8xx/speed.c b/arch/powerpc/cpu/mpc8xx/speed.c index 6e13e5de02..091b49f24a 100644 --- a/arch/powerpc/cpu/mpc8xx/speed.c +++ b/arch/powerpc/cpu/mpc8xx/speed.c @@ -192,7 +192,7 @@ void get_brgclk(uint sccr) divider = 64; break; } - gd->brg_clk = gd->cpu_clk/divider; + gd->arch.brg_clk = gd->cpu_clk/divider; } #if !defined(CONFIG_8xx_CPUCLK_DEFAULT) diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index e8613be393..39525fb29d 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -86,6 +86,8 @@ static struct cpu_type cpu_type_list[] = { CPU_TYPE_ENTRY(B4220, B4220, 0), CPU_TYPE_ENTRY(BSC9130, 9130, 1), CPU_TYPE_ENTRY(BSC9131, 9131, 1), + CPU_TYPE_ENTRY(BSC9132, 9132, 2), + CPU_TYPE_ENTRY(BSC9232, 9232, 2), #elif defined(CONFIG_MPC86xx) CPU_TYPE_ENTRY(8610, 8610, 1), CPU_TYPE_ENTRY(8641, 8641, 2), @@ -146,7 +148,7 @@ struct cpu_type *identify_cpu(u32 ver) u32 cpu_mask(void) { ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; - struct cpu_type *cpu = gd->cpu; + struct cpu_type *cpu = gd->arch.cpu; /* better to query feature reporting register than just assume 1 */ if (cpu == &cpu_type_unknown) @@ -164,7 +166,7 @@ u32 cpu_mask(void) */ int cpu_numcores(void) { - struct cpu_type *cpu = gd->cpu; + struct cpu_type *cpu = gd->arch.cpu; /* * Report # of cores in terms of the cpu_mask if we haven't @@ -194,7 +196,7 @@ int probecpu (void) svr = get_svr(); ver = SVR_SOC_VER(svr); - gd->cpu = identify_cpu(ver); + gd->arch.cpu = identify_cpu(ver); return 0; } @@ -202,7 +204,7 @@ int probecpu (void) /* Once in memory, compute mask & # cores once and save them off */ int fixup_cpu(void) { - struct cpu_type *cpu = gd->cpu; + struct cpu_type *cpu = gd->arch.cpu; if (cpu->num_cores == 0) { cpu->mask = cpu_mask(); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 8016bcdc22..26c42f7039 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -1190,7 +1190,11 @@ static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) { unsigned int init_value; /* Initialization value */ +#ifdef CONFIG_MEM_INIT_VALUE + init_value = CONFIG_MEM_INIT_VALUE; +#else init_value = 0xDEADBEEF; +#endif ddr->ddr_data_init = init_value; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h index c8b0f91676..4dd55fc4c3 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h @@ -86,7 +86,8 @@ void fsl_ddr_set_lawbar( unsigned int memctl_interleaved, unsigned int ctrl_num); -unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo); +int fsl_ddr_interactive_env_var_exists(void); +unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set); void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, unsigned int ctrl_num); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index cb71f94ba1..46257c9529 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1369,14 +1369,15 @@ struct data_strings { #define DATA_OPTIONS(name, step, dimm) {#name, step, dimm} -unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) -{ - unsigned long long ddrsize; - const char *prompt = "FSL DDR>"; - char buffer[CONFIG_SYS_CBSIZE]; - char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ - int argc; - unsigned int next_step = STEP_GET_SPD; +static unsigned int fsl_ddr_parse_interactive_cmd( + char **argv, + int argc, + unsigned int *pstep_mask, + unsigned int *pctlr_mask, + unsigned int *pdimm_mask, + unsigned int *pdimm_number_required + ) { + static const struct data_strings options[] = { DATA_OPTIONS(spd, STEP_GET_SPD, 1), DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1), @@ -1386,6 +1387,69 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0), }; static const unsigned int n_opts = ARRAY_SIZE(options); + + unsigned int i, j; + unsigned int error = 0; + + for (i = 1; i < argc; i++) { + unsigned int matched = 0; + + for (j = 0; j < n_opts; j++) { + if (strcmp(options[j].data_name, argv[i]) != 0) + continue; + *pstep_mask |= options[j].step_mask; + *pdimm_number_required = + options[j].dimm_number_required; + matched = 1; + break; + } + + if (matched) + continue; + + if (argv[i][0] == 'c') { + char c = argv[i][1]; + if (isdigit(c)) + *pctlr_mask |= 1 << (c - '0'); + continue; + } + + if (argv[i][0] == 'd') { + char c = argv[i][1]; + if (isdigit(c)) + *pdimm_mask |= 1 << (c - '0'); + continue; + } + + printf("unknown arg %s\n", argv[i]); + *pstep_mask = 0; + error = 1; + break; + } + + return error; +} + +int fsl_ddr_interactive_env_var_exists(void) +{ + char buffer[CONFIG_SYS_CBSIZE]; + + if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0) + return 1; + + return 0; +} + +unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set) +{ + unsigned long long ddrsize; + const char *prompt = "FSL DDR>"; + char buffer[CONFIG_SYS_CBSIZE]; + char buffer2[CONFIG_SYS_CBSIZE]; + char *p = NULL; + char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ + int argc; + unsigned int next_step = STEP_GET_SPD; const char *usage = { "commands:\n" "print print SPD and intermediate computed data\n" @@ -1393,21 +1457,45 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) "recompute reload SPD and options to default and recompute regs\n" "edit modify spd, parameter, or option\n" "compute recompute registers from current next_step to end\n" + "copy copy parameters\n" "next_step shows current next_step\n" "help this message\n" "go program the memory controller and continue with u-boot\n" }; + if (var_is_set) { + if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) { + p = buffer2; + } else { + var_is_set = 0; + } + } + /* * The strategy for next_step is that it points to the next * step in the computation process that needs to be done. */ while (1) { - /* - * No need to worry for buffer overflow here in - * this function; readline() maxes out at CFG_CBSIZE - */ - readline_into_buffer(prompt, buffer, 0); + if (var_is_set) { + char *pend = strchr(p, ';'); + if (pend) { + /* found command separator, copy sub-command */ + *pend = '\0'; + strcpy(buffer, p); + p = pend + 1; + } else { + /* separator not found, copy whole string */ + strcpy(buffer, p); + p = NULL; + var_is_set = 0; + } + } else { + /* + * No need to worry for buffer overflow here in + * this function; readline() maxes out at CFG_CBSIZE + */ + readline_into_buffer(prompt, buffer, 0); + } argc = parse_line(buffer, argv); if (argc == 0) continue; @@ -1425,64 +1513,160 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) continue; } - if (strcmp(argv[0], "edit") == 0) { - unsigned int i, j; + if (strcmp(argv[0], "copy") == 0) { unsigned int error = 0; unsigned int step_mask = 0; - unsigned int ctlr_mask = 0; - unsigned int dimm_mask = 0; - char *p_element = NULL; - char *p_value = NULL; + unsigned int src_ctlr_mask = 0; + unsigned int src_dimm_mask = 0; unsigned int dimm_number_required = 0; - unsigned int ctrl_num; - unsigned int dimm_num; - unsigned int matched = 0; + unsigned int src_ctlr_num = 0; + unsigned int src_dimm_num = 0; + unsigned int dst_ctlr_num = -1; + unsigned int dst_dimm_num = -1; + unsigned int i, num_dest_parms; if (argc == 1) { - /* Only the element and value must be last */ - printf("edit <c#> <d#> " - "<spd|dimmparms|commonparms|opts|" - "addresses|regs> <element> <value>\n"); - printf("for spd, specify byte number for " - "element\n"); + printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n"); continue; } - for (i = 1; i < argc - 2; i++) { - for (j = 0; j < n_opts; j++) { - if (strcmp(options[j].data_name, - argv[i]) != 0) - continue; - step_mask |= options[j].step_mask; - dimm_number_required = - options[j].dimm_number_required; - matched = 1; - break; + error = fsl_ddr_parse_interactive_cmd( + argv, argc, + &step_mask, + &src_ctlr_mask, + &src_dimm_mask, + &dimm_number_required + ); + + /* XXX: only dimm_number_required and step_mask will + be used by this function. Parse the controller and + DIMM number separately because it is easier. */ + + if (error) + continue; + + /* parse source destination controller / DIMM */ + + num_dest_parms = dimm_number_required ? 2 : 1; + + for (i = 0; i < argc; i++) { + if (argv[i][0] == 'c') { + char c = argv[i][1]; + if (isdigit(c)) { + src_ctlr_num = (c - '0'); + break; + } } + } - if (matched) - continue; + for (i = 0; i < argc; i++) { + if (argv[i][0] == 'd') { + char c = argv[i][1]; + if (isdigit(c)) { + src_dimm_num = (c - '0'); + break; + } + } + } + + /* parse destination controller / DIMM */ + for (i = argc - 1; i >= argc - num_dest_parms; i--) { if (argv[i][0] == 'c') { char c = argv[i][1]; - if (isdigit(c)) - ctlr_mask |= 1 << (c - '0'); - continue; + if (isdigit(c)) { + dst_ctlr_num = (c - '0'); + break; + } } + } + for (i = argc - 1; i >= argc - num_dest_parms; i--) { if (argv[i][0] == 'd') { char c = argv[i][1]; - if (isdigit(c)) - dimm_mask |= 1 << (c - '0'); - continue; + if (isdigit(c)) { + dst_dimm_num = (c - '0'); + break; + } } + } + + /* TODO: validate inputs */ + + debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n", + src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask); - printf("unknown arg %s\n", argv[i]); - step_mask = 0; - error = 1; + + switch (step_mask) { + + case STEP_GET_SPD: + memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]), + &(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]), + sizeof(pinfo->spd_installed_dimms[0][0])); break; + + case STEP_COMPUTE_DIMM_PARMS: + memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]), + &(pinfo->dimm_params[src_ctlr_num][src_dimm_num]), + sizeof(pinfo->dimm_params[0][0])); + break; + + case STEP_COMPUTE_COMMON_PARMS: + memcpy(&(pinfo->common_timing_params[dst_ctlr_num]), + &(pinfo->common_timing_params[src_ctlr_num]), + sizeof(pinfo->common_timing_params[0])); + break; + + case STEP_GATHER_OPTS: + memcpy(&(pinfo->memctl_opts[dst_ctlr_num]), + &(pinfo->memctl_opts[src_ctlr_num]), + sizeof(pinfo->memctl_opts[0])); + break; + + /* someday be able to have addresses to copy addresses... */ + + case STEP_COMPUTE_REGS: + memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]), + &(pinfo->fsl_ddr_config_reg[src_ctlr_num]), + sizeof(pinfo->memctl_opts[0])); + break; + + default: + printf("unexpected step_mask value\n"); + } + + continue; + + } + + if (strcmp(argv[0], "edit") == 0) { + unsigned int error = 0; + unsigned int step_mask = 0; + unsigned int ctlr_mask = 0; + unsigned int dimm_mask = 0; + char *p_element = NULL; + char *p_value = NULL; + unsigned int dimm_number_required = 0; + unsigned int ctrl_num; + unsigned int dimm_num; + + if (argc == 1) { + /* Only the element and value must be last */ + printf("edit <c#> <d#> " + "<spd|dimmparms|commonparms|opts|" + "addresses|regs> <element> <value>\n"); + printf("for spd, specify byte number for " + "element\n"); + continue; } + error = fsl_ddr_parse_interactive_cmd( + argv, argc - 2, + &step_mask, + &ctlr_mask, + &dimm_mask, + &dimm_number_required + ); if (error) continue; @@ -1629,12 +1813,11 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) } if (strcmp(argv[0], "print") == 0) { - unsigned int i, j; unsigned int error = 0; unsigned int step_mask = 0; unsigned int ctlr_mask = 0; unsigned int dimm_mask = 0; - unsigned int matched = 0; + unsigned int dimm_number_required = 0; if (argc == 1) { printf("print [c<n>] [d<n>] [spd] [dimmparms] " @@ -1642,38 +1825,13 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) continue; } - for (i = 1; i < argc; i++) { - for (j = 0; j < n_opts; j++) { - if (strcmp(options[j].data_name, - argv[i]) != 0) - continue; - step_mask |= options[j].step_mask; - matched = 1; - break; - } - - if (matched) - continue; - - if (argv[i][0] == 'c') { - char c = argv[i][1]; - if (isdigit(c)) - ctlr_mask |= 1 << (c - '0'); - continue; - } - - if (argv[i][0] == 'd') { - char c = argv[i][1]; - if (isdigit(c)) - dimm_mask |= 1 << (c - '0'); - continue; - } - - printf("unknown arg %s\n", argv[i]); - step_mask = 0; - error = 1; - break; - } + error = fsl_ddr_parse_interactive_cmd( + argv, argc, + &step_mask, + &ctlr_mask, + &dimm_mask, + &dimm_number_required + ); if (error) continue; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index d6b73c7af1..5311a262a2 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -532,9 +532,11 @@ phys_size_t fsl_ddr_sdram(void) /* Compute it once normally. */ #ifdef CONFIG_FSL_DDR_INTERACTIVE - if (getenv("ddr_interactive")) - total_memory = fsl_ddr_interactive(&info); - else + if (tstc() && (getc() == 'd')) { /* we got a key press of 'd' */ + total_memory = fsl_ddr_interactive(&info, 0); + } else if (fsl_ddr_interactive_env_var_exists()) { + total_memory = fsl_ddr_interactive(&info, 1); + } else #endif total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 1986fea030..284709428d 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -297,10 +297,86 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev) fdt_strerror(err)); } #elif CONFIG_SYS_FSL_SEC_COMPAT >= 4 /* SEC4 */ +static u8 caam_get_era(void) +{ + static const struct { + u16 ip_id; + u8 maj_rev; + u8 era; + } caam_eras[] = { + {0x0A10, 1, 1}, + {0x0A10, 2, 2}, + {0x0A12, 1, 3}, + {0x0A14, 1, 3}, + {0x0A14, 2, 4}, + {0x0A16, 1, 4}, + {0x0A10, 3, 4}, + {0x0A11, 1, 4}, + {0x0A18, 1, 4}, + {0x0A11, 2, 5}, + {0x0A12, 2, 5}, + {0x0A13, 1, 5}, + {0x0A1C, 1, 5} + }; + + ccsr_sec_t __iomem *sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; + u32 secvid_ms = in_be32(&sec->secvid_ms); + u32 ccbvid = in_be32(&sec->ccbvid); + u16 ip_id = (secvid_ms & SEC_SECVID_MS_IPID_MASK) >> + SEC_SECVID_MS_IPID_SHIFT; + u8 maj_rev = (secvid_ms & SEC_SECVID_MS_MAJ_REV_MASK) >> + SEC_SECVID_MS_MAJ_REV_SHIFT; + u8 era = (ccbvid & SEC_CCBVID_ERA_MASK) >> SEC_CCBVID_ERA_SHIFT; + + int i; + + if (era) /* This is '0' prior to CAAM ERA-6 */ + return era; + + for (i = 0; i < ARRAY_SIZE(caam_eras); i++) + if (caam_eras[i].ip_id == ip_id && + caam_eras[i].maj_rev == maj_rev) + return caam_eras[i].era; + + return 0; +} + +static void fdt_fixup_crypto_era(void *blob, u32 era) +{ + int err; + int crypto_node; + + crypto_node = fdt_path_offset(blob, "crypto"); + if (crypto_node < 0) { + printf("WARNING: Missing crypto node\n"); + return; + } + + err = fdt_setprop(blob, crypto_node, "fsl,sec-era", &era, + sizeof(era)); + if (err < 0) { + printf("ERROR: could not set fsl,sec-era property: %s\n", + fdt_strerror(err)); + } +} + void fdt_fixup_crypto_node(void *blob, int sec_rev) { - if (!sec_rev) + u8 era; + + if (!sec_rev) { fdt_del_node_and_alias(blob, "crypto"); + return; + } + + /* Add SEC ERA information in compatible */ + era = caam_get_era(); + if (era) { + fdt_fixup_crypto_era(blob, era); + } else { + printf("WARNING: Unable to get ERA for CAAM rev: %d\n", + sec_rev); + } } #endif diff --git a/arch/powerpc/cpu/mpc8xxx/law.c b/arch/powerpc/cpu/mpc8xxx/law.c index ce1d71e307..6f9d5683a9 100644 --- a/arch/powerpc/cpu/mpc8xxx/law.c +++ b/arch/powerpc/cpu/mpc8xxx/law.c @@ -69,7 +69,7 @@ static inline void set_law_base_addr(int idx, phys_addr_t addr) void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { - gd->used_laws |= (1 << idx); + gd->arch.used_laws |= (1 << idx); out_be32(LAWAR_ADDR(idx), 0); set_law_base_addr(idx, addr); @@ -81,7 +81,7 @@ void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id) void disable_law(u8 idx) { - gd->used_laws &= ~(1 << idx); + gd->arch.used_laws &= ~(1 << idx); out_be32(LAWAR_ADDR(idx), 0); set_law_base_addr(idx, 0); @@ -112,7 +112,7 @@ static int get_law_entry(u8 i, struct law_entry *e) int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) { - u32 idx = ffz(gd->used_laws); + u32 idx = ffz(gd->arch.used_laws); if (idx >= FSL_HW_NUM_LAWS) return -1; @@ -128,11 +128,11 @@ int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id) u32 idx; /* we have no LAWs free */ - if (gd->used_laws == -1) + if (gd->arch.used_laws == -1) return -1; /* grab the last free law */ - idx = __ilog2(~(gd->used_laws)); + idx = __ilog2(~(gd->arch.used_laws)); if (idx >= FSL_HW_NUM_LAWS) return -1; @@ -240,9 +240,9 @@ void init_laws(void) int i; #if FSL_HW_NUM_LAWS < 32 - gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1); + gd->arch.used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1); #elif FSL_HW_NUM_LAWS == 32 - gd->used_laws = 0; + gd->arch.used_laws = 0; #else #error FSL_HW_NUM_LAWS can not be greater than 32 w/o code changes #endif @@ -255,7 +255,7 @@ void init_laws(void) u32 lawar = in_be32(LAWAR_ADDR(i)); if (lawar & LAW_EN) - gd->used_laws |= (1 << i); + gd->arch.used_laws |= (1 << i); } #if (defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)) || \ diff --git a/arch/powerpc/cpu/ppc4xx/4xx_uart.c b/arch/powerpc/cpu/ppc4xx/4xx_uart.c index 38ba60bb0d..2ab185f0fd 100644 --- a/arch/powerpc/cpu/ppc4xx/4xx_uart.c +++ b/arch/powerpc/cpu/ppc4xx/4xx_uart.c @@ -296,10 +296,10 @@ int get_serial_clock(void) * the UART divisor is available */ #ifdef CONFIG_SYS_EXT_SERIAL_CLOCK - gd->uart_clk = CONFIG_SYS_EXT_SERIAL_CLOCK; + gd->arch.uart_clk = CONFIG_SYS_EXT_SERIAL_CLOCK; #else get_sys_info(&sys_info); - gd->uart_clk = sys_info.freqUART / udiv; + gd->arch.uart_clk = sys_info.freqUART / udiv; #endif return clk; diff --git a/arch/powerpc/cpu/ppc4xx/fdt.c b/arch/powerpc/cpu/ppc4xx/fdt.c index 5ddb880241..3cdd5319a9 100644 --- a/arch/powerpc/cpu/ppc4xx/fdt.c +++ b/arch/powerpc/cpu/ppc4xx/fdt.c @@ -29,7 +29,6 @@ #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) #include <libfdt.h> -#include <libfdt_env.h> #include <fdt_support.h> #include <asm/4xx_pcie.h> @@ -141,7 +140,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) /* * Fixup all UART clocks for CPU internal UARTs - * (only these UARTs are definitely clocked by gd->uart_clk) + * (only these UARTs are definitely clocked by gd->arch.uart_clk) * * These UARTs are direct childs of /plb/opb. This code * does not touch any UARTs that are connected to the ebc. @@ -160,7 +159,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) (fdt_node_check_compatible(blob, off, "ns16550") == 0)) fdt_setprop(blob, off, "clock-frequency", - (void*)&(gd->uart_clk), 4); + (void *)&gd->arch.uart_clk, 4); } /* diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 0b9638bcee..d57c178f7f 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -493,6 +493,21 @@ #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#elif defined(CONFIG_BSC9132) +#define CONFIG_MAX_CPUS 2 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 3 +#define CONFIG_FSL_SDHC_V2_3 +#define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_TSECV2 +#define CONFIG_SYS_FSL_SEC_COMPAT 4 +#define CONFIG_NUM_DDR_CONTROLLERS 2 +#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 +#define CONFIG_NAND_FSL_IFC +#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK +#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" + #elif defined(CONFIG_PPC_T4240) #define CONFIG_SYS_PPC64 /* 64-bit core */ #define CONFIG_FSL_CORENET /* Freescale CoreNet platform */ @@ -523,6 +538,28 @@ #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_A004468 #define CONFIG_SYS_FSL_ERRATUM_A_004934 +#define CONFIG_SYS_FSL_ERRATUM_A005871 +#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 + +#elif defined(CONFIG_PPC_B4420) +#define CONFIG_SYS_PPC64 /* 64-bit core */ +#define CONFIG_FSL_CORENET /* Freescale CoreNet platform */ +#define CONFIG_SYS_FSL_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */ +#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */ +#define CONFIG_MAX_CPUS 2 +#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 +#define CONFIG_SYS_FSL_NUM_LAWS 32 +#define CONFIG_SYS_FSL_SEC_COMPAT 4 +#define CONFIG_SYS_NUM_FMAN 1 +#define CONFIG_SYS_NUM_FM1_DTSEC 4 +#define CONFIG_NUM_DDR_CONTROLLERS 1 +#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_7 +#define CONFIG_SYS_FMAN_V3 +#define CONFIG_SYS_FM_MURAM_SIZE 0x60000 +#define CONFIG_SYS_FSL_TBCLK_DIV 16 +#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4" +#define CONFIG_SYS_FSL_USB1_PHY_ENABLE +#define CONFIG_SYS_FSL_ERRATUM_A_004934 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 #elif defined(CONFIG_PPC_B4860) @@ -537,7 +574,7 @@ #define CONFIG_SYS_NUM_FMAN 1 #define CONFIG_SYS_NUM_FM1_DTSEC 6 #define CONFIG_SYS_NUM_FM1_10GEC 2 -#define CONFIG_NUM_DDR_CONTROLLERS 1 +#define CONFIG_NUM_DDR_CONTROLLERS 2 #define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_7 #define CONFIG_SYS_FMAN_V3 #define CONFIG_SYS_FM_MURAM_SIZE 0x60000 diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h index cb3a80bb2b..d5db8549cc 100644 --- a/arch/powerpc/include/asm/global_data.h +++ b/arch/powerpc/include/asm/global_data.h @@ -27,76 +27,61 @@ #include "config.h" #include "asm/types.h" -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ - -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long bus_clk; +/* Architecture-specific global data */ +struct arch_global_data { +#if defined(CONFIG_FSL_ESDHC) + u32 sdhc_clk; +#endif #if defined(CONFIG_8xx) - unsigned long brg_clk; + unsigned long brg_clk; #endif #if defined(CONFIG_CPM2) /* There are many clocks on the MPC8260 - see page 9-5 */ - unsigned long vco_out; - unsigned long cpm_clk; - unsigned long scc_clk; - unsigned long brg_clk; -#ifdef CONFIG_PCI - unsigned long pci_clk; -#endif + unsigned long vco_out; + unsigned long cpm_clk; + unsigned long scc_clk; + unsigned long brg_clk; #endif - unsigned long mem_clk; + /* TODO: sjg@chromium.org: Should these be unslgned long? */ #if defined(CONFIG_MPC83xx) /* There are other clocks in the MPC83XX */ u32 csb_clk; -#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ +# if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) u32 tsec1_clk; u32 tsec2_clk; u32 usbdr_clk; -#elif defined(CONFIG_MPC8309) +# elif defined(CONFIG_MPC8309) u32 usbdr_clk; -#endif -#if defined (CONFIG_MPC834x) +# endif +# if defined(CONFIG_MPC834x) u32 usbmph_clk; -#endif /* CONFIG_MPC834x */ -#if defined(CONFIG_MPC8315) +# endif /* CONFIG_MPC834x */ +# if defined(CONFIG_MPC8315) u32 tdm_clk; -#endif +# endif u32 core_clk; u32 enc_clk; u32 lbiu_clk; u32 lclk_clk; - u32 pci_clk; -#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ +# if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ defined(CONFIG_MPC837x) u32 pciexp1_clk; u32 pciexp2_clk; -#endif -#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) +# endif +# if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) u32 sata_clk; -#endif -#if defined(CONFIG_MPC8360) - u32 mem_sec_clk; -#endif /* CONFIG_MPC8360 */ -#endif -#if defined(CONFIG_FSL_ESDHC) - u32 sdhc_clk; +# endif +# if defined(CONFIG_MPC8360) + u32 mem_sec_clk; +# endif /* CONFIG_MPC8360 */ #endif #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) u32 lbc_clk; void *cpu; #endif /* CONFIG_MPC85xx || CONFIG_MPC86xx */ -#if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) +#if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ + defined(CONFIG_MPC86xx) u32 i2c1_clk; u32 i2c2_clk; #endif @@ -113,68 +98,32 @@ typedef struct global_data { u32 used_tlb_cams[(CONFIG_SYS_NUM_TLBCAMS+31)/32]; #endif #if defined(CONFIG_MPC5xxx) - unsigned long ipb_clk; - unsigned long pci_clk; + unsigned long ipb_clk; #endif #if defined(CONFIG_MPC512X) u32 ips_clk; u32 csb_clk; - u32 pci_clk; #endif /* CONFIG_MPC512X */ #if defined(CONFIG_MPC8220) - unsigned long bExtUart; - unsigned long inp_clk; - unsigned long pci_clk; - unsigned long vco_clk; - unsigned long pev_clk; - unsigned long flb_clk; -#endif - phys_size_t ram_size; /* RAM size */ - unsigned long reset_status; /* reset status register at boot */ -#if defined(CONFIG_MPC83xx) - unsigned long arbiter_event_attributes; - unsigned long arbiter_event_address; + unsigned long inp_clk; + unsigned long vco_clk; + unsigned long pev_clk; + unsigned long flb_clk; #endif - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ + unsigned long reset_status; /* reset status register at boot */ +#if defined(CONFIG_MPC83xx) + unsigned long arbiter_event_attributes; + unsigned long arbiter_event_address; #endif #if defined(CONFIG_SYS_ALLOC_DPRAM) || defined(CONFIG_CPM2) - unsigned int dp_alloc_base; - unsigned int dp_alloc_top; + unsigned int dp_alloc_base; + unsigned int dp_alloc_top; #endif #if defined(CONFIG_4xx) - u32 uart_clk; + u32 uart_clk; #endif /* CONFIG_4xx */ #if defined(CONFIG_SYS_GT_6426x) - unsigned int mirror_hack[16]; -#endif -#if defined(CONFIG_A3000) || \ - defined(CONFIG_HIDDEN_DRAGON) || \ - defined(CONFIG_MUSENKI) || \ - defined(CONFIG_SANDPOINT) - void * console_addr; -#endif - unsigned long relocaddr; /* Start address of U-Boot in RAM */ -#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) - unsigned long fb_base; /* Base address of framebuffer memory */ -#endif -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - unsigned long post_log_word; /* Record POST activities */ - unsigned long post_log_res; /* success of POST test */ - unsigned long post_init_f_time; /* When post_init_f started */ -#endif -#ifdef CONFIG_BOARD_TYPES - unsigned long board_type; -#endif -#ifdef CONFIG_MODEM_SUPPORT - unsigned long do_mdm_init; - unsigned long be_quiet; -#endif -#if defined(CONFIG_LWMON) || defined(CONFIG_LWMON5) - unsigned long kbd_status; + unsigned int mirror_hack[16]; #endif #ifdef CONFIG_SYS_FPGA_COUNT unsigned fpga_state[CONFIG_SYS_FPGA_COUNT]; @@ -182,11 +131,12 @@ typedef struct global_data { #if defined(CONFIG_WD_MAX_RATE) unsigned long long wdt_last; /* trace watch-dog triggering rate */ #endif - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +#if defined(CONFIG_LWMON) || defined(CONFIG_LWMON5) + unsigned long kbd_status; +#endif +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #if 1 #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r2") diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 296b549779..4eb3f79230 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1840,7 +1840,7 @@ typedef struct ccsr_gur { #define FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT 11 #define FSL_CORENET2_RCWSR4_SRDS4_PRTCL 0x000000f8 #define FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT 3 -#elif defined(CONFIG_PPC_B4860) +#elif defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420) #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL 0xfe000000 #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT 25 #define FSL_CORENET2_RCWSR4_SRDS2_PRTCL 0x00ff0000 @@ -2150,7 +2150,7 @@ typedef struct ccsr_gur { #define MPC85xx_PORPLLSR_DDR_RATIO 0x3e000000 #define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT 25 #else -#ifdef CONFIG_BSC9131 +#if defined(CONFIG_BSC9131) || defined(CONFIG_BSC9132) #define MPC85xx_PORPLLSR_DDR_RATIO 0x00003f00 #else #define MPC85xx_PORPLLSR_DDR_RATIO 0x00003e00 @@ -2164,6 +2164,11 @@ typedef struct ccsr_gur { u32 porbmsr; /* POR boot mode status */ #define MPC85xx_PORBMSR_HA 0x00070000 #define MPC85xx_PORBMSR_HA_SHIFT 16 +#define MPC85XX_PORBMSR_ROMLOC_SHIFT 24 +#define PORBMSR_ROMLOC_SPI 0x6 +#define PORBMSR_ROMLOC_SDHC 0x7 +#define PORBMSR_ROMLOC_NAND_2K 0x9 +#define PORBMSR_ROMLOC_NOR 0xf u32 porimpscr; /* POR I/O impedance status & control */ u32 pordevsr; /* POR I/O device status regsiter */ #if defined(CONFIG_P1017) || defined(CONFIG_P1023) @@ -2188,6 +2193,9 @@ typedef struct ccsr_gur { #if defined(CONFIG_P1010) #define MPC85xx_PORDEVSR_IO_SEL 0x00600000 #define MPC85xx_PORDEVSR_IO_SEL_SHIFT 21 +#elif defined(CONFIG_BSC9132) +#define MPC85xx_PORDEVSR_IO_SEL 0x00FE0000 +#define MPC85xx_PORDEVSR_IO_SEL_SHIFT 17 #else #define MPC85xx_PORDEVSR_IO_SEL 0x00780000 #define MPC85xx_PORDEVSR_IO_SEL_SHIFT 19 @@ -2345,6 +2353,10 @@ typedef struct ccsr_gur { #define MPC85xx_PMUXCR_SPI1_CS3_dbg_adi2_rxen 0x00000002 #define MPC85xx_PMUXCR_SPI1_CS3_GPO76 0x00000003 #endif +#ifdef CONFIG_BSC9132 +#define MPC85xx_PMUXCR0_SIM_SEL_MASK 0x0003b000 +#define MPC85xx_PMUXCR0_SIM_SEL 0x00014000 +#endif u32 pmuxcr2; /* Alt. function signal multiplex control 2 */ #if defined(CONFIG_P1010) || defined(CONFIG_P1014) #define MPC85xx_PMUXCR2_UART_GPIO 0x40000000 @@ -2375,6 +2387,7 @@ typedef struct ccsr_gur { #define MPC85xx_PMUXCR2_ETSECUSB_MASK 0x001f8000 #define MPC85xx_PMUXCR2_USB 0x00150000 #endif +#if defined(CONFIG_BSC9131) || defined(CONFIG_BSC9132) #if defined(CONFIG_BSC9131) #define MPC85xx_PMUXCR2_UART_CTS_B0_SIM_PD 0X40000000 #define MPC85xx_PMUXCR2_UART_CTS_B0_DSP_TMS 0X80000000 @@ -2418,8 +2431,9 @@ typedef struct ccsr_gur { #define MPC85xx_PMUXCR2_ANT3_AGC_GPO53 0x00000004 #define MPC85xx_PMUXCR2_ANT3_DO_TDM 0x00000001 #define MPC85xx_PMUXCR2_ANT3_DO_GPIO46_49 0x00000002 +#endif u32 pmuxcr3; - +#if defined(CONFIG_BSC9131) #define MPC85xx_PMUXCR3_ANT3_DO4_5_TDM 0x40000000 #define MPC85xx_PMUXCR3_ANT3_DO4_5_GPIO_50_51 0x80000000 #define MPC85xx_PMUXCR3_ANT3_DO6_7_TRIG_IN_SRESET_B 0x10000000 @@ -2434,6 +2448,13 @@ typedef struct ccsr_gur { #define MPC85xx_PMUXCR3_SPI2_CS3_GPO94 0x00040000 #define MPC85xx_PMUXCR3_ANT2_AGC_RSVD 0x00010000 #define MPC85xx_PMUXCR3_ANT2_GPO89 0x00030000 +#endif +#ifdef CONFIG_BSC9132 +#define MPC85xx_PMUXCR3_USB_SEL_MASK 0x0000ff00 +#define MPC85xx_PMUXCR3_UART2_SEL 0x00005000 +#define MPC85xx_PMUXCR3_UART3_SEL_MASK 0xc0000000 +#define MPC85xx_PMUXCR3_UART3_SEL 0x40000000 +#endif u32 pmuxcr4; #else u8 res6[8]; @@ -2727,6 +2748,12 @@ typedef struct ccsr_sec { #define SEC_CHANUM_MS_JRNUM_SHIFT 28 #define SEC_CHANUM_MS_DECONUM_MASK 0x0f000000 #define SEC_CHANUM_MS_DECONUM_SHIFT 24 +#define SEC_SECVID_MS_IPID_MASK 0xffff0000 +#define SEC_SECVID_MS_IPID_SHIFT 16 +#define SEC_SECVID_MS_MAJ_REV_MASK 0x0000ff00 +#define SEC_SECVID_MS_MAJ_REV_SHIFT 8 +#define SEC_CCBVID_ERA_MASK 0xff000000 +#define SEC_CCBVID_ERA_SHIFT 24 #endif typedef struct ccsr_qman { @@ -2962,6 +2989,7 @@ struct ccsr_pman { #endif #define CONFIG_SYS_MDIO1_OFFSET 0x24000 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET 0x2e000 +#define CONFIG_SYS_FSL_SEC_OFFSET 0x30000 #define CONFIG_SYS_MPC85xx_SERDES2_OFFSET 0xE3100 #define CONFIG_SYS_MPC85xx_SERDES1_OFFSET 0xE3000 #define CONFIG_SYS_SNVS_OFFSET 0xE6000 diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 2e0e292da0..b700a3a0be 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -401,8 +401,8 @@ extern void print_bats(void); #define MAS1_IPROT 0x40000000 #define MAS1_TID(x) (((x) << 16) & 0x3FFF0000) #define MAS1_TS 0x00001000 -#define MAS1_TSIZE(x) (((x) << 8) & 0x00000F00) -#define TSIZE_TO_BYTES(x) (1ULL << (((x) * 2) + 10)) +#define MAS1_TSIZE(x) (((x) << 7) & 0x00000F80) +#define TSIZE_TO_BYTES(x) (1ULL << ((x) + 10)) #define MAS2_EPN 0xFFFFF000 #define MAS2_X0 0x00000040 @@ -458,22 +458,38 @@ extern void print_bats(void); #define FSL_BOOKE_MAS7(rpn) \ (((u64)(rpn)) >> 32) -#define BOOKE_PAGESZ_1K 0 -#define BOOKE_PAGESZ_4K 1 -#define BOOKE_PAGESZ_16K 2 -#define BOOKE_PAGESZ_64K 3 -#define BOOKE_PAGESZ_256K 4 -#define BOOKE_PAGESZ_1M 5 -#define BOOKE_PAGESZ_4M 6 -#define BOOKE_PAGESZ_16M 7 -#define BOOKE_PAGESZ_64M 8 -#define BOOKE_PAGESZ_256M 9 -#define BOOKE_PAGESZ_1G 10 -#define BOOKE_PAGESZ_4G 11 -#define BOOKE_PAGESZ_16GB 12 -#define BOOKE_PAGESZ_64GB 13 -#define BOOKE_PAGESZ_256GB 14 -#define BOOKE_PAGESZ_1TB 15 +#define BOOKE_PAGESZ_1K 0 +#define BOOKE_PAGESZ_2K 1 +#define BOOKE_PAGESZ_4K 2 +#define BOOKE_PAGESZ_8K 3 +#define BOOKE_PAGESZ_16K 4 +#define BOOKE_PAGESZ_32K 5 +#define BOOKE_PAGESZ_64K 6 +#define BOOKE_PAGESZ_128K 7 +#define BOOKE_PAGESZ_256K 8 +#define BOOKE_PAGESZ_512K 9 +#define BOOKE_PAGESZ_1M 10 +#define BOOKE_PAGESZ_2M 11 +#define BOOKE_PAGESZ_4M 12 +#define BOOKE_PAGESZ_8M 13 +#define BOOKE_PAGESZ_16M 14 +#define BOOKE_PAGESZ_32M 15 +#define BOOKE_PAGESZ_64M 16 +#define BOOKE_PAGESZ_128M 17 +#define BOOKE_PAGESZ_256M 18 +#define BOOKE_PAGESZ_512M 19 +#define BOOKE_PAGESZ_1G 20 +#define BOOKE_PAGESZ_2G 21 +#define BOOKE_PAGESZ_4G 22 +#define BOOKE_PAGESZ_8G 23 +#define BOOKE_PAGESZ_16GB 24 +#define BOOKE_PAGESZ_32GB 25 +#define BOOKE_PAGESZ_64GB 26 +#define BOOKE_PAGESZ_128GB 27 +#define BOOKE_PAGESZ_256GB 28 +#define BOOKE_PAGESZ_512GB 29 +#define BOOKE_PAGESZ_1TB 30 +#define BOOKE_PAGESZ_2TB 31 #define TLBIVAX_ALL 4 #define TLBIVAX_TLB0 0 diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 19fe250305..8c91f0849b 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1113,6 +1113,8 @@ #define SVR_9130 0x860001 #define SVR_9131 0x860000 +#define SVR_9132 0x861000 +#define SVR_9232 0x861400 #define SVR_Unknown 0xFFFFFF diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 844fe8636d..86cf02ace4 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -47,7 +47,8 @@ endif endif ifdef MINIMAL -COBJS-y += cache.o +COBJS-y += cache.o time.o +SOBJS-y += ticks.o else SOBJS-y += ppcstring.o diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 6a7bf4b6c2..12270a4533 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -556,11 +556,11 @@ void board_init_f(ulong bootflag) #endif #if defined(CONFIG_MPC8220) bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ - bd->bi_inpfreq = gd->inp_clk; + bd->bi_inpfreq = gd->arch.inp_clk; bd->bi_pcifreq = gd->pci_clk; - bd->bi_vcofreq = gd->vco_clk; - bd->bi_pevfreq = gd->pev_clk; - bd->bi_flbfreq = gd->flb_clk; + bd->bi_vcofreq = gd->arch.vco_clk; + bd->bi_pevfreq = gd->arch.pev_clk; + bd->bi_flbfreq = gd->arch.flb_clk; /* store bootparam to sram (backward compatible), here? */ { @@ -568,10 +568,10 @@ void board_init_f(ulong bootflag) *sram++ = gd->ram_size; *sram++ = gd->bus_clk; - *sram++ = gd->inp_clk; + *sram++ = gd->arch.inp_clk; *sram++ = gd->cpu_clk; - *sram++ = gd->vco_clk; - *sram++ = gd->flb_clk; + *sram++ = gd->arch.vco_clk; + *sram++ = gd->arch.flb_clk; *sram++ = 0xb8c3ba11; /* boot signature */ } #endif @@ -580,16 +580,16 @@ void board_init_f(ulong bootflag) bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */ #if defined(CONFIG_CPM2) - bd->bi_cpmfreq = gd->cpm_clk; - bd->bi_brgfreq = gd->brg_clk; - bd->bi_sccfreq = gd->scc_clk; - bd->bi_vco = gd->vco_out; + bd->bi_cpmfreq = gd->arch.cpm_clk; + bd->bi_brgfreq = gd->arch.brg_clk; + bd->bi_sccfreq = gd->arch.scc_clk; + bd->bi_vco = gd->arch.vco_out; #endif /* CONFIG_CPM2 */ #if defined(CONFIG_MPC512X) - bd->bi_ipsfreq = gd->ips_clk; + bd->bi_ipsfreq = gd->arch.ips_clk; #endif /* CONFIG_MPC512X */ #if defined(CONFIG_MPC5xxx) - bd->bi_ipbfreq = gd->ipb_clk; + bd->bi_ipbfreq = gd->arch.ipb_clk; bd->bi_pcifreq = gd->pci_clk; #endif /* CONFIG_MPC5xxx */ bd->bi_baudrate = gd->baudrate; /* Console Baudrate */ @@ -649,10 +649,11 @@ void board_init_r(gd_t *id, ulong dest_addr) #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) /* - * The gd->cpu pointer is set to an address in flash before relocation. - * We need to update it to point to the same CPU entry in RAM. + * The gd->arch.cpu pointer is set to an address in flash before + * relocation. We need to update it to point to the same CPU entry + * in RAM. */ - gd->cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; + gd->arch.cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; /* * If we didn't know the cpu mask & # cores, we can save them of diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 7088293a36..0119a7b6eb 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -36,10 +36,8 @@ #include <asm/mp.h> #if defined(CONFIG_OF_LIBFDT) -#include <fdt.h> #include <libfdt.h> #include <fdt_support.h> - #endif #ifdef CONFIG_SYS_INIT_RAM_LOCK diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d7684d38eb..b2788d5d53 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -54,7 +54,7 @@ int cleanup_before_linux(void) void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) { - return (void *)(gd->ram_buf + paddr); + return (void *)(gd->arch.ram_buf + paddr); } void flush_dcache_range(unsigned long start, unsigned long stop) diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index 78a751d96f..3bedf77c5c 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -25,30 +25,13 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long fb_base; /* base address of frame buffer */ +/* Architecture-specific global data */ +struct arch_global_data { u8 *ram_buf; /* emulated RAM buffer */ - phys_size_t ram_size; /* RAM size */ - const void *fdt_blob; /* Our device tree, NULL if none */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR extern gd_t *gd diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c index 83858c1ffe..3752fab502 100644 --- a/arch/sandbox/lib/board.c +++ b/arch/sandbox/lib/board.c @@ -174,7 +174,7 @@ void board_init_f(ulong bootflag) mem = os_malloc(CONFIG_SYS_SDRAM_SIZE); assert(mem); - gd->ram_buf = mem; + gd->arch.ram_buf = mem; addr = (ulong)(mem + size); /* @@ -227,8 +227,8 @@ void board_init_r(gd_t *id, ulong dest_addr) #endif /* The Malloc area is at the top of simulated DRAM */ - mem_malloc_init((ulong)gd->ram_buf + gd->ram_size - TOTAL_MALLOC_LEN, - TOTAL_MALLOC_LEN); + mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size - + TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); /* initialize environment */ env_relocate(); diff --git a/arch/sh/include/asm/global_data.h b/arch/sh/include/asm/global_data.h index 9a2c19376d..0360230043 100644 --- a/arch/sh/include/asm/global_data.h +++ b/arch/sh/include/asm/global_data.h @@ -27,24 +27,11 @@ #ifndef __ASM_SH_GLOBALDATA_H_ #define __ASM_SH_GLOBALDATA_H_ -typedef struct global_data -{ - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif - phys_size_t ram_size; /* RAM size */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid */ - void **jt; /* Standalone app jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("r13") diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index aa63b35cab..9f019b1331 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -29,54 +29,11 @@ #include "asm/types.h" -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ - -typedef struct global_data { - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long bus_clk; - - phys_size_t ram_size; /* RAM size */ - unsigned long reloc_off; /* Relocation Offset */ - unsigned long reset_status; /* reset status register at boot */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long have_console; /* serial_init() was called */ - -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ -#endif -#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) - unsigned long fb_base; /* Base address of framebuffer memory */ -#endif -#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) - unsigned long post_log_word; /* Record POST activities */ - unsigned long post_log_res; /* success of POST test */ - unsigned long post_init_f_time; /* When post_init_f started */ -#endif -#ifdef CONFIG_BOARD_TYPES - unsigned long board_type; -#endif -#ifdef CONFIG_MODEM_SUPPORT - unsigned long do_mdm_init; - unsigned long be_quiet; -#endif -#ifdef CONFIG_LWMON - unsigned long kbd_status; -#endif - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -} gd_t; +/* Architecture-specific global data */ +struct arch_global_data { +}; -#include <asm-generic/global_data_flags.h> +#include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("%g7") diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 57324b6174..7b520f8dca 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -29,12 +29,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).o START-y = start.o -RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += resetvec.o start16.o +START-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o COBJS = interrupts.o cpu.o timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START-y) $(RESET_OBJS-)) +START := $(addprefix $(obj),$(START-y)) all: $(obj).depend $(START) $(LIB) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 315e87afeb..6a23974ff5 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -100,7 +100,9 @@ void setup_gdt(gd_t *id, u64 *gdt_addr) gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff); /* FS: data, read/write, 4 GB, base (Global Data Pointer) */ - gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093, (ulong)id, 0xfffff); + id->arch.gd_addr = id; + gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093, + (ulong)&id->arch.gd_addr, 0xfffff); /* 16-bit CS: code, read/execute, 64 kB, base 0 */ gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff); diff --git a/arch/x86/cpu/sc520/Makefile b/arch/x86/cpu/sc520/Makefile deleted file mode 100644 index f462264b8d..0000000000 --- a/arch/x86/cpu/sc520/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# -# (C) Copyright 2008 -# Graeme Russ, graeme.russ@gmail.com. -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2002 -# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB := $(obj)lib$(SOC).o - -COBJS-$(CONFIG_SYS_SC520) += sc520.o -COBJS-$(CONFIG_PCI) += sc520_pci.o -COBJS-$(CONFIG_SYS_SC520_RESET) += sc520_reset.o -COBJS-$(CONFIG_SYS_SC520) += sc520_sdram.o -COBJS-$(CONFIG_SYS_SC520_SSI) += sc520_ssi.o -COBJS-$(CONFIG_SYS_SC520_TIMER) += sc520_timer.o - -SOBJS-$(CONFIG_SYS_SC520) += sc520_car.o - -SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(call cmd_link_o_target, $(OBJS)) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -#########################################################################
\ No newline at end of file diff --git a/arch/x86/cpu/sc520/asm-offsets.c b/arch/x86/cpu/sc520/asm-offsets.c deleted file mode 100644 index 794f00cdb9..0000000000 --- a/arch/x86/cpu/sc520/asm-offsets.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c - * - * This program is used to generate definitions needed by - * assembly language modules. - * - * We use the technique used in the OSF Mach kernel code: - * generate asm statements containing #defines, - * compile this file to assembler, and then extract the - * #defines from the assembly-language output. - * - * 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. - */ - -#include <common.h> -#include <asm/arch/sc520.h> - -#include <linux/kbuild.h> - -int main(void) -{ - DEFINE(GENERATED_GD_RELOC_OFF, offsetof(gd_t, reloc_off)); - - DEFINE(GENERATED_SC520_PAR0, offsetof(struct sc520_mmcr, par[0])); - DEFINE(GENERATED_SC520_PAR1, offsetof(struct sc520_mmcr, par[1])); - DEFINE(GENERATED_SC520_PAR2, offsetof(struct sc520_mmcr, par[2])); - DEFINE(GENERATED_SC520_PAR3, offsetof(struct sc520_mmcr, par[3])); - DEFINE(GENERATED_SC520_PAR4, offsetof(struct sc520_mmcr, par[4])); - DEFINE(GENERATED_SC520_PAR5, offsetof(struct sc520_mmcr, par[5])); - DEFINE(GENERATED_SC520_PAR6, offsetof(struct sc520_mmcr, par[6])); - DEFINE(GENERATED_SC520_PAR7, offsetof(struct sc520_mmcr, par[7])); - DEFINE(GENERATED_SC520_PAR8, offsetof(struct sc520_mmcr, par[8])); - DEFINE(GENERATED_SC520_PAR9, offsetof(struct sc520_mmcr, par[9])); - DEFINE(GENERATED_SC520_PAR10, offsetof(struct sc520_mmcr, par[10])); - DEFINE(GENERATED_SC520_PAR11, offsetof(struct sc520_mmcr, par[11])); - DEFINE(GENERATED_SC520_PAR12, offsetof(struct sc520_mmcr, par[12])); - DEFINE(GENERATED_SC520_PAR13, offsetof(struct sc520_mmcr, par[13])); - DEFINE(GENERATED_SC520_PAR14, offsetof(struct sc520_mmcr, par[14])); - DEFINE(GENERATED_SC520_PAR15, offsetof(struct sc520_mmcr, par[15])); - - return 0; -} diff --git a/arch/x86/cpu/sc520/sc520.c b/arch/x86/cpu/sc520/sc520.c deleted file mode 100644 index 3fe85e7648..0000000000 --- a/arch/x86/cpu/sc520/sc520.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * (C) Copyright 2008-2011 - * Graeme Russ, <graeme.russ@gmail.com> - * - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/processor-flags.h> -#include <asm/arch/sc520.h> - -DECLARE_GLOBAL_DATA_PTR; - -sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)SC520_MMCR_BASE; - -int cpu_init_f(void) -{ - if (CONFIG_SYS_SC520_HIGH_SPEED) { - /* set it to 133 MHz and write back */ - writeb(0x02, &sc520_mmcr->cpuctl); - gd->cpu_clk = 133000000; - } else { - /* set it to 100 MHz and write back */ - writeb(0x01, &sc520_mmcr->cpuctl); - gd->cpu_clk = 100000000; - } - - /* wait at least one millisecond */ - asm("movl $0x2000, %%ecx\n" - "0: pushl %%ecx\n" - "popl %%ecx\n" - "loop 0b\n" : : : "ecx"); - - return x86_cpu_init_f(); -} - -int cpu_init_r(void) -{ - /* Disable the PAR used for CAR */ - writel(0x0000000, &sc520_mmcr->par[2]); - - /* turn on the SDRAM write buffer */ - writeb(0x11, &sc520_mmcr->dbctl); - - return x86_cpu_init_r(); -} diff --git a/arch/x86/cpu/sc520/sc520_car.S b/arch/x86/cpu/sc520/sc520_car.S deleted file mode 100644 index c04cc1f116..0000000000 --- a/arch/x86/cpu/sc520/sc520_car.S +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (C) Copyright 2010-2011 - * Graeme Russ, <graeme.russ@gmail.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 <config.h> -#include <asm/processor-flags.h> -#include <asm/arch/sc520.h> -#include <generated/asm-offsets.h> - -.section .text - -.globl car_init -car_init: - /* - * How to enable Cache-As-RAM for the AMD Elan SC520: - * 1. Turn off the CPU Cache (may not be strictly required) - * 2. Set code execution PAR (usually the BOOTCS region) to be - * non-cachable - * 3. Create a Cachable PAR Region for an area of memory which is - * a) NOT where the code is being executed - * b) NOT SDRAM (Controller not initialised yet) - * c) WILL response to read requests - * The easiest way to do this is to create a second BOOTCS - * PAR mappnig with an address != the PAR in step 2 - * 4. Issue a wbinvd to invalidate the CPU cache - * 5. Turn on the CPU Cache - * 6. Read 16kB from the cached PAR region setup in step 3 - * 7. Turn off the CPU Cache (but DO NOT issue a wbinvd) - * - * The following code uses PAR2 as the cached PAR (PAR0 and PAR1 - * are avoided as these are the only two PARs which can be used - * as PCI BUS Memory regions which the board might require) - * - * The configuration of PAR2 must be set in the board configuration - * file as CONFIG_SYS_SC520_CAR_PAR - */ - - /* Configure Cache-As-RAM PAR */ - movl $CONFIG_SYS_SC520_CAR_PAR, %eax - movl $(SC520_MMCR_BASE + GENERATED_SC520_PAR2), %edi - movl %eax, (%edi) - - /* Trash the cache then turn it on */ - wbinvd - movl %cr0, %eax - andl $~(X86_CR0_NW | X86_CR0_CD), %eax - movl %eax, %cr0 - - /* - * The cache is now enabled and empty. Map a region of memory to - * it by reading that region. - */ - movl $CONFIG_SYS_CAR_ADDR, %esi - movl $CONFIG_SYS_CAR_SIZE, %ecx - shrl $2, %ecx /* we are reading longs */ - cld - rep lodsl - - /* Turn off the cache, but don't trash it */ - movl %cr0, %eax - orl $(X86_CR0_NW | X86_CR0_CD), %eax - movl %eax, %cr0 - - /* Clear the CAR region */ - xorl %eax, %eax - movl $CONFIG_SYS_CAR_ADDR, %edi - movl $CONFIG_SYS_CAR_SIZE, %ecx - shrl $2, %ecx /* we are writing longs */ - rep stosl - - /* - * Done - We should now have CONFIG_SYS_CAR_SIZE bytes of - * Cache-As-RAM - */ - jmp car_init_ret diff --git a/arch/x86/cpu/sc520/sc520_pci.c b/arch/x86/cpu/sc520/sc520_pci.c deleted file mode 100644 index 52d07c119a..0000000000 --- a/arch/x86/cpu/sc520/sc520_pci.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * (C) Copyright 2008-2011 - * Graeme Russ, <graeme.russ@gmail.com> - * - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <pci.h> -#include <asm/io.h> -#include <asm/pci.h> -#include <asm/arch/pci.h> -#include <asm/arch/sc520.h> - -static struct { - u8 priority; - u16 level_reg; - u8 level_bit; -} sc520_irq[] = { - { SC520_IRQ0, 0, 0x01 }, - { SC520_IRQ1, 0, 0x02 }, - { SC520_IRQ2, 1, 0x02 }, - { SC520_IRQ3, 0, 0x08 }, - { SC520_IRQ4, 0, 0x10 }, - { SC520_IRQ5, 0, 0x20 }, - { SC520_IRQ6, 0, 0x40 }, - { SC520_IRQ7, 0, 0x80 }, - - { SC520_IRQ8, 1, 0x01 }, - { SC520_IRQ9, 1, 0x02 }, - { SC520_IRQ10, 1, 0x04 }, - { SC520_IRQ11, 1, 0x08 }, - { SC520_IRQ12, 1, 0x10 }, - { SC520_IRQ13, 1, 0x20 }, - { SC520_IRQ14, 1, 0x40 }, - { SC520_IRQ15, 1, 0x80 } -}; - -/* The interrupt used for PCI INTA-INTD */ -int sc520_pci_ints[15] = { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1 -}; - -/* utility function to configure a pci interrupt */ -int pci_sc520_set_irq(int pci_pin, int irq) -{ - int i; - u8 tmpb; - u16 tmpw; - - debug("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq); - - if (irq < 0 || irq > 15) - return -1; /* illegal irq */ - - if (pci_pin < 0 || pci_pin > 15) - return -1; /* illegal pci int pin */ - - /* first disable any non-pci interrupt source that use - * this level */ - - /* PCI interrupt mapping (A through D)*/ - for (i = 0; i <= 3 ; i++) { - tmpb = readb(&sc520_mmcr->pci_int_map[i]); - - if (tmpb == sc520_irq[irq].priority) - writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pci_int_map[i]); - } - - /* GP IRQ interrupt mapping */ - for (i = 0; i <= 10 ; i++) { - tmpb = readb(&sc520_mmcr->gp_int_map[i]); - - if (tmpb == sc520_irq[irq].priority) - writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_int_map[i]); - } - - /* Set the trigger to level */ - tmpb = readb(&sc520_mmcr->pic_mode[sc520_irq[irq].level_reg]); - tmpb |= sc520_irq[irq].level_bit; - writeb(tmpb, &sc520_mmcr->pic_mode[sc520_irq[irq].level_reg]); - - - if (pci_pin < 4) { - /* PCI INTA-INTD */ - /* route the interrupt */ - writeb(sc520_irq[irq].priority, - &sc520_mmcr->pci_int_map[pci_pin]); - } else { - /* GPIRQ0-GPIRQ10 used for additional PCI INTS */ - writeb(sc520_irq[irq].priority, - &sc520_mmcr->gp_int_map[pci_pin - 4]); - - /* also set the polarity in this case */ - tmpw = readw(&sc520_mmcr->intpinpol); - tmpw |= (1 << (pci_pin-4)); - writew(tmpw, &sc520_mmcr->intpinpol); - } - - /* register the pin */ - sc520_pci_ints[pci_pin] = irq; - - - return 0; /* OK */ -} - -void pci_sc520_init(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0xff; - hose->region_count = pci_set_regions(hose); - - pci_setup_type1(hose); - - pci_register_hose(hose); - - hose->last_busno = pci_hose_scan(hose); - - /* enable target memory acceses on host brige */ - pci_write_config_word(0, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); -} diff --git a/arch/x86/cpu/sc520/sc520_sdram.c b/arch/x86/cpu/sc520/sc520_sdram.c deleted file mode 100644 index 9dc13342e3..0000000000 --- a/arch/x86/cpu/sc520/sc520_sdram.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * Graeme Russ, <graeme.russ@gmail.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/processor-flags.h> -#include <asm/arch/sc520.h> - -DECLARE_GLOBAL_DATA_PTR; - -struct sc520_sdram_info { - u8 banks; - u8 columns; - u8 rows; - u8 size; -}; - -static void sc520_sizemem(void); -static void sc520_set_dram_timing(void); -static void sc520_set_dram_refresh_rate(void); -static void sc520_enable_dram_refresh(void); -static void sc520_enable_sdram(void); - -int dram_init_f(void) -{ - sc520_sizemem(); - sc520_set_dram_timing(); - sc520_set_dram_refresh_rate(); - sc520_enable_dram_refresh(); - sc520_enable_sdram(); - - return 0; -} - -static inline void sc520_dummy_write(void) -{ - writew(0x0000, CACHELINESZ); -} -static inline void sc520_issue_sdram_op_mode_select(u8 command) -{ - writeb(command, &sc520_mmcr->drcctl); - sc520_dummy_write(); -} - -static inline int check_long(u32 test_long) -{ - u8 i; - u8 tmp_byte = (u8)(test_long & 0x000000ff); - - for (i = 1; i < 4; i++) { - if ((u8)((test_long >> (i * 8)) & 0x000000ff) != tmp_byte) - return -1; - } - - return 0; -} - -static inline int write_and_test(u32 data, u32 address) -{ - writel(data, address); - if (readl(address) == data) - return 0; /* Good */ - else - return -1; /* Bad */ -} - -static void sc520_enable_sdram(void) -{ - u32 par_config; - - /* Enable Writes, Caching and Code Execution to SDRAM */ - par_config = readl(&sc520_mmcr->par[3]); - par_config &= ~(SC520_PAR_EXEC_DIS | - SC520_PAR_CACHE_DIS | - SC520_PAR_WRITE_DIS); - writel(par_config, &sc520_mmcr->par[3]); - - par_config = readl(&sc520_mmcr->par[4]); - par_config &= ~(SC520_PAR_EXEC_DIS | - SC520_PAR_CACHE_DIS | - SC520_PAR_WRITE_DIS); - writel(par_config, &sc520_mmcr->par[4]); -} - -static void sc520_set_dram_timing(void) -{ - u8 drctmctl = 0x00; - -#if defined CONFIG_SYS_SDRAM_DRCTMCTL - /* just have your hardware designer _GIVE_ you what you need here! */ - drctmctl = CONFIG_SYS_SDRAM_DRCTMCTL; -#else - switch (CONFIG_SYS_SDRAM_RAS_CAS_DELAY) { - case 2: - break; - case 3: - drctmctl |= 0x01; - break; - case 4: - default: - drctmctl |= 0x02; - break; - } - - switch (CONFIG_SYS_SDRAM_PRECHARGE_DELAY) { - case 2: - break; - case 3: - drctmctl |= 0x04; - break; - case 4: - default: - drctmctl |= 0x08; - break; - - case 6: - drctmctl |= 0x0c; - break; - } - - switch (CONFIG_SYS_SDRAM_CAS_LATENCY) { - case 2: - break; - case 3: - default: - drctmctl |= 0x10; - break; - } -#endif - writeb(drctmctl, &sc520_mmcr->drctmctl); - - /* Issue load mode register command */ - sc520_issue_sdram_op_mode_select(0x03); -} - -static void sc520_set_dram_refresh_rate(void) -{ - u8 drctl; - - drctl = readb(&sc520_mmcr->drcctl); - drctl &= 0xcf; - - switch (CONFIG_SYS_SDRAM_REFRESH_RATE) { - case 78: - break; - case 156: - default: - drctl |= 0x10; - break; - case 312: - drctl |= 0x20; - break; - case 624: - drctl |= 0x30; - break; - } - - writeb(drctl, &sc520_mmcr->drcctl); -} - -static void sc520_enable_dram_refresh(void) -{ - u8 drctl; - - drctl = readb(&sc520_mmcr->drcctl); - drctl &= 0x30; /* keep refresh rate */ - drctl |= 0x08; /* enable refresh, normal mode */ - - writeb(drctl, &sc520_mmcr->drcctl); -} - -static void sc520_get_bank_info(int bank, struct sc520_sdram_info *bank_info) -{ - u32 col_data; - u32 row_data; - - u32 drcbendadr; - u16 drccfg; - - u8 banks = 0x00; - u8 columns = 0x00; - u8 rows = 0x00; - - bank_info->banks = 0x00; - bank_info->columns = 0x00; - bank_info->rows = 0x00; - bank_info->size = 0x00; - - if ((bank < 0) || (bank > 3)) { - printf("Bad Bank ID\n"); - return; - } - - /* Save configuration */ - drcbendadr = readl(&sc520_mmcr->drcbendadr); - drccfg = readw(&sc520_mmcr->drccfg); - - /* Setup SDRAM Bank to largest possible size */ - writew(0x000b << (bank * 4), &sc520_mmcr->drccfg); - - /* Set ending address for this bank */ - writel(0x000000ff << (bank * 8), &sc520_mmcr->drcbendadr); - - /* write col 11 wrap adr */ - if (write_and_test(COL11_DATA, COL11_ADR) != 0) - goto restore_and_exit; - - /* write col 10 wrap adr */ - if (write_and_test(COL10_DATA, COL10_ADR) != 0) - goto restore_and_exit; - - /* write col 9 wrap adr */ - if (write_and_test(COL09_DATA, COL09_ADR) != 0) - goto restore_and_exit; - - /* write col 8 wrap adr */ - if (write_and_test(COL08_DATA, COL08_ADR) != 0) - goto restore_and_exit; - - col_data = readl(COL11_ADR); - - /* All four bytes in the read long must be the same */ - if (check_long(col_data) < 0) - goto restore_and_exit; - - if ((col_data >= COL08_DATA) && (col_data <= COL11_DATA)) - columns = (u8)(col_data & 0x000000ff); - else - goto restore_and_exit; - - /* write row 14 wrap adr */ - if (write_and_test(ROW14_DATA, ROW14_ADR) != 0) - goto restore_and_exit; - - /* write row 13 wrap adr */ - if (write_and_test(ROW13_DATA, ROW13_ADR) != 0) - goto restore_and_exit; - - /* write row 12 wrap adr */ - if (write_and_test(ROW12_DATA, ROW12_ADR) != 0) - goto restore_and_exit; - - /* write row 11 wrap adr */ - if (write_and_test(ROW11_DATA, ROW11_ADR) != 0) - goto restore_and_exit; - - if (write_and_test(ROW10_DATA, ROW10_ADR) != 0) - goto restore_and_exit; - - /* - * read data @ row 12 wrap adr to determine number of banks, - * and read data @ row 14 wrap adr to determine number of rows. - * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM. - * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4 - * if data @ row 12 wrap == 11 or 12, we have 4 banks, - */ - row_data = readl(ROW12_ADR); - - /* All four bytes in the read long must be the same */ - if (check_long(row_data) != 0) - goto restore_and_exit; - - switch (row_data) { - case ROW10_DATA: - banks = 2; - break; - - case ROW11_DATA: - case ROW12_DATA: - banks = 4; - break; - - default: - goto restore_and_exit; - } - - row_data = readl(ROW14_ADR); - - /* All four bytes in the read long must be the same */ - if (check_long(row_data) != 0) - goto restore_and_exit; - - switch (row_data) { - case ROW11_DATA: - case ROW12_DATA: - case ROW13_DATA: - case ROW14_DATA: - rows = (u8)(row_data & 0x000000ff); - break; - - default: - goto restore_and_exit; - } - - bank_info->banks = banks; - bank_info->columns = columns; - bank_info->rows = rows; - - if ((bank_info->banks != 0) && - (bank_info->columns != 0) && - (bank_info->rows != 0)) { - bank_info->size = bank_info->rows; - bank_info->size >>= (11 - bank_info->columns); - bank_info->size++; - } - -restore_and_exit: - /* Restore configuration */ - writel(drcbendadr, &sc520_mmcr->drcbendadr); - writew(drccfg, &sc520_mmcr->drccfg); -} - -static void sc520_setup_sizemem(void) -{ - u8 i; - - /* Disable write buffer */ - writeb(0x00, &sc520_mmcr->dbctl); - - /* Disable ECC */ - writeb(0x00, &sc520_mmcr->eccctl); - - /* Set slowest SDRAM timing */ - writeb(0x1e, &sc520_mmcr->drctmctl); - - /* Issue a NOP to all SDRAM banks */ - sc520_issue_sdram_op_mode_select(0x01); - - /* Delay for 100 microseconds */ - udelay(100); - - /* Issue 'All Banks Precharge' command */ - sc520_issue_sdram_op_mode_select(0x02); - - /* Issue 2 'Auto Refresh Enable' command */ - sc520_issue_sdram_op_mode_select(0x04); - sc520_dummy_write(); - - /* Issue 'Load Mode Register' command */ - sc520_issue_sdram_op_mode_select(0x03); - - /* Issue 8 more 'Auto Refresh Enable' commands */ - sc520_issue_sdram_op_mode_select(0x04); - for (i = 0; i < 7; i++) - sc520_dummy_write(); - - /* Set control register to 'Normal Mode' */ - writeb(0x00, &sc520_mmcr->drcctl); -} - -static void sc520_sizemem(void) -{ - struct sc520_sdram_info sdram_info[4]; - u8 bank_config = 0x00; - u8 end_addr = 0x00; - u16 drccfg = 0x0000; - u32 drcbendadr = 0x00000000; - u8 i; - - /* Use PARs to disable caching of maximum allowable 256MB SDRAM */ - writel(SC520_SDRAM1_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[3]); - writel(SC520_SDRAM2_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[4]); - - sc520_setup_sizemem(); - - gd->ram_size = 0; - - /* Size each SDRAM bank */ - for (i = 0; i <= 3; i++) { - sc520_get_bank_info(i, &sdram_info[i]); - - if (sdram_info[i].banks != 0) { - /* Update Configuration register */ - bank_config = sdram_info[i].columns - 8; - - if (sdram_info[i].banks == 4) - bank_config |= 0x08; - - drccfg |= bank_config << (i * 4); - - /* Update End Address register */ - end_addr += sdram_info[i].size; - drcbendadr |= (end_addr | 0x80) << (i * 8); - - gd->ram_size += sdram_info[i].size << 22; - } - - /* Issue 'All Banks Precharge' command */ - sc520_issue_sdram_op_mode_select(0x02); - - /* Set control register to 'Normal Mode' */ - writeb(0x00, &sc520_mmcr->drcctl); - } - - writel(drcbendadr, &sc520_mmcr->drcbendadr); - writew(drccfg, &sc520_mmcr->drccfg); - - /* Clear PARs preventing caching of SDRAM */ - writel(0x00000000, &sc520_mmcr->par[3]); - writel(0x00000000, &sc520_mmcr->par[4]); -} - -int dram_init(void) -{ - ulong dram_ctrl; - ulong dram_present = 0x00000000; - - /* - * We read-back the configuration of the dram - * controller that the assembly code wrote - */ - dram_ctrl = readl(&sc520_mmcr->drcbendadr); - - gd->bd->bi_dram[0].start = 0; - if (dram_ctrl & 0x80) { - /* bank 0 enabled */ - gd->bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22; - dram_present = gd->bd->bi_dram[1].start; - gd->bd->bi_dram[0].size = gd->bd->bi_dram[1].start; - } else { - gd->bd->bi_dram[0].size = 0; - gd->bd->bi_dram[1].start = gd->bd->bi_dram[0].start; - } - - if (dram_ctrl & 0x8000) { - /* bank 1 enabled */ - gd->bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14; - dram_present = gd->bd->bi_dram[2].start; - gd->bd->bi_dram[1].size = gd->bd->bi_dram[2].start - - gd->bd->bi_dram[1].start; - } else { - gd->bd->bi_dram[1].size = 0; - gd->bd->bi_dram[2].start = gd->bd->bi_dram[1].start; - } - - if (dram_ctrl & 0x800000) { - /* bank 2 enabled */ - gd->bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6; - dram_present = gd->bd->bi_dram[3].start; - gd->bd->bi_dram[2].size = gd->bd->bi_dram[3].start - - gd->bd->bi_dram[2].start; - } else { - gd->bd->bi_dram[2].size = 0; - gd->bd->bi_dram[3].start = gd->bd->bi_dram[2].start; - } - - if (dram_ctrl & 0x80000000) { - /* bank 3 enabled */ - dram_present = (dram_ctrl & 0x7f000000) >> 2; - gd->bd->bi_dram[3].size = dram_present - - gd->bd->bi_dram[3].start; - } else { - gd->bd->bi_dram[3].size = 0; - } - - gd->ram_size = dram_present; - - return 0; -} diff --git a/arch/x86/cpu/sc520/sc520_ssi.c b/arch/x86/cpu/sc520/sc520_ssi.c deleted file mode 100644 index cc601e56e4..0000000000 --- a/arch/x86/cpu/sc520/sc520_ssi.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/ssi.h> -#include <asm/arch/sc520.h> - -int ssi_set_interface(int freq, int lsb_first, int inv_clock, int inv_phase) -{ - u8 temp = 0; - - if (freq >= 8192) - temp |= CTL_CLK_SEL_4; - else if (freq >= 4096) - temp |= CTL_CLK_SEL_8; - else if (freq >= 2048) - temp |= CTL_CLK_SEL_16; - else if (freq >= 1024) - temp |= CTL_CLK_SEL_32; - else if (freq >= 512) - temp |= CTL_CLK_SEL_64; - else if (freq >= 256) - temp |= CTL_CLK_SEL_128; - else if (freq >= 128) - temp |= CTL_CLK_SEL_256; - else - temp |= CTL_CLK_SEL_512; - - if (!lsb_first) - temp |= MSBF_ENB; - - if (inv_clock) - temp |= CLK_INV_ENB; - - if (inv_phase) - temp |= PHS_INV_ENB; - - writeb(temp, &sc520_mmcr->ssictl); - - return 0; -} - -u8 ssi_txrx_byte(u8 data) -{ - writeb(data, &sc520_mmcr->ssixmit); - while (readb(&sc520_mmcr->ssista) & SSISTA_BSY) - ; - writeb(SSICMD_CMD_SEL_XMITRCV, &sc520_mmcr->ssicmd); - while (readb(&sc520_mmcr->ssista) & SSISTA_BSY) - ; - - return readb(&sc520_mmcr->ssircv); -} - -void ssi_tx_byte(u8 data) -{ - writeb(data, &sc520_mmcr->ssixmit); - while (readb(&sc520_mmcr->ssista) & SSISTA_BSY) - ; - writeb(SSICMD_CMD_SEL_XMIT, &sc520_mmcr->ssicmd); -} - -u8 ssi_rx_byte(void) -{ - while (readb(&sc520_mmcr->ssista) & SSISTA_BSY) - ; - writeb(SSICMD_CMD_SEL_RCV, &sc520_mmcr->ssicmd); - while (readb(&sc520_mmcr->ssista) & SSISTA_BSY) - ; - - return readb(&sc520_mmcr->ssircv); -} diff --git a/arch/x86/cpu/sc520/sc520_timer.c b/arch/x86/cpu/sc520/sc520_timer.c deleted file mode 100644 index 41f121f86f..0000000000 --- a/arch/x86/cpu/sc520/sc520_timer.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * (C) Copyright 2008-2011 - * Graeme Russ, <graeme.russ@gmail.com> - * - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/interrupt.h> -#include <asm/arch/sc520.h> - -void sc520_timer_isr(void) -{ - /* Ack the GP Timer Interrupt */ - writeb(0x02, &sc520_mmcr->gptmrsta); -} - -int timer_init(void) -{ - /* Register the SC520 specific timer interrupt handler */ - register_timer_isr(sc520_timer_isr); - - /* Install interrupt handler for GP Timer 1 */ - irq_install_handler (0, timer_isr, NULL); - - /* Map GP Timer 1 to Master PIC IR0 */ - writeb(0x01, &sc520_mmcr->gp_tmr_int_map[1]); - - /* Disable GP Timers 1 & 2 - Allow configuration writes */ - writew(0x4000, &sc520_mmcr->gptmr1ctl); - writew(0x4000, &sc520_mmcr->gptmr2ctl); - - /* Reset GP Timers 1 & 2 */ - writew(0x0000, &sc520_mmcr->gptmr1cnt); - writew(0x0000, &sc520_mmcr->gptmr2cnt); - - /* Setup GP Timer 2 as a 100kHz (10us) prescaler */ - writew(83, &sc520_mmcr->gptmr2maxcmpa); - writew(0xc001, &sc520_mmcr->gptmr2ctl); - - /* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */ - writew(100, &sc520_mmcr->gptmr1maxcmpa); - writew(0xe009, &sc520_mmcr->gptmr1ctl); - - unmask_irq(0); - - /* Clear the GP Timer 1 status register to get the show rolling*/ - writeb(0x02, &sc520_mmcr->gptmrsta); - - return 0; -} - -/* Allow boards to override udelay implementation */ -void __udelay(unsigned long usec) - __attribute__((weak, alias("sc520_udelay"))); - -void sc520_udelay(unsigned long usec) -{ - int m = 0; - long u; - - readw(&sc520_mmcr->swtmrmilli); - readw(&sc520_mmcr->swtmrmicro); - - do { - m += readw(&sc520_mmcr->swtmrmilli); - u = readw(&sc520_mmcr->swtmrmicro) + (m * 1000); - } while (u < usec); -} diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index e960e21f6e..f389584567 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -113,9 +113,6 @@ car_init_ret: /* Set second parameter to setup_gdt */ movl %esp, %edx - /* gd->gd_addr = gd (Required to allow gd->xyz to work) */ - movl %eax, (%eax) - /* Setup global descriptor table so gd->xyz works */ call setup_gdt @@ -171,9 +168,6 @@ board_init_f_r_trampoline: /* Set second parameter to setup_gdt */ movl %esp, %edx - /* gd->gd_addr = gd (Required to allow gd->xyz to work) */ - movl %eax, (%eax) - /* Setup global descriptor table so gd->xyz works */ call setup_gdt diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds index 0c6f0e31d8..2313cd793a 100644 --- a/arch/x86/cpu/u-boot.lds +++ b/arch/x86/cpu/u-boot.lds @@ -86,7 +86,7 @@ SECTIONS __bios_start = LOADADDR(.bios); __bios_size = SIZEOF(.bios); -#ifndef CONFIG_X86_NO_RESET_VECTOR +#ifdef CONFIG_X86_RESET_VECTOR /* * The following expressions place the 16-bit Real-Mode code and diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h index 77ae304969..78d3a9d49e 100644 --- a/arch/x86/include/asm/arch-coreboot/sysinfo.h +++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h @@ -32,7 +32,7 @@ #include <common.h> #include <compiler.h> -#include <fdt.h> +#include <libfdt.h> #include <asm/arch/tables.h> /* Allow a maximum of 16 memory range definitions. */ diff --git a/arch/x86/include/asm/arch-sc520/pci.h b/arch/x86/include/asm/arch-sc520/pci.h deleted file mode 100644 index 12ba656ff0..0000000000 --- a/arch/x86/include/asm/arch-sc520/pci.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>. - * - * 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 _ASM_IC_SC520_PCI_H_ -#define _ASM_IC_SC520_PCI_H_ 1 - -/* bus mapping constants (used for PCI core initialization) */ /* bus mapping constants */ -#define SC520_REG_ADDR 0x00000cf8 -#define SC520_REG_DATA 0x00000cfc - -#define SC520_ISA_MEM_PHYS 0x00000000 -#define SC520_ISA_MEM_BUS 0x00000000 -#define SC520_ISA_MEM_SIZE 0x01000000 - -#define SC520_ISA_IO_PHYS 0x00000000 -#define SC520_ISA_IO_BUS 0x00000000 -#define SC520_ISA_IO_SIZE 0x00001000 - -/* PCI I/O space from 0x1000 to 0xdfff - * (make 0xe000-0xfdff available for stuff like PCCard boot) */ -#define SC520_PCI_IO_PHYS 0x00001000 -#define SC520_PCI_IO_BUS 0x00001000 -#define SC520_PCI_IO_SIZE 0x0000d000 - -/* system memory from 0x00000000 to 0x0fffffff */ -#define SC520_PCI_MEMORY_PHYS 0x00000000 -#define SC520_PCI_MEMORY_BUS 0x00000000 -#define SC520_PCI_MEMORY_SIZE 0x10000000 - -/* PCI bus memory from 0x10000000 to 0x26ffffff - * (make 0x27000000 - 0x27ffffff available for stuff like PCCard boot) */ -#define SC520_PCI_MEM_PHYS 0x10000000 -#define SC520_PCI_MEM_BUS 0x10000000 -#define SC520_PCI_MEM_SIZE 0x17000000 - -/* pin number used for PCI interrupt mappings */ -#define SC520_PCI_INTA 0 -#define SC520_PCI_INTB 1 -#define SC520_PCI_INTC 2 -#define SC520_PCI_INTD 3 -#define SC520_PCI_GPIRQ0 4 -#define SC520_PCI_GPIRQ1 5 -#define SC520_PCI_GPIRQ2 6 -#define SC520_PCI_GPIRQ3 7 -#define SC520_PCI_GPIRQ4 8 -#define SC520_PCI_GPIRQ5 9 -#define SC520_PCI_GPIRQ6 10 -#define SC520_PCI_GPIRQ7 11 -#define SC520_PCI_GPIRQ8 12 -#define SC520_PCI_GPIRQ9 13 -#define SC520_PCI_GPIRQ10 14 - -extern int sc520_pci_ints[]; - -void pci_sc520_init(struct pci_controller *hose); -int pci_set_regions(struct pci_controller *hose); -int pci_sc520_set_irq(int pci_pin, int irq); - -#endif diff --git a/arch/x86/include/asm/arch-sc520/sc520.h b/arch/x86/include/asm/arch-sc520/sc520.h deleted file mode 100644 index 9dc29d39bc..0000000000 --- a/arch/x86/include/asm/arch-sc520/sc520.h +++ /dev/null @@ -1,372 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>. - * - * 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 _ASM_IC_SC520_H_ -#define _ASM_IC_SC520_H_ 1 - -#ifndef __ASSEMBLY__ - -void init_sc520(void); -unsigned long init_sc520_dram(void); -void sc520_udelay(unsigned long usec); - -/* Memory mapped configuration registers */ -typedef struct sc520_mmcr { - u16 revid; /* ElanSC520 microcontroller revision id */ - u8 cpuctl; /* am5x86 CPU control */ - - u8 pad_0x003[0x0d]; - - u8 drcctl; /* SDRAM control */ - u8 pad_0x011[0x01]; - u8 drctmctl; /* SDRAM timing control */ - u8 pad_0x013[0x01]; - u16 drccfg; /* SDRAM bank configuration*/ - u8 pad_0x016[0x02]; - u32 drcbendadr; /* SDRAM bank 0-3 ending address*/ - u8 pad_0x01c[0x04]; - u8 eccctl; /* ECC control */ - u8 eccsta; /* ECC status */ - u8 eccckbpos; /* ECC check bit position */ - u8 ecccktest; /* ECC Check Code Test */ - u32 eccsbadd; /* ECC single-bit error address */ - u32 eccmbadd; /* ECC multi-bit error address */ - - u8 pad_0x02c[0x14]; - - u8 dbctl; /* SDRAM buffer control */ - - u8 pad_0x041[0x0f]; - - u16 bootcsctl; /* /BOOTCS control */ - u8 pad_0x052[0x02]; - u16 romcs1ctl; /* /ROMCS1 control */ - u16 romcs2ctl; /* /ROMCS2 control */ - - u8 pad_0x058[0x08]; - - u16 hbctl; /* host bridge control */ - u16 hbtgtirqctl; /* host bridge target interrupt control */ - u16 hbtgtirqsta; /* host bridge target interrupt status */ - u16 hbmstirqctl; /* host bridge target interrupt control */ - u16 hbmstirqsta; /* host bridge master interrupt status */ - u8 pad_0x06a[0x02]; - u32 mstintadd; /* host bridge master interrupt address */ - - u8 sysarbctl; /* system arbiter control */ - u8 pciarbsta; /* PCI bus arbiter status */ - u16 sysarbmenb; /* system arbiter master enable */ - u32 arbprictl; /* arbiter priority control */ - - u8 pad_0x078[0x08]; - - u8 adddecctl; /* address decode control */ - u8 pad_0x081[0x01]; - u16 wpvsta; /* write-protect violation status */ - u8 pad_0x084[0x04]; - u32 par[16]; /* programmable address regions */ - - u8 pad_0x0c8[0x0b38]; - - u8 gpecho; /* GP echo mode */ - u8 gpcsdw; /* GP chip select data width */ - u16 gpcsqual; /* GP chip select qualification */ - u8 pad_0xc04[0x4]; - u8 gpcsrt; /* GP chip select recovery time */ - u8 gpcspw; /* GP chip select pulse width */ - u8 gpcsoff; /* GP chip select offset */ - u8 gprdw; /* GP read pulse width */ - u8 gprdoff; /* GP read offset */ - u8 gpwrw; /* GP write pulse width */ - u8 gpwroff; /* GP write offset */ - u8 gpalew; /* GP ale pulse width */ - u8 gpaleoff; /* GP ale offset */ - - u8 pad_0xc11[0x0f]; - - u16 piopfs15_0; /* PIO15-PIO0 pin function select */ - u16 piopfs31_16; /* PIO31-PIO16 pin function select */ - u8 cspfs; /* chip select pin function select */ - u8 pad_0xc25[0x01]; - u8 clksel; /* clock select */ - u8 pad_0xc27[0x01]; - u16 dsctl; /* drive strength control */ - u16 piodir15_0; /* PIO15-PIO0 direction */ - u16 piodir31_16; /* PIO31-PIO16 direction */ - u8 pad_0xc2e[0x02]; - u16 piodata15_0 ; /* PIO15-PIO0 data */ - u16 piodata31_16; /* PIO31-PIO16 data */ - u16 pioset15_0; /* PIO15-PIO0 set */ - u16 pioset31_16; /* PIO31-PIO16 set */ - u16 pioclr15_0; /* PIO15-PIO0 clear */ - u16 pioclr31_16; /* PIO31-PIO16 clear */ - - u8 pad_0xc3c[0x24]; - - u16 swtmrmilli; /* software timer millisecond count */ - u16 swtmrmicro; /* software timer microsecond count */ - u8 swtmrcfg; /* software timer configuration */ - - u8 pad_0xc65[0x0b]; - - u8 gptmrsta; /* GP timers status register */ - u8 pad_0xc71; - u16 gptmr0ctl; /* GP timer 0 mode/control */ - u16 gptmr0cnt; /* GP timer 0 count */ - u16 gptmr0maxcmpa; /* GP timer 0 maxcount compare A */ - u16 gptmr0maxcmpb; /* GP timer 0 maxcount compare B */ - u16 gptmr1ctl; /* GP timer 1 mode/control */ - u16 gptmr1cnt; /* GP timer 1 count */ - u16 gptmr1maxcmpa; /* GP timer 1 maxcount compare A */ - u16 gptmr1maxcmpb; /* GP timer 1 maxcount compare B*/ - u16 gptmr2ctl; /* GP timer 2 mode/control */ - u16 gptmr2cnt; /* GP timer 2 count */ - u8 pad_0xc86[0x08]; - u16 gptmr2maxcmpa; /* GP timer 2 maxcount compare A */ - - u8 pad_0xc90[0x20]; - - u16 wdtmrctl; /* watchdog timer control */ - u16 wdtmrcntl; /* watchdog timer count low */ - u16 wdtmrcnth; /* watchdog timer count high */ - - u8 pad_0xcb6[0x0a]; - - u8 uart1ctl; /* UART 1 general control */ - u8 uart1sta; /* UART 1 general status */ - u8 uart1fcrshad; /* UART 1 FIFO control shadow */ - u8 pad_0xcc3[0x01]; - u8 uart2ctl; /* UART 2 general control */ - u8 uart2sta; /* UART 2 general status */ - u8 uart2fcrshad; /* UART 2 FIFO control shadow */ - - u8 pad_0xcc7[0x09]; - - u8 ssictl; /* SSI control */ - u8 ssixmit; /* SSI transmit */ - u8 ssicmd; /* SSI command */ - u8 ssista; /* SSI status */ - u8 ssircv; /* SSI receive */ - - u8 pad_0xcd5[0x2b]; - - u8 picicr; /* interrupt control */ - u8 pad_0xd01[0x01]; - u8 pic_mode[3]; /* PIC interrupt mode */ - u8 pad_0xd05[0x03]; - u16 swint16_1; /* software interrupt 16-1 control */ - u8 swint22_17; /* software interrupt 22-17/NMI control */ - u8 pad_0xd0b[0x05]; - u16 intpinpol; /* interrupt pin polarity */ - u8 pad_0xd12[0x02]; - u16 pcihostmap; /* PCI host bridge interrupt mapping */ - u8 pad_0xd16[0x02]; - u16 eccmap; /* ECC interrupt mapping */ - u8 gp_tmr_int_map[3]; /* GP timer interrupt mapping */ - u8 pad_0xd1d[0x03]; - u8 pit_int_map[3]; /* PIT interrupt mapping */ - u8 pad_0xd23[0x05]; - u8 uart_int_map[2]; /* UART interrupt mapping */ - u8 pad_0xd2a[0x06]; - u8 pci_int_map[4]; /* PCI interrupt mapping (A through D)*/ - u8 pad_0xd34[0x0c]; - u8 dmabcintmap; /* DMA buffer chaining interrupt mapping */ - u8 ssimap; /* SSI interrupt mapping register */ - u8 wdtmap; /* watchdog timer interrupt mapping */ - u8 rtcmap; /* RTC interrupt mapping register */ - u8 wpvmap; /* write-protect interrupt mapping */ - u8 icemap; /* AMDebug JTAG Rx/Tx interrupt mapping */ - u8 ferrmap; /* floating point error interrupt mapping */ - u8 pad_0xd47[0x09]; - u8 gp_int_map[11]; /* GP IRQ interrupt mapping */ - - u8 pad_0xd5b[0x15]; - - u8 sysinfo; /* system board information */ - u8 pad_0xd71[0x01]; - u8 rescfg; /* reset configuration */ - u8 pad_0xd73[0x01]; - u8 ressta; /* reset status */ - - u8 pad_0xd75[0x0b]; - - u8 gpdmactl; /* GP-DMA Control */ - u8 gpdmammio; /* GP-DMA memory-mapped I/O */ - u16 gpdmaextchmapa; /* GP-DMA resource channel map a */ - u16 gpdmaextchmapb; /* GP-DMA resource channel map b */ - u8 gp_dma_ext_pg_0; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_1; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_2; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_3; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_5; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_6; /* GP-DMA channel extended page 0 */ - u8 gp_dma_ext_pg_7; /* GP-DMA channel extended page 0 */ - u8 pad_0xd8d[0x03]; - u8 gpdmaexttc3; /* GP-DMA channel 3 extender transfer count */ - u8 gpdmaexttc5; /* GP-DMA channel 5 extender transfer count */ - u8 gpdmaexttc6; /* GP-DMA channel 6 extender transfer count */ - u8 gpdmaexttc7; /* GP-DMA channel 7 extender transfer count */ - u8 pad_0xd94[0x4]; - u8 gpdmabcctl; /* buffer chaining control */ - u8 gpdmabcsta; /* buffer chaining status */ - u8 gpdmabsintenb; /* buffer chaining interrupt enable */ - u8 gpdmabcval; /* buffer chaining valid */ - u8 pad_0xd9c[0x04]; - u16 gpdmanxtaddl3; /* GP-DMA channel 3 next address low */ - u16 gpdmanxtaddh3; /* GP-DMA channel 3 next address high */ - u16 gpdmanxtaddl5; /* GP-DMA channel 5 next address low */ - u16 gpdmanxtaddh5; /* GP-DMA channel 5 next address high */ - u16 gpdmanxtaddl6; /* GP-DMA channel 6 next address low */ - u16 gpdmanxtaddh6; /* GP-DMA channel 6 next address high */ - u16 gpdmanxtaddl7; /* GP-DMA channel 7 next address low */ - u16 gpdmanxtaddh7; /* GP-DMA channel 7 next address high */ - u16 gpdmanxttcl3; /* GP-DMA channel 3 next transfer count low */ - u16 gpdmanxttch3; /* GP-DMA channel 3 next transfer count high */ - u16 gpdmanxttcl5; /* GP-DMA channel 5 next transfer count low */ - u16 gpdmanxttch5; /* GP-DMA channel 5 next transfer count high */ - u16 gpdmanxttcl6; /* GP-DMA channel 6 next transfer count low */ - u16 gpdmanxttch6; /* GP-DMA channel 6 next transfer count high */ - u16 gpdmanxttcl7; /* GP-DMA channel 7 next transfer count low */ - u16 gpdmanxttch7; /* GP-DMA channel 7 next transfer count high */ - - u8 pad_0xdc0[0x0240]; -} sc520_mmcr_t; - -extern sc520_mmcr_t *sc520_mmcr; - -#endif - -/* Memory Mapped Control Registers (MMCR) Base Address */ -#define SC520_MMCR_BASE 0xfffef000 - -/* - * PARs for maximum allowable 256MB of SDRAM @ 0x00000000 - * Two PARs are required due to maximum PAR size of 128MB - * These are used in the SDRAM sizing code to disable caching - * - * 111 0 0 0 1 11111111111 00000000000000 }- 0xe3ffc000 - * 111 0 0 0 1 11111111111 00100000000000 }- 0xe3ffc800 - * \ / | | | | \----+----/ \-----+------/ - * | | | | | | +---------- Start at 0x00000000 - * | | | | | | 0x08000000 - * | | | | | +----------------------- 128MB Region Size - * | | | | | ((2047 + 1) * 64kB) - * | | | | +------------------------------ 64kB Page Size - * | | | +-------------------------------- Writes Enabled - * | | +---------------------------------- Caching Enabled - * | +------------------------------------ Execution Enabled - * +--------------------------------------- SDRAM - */ -#define SC520_SDRAM1_PAR 0xe3ffc000 -#define SC520_SDRAM2_PAR 0xe3ffc800 - -#define SC520_PAR_WRITE_DIS 0x04000000 -#define SC520_PAR_CACHE_DIS 0x08000000 -#define SC520_PAR_EXEC_DIS 0x10000000 - -/* - * Programmable Address Regions to cover 256MB SDRAM (Maximum supported) - * required for DRAM sizing code - */ - -/* MMCR Register bits (not all of them :) ) */ - -/* SSI Stuff */ -#define CTL_CLK_SEL_4 0x00 /* Nominal Bit Rate = 8 MHz */ -#define CTL_CLK_SEL_8 0x10 /* Nominal Bit Rate = 4 MHz */ -#define CTL_CLK_SEL_16 0x20 /* Nominal Bit Rate = 2 MHz */ -#define CTL_CLK_SEL_32 0x30 /* Nominal Bit Rate = 1 MHz */ -#define CTL_CLK_SEL_64 0x40 /* Nominal Bit Rate = 512 KHz */ -#define CTL_CLK_SEL_128 0x50 /* Nominal Bit Rate = 256 KHz */ -#define CTL_CLK_SEL_256 0x60 /* Nominal Bit Rate = 128 KHz */ -#define CTL_CLK_SEL_512 0x70 /* Nominal Bit Rate = 64 KHz */ - -#define TC_INT_ENB 0x08 /* Transaction Complete Interrupt Enable */ -#define PHS_INV_ENB 0x04 /* SSI Inverted Phase Mode Enable */ -#define CLK_INV_ENB 0x02 /* SSI Inverted Clock Mode Enable */ -#define MSBF_ENB 0x01 /* SSI Most Significant Bit First Mode Enable */ - -#define SSICMD_CMD_SEL_XMITRCV 0x03 /* Simultaneous Transmit / Receive Transaction */ -#define SSICMD_CMD_SEL_RCV 0x02 /* Receive Transaction */ -#define SSICMD_CMD_SEL_XMIT 0x01 /* Transmit Transaction */ -#define SSISTA_BSY 0x02 /* SSI Busy */ -#define SSISTA_TC_INT 0x01 /* SSI Transaction Complete Interrupt */ - -/* BITS for SC520_ADDDECCTL: */ -#define WPV_INT_ENB 0x80 /* Write-Protect Violation Interrupt Enable */ -#define IO_HOLE_DEST_PCI 0x10 /* I/O Hole Access Destination */ -#define RTC_DIS 0x04 /* RTC Disable */ -#define UART2_DIS 0x02 /* UART2 Disable */ -#define UART1_DIS 0x01 /* UART1 Disable */ - -/* - * Defines used for SDRAM Sizing (number of columns and rows) - * Refer to section 10.6.4 - SDRAM Sizing Algorithm in the - * Elan SC520 Microcontroller User's Manual (Order #22004B) - */ -#define CACHELINESZ 0x00000010 - -#define COL11_ADR 0x0e001e00 -#define COL10_ADR 0x0e000e00 -#define COL09_ADR 0x0e000600 -#define COL08_ADR 0x0e000200 -#define COL11_DATA 0x0b0b0b0b -#define COL10_DATA 0x0a0a0a0a -#define COL09_DATA 0x09090909 -#define COL08_DATA 0x08080808 - -#define ROW14_ADR 0x0f000000 -#define ROW13_ADR 0x07000000 -#define ROW12_ADR 0x03000000 -#define ROW11_ADR 0x01000000 -#define ROW10_ADR 0x00000000 -#define ROW14_DATA 0x3f3f3f3f -#define ROW13_DATA 0x1f1f1f1f -#define ROW12_DATA 0x0f0f0f0f -#define ROW11_DATA 0x07070707 -#define ROW10_DATA 0xaaaaaaaa - -/* 0x28000000 - 0x3fffffff is used by the flash banks */ - -/* 0x40000000 - 0xffffffff is not adressable by the SC520 */ - -/* priority numbers used for interrupt channel mappings */ -#define SC520_IRQ_DISABLED 0 -#define SC520_IRQ0 1 -#define SC520_IRQ1 2 -#define SC520_IRQ2 4 /* same as IRQ9 */ -#define SC520_IRQ3 11 -#define SC520_IRQ4 12 -#define SC520_IRQ5 13 -#define SC520_IRQ6 21 -#define SC520_IRQ7 22 -#define SC520_IRQ8 3 -#define SC520_IRQ9 4 -#define SC520_IRQ10 5 -#define SC520_IRQ11 6 -#define SC520_IRQ12 7 -#define SC520_IRQ13 8 -#define SC520_IRQ14 9 -#define SC520_IRQ15 10 - -#endif diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index dc6402b67d..8a96fc96e8 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -23,46 +23,19 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H -/* - * The following data structure is placed in some memory wich is - * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or - * some locked parts of the data cache) to allow for a minimum set of - * global variables during system initialization (until we have set - * up the memory controller so that we can use RAM). - */ #ifndef __ASSEMBLY__ -#include <asm/u-boot.h> - -typedef struct global_data gd_t; +/* Architecture-specific global data */ +struct arch_global_data { + struct global_data *gd_addr; /* Location of Global Data */ +}; -struct global_data { - /* NOTE: gd_addr MUST be first member of struct global_data! */ - gd_t *gd_addr; /* Location of Global Data */ - bd_t *bd; - unsigned long flags; - unsigned int baudrate; - unsigned long have_console; /* serial_init() was called */ -#ifdef CONFIG_PRE_CONSOLE_BUFFER - unsigned long precon_buf_idx; /* Pre-Console buffer index */ #endif - unsigned long reloc_off; /* Relocation Offset */ - unsigned long load_off; /* Load Offset */ - unsigned long env_addr; /* Address of Environment struct */ - unsigned long env_valid; /* Checksum of Environment valid? */ - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long bus_clk; - unsigned long relocaddr; /* Start address of U-Boot in RAM */ - unsigned long start_addr_sp; /* start_addr_stackpointer */ - unsigned long gdt_addr; /* Location of GDT */ - phys_size_t ram_size; /* RAM size */ - unsigned long reset_status; /* reset status register at boot */ - const void *fdt_blob; /* Our device tree, NULL if none */ - void **jt; /* jump table */ - char env_buf[32]; /* buffer for getenv() before reloc. */ -}; +#include <asm-generic/global_data.h> + +#ifndef __ASSEMBLY__ static inline gd_t *get_fs_gd_ptr(void) { gd_t *gd_ptr; @@ -76,8 +49,6 @@ static inline gd_t *get_fs_gd_ptr(void) #endif -#include <asm-generic/global_data_flags.h> - /* * Our private Global Data Flags */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 0a52cc896c..9b24dc5fdf 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -25,16 +25,6 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o -ifeq ($(CONFIG_X86_NO_REAL_MODE),) -SOBJS-$(CONFIG_SYS_PC_BIOS) += bios.o -SOBJS-$(CONFIG_SYS_PCI_BIOS) += bios_pci.o -COBJS-y += realmode.o -SOBJS-y += realmode_switch.o - -COBJS-$(CONFIG_SYS_PC_BIOS) += bios_setup.o -COBJS-$(CONFIG_VIDEO_VGA) += video_bios.o -endif - COBJS-y += board.o COBJS-y += bootm.o COBJS-y += cmd_boot.o diff --git a/arch/x86/lib/bios.S b/arch/x86/lib/bios.S deleted file mode 100644 index 239aaa9cfa..0000000000 --- a/arch/x86/lib/bios.S +++ /dev/null @@ -1,569 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * 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 - */ - -/* - * Based on msbios.c from rolo 1.6: - *---------------------------------------------------------------------- - * (C) Copyright 2000 - * Sysgo Real-Time Solutions GmbH - * Klein-Winternheim, Germany - *---------------------------------------------------------------------- - */ - -#include "bios.h" - -/* - * During it's initialization phase, before switching to protected - * mode, the Linux Kernel makes a few BIOS calls. This won't work - * if the board does not have a BIOS. - * - * This is a very minimalisic BIOS that supplies just enough - * functionality to keep the Linux Kernel happy. It is NOT - * a general purpose replacement for a real BIOS !! - */ - -.section .bios, "ax" -.code16 -.org 0 - /* a call to f000:0 should warmboot */ - jmp realmode_reset - -.globl rm_int00 -.hidden rm_int00 -.type rm_int00, @function -rm_int00: - pushw $0 - jmp any_interrupt16 -.globl rm_int01 -.hidden rm_int01 -.type rm_int01, @function -rm_int01: - pushw $1 - jmp any_interrupt16 -.globl rm_int02 -.hidden rm_int02 -.type rm_int02, @function -rm_int02: - pushw $2 - jmp any_interrupt16 -.globl rm_int03 -.hidden rm_int03 -.type rm_int03, @function -rm_int03: - pushw $3 - jmp any_interrupt16 -.globl rm_int04 -.hidden rm_int04 -.type rm_int04, @function -rm_int04: - pushw $4 - jmp any_interrupt16 -.globl rm_int05 -.hidden rm_int05 -.type rm_int05, @function -rm_int05: - pushw $5 - jmp any_interrupt16 -.globl rm_int06 -.hidden rm_int06 -.type rm_int06, @function -rm_int06: - pushw $6 - jmp any_interrupt16 -.globl rm_int07 -.hidden rm_int07 -.type rm_int07, @function -rm_int07: - pushw $7 - jmp any_interrupt16 -.globl rm_int08 -.hidden rm_int08 -.type rm_int08, @function -rm_int08: - pushw $8 - jmp any_interrupt16 -.globl rm_int09 -.hidden rm_int09 -.type rm_int09, @function -rm_int09: - pushw $9 - jmp any_interrupt16 -.globl rm_int0a -.hidden rm_int0a -.type rm_int0a, @function -rm_int0a: - pushw $10 - jmp any_interrupt16 -.globl rm_int0b -.hidden rm_int0b -.type rm_int0b, @function -rm_int0b: - pushw $11 - jmp any_interrupt16 -.globl rm_int0c -.hidden rm_int0c -.type rm_int0c, @function -rm_int0c: - pushw $12 - jmp any_interrupt16 -.globl rm_int0d -.hidden rm_int0d -.type rm_int0d, @function -rm_int0d: - pushw $13 - jmp any_interrupt16 -.globl rm_int0e -.hidden rm_int0e -.type rm_int0e, @function -rm_int0e: - pushw $14 - jmp any_interrupt16 -.globl rm_int0f -.hidden rm_int0f -.type rm_int0f, @function -rm_int0f: - pushw $15 - jmp any_interrupt16 -.globl rm_int10 -.hidden rm_int10 -.type rm_int10, @function -rm_int10: - pushw $16 - jmp any_interrupt16 -.globl rm_int11 -.hidden rm_int11 -.type rm_int11, @function -rm_int11: - pushw $17 - jmp any_interrupt16 -.globl rm_int12 -.hidden rm_int12 -.type rm_int12, @function -rm_int12: - pushw $18 - jmp any_interrupt16 -.globl rm_int13 -.hidden rm_int13 -.type rm_int13, @function -rm_int13: - pushw $19 - jmp any_interrupt16 -.globl rm_int14 -.hidden rm_int14 -.type rm_int14, @function -rm_int14: - pushw $20 - jmp any_interrupt16 -.globl rm_int15 -.hidden rm_int15 -.type rm_int15, @function -rm_int15: - pushw $21 - jmp any_interrupt16 -.globl rm_int16 -.hidden rm_int16 -.type rm_int16, @function -rm_int16: - pushw $22 - jmp any_interrupt16 -.globl rm_int17 -.hidden rm_int17 -.type rm_int17, @function -rm_int17: - pushw $23 - jmp any_interrupt16 -.globl rm_int18 -.hidden rm_int18 -.type rm_int18, @function -rm_int18: - pushw $24 - jmp any_interrupt16 -.globl rm_int19 -.hidden rm_int19 -.type rm_int19, @function -rm_int19: - pushw $25 - jmp any_interrupt16 -.globl rm_int1a -.hidden rm_int1a -.type rm_int1a, @function -rm_int1a: - pushw $26 - jmp any_interrupt16 -.globl rm_int1b -.hidden rm_int1b -.type rm_int1b, @function -rm_int1b: - pushw $27 - jmp any_interrupt16 -.globl rm_int1c -.hidden rm_int1c -.type rm_int1c, @function -rm_int1c: - pushw $28 - jmp any_interrupt16 -.globl rm_int1d -.hidden rm_int1d -.type rm_int1d, @function -rm_int1d: - pushw $29 - jmp any_interrupt16 -.globl rm_int1e -.hidden rm_int1e -.type rm_int1e, @function -rm_int1e: - pushw $30 - jmp any_interrupt16 -.globl rm_int1f -.hidden rm_int1f -.type rm_int1f, @function -rm_int1f: - pushw $31 - jmp any_interrupt16 -.globl rm_def_int -.hidden rm_def_int -.type rm_def_int, @function -rm_def_int: - iret - - /* - * All interrupt jumptable entries jump to here after pushing the - * interrupt vector number onto the stack. - */ -any_interrupt16: - MAKE_BIOS_STACK - -gs movw OFFS_VECTOR(%bp), %ax - cmpw $0x10, %ax - je Lint_10h - cmpw $0x11, %ax - je Lint_11h - cmpw $0x12, %ax - je Lint_12h - cmpw $0x13, %ax - je Lint_13h - cmpw $0x15, %ax - je Lint_15h - cmpw $0x16, %ax - je Lint_16h - cmpw $0x1a, %ax - je Lint_1ah - movw $0xffff, %ax - jmp Lout -Lint_10h: - /* VGA BIOS services */ - call bios_10h - jmp Lout -Lint_11h: - call bios_11h - jmp Lout -Lint_12h: - call bios_12h - jmp Lout -Lint_13h: - /* BIOS disk services */ - call bios_13h - jmp Lout -Lint_15h: - /* Misc. BIOS services */ - call bios_15h - jmp Lout -Lint_16h: - /* keyboard services */ - call bios_16h - jmp Lout -Lint_1ah: - /* PCI bios */ - call bios_1ah - jmp Lout -Lout: - cmpw $0, %ax - je Lhandeled - - /* - * Insert code for unhandeled INTs here. - * - * ROLO prints a message to the console we could do that but then - * we're in 16bit mode so we'll have to get back into 32bit mode - * to use the console I/O routines (if we do this we should make - * int 0x10 and int 0x16 work as well) - */ -Lhandeled: - RESTORE_CALLERS_STACK - - /* dump vector number */ - addw $2,%sp - - /* return from interrupt */ - iret - -/* - ************************************************************ - * BIOS interrupt 10h -- VGA services - ************************************************************ - */ -bios_10h: -gs movw OFFS_AX(%bp), %ax - shrw $8, %ax - cmpw $0x3, %ax - je Lcur_pos - cmpw $0xf, %ax - je Lvid_state - cmpw $0x12, %ax - je Lvid_cfg - movw $0xffff, %ax - ret -Lcur_pos: - /* Read Cursor Position and Size */ -gs movw $0, OFFS_CX(%bp) -gs movw $0, OFFS_DX(%bp) - xorw %ax, %ax - ret -Lvid_state: - /* Get Video State - 80 columns, 80x25, 16 colors */ -gs movw $(80 << 8|0x03), OFFS_AX(%bp) -gs movw $0, OFFS_BX(%bp) - xorw %ax, %ax - ret -Lvid_cfg: - /* Video Subsystem Configuration (EGA/VGA) - indicate CGA/MDA/HGA */ -gs movw $0x10, OFFS_BX(%bp) - xorw %ax, %ax - ret - -/* - ************************************************************ - * BIOS interrupt 11h -- Equipment determination - ************************************************************ - */ - -bios_11h: -cs movw bios_equipment, %ax -gs movw %ax, OFFS_AX(%bp) - xorw %ax, %ax - ret - -/* - ************************************************************ - * BIOS interrupt 12h -- Get Memory Size - ************************************************************ - */ -bios_12h: -cs movw ram_in_64kb_chunks, %ax - cmpw $0xa, %ax - ja b12_more_than_640k - shlw $6, %ax - jmp b12_return -b12_more_than_640k: - movw $0x280, %ax -b12_return: - /* return number of kilobytes in ax */ -gs movw %ax, OFFS_AX(%bp) - -gs movw OFFS_FLAGS(%bp), %ax - - /* clear carry -- function succeeded */ - andw $0xfffe, %ax -gs movw %ax, OFFS_FLAGS(%bp) - - xorw %ax, %ax - ret - -/* - ************************************************************ - * BIOS interrupt 13h -- Disk services - ************************************************************ - */ -bios_13h: -gs movw OFFS_AX(%bp), %ax - shrw $8, %ax - cmpw $0x15, %ax - je Lfunc_15h - movw $0xffff, %ax - ret -Lfunc_15h: -gs movw OFFS_AX(%bp), %ax - - /* return AH=0->drive not present */ - andw $0x00ff, %ax -gs movw %ax, OFFS_AX(%bp) - xorw %ax, %ax - ret - -/* - *********************************************************** - * BIOS interrupt 15h -- Miscellaneous services - *********************************************************** - */ -bios_15h: -gs movw OFFS_AX(%bp), %ax - shrw $8, %ax - cmpw $0xc0, %ax - je Lfunc_c0h - cmpw $0xe8, %ax - je Lfunc_e8h - cmpw $0x88, %ax - je Lfunc_88h - movw $0xffff, %ax - ret - -Lfunc_c0h: - /* Return System Configuration Parameters (PS2 only) */ -gs movw OFFS_FLAGS(%bp), %ax - - /* return carry -- function not supported */ - orw $1, %ax -gs movw %ax, OFFS_FLAGS(%bp) - xorw %ax, %ax - ret - -Lfunc_e8h: -gs movw OFFS_AX(%bp), %ax - andw $0xff, %ax - cmpw $1, %ax - je Lfunc_e801h -gs movw OFFS_FLAGS(%bp), %ax - - /* return carry -- function not supported */ - orw $1, %ax -gs movw %ax, OFFS_FLAGS(%bp) - xorw %ax, %ax - ret - -Lfunc_e801h: - /* Get memory size for >64M Configurations */ -cs movw ram_in_64kb_chunks, %ax - cmpw $0x100, %ax - ja e801_more_than_16mb - - /* multiply by 64 */ - shlw $6, %ax - - /* 1st meg does not count */ - subw $0x400, %ax - - /* return memory size between 1M and 16M in 1kb chunks in AX and CX */ -gs movw %ax, OFFS_AX(%bp) -gs movw %ax, OFFS_CX(%bp) - - /* set BX and DX to 0*/ -gs movw $0, OFFS_BX(%bp) -gs movw $0, OFFS_DX(%bp) -gs movw OFFS_FLAGS(%bp), %ax - - /* clear carry -- function succeeded */ - andw $0xfffe, %ax -gs movw %ax, OFFS_FLAGS(%bp) - xorw %ax, %ax - ret - -e801_more_than_16mb: - /* subtract 16MB */ - subw $0x100, %ax - - /* return 0x3c00 (16MB-1MB) in AX and CX */ -gs movw $0x3c00, OFFS_AX(%bp) -gs movw $0x3c00, OFFS_CX(%bp) - - /* set BX and DX to number of 64kb chunks above 16MB */ -gs movw %ax, OFFS_BX(%bp) -gs movw %ax, OFFS_DX(%bp) - -gs movw OFFS_FLAGS(%bp), %ax - - /* clear carry -- function succeeded */ - andw $0xfffe, %ax -gs movw %ax, OFFS_FLAGS(%bp) - xorw %ax, %ax - ret - -Lfunc_88h: -cs movw ram_in_64kb_chunks, %ax - cmpw $0x100, %ax - jna b88_not_more_than16 - movw $0x100, %ax -b88_not_more_than16: - shlw $6, %ax - - /* 1st meg does not count */ - subw $0x400, %ax - - /* return number of kilobytes between 16MB and 16MB in ax */ -gs movw %ax, OFFS_AX(%bp) - -gs movw OFFS_FLAGS(%bp), %ax - - /* clear carry -- function succeeded */ - andw $0xfffe, %ax -gs movw %ax, OFFS_FLAGS(%bp) - - xorw %ax, %ax - ret - -/* - ************************************************************ - * BIOS interrupt 16h -- keyboard services - ************************************************************ - */ -bios_16h: -gs movw OFFS_AX(%bp), %ax - shrw $8, %ax - cmpw $0x03, %ax - je Lfunc_03h - movw $0xffff, %ax - ret -Lfunc_03h: - /* do nothing -- function not supported */ - xorw %ax, %ax - ret - -/* - ************************************************************ - * BIOS interrupt 1ah -- PCI bios - ************************************************************ - */ -bios_1ah: -gs movw OFFS_AX(%bp), %ax - cmpb $0xb1, %ah - je Lfunc_b1h - movw $0xffff, %ax - ret -Lfunc_b1h: - call realmode_pci_bios - - /* do nothing -- function not supported */ - xorw %ax, %ax - ret - - -.globl ram_in_64kb_chunks -.hidden ram_in_64kb_chunks -.type ram_in_64kb_chunks, @function -ram_in_64kb_chunks: - .word 0 - -.globl bios_equipment -.hidden bios_equipment -.type bios_equipment, @function -bios_equipment: - .word 0 diff --git a/arch/x86/lib/bios.h b/arch/x86/lib/bios.h index a220983df1..96509b066e 100644 --- a/arch/x86/lib/bios.h +++ b/arch/x86/lib/bios.h @@ -145,9 +145,6 @@ extern void *rm_int1e; extern void *rm_int1f; extern void *rm_def_int; -extern void *realmode_reset; -extern void *realmode_pci_bios_call_entry; - #define RELOC_16_LONG(seg, off) (*(u32 *)(seg << 4 | (u32)&off)) #define RELOC_16_WORD(seg, off) (*(u16 *)(seg << 4 | (u32)&off)) #define RELOC_16_BYTE(seg, off) (*(u8 *)(seg << 4 | (u32)&off)) diff --git a/arch/x86/lib/bios_pci.S b/arch/x86/lib/bios_pci.S deleted file mode 100644 index 47c478b27d..0000000000 --- a/arch/x86/lib/bios_pci.S +++ /dev/null @@ -1,447 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se - * - * 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 - */ - -/* - * x86 realmode assembly implementation of a PCI BIOS - * for platforms that use one PCI hose and configuration - * access type 1. (The common case for low-end PC's) - */ - -#include "bios.h" - -#define PCI_BIOS_DEBUG - -.section .bios, "ax" -.code16 -.globl realmode_pci_bios_call_entry -.hidden realmode_pci_bios_call_entry -.type realmode_pci_bios_call_entry, @function -realmode_pci_bios_call_entry: - MAKE_BIOS_STACK - call realmode_pci_bios - RESTORE_CALLERS_STACK - ret - - -.globl realmode_pci_bios -realmode_pci_bios: -gs movw OFFS_AX(%bp), %ax - cmpb $1, %al - je pci_bios_present - cmpb $2, %al - je pci_bios_find_device - cmpb $3, %al - je pci_bios_find_class - cmpb $6, %al - je pci_bios_generate_special_cycle - cmpb $8, %al - je pci_bios_read_cfg_byte - cmpb $9, %al - je pci_bios_read_cfg_word - cmpb $10, %al - je pci_bios_read_cfg_dword - cmpb $11, %al - je pci_bios_write_cfg_byte - cmpb $12, %al - je pci_bios_write_cfg_word - cmpb $13, %al - je pci_bios_write_cfg_dword - cmpb $14, %al - je pci_bios_get_irq_routing - cmpb $15, %al - je pci_bios_set_irq - jmp unknown_function - -/*****************************************************************************/ - -pci_bios_present: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_present -#endif - movl $0x20494350, %eax -gs movl %eax, OFFS_EDX(%bp) - - /* We support cfg type 1 version 2.10 */ - movb $0x01, %al -gs movb %al, OFFS_AL(%bp) - movw $0x0210, %ax -gs movw %ax, OFFS_BX(%bp) - - /* last bus number */ -cs movb pci_last_bus, %al -gs movb %al, OFFS_CL(%bp) - jmp clear_carry - -/*****************************************************************************/ - -/* device 0-31, function 0-7 */ -pci_bios_find_device: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_find_device -#endif -gs movw OFFS_CX(%bp), %di - shll $16, %edi -gs movw OFFS_DX(%bp), %di - /* edi now holds device in upper 16 bits and vendor in lower 16 bits */ - -gs movw OFFS_SI(%bp), %si - - /* start at bus 0 dev 0 function 0 */ - xorw %bx, %bx -pfd_loop: - /* dword 0 is vendor/device */ - xorw %ax, %ax - call __pci_bios_select_register - movw $0xcfc, %dx - inl %dx, %eax - - /* our device ? */ - cmpl %edi, %eax - je pfd_found_one -pfd_next_dev: - /* check for multi function devices */ - movw %bx, %ax - andw $3, %ax - jnz pfd_function_not_zero - movw $0x000c, %ax - call __pci_bios_select_register - movw $0xcfe, %dx - inb %dx, %al - andb $0x80, %al - jz pfd_not_multi_function -pfd_function_not_zero: - /* next function, overflows in to device number, then bus number */ - incw %bx - jmp pfd_check_bus - -pfd_not_multi_function: - /* remove function bits */ - andw $0xfff8, %bx - - /* next device, overflows in to bus number */ - addw $0x0008, %bx -pfd_check_bus: -cs movb pci_last_bus, %ah - cmpb %ah, %bh - ja pfd_not_found - jmp pfd_loop -pfd_found_one: - decw %si - js pfd_done - jmp pfd_next_dev - -pfd_done: -gs movw %bx, OFFS_BX(%bp) - jmp clear_carry - -pfd_not_found: - /* device not found */ - movb $0x86, %ah - jmp set_carry - -/*****************************************************************************/ - -pci_bios_find_class: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_find_class -#endif -gs movl OFFS_ECX(%bp), %edi - - /* edi now holds class-code in lower 24 bits */ - andl $0x00ffffff, %edi -gs movw OFFS_SI(%bp), %si - - /* start at bus 0 dev 0 function 0 */ - xorw %bx, %bx -pfc_loop: - /* dword 8 is class-code high 24bits */ - movw $8, %ax - call __pci_bios_select_register - movw $0xcfc, %dx - inl %dx, %eax - shrl $8, %eax - andl $0x00ffffff, %eax - - /* our device ? */ - cmpl %edi, %eax - je pfc_found_one -pfc_next_dev: - /* check for multi function devices */ - andw $3, %bx - jnz pfc_function_not_zero - movw $0x000c, %ax - call __pci_bios_select_register - movw $0xcfe, %dx - inb %dx, %al - andb $0x80, %al - jz pfc_not_multi_function -pfc_function_not_zero: - /* next function, overflows in to device number, then bus number */ - incw %bx - jmp pfc_check_bus - -pfc_not_multi_function: - /* remove function bits */ - andw $0xfff8, %bx - - /* next device, overflows in to bus number */ - addw $0x0008, %bx -pfc_check_bus: -cs movb pci_last_bus, %ah - cmpb %ah, %bh - ja pfc_not_found - jmp pfc_loop -pfc_found_one: - decw %si - js pfc_done - jmp pfc_next_dev - -pfc_done: -gs movw %bx, OFFS_BX(%bp) - jmp clear_carry - -pfc_not_found: - /* device not found */ - movb $0x86, %ah - jmp set_carry - -/*****************************************************************************/ - -pci_bios_generate_special_cycle: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_generate_special_cycle -#endif - /* function not supported */ - movb $0x81, %ah - jmp set_carry - -/*****************************************************************************/ - -pci_bios_read_cfg_byte: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_read_cfg_byte -#endif - call pci_bios_select_register -gs movw OFFS_DI(%bp), %dx - andw $3, %dx - addw $0xcfc, %dx - inb %dx, %al -gs movb %al, OFFS_CL(%bp) - jmp clear_carry - -/*****************************************************************************/ - -pci_bios_read_cfg_word: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_read_cfg_word -#endif - call pci_bios_select_register -gs movw OFFS_DI(%bp), %dx - andw $2, %dx - addw $0xcfc, %dx - inw %dx, %ax -gs movw %ax, OFFS_CX(%bp) - jmp clear_carry - - -/*****************************************************************************/ - -pci_bios_read_cfg_dword: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_read_cfg_dword -#endif - call pci_bios_select_register - movw $0xcfc, %dx - inl %dx, %eax -gs movl %eax, OFFS_ECX(%bp) - jmp clear_carry - -/*****************************************************************************/ - -pci_bios_write_cfg_byte: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_write_cfg_byte -#endif - call pci_bios_select_register -gs movw OFFS_DI(%bp), %dx -gs movb OFFS_CL(%bp), %al - andw $3, %dx - addw $0xcfc, %dx - outb %al, %dx - jmp clear_carry - -/*****************************************************************************/ - -pci_bios_write_cfg_word: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_write_cfg_word -#endif - call pci_bios_select_register -gs movw OFFS_DI(%bp), %dx -gs movw OFFS_CX(%bp), %ax - andw $2, %dx - addw $0xcfc, %dx - outw %ax, %dx - jmp clear_carry - -/*****************************************************************************/ - -pci_bios_write_cfg_dword: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_write_cfg_dword -#endif - call pci_bios_select_register -gs movl OFFS_ECX(%bp), %eax - movw $0xcfc, %dx - outl %eax, %dx - jmp clear_carry - -/*****************************************************************************/ - -pci_bios_get_irq_routing: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_get_irq_routing -#endif - /* function not supported */ - movb $0x81, %ah - jmp set_carry - -/*****************************************************************************/ - -pci_bios_set_irq: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_set_irq -#endif - /* function not supported */ - movb $0x81, %ah - jmp set_carry - -/*****************************************************************************/ - -unknown_function: -#ifdef PCI_BIOS_DEBUG -cs incl num_pci_bios_unknown_function -#endif - /* function not supported */ - movb $0x81, %ah - jmp set_carry - -/*****************************************************************************/ - -pci_bios_select_register: -gs movw OFFS_BX(%bp), %bx -gs movw OFFS_DI(%bp), %ax -/* destroys eax, dx */ -__pci_bios_select_register: - /* BX holds device id, AX holds register index */ - pushl %ebx - andl $0xfc, %eax - andl $0xffff, %ebx - shll $8, %ebx - orl %ebx, %eax - orl $0x80000000, %eax - movw $0xcf8, %dx - outl %eax, %dx - popl %ebx - ret - - -clear_carry: -gs movw OFFS_FLAGS(%bp), %ax - - /* clear carry -- function succeeded */ - andw $0xfffe, %ax -gs movw %ax, OFFS_FLAGS(%bp) - xorw %ax, %ax -gs movb %ah, OFFS_AH(%bp) - ret - -set_carry: -gs movb %ah, OFFS_AH(%bp) -gs movw OFFS_FLAGS(%bp), %ax - - /* return carry -- function not supported */ - orw $1, %ax -gs movw %ax, OFFS_FLAGS(%bp) - movw $-1, %ax - ret - -/*****************************************************************************/ - -.globl pci_last_bus -pci_last_bus: - .byte 0 - -#ifdef PCI_BIOS_DEBUG -.globl num_pci_bios_present -num_pci_bios_present: - .long 0 - -.globl num_pci_bios_find_device -num_pci_bios_find_device: - .long 0 - -.globl num_pci_bios_find_class -num_pci_bios_find_class: - .long 0 - -.globl num_pci_bios_generate_special_cycle -num_pci_bios_generate_special_cycle: - .long 0 - -.globl num_pci_bios_read_cfg_byte -num_pci_bios_read_cfg_byte: - .long 0 - -.globl num_pci_bios_read_cfg_word -num_pci_bios_read_cfg_word: - .long 0 - -.globl num_pci_bios_read_cfg_dword -num_pci_bios_read_cfg_dword: - .long 0 - -.globl num_pci_bios_write_cfg_byte -num_pci_bios_write_cfg_byte: - .long 0 - -.globl num_pci_bios_write_cfg_word -num_pci_bios_write_cfg_word: - .long 0 - -.globl num_pci_bios_write_cfg_dword -num_pci_bios_write_cfg_dword: - .long 0 - -.globl num_pci_bios_get_irq_routing -num_pci_bios_get_irq_routing: - .long 0 - -.globl num_pci_bios_set_irq -num_pci_bios_set_irq: - .long 0 - -.globl num_pci_bios_unknown_function -num_pci_bios_unknown_function: - .long 0 -#endif diff --git a/arch/x86/lib/bios_setup.c b/arch/x86/lib/bios_setup.c deleted file mode 100644 index 265f7d671e..0000000000 --- a/arch/x86/lib/bios_setup.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * 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 - */ - -/* - * Partly based on msbios.c from rolo 1.6: - *---------------------------------------------------------------------- - * (C) Copyright 2000 - * Sysgo Real-Time Solutions GmbH - * Klein-Winternheim, Germany - *---------------------------------------------------------------------- - */ - -#include <common.h> -#include <pci.h> -#include <asm/realmode.h> -#include <asm/io.h> -#include "bios.h" - -DECLARE_GLOBAL_DATA_PTR; - -#define NUMVECTS 256 - -static int set_jmp_vector(int entry_point, void *target) -{ - if (entry_point & ~0xffff) - return -1; - - if (((u32)target - 0xf0000) & ~0xffff) - return -1; - - printf("set_jmp_vector: 0xf000:%04x -> %p\n", - entry_point, target); - - /* jmp opcode */ - writeb(0xea, 0xf0000 + entry_point); - - /* offset */ - writew(((u32)target-0xf0000), 0xf0000 + entry_point + 1); - - /* segment */ - writew(0xf000, 0xf0000 + entry_point + 3); - - return 0; -} - -/* Install an interrupt vector */ -static void setvector(int vector, u16 segment, void *handler) -{ - u16 *ptr = (u16 *)(vector * 4); - ptr[0] = ((u32)handler - (segment << 4)) & 0xffff; - ptr[1] = segment; - -#if 0 - printf("setvector: int%02x -> %04x:%04x\n", - vector, ptr[1], ptr[0]); -#endif -} - -int bios_setup(void) -{ - /* The BIOS section is not relocated and still in the ROM. */ - ulong bios_start = (ulong)&__bios_start; - ulong bios_size = (ulong)&__bios_size; - - static int done; - int vector; -#ifdef CONFIG_PCI - struct pci_controller *pri_hose; -#endif - if (done) - return 0; - - done = 1; - - if (bios_size > 65536) { - printf("BIOS too large (%ld bytes, max is 65536)\n", - bios_size); - return -1; - } - - memcpy(BIOS_BASE, (void *)bios_start, bios_size); - - /* clear bda */ - memset(BIOS_DATA, 0, BIOS_DATA_SIZE); - - /* enter some values to the bda */ - writew(0x3f8, BIOS_DATA); /* com1 addr */ - writew(0x2f8, BIOS_DATA+2); /* com2 addr */ - writew(0x3e8, BIOS_DATA+4); /* com3 addr */ - writew(0x2e8, BIOS_DATA+6); /* com4 addr */ - writew(0x278, BIOS_DATA+8); /* lpt1 addr */ - /* - * The kernel wants to read the base memory size - * from 40:13. Put a zero there to avoid an error message - */ - writew(0, BIOS_DATA+0x13); /* base memory size */ - - - /* setup realmode interrupt vectors */ - for (vector = 0; vector < NUMVECTS; vector++) - setvector(vector, BIOS_CS, &rm_def_int); - - setvector(0x00, BIOS_CS, &rm_int00); - setvector(0x01, BIOS_CS, &rm_int01); - setvector(0x02, BIOS_CS, &rm_int02); - setvector(0x03, BIOS_CS, &rm_int03); - setvector(0x04, BIOS_CS, &rm_int04); - setvector(0x05, BIOS_CS, &rm_int05); - setvector(0x06, BIOS_CS, &rm_int06); - setvector(0x07, BIOS_CS, &rm_int07); - setvector(0x08, BIOS_CS, &rm_int08); - setvector(0x09, BIOS_CS, &rm_int09); - setvector(0x0a, BIOS_CS, &rm_int0a); - setvector(0x0b, BIOS_CS, &rm_int0b); - setvector(0x0c, BIOS_CS, &rm_int0c); - setvector(0x0d, BIOS_CS, &rm_int0d); - setvector(0x0e, BIOS_CS, &rm_int0e); - setvector(0x0f, BIOS_CS, &rm_int0f); - setvector(0x10, BIOS_CS, &rm_int10); - setvector(0x11, BIOS_CS, &rm_int11); - setvector(0x12, BIOS_CS, &rm_int12); - setvector(0x13, BIOS_CS, &rm_int13); - setvector(0x14, BIOS_CS, &rm_int14); - setvector(0x15, BIOS_CS, &rm_int15); - setvector(0x16, BIOS_CS, &rm_int16); - setvector(0x17, BIOS_CS, &rm_int17); - setvector(0x18, BIOS_CS, &rm_int18); - setvector(0x19, BIOS_CS, &rm_int19); - setvector(0x1a, BIOS_CS, &rm_int1a); - setvector(0x1b, BIOS_CS, &rm_int1b); - setvector(0x1c, BIOS_CS, &rm_int1c); - setvector(0x1d, BIOS_CS, &rm_int1d); - setvector(0x1e, BIOS_CS, &rm_int1e); - setvector(0x1f, BIOS_CS, &rm_int1f); - - set_jmp_vector(0xfff0, &realmode_reset); - set_jmp_vector(0xfe6e, &realmode_pci_bios_call_entry); - - /* fill in data area */ - RELOC_16_WORD(0xf000, ram_in_64kb_chunks) = gd->ram_size >> 16; - RELOC_16_WORD(0xf000, bios_equipment) = 0; /* FixMe */ - - /* If we assume only one PCI hose, this PCI hose - * will own PCI bus #0, and the last PCI bus of - * that PCI hose will be the last PCI bus in the - * system. - * (This, ofcause break on multi hose systems, - * but our PCI BIOS only support one hose anyway) - */ -#ifdef CONFIG_PCI - pri_hose = pci_bus_to_hose(0); - if (NULL != pri_hose) { - /* fill in last pci bus number for use by the realmode - * PCI BIOS */ - RELOC_16_BYTE(0xf000, pci_last_bus) = pri_hose->last_busno; - } -#endif - return 0; -} diff --git a/arch/x86/lib/realmode.c b/arch/x86/lib/realmode.c deleted file mode 100644 index 75511b2bdf..0000000000 --- a/arch/x86/lib/realmode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/ptrace.h> -#include <asm/realmode.h> - -#define REALMODE_MAILBOX ((char *)0xe00) - -int realmode_setup(void) -{ - /* The realmode section is not relocated and still in the ROM. */ - ulong realmode_start = (ulong)&__realmode_start; - ulong realmode_size = (ulong)&__realmode_size; - - /* copy the realmode switch code */ - if (realmode_size > (REALMODE_MAILBOX - (char *)REALMODE_BASE)) { - printf("realmode switch too large (%ld bytes, max is %d)\n", - realmode_size, - (int)(REALMODE_MAILBOX - (char *)REALMODE_BASE)); - return -1; - } - - memcpy((char *)REALMODE_BASE, (void *)realmode_start, realmode_size); - asm("wbinvd\n"); - - return 0; -} - -int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out) -{ - - /* setup out thin bios emulation */ - if (bios_setup()) - return -1; - - if (realmode_setup()) - return -1; - - in->eip = off; - in->xcs = seg; - if ((in->esp & 0xffff) < 4) - printf("Warning: entering realmode with sp < 4 will fail\n"); - - memcpy(REALMODE_MAILBOX, in, sizeof(struct pt_regs)); - asm("wbinvd\n"); - - __asm__ volatile ( - "lcall $0x20,%0\n" : : "i" (&realmode_enter)); - - asm("wbinvd\n"); - memcpy(out, REALMODE_MAILBOX, sizeof(struct pt_regs)); - - return out->eax; -} - -/* - * This code is supposed to access a realmode interrupt - * it does currently not work for me - */ -int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out) -{ - /* place two instructions at 0x700 */ - writeb(0xcd, 0x700); /* int $lvl */ - writeb(lvl, 0x701); - writeb(0xcb, 0x702); /* lret */ - asm("wbinvd\n"); - - enter_realmode(0x00, 0x700, in, out); - - return out->eflags & 0x00000001; -} diff --git a/arch/x86/lib/realmode_switch.S b/arch/x86/lib/realmode_switch.S deleted file mode 100644 index c4c4c4378e..0000000000 --- a/arch/x86/lib/realmode_switch.S +++ /dev/null @@ -1,232 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se - * - * 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 - */ - -/* 32bit -> 16bit -> 32bit mode switch code */ - -/* - * Stack frame at 0xe00 - * e00 ebx; - * e04 ecx; - * e08 edx; - * e0c esi; - * e10 edi; - * e14 ebp; - * e18 eax; - * e1c ds; - * e20 es; - * e24 fs; - * e28 gs; - * e2c orig_eax; - * e30 eip; - * e34 cs; - * e38 eflags; - * e3c esp; - * e40 ss; - */ - -#define a32 .byte 0x67; /* address size prefix 32 */ -#define o32 .byte 0x66; /* operand size prefix 32 */ - -.section .realmode, "ax" -.code16 - - /* 16bit protected mode code here */ -.globl realmode_enter -realmode_enter: -o32 pusha -o32 pushf - cli - sidt saved_idt - sgdt saved_gdt - movl %esp, %eax - movl %eax, saved_protected_mode_esp - - movl $0x10, %eax - movl %eax, %esp - movw $0x28, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - - lidt realmode_idt_ptr - /* Go back into real mode by clearing PE to 0 */ - movl %cr0, %eax - andl $0x7ffffffe, %eax - movl %eax, %cr0 - - /* switch to real mode */ - ljmp $0x0,$do_realmode - -do_realmode: - /* realmode code from here */ - movw %cs,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - - /* create a temporary stack */ - movw $0xc0, %ax - movw %ax, %ss - movw $0x200, %ax - movw %ax, %sp - - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %eax - movl %eax, temp_eax - popl %eax - movw %ax, %ds - popl %eax - movw %ax, %es - popl %eax - movw %ax, %fs - popl %eax - movw %ax, %gs - popl %eax /* orig_eax */ - popl %eax -cs movw %ax, temp_ip - popl %eax -cs movw %ax, temp_cs -o32 popf - popl %eax - popw %ss - movl %eax, %esp -cs movl temp_eax, %eax - - /* self-modifying code, better flush the cache */ - wbinvd - - .byte 0x9a /* lcall */ -temp_ip: - .word 0 /* new ip */ -temp_cs: - .word 0 /* new cs */ - -realmode_ret: - /* save eax, esp and ss */ -cs movl %eax, saved_eax - movl %esp, %eax -cs movl %eax, saved_esp - movw %ss, %ax -cs movw %ax, saved_ss - - /* - * restore the stack, note that we set sp to 0x244; - * pt_regs is 0x44 bytes long and we push the structure - * backwards on to the stack, bottom first - */ - movw $0xc0, %ax - movw %ax, %ss - movw $0x244, %ax - movw %ax, %sp - - xorl %eax,%eax -cs movw saved_ss, %ax - pushl %eax -cs movl saved_esp, %eax - pushl %eax -o32 pushf - xorl %eax,%eax -cs movw temp_cs, %ax - pushl %eax -cs movw temp_ip, %ax - pushl %eax - pushl $0 - movw %gs, %ax - pushl %eax - movw %fs, %ax - pushl %eax - movw %es, %ax - pushl %eax - movw %ds, %ax - pushl %eax - movl saved_eax, %eax - pushl %eax - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - -o32 cs lidt saved_idt -o32 cs lgdt saved_gdt - - /* Go back into protected mode reset PE to 1 */ - movl %cr0, %eax - orl $1,%eax - movl %eax, %cr0 - - /* flush prefetch queue */ - jmp next_line -next_line: - movw $return_ptr, %ax - movw %ax,%bp -o32 cs ljmp *(%bp) - -.code32 -protected_mode: - /* Reload segment registers */ - movl $0x18, %eax - movw %ax, %fs - movw %ax, %ds - movw %ax, %gs - movw %ax, %es - movw %ax, %ss - movl saved_protected_mode_esp, %eax - movl %eax, %esp - popf - popa - ret - -temp_eax: - .long 0 - -saved_ss: - .word 0 -saved_esp: - .long 0 -saved_eax: - .long 0 - -realmode_idt_ptr: - .word 0x400 - .word 0x0, 0x0 - -saved_gdt: - .word 0, 0, 0, 0 -saved_idt: - .word 0, 0, 0, 0 - -saved_protected_mode_esp: - .long 0 - -return_ptr: - .long protected_mode - .word 0x10 diff --git a/arch/x86/lib/video.c b/arch/x86/lib/video.c index 20e2416ae1..81824f3144 100644 --- a/arch/x86/lib/video.c +++ b/arch/x86/lib/video.c @@ -26,7 +26,6 @@ #include <stdio_dev.h> #include <i8042.h> #include <asm/ptrace.h> -#include <asm/realmode.h> #include <asm/io.h> #include <asm/pci.h> @@ -222,10 +221,5 @@ int video_init(void) int drv_video_init(void) { -#ifndef CONFIG_X86_NO_REAL_MODE - if (video_bios_init()) - return 1; -#endif - return video_init(); } diff --git a/arch/x86/lib/video_bios.c b/arch/x86/lib/video_bios.c deleted file mode 100644 index 1e06759d9e..0000000000 --- a/arch/x86/lib/video_bios.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <pci.h> -#include <malloc.h> -#include <asm/ptrace.h> -#include <asm/realmode.h> -#include <asm/io.h> -#include <asm/pci.h> -#include "bios.h" - -#undef PCI_BIOS_DEBUG -#undef VGA_BIOS_DEBUG - -#ifdef VGA_BIOS_DEBUG -#define PRINTF(fmt, args...) printf(fmt, ##args) -#else -#define PRINTF(fmt, args...) -#endif - -#define PCI_CLASS_VIDEO 3 -#define PCI_CLASS_VIDEO_STD 0 -#define PCI_CLASS_VIDEO_PROG_IF_VGA 0 - -DEFINE_PCI_DEVICE_TABLE(supported) = { - {PCI_VIDEO_VENDOR_ID, PCI_VIDEO_DEVICE_ID}, - {} -}; - -static u32 probe_pci_video(void) -{ - struct pci_controller *hose; - pci_dev_t devbusfn = pci_find_devices(supported, 0); - - if ((devbusfn != -1)) { - u32 old; - u32 addr; - - /* PCI video device detected */ - printf("Found PCI VGA device at %02x.%02x.%x\n", - PCI_BUS(devbusfn), - PCI_DEV(devbusfn), - PCI_FUNC(devbusfn)); - - /* Enable I/O decoding as well, PCI viudeo boards - * support I/O accesses, but they provide no - * bar register for this since the ports are fixed. - */ - pci_write_config_word(devbusfn, - PCI_COMMAND, - PCI_COMMAND_MEMORY | - PCI_COMMAND_IO | - PCI_COMMAND_MASTER); - - /* Test the ROM decoder, do the device support a rom? */ - pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &old); - pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, - (u32)PCI_ROM_ADDRESS_MASK); - pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &addr); - pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, old); - - if (!addr) { - printf("PCI VGA have no ROM?\n"); - return 0; - } - - /* device have a rom */ - if (pci_shadow_rom(devbusfn, (void *)0xc0000)) { - printf("Shadowing of PCI VGA BIOS failed\n"); - return 0; - } - - /* Now enable lagacy VGA port access */ - hose = pci_bus_to_hose(PCI_BUS(devbusfn)); - if (pci_enable_legacy_video_ports(hose)) { - printf("PCI VGA enable failed\n"); - return 0; - } - - - /* return the pci device info, that we'll need later */ - return PCI_BUS(devbusfn) << 8 | - PCI_DEV(devbusfn) << 3 | (PCI_FUNC(devbusfn) & 7); - } - - return 0; -} - -static int probe_isa_video(void) -{ - u32 ptr; - char *buf; - - ptr = isa_map_rom(0xc0000, 0x8000); - - if (!ptr) - return -1; - - buf = malloc(0x8000); - if (!buf) { - isa_unmap_rom(ptr); - return -1; - } - - if (readw(ptr) != 0xaa55) { - free(buf); - isa_unmap_rom(ptr); - return -1; - } - - /* shadow the rom */ - memcpy(buf, (void *)ptr, 0x8000); - isa_unmap_rom(ptr); - memcpy((void *)0xc0000, buf, 0x8000); - - free(buf); - - return 0; -} - -int video_bios_init(void) -{ - struct pt_regs regs; - int size; - int i; - u8 sum; - - /* clear the video bios area in case we warmbooted */ - memset((void *)0xc0000, 0, 0x8000); - memset(®s, 0, sizeof(struct pt_regs)); - - if (probe_isa_video()) - /* No ISA board found, try the PCI bus */ - regs.eax = probe_pci_video(); - - /* Did we succeed in mapping any video bios */ - if (readw(0xc0000) == 0xaa55) { - PRINTF("Found video bios signature\n"); - size = readb(0xc0002) * 512; - PRINTF("size %d\n", size); - sum = 0; - - for (i = 0; i < size; i++) - sum += readb(0xc0000 + i); - - PRINTF("Checksum is %sOK\n", sum ? "NOT " : ""); - - if (sum) - return 1; - - /* - * Some video bioses (ATI Mach64) seem to think that - * the original int 10 handler is always at - * 0xf000:0xf065 , place an iret instruction there - */ - writeb(0xcf, 0xff065); - - regs.esp = 0x8000; - regs.xss = 0x2000; - enter_realmode(0xc000, 3, ®s, ®s); - - PRINTF("INT 0x10 vector after: %04x:%04x\n", - readw(0x42), readw(0x40)); - PRINTF("BIOS returned %scarry\n", - regs.eflags & 0x00000001 ? "" : "NOT "); -#ifdef PCI_BIOS_DEBUG - print_bios_bios_stat(); -#endif - return regs.eflags & 0x00000001; - - } - - return 1; - -} diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 46af391f29..4e9e1f77e5 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -33,7 +33,6 @@ #include <asm/io.h> #include <asm/ptrace.h> #include <asm/zimage.h> -#include <asm/realmode.h> #include <asm/byteorder.h> #include <asm/bootparam.h> #ifdef CONFIG_SYS_COREBOOT @@ -175,16 +174,9 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, else *load_address = (void *)ZIMAGE_LOAD_ADDR; -#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE) printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base); memset(setup_base, 0, sizeof(*setup_base)); setup_base->hdr = params->hdr; -#else - /* load setup */ - printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n", - (ulong)setup_base, setup_size); - memmove(setup_base, image, setup_size); -#endif if (bootproto >= 0x0204) kernel_size = hdr->syssize * 16; @@ -241,10 +233,8 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, struct setup_header *hdr = &setup_base->hdr; int bootproto = get_boot_protocol(hdr); -#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE) setup_base->e820_entries = install_e820_map( ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map); -#endif if (bootproto == 0x0100) { setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC; @@ -300,7 +290,6 @@ void boot_zimage(void *setup_base, void *load_address) #ifdef CONFIG_SYS_COREBOOT timestamp_add_now(TS_U_BOOT_START_KERNEL); #endif -#if defined CONFIG_ZBOOT_32 /* * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params * structure, and then jump to the kernel. We assume that %cs is @@ -317,18 +306,6 @@ void boot_zimage(void *setup_base, void *load_address) "b"(0), "D"(0) : "%ebp" ); -#else - struct pt_regs regs; - - memset(®s, 0, sizeof(struct pt_regs)); - regs.xds = (u32)setup_base >> 4; - regs.xes = regs.xds; - regs.xss = regs.xds; - regs.esp = 0x9000; - regs.eflags = 0; - enter_realmode(((u32)setup_base + SETUP_START_OFFSET) >> 4, 0, - ®s, ®s); -#endif } void setup_pcat_compatibility(void) |