summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/include
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-03-05 01:09:11 +0400
committerArnd Bergmann <arnd@arndb.de>2012-03-05 01:20:46 +0400
commit709baa67c676a187a63c0f0f40efceb3fb1eef72 (patch)
tree0a2b8bab5ac4f52069a1e50d20028ae44d8c256a /arch/arm/mach-tegra/include
parent281a9f78eaa5d0d78bd0e3acd181a24d3bad28e3 (diff)
parent8c690fdf465be9d97229f6bb0e6346624d6753a9 (diff)
downloadlinux-709baa67c676a187a63c0f0f40efceb3fb1eef72.tar.xz
Merge tag 'tegra-soc2' of git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra into tegra/soc2
From: Olof Johansson <olof@lixom.net> Tegra 30 SMP support I did this as a separate topic branch because it depends on both the soc and the soc-drivers branch, so it brings both of those in as a base. This branch contains work to enable SMP support on Tegra30 and reworks some of the SMP bringup for T20 as well. It also contains a device tree patch that builds on top of the SMP/clock changes in the rest of the branch, so it made more sense to apply it here than deal with the merge conflicts back and forth. * tag 'tegra-soc2' of git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra: ARM: dt: Explicitly configure all serial ports on Tegra Cardhu ARM: tegra: support for secondary cores on Tegra30 ARM: tegra: support for Tegra30 CPU powerdomains ARM: tegra: add support for Tegra30 powerdomains ARM: tegra: export tegra_powergate_is_powered() ARM: tegra: prepare powergate.c for multiple variants ARM: tegra: rework Tegra secondary CPU core bringup ARM: tegra: functions to access the flowcontroller ARM: tegra: initialize Tegra chipid early ARM: tegra: export Tegra chipid ARM: tegra: cleanup use of chipid register Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-tegra/include')
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S88
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h10
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio-tegra.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h6
-rw-r--r--arch/arm/mach-tegra/include/mach/irammap.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h7
-rw-r--r--arch/arm/mach-tegra/include/mach/powergate.h15
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h118
9 files changed, 258 insertions, 33 deletions
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index fc3ecb66de08..d97e403303a0 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -22,10 +22,20 @@
struct clk;
+enum tegra_clk_ex_param {
+ TEGRA_CLK_VI_INP_SEL,
+ TEGRA_CLK_DTV_INVERT,
+ TEGRA_CLK_NAND_PAD_DIV2_ENB,
+ TEGRA_CLK_PLLD_CSI_OUT_ENB,
+ TEGRA_CLK_PLLD_DSI_OUT_ENB,
+ TEGRA_CLK_PLLD_MIPI_MUX_SEL,
+};
+
void tegra_periph_reset_deassert(struct clk *c);
void tegra_periph_reset_assert(struct clk *c);
unsigned long clk_get_rate_all_locked(struct clk *c);
void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
+int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 619abc63aee8..90069abd37bd 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -1,11 +1,17 @@
/*
* arch/arm/mach-tegra/include/mach/debug-macro.S
*
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
+ * Doug Anderson <dianders@chromium.org>
+ * Stephen Warren <swarren@nvidia.com>
+ *
+ * Portions based on mach-omap2's debug-macro.S
+ * Copyright (C) 1994-1999 Russell King
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -18,18 +24,78 @@
*
*/
+#include <linux/serial_reg.h>
+
#include <mach/io.h>
#include <mach/iomap.h>
+#include <mach/irammap.h>
+
+ .macro addruart, rp, rv, tmp
+ adr \rp, 99f @ actual addr of 99f
+ ldr \rv, [\rp] @ linked addr is stored there
+ sub \rv, \rv, \rp @ offset between the two
+ ldr \rp, [\rp, #4] @ linked tegra_uart_config
+ sub \tmp, \rp, \rv @ actual tegra_uart_config
+ ldr \rp, [\tmp] @ Load tegra_uart_config
+ cmp \rp, #1 @ needs intitialization?
+ bne 100f @ no; go load the addresses
+ mov \rv, #0 @ yes; record init is done
+ str \rv, [\tmp]
+ mov \rp, #TEGRA_IRAM_BASE @ See if cookie is in IRAM
+ ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
+ movw \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
+ movt \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
+ cmp \rv, \rp @ Cookie present?
+ bne 100f @ No, use default UART
+ mov \rp, #TEGRA_IRAM_BASE @ Load UART address from IRAM
+ ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
+ str \rv, [\tmp, #4] @ Store in tegra_uart_phys
+ sub \rv, \rv, #IO_APB_PHYS @ Calculate virt address
+ add \rv, \rv, #IO_APB_VIRT
+ str \rv, [\tmp, #8] @ Store in tegra_uart_virt
+ b 100f
+
+ .align
+99: .word .
+ .word tegra_uart_config
+ .ltorg
+
+100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys
+ ldr \rv, [\tmp, #8] @ Load tegra_uart_virt
+ .endm
+
+#define UART_SHIFT 2
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
+ * We use the fact that all 5 valid UART addresses all have something in the
+ * 2nd-to-lowest byte.
+ */
- .macro addruart, rp, rv, tmp
- ldr \rp, =IO_APB_PHYS @ physical
- ldr \rv, =IO_APB_VIRT @ virtual
- orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
- orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
- orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
- orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
- .endm
+ .macro senduart, rd, rx
+ tst \rx, #0x0000ff00
+ strneb \rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+ .endm
-#define UART_SHIFT 2
-#include <asm/hardware/debug-8250.S>
+ .macro busyuart, rd, rx
+ tst \rx, #0x0000ff00
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ bne 1001b
+1002:
+ .endm
+ .macro waituart, rd, rx
+#ifdef FLOW_CONTROL
+ tst \rx, #0x0000ff00
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+1002:
+#endif
+ .endm
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
index d0132e8031a1..3c9339058bec 100644
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -23,11 +23,6 @@
#include <linux/list.h>
-#if defined(CONFIG_TEGRA_SYSTEM_DMA)
-
-struct tegra_dma_req;
-struct tegra_dma_channel;
-
#define TEGRA_DMA_REQ_SEL_CNTR 0
#define TEGRA_DMA_REQ_SEL_I2S_2 1
#define TEGRA_DMA_REQ_SEL_I2S_1 2
@@ -56,6 +51,11 @@ struct tegra_dma_channel;
#define TEGRA_DMA_REQ_SEL_OWR 25
#define TEGRA_DMA_REQ_SEL_INVALID 31
+#if defined(CONFIG_TEGRA_SYSTEM_DMA)
+
+struct tegra_dma_req;
+struct tegra_dma_channel;
+
enum tegra_dma_mode {
TEGRA_DMA_SHARED = 1,
TEGRA_DMA_MODE_CONTINOUS = 2,
diff --git a/arch/arm/mach-tegra/include/mach/gpio-tegra.h b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
index 87d37fdf5084..6140820555e1 100644
--- a/arch/arm/mach-tegra/include/mach/gpio-tegra.h
+++ b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
@@ -25,8 +25,6 @@
#define TEGRA_NR_GPIOS INT_GPIO_NR
-#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
-
struct tegra_gpio_table {
int gpio; /* GPIO number */
bool enable; /* Enable for GPIO at init? */
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 19dec3ac0854..cff672a344f4 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -74,6 +74,9 @@
#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
+#define TEGRA_QUINARY_ICTLR_BASE 0x60004400
+#define TEGRA_QUINARY_ICTLR_SIZE SZ_64
+
#define TEGRA_TMR1_BASE 0x60005000
#define TEGRA_TMR1_SIZE SZ_8
@@ -110,6 +113,9 @@
#define TEGRA_AHB_GIZMO_BASE 0x6000C004
#define TEGRA_AHB_GIZMO_SIZE 0x10C
+#define TEGRA_SB_BASE 0x6000C200
+#define TEGRA_SB_SIZE 256
+
#define TEGRA_STATMON_BASE 0x6000C400
#define TEGRA_STATMON_SIZE SZ_1K
diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/include/mach/irammap.h
new file mode 100644
index 000000000000..0cbe63261854
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irammap.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_IRAMMAP_H
+#define __MACH_TEGRA_IRAMMAP_H
+
+#include <asm/sizes.h>
+
+/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
+#define TEGRA_IRAM_RESET_HANDLER_OFFSET 0
+#define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K
+
+/*
+ * These locations are written to by uncompress.h, and read by debug-macro.S.
+ * The first word holds the cookie value if the data is valid. The second
+ * word holds the UART physical address.
+ */
+#define TEGRA_IRAM_DEBUG_UART_OFFSET SZ_1K
+#define TEGRA_IRAM_DEBUG_UART_SIZE 8
+#define TEGRA_IRAM_DEBUG_UART_COOKIE 0x55415254
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index a2146cd6867d..aad1a2c1d714 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -165,11 +165,12 @@
#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
-#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE)
-
+/* Tegra30 has 5 banks of 32 IRQs */
+#define INT_MAIN_NR (32 * 5)
#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
-#define INT_GPIO_NR (28 * 8)
+/* Tegra30 has 8 banks of 32 GPIOs */
+#define INT_GPIO_NR (32 * 8)
#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h
index 39c396d2ddb0..4752b1a68f35 100644
--- a/arch/arm/mach-tegra/include/mach/powergate.h
+++ b/arch/arm/mach-tegra/include/mach/powergate.h
@@ -27,8 +27,21 @@
#define TEGRA_POWERGATE_VDEC 4
#define TEGRA_POWERGATE_L2 5
#define TEGRA_POWERGATE_MPE 6
-#define TEGRA_NUM_POWERGATE 7
+#define TEGRA_POWERGATE_HEG 7
+#define TEGRA_POWERGATE_SATA 8
+#define TEGRA_POWERGATE_CPU1 9
+#define TEGRA_POWERGATE_CPU2 10
+#define TEGRA_POWERGATE_CPU3 11
+#define TEGRA_POWERGATE_CELP 12
+#define TEGRA_POWERGATE_3D1 13
+#define TEGRA_POWERGATE_CPU0 TEGRA_POWERGATE_CPU
+#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
+
+int __init tegra_powergate_init(void);
+
+int tegra_cpu_powergate_id(int cpuid);
+int tegra_powergate_is_powered(int id);
int tegra_powergate_power_on(int id);
int tegra_powergate_power_off(int id);
int tegra_powergate_remove_clamping(int id);
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 4e8323770c79..b066ba0ee3c3 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -2,10 +2,14 @@
* arch/arm/mach-tegra/include/mach/uncompress.h
*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
+ * Doug Anderson <dianders@chromium.org>
+ * Stephen Warren <swarren@nvidia.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -21,40 +25,132 @@
#ifndef __MACH_TEGRA_UNCOMPRESS_H
#define __MACH_TEGRA_UNCOMPRESS_H
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/serial_reg.h>
#include <mach/iomap.h>
+#include <mach/irammap.h>
+
+#define DEBUG_UART_SHIFT 2
+
+volatile u8 *uart;
static void putc(int c)
{
- volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
- int shift = 2;
-
if (uart == NULL)
return;
- while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+ while (!(uart[UART_LSR << DEBUG_UART_SHIFT] & UART_LSR_THRE))
barrier();
- uart[UART_TX << shift] = c;
+ uart[UART_TX << DEBUG_UART_SHIFT] = c;
}
static inline void flush(void)
{
}
+static inline void save_uart_address(void)
+{
+ u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);
+
+ if (uart) {
+ buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
+ buf[1] = (u32)uart;
+ } else
+ buf[0] = 0;
+}
+
+/*
+ * Setup before decompression. This is where we do UART selection for
+ * earlyprintk and init the uart_base register.
+ */
static inline void arch_decomp_setup(void)
{
- volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
- int shift = 2;
+ static const struct {
+ u32 base;
+ u32 reset_reg;
+ u32 clock_reg;
+ u32 bit;
+ } uarts[] = {
+ {
+ TEGRA_UARTA_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 6,
+ },
+ {
+ TEGRA_UARTB_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 7,
+ },
+ {
+ TEGRA_UARTC_BASE,
+ TEGRA_CLK_RESET_BASE + 0x08,
+ TEGRA_CLK_RESET_BASE + 0x14,
+ 23,
+ },
+ {
+ TEGRA_UARTD_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 1,
+ },
+ {
+ TEGRA_UARTE_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 2,
+ },
+ };
+ int i;
+ volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
+ u32 chip, div;
+
+ /*
+ * Look for the first UART that:
+ * a) Is not in reset.
+ * b) Is clocked.
+ * c) Has a 'D' in the scratchpad register.
+ *
+ * Note that on Tegra30, the first two conditions are required, since
+ * if not true, accesses to the UART scratch register will hang.
+ * Tegra20 doesn't have this issue.
+ *
+ * The intent is that the bootloader will tell the kernel which UART
+ * to use by setting up those conditions. If nothing found, we'll fall
+ * back to what's specified in TEGRA_DEBUG_UART_BASE.
+ */
+ for (i = 0; i < ARRAY_SIZE(uarts); i++) {
+ if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
+ continue;
+ if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+ continue;
+
+ uart = (volatile u8 *)uarts[i].base;
+ if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
+ continue;
+
+ break;
+ }
+ if (i == ARRAY_SIZE(uarts))
+ uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+ save_uart_address();
if (uart == NULL)
return;
- uart[UART_LCR << shift] |= UART_LCR_DLAB;
- uart[UART_DLL << shift] = 0x75;
- uart[UART_DLM << shift] = 0x0;
- uart[UART_LCR << shift] = 3;
+ chip = (apb_misc[0x804 / 4] >> 8) & 0xff;
+ if (chip == 0x20)
+ div = 0x0075;
+ else
+ div = 0x00dd;
+
+ uart[UART_LCR << DEBUG_UART_SHIFT] |= UART_LCR_DLAB;
+ uart[UART_DLL << DEBUG_UART_SHIFT] = div & 0xff;
+ uart[UART_DLM << DEBUG_UART_SHIFT] = div >> 8;
+ uart[UART_LCR << DEBUG_UART_SHIFT] = 3;
}
static inline void arch_decomp_wdog(void)