ARM: Tegra210: Add support to common Tegra source/config files

Derived from Tegra124, modified as appropriate during T210
board bringup. Cleaned up debug statements to conserve
string space, too. This also adds misc 64-bit changes
from Thierry Reding/Stephen Warren.

Signed-off-by: Tom Warren <twarren@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
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 @@
 	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/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 += 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_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 @@
 			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 @@
 	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 @@
 	/* 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 @@
 	-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 @@
 	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 @@
 	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 @@
 	 * - 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 @@
 
 	/* 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 @@
 /*
  * 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 @@
 {
 	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 @@
 		break;
 	case CHIPID_TEGRA30:
 	case CHIPID_TEGRA114:
+	case CHIPID_TEGRA124:
+	case CHIPID_TEGRA210:
 	default:
 		return 4;
 		break;
@@ -128,13 +131,30 @@
 		{ .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 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 @@
 	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 @@
 	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 @@
 {
 	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 @@
 {
 	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 @@
 	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 @@
 	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 @@
 {
 	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 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 @@
 rstctl:
 	.word	PRM_RSTCTRL
 ENDPROC(reset_cpu)
+#endif