From d9e73a87a9bf30fca8de0578007ae431f18e5434 Mon Sep 17 00:00:00 2001 From: Allen Martin Date: Fri, 31 Aug 2012 08:30:01 +0000 Subject: tegra20: move tegra20 SoC code to arch/arm/cpu/tegra20-common In preparation for splitting out the armv4t code from tegra20, move the tegra20 SoC code to arch/arm/cpu/tegra20-common. This code will be compiled armv4t for the arm7tdmi and armv7 for the cortex A9. Signed-off-by: Allen Martin Acked-by: Stephen Warren Tested-by: Thierry Reding Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/tegra20/Makefile | 15 +- arch/arm/cpu/armv7/tegra20/ap20.c | 388 ---------- arch/arm/cpu/armv7/tegra20/board.c | 167 ----- arch/arm/cpu/armv7/tegra20/clock.c | 1087 ---------------------------- arch/arm/cpu/armv7/tegra20/crypto.c | 230 ------ arch/arm/cpu/armv7/tegra20/crypto.h | 36 - arch/arm/cpu/armv7/tegra20/emc.c | 286 -------- arch/arm/cpu/armv7/tegra20/funcmux.c | 249 ------- arch/arm/cpu/armv7/tegra20/lowlevel_init.S | 42 -- arch/arm/cpu/armv7/tegra20/pinmux.c | 572 --------------- arch/arm/cpu/armv7/tegra20/pmu.c | 70 -- arch/arm/cpu/armv7/tegra20/sys_info.c | 35 - arch/arm/cpu/armv7/tegra20/timer.c | 111 --- arch/arm/cpu/armv7/tegra20/warmboot.c | 386 ---------- arch/arm/cpu/armv7/tegra20/warmboot_avp.c | 250 ------- arch/arm/cpu/armv7/tegra20/warmboot_avp.h | 81 --- 16 files changed, 2 insertions(+), 4003 deletions(-) delete mode 100644 arch/arm/cpu/armv7/tegra20/ap20.c delete mode 100644 arch/arm/cpu/armv7/tegra20/board.c delete mode 100644 arch/arm/cpu/armv7/tegra20/clock.c delete mode 100644 arch/arm/cpu/armv7/tegra20/crypto.c delete mode 100644 arch/arm/cpu/armv7/tegra20/crypto.h delete mode 100644 arch/arm/cpu/armv7/tegra20/emc.c delete mode 100644 arch/arm/cpu/armv7/tegra20/funcmux.c delete mode 100644 arch/arm/cpu/armv7/tegra20/lowlevel_init.S delete mode 100644 arch/arm/cpu/armv7/tegra20/pinmux.c delete mode 100644 arch/arm/cpu/armv7/tegra20/pmu.c delete mode 100644 arch/arm/cpu/armv7/tegra20/sys_info.c delete mode 100644 arch/arm/cpu/armv7/tegra20/timer.c delete mode 100644 arch/arm/cpu/armv7/tegra20/warmboot.c delete mode 100644 arch/arm/cpu/armv7/tegra20/warmboot_avp.c delete mode 100644 arch/arm/cpu/armv7/tegra20/warmboot_avp.h (limited to 'arch/arm/cpu/armv7') diff --git a/arch/arm/cpu/armv7/tegra20/Makefile b/arch/arm/cpu/armv7/tegra20/Makefile index da626465be..5f4035d79c 100644 --- a/arch/arm/cpu/armv7/tegra20/Makefile +++ b/arch/arm/cpu/armv7/tegra20/Makefile @@ -23,27 +23,16 @@ # MA 02111-1307 USA # -# The AVP is ARMv4T architecture so we must use special compiler -# flags for any startup files it might use. -CFLAGS_arch/arm/cpu/armv7/tegra20/ap20.o += -march=armv4t -CFLAGS_arch/arm/cpu/armv7/tegra20/clock.o += -march=armv4t -CFLAGS_arch/arm/cpu/armv7/tegra20/warmboot_avp.o += -march=armv4t - include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -SOBJS := lowlevel_init.o -COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o -COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o -COBJS-$(CONFIG_TEGRA_PMU) += pmu.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o -COBJS-$(CONFIG_TEGRA20_LP0) += crypto.o warmboot.o warmboot_avp.o COBJS-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o COBJS := $(COBJS-y) -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) all: $(obj).depend $(LIB) diff --git a/arch/arm/cpu/armv7/tegra20/ap20.c b/arch/arm/cpu/armv7/tegra20/ap20.c deleted file mode 100644 index 8b6afbcf57..0000000000 --- a/arch/arm/cpu/armv7/tegra20/ap20.c +++ /dev/null @@ -1,388 +0,0 @@ -/* -* (C) Copyright 2010-2011 -* NVIDIA Corporation -* -* See file CREDITS for list of people who contributed to this -* project. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, -* MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int tegra_get_chip_type(void) -{ - struct apb_misc_gp_ctlr *gp; - struct fuse_regs *fuse = (struct fuse_regs *)TEGRA20_FUSE_BASE; - uint tegra_sku_id, rev; - - /* - * This is undocumented, Chip ID is bits 15:8 of the register - * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for - * Tegra30 - */ - gp = (struct apb_misc_gp_ctlr *)TEGRA20_APB_MISC_GP_BASE; - rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; - - tegra_sku_id = readl(&fuse->sku_info) & 0xff; - - switch (rev) { - case CHIPID_TEGRA20: - switch (tegra_sku_id) { - case SKU_ID_T20: - return TEGRA_SOC_T20; - case SKU_ID_T25SE: - case SKU_ID_AP25: - case SKU_ID_T25: - case SKU_ID_AP25E: - case SKU_ID_T25E: - return TEGRA_SOC_T25; - } - break; - } - /* unknown sku id */ - return TEGRA_SOC_UNKNOWN; -} - -/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ -static 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_simple *pll = - &clkrst->crc_pll_simple[CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE]; - 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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_PMC_BASE; - u32 reg; - - reg = readl(&pmc->pmc_cntrl); - reg |= CPUPWRREQ_OE; - writel(reg, &pmc->pmc_cntrl); - - /* - * The TI PMU65861C needs a 3.75ms delay between enabling - * the power rail and enabling the CPU clock. This delay - * between SM1EN and SM1 is for switching time + the ramp - * up of the voltage to the CPU (VDD_CPU from PMU). - */ - udelay(3750); -} - -static void reset_A9_cpu(int reset) -{ - /* - * 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 */ - enable_cpu_power_rail(); - - /* Hold the CPUs in reset */ - reset_A9_cpu(1); - - /* Disable the CPU clock */ - enable_cpu_clock(0); - - /* Enable CoreSight */ - clock_enable_coresight(1); - - /* - * Set the entry point for CPU execution from reset, - * if it's a non-zero value. - */ - if (reset_vector) - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Enable the CPU clock */ - enable_cpu_clock(1); - - /* If the CPU doesn't already have power, power it up */ - powerup_cpu(); - - /* Take the CPU out of reset */ - reset_A9_cpu(0); -} - - -void halt_avp(void) -{ - for (;;) { - writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ - | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)), - FLOW_CTLR_HALT_COP_EVENTS); - } -} - -void enable_scu(void) -{ - struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; - u32 reg; - - /* If SCU already setup/enabled, return */ - if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) - return; - - /* Invalidate all ways for all processors */ - writel(0xFFFF, &scu->scu_inv_all); - - /* Enable SCU - bit 0 */ - reg = readl(&scu->scu_ctrl); - reg |= SCU_CTRL_ENABLE; - writel(reg, &scu->scu_ctrl); -} - -static u32 get_odmdata(void) -{ - /* - * ODMDATA is stored in the BCT in IRAM by the BootROM. - * The BCT start and size are stored in the BIT in IRAM. - * Read the data @ bct_start + (bct_size - 12). This works - * on T20 and T30 BCTs, which are locked down. If this changes - * in new chips (T114, etc.), we can revisit this algorithm. - */ - - u32 bct_start, odmdata; - - bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR); - odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); - - return odmdata; -} - -void init_pmc_scratch(void) -{ - struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE; - u32 odmdata; - int i; - - /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ - for (i = 0; i < 23; i++) - writel(0, &pmc->pmc_scratch1+i); - - /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ - odmdata = get_odmdata(); - writel(odmdata, &pmc->pmc_scratch20); - -#ifdef CONFIG_TEGRA20_LP0 - /* save Sdram params to PMC 2, 4, and 24 for WB0 */ - warmboot_save_sdram_params(); -#endif -} - -void tegra20_start(void) -{ - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - - /* If we are the AVP, start up the first Cortex-A9 */ - if (!ap20_cpu_is_cortexa9()) { - /* enable JTAG */ - writel(0xC0, &pmt->pmt_cfg_ctl); - - /* - * If we are ARM7 - give it a different stack. We are about to - * start up the A9 which will want to use this one. - */ - asm volatile("mov sp, %0\n" - : : "r"(AVP_EARLY_BOOT_STACK_LIMIT)); - - start_cpu((u32)_start); - halt_avp(); - /* not reached */ - } - - /* Init PMC scratch memory */ - init_pmc_scratch(); - - enable_scu(); - - /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ - asm volatile( - "mrc p15, 0, r0, c1, c0, 1\n" - "orr r0, r0, #0x41\n" - "mcr p15, 0, r0, c1, c0, 1\n"); - - /* FIXME: should have ap20's L2 disabled too? */ -} diff --git a/arch/arm/cpu/armv7/tegra20/board.c b/arch/arm/cpu/armv7/tegra20/board.c deleted file mode 100644 index e595ff9c07..0000000000 --- a/arch/arm/cpu/armv7/tegra20/board.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -enum { - /* UARTs which we can enable */ - UARTA = 1 << 0, - UARTB = 1 << 1, - UARTD = 1 << 3, - UART_COUNT = 4, -}; - -/* - * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0, - * so we are using this value to identify memory size. - */ - -unsigned int query_sdram_size(void) -{ - struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE; - u32 reg; - - reg = readl(&pmc->pmc_scratch20); - debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg); - - /* bits 31:28 in OdmData are used for RAM size */ - switch ((reg) >> 28) { - case 1: - return 0x10000000; /* 256 MB */ - case 2: - default: - return 0x20000000; /* 512 MB */ - case 3: - return 0x40000000; /* 1GB */ - } -} - -int dram_init(void) -{ - /* We do not initialise DRAM here. We just query the size */ - gd->ram_size = query_sdram_size(); - return 0; -} - -#ifdef CONFIG_DISPLAY_BOARDINFO -int checkboard(void) -{ - printf("Board: %s\n", sysinfo.board_string); - return 0; -} -#endif /* CONFIG_DISPLAY_BOARDINFO */ - -#ifdef CONFIG_ARCH_CPU_INIT -/* - * Note this function is executed by the ARM7TDMI AVP. It does not return - * in this case. It is also called once the A9 starts up, but does nothing in - * that case. - */ -int arch_cpu_init(void) -{ - /* Fire up the Cortex A9 */ - tegra20_start(); - - /* We didn't do this init in start.S, so do it now */ - cpu_init_cp15(); - - /* Initialize essential common plls */ - clock_early_init(); - - return 0; -} -#endif - -static int uart_configs[] = { -#if defined(CONFIG_TEGRA20_UARTA_UAA_UAB) - FUNCMUX_UART1_UAA_UAB, -#elif defined(CONFIG_TEGRA20_UARTA_GPU) - FUNCMUX_UART1_GPU, -#elif defined(CONFIG_TEGRA20_UARTA_SDIO1) - FUNCMUX_UART1_SDIO1, -#else - FUNCMUX_UART1_IRRX_IRTX, -#endif - FUNCMUX_UART2_IRDA, - -1, - FUNCMUX_UART4_GMC, - -1, -}; - -/** - * Set up the specified uarts - * - * @param uarts_ids Mask containing UARTs to init (UARTx) - */ -static void setup_uarts(int uart_ids) -{ - static enum periph_id id_for_uart[] = { - PERIPH_ID_UART1, - PERIPH_ID_UART2, - PERIPH_ID_UART3, - PERIPH_ID_UART4, - }; - size_t i; - - for (i = 0; i < UART_COUNT; i++) { - if (uart_ids & (1 << i)) { - enum periph_id id = id_for_uart[i]; - - funcmux_select(id, uart_configs[i]); - clock_ll_start_uart(id); - } - } -} - -void board_init_uart_f(void) -{ - int uart_ids = 0; /* bit mask of which UART ids to enable */ - -#ifdef CONFIG_TEGRA20_ENABLE_UARTA - uart_ids |= UARTA; -#endif -#ifdef CONFIG_TEGRA20_ENABLE_UARTB - uart_ids |= UARTB; -#endif -#ifdef CONFIG_TEGRA20_ENABLE_UARTD - uart_ids |= UARTD; -#endif - setup_uarts(uart_ids); -} - -#ifndef CONFIG_SYS_DCACHE_OFF -void enable_caches(void) -{ - /* Enable D-cache. I-cache is already enabled in start.S */ - dcache_enable(); -} -#endif diff --git a/arch/arm/cpu/armv7/tegra20/clock.c b/arch/arm/cpu/armv7/tegra20/clock.c deleted file mode 100644 index 24038745bd..0000000000 --- a/arch/arm/cpu/armv7/tegra20/clock.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * 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 - */ - -/* Tegra20 Clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * 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 - * 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_PCMT with 16-bit divider */ - CLOCK_TYPE_PCXTS, - CLOCK_TYPE_PDCT, - - CLOCK_TYPE_COUNT, - 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 */ -}; - -/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS - * is special as it has 5 sources. Since it also has a different number of - * bits in its register for the source, we just handle it with a special - * case in the code. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, -}; - -/* - * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is - * not in the header file since it is for purely internal use - 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. - * - * Note to SOC vendors: perhaps define a unified numbering for peripherals and - * use it for reset, clock enable, clock source/divider and even pinmuxing - * if you can. - */ -enum periphc_internal_id { - /* 0x00 */ - PERIPHC_I2S1, - PERIPHC_I2S2, - PERIPHC_SPDIF_OUT, - PERIPHC_SPDIF_IN, - PERIPHC_PWM, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_SPI3, - - /* 0x08 */ - PERIPHC_XIO, - PERIPHC_I2C1, - PERIPHC_DVC_I2C, - PERIPHC_TWC, - PERIPHC_0c, - PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ - PERIPHC_DISP1, - PERIPHC_DISP2, - - /* 0x10 */ - PERIPHC_CVE, - PERIPHC_IDE0, - PERIPHC_VI, - PERIPHC_1c, - 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_21, - PERIPHC_TVO, - PERIPHC_HDMI, - PERIPHC_24, - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_EMC, - - /* 0x28 */ - PERIPHC_UART3, - PERIPHC_29, - PERIPHC_VI_SENSOR, - PERIPHC_2b, - PERIPHC_2c, - PERIPHC_SPI4, - PERIPHC_I2C3, - PERIPHC_SDMMC3, - - /* 0x30 */ - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_VDE, - PERIPHC_OWR, - PERIPHC_NOR, - PERIPHC_CSITE, - - PERIPHC_COUNT, - - 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 - */ -#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_PCXTS), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), - - /* 0x08 */ - TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), - - /* 0x10 */ - TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), - 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), - 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_PDCT), - 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_SPI4, 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), -}; - -/* - * 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(RESERVED1), - NONE(RESERVED2), - NONE(AC97), - NONE(RTC), - NONE(TMR), - PERIPHC_UART1, - PERIPHC_UART2, /* and vfir 0x68 */ - - /* 0x08 */ - NONE(GPIO), - PERIPHC_SDMMC2, - NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ - PERIPHC_I2S1, - PERIPHC_I2C1, - PERIPHC_NDFLASH, - PERIPHC_SDMMC1, - PERIPHC_SDMMC4, - - /* 0x10 */ - PERIPHC_TWC, - PERIPHC_PWM, - PERIPHC_I2S2, - PERIPHC_EPP, - PERIPHC_VI, - PERIPHC_G2D, - NONE(USBD), - NONE(ISP), - - /* 0x18 */ - PERIPHC_G3D, - PERIPHC_IDE0, - PERIPHC_DISP2, - PERIPHC_DISP1, - PERIPHC_HOST1X, - NONE(VCP), - NONE(RESERVED30), - NONE(CACHE2), - - /* Middle word: 63:32 */ - NONE(MEM), - NONE(AHBDMA), - NONE(APBDMA), - NONE(RESERVED35), - NONE(KBC), - NONE(STAT_MON), - NONE(PMC), - NONE(FUSE), - - /* 0x28 */ - NONE(KFUSE), - NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ - PERIPHC_NOR, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_XIO, - PERIPHC_SPI3, - PERIPHC_DVC_I2C, - - /* 0x30 */ - NONE(DSI), - PERIPHC_TVO, /* also CVE 0x40 */ - PERIPHC_MIPI, - PERIPHC_HDMI, - PERIPHC_CSITE, - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_UART3, - - /* 0x38 */ - NONE(RESERVED56), - PERIPHC_EMC, - NONE(USB2), - NONE(USB3), - PERIPHC_MPE, - PERIPHC_VDE, - NONE(BSEA), - NONE(BSEV), - - /* Upper word 95:64 */ - NONE(SPEEDO), - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_I2C3, - PERIPHC_SPI4, - PERIPHC_SDMMC3, - NONE(PCIE), - PERIPHC_OWR, - - /* 0x48 */ - NONE(AFI), - NONE(CORESIGHT), - NONE(RESERVED74), - NONE(AVPUCQ), - NONE(RESERVED76), - NONE(RESERVED77), - NONE(RESERVED78), - NONE(RESERVED79), - - /* 0x50 */ - NONE(RESERVED80), - NONE(RESERVED81), - NONE(RESERVED82), - NONE(RESERVED83), - NONE(IRAMA), - NONE(IRAMB), - NONE(IRAMC), - NONE(IRAMD), - - /* 0x58 */ - NONE(CRAM2), -}; - -/* - * Get the oscillator frequency, from the corresponding hardware configuration - * field. - */ -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); - 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: - 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) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - enum periphc_internal_id internal_id; - - assert(clock_periph_id_isvalid(periph_id)); - internal_id = periph_id_to_internal_id[periph_id]; - assert(internal_id != -1); - 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); -} - -/** - * 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. - * - * 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) - */ -static 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)); - - /* - * Special cases here for the clock with a 4-bit source mux and I2C - * with its 16-bit divisor - */ - if (type == CLOCK_TYPE_PCXTS) - *mux_bits = 4; - else - *mux_bits = 2; - 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; - - /* - * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS - * which is not in our table. If not, then they are asking for a - * source which this peripheral can't access through its mux. - */ - assert(type == CLOCK_TYPE_PCXTS); - assert(parent == CLOCK_ID_SFROM32KHZ); - if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) - return 4; /* mux value for this clock */ - - /* 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; -} - -/** - * 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 = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; - u32 reg; - - /* Enable/disable the clock to this peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - reg = readl(clk); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - 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 = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; - u32 reg; - - /* Enable/disable reset to the peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - reg = readl(reset); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - 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 - * the same but we are very cautious so we check that a valid clock ID is - * provided. - * - * @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) -{ - if (clk_id > 95) - 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: - 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) -{ - /* - * PLLP output frequency set to 216MHz - * PLLC output frequency set to 600Mhz - * - * TODO: Can we calculate these values instead of hard-coding? - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 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, 432, 13, 1, 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; - } -} - -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/armv7/tegra20/crypto.c b/arch/arm/cpu/armv7/tegra20/crypto.c deleted file mode 100644 index 5f0b240e27..0000000000 --- a/arch/arm/cpu/armv7/tegra20/crypto.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010 - 2011 NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include "crypto.h" -#include "aes.h" - -static u8 zero_key[16]; - -#define AES_CMAC_CONST_RB 0x87 /* from RFC 4493, Figure 2.2 */ - -enum security_op { - SECURITY_SIGN = 1 << 0, /* Sign the data */ - SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */ -}; - -static void debug_print_vector(char *name, u32 num_bytes, u8 *data) -{ - u32 i; - - debug("%s [%d] @0x%08x", name, num_bytes, (u32)data); - for (i = 0; i < num_bytes; i++) { - if (i % 16 == 0) - debug(" = "); - debug("%02x", data[i]); - if ((i+1) % 16 != 0) - debug(" "); - } - debug("\n"); -} - -/** - * Apply chain data to the destination using EOR - * - * Each array is of length AES_AES_KEY_LENGTH. - * - * \param cbc_chain_data Chain data - * \param src Source data - * \param dst Destination data, which is modified here - */ -static void apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst) -{ - int i; - - for (i = 0; i < 16; i++) - *dst++ = *src++ ^ *cbc_chain_data++; -} - -/** - * Encrypt some data with AES. - * - * \param key_schedule Expanded key to use - * \param src Source data to encrypt - * \param dst Destination buffer - * \param num_aes_blocks Number of AES blocks to encrypt - */ -static void encrypt_object(u8 *key_schedule, u8 *src, u8 *dst, - u32 num_aes_blocks) -{ - u8 tmp_data[AES_KEY_LENGTH]; - u8 *cbc_chain_data; - u32 i; - - cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ - - for (i = 0; i < num_aes_blocks; i++) { - debug("encrypt_object: block %d of %d\n", i, num_aes_blocks); - debug_print_vector("AES Src", AES_KEY_LENGTH, src); - - /* Apply the chain data */ - apply_cbc_chain_data(cbc_chain_data, src, tmp_data); - debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data); - - /* encrypt the AES block */ - aes_encrypt(tmp_data, key_schedule, dst); - debug_print_vector("AES Dst", AES_KEY_LENGTH, dst); - - /* Update pointers for next loop. */ - cbc_chain_data = dst; - src += AES_KEY_LENGTH; - dst += AES_KEY_LENGTH; - } -} - -/** - * Shift a vector left by one bit - * - * \param in Input vector - * \param out Output vector - * \param size Length of vector in bytes - */ -static void left_shift_vector(u8 *in, u8 *out, int size) -{ - int carry = 0; - int i; - - for (i = size - 1; i >= 0; i--) { - out[i] = (in[i] << 1) | carry; - carry = in[i] >> 7; /* get most significant bit */ - } -} - -/** - * Sign a block of data, putting the result into dst. - * - * \param key Input AES key, length AES_KEY_LENGTH - * \param key_schedule Expanded key to use - * \param src Source data of length 'num_aes_blocks' blocks - * \param dst Destination buffer, length AES_KEY_LENGTH - * \param num_aes_blocks Number of AES blocks to encrypt - */ -static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, - u32 num_aes_blocks) -{ - u8 tmp_data[AES_KEY_LENGTH]; - u8 left[AES_KEY_LENGTH]; - u8 k1[AES_KEY_LENGTH]; - u8 *cbc_chain_data; - unsigned i; - - cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ - - /* compute K1 constant needed by AES-CMAC calculation */ - for (i = 0; i < AES_KEY_LENGTH; i++) - tmp_data[i] = 0; - - encrypt_object(key_schedule, tmp_data, left, 1); - debug_print_vector("AES(key, nonce)", AES_KEY_LENGTH, left); - - left_shift_vector(left, k1, sizeof(left)); - debug_print_vector("L", AES_KEY_LENGTH, left); - - if ((left[0] >> 7) != 0) /* get MSB of L */ - k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB; - debug_print_vector("K1", AES_KEY_LENGTH, k1); - - /* compute the AES-CMAC value */ - for (i = 0; i < num_aes_blocks; i++) { - /* Apply the chain data */ - apply_cbc_chain_data(cbc_chain_data, src, tmp_data); - - /* for the final block, XOR K1 into the IV */ - if (i == num_aes_blocks - 1) - apply_cbc_chain_data(tmp_data, k1, tmp_data); - - /* encrypt the AES block */ - aes_encrypt(tmp_data, key_schedule, dst); - - debug("sign_obj: block %d of %d\n", i, num_aes_blocks); - debug_print_vector("AES-CMAC Src", AES_KEY_LENGTH, src); - debug_print_vector("AES-CMAC Xor", AES_KEY_LENGTH, tmp_data); - debug_print_vector("AES-CMAC Dst", AES_KEY_LENGTH, dst); - - /* Update pointers for next loop. */ - cbc_chain_data = dst; - src += AES_KEY_LENGTH; - } - - debug_print_vector("AES-CMAC Hash", AES_KEY_LENGTH, dst); -} - -/** - * Encrypt and sign a block of data (depending on security mode). - * - * \param key Input AES key, length AES_KEY_LENGTH - * \param oper Security operations mask to perform (enum security_op) - * \param src Source data - * \param length Size of source data - * \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes - */ -static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, - u32 length, u8 *sig_dst) -{ - u32 num_aes_blocks; - u8 key_schedule[AES_EXPAND_KEY_LENGTH]; - - debug("encrypt_and_sign: length = %d\n", length); - debug_print_vector("AES key", AES_KEY_LENGTH, key); - - /* - * The only need for a key is for signing/checksum purposes, so - * if not encrypting, expand a key of 0s. - */ - aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule); - - num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH; - - if (oper & SECURITY_ENCRYPT) { - /* Perform this in place, resulting in src being encrypted. */ - debug("encrypt_and_sign: begin encryption\n"); - encrypt_object(key_schedule, src, src, num_aes_blocks); - debug("encrypt_and_sign: end encryption\n"); - } - - if (oper & SECURITY_SIGN) { - /* encrypt the data, overwriting the result in signature. */ - debug("encrypt_and_sign: begin signing\n"); - sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); - debug("encrypt_and_sign: end signing\n"); - } - - return 0; -} - -int sign_data_block(u8 *source, unsigned length, u8 *signature) -{ - return encrypt_and_sign(zero_key, SECURITY_SIGN, source, - length, signature); -} diff --git a/arch/arm/cpu/armv7/tegra20/crypto.h b/arch/arm/cpu/armv7/tegra20/crypto.h deleted file mode 100644 index aff67e77b0..0000000000 --- a/arch/arm/cpu/armv7/tegra20/crypto.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010 - 2011 NVIDIA Corporation - * - * 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 _CRYPTO_H_ -#define _CRYPTO_H_ - -/** - * Sign a block of data - * - * \param source Source data - * \param length Size of source data - * \param signature Destination address for signature, AES_KEY_LENGTH bytes - */ -int sign_data_block(u8 *source, unsigned length, u8 *signature); - -#endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/cpu/armv7/tegra20/emc.c b/arch/arm/cpu/armv7/tegra20/emc.c deleted file mode 100644 index ffc05e453a..0000000000 --- a/arch/arm/cpu/armv7/tegra20/emc.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The EMC registers have shadow registers. When the EMC clock is updated - * in the clock controller, the shadow registers are copied to the active - * registers, allowing glitchless memory bus frequency changes. - * This function updates the shadow registers for a new clock frequency, - * and relies on the clock lock on the emc clock to avoid races between - * multiple frequency changes - */ - -/* - * This table defines the ordering of the registers provided to - * tegra_set_mmc() - * TODO: Convert to fdt version once available - */ -static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { - 0x2c, /* RC */ - 0x30, /* RFC */ - 0x34, /* RAS */ - 0x38, /* RP */ - 0x3c, /* R2W */ - 0x40, /* W2R */ - 0x44, /* R2P */ - 0x48, /* W2P */ - 0x4c, /* RD_RCD */ - 0x50, /* WR_RCD */ - 0x54, /* RRD */ - 0x58, /* REXT */ - 0x5c, /* WDV */ - 0x60, /* QUSE */ - 0x64, /* QRST */ - 0x68, /* QSAFE */ - 0x6c, /* RDV */ - 0x70, /* REFRESH */ - 0x74, /* BURST_REFRESH_NUM */ - 0x78, /* PDEX2WR */ - 0x7c, /* PDEX2RD */ - 0x80, /* PCHG2PDEN */ - 0x84, /* ACT2PDEN */ - 0x88, /* AR2PDEN */ - 0x8c, /* RW2PDEN */ - 0x90, /* TXSR */ - 0x94, /* TCKE */ - 0x98, /* TFAW */ - 0x9c, /* TRPAB */ - 0xa0, /* TCLKSTABLE */ - 0xa4, /* TCLKSTOP */ - 0xa8, /* TREFBW */ - 0xac, /* QUSE_EXTRA */ - 0x114, /* FBIO_CFG6 */ - 0xb0, /* ODT_WRITE */ - 0xb4, /* ODT_READ */ - 0x104, /* FBIO_CFG5 */ - 0x2bc, /* CFG_DIG_DLL */ - 0x2c0, /* DLL_XFORM_DQS */ - 0x2c4, /* DLL_XFORM_QUSE */ - 0x2e0, /* ZCAL_REF_CNT */ - 0x2e4, /* ZCAL_WAIT_CNT */ - 0x2a8, /* AUTO_CAL_INTERVAL */ - 0x2d0, /* CFG_CLKTRIM_0 */ - 0x2d4, /* CFG_CLKTRIM_1 */ - 0x2d8, /* CFG_CLKTRIM_2 */ -}; - -struct emc_ctlr *emc_get_controller(const void *blob) -{ - fdt_addr_t addr; - int node; - - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); - if (node > 0) { - addr = fdtdec_get_addr(blob, node, "reg"); - if (addr != FDT_ADDR_T_NONE) - return (struct emc_ctlr *)addr; - } - return NULL; -} - -/* Error codes we use */ -enum { - ERR_NO_EMC_NODE = -10, - ERR_NO_EMC_REG, - ERR_NO_FREQ, - ERR_FREQ_NOT_FOUND, - ERR_BAD_REGS, - ERR_NO_RAM_CODE, - ERR_RAM_CODE_NOT_FOUND, -}; - -/** - * Find EMC tables for the given ram code. - * - * The tegra EMC binding has two options, one using the ram code and one not. - * We detect which is in use by looking for the nvidia,use-ram-code property. - * If this is not present, then the EMC tables are directly below 'node', - * otherwise we select the correct emc-tables subnode based on the 'ram_code' - * value. - * - * @param blob Device tree blob - * @param node EMC node (nvidia,tegra20-emc compatible string) - * @param ram_code RAM code to select (0-3, or -1 if unknown) - * @return 0 if ok, otherwise a -ve ERR_ code (see enum above) - */ -static int find_emc_tables(const void *blob, int node, int ram_code) -{ - int need_ram_code; - int depth; - int offset; - - /* If we are using RAM codes, scan through the tables for our code */ - need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code"); - if (!need_ram_code) - return node; - if (ram_code == -1) { - debug("%s: RAM code required but not supplied\n", __func__); - return ERR_NO_RAM_CODE; - } - - offset = node; - depth = 0; - do { - /* - * Sadly there is no compatible string so we cannot use - * fdtdec_next_compatible_subnode(). - */ - offset = fdt_next_node(blob, offset, &depth); - if (depth <= 0) - break; - - /* Make sure this is a direct subnode */ - if (depth != 1) - continue; - if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL))) - continue; - - if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1) - == ram_code) - return offset; - } while (1); - - debug("%s: Could not find tables for RAM code %d\n", __func__, - ram_code); - return ERR_RAM_CODE_NOT_FOUND; -} - -/** - * Decode the EMC node of the device tree, returning a pointer to the emc - * controller and the table to be used for the given rate. - * - * @param blob Device tree blob - * @param rate Clock speed of memory controller in Hz (=2x memory bus rate) - * @param emcp Returns address of EMC controller registers - * @param tablep Returns pointer to table to program into EMC. There are - * TEGRA_EMC_NUM_REGS entries, destined for offsets as per the - * emc_reg_addr array. - * @return 0 if ok, otherwise a -ve error code which will allow someone to - * figure out roughly what went wrong by looking at this code. - */ -static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp, - const u32 **tablep) -{ - struct apb_misc_pp_ctlr *pp = - (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; - int ram_code; - int depth; - int node; - - ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK) - >> RAM_CODE_SHIFT; - /* - * The EMC clock rate is twice the bus rate, and the bus rate is - * measured in kHz - */ - rate = rate / 2 / 1000; - - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); - if (node < 0) { - debug("%s: No EMC node found in FDT\n", __func__); - return ERR_NO_EMC_NODE; - } - *emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg"); - if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) { - debug("%s: No EMC node reg property\n", __func__); - return ERR_NO_EMC_REG; - } - - /* Work out the parent node which contains our EMC tables */ - node = find_emc_tables(blob, node, ram_code & 3); - if (node < 0) - return node; - - depth = 0; - for (;;) { - int node_rate; - - node = fdtdec_next_compatible_subnode(blob, node, - COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth); - if (node < 0) - break; - node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1); - if (node_rate == -1) { - debug("%s: Missing clock-frequency\n", __func__); - return ERR_NO_FREQ; /* we expect this property */ - } - - if (node_rate == rate) - break; - } - if (node < 0) { - debug("%s: No node found for clock frequency %d\n", __func__, - rate); - return ERR_FREQ_NOT_FOUND; - } - - *tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers", - TEGRA_EMC_NUM_REGS); - if (!*tablep) { - debug("%s: node '%s' array missing / wrong size\n", __func__, - fdt_get_name(blob, node, NULL)); - return ERR_BAD_REGS; - } - - /* All seems well */ - return 0; -} - -int tegra_set_emc(const void *blob, unsigned rate) -{ - struct emc_ctlr *emc; - const u32 *table; - int err, i; - - err = decode_emc(blob, rate, &emc, &table); - if (err) { - debug("Warning: no valid EMC (%d), memory timings unset\n", - err); - return err; - } - - debug("%s: Table found, setting EMC values as follows:\n", __func__); - for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) { - u32 value = fdt32_to_cpu(table[i]); - u32 addr = (uintptr_t)emc + emc_reg_addr[i]; - - debug(" %#x: %#x\n", addr, value); - writel(value, addr); - } - - /* trigger emc with new settings */ - clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY, - clock_get_rate(CLOCK_ID_MEMORY), NULL); - debug("EMC clock set to %lu\n", - clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY)); - - return 0; -} diff --git a/arch/arm/cpu/armv7/tegra20/funcmux.c b/arch/arm/cpu/armv7/tegra20/funcmux.c deleted file mode 100644 index 8cfed645ce..0000000000 --- a/arch/arm/cpu/armv7/tegra20/funcmux.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * 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 - */ - -/* Tegra20 high-level function multiplexing */ -#include -#include -#include -#include - -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_IRRX_IRTX: - pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); - pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PINGRP_IRRX); - pinmux_tristate_disable(PINGRP_IRTX); - break; - case FUNCMUX_UART1_UAA_UAB: - pinmux_set_func(PINGRP_UAA, PMUX_FUNC_UARTA); - pinmux_set_func(PINGRP_UAB, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PINGRP_UAA); - pinmux_tristate_disable(PINGRP_UAB); - bad_config = 0; - break; - case FUNCMUX_UART1_GPU: - pinmux_set_func(PINGRP_GPU, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PINGRP_GPU); - bad_config = 0; - break; - case FUNCMUX_UART1_SDIO1: - pinmux_set_func(PINGRP_SDIO1, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PINGRP_SDIO1); - bad_config = 0; - break; - } - if (!bad_config) { - /* - * Tegra appears to boot with function UARTA pre- - * selected on mux group SDB. If two mux groups are - * both set to the same function, it's unclear which - * group's pins drive the RX signals into the HW. - * For UARTA, SDB certainly overrides group IRTX in - * practice. To solve this, configure some alternative - * function on SDB to avoid the conflict. Also, tri- - * state the group to avoid driving any signal onto it - * until we know what's connected. - */ - pinmux_tristate_enable(PINGRP_SDB); - pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3); - } - break; - - case PERIPH_ID_UART2: - if (config == FUNCMUX_UART2_IRDA) { - pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); - pinmux_tristate_disable(PINGRP_UAD); - } - break; - - case PERIPH_ID_UART4: - if (config == FUNCMUX_UART4_GMC) { - pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); - pinmux_tristate_disable(PINGRP_GMC); - } - break; - - case PERIPH_ID_DVC_I2C: - /* there is only one selection, pinmux_config is ignored */ - if (config == FUNCMUX_DVC_I2CP) { - pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C); - pinmux_tristate_disable(PINGRP_I2CP); - } - break; - - case PERIPH_ID_I2C1: - /* support pinmux_config of 0 for now, */ - if (config == FUNCMUX_I2C1_RM) { - pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C); - pinmux_tristate_disable(PINGRP_RM); - } - break; - case PERIPH_ID_I2C2: /* I2C2 */ - switch (config) { - case FUNCMUX_I2C2_DDC: /* DDC pin group, select I2C2 */ - pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2); - /* PTA to HDMI */ - pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI); - pinmux_tristate_disable(PINGRP_DDC); - break; - case FUNCMUX_I2C2_PTA: /* PTA pin group, select I2C2 */ - pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2); - /* set DDC_SEL to RSVDx (RSVD2 works for now) */ - pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2); - pinmux_tristate_disable(PINGRP_PTA); - bad_config = 0; - break; - } - break; - case PERIPH_ID_I2C3: /* I2C3 */ - /* support pinmux_config of 0 for now */ - if (config == FUNCMUX_I2C3_DTF) { - pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3); - pinmux_tristate_disable(PINGRP_DTF); - } - break; - - case PERIPH_ID_SDMMC1: - if (config == FUNCMUX_SDMMC1_SDIO1_4BIT) { - pinmux_set_func(PINGRP_SDIO1, PMUX_FUNC_SDIO1); - pinmux_tristate_disable(PINGRP_SDIO1); - } - break; - - case PERIPH_ID_SDMMC2: - if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { - pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2); - pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2); - - pinmux_tristate_disable(PINGRP_DTA); - pinmux_tristate_disable(PINGRP_DTD); - } - break; - - case PERIPH_ID_SDMMC3: - switch (config) { - case FUNCMUX_SDMMC3_SDB_SLXA_8BIT: - pinmux_set_func(PINGRP_SLXA, PMUX_FUNC_SDIO3); - pinmux_set_func(PINGRP_SLXC, PMUX_FUNC_SDIO3); - pinmux_set_func(PINGRP_SLXD, PMUX_FUNC_SDIO3); - pinmux_set_func(PINGRP_SLXK, PMUX_FUNC_SDIO3); - - pinmux_tristate_disable(PINGRP_SLXA); - pinmux_tristate_disable(PINGRP_SLXC); - pinmux_tristate_disable(PINGRP_SLXD); - pinmux_tristate_disable(PINGRP_SLXK); - /* fall through */ - - case FUNCMUX_SDMMC3_SDB_4BIT: - pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3); - pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3); - pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3); - - pinmux_tristate_disable(PINGRP_SDB); - pinmux_tristate_disable(PINGRP_SDC); - pinmux_tristate_disable(PINGRP_SDD); - bad_config = 0; - break; - } - break; - - case PERIPH_ID_SDMMC4: - switch (config) { - case FUNCMUX_SDMMC4_ATC_ATD_8BIT: - pinmux_set_func(PINGRP_ATC, PMUX_FUNC_SDIO4); - pinmux_set_func(PINGRP_ATD, PMUX_FUNC_SDIO4); - - pinmux_tristate_disable(PINGRP_ATC); - pinmux_tristate_disable(PINGRP_ATD); - break; - - case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT: - pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4); - pinmux_tristate_disable(PINGRP_GME); - /* fall through */ - - case FUNCMUX_SDMMC4_ATB_GMA_4_BIT: - pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4); - pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4); - - pinmux_tristate_disable(PINGRP_ATB); - pinmux_tristate_disable(PINGRP_GMA); - bad_config = 0; - break; - } - break; - - case PERIPH_ID_KBC: - if (config == FUNCMUX_DEFAULT) { - enum pmux_pingrp grp[] = {PINGRP_KBCA, PINGRP_KBCB, - PINGRP_KBCC, PINGRP_KBCD, PINGRP_KBCE, - PINGRP_KBCF}; - int i; - - for (i = 0; i < ARRAY_SIZE(grp); i++) { - pinmux_tristate_disable(grp[i]); - pinmux_set_func(grp[i], PMUX_FUNC_KBC); - pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); - } - } - break; - - case PERIPH_ID_USB2: - if (config == FUNCMUX_USB2_ULPI) { - pinmux_set_func(PINGRP_UAA, PMUX_FUNC_ULPI); - pinmux_set_func(PINGRP_UAB, PMUX_FUNC_ULPI); - pinmux_set_func(PINGRP_UDA, PMUX_FUNC_ULPI); - - pinmux_tristate_disable(PINGRP_UAA); - pinmux_tristate_disable(PINGRP_UAB); - pinmux_tristate_disable(PINGRP_UDA); - } - break; - - case PERIPH_ID_SPI1: - if (config == FUNCMUX_SPI1_GMC_GMD) { - pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); - pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH); - - pinmux_tristate_disable(PINGRP_GMC); - pinmux_tristate_disable(PINGRP_GMD); - } - break; - - 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/armv7/tegra20/lowlevel_init.S b/arch/arm/cpu/armv7/tegra20/lowlevel_init.S deleted file mode 100644 index d117f23a62..0000000000 --- a/arch/arm/cpu/armv7/tegra20/lowlevel_init.S +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SoC-specific setup info - * - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - - .align 5 -ENTRY(reset_cpu) - ldr r1, rstctl @ get addr for global reset - @ reg - ldr r3, [r1] - orr r3, r3, #0x10 - str r3, [r1] @ force reset - mov r0, r0 -_loop_forever: - b _loop_forever -rstctl: - .word PRM_RSTCTRL -ENDPROC(reset_cpu) diff --git a/arch/arm/cpu/armv7/tegra20/pinmux.c b/arch/arm/cpu/armv7/tegra20/pinmux.c deleted file mode 100644 index 70e84dfa17..0000000000 --- a/arch/arm/cpu/armv7/tegra20/pinmux.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * 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 - */ - -/* Tegra20 pin multiplexing functions */ - -#include -#include -#include -#include - - -/* - * This defines the order of the pin mux control bits in the registers. For - * some reason there is no correspendence between the tristate, pin mux and - * pullup/pulldown registers. - */ -enum pmux_ctlid { - /* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */ - MUXCTL_UAA, - MUXCTL_UAB, - MUXCTL_UAC, - MUXCTL_UAD, - MUXCTL_UDA, - MUXCTL_RESERVED5, - MUXCTL_ATE, - MUXCTL_RM, - - MUXCTL_ATB, - MUXCTL_RESERVED9, - MUXCTL_ATD, - MUXCTL_ATC, - MUXCTL_ATA, - MUXCTL_KBCF, - MUXCTL_KBCE, - MUXCTL_SDMMC1, - - /* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */ - MUXCTL_GMA, - MUXCTL_GMC, - MUXCTL_HDINT, - MUXCTL_SLXA, - MUXCTL_OWC, - MUXCTL_SLXC, - MUXCTL_SLXD, - MUXCTL_SLXK, - - MUXCTL_UCA, - MUXCTL_UCB, - MUXCTL_DTA, - MUXCTL_DTB, - MUXCTL_RESERVED28, - MUXCTL_DTC, - MUXCTL_DTD, - MUXCTL_DTE, - - /* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */ - MUXCTL_DDC, - MUXCTL_CDEV1, - MUXCTL_CDEV2, - MUXCTL_CSUS, - MUXCTL_I2CP, - MUXCTL_KBCA, - MUXCTL_KBCB, - MUXCTL_KBCC, - - MUXCTL_IRTX, - MUXCTL_IRRX, - MUXCTL_DAP1, - MUXCTL_DAP2, - MUXCTL_DAP3, - MUXCTL_DAP4, - MUXCTL_GMB, - MUXCTL_GMD, - - /* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */ - MUXCTL_GME, - MUXCTL_GPV, - MUXCTL_GPU, - MUXCTL_SPDO, - MUXCTL_SPDI, - MUXCTL_SDB, - MUXCTL_SDC, - MUXCTL_SDD, - - MUXCTL_SPIH, - MUXCTL_SPIG, - MUXCTL_SPIF, - MUXCTL_SPIE, - MUXCTL_SPID, - MUXCTL_SPIC, - MUXCTL_SPIB, - MUXCTL_SPIA, - - /* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */ - MUXCTL_LPW0, - MUXCTL_LPW1, - MUXCTL_LPW2, - MUXCTL_LSDI, - MUXCTL_LSDA, - MUXCTL_LSPI, - MUXCTL_LCSN, - MUXCTL_LDC, - - MUXCTL_LSCK, - MUXCTL_LSC0, - MUXCTL_LSC1, - MUXCTL_LHS, - MUXCTL_LVS, - MUXCTL_LM0, - MUXCTL_LM1, - MUXCTL_LVP0, - - /* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */ - MUXCTL_LD0, - MUXCTL_LD1, - MUXCTL_LD2, - MUXCTL_LD3, - MUXCTL_LD4, - MUXCTL_LD5, - MUXCTL_LD6, - MUXCTL_LD7, - - MUXCTL_LD8, - MUXCTL_LD9, - MUXCTL_LD10, - MUXCTL_LD11, - MUXCTL_LD12, - MUXCTL_LD13, - MUXCTL_LD14, - MUXCTL_LD15, - - /* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */ - MUXCTL_LD16, - MUXCTL_LD17, - MUXCTL_LHP1, - MUXCTL_LHP2, - MUXCTL_LVP1, - MUXCTL_LHP0, - MUXCTL_RESERVED102, - MUXCTL_LPP, - - MUXCTL_LDI, - MUXCTL_PMC, - MUXCTL_CRTP, - MUXCTL_PTA, - MUXCTL_RESERVED108, - MUXCTL_KBCD, - MUXCTL_GPU7, - MUXCTL_DTF, - - MUXCTL_NONE = -1, -}; - -/* - * And this defines the order of the pullup/pulldown controls which are again - * in a different order - */ -enum pmux_pullid { - /* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */ - PUCTL_ATA, - PUCTL_ATB, - PUCTL_ATC, - PUCTL_ATD, - PUCTL_ATE, - PUCTL_DAP1, - PUCTL_DAP2, - PUCTL_DAP3, - - PUCTL_DAP4, - PUCTL_DTA, - PUCTL_DTB, - PUCTL_DTC, - PUCTL_DTD, - PUCTL_DTE, - PUCTL_DTF, - PUCTL_GPV, - - /* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */ - PUCTL_RM, - PUCTL_I2CP, - PUCTL_PTA, - PUCTL_GPU7, - PUCTL_KBCA, - PUCTL_KBCB, - PUCTL_KBCC, - PUCTL_KBCD, - - PUCTL_SPDI, - PUCTL_SPDO, - PUCTL_GPSLXAU, - PUCTL_CRTP, - PUCTL_SLXC, - PUCTL_SLXD, - PUCTL_SLXK, - - /* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */ - PUCTL_CDEV1, - PUCTL_CDEV2, - PUCTL_SPIA, - PUCTL_SPIB, - PUCTL_SPIC, - PUCTL_SPID, - PUCTL_SPIE, - PUCTL_SPIF, - - PUCTL_SPIG, - PUCTL_SPIH, - PUCTL_IRTX, - PUCTL_IRRX, - PUCTL_GME, - PUCTL_RESERVED45, - PUCTL_XM2D, - PUCTL_XM2C, - - /* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */ - PUCTL_UAA, - PUCTL_UAB, - PUCTL_UAC, - PUCTL_UAD, - PUCTL_UCA, - PUCTL_UCB, - PUCTL_LD17, - PUCTL_LD19_18, - - PUCTL_LD21_20, - PUCTL_LD23_22, - PUCTL_LS, - PUCTL_LC, - PUCTL_CSUS, - PUCTL_DDRC, - PUCTL_SDC, - PUCTL_SDD, - - /* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */ - PUCTL_KBCF, - PUCTL_KBCE, - PUCTL_PMCA, - PUCTL_PMCB, - PUCTL_PMCC, - PUCTL_PMCD, - PUCTL_PMCE, - PUCTL_CK32, - - PUCTL_UDA, - PUCTL_SDMMC1, - PUCTL_GMA, - PUCTL_GMB, - PUCTL_GMC, - PUCTL_GMD, - PUCTL_DDC, - PUCTL_OWC, - - PUCTL_NONE = -1 -}; - -struct tegra_pingroup_desc { - const char *name; - enum pmux_func funcs[4]; - enum pmux_func func_safe; - enum pmux_vddio vddio; - enum pmux_ctlid ctl_id; - enum pmux_pullid pull_id; -}; - - -/* Converts a pmux_pingrp number to a tristate register: 0=A, 1=B, 2=C, 3=D */ -#define TRISTATE_REG(pmux_pingrp) ((pmux_pingrp) >> 5) - -/* Mask value for a tristate (within TRISTATE_REG(id)) */ -#define TRISTATE_MASK(pmux_pingrp) (1 << ((pmux_pingrp) & 0x1f)) - -/* Converts a PUCTL id to a pull register: 0=A, 1=B...4=E */ -#define PULL_REG(pmux_pullid) ((pmux_pullid) >> 4) - -/* Converts a PUCTL id to a shift position */ -#define PULL_SHIFT(pmux_pullid) ((pmux_pullid << 1) & 0x1f) - -/* Converts a MUXCTL id to a ctl register: 0=A, 1=B...6=G */ -#define MUXCTL_REG(pmux_ctlid) ((pmux_ctlid) >> 4) - -/* Converts a MUXCTL id to a shift position */ -#define MUXCTL_SHIFT(pmux_ctlid) ((pmux_ctlid << 1) & 0x1f) - -/* Convenient macro for defining pin group properties */ -#define PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, mux, pupd) \ - { \ - .vddio = PMUX_VDDIO_ ## vdd, \ - .funcs = { \ - PMUX_FUNC_ ## f0, \ - PMUX_FUNC_ ## f1, \ - PMUX_FUNC_ ## f2, \ - PMUX_FUNC_ ## f3, \ - }, \ - .func_safe = PMUX_FUNC_ ## f_safe, \ - .ctl_id = mux, \ - .pull_id = pupd \ - } - -/* A normal pin group where the mux name and pull-up name match */ -#define PIN(pg_name, vdd, f0, f1, f2, f3, f_safe) \ - PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, \ - MUXCTL_ ## pg_name, PUCTL_ ## pg_name) - -/* A pin group where the pull-up name doesn't have a 1-1 mapping */ -#define PINP(pg_name, vdd, f0, f1, f2, f3, f_safe, pupd) \ - PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, \ - MUXCTL_ ## pg_name, PUCTL_ ## pupd) - -/* A pin group number which is not used */ -#define PIN_RESERVED \ - PIN(NONE, NONE, NONE, NONE, NONE, NONE, NONE) - -const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = { - PIN(ATA, NAND, IDE, NAND, GMI, RSVD, IDE), - PIN(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE), - PIN(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE), - PIN(ATD, NAND, IDE, NAND, GMI, SDIO4, IDE), - PIN(CDEV1, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC), - PIN(CDEV2, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC), - PIN(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, - PLLC_OUT1), - PIN(DAP1, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1), - - PIN(DAP2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2), - PIN(DAP3, BB, DAP3, RSVD, RSVD, RSVD, DAP3), - PIN(DAP4, UART, DAP4, RSVD, GMI, RSVD, DAP4), - PIN(DTA, VI, RSVD, SDIO2, VI, RSVD, RSVD4), - PIN(DTB, VI, RSVD, RSVD, VI, SPI1, RSVD1), - PIN(DTC, VI, RSVD, RSVD, VI, RSVD, RSVD1), - PIN(DTD, VI, RSVD, SDIO2, VI, RSVD, RSVD1), - PIN(DTE, VI, RSVD, RSVD, VI, SPI1, RSVD1), - - PINP(GPU, UART, PWM, UARTA, GMI, RSVD, RSVD4, - GPSLXAU), - PIN(GPV, SD, PCIE, RSVD, RSVD, RSVD, PCIE), - PIN(I2CP, SYS, I2C, RSVD, RSVD, RSVD, RSVD4), - PIN(IRTX, UART, UARTA, UARTB, GMI, SPI4, UARTB), - PIN(IRRX, UART, UARTA, UARTB, GMI, SPI4, UARTB), - PIN(KBCB, SYS, KBC, NAND, SDIO2, MIO, KBC), - PIN(KBCA, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC), - PINP(PMC, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, NONE), - - PIN(PTA, NAND, I2C2, HDMI, GMI, RSVD, RSVD4), - PIN(RM, UART, I2C, RSVD, RSVD, RSVD, RSVD4), - PIN(KBCE, SYS, KBC, NAND, OWR, RSVD, KBC), - PIN(KBCF, SYS, KBC, NAND, TRACE, MIO, KBC), - PIN(GMA, NAND, UARTE, SPI3, GMI, SDIO4, SPI3), - PIN(GMC, NAND, UARTD, SPI4, GMI, SFLASH, SPI4), - PIN(SDMMC1, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2), - PIN(OWC, SYS, OWR, RSVD, RSVD, RSVD, OWR), - - PIN(GME, NAND, RSVD, DAP5, GMI, SDIO4, GMI), - PIN(SDC, SD, PWM, TWC, SDIO3, SPI3, TWC), - PIN(SDD, SD, UARTA, PWM, SDIO3, SPI3, PWM), - PIN_RESERVED, - PINP(SLXA, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, CRTP), - PIN(SLXC, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4), - PIN(SLXD, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4), - PIN(SLXK, SD, PCIE, SPI4, SDIO3, SPI2, PCIE), - - PIN(SPDI, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2), - PIN(SPDO, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2), - PIN(SPIA, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), - PIN(SPIB, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), - PIN(SPIC, AUDIO, SPI1, SPI2, SPI3, GMI, GMI), - PIN(SPID, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI), - PIN(SPIE, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI), - PIN(SPIF, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4), - - PIN(SPIG, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT), - PIN(SPIH, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT), - 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(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4), - PIN(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4), - - PIN_RESERVED, - PIN(ATE, NAND, IDE, NAND, GMI, RSVD, IDE), - PIN(KBCC, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC), - PIN_RESERVED, - PIN_RESERVED, - PIN(GMB, NAND, IDE, NAND, GMI, GMI_INT, GMI), - PIN(GMD, NAND, RSVD, NAND, GMI, SFLASH, GMI), - PIN(DDC, LCD, I2C2, RSVD, RSVD, RSVD, RSVD4), - - /* 64 */ - PINP(LD0, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD1, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD2, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD3, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD4, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD5, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD6, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD7, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - - PINP(LD8, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD9, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD10, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD11, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD12, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD13, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD14, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD15, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - - PINP(LD16, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LD17), - PINP(LD17, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD17), - PINP(LHP0, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD21_20), - PINP(LHP1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD19_18), - PINP(LHP2, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD19_18), - PINP(LVP0, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LC), - PINP(LVP1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD21_20), - PINP(HDINT, LCD, HDMI, RSVD, RSVD, RSVD, HDMI , LC), - - PINP(LM0, LCD, DISPA, DISPB, SPI3, RSVD, RSVD4, LC), - PINP(LM1, LCD, DISPA, DISPB, RSVD, CRT, RSVD3, LC), - PINP(LVS, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), - PINP(LSC0, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), - PINP(LSC1, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), - PINP(LSCK, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), - PINP(LDC, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LS), - PINP(LCSN, LCD, DISPA, DISPB, SPI3, RSVD, RSVD4, LS), - - /* 96 */ - PINP(LSPI, LCD, DISPA, DISPB, XIO, HDMI, DISPA, LC), - PINP(LSDA, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), - PINP(LSDI, LCD, DISPA, DISPB, SPI3, RSVD, DISPA, LS), - PINP(LPW0, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), - PINP(LPW1, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LS), - PINP(LPW2, LCD, DISPA, DISPB, SPI3, HDMI, DISPA, LS), - PINP(LDI, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD23_22), - PINP(LHS, LCD, DISPA, DISPB, XIO, RSVD, RSVD4, LC), - - PINP(LPP, LCD, DISPA, DISPB, RSVD, RSVD, RSVD4, LD23_22), - PIN_RESERVED, - PIN(KBCD, SYS, KBC, NAND, SDIO2, MIO, KBC), - PIN(GPU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK), - PIN(DTF, VI, I2C3, RSVD, VI, RSVD, RSVD4), - PIN(UDA, BB, SPI1, RSVD, UARTD, ULPI, RSVD2), - PIN(CRTP, LCD, CRT, RSVD, RSVD, RSVD, RSVD), - PINP(SDB, SD, UARTA, PWM, SDIO3, SPI2, PWM, NONE), - - /* these pin groups only have pullup and pull down control */ - PINALL(CK32, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(DDRC, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(PMCA, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(PMCB, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(PMCC, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(PMCD, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(PMCE, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), - PINALL(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, MUXCTL_NONE, - PUCTL_NONE), -}; - -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_tri[TRISTATE_REG(pin)]; - u32 reg; - - reg = readl(tri); - if (enable) - reg |= TRISTATE_MASK(pin); - else - reg &= ~TRISTATE_MASK(pin); - 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; - enum pmux_pullid pull_id = tegra_soc_pingroups[pin].pull_id; - u32 *pull = &pmt->pmt_pull[PULL_REG(pull_id)]; - u32 mask_bit; - u32 reg; - mask_bit = PULL_SHIFT(pull_id); - - reg = readl(pull); - reg &= ~(0x3 << mask_bit); - reg |= pupd << mask_bit; - 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; - enum pmux_ctlid mux_id = tegra_soc_pingroups[pin].ctl_id; - u32 *muxctl = &pmt->pmt_ctl[MUXCTL_REG(mux_id)]; - u32 mask_bit; - int i, mux = -1; - u32 reg; - - assert(pmux_func_isvalid(func)); - - /* Handle special values */ - if (func >= PMUX_FUNC_RSVD1) { - mux = (func - PMUX_FUNC_RSVD1) & 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); - - mask_bit = MUXCTL_SHIFT(mux_id); - reg = readl(muxctl); - reg &= ~(0x3 << mask_bit); - reg |= mux << mask_bit; - writel(reg, muxctl); -} - -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); -} - -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/armv7/tegra20/pmu.c b/arch/arm/cpu/armv7/tegra20/pmu.c deleted file mode 100644 index 53505e9c50..0000000000 --- a/arch/arm/cpu/armv7/tegra20/pmu.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010,2011 NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#define VDD_CORE_NOMINAL_T25 0x17 /* 1.3v */ -#define VDD_CPU_NOMINAL_T25 0x10 /* 1.125v */ - -#define VDD_CORE_NOMINAL_T20 0x16 /* 1.275v */ -#define VDD_CPU_NOMINAL_T20 0x0f /* 1.1v */ - -#define VDD_RELATION 0x02 /* 50mv */ -#define VDD_TRANSITION_STEP 0x06 /* 150mv */ -#define VDD_TRANSITION_RATE 0x06 /* 3.52mv/us */ - -int pmu_set_nominal(void) -{ - int core, cpu, bus; - - /* by default, the table has been filled with T25 settings */ - switch (tegra_get_chip_type()) { - case TEGRA_SOC_T20: - core = VDD_CORE_NOMINAL_T20; - cpu = VDD_CPU_NOMINAL_T20; - break; - case TEGRA_SOC_T25: - core = VDD_CORE_NOMINAL_T25; - cpu = VDD_CPU_NOMINAL_T25; - break; - default: - debug("%s: Unknown chip type\n", __func__); - return -1; - } - - bus = tegra_i2c_get_dvc_bus_num(); - if (bus == -1) { - debug("%s: Cannot find DVC I2C bus\n", __func__); - return -1; - } - tps6586x_init(bus); - tps6586x_set_pwm_mode(TPS6586X_PWM_SM1); - return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP, - VDD_TRANSITION_RATE, VDD_RELATION); -} diff --git a/arch/arm/cpu/armv7/tegra20/sys_info.c b/arch/arm/cpu/armv7/tegra20/sys_info.c deleted file mode 100644 index 1a0bb561a7..0000000000 --- a/arch/arm/cpu/armv7/tegra20/sys_info.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * 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 - -#ifdef CONFIG_DISPLAY_CPUINFO -/* Print CPU information */ -int print_cpuinfo(void) -{ - puts("TEGRA20\n"); - - /* TBD: Add printf of major/minor rev info, stepping, etc. */ - return 0; -} -#endif /* CONFIG_DISPLAY_CPUINFO */ diff --git a/arch/arm/cpu/armv7/tegra20/timer.c b/arch/arm/cpu/armv7/tegra20/timer.c deleted file mode 100644 index 562e414012..0000000000 --- a/arch/arm/cpu/armv7/tegra20/timer.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * (C) Copyright 2008 - * Texas Instruments - * - * Richard Woodruff - * Syed Moahmmed Khasim - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* counter runs at 1MHz */ -#define TIMER_CLK 1000000 -#define TIMER_LOAD_VAL 0xffffffff - -/* timer without interrupts */ -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds */ -void __udelay(unsigned long usec) -{ - long tmo = usec * (TIMER_CLK / 1000) / 1000; - unsigned long now, last = timer_get_us(); - - while (tmo > 0) { - now = timer_get_us(); - if (last > now) /* count up timer overflow */ - tmo -= TIMER_LOAD_VAL - last + now; - else - tmo -= now - last; - last = now; - } -} - -ulong get_timer_masked(void) -{ - ulong now; - - /* current tick value */ - now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ); - - if (now >= gd->lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolute diff ticks */ - gd->tbl += (now - gd->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; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} - -unsigned long timer_get_us(void) -{ - struct timerus *timer_base = (struct timerus *)NV_PA_TMRUS_BASE; - - return readl(&timer_base->cntr_1us); -} diff --git a/arch/arm/cpu/armv7/tegra20/warmboot.c b/arch/arm/cpu/armv7/tegra20/warmboot.c deleted file mode 100644 index 809ea0133e..0000000000 --- a/arch/arm/cpu/armv7/tegra20/warmboot.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * (C) Copyright 2010 - 2011 - * NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_TEGRA_CLOCK_SCALING -#error "You must enable CONFIG_TEGRA_CLOCK_SCALING to use CONFIG_TEGRA20_LP0" -#endif - -/* - * 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) - -/* TODO: If we later add support for the Misc GP controller, refactor this */ -union xm2cfga_reg { - struct { - u32 reserved0:2; - u32 hsm_en:1; - u32 reserved1:2; - u32 preemp_en:1; - u32 vref_en:1; - u32 reserved2:5; - u32 cal_drvdn:5; - u32 reserved3:3; - u32 cal_drvup:5; - u32 reserved4:3; - u32 cal_drvdn_slwr:2; - u32 cal_drvup_slwf:2; - }; - u32 word; -}; - -union xm2cfgd_reg { - struct { - u32 reserved0:2; - u32 hsm_en:1; - u32 schmt_en:1; - u32 lpmd:2; - u32 vref_en:1; - u32 reserved1:5; - u32 cal_drvdn:5; - u32 reserved2:3; - u32 cal_drvup:5; - u32 reserved3:3; - u32 cal_drvdn_slwr:2; - u32 cal_drvup_slwf:2; - }; - u32 word; -}; - -/* - * TODO: This register is not documented in the TRM yet. We could move this - * into the EMC and give it a proper interface, but not while it is - * undocumented. - */ -union fbio_spare_reg { - struct { - u32 reserved:24; - u32 cfg_wb0:8; - }; - u32 word; -}; - -/* We pack the resume information into these unions for later */ -union scratch2_reg { - struct { - u32 pllm_base_divm:5; - u32 pllm_base_divn:10; - u32 pllm_base_divp:3; - u32 pllm_misc_lfcon:4; - u32 pllm_misc_cpcon:4; - u32 gp_xm2cfga_padctrl_preemp:1; - u32 gp_xm2cfgd_padctrl_schmt:1; - u32 osc_ctrl_xobp:1; - u32 memory_type:3; - }; - u32 word; -}; - -union scratch4_reg { - struct { - u32 emc_clock_divider:8; - u32 pllm_stable_time:8; - u32 pllx_stable_time:8; - u32 emc_fbio_spare_cfg_wb0:8; - }; - u32 word; -}; - -union scratch24_reg { - struct { - u32 emc_auto_cal_wait:8; - u32 emc_pin_program_wait:8; - u32 warmboot_wait:8; - u32 reserved:8; - }; - u32 word; -}; - -int warmboot_save_sdram_params(void) -{ - u32 ram_code; - struct sdram_params sdram; - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)TEGRA20_APB_MISC_GP_BASE; - struct emc_ctlr *emc = emc_get_controller(gd->fdt_blob); - union scratch2_reg scratch2; - union scratch4_reg scratch4; - union scratch24_reg scratch24; - union xm2cfga_reg xm2cfga; - union xm2cfgd_reg xm2cfgd; - union fbio_spare_reg fbio_spare; - - /* get ram code that is used as index to array sdram_params in BCT */ - ram_code = (readl(&pmt->pmt_strap_opt_a) >> - STRAP_OPT_A_RAM_CODE_SHIFT) & 3; - memcpy(&sdram, - (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code), - sizeof(sdram)); - - xm2cfga.word = readl(&gp->xm2cfga); - xm2cfgd.word = readl(&gp->xm2cfgd); - - scratch2.word = 0; - scratch2.osc_ctrl_xobp = clock_get_osc_bypass(); - - /* Get the memory PLL settings */ - { - u32 divm, divn, divp, cpcon, lfcon; - - if (clock_ll_read_pll(CLOCK_ID_MEMORY, &divm, &divn, &divp, - &cpcon, &lfcon)) - return -1; - scratch2.pllm_base_divm = divm; - scratch2.pllm_base_divn = divn; - scratch2.pllm_base_divp = divp; - scratch2.pllm_misc_cpcon = cpcon; - scratch2.pllm_misc_lfcon = lfcon; - } - - scratch2.gp_xm2cfga_padctrl_preemp = xm2cfga.preemp_en; - scratch2.gp_xm2cfgd_padctrl_schmt = xm2cfgd.schmt_en; - scratch2.memory_type = sdram.memory_type; - writel(scratch2.word, &pmc->pmc_scratch2); - - /* collect data from various sources for pmc_scratch4 */ - fbio_spare.word = readl(&emc->fbio_spare); - scratch4.word = 0; - scratch4.emc_fbio_spare_cfg_wb0 = fbio_spare.cfg_wb0; - scratch4.emc_clock_divider = sdram.emc_clock_divider; - scratch4.pllm_stable_time = -1; - scratch4.pllx_stable_time = -1; - writel(scratch4.word, &pmc->pmc_scratch4); - - /* collect various data from sdram for pmc_scratch24 */ - scratch24.word = 0; - scratch24.emc_pin_program_wait = sdram.emc_pin_program_wait; - scratch24.emc_auto_cal_wait = sdram.emc_auto_cal_wait; - scratch24.warmboot_wait = sdram.warm_boot_wait; - writel(scratch24.word, &pmc->pmc_scratch24); - - return 0; -} - -static u32 get_major_version(void) -{ - u32 major_id; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)TEGRA20_APB_MISC_GP_BASE; - - major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >> - HIDREV_MAJORPREV_SHIFT; - return major_id; -} - -static int is_production_mode_fuse_set(struct fuse_regs *fuse) -{ - return readl(&fuse->production_mode); -} - -static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse) -{ - return readl(&fuse->security_mode); -} - -static int is_failure_analysis_mode(struct fuse_regs *fuse) -{ - return readl(&fuse->fa); -} - -static int ap20_is_odm_production_mode(void) -{ - struct fuse_regs *fuse = (struct fuse_regs *)TEGRA20_FUSE_BASE; - - if (!is_failure_analysis_mode(fuse) && - is_odm_production_mode_fuse_set(fuse)) - return 1; - else - return 0; -} - -static int ap20_is_production_mode(void) -{ - struct fuse_regs *fuse = (struct fuse_regs *)TEGRA20_FUSE_BASE; - - if (get_major_version() == 0) - return 1; - - if (!is_failure_analysis_mode(fuse) && - is_production_mode_fuse_set(fuse) && - !is_odm_production_mode_fuse_set(fuse)) - return 1; - else - return 0; -} - -static enum fuse_operating_mode fuse_get_operation_mode(void) -{ - u32 chip_id; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)TEGRA20_APB_MISC_GP_BASE; - - chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> - HIDREV_CHIPID_SHIFT; - if (chip_id == CHIPID_TEGRA20) { - if (ap20_is_odm_production_mode()) { - printf("!! odm_production_mode is not supported !!\n"); - return MODE_UNDEFINED; - } else - if (ap20_is_production_mode()) - return MODE_PRODUCTION; - else - return MODE_UNDEFINED; - } - return MODE_UNDEFINED; -} - -static void determine_crypto_options(int *is_encrypted, int *is_signed, - int *use_zero_key) -{ - switch (fuse_get_operation_mode()) { - case MODE_PRODUCTION: - *is_encrypted = 0; - *is_signed = 1; - *use_zero_key = 1; - break; - case MODE_UNDEFINED: - default: - *is_encrypted = 0; - *is_signed = 0; - *use_zero_key = 0; - break; - } -} - -static int sign_wb_code(u32 start, u32 length, int use_zero_key) -{ - int err; - u8 *source; /* Pointer to source */ - u8 *hash; - - /* Calculate AES block parameters. */ - source = (u8 *)(start + offsetof(struct wb_header, random_aes_block)); - length -= offsetof(struct wb_header, random_aes_block); - hash = (u8 *)(start + offsetof(struct wb_header, hash)); - err = sign_data_block(source, length, hash); - - return err; -} - -int warmboot_prepare_code(u32 seg_address, u32 seg_length) -{ - int err = 0; - u32 length; /* length of the signed/encrypt code */ - struct wb_header *dst_header; /* Pointer to dest WB header */ - int is_encrypted; /* Segment is encrypted */ - int is_signed; /* Segment is signed */ - int use_zero_key; /* Use key of all zeros */ - - /* Determine crypto options. */ - determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key); - - /* Get the actual code limits. */ - length = roundup(((u32)wb_end - (u32)wb_start), 16); - - /* - * The region specified by seg_address must be in SDRAM and must be - * nonzero in length. - */ - if (seg_length == 0 || seg_address < NV_PA_SDRAM_BASE || - seg_address + seg_length >= NV_PA_SDRAM_BASE + gd->ram_size) { - err = -EFAULT; - goto fail; - } - - /* Things must be 16-byte aligned. */ - if ((seg_length & 0xF) || (seg_address & 0xF)) { - err = -EINVAL; - goto fail; - } - - /* Will the code fit? (destination includes wb_header + wb code) */ - if (seg_length < (length + sizeof(struct wb_header))) { - err = -EINVAL; - goto fail; - } - - dst_header = (struct wb_header *)seg_address; - memset((char *)dst_header, 0, sizeof(struct wb_header)); - - /* Populate the random_aes_block as requested. */ - { - u32 *aes_block = (u32 *)&(dst_header->random_aes_block); - u32 *end = (u32 *)(((u32)aes_block) + - sizeof(dst_header->random_aes_block)); - - do { - *aes_block++ = 0; - } while (aes_block < end); - } - - /* Populate the header. */ - dst_header->length_insecure = length + sizeof(struct wb_header); - dst_header->length_secure = length + sizeof(struct wb_header); - dst_header->destination = AP20_WB_RUN_ADDRESS; - dst_header->entry_point = AP20_WB_RUN_ADDRESS; - dst_header->code_length = length; - - if (is_encrypted) { - printf("!!!! Encryption is not supported !!!!\n"); - dst_header->length_insecure = 0; - err = -EACCES; - goto fail; - } else - /* copy the wb code directly following dst_header. */ - memcpy((char *)(dst_header+1), (char *)wb_start, length); - - if (is_signed) - err = sign_wb_code(seg_address, dst_header->length_insecure, - use_zero_key); - -fail: - if (err) - printf("Warning: warmboot code copy failed (error=%d)\n", err); - - return err; -} diff --git a/arch/arm/cpu/armv7/tegra20/warmboot_avp.c b/arch/arm/cpu/armv7/tegra20/warmboot_avp.c deleted file mode 100644 index cd01908a46..0000000000 --- a/arch/arm/cpu/armv7/tegra20/warmboot_avp.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * (C) Copyright 2010 - 2011 - * NVIDIA Corporation - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "warmboot_avp.h" - -#define DEBUG_RESET_CORESIGHT - -void wb_start(void) -{ - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE; - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - union osc_ctrl_reg osc_ctrl; - union pllx_base_reg pllx_base; - union pllx_misc_reg pllx_misc; - union scratch3_reg scratch3; - u32 reg; - - /* enable JTAG & TBE */ - writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &pmt->pmt_cfg_ctl); - - /* Are we running where we're supposed to be? */ - asm volatile ( - "adr %0, wb_start;" /* reg: wb_start address */ - : "=r"(reg) /* output */ - /* no input, no clobber list */ - ); - - if (reg != AP20_WB_RUN_ADDRESS) - goto do_reset; - - /* Are we running with AVP? */ - if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP) - goto do_reset; - -#ifdef DEBUG_RESET_CORESIGHT - /* Assert CoreSight reset */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); - reg |= SWR_CSITE_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); -#endif - - /* TODO: Set the drive strength - maybe make this a board parameter? */ - osc_ctrl.word = readl(&clkrst->crc_osc_ctrl); - osc_ctrl.xofs = 4; - osc_ctrl.xoe = 1; - writel(osc_ctrl.word, &clkrst->crc_osc_ctrl); - - /* Power up the CPU complex if necessary */ - if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) { - reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START; - writel(reg, &pmc->pmc_pwrgate_toggle); - while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) - ; - } - - /* Remove the I/O clamps from the CPU power partition. */ - reg = readl(&pmc->pmc_remove_clamping); - reg |= CPU_CLMP; - writel(reg, &pmc->pmc_remove_clamping); - - reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP; - writel(reg, &flow->halt_cop_events); - - /* Assert CPU complex reset */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); - reg |= CPU_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - - /* Hold both CPUs in reset */ - reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 | - CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1; - writel(reg, &clkrst->crc_cpu_cmplx_set); - - /* Halt CPU1 at the flow controller for uni-processor configurations */ - writel(EVENT_MODE_STOP, &flow->halt_cpu1_events); - - /* - * Set the CPU reset vector. SCRATCH41 contains the physical - * address of the CPU-side restoration code. - */ - reg = readl(&pmc->pmc_scratch41); - writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Select CPU complex clock source */ - writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - - /* Start the CPU0 clock and stop the CPU1 clock */ - reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN | - CPU_CMPLX_CPU1_CLK_STP_STOP; - writel(reg, &clkrst->crc_clk_cpu_cmplx); - - /* Enable the CPU complex clock */ - reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]); - reg |= CLK_ENB_CPU; - writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]); - - /* Make sure the resets were held for at least 2 microseconds */ - reg = readl(TIMER_USEC_CNTR); - while (readl(TIMER_USEC_CNTR) <= (reg + 2)) - ; - -#ifdef DEBUG_RESET_CORESIGHT - /* - * De-assert CoreSight reset. - * NOTE: We're leaving the CoreSight clock on the oscillator for - * now. It will be restored to its original clock source - * when the CPU-side restoration code runs. - */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); - reg &= ~SWR_CSITE_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); -#endif - - /* Unlock the CPU CoreSight interfaces */ - reg = 0xC5ACCE55; - writel(reg, CSITE_CPU_DBG0_LAR); - writel(reg, CSITE_CPU_DBG1_LAR); - - /* - * Sample the microsecond timestamp again. This is the time we must - * use when returning from LP0 for PLL stabilization delays. - */ - reg = readl(TIMER_USEC_CNTR); - writel(reg, &pmc->pmc_scratch1); - - pllx_base.word = 0; - pllx_misc.word = 0; - scratch3.word = readl(&pmc->pmc_scratch3); - - /* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */ - reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1; - - /* - * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and - * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz. - * - * reg is used to calculate the pllx freq, which is used to determine if - * to set dccon or not. - */ - if (reg > 26) - reg = 19; - - /* PLLX_BASE.PLLX_DIVM */ - if (scratch3.pllx_base_divm == reg) - reg = 0; - else - reg = 1; - - /* PLLX_BASE.PLLX_DIVN */ - pllx_base.divn = scratch3.pllx_base_divn; - reg = scratch3.pllx_base_divn << reg; - - /* PLLX_BASE.PLLX_DIVP */ - pllx_base.divp = scratch3.pllx_base_divp; - reg = reg >> scratch3.pllx_base_divp; - - pllx_base.bypass = 1; - - /* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */ - if (reg > 600) - pllx_misc.dccon = 1; - - /* PLLX_MISC_LFCON */ - pllx_misc.lfcon = scratch3.pllx_misc_lfcon; - - /* PLLX_MISC_CPCON */ - pllx_misc.cpcon = scratch3.pllx_misc_cpcon; - - writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc); - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - - pllx_base.enable = 1; - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - pllx_base.bypass = 0; - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - - writel(0, flow->halt_cpu_events); - - reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0; - writel(reg, &clkrst->crc_cpu_cmplx_clr); - - reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE | - PLLM_OUT1_RATIO_VAL_8; - writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out); - - reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 | - SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 | - SCLK_SYS_STATE_IDLE; - writel(reg, &clkrst->crc_sclk_brst_pol); - - /* avp_resume: no return after the write */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); - reg &= ~CPU_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - - /* avp_halt: */ -avp_halt: - reg = EVENT_MODE_STOP | EVENT_JTAG; - writel(reg, flow->halt_cop_events); - goto avp_halt; - -do_reset: - /* - * Execution comes here if something goes wrong. The chip is reset and - * a cold boot is performed. - */ - writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - goto do_reset; -} - -/* - * wb_end() is a dummy function, and must be directly following wb_start(), - * and is used to calculate the size of wb_start(). - */ -void wb_end(void) -{ -} diff --git a/arch/arm/cpu/armv7/tegra20/warmboot_avp.h b/arch/arm/cpu/armv7/tegra20/warmboot_avp.h deleted file mode 100644 index 4b71c07843..0000000000 --- a/arch/arm/cpu/armv7/tegra20/warmboot_avp.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * (C) Copyright 2010, 2011 - * NVIDIA Corporation - * - * 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 _WARMBOOT_AVP_H_ -#define _WARMBOOT_AVP_H_ - -#define TEGRA_DEV_L 0 -#define TEGRA_DEV_H 1 -#define TEGRA_DEV_U 2 - -#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) -#define SIMPLE_PLLE (CLOCK_ID_EPCI - CLOCK_ID_FIRST_SIMPLE) - -#define TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0) -#define TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4) - -#define USEC_CFG_DIVISOR_MASK 0xffff - -#define CONFIG_CTL_TBE (1 << 7) -#define CONFIG_CTL_JTAG (1 << 6) - -#define CPU_RST (1 << 0) -#define CLK_ENB_CPU (1 << 0) -#define SWR_TRIG_SYS_RST (1 << 2) -#define SWR_CSITE_RST (1 << 9) - -#define PWRGATE_STATUS_CPU (1 << 0) -#define PWRGATE_TOGGLE_PARTID_CPU (0 << 0) -#define PWRGATE_TOGGLE_START (1 << 8) - -#define CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 (3 << 0) -#define CPU_CMPLX_CPU0_CLK_STP_STOP (1 << 8) -#define CPU_CMPLX_CPU0_CLK_STP_RUN (0 << 8) -#define CPU_CMPLX_CPU1_CLK_STP_STOP (1 << 9) -#define CPU_CMPLX_CPU1_CLK_STP_RUN (0 << 9) - -#define CPU_CMPLX_CPURESET0 (1 << 0) -#define CPU_CMPLX_CPURESET1 (1 << 1) -#define CPU_CMPLX_DERESET0 (1 << 4) -#define CPU_CMPLX_DERESET1 (1 << 5) -#define CPU_CMPLX_DBGRESET0 (1 << 12) -#define CPU_CMPLX_DBGRESET1 (1 << 13) - -#define PLLM_OUT1_RSTN_RESET_DISABLE (1 << 0) -#define PLLM_OUT1_CLKEN_ENABLE (1 << 1) -#define PLLM_OUT1_RATIO_VAL_8 (8 << 8) - -#define SCLK_SYS_STATE_IDLE (1 << 28) -#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) - -#define EVENT_ZERO_VAL_20 (20 << 0) -#define EVENT_MSEC (1 << 24) -#define EVENT_JTAG (1 << 28) -#define EVENT_MODE_STOP (2 << 29) - -#define CCLK_PLLP_BURST_POLICY 0x20004444 - -#endif -- cgit v1.2.1