diff options
Diffstat (limited to 'arch/arm/cpu/tegra-common')
-rw-r--r-- | arch/arm/cpu/tegra-common/Makefile | 19 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/ap.c | 169 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/board.c | 159 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/cache.c | 46 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/clock.c | 669 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/lowlevel_init.S | 26 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/pinmux-common.c | 527 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/powergate.c | 102 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/sys_info.c | 31 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/vpr.c | 35 | ||||
-rw-r--r-- | arch/arm/cpu/tegra-common/xusb-padctl.c | 39 |
11 files changed, 0 insertions, 1822 deletions
diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile deleted file mode 100644 index a78869e..0000000 --- a/arch/arm/cpu/tegra-common/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += ap.o -obj-y += board.o -obj-y += cache.o -obj-y += clock.o -obj-y += lowlevel_init.o -obj-y += pinmux-common.o -obj-y += powergate.o -obj-y += xusb-padctl.o -obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o -obj-$(CONFIG_TEGRA124) += vpr.o diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c deleted file mode 100644 index a17dfd1..0000000 --- a/arch/arm/cpu/tegra-common/ap.c +++ /dev/null @@ -1,169 +0,0 @@ -/* -* (C) Copyright 2010-2014 -* NVIDIA Corporation <www.nvidia.com> -* - * SPDX-License-Identifier: GPL-2.0+ -*/ - -/* Tegra AP (Application Processor) code */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/gp_padctrl.h> -#include <asm/arch-tegra/ap.h> -#include <asm/arch-tegra/clock.h> -#include <asm/arch-tegra/fuse.h> -#include <asm/arch-tegra/pmc.h> -#include <asm/arch-tegra/scu.h> -#include <asm/arch-tegra/tegra.h> -#include <asm/arch-tegra/warmboot.h> - -int tegra_get_chip(void) -{ - int rev; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - - /* - * This is undocumented, Chip ID is bits 15:8 of the register - * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for - * Tegra30, 0x35 for T114, and 0x40 for Tegra124. - */ - rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; - debug("%s: CHIPID is 0x%02X\n", __func__, rev); - - return rev; -} - -int tegra_get_sku_info(void) -{ - int sku_id; - struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; - - sku_id = readl(&fuse->sku_info) & 0xff; - debug("%s: SKU info byte is 0x%02X\n", __func__, sku_id); - - return sku_id; -} - -int tegra_get_chip_sku(void) -{ - uint sku_id, chip_id; - - chip_id = tegra_get_chip(); - sku_id = tegra_get_sku_info(); - - switch (chip_id) { - case CHIPID_TEGRA20: - switch (sku_id) { - case SKU_ID_T20_7: - 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; - case CHIPID_TEGRA30: - switch (sku_id) { - case SKU_ID_T33: - case SKU_ID_T30: - case SKU_ID_TM30MQS_P_A3: - default: - return TEGRA_SOC_T30; - } - break; - case CHIPID_TEGRA114: - switch (sku_id) { - case SKU_ID_T114_ENG: - case SKU_ID_T114_1: - default: - return TEGRA_SOC_T114; - } - break; - case CHIPID_TEGRA124: - switch (sku_id) { - case SKU_ID_T124_ENG: - default: - return TEGRA_SOC_T124; - } - break; - } - - /* unknown chip/sku id */ - printf("%s: ERROR: UNKNOWN CHIP/SKU ID COMBO (0x%02X/0x%02X)\n", - __func__, chip_id, sku_id); - return TEGRA_SOC_UNKNOWN; -} - -static void enable_scu(void) -{ - struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; - u32 reg; - - /* Only enable the SCU on T20/T25 */ - if (tegra_get_chip() != CHIPID_TEGRA20) - return; - - /* 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 BCTs for currently supported SoCs, which are locked down. - * If this changes in new chips, we can revisit this algorithm. - */ - - u32 bct_start, odmdata; - - bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); - odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); - - return odmdata; -} - -static void init_pmc_scratch(void) -{ - struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_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); -} - -void s_init(void) -{ - /* Init PMC scratch memory */ - init_pmc_scratch(); - - enable_scu(); - - /* init the cache */ - config_cache(); - - /* init vpr */ - config_vpr(); -} diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c deleted file mode 100644 index b6a84a5..0000000 --- a/arch/arm/cpu/tegra-common/board.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * (C) Copyright 2010-2014 - * NVIDIA Corporation <www.nvidia.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/funcmux.h> -#include <asm/arch/mc.h> -#include <asm/arch/tegra.h> -#include <asm/arch-tegra/board.h> -#include <asm/arch-tegra/pmc.h> -#include <asm/arch-tegra/sys_proto.h> -#include <asm/arch-tegra/warmboot.h> - -DECLARE_GLOBAL_DATA_PTR; - -enum { - /* UARTs which we can enable */ - UARTA = 1 << 0, - UARTB = 1 << 1, - UARTC = 1 << 2, - UARTD = 1 << 3, - UARTE = 1 << 4, - UART_COUNT = 5, -}; - -/* Read the RAM size directly from the memory controller */ -unsigned int query_sdram_size(void) -{ - struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; - u32 size_mb; - - size_mb = readl(&mc->mc_emem_cfg); -#if defined(CONFIG_TEGRA20) - debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", size_mb); - size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024); -#else - debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", size_mb); - size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024 * 1024); -#endif - -#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) - /* External memory limited to 2047 MB due to IROM/HI-VEC */ - if (size_mb == SZ_2G) size_mb -= SZ_1M; -#endif - - return size_mb; -} - -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 */ - -static int uart_configs[] = { -#if defined(CONFIG_TEGRA20) - #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) - FUNCMUX_UART1_UAA_UAB, - #elif defined(CONFIG_TEGRA_UARTA_GPU) - FUNCMUX_UART1_GPU, - #elif defined(CONFIG_TEGRA_UARTA_SDIO1) - FUNCMUX_UART1_SDIO1, - #else - FUNCMUX_UART1_IRRX_IRTX, -#endif - FUNCMUX_UART2_UAD, - -1, - FUNCMUX_UART4_GMC, - -1, -#elif defined(CONFIG_TEGRA30) - FUNCMUX_UART1_ULPI, /* UARTA */ - -1, - -1, - -1, - -1, -#elif defined(CONFIG_TEGRA114) - -1, - -1, - -1, - FUNCMUX_UART4_GMI, /* UARTD */ - -1, -#else /* Tegra124 */ - FUNCMUX_UART1_KBC, /* UARTA */ - -1, - -1, - FUNCMUX_UART4_GPIO, /* UARTD */ - -1, -#endif -}; - -/** - * 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, - PERIPH_ID_UART5, - }; - 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_TEGRA_ENABLE_UARTA - uart_ids |= UARTA; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTB - uart_ids |= UARTB; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTC - uart_ids |= UARTC; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTD - uart_ids |= UARTD; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTE - uart_ids |= UARTE; -#endif - setup_uarts(uart_ids); -} - -#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/tegra-common/cache.c b/arch/arm/cpu/tegra-common/cache.c deleted file mode 100644 index 94f5bce..0000000 --- a/arch/arm/cpu/tegra-common/cache.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Tegra cache routines */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch-tegra/ap.h> -#include <asm/arch/gp_padctrl.h> - -void config_cache(void) -{ - u32 reg = 0; - - /* 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"); - - /* Currently, only Tegra114+ needs this L2 cache change to boot Linux */ - if (tegra_get_chip() < CHIPID_TEGRA114) - return; - - /* - * Systems with an architectural L2 cache must not use the PL310. - * Config L2CTLR here for a data RAM latency of 3 cycles. - */ - asm("mrc p15, 1, %0, c9, c0, 2" : : "r" (reg)); - reg &= ~7; - reg |= 2; - asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg)); -} diff --git a/arch/arm/cpu/tegra-common/clock.c b/arch/arm/cpu/tegra-common/clock.c deleted file mode 100644 index 11c7435..0000000 --- a/arch/arm/cpu/tegra-common/clock.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Tegra SoC common clock control functions */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/tegra.h> -#include <asm/arch-tegra/clk_rst.h> -#include <asm/arch-tegra/timer.h> -#include <div64.h> -#include <fdtdec.h> - -/* - * This is our record of the current clock rate of each clock. We don't - * fill all of these in since we are only really interested in clocks which - * we use as parents. - */ -static unsigned pll_rate[CLOCK_ID_COUNT]; - -/* - * The oscillator frequency is fixed to one of four set values. Based on this - * the other clocks are set up appropriately. - */ -static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { - 13000000, - 19200000, - 12000000, - 26000000, -}; - -/* return 1 if a peripheral ID is in range */ -#define clock_type_id_isvalid(id) ((id) >= 0 && \ - (id) < CLOCK_TYPE_COUNT) - -char pllp_valid = 1; /* PLLP is set up correctly */ - -/* return 1 if a periphc_internal_id is in range */ -#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ - (id) < PERIPHC_COUNT) - -/* number of clock outputs of a PLL */ -static const u8 pll_num_clkouts[] = { - 1, /* PLLC */ - 1, /* PLLM */ - 4, /* PLLP */ - 1, /* PLLA */ - 0, /* PLLU */ - 0, /* PLLD */ -}; - -int clock_get_osc_bypass(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; -} - -/* Returns a pointer to the registers of the given pll */ -static struct clk_pll *get_pll(enum clock_id clkid) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - - assert(clock_id_is_pll(clkid)); - return &clkrst->crc_pll[clkid]; -} - -int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, - u32 *divp, u32 *cpcon, u32 *lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - assert(clkid != CLOCK_ID_USB); - - /* Safety check, adds to code size but is small */ - if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) - return -1; - data = readl(&pll->pll_base); - *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; - *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - data = readl(&pll->pll_misc); - *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; - *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; - - return 0; -} - -unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, - u32 divp, u32 cpcon, u32 lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - /* - * We cheat by treating all PLL (except PLLU) in the same fashion. - * This works only because: - * - same fields are always mapped at same offsets, except DCCON - * - DCCON is always 0, doesn't conflict - * - M,N, P of PLLP values are ignored for PLLP - */ - data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); - writel(data, &pll->pll_misc); - - data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | - (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); - - if (clkid == CLOCK_ID_USB) - data |= divp << PLLU_VCO_FREQ_SHIFT; - else - data |= divp << PLL_DIVP_SHIFT; - writel(data, &pll->pll_base); - - /* calculate the stable time */ - return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; -} - -void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, - unsigned divisor) -{ - u32 *reg = get_periph_source_reg(periph_id); - u32 value; - - value = readl(reg); - - value &= ~OUT_CLK_SOURCE_31_30_MASK; - value |= source << OUT_CLK_SOURCE_31_30_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_31_30_MASK, - source << OUT_CLK_SOURCE_31_30_SHIFT); -} - -/** - * Given the parent's rate and the required rate for the children, this works - * out the peripheral clock divider to use, in 7.1 binary format. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @return divider which should be used - */ -static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate) -{ - u64 divider = parent_rate * 2; - unsigned max_divider = 1 << divider_bits; - - divider += rate - 1; - do_div(divider, rate); - - if ((s64)divider - 2 < 0) - return 0; - - if ((s64)divider - 2 >= max_divider) - return -1; - - return divider - 2; -} - -int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) -{ - struct clk_pll *pll = get_pll(clkid); - int data = 0, div = 0, offset = 0; - - if (!clock_id_is_pll(clkid)) - return -1; - - if (pllout + 1 > pll_num_clkouts[clkid]) - return -1; - - div = clk_get_divider(8, pll_rate[clkid], rate); - - if (div < 0) - return -1; - - /* out2 and out4 are in the high part of the register */ - if (pllout == PLL_OUT2 || pllout == PLL_OUT4) - offset = 16; - - data = (div << PLL_OUT_RATIO_SHIFT) | - PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; - clrsetbits_le32(&pll->pll_out[pllout >> 1], - PLL_OUT_RATIO_MASK << offset, data << offset); - - return 0; -} - -/** - * Given the parent's rate and the divider in 7.1 format, this works out the - * resulting peripheral clock rate. - * - * @param parent_rate clock rate of parent clock in Hz - * @param divider which should be used in 7.1 format - * @return effective clock rate of peripheral - */ -static unsigned long get_rate_from_divider(unsigned long parent_rate, - int divider) -{ - u64 rate; - - rate = (u64)parent_rate * 2; - do_div(rate, divider + 2); - return rate; -} - -unsigned long clock_get_periph_rate(enum periph_id periph_id, - enum clock_id parent) -{ - u32 *reg = get_periph_source_reg(periph_id); - - return get_rate_from_divider(pll_rate[parent], - (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); -} - -/** - * Find the best available 7.1 format divisor given a parent clock rate and - * required child clock rate. This function assumes that a second-stage - * divisor is available which can divide by powers of 2 from 1 to 256. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @param extra_div value for the second-stage divisor (not set if this - * function returns -1. - * @return divider which should be used, or -1 if nothing is valid - * - */ -static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate, int *extra_div) -{ - int shift; - int best_divider = -1; - int best_error = rate; - - /* try dividers from 1 to 256 and find closest match */ - for (shift = 0; shift <= 8 && best_error > 0; shift++) { - unsigned divided_parent = parent_rate >> shift; - int divider = clk_get_divider(divider_bits, divided_parent, - rate); - unsigned effective_rate = get_rate_from_divider(divided_parent, - divider); - int error = rate - effective_rate; - - /* Given a valid divider, look for the lowest error */ - if (divider != -1 && error < best_error) { - best_error = error; - *extra_div = 1 << shift; - best_divider = divider; - } - } - - /* return what we found - *extra_div will already be set */ - return best_divider; -} - -/** - * Adjust peripheral PLL to use the given divider and source. - * - * @param periph_id peripheral to adjust - * @param source Source number (0-3 or 0-7) - * @param mux_bits Number of mux bits (2 or 4) - * @param divider Required divider in 7.1 or 15.1 format - * @return 0 if ok, -1 on error (requesting a parent clock which is not valid - * for this peripheral) - */ -static int adjust_periph_pll(enum periph_id periph_id, int source, - int mux_bits, unsigned divider) -{ - u32 *reg = get_periph_source_reg(periph_id); - - clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, - divider << OUT_CLK_DIVISOR_SHIFT); - udelay(1); - - /* work out the source clock and set it */ - if (source < 0) - return -1; - - switch (mux_bits) { - case MASK_BITS_31_30: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_30_MASK, - source << OUT_CLK_SOURCE_31_30_SHIFT); - break; - - case MASK_BITS_31_29: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_29_MASK, - source << OUT_CLK_SOURCE_31_29_SHIFT); - break; - - case MASK_BITS_31_28: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_28_MASK, - source << OUT_CLK_SOURCE_31_28_SHIFT); - break; - - default: - return -1; - } - - 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; - int xdiv = 0; - - /* work out the source clock and set it */ - source = get_periph_clock_source(periph_id, parent, &mux_bits, - ÷r_bits); - - divider = find_best_divider(divider_bits, pll_rate[parent], - rate, &xdiv); - if (extra_div) - *extra_div = xdiv; - - assert(divider >= 0); - if (adjust_periph_pll(periph_id, source, mux_bits, divider)) - return -1U; - debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, - get_periph_source_reg(periph_id), - readl(get_periph_source_reg(periph_id))); - - /* Check what we ended up with. This shouldn't matter though */ - effective_rate = clock_get_periph_rate(periph_id, parent); - if (extra_div) - effective_rate /= *extra_div; - if (rate != effective_rate) - debug("Requested clock rate %u not honored (got %u)\n", - rate, effective_rate); - return effective_rate; -} - -unsigned clock_start_periph_pll(enum periph_id periph_id, - enum clock_id parent, unsigned rate) -{ - unsigned effective_rate; - - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - - effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, - NULL); - - reset_set_enable(periph_id, 0); - return effective_rate; -} - -void clock_enable(enum periph_id clkid) -{ - clock_set_enable(clkid, 1); -} - -void clock_disable(enum periph_id clkid) -{ - clock_set_enable(clkid, 0); -} - -void reset_periph(enum periph_id periph_id, int us_delay) -{ - /* Put peripheral into reset */ - reset_set_enable(periph_id, 1); - udelay(us_delay); - - /* Remove reset */ - reset_set_enable(periph_id, 0); - - udelay(us_delay); -} - -void reset_cmplx_set_enable(int cpu, int which, int reset) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 mask; - - /* Form the mask, which depends on the cpu chosen (2 or 4) */ - assert(cpu >= 0 && cpu < MAX_NUM_CPU); - mask = which << cpu; - - /* either enable or disable those reset for that CPU */ - if (reset) - writel(mask, &clkrst->crc_cpu_cmplx_set); - else - writel(mask, &clkrst->crc_cpu_cmplx_clr); -} - -unsigned clock_get_rate(enum clock_id clkid) -{ - struct clk_pll *pll; - u32 base; - u32 divm; - u64 parent_rate; - u64 rate; - - parent_rate = osc_freq[clock_get_osc_freq()]; - if (clkid == CLOCK_ID_OSC) - return parent_rate; - - pll = get_pll(clkid); - base = readl(&pll->pll_base); - - /* Oh for bf_unpack()... */ - rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); - divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - if (clkid == CLOCK_ID_USB) - divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; - else - divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - do_div(rate, divm); - return rate; -} - -/** - * Set the output frequency you want for each PLL clock. - * PLL output frequencies are programmed by setting their N, M and P values. - * The governing equations are: - * VCO = (Fi / m) * n, Fo = VCO / (2^p) - * where Fo is the output frequency from the PLL. - * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) - * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 - * Please see Tegra TRM section 5.3 to get the detail for PLL Programming - * - * @param n PLL feedback divider(DIVN) - * @param m PLL input divider(DIVN) - * @param p post divider(DIVP) - * @param cpcon base PLL charge pump(CPCON) - * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot - * be overriden), 1 if PLL is already correct - */ -int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) -{ - u32 base_reg; - u32 misc_reg; - struct clk_pll *pll; - - pll = get_pll(clkid); - - base_reg = readl(&pll->pll_base); - - /* Set BYPASS, m, n and p to PLL_BASE */ - base_reg &= ~PLL_DIVM_MASK; - base_reg |= m << PLL_DIVM_SHIFT; - - base_reg &= ~PLL_DIVN_MASK; - base_reg |= n << PLL_DIVN_SHIFT; - - base_reg &= ~PLL_DIVP_MASK; - base_reg |= p << PLL_DIVP_SHIFT; - - if (clkid == CLOCK_ID_PERIPH) { - /* - * If the PLL is already set up, check that it is correct - * and record this info for clock_verify() to check. - */ - if (base_reg & PLL_BASE_OVRRIDE_MASK) { - base_reg |= PLL_ENABLE_MASK; - if (base_reg != readl(&pll->pll_base)) - pllp_valid = 0; - return pllp_valid ? 1 : -1; - } - base_reg |= PLL_BASE_OVRRIDE_MASK; - } - - base_reg |= PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - /* Set cpcon to PLL_MISC */ - misc_reg = readl(&pll->pll_misc); - misc_reg &= ~PLL_CPCON_MASK; - misc_reg |= cpcon << PLL_CPCON_SHIFT; - writel(misc_reg, &pll->pll_misc); - - /* Enable PLL */ - base_reg |= PLL_ENABLE_MASK; - writel(base_reg, &pll->pll_base); - - /* Disable BYPASS */ - base_reg &= ~PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - return 0; -} - -void clock_ll_start_uart(enum periph_id periph_id) -{ - /* Assert UART reset and enable clock */ - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ - - /* wait for 2us */ - udelay(2); - - /* De-assert reset to UART */ - reset_set_enable(periph_id, 0); -} - -#ifdef CONFIG_OF_CONTROL -int clock_decode_periph_id(const void *blob, int node) -{ - enum periph_id id; - u32 cell[2]; - int err; - - err = fdtdec_get_int_array(blob, node, "clocks", cell, - ARRAY_SIZE(cell)); - if (err) - return -1; - id = clk_id_to_periph_id(cell[1]); - assert(clock_periph_id_isvalid(id)); - return id; -} -#endif /* CONFIG_OF_CONTROL */ - -int clock_verify(void) -{ - struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); - u32 reg = readl(&pll->pll_base); - - if (!pllp_valid) { - printf("Warning: PLLP %x is not correct\n", reg); - return -1; - } - debug("PLLP %x is correct\n", reg); - return 0; -} - -void clock_init(void) -{ - pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); - pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); - pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); - pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); - pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; - pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU); - debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); - debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); - debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); - debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]); - debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]); - - /* Do any special system timer/TSC setup */ - arch_timer_init(); -} - -static void set_avp_clock_source(u32 src) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 val; - - val = (src << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | - (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); - writel(val, &clkrst->crc_sclk_brst_pol); - udelay(3); -} - -/* - * This function is useful on Tegra30, and any later SoCs that have compatible - * PLLP configuration registers. - */ -void tegra30_set_up_pllp(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - /* - * Based on the Tegra TRM, the system clock (which is the AVP clock) can - * run up to 275MHz. On power on, the default sytem clock source is set - * to PLLP_OUT0. This function sets PLLP's (hence PLLP_OUT0's) rate to - * 408MHz which is beyond system clock's upper limit. - * - * The fix is to set the system clock to CLK_M before initializing PLLP, - * and then switch back to PLLP_OUT4, which has an appropriate divider - * configured, after PLLP has been configured - */ - set_avp_clock_source(SCLK_SOURCE_CLKM); - - /* - * PLLP output frequency set to 408Mhz - * PLLC output frequency set to 228Mhz - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); - break; - - case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); - break; - case CLOCK_OSC_FREQ_19_2: - default: - /* - * These are not supported. It is too early to print a - * message and the UART likely won't work anyway due to the - * oscillator being wrong. - */ - break; - } - - /* Set PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ - - /* OUT1, 2 */ - /* Assert RSTN before enable */ - reg = PLLP_OUT2_RSTN_EN | PLLP_OUT1_RSTN_EN; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); - /* Set divisor and reenable */ - reg = (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) - | PLLP_OUT2_OVR | PLLP_OUT2_CLKEN | PLLP_OUT2_RSTN_DIS - | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) - | PLLP_OUT1_OVR | PLLP_OUT1_CLKEN | PLLP_OUT1_RSTN_DIS; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); - - /* OUT3, 4 */ - /* Assert RSTN before enable */ - reg = PLLP_OUT4_RSTN_EN | PLLP_OUT3_RSTN_EN; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); - /* Set divisor and reenable */ - reg = (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) - | PLLP_OUT4_OVR | PLLP_OUT4_CLKEN | PLLP_OUT4_RSTN_DIS - | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) - | PLLP_OUT3_OVR | PLLP_OUT3_CLKEN | PLLP_OUT3_RSTN_DIS; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); - - set_avp_clock_source(SCLK_SOURCE_PLLP_OUT4); -} diff --git a/arch/arm/cpu/tegra-common/lowlevel_init.S b/arch/arm/cpu/tegra-common/lowlevel_init.S deleted file mode 100644 index a211bb3..0000000 --- a/arch/arm/cpu/tegra-common/lowlevel_init.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SoC-specific setup info - * - * (C) Copyright 2010,2011 - * NVIDIA Corporation <www.nvidia.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <version.h> -#include <linux/linkage.h> - - .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/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c deleted file mode 100644 index 6e3ab0c..0000000 --- a/arch/arm/cpu/tegra-common/pinmux-common.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/pinmux.h> - -/* return 1 if a pingrp is in range */ -#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT)) - -/* return 1 if a pmux_func is in range */ -#define pmux_func_isvalid(func) \ - (((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) - -/* return 1 if a pin_pupd_is in range */ -#define pmux_pin_pupd_isvalid(pupd) \ - (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP)) - -/* return 1 if a pin_tristate_is in range */ -#define pmux_pin_tristate_isvalid(tristate) \ - (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE)) - -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC -/* return 1 if a pin_io_is in range */ -#define pmux_pin_io_isvalid(io) \ - (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT)) - -/* return 1 if a pin_lock is in range */ -#define pmux_pin_lock_isvalid(lock) \ - (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE)) - -/* return 1 if a pin_od is in range */ -#define pmux_pin_od_isvalid(od) \ - (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE)) - -/* return 1 if a pin_ioreset_is in range */ -#define pmux_pin_ioreset_isvalid(ioreset) \ - (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \ - ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) - -#ifdef TEGRA_PMX_HAS_RCV_SEL -/* return 1 if a pin_rcv_sel_is in range */ -#define pmux_pin_rcv_sel_isvalid(rcv_sel) \ - (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \ - ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH)) -#endif /* TEGRA_PMX_HAS_RCV_SEL */ -#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ - -#define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset)) - -#if defined(CONFIG_TEGRA20) - -#define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4)) -#define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2) - -#define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4)) -#define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2) - -#define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4)) -#define TRI_SHIFT(grp) ((grp) % 32) - -#else - -#define REG(pin) _R(0x3000 + ((pin) * 4)) - -#define MUX_REG(pin) REG(pin) -#define MUX_SHIFT(pin) 0 - -#define PULL_REG(pin) REG(pin) -#define PULL_SHIFT(pin) 2 - -#define TRI_REG(pin) REG(pin) -#define TRI_SHIFT(pin) 4 - -#endif /* CONFIG_TEGRA20 */ - -#define DRV_REG(group) _R(0x868 + ((group) * 4)) - -#define IO_SHIFT 5 -#define OD_SHIFT 6 -#define LOCK_SHIFT 7 -#define IO_RESET_SHIFT 8 -#define RCV_SEL_SHIFT 9 - -#if !defined(CONFIG_TEGRA20) && !defined(CONFIG_TEGRA30) -/* This register/field only exists on Tegra114 and later */ -#define APB_MISC_PP_PINMUX_GLOBAL_0 0x40 -#define CLAMP_INPUTS_WHEN_TRISTATED 1 - -void pinmux_set_tristate_input_clamping(void) -{ - u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); - u32 val; - - val = readl(reg); - val |= CLAMP_INPUTS_WHEN_TRISTATED; - writel(val, reg); -} -#endif - -void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) -{ - u32 *reg = MUX_REG(pin); - int i, mux = -1; - u32 val; - - if (func == PMUX_FUNC_DEFAULT) - return; - - /* Error check on pin and func */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_func_isvalid(func)); - - if (func >= PMUX_FUNC_RSVD1) { - mux = (func - PMUX_FUNC_RSVD1) & 3; - } 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); - - val = readl(reg); - val &= ~(3 << MUX_SHIFT(pin)); - val |= (mux << MUX_SHIFT(pin)); - writel(val, reg); -} - -void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) -{ - u32 *reg = PULL_REG(pin); - u32 val; - - /* Error check on pin and pupd */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_pupd_isvalid(pupd)); - - val = readl(reg); - val &= ~(3 << PULL_SHIFT(pin)); - val |= (pupd << PULL_SHIFT(pin)); - writel(val, reg); -} - -static void pinmux_set_tristate(enum pmux_pingrp pin, int tri) -{ - u32 *reg = TRI_REG(pin); - u32 val; - - /* Error check on pin */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_tristate_isvalid(tri)); - - val = readl(reg); - if (tri == PMUX_TRI_TRISTATE) - val |= (1 << TRI_SHIFT(pin)); - else - val &= ~(1 << TRI_SHIFT(pin)); - writel(val, reg); -} - -void pinmux_tristate_enable(enum pmux_pingrp pin) -{ - pinmux_set_tristate(pin, PMUX_TRI_TRISTATE); -} - -void pinmux_tristate_disable(enum pmux_pingrp pin) -{ - pinmux_set_tristate(pin, PMUX_TRI_NORMAL); -} - -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC -void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) -{ - u32 *reg = REG(pin); - u32 val; - - if (io == PMUX_PIN_NONE) - return; - - /* Error check on pin and io */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_io_isvalid(io)); - - val = readl(reg); - if (io == PMUX_PIN_INPUT) - val |= (io & 1) << IO_SHIFT; - else - val &= ~(1 << IO_SHIFT); - writel(val, reg); -} - -static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) -{ - u32 *reg = REG(pin); - u32 val; - - if (lock == PMUX_PIN_LOCK_DEFAULT) - return; - - /* Error check on pin and lock */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_lock_isvalid(lock)); - - val = readl(reg); - if (lock == PMUX_PIN_LOCK_ENABLE) { - val |= (1 << LOCK_SHIFT); - } else { - if (val & (1 << LOCK_SHIFT)) - printf("%s: Cannot clear LOCK bit!\n", __func__); - val &= ~(1 << LOCK_SHIFT); - } - writel(val, reg); - - return; -} - -static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) -{ - u32 *reg = REG(pin); - u32 val; - - if (od == PMUX_PIN_OD_DEFAULT) - return; - - /* Error check on pin and od */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_od_isvalid(od)); - - val = readl(reg); - if (od == PMUX_PIN_OD_ENABLE) - val |= (1 << OD_SHIFT); - else - val &= ~(1 << OD_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_ioreset(enum pmux_pingrp pin, - enum pmux_pin_ioreset ioreset) -{ - u32 *reg = REG(pin); - u32 val; - - if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) - return; - - /* Error check on pin and ioreset */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_ioreset_isvalid(ioreset)); - - val = readl(reg); - if (ioreset == PMUX_PIN_IO_RESET_ENABLE) - val |= (1 << IO_RESET_SHIFT); - else - val &= ~(1 << IO_RESET_SHIFT); - writel(val, reg); - - return; -} - -#ifdef TEGRA_PMX_HAS_RCV_SEL -static void pinmux_set_rcv_sel(enum pmux_pingrp pin, - enum pmux_pin_rcv_sel rcv_sel) -{ - u32 *reg = REG(pin); - u32 val; - - if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT) - return; - - /* Error check on pin and rcv_sel */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_rcv_sel_isvalid(rcv_sel)); - - val = readl(reg); - if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH) - val |= (1 << RCV_SEL_SHIFT); - else - val &= ~(1 << RCV_SEL_SHIFT); - writel(val, reg); - - return; -} -#endif /* TEGRA_PMX_HAS_RCV_SEL */ -#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ - -static void pinmux_config_pingrp(const struct pmux_pingrp_config *config) -{ - enum pmux_pingrp pin = config->pingrp; - - pinmux_set_func(pin, config->func); - pinmux_set_pullupdown(pin, config->pull); - pinmux_set_tristate(pin, config->tristate); -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC - pinmux_set_io(pin, config->io); - pinmux_set_lock(pin, config->lock); - pinmux_set_od(pin, config->od); - pinmux_set_ioreset(pin, config->ioreset); -#ifdef TEGRA_PMX_HAS_RCV_SEL - pinmux_set_rcv_sel(pin, config->rcv_sel); -#endif -#endif -} - -void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config, - int len) -{ - int i; - - for (i = 0; i < len; i++) - pinmux_config_pingrp(&config[i]); -} - -#ifdef TEGRA_PMX_HAS_DRVGRPS - -#define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT)) - -#define pmux_slw_isvalid(slw) \ - (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX)) - -#define pmux_drv_isvalid(drv) \ - (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX)) - -#define pmux_lpmd_isvalid(lpm) \ - (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X)) - -#define pmux_schmt_isvalid(schmt) \ - (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE)) - -#define pmux_hsm_isvalid(hsm) \ - (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE)) - -#define HSM_SHIFT 2 -#define SCHMT_SHIFT 3 -#define LPMD_SHIFT 4 -#define LPMD_MASK (3 << LPMD_SHIFT) -#define DRVDN_SHIFT 12 -#define DRVDN_MASK (0x7F << DRVDN_SHIFT) -#define DRVUP_SHIFT 20 -#define DRVUP_MASK (0x7F << DRVUP_SHIFT) -#define SLWR_SHIFT 28 -#define SLWR_MASK (3 << SLWR_SHIFT) -#define SLWF_SHIFT 30 -#define SLWF_MASK (3 << SLWF_SHIFT) - -static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (slwf == PMUX_SLWF_NONE) - return; - - /* Error check on pad and slwf */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_slw_isvalid(slwf)); - - val = readl(reg); - val &= ~SLWF_MASK; - val |= (slwf << SLWF_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (slwr == PMUX_SLWR_NONE) - return; - - /* Error check on pad and slwr */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_slw_isvalid(slwr)); - - val = readl(reg); - val &= ~SLWR_MASK; - val |= (slwr << SLWR_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (drvup == PMUX_DRVUP_NONE) - return; - - /* Error check on pad and drvup */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_drv_isvalid(drvup)); - - val = readl(reg); - val &= ~DRVUP_MASK; - val |= (drvup << DRVUP_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (drvdn == PMUX_DRVDN_NONE) - return; - - /* Error check on pad and drvdn */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_drv_isvalid(drvdn)); - - val = readl(reg); - val &= ~DRVDN_MASK; - val |= (drvdn << DRVDN_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (lpmd == PMUX_LPMD_NONE) - return; - - /* Error check pad and lpmd value */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_lpmd_isvalid(lpmd)); - - val = readl(reg); - val &= ~LPMD_MASK; - val |= (lpmd << LPMD_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (schmt == PMUX_SCHMT_NONE) - return; - - /* Error check pad */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_schmt_isvalid(schmt)); - - val = readl(reg); - if (schmt == PMUX_SCHMT_ENABLE) - val |= (1 << SCHMT_SHIFT); - else - val &= ~(1 << SCHMT_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (hsm == PMUX_HSM_NONE) - return; - - /* Error check pad */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_hsm_isvalid(hsm)); - - val = readl(reg); - if (hsm == PMUX_HSM_ENABLE) - val |= (1 << HSM_SHIFT); - else - val &= ~(1 << HSM_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config) -{ - enum pmux_drvgrp grp = config->drvgrp; - - pinmux_set_drvup_slwf(grp, config->slwf); - pinmux_set_drvdn_slwr(grp, config->slwr); - pinmux_set_drvup(grp, config->drvup); - pinmux_set_drvdn(grp, config->drvdn); - pinmux_set_lpmd(grp, config->lpmd); - pinmux_set_schmt(grp, config->schmt); - pinmux_set_hsm(grp, config->hsm); -} - -void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config, - int len) -{ - int i; - - for (i = 0; i < len; i++) - pinmux_config_drvgrp(&config[i]); -} -#endif /* TEGRA_PMX_HAS_DRVGRPS */ diff --git a/arch/arm/cpu/tegra-common/powergate.c b/arch/arm/cpu/tegra-common/powergate.c deleted file mode 100644 index 439cff3..0000000 --- a/arch/arm/cpu/tegra-common/powergate.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include <common.h> -#include <errno.h> - -#include <asm/io.h> -#include <asm/types.h> - -#include <asm/arch/powergate.h> -#include <asm/arch/tegra.h> - -#define PWRGATE_TOGGLE 0x30 -#define PWRGATE_TOGGLE_START (1 << 8) - -#define REMOVE_CLAMPING 0x34 - -#define PWRGATE_STATUS 0x38 - -static int tegra_powergate_set(enum tegra_powergate id, bool state) -{ - u32 value, mask = state ? (1 << id) : 0, old_mask; - unsigned long start, timeout = 25; - - value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); - old_mask = value & (1 << id); - - if (mask == old_mask) - return 0; - - writel(PWRGATE_TOGGLE_START | id, NV_PA_PMC_BASE + PWRGATE_TOGGLE); - - start = get_timer(0); - - while (get_timer(start) < timeout) { - value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); - if ((value & (1 << id)) == mask) - return 0; - } - - return -ETIMEDOUT; -} - -static int tegra_powergate_power_on(enum tegra_powergate id) -{ - return tegra_powergate_set(id, true); -} - -int tegra_powergate_power_off(enum tegra_powergate id) -{ - return tegra_powergate_set(id, false); -} - -static int tegra_powergate_remove_clamping(enum tegra_powergate id) -{ - unsigned long value; - - /* - * The REMOVE_CLAMPING register has the bits for the PCIE and VDEC - * partitions reversed. This was originally introduced on Tegra20 but - * has since been carried forward for backwards-compatibility. - */ - if (id == TEGRA_POWERGATE_VDEC) - value = 1 << TEGRA_POWERGATE_PCIE; - else if (id == TEGRA_POWERGATE_PCIE) - value = 1 << TEGRA_POWERGATE_VDEC; - else - value = 1 << id; - - writel(value, NV_PA_PMC_BASE + REMOVE_CLAMPING); - - return 0; -} - -int tegra_powergate_sequence_power_up(enum tegra_powergate id, - enum periph_id periph) -{ - int err; - - reset_set_enable(periph, 1); - - err = tegra_powergate_power_on(id); - if (err < 0) - return err; - - clock_enable(periph); - - udelay(10); - - err = tegra_powergate_remove_clamping(id); - if (err < 0) - return err; - - udelay(10); - - reset_set_enable(periph, 0); - - return 0; -} diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c deleted file mode 100644 index 5933c35..0000000 --- a/arch/arm/cpu/tegra-common/sys_info.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * NVIDIA Corporation <www.nvidia.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/ctype.h> - -static void upstring(char *s) -{ - while (*s) { - *s = toupper(*s); - s++; - } -} - -/* Print CPU information */ -int print_cpuinfo(void) -{ - char soc_name[10]; - - strncpy(soc_name, CONFIG_SYS_SOC, 10); - upstring(soc_name); - puts(soc_name); - puts("\n"); - - /* TBD: Add printf of major/minor rev info, stepping, etc. */ - return 0; -} diff --git a/arch/arm/cpu/tegra-common/vpr.c b/arch/arm/cpu/tegra-common/vpr.c deleted file mode 100644 index f695811..0000000 --- a/arch/arm/cpu/tegra-common/vpr.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* Tegra vpr routines */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/tegra.h> -#include <asm/arch/mc.h> - -/* Configures VPR. Right now, all we do is turn it off. */ -void config_vpr(void) -{ - struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; - - /* Turn VPR off */ - writel(0, &mc->mc_video_protect_size_mb); - writel(TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED, - &mc->mc_video_protect_reg_ctrl); - /* read back to ensure the write went through */ - readl(&mc->mc_video_protect_reg_ctrl); -} diff --git a/arch/arm/cpu/tegra-common/xusb-padctl.c b/arch/arm/cpu/tegra-common/xusb-padctl.c deleted file mode 100644 index 65f8d2e..0000000 --- a/arch/arm/cpu/tegra-common/xusb-padctl.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include <common.h> -#include <errno.h> - -#include <asm/arch-tegra/xusb-padctl.h> - -struct tegra_xusb_phy * __weak tegra_xusb_phy_get(unsigned int type) -{ - return NULL; -} - -int __weak tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -void __weak tegra_xusb_padctl_init(const void *fdt) -{ -} |