diff options
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/Kconfig | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/ap.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cache.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpu.c | 55 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpu.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/lowlevel_init.S | 15 |
9 files changed, 125 insertions, 25 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 7533e57..ba0b865 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -34,6 +34,17 @@ config TEGRA124 bool "Tegra124 family" select TEGRA_ARMV7_COMMON +config TEGRA210 + bool "Tegra210 family" + select OF_CONTROL + select ARM64 + select DM + select DM_SPI_FLASH + select DM_SERIAL + select DM_I2C + select DM_SPI + select DM_GPIO + endchoice config SYS_MALLOC_F_LEN @@ -43,5 +54,6 @@ source "arch/arm/mach-tegra/tegra20/Kconfig" source "arch/arm/mach-tegra/tegra30/Kconfig" source "arch/arm/mach-tegra/tegra114/Kconfig" source "arch/arm/mach-tegra/tegra124/Kconfig" +source "arch/arm/mach-tegra/tegra210/Kconfig" endif diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index fefc180..0db8ee0 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,5 +1,5 @@ # -# (C) Copyright 2010,2011 Nvidia Corporation. +# (C) Copyright 2010-2015 Nvidia Corporation. # # (C) Copyright 2000-2008 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -24,7 +24,9 @@ obj-y += pinmux-common.o obj-y += powergate.o obj-y += xusb-padctl.o obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o +#TCW Fix this to use a common config switch (CONFIG_LOCK_VPR?) obj-$(CONFIG_TEGRA124) += vpr.o +obj-$(CONFIG_TEGRA210) += vpr.o obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o ifndef CONFIG_SPL_BUILD @@ -35,3 +37,4 @@ obj-$(CONFIG_TEGRA20) += tegra20/ obj-$(CONFIG_TEGRA30) += tegra30/ obj-$(CONFIG_TEGRA114) += tegra114/ obj-$(CONFIG_TEGRA124) += tegra124/ +obj-$(CONFIG_TEGRA210) += tegra210/ diff --git a/arch/arm/mach-tegra/ap.c b/arch/arm/mach-tegra/ap.c index 7b89c01..e62dda5 100644 --- a/arch/arm/mach-tegra/ap.c +++ b/arch/arm/mach-tegra/ap.c @@ -1,5 +1,5 @@ /* -* (C) Copyright 2010-2014 +* (C) Copyright 2010-2015 * NVIDIA Corporation <www.nvidia.com> * * SPDX-License-Identifier: GPL-2.0+ @@ -92,6 +92,13 @@ int tegra_get_chip_sku(void) return TEGRA_SOC_T124; } break; + case CHIPID_TEGRA210: + switch (sku_id) { + case SKU_ID_T210_ENG: + default: + return TEGRA_SOC_T210; + } + break; } /* unknown chip/sku id */ @@ -100,6 +107,7 @@ int tegra_get_chip_sku(void) return TEGRA_SOC_UNKNOWN; } +#ifndef CONFIG_ARM64 static void enable_scu(void) { struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; @@ -222,3 +230,4 @@ void s_init(void) /* init vpr */ config_vpr(); } +#endif diff --git a/arch/arm/mach-tegra/board.c b/arch/arm/mach-tegra/board.c index 036bf5e..40de72d 100644 --- a/arch/arm/mach-tegra/board.c +++ b/arch/arm/mach-tegra/board.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2010-2014 + * (C) Copyright 2010-2015 * NVIDIA Corporation <www.nvidia.com> * * SPDX-License-Identifier: GPL-2.0+ @@ -143,12 +143,18 @@ static int uart_configs[] = { -1, FUNCMUX_UART4_GMI, /* UARTD */ -1, -#else /* Tegra124 */ +#elif defined(CONFIG_TEGRA124) FUNCMUX_UART1_KBC, /* UARTA */ -1, -1, FUNCMUX_UART4_GPIO, /* UARTD */ -1, +#else /* Tegra210 */ + FUNCMUX_UART1_UART1, /* UARTA */ + -1, + -1, + FUNCMUX_UART4_UART4, /* UARTD */ + -1, #endif }; diff --git a/arch/arm/mach-tegra/cache.c b/arch/arm/mach-tegra/cache.c index 94f5bce..0e9cb97 100644 --- a/arch/arm/mach-tegra/cache.c +++ b/arch/arm/mach-tegra/cache.c @@ -21,6 +21,7 @@ #include <asm/arch-tegra/ap.h> #include <asm/arch/gp_padctrl.h> +#ifndef CONFIG_ARM64 void config_cache(void) { u32 reg = 0; @@ -44,3 +45,4 @@ void config_cache(void) reg |= 2; asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg)); } +#endif diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 5c963d3..5d968d8 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2010-2015, 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, @@ -113,7 +113,11 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, data = readl(&pll->pll_misc); *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; - +#if defined(CONFIG_TEGRA210) + /* T210 PLLU uses KCP/KVCO instead of CPCON/LFCON */ + *cpcon = (data & PLLU_KCP_MASK) >> PLLU_KCP_SHIFT; + *lfcon = (data & PLLU_KVCO_MASK) >> PLLU_KVCO_SHIFT; +#endif return 0; } @@ -132,14 +136,28 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, * - 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 + * NOTE: Above is no longer true with T210 - TBD: FIX THIS */ misc_data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); +#if defined(CONFIG_TEGRA210) + /* T210 PLLU uses KCP/KVCO instead of cpcon/lfcon */ + if (clkid == CLOCK_ID_USB) { + /* preserve EN_LOCKDET, set by default */ + misc_data = readl(&pll->pll_misc); + misc_data |= (cpcon << PLLU_KCP_SHIFT) | + (lfcon << PLLU_KVCO_SHIFT); + } +#endif data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); if (clkid == CLOCK_ID_USB) +#if defined(CONFIG_TEGRA210) + data |= divp << PLLU_DIVP_SHIFT; +#else data |= divp << PLLU_VCO_FREQ_SHIFT; +#endif else data |= divp << PLL_DIVP_SHIFT; if (pll) { @@ -534,8 +552,15 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) /* Set cpcon to PLL_MISC */ misc_reg = readl(&pll->pll_misc); +#if !defined(CONFIG_TEGRA210) misc_reg &= ~PLL_CPCON_MASK; misc_reg |= cpcon << PLL_CPCON_SHIFT; +#else + /* T210 uses KCP instead, use the most common bit shift (PLLA/U/D2) */ + misc_reg &= ~PLLU_KCP_MASK; + misc_reg |= cpcon << PLLU_KCP_SHIFT; +#endif + writel(misc_reg, &pll->pll_misc); /* Enable PLL */ @@ -628,6 +653,7 @@ static void set_avp_clock_source(u32 src) /* * This function is useful on Tegra30, and any later SoCs that have compatible * PLLP configuration registers. + * NOTE: Not used on Tegra210 - see tegra210_setup_pllp in T210 clock.c */ void tegra30_set_up_pllp(void) { diff --git a/arch/arm/mach-tegra/cpu.c b/arch/arm/mach-tegra/cpu.c index c6f3b02..f7d45e8 100644 --- a/arch/arm/mach-tegra/cpu.c +++ b/arch/arm/mach-tegra/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2010-2015, 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, @@ -29,6 +29,7 @@ int get_num_cpus(void) { struct apb_misc_gp_ctlr *gp; uint rev; + debug("%s entry\n", __func__); gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; @@ -39,6 +40,8 @@ int get_num_cpus(void) break; case CHIPID_TEGRA30: case CHIPID_TEGRA114: + case CHIPID_TEGRA124: + case CHIPID_TEGRA210: default: return 4; break; @@ -128,13 +131,30 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ }, + + /* + * T210: 700 MHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 24:20 5 + * PLLX_BASE n 15: 8 8 + * PLLX_BASE m 7: 0 8 + */ + { + { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz*/ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz*/ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz*/ + { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz*/ + }, }; static inline void pllx_set_iddq(void) { -#if defined(CONFIG_TEGRA124) +#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210) struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 reg; + debug("%s entry\n", __func__); /* Disable IDDQ */ reg = readl(&clkrst->crc_pllx_misc3); @@ -151,15 +171,14 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, { int chip = tegra_get_chip(); u32 reg; + debug("%s entry\n", __func__); /* If PLLX is already enabled, just return */ if (readl(&pll->pll_base) & PLL_ENABLE_MASK) { - debug("pllx_set_rate: PLLX already enabled, returning\n"); + debug("%s: PLLX already enabled, returning\n", __func__); return 0; } - debug(" pllx_set_rate entry\n"); - pllx_set_iddq(); /* Set BYPASS, m, n and p to PLLX_BASE */ @@ -182,19 +201,19 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, reg = readl(&pll->pll_base); reg &= ~PLL_BYPASS_MASK; writel(reg, &pll->pll_base); - debug("pllx_set_rate: base = 0x%08X\n", reg); + debug("%s: base = 0x%08X\n", __func__, reg); /* Set lock_enable to PLLX_MISC */ reg = readl(&pll->pll_misc); reg |= PLL_LOCK_ENABLE_MASK; writel(reg, &pll->pll_misc); - debug("pllx_set_rate: misc = 0x%08X\n", reg); + debug("%s: misc = 0x%08X\n", __func__, reg); /* Enable PLLX last, once it's all configured */ reg = readl(&pll->pll_base); reg |= PLL_ENABLE_MASK; writel(reg, &pll->pll_base); - debug("pllx_set_rate: base final = 0x%08X\n", reg); + debug("%s: base final = 0x%08X\n", __func__, reg); return 0; } @@ -206,24 +225,23 @@ void init_pllx(void) int soc_type, sku_info, chip_sku; enum clock_osc_freq osc; struct clk_pll_table *sel; - - debug("init_pllx entry\n"); + debug("%s entry\n", __func__); /* get SOC (chip) type */ soc_type = tegra_get_chip(); - debug(" init_pllx: SoC = 0x%02X\n", soc_type); + debug("%s: SoC = 0x%02X\n", __func__, soc_type); /* get SKU info */ sku_info = tegra_get_sku_info(); - debug(" init_pllx: SKU info byte = 0x%02X\n", sku_info); + debug("%s: SKU info byte = 0x%02X\n", __func__, sku_info); /* get chip SKU, combo of the above info */ chip_sku = tegra_get_chip_sku(); - debug(" init_pllx: Chip SKU = %d\n", chip_sku); + debug("%s: Chip SKU = %d\n", __func__, chip_sku); /* get osc freq */ osc = clock_get_osc_freq(); - debug(" init_pllx: osc = %d\n", osc); + debug("%s: osc = %d\n", __func__, osc); /* set pllx */ sel = &tegra_pll_x_table[chip_sku][osc]; @@ -234,6 +252,7 @@ void enable_cpu_clock(int enable) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 clk; + debug("%s entry\n", __func__); /* * NOTE: @@ -282,6 +301,7 @@ static void remove_cpu_io_clamps(void) { struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; u32 reg; + debug("%s entry\n", __func__); /* Remove the clamps on the CPU I/O signals */ reg = readl(&pmc->pmc_remove_clamping); @@ -297,6 +317,7 @@ void powerup_cpu(void) struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; u32 reg; int timeout = IO_STABILIZATION_DELAY; + debug("%s entry\n", __func__); if (!is_cpu_powered()) { /* Toggle the CPU power state (OFF -> ON) */ @@ -336,7 +357,7 @@ void reset_A9_cpu(int reset) int num_cpus = get_num_cpus(); int cpu; - debug("reset_a9_cpu entry\n"); + debug("%s entry\n", __func__); /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ for (cpu = 1; cpu < num_cpus; cpu++) reset_cmplx_set_enable(cpu, mask, 1); @@ -350,7 +371,7 @@ void clock_enable_coresight(int enable) { u32 rst, src = 2; - debug("clock_enable_coresight entry\n"); + debug("%s entry\n", __func__); clock_set_enable(PERIPH_ID_CORESIGHT, enable); reset_set_enable(PERIPH_ID_CORESIGHT, !enable); @@ -377,6 +398,8 @@ void clock_enable_coresight(int enable) void halt_avp(void) { + debug("%s entry\n", __func__); + for (;;) { writel(HALT_COP_EVENT_JTAG | (FLOW_MODE_STOP << 29), FLOW_CTLR_HALT_COP_EVENTS); diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h index b4ca44f..3f38969 100644 --- a/arch/arm/mach-tegra/cpu.h +++ b/arch/arm/mach-tegra/cpu.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2010-2014 + * (C) Copyright 2010-2015 * NVIDIA Corporation <www.nvidia.com> * * SPDX-License-Identifier: GPL-2.0+ @@ -14,7 +14,7 @@ #define NVBL_PLLP_KHZ 216000 #define CSITE_KHZ 144000 #elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) || \ - defined(CONFIG_TEGRA124) + defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210) #define NVBL_PLLP_KHZ 408000 #define CSITE_KHZ 204000 #else @@ -35,7 +35,7 @@ #define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ #define PG_UP_TAG_0 0x0 -#define CORESIGHT_UNLOCK 0xC5ACCE55; +#define CORESIGHT_UNLOCK 0xC5ACCE55 #define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) #define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) @@ -53,6 +53,10 @@ #define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) +/* SB_AA64_RESET_LOW and _HIGH defines for CPU reset vector */ +#define SB_AA64_RESET_LOW 0x6000C230 +#define SB_AA64_RESET_HIGH 0x6000C234 + struct clk_pll_table { u16 n; u16 m; diff --git a/arch/arm/mach-tegra/lowlevel_init.S b/arch/arm/mach-tegra/lowlevel_init.S index 4bc0a3f..1273f94 100644 --- a/arch/arm/mach-tegra/lowlevel_init.S +++ b/arch/arm/mach-tegra/lowlevel_init.S @@ -10,6 +10,20 @@ #include <config.h> #include <linux/linkage.h> +#ifdef CONFIG_ARM64 + .align 5 +ENTRY(reset_cpu) + /* get address for global reset register */ + ldr x1, =PRM_RSTCTRL + ldr w3, [x1] + /* force reset */ + orr w3, w3, #0x10 + str w3, [x1] + mov w0, w0 +1: + b 1b +ENDPROC(reset_cpu) +#else .align 5 ENTRY(reset_cpu) ldr r1, rstctl @ get addr for global reset @@ -23,3 +37,4 @@ _loop_forever: rstctl: .word PRM_RSTCTRL ENDPROC(reset_cpu) +#endif |