aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Kconfig39
-rw-r--r--arch/arm/mach-tegra/Makefile7
-rw-r--r--arch/arm/mach-tegra/apbio.c2
-rw-r--r--arch/arm/mach-tegra/board-paz00.c16
-rw-r--r--arch/arm/mach-tegra/board-paz00.h25
-rw-r--r--arch/arm/mach-tegra/board.h12
-rw-r--r--arch/arm/mach-tegra/common.c115
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c7
-rw-r--r--arch/arm/mach-tegra/cpuidle.c4
-rw-r--r--arch/arm/mach-tegra/flowctrl.c2
-rw-r--r--arch/arm/mach-tegra/fuse.c109
-rw-r--r--arch/arm/mach-tegra/fuse.h1
-rw-r--r--arch/arm/mach-tegra/gpio-names.h247
-rw-r--r--arch/arm/mach-tegra/hotplug.c2
-rw-r--r--arch/arm/mach-tegra/iomap.h169
-rw-r--r--arch/arm/mach-tegra/irammap.h6
-rw-r--r--arch/arm/mach-tegra/platsmp.c4
-rw-r--r--arch/arm/mach-tegra/pm.c21
-rw-r--r--arch/arm/mach-tegra/pm.h5
-rw-r--r--arch/arm/mach-tegra/pmc.c82
-rw-r--r--arch/arm/mach-tegra/pmc.h5
-rw-r--r--arch/arm/mach-tegra/powergate.c251
-rw-r--r--arch/arm/mach-tegra/reset-handler.S24
-rw-r--r--arch/arm/mach-tegra/reset.c42
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S5
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S54
-rw-r--r--arch/arm/mach-tegra/sleep.h31
-rw-r--r--arch/arm/mach-tegra/tegra.c59
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.c347
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.h24
30 files changed, 619 insertions, 1098 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 67a76f2dfb9..095399618ca 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -1,32 +1,21 @@
-config ARCH_TEGRA
+menuconfig ARCH_TEGRA
bool "NVIDIA Tegra" if ARCH_MULTI_V7
- select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
select ARM_GIC
- select CLKDEV_LOOKUP
select CLKSRC_MMIO
- select CLKSRC_OF
- select COMMON_CLK
- select CPU_V7
- select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
- select HAVE_CLK
- select HAVE_SMP
- select MIGHT_HAVE_CACHE_L2X0
- select MIGHT_HAVE_PCI
select PINCTRL
+ select ARCH_HAS_RESET_CONTROLLER
+ select RESET_CONTROLLER
select SOC_BUS
- select SPARSE_IRQ
- select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_PHY
select USB_ULPI_VIEWPORT if USB_PHY
- select USE_OF
help
This enables support for NVIDIA Tegra based systems.
-menu "NVIDIA Tegra options"
- depends on ARCH_TEGRA
+if ARCH_TEGRA
config ARCH_TEGRA_2x_SOC
bool "Enable support for Tegra20 family"
@@ -53,14 +42,23 @@ config ARCH_TEGRA_3x_SOC
config ARCH_TEGRA_114_SOC
bool "Enable support for Tegra114 family"
- select HAVE_ARM_ARCH_TIMER
- select ARM_ERRATA_798181
+ select ARM_ERRATA_798181 if SMP
select ARM_L1_CACHE_SHIFT_6
+ select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA114
help
Support for NVIDIA Tegra T114 processor family, based on the
ARM CortexA15MP CPU
+config ARCH_TEGRA_124_SOC
+ bool "Enable support for Tegra124 family"
+ select ARM_L1_CACHE_SHIFT_6
+ select HAVE_ARM_ARCH_TIMER
+ select PINCTRL_TEGRA124
+ help
+ Support for NVIDIA Tegra T124 processor family, based on the
+ ARM CortexA15MP CPU
+
config TEGRA_AHB
bool "Enable AHB driver for NVIDIA Tegra SoCs"
default y
@@ -69,7 +67,4 @@ config TEGRA_AHB
which controls AHB bus master arbitration and some
performance parameters(priority, prefech size).
-config TEGRA_EMC_SCALING_ENABLE
- bool "Enable scaling the memory frequency"
-
-endmenu
+endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e7e5f45c655..6fbfbb77dcd 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,6 +1,5 @@
asflags-y += -march=armv7-a
-obj-y += common.o
obj-y += io.o
obj-y += irq.o
obj-y += fuse.o
@@ -15,7 +14,6 @@ obj-y += sleep.o
obj-y += tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
ifeq ($(CONFIG_CPU_IDLE),y)
@@ -36,5 +34,10 @@ obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
endif
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o
+endif
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index d7aa52ea6cf..bc471973cf0 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -114,7 +114,7 @@ static int do_dma_transfer(unsigned long apb_add,
dma_desc->callback = apb_dma_complete;
dma_desc->callback_param = NULL;
- INIT_COMPLETION(tegra_apb_wait);
+ reinit_completion(&tegra_apb_wait);
dmaengine_submit(dma_desc);
dma_async_issue_pending(tegra_apb_dma_chan);
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index 740e16f6472..9c6029ba526 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -18,14 +18,12 @@
*/
#include <linux/platform_device.h>
+#include <linux/gpio/driver.h>
#include <linux/rfkill-gpio.h>
#include "board.h"
-#include "board-paz00.h"
static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
- .name = "wifi_rfkill",
- .reset_gpio = TEGRA_WIFI_RST,
- .shutdown_gpio = TEGRA_WIFI_PWRN,
+ .name = "wifi_rfkill",
.type = RFKILL_TYPE_WLAN,
};
@@ -37,7 +35,17 @@ static struct platform_device wifi_rfkill_device = {
},
};
+static struct gpiod_lookup_table wifi_gpio_lookup = {
+ .dev_id = "rfkill_gpio",
+ .table = {
+ GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0),
+ GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0),
+ { },
+ },
+};
+
void __init tegra_paz00_wifikill_init(void)
{
+ gpiod_add_lookup_table(&wifi_gpio_lookup);
platform_device_register(&wifi_rfkill_device);
}
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
deleted file mode 100644
index 25c08ecef52..00000000000
--- a/arch/arm/mach-tegra/board-paz00.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-tegra/board-paz00.h
- *
- * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _MACH_TEGRA_BOARD_PAZ00_H
-#define _MACH_TEGRA_BOARD_PAZ00_H
-
-#include "gpio-names.h"
-
-#define TEGRA_WIFI_PWRN TEGRA_GPIO_PK5
-#define TEGRA_WIFI_RST TEGRA_GPIO_PD1
-
-#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index db6810dc0b3..bcf5dbf69d5 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -25,20 +25,8 @@
#include <linux/types.h>
#include <linux/reboot.h>
-void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd);
-
-void __init tegra_init_early(void);
void __init tegra_map_common_io(void);
void __init tegra_init_irq(void);
-void __init tegra_dt_init_irq(void);
-
-void tegra_init_late(void);
-
-#ifdef CONFIG_DEBUG_FS
-int tegra_clk_debugfs_init(void);
-#else
-static inline int tegra_clk_debugfs_init(void) { return 0; }
-#endif
int __init tegra_powergate_init(void);
#if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS)
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
deleted file mode 100644
index 94a119a35af..00000000000
--- a/arch/arm/mach-tegra/common.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * arch/arm/mach-tegra/common.c
- *
- * Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/irqchip.h>
-#include <linux/clk-provider.h>
-
-#include <asm/hardware/cache-l2x0.h>
-
-#include "board.h"
-#include "common.h"
-#include "cpuidle.h"
-#include "fuse.h"
-#include "iomap.h"
-#include "irq.h"
-#include "pmc.h"
-#include "apbio.h"
-#include "sleep.h"
-#include "pm.h"
-#include "reset.h"
-
-/*
- * Storage for debug-macro.S's state.
- *
- * This must be in .data not .bss so that it gets initialized each time the
- * kernel is loaded. The data is declared here rather than debug-macro.S so
- * that multiple inclusions of debug-macro.S point at the same data.
- */
-u32 tegra_uart_config[4] = {
- /* Debug UART initialization required */
- 1,
- /* Debug UART physical address */
- 0,
- /* Debug UART virtual address */
- 0,
- /* Scratch space for debug macro */
- 0,
-};
-
-#ifdef CONFIG_OF
-void __init tegra_dt_init_irq(void)
-{
- of_clk_init(NULL);
- tegra_pmc_init();
- tegra_init_irq();
- irqchip_init();
- tegra_legacy_irq_syscore_init();
-}
-#endif
-
-void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd)
-{
- void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0);
- u32 reg;
-
- reg = readl_relaxed(reset);
- reg |= 0x10;
- writel_relaxed(reg, reset);
-}
-
-static void __init tegra_init_cache(void)
-{
-#ifdef CONFIG_CACHE_L2X0
- int ret;
- void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
- u32 aux_ctrl, cache_type;
-
- cache_type = readl(p + L2X0_CACHE_TYPE);
- aux_ctrl = (cache_type & 0x700) << (17-8);
- aux_ctrl |= 0x7C400001;
-
- ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
- if (!ret)
- l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
-#endif
-
-}
-
-void __init tegra_init_early(void)
-{
- tegra_cpu_reset_handler_init();
- tegra_apb_io_init();
- tegra_init_fuse();
- tegra_init_cache();
- tegra_powergate_init();
- tegra_hotplug_init();
-}
-
-void __init tegra_init_late(void)
-{
- tegra_init_suspend();
- tegra_cpuidle_init();
- tegra_powergate_debugfs_init();
-}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index e0b87300243..b5fb7c110c6 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -19,6 +19,7 @@
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/clockchips.h>
+#include <asm/firmware.h>
#include <asm/cpuidle.h>
#include <asm/suspend.h>
@@ -45,7 +46,11 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
- cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+ call_firmware_op(prepare_idle);
+
+ /* Do suspend by ourselves if the firmware does not implement it */
+ if (call_firmware_op(do_idle) == -ENOSYS)
+ cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 0961dfcf83a..7bc5d8d667f 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -39,7 +39,9 @@ void __init tegra_cpuidle_init(void)
tegra30_cpuidle_init();
break;
case TEGRA114:
- if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+ case TEGRA124:
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra114_cpuidle_init();
break;
}
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index 5348543382b..ce8ab8abf06 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -87,6 +87,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
break;
case TEGRA30:
case TEGRA114:
+ case TEGRA124:
/* clear wfe bitmap */
reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
/* clear wfi bitmap */
@@ -125,6 +126,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
break;
case TEGRA30:
case TEGRA114:
+ case TEGRA124:
/* clear wfe bitmap */
reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
/* clear wfi bitmap */
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index e035cd284a6..c9ac23b385b 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -21,14 +21,27 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/export.h>
+#include <linux/random.h>
+#include <linux/clk.h>
#include <linux/tegra-soc.h>
#include "fuse.h"
#include "iomap.h"
#include "apbio.h"
+/* Tegra20 only */
#define FUSE_UID_LOW 0x108
#define FUSE_UID_HIGH 0x10c
+
+/* Tegra30 and later */
+#define FUSE_VENDOR_CODE 0x200
+#define FUSE_FAB_CODE 0x204
+#define FUSE_LOT_CODE_0 0x208
+#define FUSE_LOT_CODE_1 0x20c
+#define FUSE_WAFER_ID 0x210
+#define FUSE_X_COORDINATE 0x214
+#define FUSE_Y_COORDINATE 0x218
+
#define FUSE_SKU_INFO 0x110
#define TEGRA20_FUSE_SPARE_BIT 0x200
@@ -42,6 +55,7 @@ int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
int tegra_soc_speedo_id;
enum tegra_revision tegra_revision;
+static struct clk *fuse_clk;
static int tegra_fuse_spare_bit;
static void (*tegra_init_speedo_data)(void);
@@ -65,6 +79,22 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
[TEGRA_REVISION_A04] = "A04",
};
+static void tegra_fuse_enable_clk(void)
+{
+ if (IS_ERR(fuse_clk))
+ fuse_clk = clk_get_sys(NULL, "fuse");
+ if (IS_ERR(fuse_clk))
+ return;
+ clk_prepare_enable(fuse_clk);
+}
+
+static void tegra_fuse_disable_clk(void)
+{
+ if (IS_ERR(fuse_clk))
+ return;
+ clk_disable_unprepare(fuse_clk);
+}
+
u32 tegra_fuse_readl(unsigned long offset)
{
return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
@@ -72,7 +102,15 @@ u32 tegra_fuse_readl(unsigned long offset)
bool tegra_spare_fuse(int bit)
{
- return tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
+ bool ret;
+
+ tegra_fuse_enable_clk();
+
+ ret = tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
+
+ tegra_fuse_disable_clk();
+
+ return ret;
}
static enum tegra_revision tegra_get_revision(u32 id)
@@ -101,10 +139,14 @@ static void tegra_get_process_id(void)
{
u32 reg;
+ tegra_fuse_enable_clk();
+
reg = tegra_fuse_readl(tegra_fuse_spare_bit);
tegra_cpu_process_id = (reg >> 6) & 3;
reg = tegra_fuse_readl(tegra_fuse_spare_bit);
tegra_core_process_id = (reg >> 12) & 3;
+
+ tegra_fuse_disable_clk();
}
u32 tegra_read_chipid(void)
@@ -112,21 +154,60 @@ u32 tegra_read_chipid(void)
return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
}
-void tegra_init_fuse(void)
+static void __init tegra20_fuse_init_randomness(void)
+{
+ u32 randomness[2];
+
+ randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
+ randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+/* Applies to Tegra30 or later */
+static void __init tegra30_fuse_init_randomness(void)
+{
+ u32 randomness[7];
+
+ randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
+ randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
+ randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
+ randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
+ randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
+ randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
+ randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+void __init tegra_init_fuse(void)
{
u32 id;
+ u32 randomness[5];
u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
reg |= 1 << 28;
writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
+ /*
+ * Enable FUSE clock. This needs to be hardcoded because the clock
+ * subsystem is not active during early boot.
+ */
+ reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
+ reg |= 1 << 7;
+ writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x14));
+ fuse_clk = ERR_PTR(-EINVAL);
+
reg = tegra_fuse_readl(FUSE_SKU_INFO);
+ randomness[0] = reg;
tegra_sku_id = reg & 0xFF;
reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+ randomness[1] = reg;
tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
id = tegra_read_chipid();
+ randomness[2] = id;
tegra_chip_id = (id >> 8) & 0xff;
switch (tegra_chip_id) {
@@ -149,19 +230,23 @@ void tegra_init_fuse(void)
tegra_revision = tegra_get_revision(id);
tegra_init_speedo_data();
+ randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
+ randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
+
+ add_device_randomness(randomness, sizeof(randomness));
+ switch (tegra_chip_id) {
+ case TEGRA20:
+ tegra20_fuse_init_randomness();
+ break;
+ case TEGRA30:
+ case TEGRA114:
+ default:
+ tegra30_fuse_init_randomness();
+ break;
+ }
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
tegra_revision_name[tegra_revision],
tegra_sku_id, tegra_cpu_process_id,
tegra_core_process_id);
}
-
-unsigned long long tegra_chip_uid(void)
-{
- unsigned long long lo, hi;
-
- lo = tegra_fuse_readl(FUSE_UID_LOW);
- hi = tegra_fuse_readl(FUSE_UID_HIGH);
- return (hi << 32ull) | lo;
-}
-EXPORT_SYMBOL(tegra_chip_uid);
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index def79683bef..c01d04785d6 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -29,6 +29,7 @@
#define TEGRA20 0x20
#define TEGRA30 0x30
#define TEGRA114 0x35
+#define TEGRA124 0x40
#ifndef __ASSEMBLY__
enum tegra_revision {
diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h
deleted file mode 100644
index f28220a641b..00000000000
--- a/arch/arm/mach-tegra/gpio-names.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/gpio-names.h
- *
- * Copyright (c) 2010 Google, Inc
- *
- * Author:
- * Erik Gilling <konkers@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- */
-
-#ifndef __MACH_TEGRA_GPIO_NAMES_H
-#define __MACH_TEGRA_GPIO_NAMES_H
-
-#define TEGRA_GPIO_PA0 0
-#define TEGRA_GPIO_PA1 1
-#define TEGRA_GPIO_PA2 2
-#define TEGRA_GPIO_PA3 3
-#define TEGRA_GPIO_PA4 4
-#define TEGRA_GPIO_PA5 5
-#define TEGRA_GPIO_PA6 6
-#define TEGRA_GPIO_PA7 7
-#define TEGRA_GPIO_PB0 8
-#define TEGRA_GPIO_PB1 9
-#define TEGRA_GPIO_PB2 10
-#define TEGRA_GPIO_PB3 11
-#define TEGRA_GPIO_PB4 12
-#define TEGRA_GPIO_PB5 13
-#define TEGRA_GPIO_PB6 14
-#define TEGRA_GPIO_PB7 15
-#define TEGRA_GPIO_PC0 16
-#define TEGRA_GPIO_PC1 17
-#define TEGRA_GPIO_PC2 18
-#define TEGRA_GPIO_PC3 19
-#define TEGRA_GPIO_PC4 20
-#define TEGRA_GPIO_PC5 21
-#define TEGRA_GPIO_PC6 22
-#define TEGRA_GPIO_PC7 23
-#define TEGRA_GPIO_PD0 24
-#define TEGRA_GPIO_PD1 25
-#define TEGRA_GPIO_PD2 26
-#define TEGRA_GPIO_PD3 27
-#define TEGRA_GPIO_PD4 28
-#define TEGRA_GPIO_PD5 29
-#define TEGRA_GPIO_PD6 30
-#define TEGRA_GPIO_PD7 31
-#define TEGRA_GPIO_PE0 32
-#define TEGRA_GPIO_PE1 33
-#define TEGRA_GPIO_PE2 34
-#define TEGRA_GPIO_PE3 35
-#define TEGRA_GPIO_PE4 36
-#define TEGRA_GPIO_PE5 37
-#define TEGRA_GPIO_PE6 38
-#define TEGRA_GPIO_PE7 39
-#define TEGRA_GPIO_PF0 40
-#define TEGRA_GPIO_PF1 41
-#define TEGRA_GPIO_PF2 42
-#define TEGRA_GPIO_PF3 43
-#define TEGRA_GPIO_PF4 44
-#define TEGRA_GPIO_PF5 45
-#define TEGRA_GPIO_PF6 46
-#define TEGRA_GPIO_PF7 47
-#define TEGRA_GPIO_PG0 48
-#define TEGRA_GPIO_PG1 49
-#define TEGRA_GPIO_PG2 50
-#define TEGRA_GPIO_PG3 51
-#define TEGRA_GPIO_PG4 52
-#define TEGRA_GPIO_PG5 53
-#define TEGRA_GPIO_PG6 54
-#define TEGRA_GPIO_PG7 55
-#define TEGRA_GPIO_PH0 56
-#define TEGRA_GPIO_PH1 57
-#define TEGRA_GPIO_PH2 58
-#define TEGRA_GPIO_PH3 59
-#define TEGRA_GPIO_PH4 60
-#define TEGRA_GPIO_PH5 61
-#define TEGRA_GPIO_PH6 62
-#define TEGRA_GPIO_PH7 63
-#define TEGRA_GPIO_PI0 64
-#define TEGRA_GPIO_PI1 65
-#define TEGRA_GPIO_PI2 66
-#define TEGRA_GPIO_PI3 67
-#define TEGRA_GPIO_PI4 68
-#define TEGRA_GPIO_PI5 69
-#define TEGRA_GPIO_PI6 70
-#define TEGRA_GPIO_PI7 71
-#define TEGRA_GPIO_PJ0 72
-#define TEGRA_GPIO_PJ1 73
-#define TEGRA_GPIO_PJ2 74
-#define TEGRA_GPIO_PJ3 75
-#define TEGRA_GPIO_PJ4 76
-#define TEGRA_GPIO_PJ5 77
-#define TEGRA_GPIO_PJ6 78
-#define TEGRA_GPIO_PJ7 79
-#define TEGRA_GPIO_PK0 80
-#define TEGRA_GPIO_PK1 81
-#define TEGRA_GPIO_PK2 82
-#define TEGRA_GPIO_PK3 83
-#define TEGRA_GPIO_PK4 84
-#define TEGRA_GPIO_PK5 85
-#define TEGRA_GPIO_PK6 86
-#define TEGRA_GPIO_PK7 87
-#define TEGRA_GPIO_PL0 88
-#define TEGRA_GPIO_PL1 89
-#define TEGRA_GPIO_PL2 90
-#define TEGRA_GPIO_PL3 91
-#define TEGRA_GPIO_PL4 92
-#define TEGRA_GPIO_PL5 93
-#define TEGRA_GPIO_PL6 94
-#define TEGRA_GPIO_PL7 95
-#define TEGRA_GPIO_PM0 96
-#define TEGRA_GPIO_PM1 97
-#define TEGRA_GPIO_PM2 98
-#define TEGRA_GPIO_PM3 99
-#define TEGRA_GPIO_PM4 100
-#define TEGRA_GPIO_PM5 101
-#define TEGRA_GPIO_PM6 102
-#define TEGRA_GPIO_PM7 103
-#define TEGRA_GPIO_PN0 104
-#define TEGRA_GPIO_PN1 105
-#define TEGRA_GPIO_PN2 106
-#define TEGRA_GPIO_PN3 107
-#define TEGRA_GPIO_PN4 108
-#define TEGRA_GPIO_PN5 109
-#define TEGRA_GPIO_PN6 110
-#define TEGRA_GPIO_PN7 111
-#define TEGRA_GPIO_PO0 112
-#define TEGRA_GPIO_PO1 113
-#define TEGRA_GPIO_PO2 114
-#define TEGRA_GPIO_PO3 115
-#define TEGRA_GPIO_PO4 116
-#define TEGRA_GPIO_PO5 117
-#define TEGRA_GPIO_PO6 118
-#define TEGRA_GPIO_PO7 119
-#define TEGRA_GPIO_PP0 120
-#define TEGRA_GPIO_PP1 121
-#define TEGRA_GPIO_PP2 122
-#define TEGRA_GPIO_PP3 123
-#define TEGRA_GPIO_PP4 124
-#define TEGRA_GPIO_PP5 125
-#define TEGRA_GPIO_PP6 126
-#define TEGRA_GPIO_PP7 127
-#define TEGRA_GPIO_PQ0 128
-#define TEGRA_GPIO_PQ1 129
-#define TEGRA_GPIO_PQ2 130
-#define TEGRA_GPIO_PQ3 131
-#define TEGRA_GPIO_PQ4 132
-#define TEGRA_GPIO_PQ5 133
-#define TEGRA_GPIO_PQ6 134
-#define TEGRA_GPIO_PQ7 135
-#define TEGRA_GPIO_PR0 136
-#define TEGRA_GPIO_PR1 137
-#define TEGRA_GPIO_PR2 138
-#define TEGRA_GPIO_PR3 139
-#define TEGRA_GPIO_PR4 140
-#define TEGRA_GPIO_PR5 141
-#define TEGRA_GPIO_PR6 142
-#define TEGRA_GPIO_PR7 143
-#define TEGRA_GPIO_PS0 144
-#define TEGRA_GPIO_PS1 145
-#define TEGRA_GPIO_PS2 146
-#define TEGRA_GPIO_PS3 147
-#define TEGRA_GPIO_PS4 148
-#define TEGRA_GPIO_PS5 149
-#define TEGRA_GPIO_PS6 150
-#define TEGRA_GPIO_PS7 151
-#define TEGRA_GPIO_PT0 152
-#define TEGRA_GPIO_PT1 153
-#define TEGRA_GPIO_PT2 154
-#define TEGRA_GPIO_PT3 155
-#define TEGRA_GPIO_PT4 156
-#define TEGRA_GPIO_PT5 157
-#define TEGRA_GPIO_PT6 158
-#define TEGRA_GPIO_PT7 159
-#define TEGRA_GPIO_PU0 160
-#define TEGRA_GPIO_PU1 161
-#define TEGRA_GPIO_PU2 162
-#define TEGRA_GPIO_PU3 163
-#define TEGRA_GPIO_PU4 164
-#define TEGRA_GPIO_PU5 165
-#define TEGRA_GPIO_PU6 166
-#define TEGRA_GPIO_PU7 167
-#define TEGRA_GPIO_PV0 168
-#define TEGRA_GPIO_PV1 169
-#define TEGRA_GPIO_PV2 170
-#define TEGRA_GPIO_PV3 171
-#define TEGRA_GPIO_PV4 172
-#define TEGRA_GPIO_PV5 173
-#define TEGRA_GPIO_PV6 174
-#define TEGRA_GPIO_PV7 175
-#define TEGRA_GPIO_PW0 176
-#define TEGRA_GPIO_PW1 177
-#define TEGRA_GPIO_PW2 178
-#define TEGRA_GPIO_PW3 179
-#define TEGRA_GPIO_PW4 180
-#define TEGRA_GPIO_PW5 181
-#define TEGRA_GPIO_PW6 182
-#define TEGRA_GPIO_PW7 183
-#define TEGRA_GPIO_PX0 184
-#define TEGRA_GPIO_PX1 185
-#define TEGRA_GPIO_PX2 186
-#define TEGRA_GPIO_PX3 187
-#define TEGRA_GPIO_PX4 188
-#define TEGRA_GPIO_PX5 189
-#define TEGRA_GPIO_PX6 190
-#define TEGRA_GPIO_PX7 191
-#define TEGRA_GPIO_PY0 192
-#define TEGRA_GPIO_PY1 193
-#define TEGRA_GPIO_PY2 194
-#define TEGRA_GPIO_PY3 195
-#define TEGRA_GPIO_PY4 196
-#define TEGRA_GPIO_PY5 197
-#define TEGRA_GPIO_PY6 198
-#define TEGRA_GPIO_PY7 199
-#define TEGRA_GPIO_PZ0 200
-#define TEGRA_GPIO_PZ1 201
-#define TEGRA_GPIO_PZ2 202
-#define TEGRA_GPIO_PZ3 203
-#define TEGRA_GPIO_PZ4 204
-#define TEGRA_GPIO_PZ5 205
-#define TEGRA_GPIO_PZ6 206
-#define TEGRA_GPIO_PZ7 207
-#define TEGRA_GPIO_PAA0 208
-#define TEGRA_GPIO_PAA1 209
-#define TEGRA_GPIO_PAA2 210
-#define TEGRA_GPIO_PAA3 211
-#define TEGRA_GPIO_PAA4 212
-#define TEGRA_GPIO_PAA5 213
-#define TEGRA_GPIO_PAA6 214
-#define TEGRA_GPIO_PAA7 215
-#define TEGRA_GPIO_PBB0 216
-#define TEGRA_GPIO_PBB1 217
-#define TEGRA_GPIO_PBB2 218
-#define TEGRA_GPIO_PBB3 219
-#define TEGRA_GPIO_PBB4 220
-#define TEGRA_GPIO_PBB5 221
-#define TEGRA_GPIO_PBB6 222
-#define TEGRA_GPIO_PBB7 223
-
-#endif
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 04de2e86092..ff26af26bd0 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -57,4 +57,6 @@ void __init tegra_hotplug_init(void)
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
}
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
index 3f5fa0749bd..ee79808e93a 100644
--- a/arch/arm/mach-tegra/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -19,49 +19,18 @@
#ifndef __MACH_TEGRA_IOMAP_H
#define __MACH_TEGRA_IOMAP_H
+#include <asm/pgtable.h>
#include <asm/sizes.h>
#define TEGRA_IRAM_BASE 0x40000000
#define TEGRA_IRAM_SIZE SZ_256K
-#define TEGRA_IRAM_CODE_AREA (TEGRA_IRAM_BASE + SZ_4K)
-
-#define TEGRA_HOST1X_BASE 0x50000000
-#define TEGRA_HOST1X_SIZE 0x24000
-
#define TEGRA_ARM_PERIF_BASE 0x50040000
#define TEGRA_ARM_PERIF_SIZE SZ_8K
-#define TEGRA_ARM_PL310_BASE 0x50043000
-#define TEGRA_ARM_PL310_SIZE SZ_4K
-
#define TEGRA_ARM_INT_DIST_BASE 0x50041000
#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
-#define TEGRA_MPE_BASE 0x54040000
-#define TEGRA_MPE_SIZE SZ_256K
-
-#define TEGRA_VI_BASE 0x54080000
-#define TEGRA_VI_SIZE SZ_256K
-
-#define TEGRA_ISP_BASE 0x54100000
-#define TEGRA_ISP_SIZE SZ_256K
-
-#define TEGRA_DISPLAY_BASE 0x54200000
-#define TEGRA_DISPLAY_SIZE SZ_256K
-
-#define TEGRA_DISPLAY2_BASE 0x54240000
-#define TEGRA_DISPLAY2_SIZE SZ_256K
-
-#define TEGRA_HDMI_BASE 0x54280000
-#define TEGRA_HDMI_SIZE SZ_256K
-
-#define TEGRA_GART_BASE 0x58000000
-#define TEGRA_GART_SIZE SZ_32M
-
-#define TEGRA_RES_SEMA_BASE 0x60001000
-#define TEGRA_RES_SEMA_SIZE SZ_4K
-
#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
@@ -98,51 +67,15 @@
#define TEGRA_FLOW_CTRL_BASE 0x60007000
#define TEGRA_FLOW_CTRL_SIZE 20
-#define TEGRA_AHB_DMA_BASE 0x60008000
-#define TEGRA_AHB_DMA_SIZE SZ_4K
-
-#define TEGRA_AHB_DMA_CH0_BASE 0x60009000
-#define TEGRA_AHB_DMA_CH0_SIZE 32
-
-#define TEGRA_APB_DMA_BASE 0x6000A000
-#define TEGRA_APB_DMA_SIZE SZ_4K
-
-#define TEGRA_APB_DMA_CH0_BASE 0x6000B000
-#define TEGRA_APB_DMA_CH0_SIZE 32
-
-#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
-
-#define TEGRA_GPIO_BASE 0x6000D000
-#define TEGRA_GPIO_SIZE SZ_4K
-
#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
#define TEGRA_APB_MISC_BASE 0x70000000
#define TEGRA_APB_MISC_SIZE SZ_4K
-#define TEGRA_APB_MISC_DAS_BASE 0x70000c00
-#define TEGRA_APB_MISC_DAS_SIZE SZ_128
-
-#define TEGRA_AC97_BASE 0x70002000
-#define TEGRA_AC97_SIZE SZ_512
-
-#define TEGRA_SPDIF_BASE 0x70002400
-#define TEGRA_SPDIF_SIZE SZ_512
-
-#define TEGRA_I2S1_BASE 0x70002800
-#define TEGRA_I2S1_SIZE SZ_256
-
-#define TEGRA_I2S2_BASE 0x70002A00
-#define TEGRA_I2S2_SIZE SZ_256
-
#define TEGRA_UARTA_BASE 0x70006000
#define TEGRA_UARTA_SIZE SZ_64
@@ -158,133 +91,51 @@
#define TEGRA_UARTE_BASE 0x70006400
#define TEGRA_UARTE_SIZE SZ_256
-#define TEGRA_NAND_BASE 0x70008000
-#define TEGRA_NAND_SIZE SZ_256
-
-#define TEGRA_HSMMC_BASE 0x70008500
-#define TEGRA_HSMMC_SIZE SZ_256
-
-#define TEGRA_SNOR_BASE 0x70009000
-#define TEGRA_SNOR_SIZE SZ_4K
-
-#define TEGRA_PWFM_BASE 0x7000A000
-#define TEGRA_PWFM_SIZE SZ_256
-
-#define TEGRA_PWFM0_BASE 0x7000A000
-#define TEGRA_PWFM0_SIZE 4
-
-#define TEGRA_PWFM1_BASE 0x7000A010
-#define TEGRA_PWFM1_SIZE 4
-
-#define TEGRA_PWFM2_BASE 0x7000A020
-#define TEGRA_PWFM2_SIZE 4
-
-#define TEGRA_PWFM3_BASE 0x7000A030
-#define TEGRA_PWFM3_SIZE 4
-
-#define TEGRA_MIPI_BASE 0x7000B000
-#define TEGRA_MIPI_SIZE SZ_256
-
-#define TEGRA_I2C_BASE 0x7000C000
-#define TEGRA_I2C_SIZE SZ_256
-
-#define TEGRA_TWC_BASE 0x7000C100
-#define TEGRA_TWC_SIZE SZ_256
-
-#define TEGRA_SPI_BASE 0x7000C380
-#define TEGRA_SPI_SIZE 48
-
-#define TEGRA_I2C2_BASE 0x7000C400
-#define TEGRA_I2C2_SIZE SZ_256
-
-#define TEGRA_I2C3_BASE 0x7000C500
-#define TEGRA_I2C3_SIZE SZ_256
-
-#define TEGRA_OWR_BASE 0x7000C600
-#define TEGRA_OWR_SIZE 80
-
-#define TEGRA_DVC_BASE 0x7000D000
-#define TEGRA_DVC_SIZE SZ_512
-
-#define TEGRA_SPI1_BASE 0x7000D400
-#define TEGRA_SPI1_SIZE SZ_512
-
-#define TEGRA_SPI2_BASE 0x7000D600
-#define TEGRA_SPI2_SIZE SZ_512
-
-#define TEGRA_SPI3_BASE 0x7000D800
-#define TEGRA_SPI3_SIZE SZ_512
-
-#define TEGRA_SPI4_BASE 0x7000DA00
-#define TEGRA_SPI4_SIZE SZ_512
-
-#define TEGRA_RTC_BASE 0x7000E000
-#define TEGRA_RTC_SIZE SZ_256
-
-#define TEGRA_KBC_BASE 0x7000E200
-#define TEGRA_KBC_SIZE SZ_256
-
#define TEGRA_PMC_BASE 0x7000E400
#define TEGRA_PMC_SIZE SZ_256
-#define TEGRA_MC_BASE 0x7000F000
-#define TEGRA_MC_SIZE SZ_1K
-
#define TEGRA_EMC_BASE 0x7000F400
#define TEGRA_EMC_SIZE SZ_1K
#define TEGRA_FUSE_BASE 0x7000F800
#define TEGRA_FUSE_SIZE SZ_1K
-#define TEGRA_KFUSE_BASE 0x7000FC00
-#define TEGRA_KFUSE_SIZE SZ_1K
-
#define TEGRA_EMC0_BASE 0x7001A000
#define TEGRA_EMC0_SIZE SZ_2K
#define TEGRA_EMC1_BASE 0x7001A800
#define TEGRA_EMC1_SIZE SZ_2K
+#define TEGRA124_EMC_BASE 0x7001B000
+#define TEGRA124_EMC_SIZE SZ_2K
+
#define TEGRA_CSITE_BASE 0x70040000
#define TEGRA_CSITE_SIZE SZ_256K
-#define TEGRA_SDMMC1_BASE 0xC8000000
-#define TEGRA_SDMMC1_SIZE SZ_512
-
-#define TEGRA_SDMMC2_BASE 0xC8000200
-#define TEGRA_SDMMC2_SIZE SZ_512
-
-#define TEGRA_SDMMC3_BASE 0xC8000400
-#define TEGRA_SDMMC3_SIZE SZ_512
-
-#define TEGRA_SDMMC4_BASE 0xC8000600
-#define TEGRA_SDMMC4_SIZE SZ_512
-
/* On TEGRA, many peripherals are very closely packed in
* two 256MB io windows (that actually only use about 64KB
* at the start of each).
*
- * We will just map the first 1MB of each window (to minimize
+ * We will just map the first MMU section of each window (to minimize
* pt entries needed) and provide a macro to transform physical
* io addresses to an appropriate void __iomem *.
- *
*/
#define IO_IRAM_PHYS 0x40000000
#define IO_IRAM_VIRT IOMEM(0xFE400000)
#define IO_IRAM_SIZE SZ_256K
-#define IO_CPU_PHYS 0x50040000
-#define IO_CPU_VIRT IOMEM(0xFE000000)
+#define IO_CPU_PHYS 0x50040000
+#define IO_CPU_VIRT IOMEM(0xFE440000)
#define IO_CPU_SIZE SZ_16K
#define IO_PPSB_PHYS 0x60000000
#define IO_PPSB_VIRT IOMEM(0xFE200000)
-#define IO_PPSB_SIZE SZ_1M
+#define IO_PPSB_SIZE SECTION_SIZE
#define IO_APB_PHYS 0x70000000
-#define IO_APB_VIRT IOMEM(0xFE300000)
-#define IO_APB_SIZE SZ_1M
+#define IO_APB_VIRT IOMEM(0xFE000000)
+#define IO_APB_SIZE SECTION_SIZE
#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
diff --git a/arch/arm/mach-tegra/irammap.h b/arch/arm/mach-tegra/irammap.h
index 501952a8434..e32e1742c9a 100644
--- a/arch/arm/mach-tegra/irammap.h
+++ b/arch/arm/mach-tegra/irammap.h
@@ -23,4 +23,10 @@
#define TEGRA_IRAM_RESET_HANDLER_OFFSET 0
#define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K
+/*
+ * This area is used for LPx resume vector, only while LPx power state is
+ * active. At other times, the AVP may use this area for arbitrary purposes
+ */
+#define TEGRA_IRAM_LPx_RESUME_AREA (TEGRA_IRAM_BASE + SZ_4K)
+
#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 2d0203627fb..929d1046e2b 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -114,7 +114,7 @@ static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
/* Wait for the power to come up. */
timeout = jiffies + msecs_to_jiffies(100);
- while (tegra_pmc_cpu_is_powered(cpu)) {
+ while (!tegra_pmc_cpu_is_powered(cpu)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
udelay(10);
@@ -176,6 +176,8 @@ static int tegra_boot_secondary(unsigned int cpu,
return tegra30_boot_secondary(cpu, idle);
if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
return tegra114_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124)
+ return tegra114_boot_secondary(cpu, idle);
return -EINVAL;
}
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index ed294a04e1d..f55b05a29b5 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -24,6 +24,7 @@
#include <linux/cpu_pm.h>
#include <linux/suspend.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/clk/tegra.h>
#include <asm/smp_plat.h>
@@ -59,8 +60,10 @@ static void tegra_tear_down_cpu_init(void)
break;
case TEGRA30:
case TEGRA114:
+ case TEGRA124:
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
- IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra_tear_down_cpu = tegra30_tear_down_cpu;
break;
}
@@ -216,8 +219,10 @@ static bool tegra_lp1_iram_hook(void)
break;
case TEGRA30:
case TEGRA114:
+ case TEGRA124:
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
- IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra30_lp1_iram_hook();
break;
default:
@@ -244,8 +249,10 @@ static bool tegra_sleep_core_init(void)
break;
case TEGRA30:
case TEGRA114:
+ case TEGRA124:
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
- IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+ IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
+ IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
tegra30_sleep_core_init();
break;
default:
@@ -263,10 +270,10 @@ static void tegra_suspend_enter_lp1(void)
tegra_pmc_suspend();
/* copy the reset vector & SDRAM shutdown code into IRAM */
- memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_CODE_AREA),
- iram_save_size);
- memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), tegra_lp1_iram.start_addr,
+ memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
iram_save_size);
+ memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA),
+ tegra_lp1_iram.start_addr, iram_save_size);
*((u32 *)tegra_cpu_lp1_mask) = 1;
}
@@ -276,7 +283,7 @@ static void tegra_suspend_exit_lp1(void)
tegra_pmc_resume();
/* restore IRAM */
- memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), iram_save_addr,
+ memcpy(IO_ADDRESS(TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr,
iram_save_size);
*(u32 *)tegra_cpu_lp1_mask = 0;
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index fe204e5256e..f4a89698e5b 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -35,11 +35,6 @@ void tegra20_sleep_core_init(void);
void tegra30_lp1_iram_hook(void);
void tegra30_sleep_core_init(void);
-extern unsigned long l2x0_saved_regs_addr;
-
-void save_cpu_arch_register(void);
-void restore_cpu_arch_register(void);
-
void tegra_clear_cpu_in_lp2(void);
bool tegra_set_cpu_in_lp2(void);
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 8acb881f7cf..7c7123e7557 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/tegra-powergate.h>
#include "flowctrl.h"
#include "fuse.h"
@@ -40,15 +41,17 @@
#define PMC_REMOVE_CLAMPING 0x34
#define PMC_PWRGATE_STATUS 0x38
+#define PMC_SCRATCH0 0x50
+#define PMC_SCRATCH0_MODE_RECOVERY (1 << 31)
+#define PMC_SCRATCH0_MODE_BOOTLOADER (1 << 30)
+#define PMC_SCRATCH0_MODE_RCM (1 << 1)
+#define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \
+ PMC_SCRATCH0_MODE_BOOTLOADER | \
+ PMC_SCRATCH0_MODE_RCM)
+
#define PMC_CPUPWRGOOD_TIMER 0xc8
#define PMC_CPUPWROFF_TIMER 0xcc
-#define TEGRA_POWERGATE_PCIE 3
-#define TEGRA_POWERGATE_VDEC 4
-#define TEGRA_POWERGATE_CPU1 9
-#define TEGRA_POWERGATE_CPU2 10
-#define TEGRA_POWERGATE_CPU3 11
-
static u8 tegra_cpu_domains[] = {
0xFF, /* not available for CPU0 */
TEGRA_POWERGATE_CPU1,
@@ -166,6 +169,31 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
return tegra_pmc_powergate_remove_clamping(id);
}
+void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 val;
+
+ val = tegra_pmc_readl(PMC_SCRATCH0);
+ val &= ~PMC_SCRATCH0_MODE_MASK;
+
+ if (cmd) {
+ if (strcmp(cmd, "recovery") == 0)
+ val |= PMC_SCRATCH0_MODE_RECOVERY;
+
+ if (strcmp(cmd, "bootloader") == 0)
+ val |= PMC_SCRATCH0_MODE_BOOTLOADER;
+
+ if (strcmp(cmd, "forced-recovery") == 0)
+ val |= PMC_SCRATCH0_MODE_RCM;
+ }
+
+ tegra_pmc_writel(val, PMC_SCRATCH0);
+
+ val = tegra_pmc_readl(0);
+ val |= 0x10;
+ tegra_pmc_writel(val, 0);
+}
+
#ifdef CONFIG_PM_SLEEP
static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate)
{
@@ -279,19 +307,17 @@ void tegra_pmc_suspend_init(void)
#endif
static const struct of_device_id matches[] __initconst = {
+ { .compatible = "nvidia,tegra124-pmc" },
{ .compatible = "nvidia,tegra114-pmc" },
{ .compatible = "nvidia,tegra30-pmc" },
{ .compatible = "nvidia,tegra20-pmc" },
{ }
};
-static void __init tegra_pmc_parse_dt(void)
+void __init tegra_pmc_init_irq(void)
{
struct device_node *np;
- u32 prop;
- enum tegra_suspend_mode suspend_mode;
- u32 core_good_time[2] = {0, 0};
- u32 lp0_vec[2] = {0, 0};
+ u32 val;
np = of_find_matching_node(NULL, matches);
BUG_ON(!np);
@@ -300,6 +326,26 @@ static void __init tegra_pmc_parse_dt(void)
tegra_pmc_invert_interrupt = of_property_read_bool(np,
"nvidia,invert-interrupt");
+
+ val = tegra_pmc_readl(PMC_CTRL);
+ if (tegra_pmc_invert_interrupt)
+ val |= PMC_CTRL_INTR_LOW;
+ else
+ val &= ~PMC_CTRL_INTR_LOW;
+ tegra_pmc_writel(val, PMC_CTRL);
+}
+
+void __init tegra_pmc_init(void)
+{
+ struct device_node *np;
+ u32 prop;
+ enum tegra_suspend_mode suspend_mode;
+ u32 core_good_time[2] = {0, 0};
+ u32 lp0_vec[2] = {0, 0};
+
+ np = of_find_matching_node(NULL, matches);
+ BUG_ON(!np);
+
tegra_pclk = of_clk_get_by_name(np, "pclk");
WARN_ON(IS_ERR(tegra_pclk));
@@ -365,17 +411,3 @@ static void __init tegra_pmc_parse_dt(void)
pmc_pm_data.suspend_mode = suspend_mode;
}
-
-void __init tegra_pmc_init(void)
-{
- u32 val;
-
- tegra_pmc_parse_dt();
-
- val = tegra_pmc_readl(PMC_CTRL);
- if (tegra_pmc_invert_interrupt)
- val |= PMC_CTRL_INTR_LOW;
- else
- val &= ~PMC_CTRL_INTR_LOW;
- tegra_pmc_writel(val, PMC_CTRL);
-}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 549f8c7b762..59e19c34429 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -18,6 +18,8 @@
#ifndef __MACH_TEGRA_PMC_H
#define __MACH_TEGRA_PMC_H
+#include <linux/reboot.h>
+
enum tegra_suspend_mode {
TEGRA_SUSPEND_NONE = 0,
TEGRA_SUSPEND_LP2, /* CPU voltage off */
@@ -39,6 +41,9 @@ bool tegra_pmc_cpu_is_powered(int cpuid);
int tegra_pmc_cpu_power_on(int cpuid);
int tegra_pmc_cpu_remove_clamping(int cpuid);
+void tegra_pmc_restart(enum reboot_mode mode, const char *cmd);
+
+void tegra_pmc_init_irq(void);
void tegra_pmc_init(void);
#endif
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index f076f0f80fc..4cefc5cd6be 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -25,6 +25,7 @@
#include <linux/export.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/reset.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/clk/tegra.h>
@@ -33,6 +34,10 @@
#include "fuse.h"
#include "iomap.h"
+#define DPD_SAMPLE 0x020
+#define DPD_SAMPLE_ENABLE (1 << 0)
+#define DPD_SAMPLE_DISABLE (0 << 0)
+
#define PWRGATE_TOGGLE 0x30
#define PWRGATE_TOGGLE_START (1 << 8)
@@ -40,10 +45,38 @@
#define PWRGATE_STATUS 0x38
+#define IO_DPD_REQ 0x1b8
+#define IO_DPD_REQ_CODE_IDLE (0 << 30)
+#define IO_DPD_REQ_CODE_OFF (1 << 30)
+#define IO_DPD_REQ_CODE_ON (2 << 30)
+#define IO_DPD_REQ_CODE_MASK (3 << 30)
+
+#define IO_DPD_STATUS 0x1bc
+#define IO_DPD2_REQ 0x1c0
+#define IO_DPD2_STATUS 0x1c4
+#define SEL_DPD_TIM 0x1c8
+
+#define GPU_RG_CNTRL 0x2d4
+
static int tegra_num_powerdomains;
static int tegra_num_cpu_domains;
-static u8 *tegra_cpu_domains;
-static u8 tegra30_cpu_domains[] = {
+static const u8 *tegra_cpu_domains;
+
+static const u8 tegra30_cpu_domains[] = {
+ TEGRA_POWERGATE_CPU,
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+
+static const u8 tegra114_cpu_domains[] = {
+ TEGRA_POWERGATE_CPU0,
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+
+static const u8 tegra124_cpu_domains[] = {
TEGRA_POWERGATE_CPU0,
TEGRA_POWERGATE_CPU1,
TEGRA_POWERGATE_CPU2,
@@ -100,6 +133,7 @@ int tegra_powergate_power_off(int id)
return tegra_powergate_set(id, false);
}
+EXPORT_SYMBOL(tegra_powergate_power_off);
int tegra_powergate_is_powered(int id)
{
@@ -120,12 +154,23 @@ int tegra_powergate_remove_clamping(int id)
return -EINVAL;
/*
+ * The Tegra124 GPU has a separate register (with different semantics)
+ * to remove clamps.
+ */
+ if (tegra_chip_id == TEGRA124) {
+ if (id == TEGRA_POWERGATE_3D) {
+ pmc_write(0, GPU_RG_CNTRL);
+ return 0;
+ }
+ }
+
+ /*
* Tegra 2 has a bug where PCIE and VDE clamping masks are
* swapped relatively to the partition ids
*/
- if (id == TEGRA_POWERGATE_VDEC)
+ if (id == TEGRA_POWERGATE_VDEC)
mask = (1 << TEGRA_POWERGATE_PCIE);
- else if (id == TEGRA_POWERGATE_PCIE)
+ else if (id == TEGRA_POWERGATE_PCIE)
mask = (1 << TEGRA_POWERGATE_VDEC);
else
mask = (1 << id);
@@ -134,13 +179,15 @@ int tegra_powergate_remove_clamping(int id)
return 0;
}
+EXPORT_SYMBOL(tegra_powergate_remove_clamping);
/* Must be called with clk disabled, and returns with clk enabled */
-int tegra_powergate_sequence_power_up(int id, struct clk *clk)
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+ struct reset_control *rst)
{
int ret;
- tegra_periph_reset_assert(clk);
+ reset_control_assert(rst);
ret = tegra_powergate_power_on(id);
if (ret)
@@ -157,7 +204,7 @@ int tegra_powergate_sequence_power_up(int id, struct clk *clk)
goto err_clamp;
udelay(10);
- tegra_periph_reset_deassert(clk);
+ reset_control_deassert(rst);
return 0;
@@ -189,6 +236,16 @@ int __init tegra_powergate_init(void)
tegra_num_cpu_domains = 4;
tegra_cpu_domains = tegra30_cpu_domains;
break;
+ case TEGRA114:
+ tegra_num_powerdomains = 23;
+ tegra_num_cpu_domains = 4;
+ tegra_cpu_domains = tegra114_cpu_domains;
+ break;
+ case TEGRA124:
+ tegra_num_powerdomains = 25;
+ tegra_num_cpu_domains = 4;
+ tegra_cpu_domains = tegra124_cpu_domains;
+ break;
default:
/* Unknown Tegra variant. Disable powergating */
tegra_num_powerdomains = 0;
@@ -229,6 +286,54 @@ static const char * const powergate_name_t30[] = {
[TEGRA_POWERGATE_3D1] = "3d1",
};
+static const char * const powergate_name_t114[] = {
+ [TEGRA_POWERGATE_CPU] = "crail",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_HEG] = "heg",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CELP] = "celp",
+ [TEGRA_POWERGATE_CPU0] = "cpu0",
+ [TEGRA_POWERGATE_C0NC] = "c0nc",
+ [TEGRA_POWERGATE_C1NC] = "c1nc",
+ [TEGRA_POWERGATE_DIS] = "dis",
+ [TEGRA_POWERGATE_DISB] = "disb",
+ [TEGRA_POWERGATE_XUSBA] = "xusba",
+ [TEGRA_POWERGATE_XUSBB] = "xusbb",
+ [TEGRA_POWERGATE_XUSBC] = "xusbc",
+};
+
+static const char * const powergate_name_t124[] = {
+ [TEGRA_POWERGATE_CPU] = "crail",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_L2] = "l2",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_HEG] = "heg",
+ [TEGRA_POWERGATE_SATA] = "sata",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CELP] = "celp",
+ [TEGRA_POWERGATE_CPU0] = "cpu0",
+ [TEGRA_POWERGATE_C0NC] = "c0nc",
+ [TEGRA_POWERGATE_C1NC] = "c1nc",
+ [TEGRA_POWERGATE_SOR] = "sor",
+ [TEGRA_POWERGATE_DIS] = "dis",
+ [TEGRA_POWERGATE_DISB] = "disb",
+ [TEGRA_POWERGATE_XUSBA] = "xusba",
+ [TEGRA_POWERGATE_XUSBB] = "xusbb",
+ [TEGRA_POWERGATE_XUSBC] = "xusbc",
+ [TEGRA_POWERGATE_VIC] = "vic",
+ [TEGRA_POWERGATE_IRAM] = "iram",
+};
+
static int powergate_show(struct seq_file *s, void *data)
{
int i;
@@ -236,9 +341,14 @@ static int powergate_show(struct seq_file *s, void *data)
seq_printf(s, " powergate powered\n");
seq_printf(s, "------------------\n");
- for (i = 0; i < tegra_num_powerdomains; i++)
+ for (i = 0; i < tegra_num_powerdomains; i++) {
+ if (!powergate_name[i])
+ continue;
+
seq_printf(s, " %9s %7s\n", powergate_name[i],
tegra_powergate_is_powered(i) ? "yes" : "no");
+ }
+
return 0;
}
@@ -265,6 +375,12 @@ int __init tegra_powergate_debugfs_init(void)
case TEGRA30:
powergate_name = powergate_name_t30;
break;
+ case TEGRA114:
+ powergate_name = powergate_name_t114;
+ break;
+ case TEGRA124:
+ powergate_name = powergate_name_t124;
+ break;
}
if (powergate_name) {
@@ -278,3 +394,122 @@ int __init tegra_powergate_debugfs_init(void)
}
#endif
+
+static int tegra_io_rail_prepare(int id, unsigned long *request,
+ unsigned long *status, unsigned int *bit)
+{
+ unsigned long rate, value;
+ struct clk *clk;
+
+ *bit = id % 32;
+
+ /*
+ * There are two sets of 30 bits to select IO rails, but bits 30 and
+ * 31 are control bits rather than IO rail selection bits.
+ */
+ if (id > 63 || *bit == 30 || *bit == 31)
+ return -EINVAL;
+
+ if (id < 32) {
+ *status = IO_DPD_STATUS;
+ *request = IO_DPD_REQ;
+ } else {
+ *status = IO_DPD2_STATUS;
+ *request = IO_DPD2_REQ;
+ }
+
+ clk = clk_get_sys(NULL, "pclk");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+
+ pmc_write(DPD_SAMPLE_ENABLE, DPD_SAMPLE);
+
+ /* must be at least 200 ns, in APB (PCLK) clock cycles */
+ value = DIV_ROUND_UP(1000000000, rate);
+ value = DIV_ROUND_UP(200, value);
+ pmc_write(value, SEL_DPD_TIM);
+
+ return 0;
+}
+
+static int tegra_io_rail_poll(unsigned long offset, unsigned long mask,
+ unsigned long val, unsigned long timeout)
+{
+ unsigned long value;
+
+ timeout = jiffies + msecs_to_jiffies(timeout);
+
+ while (time_after(timeout, jiffies)) {
+ value = pmc_read(offset);
+ if ((value & mask) == val)
+ return 0;
+
+ usleep_range(250, 1000);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void tegra_io_rail_unprepare(void)
+{
+ pmc_write(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
+}
+
+int tegra_io_rail_power_on(int id)
+{
+ unsigned long request, status, value;
+ unsigned int bit, mask;
+ int err;
+
+ err = tegra_io_rail_prepare(id, &request, &status, &bit);
+ if (err < 0)
+ return err;
+
+ mask = 1 << bit;
+
+ value = pmc_read(request);
+ value |= mask;
+ value &= ~IO_DPD_REQ_CODE_MASK;
+ value |= IO_DPD_REQ_CODE_OFF;
+ pmc_write(value, request);
+
+ err = tegra_io_rail_poll(status, mask, 0, 250);
+ if (err < 0)
+ return err;
+
+ tegra_io_rail_unprepare();
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_io_rail_power_on);
+
+int tegra_io_rail_power_off(int id)
+{
+ unsigned long request, status, value;
+ unsigned int bit, mask;
+ int err;
+
+ err = tegra_io_rail_prepare(id, &request, &status, &bit);
+ if (err < 0)
+ return err;
+
+ mask = 1 << bit;
+
+ value = pmc_read(request);
+ value |= mask;
+ value &= ~IO_DPD_REQ_CODE_MASK;
+ value |= IO_DPD_REQ_CODE_ON;
+ pmc_write(value, request);
+
+ err = tegra_io_rail_poll(status, mask, mask, 250);
+ if (err < 0)
+ return err;
+
+ tegra_io_rail_unprepare();
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_io_rail_power_off);
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index f527b2c2dea..578d4d1ad64 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -19,7 +19,6 @@
#include <asm/cache.h>
#include <asm/asm-offsets.h>
-#include <asm/hardware/cache-l2x0.h>
#include "flowctrl.h"
#include "fuse.h"
@@ -45,17 +44,11 @@
ENTRY(tegra_resume)
check_cpu_part_num 0xc09, r8, r9
bleq v7_invalidate_l1
- blne tegra_init_l2_for_a15
cpu_id r0
- tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
- cmp r6, #TEGRA114
- beq no_cpu0_chk
-
cmp r0, #0 @ CPU0?
THUMB( it ne )
bne cpu_resume @ no
-no_cpu0_chk:
/* Are we on Tegra20? */
cmp r6, #TEGRA20
@@ -75,7 +68,7 @@ no_cpu0_chk:
mov32 r9, 0xc09
cmp r8, r9
- bne not_ca9
+ bne end_ca9_scu_l2_resume
#ifdef CONFIG_HAVE_ARM_SCU
/* enable SCU */
mov32 r0, TEGRA_ARM_PERIF_BASE
@@ -84,20 +77,19 @@ no_cpu0_chk:
str r1, [r0]
#endif
+#ifdef CONFIG_CACHE_L2X0
/* L2 cache resume & re-enable */
- l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
-not_ca9:
+ bl l2c310_early_resume
+#endif
+end_ca9_scu_l2_resume:
+ mov32 r9, 0xc0f
+ cmp r8, r9
+ bleq tegra_init_l2_for_a15
b cpu_resume
ENDPROC(tegra_resume)
#endif
-#ifdef CONFIG_CACHE_L2X0
- .globl l2x0_saved_regs_addr
-l2x0_saved_regs_addr:
- .long 0
-#endif
-
.align L1_CACHE_SHIFT
ENTRY(__tegra_cpu_reset_handler_start)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index fd0bbf8a6c9..146fe8e0ae7 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -21,6 +21,7 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/firmware.h>
#include "iomap.h"
#include "irammap.h"
@@ -33,26 +34,18 @@
static bool is_enabled;
-static void __init tegra_cpu_reset_handler_enable(void)
+static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
{
- void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
void __iomem *evp_cpu_reset =
IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
u32 reg;
- BUG_ON(is_enabled);
- BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
-
- memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
- tegra_cpu_reset_handler_size);
-
/*
* NOTE: This must be the one and only write to the EVP CPU reset
* vector in the entire system.
*/
- writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
- evp_cpu_reset);
+ writel(reset_address, evp_cpu_reset);
wmb();
reg = readl(evp_cpu_reset);
@@ -66,8 +59,33 @@ static void __init tegra_cpu_reset_handler_enable(void)
writel(reg, sb_ctrl);
wmb();
}
+}
+
+static void __init tegra_cpu_reset_handler_enable(void)
+{
+ void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+ const u32 reset_address = TEGRA_IRAM_RESET_BASE +
+ tegra_cpu_reset_handler_offset;
+ int err;
+
+ BUG_ON(is_enabled);
+ BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
- is_enabled = true;
+ memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+ tegra_cpu_reset_handler_size);
+
+ err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
+ switch (err) {
+ case -ENOSYS:
+ tegra_cpu_reset_handler_set(reset_address);
+ /* pass-through */
+ case 0:
+ is_enabled = true;
+ break;
+ default:
+ pr_crit("Cannot set CPU reset handler: %d\n", err);
+ BUG();
+ }
}
void __init tegra_cpu_reset_handler_init(void)
@@ -82,7 +100,7 @@ void __init tegra_cpu_reset_handler_init(void)
#ifdef CONFIG_PM_SLEEP
__tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
- TEGRA_IRAM_CODE_AREA;
+ TEGRA_IRAM_LPx_RESUME_AREA;
__tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
virt_to_phys((void *)tegra_resume);
#endif
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 5c3bd11c983..aaaf3abd268 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -25,6 +25,7 @@
#include <asm/cp15.h>
#include <asm/cache.h>
+#include "irammap.h"
#include "sleep.h"
#include "flowctrl.h"
@@ -235,7 +236,7 @@ ENTRY(tegra20_sleep_core_finish)
mov32 r0, tegra20_tear_down_core
mov32 r1, tegra20_iram_start
sub r0, r0, r1
- mov32 r1, TEGRA_IRAM_CODE_AREA
+ mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
add r0, r0, r1
mov pc, r3
@@ -328,7 +329,7 @@ tegra20_iram_start:
* The physical address of tegra_resume expected to be stored in
* PMC_SCRATCH41.
*
- * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
*/
ENTRY(tegra20_lp1_reset)
/*
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index 63fa91b5faf..b16d4a57fa5 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -20,6 +20,7 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>
+#include "irammap.h"
#include "fuse.h"
#include "sleep.h"
#include "flowctrl.h"
@@ -262,7 +263,7 @@ ENTRY(tegra30_sleep_core_finish)
mov32 r0, tegra30_tear_down_core
mov32 r1, tegra30_iram_start
sub r0, r0, r1
- mov32 r1, TEGRA_IRAM_CODE_AREA
+ mov32 r1, TEGRA_IRAM_LPx_RESUME_AREA
add r0, r0, r1
mov pc, r3
@@ -314,7 +315,7 @@ tegra30_iram_start:
* The physical address of tegra_resume expected to be stored in
* PMC_SCRATCH41.
*
- * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
+ * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_LPx_RESUME_AREA.
*/
ENTRY(tegra30_lp1_reset)
/*
@@ -382,7 +383,7 @@ _pll_m_c_x_done:
add r1, r1, #LOCK_DELAY
wait_until r1, r7, r3
- adr r5, tegra30_sdram_pad_save
+ adr r5, tegra_sdram_pad_save
ldr r4, [r5, #0x18] @ restore CLK_SOURCE_MSELECT
str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
@@ -407,8 +408,12 @@ _pll_m_c_x_done:
cmp r10, #TEGRA30
movweq r0, #:lower16:TEGRA_EMC_BASE @ r0 reserved for emc base
movteq r0, #:upper16:TEGRA_EMC_BASE
- movwne r0, #:lower16:TEGRA_EMC0_BASE
- movtne r0, #:upper16:TEGRA_EMC0_BASE
+ cmp r10, #TEGRA114
+ movweq r0, #:lower16:TEGRA_EMC0_BASE
+ movteq r0, #:upper16:TEGRA_EMC0_BASE
+ cmp r10, #TEGRA124
+ movweq r0, #:lower16:TEGRA124_EMC_BASE
+ movteq r0, #:upper16:TEGRA124_EMC_BASE
exit_self_refresh:
ldr r1, [r5, #0xC] @ restore EMC_XM2VTTGENPADCTRL
@@ -537,6 +542,7 @@ tegra30_sdram_pad_address:
.word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
.word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
.word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
+tegra30_sdram_pad_address_end:
tegra114_sdram_pad_address:
.word TEGRA_EMC0_BASE + EMC_CFG @0x0
@@ -552,16 +558,28 @@ tegra114_sdram_pad_address:
.word TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL @0x28
.word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL @0x2c
.word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2 @0x30
+tegra114_sdram_pad_adress_end:
+
+tegra124_sdram_pad_address:
+ .word TEGRA124_EMC_BASE + EMC_CFG @0x0
+ .word TEGRA124_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
+ .word TEGRA124_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
+ .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
+ .word TEGRA124_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
+ .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
+ .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
+tegra124_sdram_pad_address_end:
tegra30_sdram_pad_size:
- .word tegra114_sdram_pad_address - tegra30_sdram_pad_address
+ .word tegra30_sdram_pad_address_end - tegra30_sdram_pad_address
tegra114_sdram_pad_size:
- .word tegra30_sdram_pad_size - tegra114_sdram_pad_address
+ .word tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address
- .type tegra30_sdram_pad_save, %object
-tegra30_sdram_pad_save:
- .rept (tegra30_sdram_pad_size - tegra114_sdram_pad_address) / 4
+ .type tegra_sdram_pad_save, %object
+tegra_sdram_pad_save:
+ .rept (tegra114_sdram_pad_adress_end - tegra114_sdram_pad_address) / 4
.long 0
.endr
@@ -692,13 +710,18 @@ halted:
*/
tegra30_sdram_self_refresh:
- adr r8, tegra30_sdram_pad_save
+ adr r8, tegra_sdram_pad_save
tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
cmp r10, #TEGRA30
adreq r2, tegra30_sdram_pad_address
ldreq r3, tegra30_sdram_pad_size
- adrne r2, tegra114_sdram_pad_address
- ldrne r3, tegra114_sdram_pad_size
+ cmp r10, #TEGRA114
+ adreq r2, tegra114_sdram_pad_address
+ ldreq r3, tegra114_sdram_pad_size
+ cmp r10, #TEGRA124
+ adreq r2, tegra124_sdram_pad_address
+ ldreq r3, tegra30_sdram_pad_size
+
mov r9, #0
padsave:
@@ -716,7 +739,10 @@ padsave_done:
cmp r10, #TEGRA30
ldreq r0, =TEGRA_EMC_BASE @ r0 reserved for emc base addr
- ldrne r0, =TEGRA_EMC0_BASE
+ cmp r10, #TEGRA114
+ ldreq r0, =TEGRA_EMC0_BASE
+ cmp r10, #TEGRA124
+ ldreq r0, =TEGRA124_EMC_BASE
enter_self_refresh:
cmp r10, #TEGRA30
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index a4edbb3abd3..339fe42cd6f 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -120,37 +120,6 @@
mov \tmp1, \tmp1, lsr #8
.endm
-/* Macro to resume & re-enable L2 cache */
-#ifndef L2X0_CTRL_EN
-#define L2X0_CTRL_EN 1
-#endif
-
-#ifdef CONFIG_CACHE_L2X0
-.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
- W(adr) \tmp1, \phys_l2x0_saved_regs
- ldr \tmp1, [\tmp1]
- ldr \tmp2, [\tmp1, #L2X0_R_PHY_BASE]
- ldr \tmp3, [\tmp2, #L2X0_CTRL]
- tst \tmp3, #L2X0_CTRL_EN
- bne exit_l2_resume
- ldr \tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
- str \tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
- ldr \tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
- str \tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
- ldr \tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
- str \tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
- ldr \tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
- str \tmp3, [\tmp2, #L2X0_POWER_CTRL]
- ldr \tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
- str \tmp3, [\tmp2, #L2X0_AUX_CTRL]
- mov \tmp3, #L2X0_CTRL_EN
- str \tmp3, [\tmp2, #L2X0_CTRL]
-exit_l2_resume:
-.endm
-#else /* CONFIG_CACHE_L2X0 */
-.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
-.endm
-#endif /* CONFIG_CACHE_L2X0 */
#else
void tegra_pen_lock(void);
void tegra_pen_unlock(void);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 5b8605547a0..15ac9fcc96b 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -16,7 +16,6 @@
*
*/
-#include <linux/clocksource.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -34,16 +33,60 @@
#include <linux/sys_soc.h>
#include <linux/usb/tegra_usb_phy.h>
#include <linux/clk/tegra.h>
+#include <linux/irqchip.h>
+#include <asm/hardware/cache-l2x0.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/setup.h>
+#include <asm/trusted_foundations.h>
+#include "apbio.h"
#include "board.h"
#include "common.h"
+#include "cpuidle.h"
#include "fuse.h"
#include "iomap.h"
+#include "irq.h"
+#include "pmc.h"
+#include "pm.h"
+#include "reset.h"
+#include "sleep.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+u32 tegra_uart_config[3] = {
+ /* Debug UART initialization required */
+ 1,
+ /* Debug UART physical address */
+ 0,
+ /* Debug UART virtual address */
+ 0,
+};
+
+static void __init tegra_init_early(void)
+{
+ of_register_trusted_foundations();
+ tegra_apb_io_init();
+ tegra_init_fuse();
+ tegra_cpu_reset_handler_init();
+ tegra_powergate_init();
+ tegra_hotplug_init();
+}
+
+static void __init tegra_dt_init_irq(void)
+{
+ tegra_pmc_init_irq();
+ tegra_init_irq();
+ irqchip_init();
+ tegra_legacy_irq_syscore_init();
+}
static void __init tegra_dt_init(void)
{
@@ -51,6 +94,8 @@ static void __init tegra_dt_init(void)
struct soc_device *soc_dev;
struct device *parent = NULL;
+ tegra_pmc_init();
+
tegra_clocks_apply_init_table();
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
@@ -97,7 +142,9 @@ static void __init tegra_dt_init_late(void)
{
int i;
- tegra_init_late();
+ tegra_init_suspend();
+ tegra_cpuidle_init();
+ tegra_powergate_debugfs_init();
for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
if (of_machine_is_compatible(board_init_funcs[i].machine)) {
@@ -108,6 +155,7 @@ static void __init tegra_dt_init_late(void)
}
static const char * const tegra_dt_board_compat[] = {
+ "nvidia,tegra124",
"nvidia,tegra114",
"nvidia,tegra30",
"nvidia,tegra20",
@@ -115,13 +163,14 @@ static const char * const tegra_dt_board_compat[] = {
};
DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
- .map_io = tegra_map_common_io,
+ .l2c_aux_val = 0x3c400001,
+ .l2c_aux_mask = 0xc20fc3fe,
.smp = smp_ops(tegra_smp_ops),
+ .map_io = tegra_map_common_io,
.init_early = tegra_init_early,
.init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
.init_machine = tegra_dt_init,
.init_late = tegra_dt_init_late,
- .restart = tegra_assert_system_reset,
+ .restart = tegra_pmc_restart,
.dt_compat = tegra_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
deleted file mode 100644
index 3ae4a7f1a2f..00000000000
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/tegra_emc.h>
-
-#include "tegra2_emc.h"
-#include "fuse.h"
-
-#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
-static bool emc_enable = true;
-#else
-static bool emc_enable;
-#endif
-module_param(emc_enable, bool, 0644);
-
-static struct platform_device *emc_pdev;
-static void __iomem *emc_regbase;
-
-static inline void emc_writel(u32 val, unsigned long addr)
-{
- writel(val, emc_regbase + addr);
-}
-
-static inline u32 emc_readl(unsigned long addr)
-{
- return readl(emc_regbase + addr);
-}
-
-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 */
-};
-
-/* Select the closest EMC rate that is higher than the requested rate */
-long tegra_emc_round_rate(unsigned long rate)
-{
- struct tegra_emc_pdata *pdata;
- int i;
- int best = -1;
- unsigned long distance = ULONG_MAX;
-
- if (!emc_pdev)
- return -EINVAL;
-
- pdata = emc_pdev->dev.platform_data;
-
- pr_debug("%s: %lu\n", __func__, rate);
-
- /*
- * The EMC clock rate is twice the bus rate, and the bus rate is
- * measured in kHz
- */
- rate = rate / 2 / 1000;
-
- for (i = 0; i < pdata->num_tables; i++) {
- if (pdata->tables[i].rate >= rate &&
- (pdata->tables[i].rate - rate) < distance) {
- distance = pdata->tables[i].rate - rate;
- best = i;
- }
- }
-
- if (best < 0)
- return -EINVAL;
-
- pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
-
- return pdata->tables[best].rate * 2 * 1000;
-}
-
-/*
- * 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
- */
-int tegra_emc_set_rate(unsigned long rate)
-{
- struct tegra_emc_pdata *pdata;
- int i;
- int j;
-
- if (!emc_pdev)
- return -EINVAL;
-
- pdata = emc_pdev->dev.platform_data;
-
- /*
- * The EMC clock rate is twice the bus rate, and the bus rate is
- * measured in kHz
- */
- rate = rate / 2 / 1000;
-
- for (i = 0; i < pdata->num_tables; i++)
- if (pdata->tables[i].rate == rate)
- break;
-
- if (i >= pdata->num_tables)
- return -EINVAL;
-
- pr_debug("%s: setting to %lu\n", __func__, rate);
-
- for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
-
- emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
-
- return 0;
-}
-
-#ifdef CONFIG_OF
-static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
-{
- struct device_node *iter;
- u32 reg;
-
- for_each_child_of_node(np, iter) {
- if (of_property_read_u32(iter, "nvidia,ram-code", &reg))
- continue;
- if (reg == tegra_bct_strapping)
- return of_node_get(iter);
- }
-
- return NULL;
-}
-
-static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
- struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *tnp, *iter;
- struct tegra_emc_pdata *pdata;
- int ret, i, num_tables;
-
- if (!np)
- return NULL;
-
- if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
- tnp = tegra_emc_ramcode_devnode(np);
- if (!tnp)
- dev_warn(&pdev->dev,
- "can't find emc table for ram-code 0x%02x\n",
- tegra_bct_strapping);
- } else
- tnp = of_node_get(np);
-
- if (!tnp)
- return NULL;
-
- num_tables = 0;
- for_each_child_of_node(tnp, iter)
- if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
- num_tables++;
-
- if (!num_tables) {
- pdata = NULL;
- goto out;
- }
-
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- pdata->tables = devm_kzalloc(&pdev->dev,
- sizeof(*pdata->tables) * num_tables,
- GFP_KERNEL);
-
- i = 0;
- for_each_child_of_node(tnp, iter) {
- u32 prop;
-
- ret = of_property_read_u32(iter, "clock-frequency", &prop);
- if (ret) {
- dev_err(&pdev->dev, "no clock-frequency in %s\n",
- iter->full_name);
- continue;
- }
- pdata->tables[i].rate = prop;
-
- ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
- pdata->tables[i].regs,
- TEGRA_EMC_NUM_REGS);
- if (ret) {
- dev_err(&pdev->dev,
- "malformed emc-registers property in %s\n",
- iter->full_name);
- continue;
- }
-
- i++;
- }
- pdata->num_tables = i;
-
-out:
- of_node_put(tnp);
- return pdata;
-}
-#else
-static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
- struct platform_device *pdev)
-{
- return NULL;
-}
-#endif
-
-static struct tegra_emc_pdata *tegra_emc_fill_pdata(struct platform_device *pdev)
-{
- struct clk *c = clk_get_sys(NULL, "emc");
- struct tegra_emc_pdata *pdata;
- unsigned long khz;
- int i;
-
- WARN_ON(pdev->dev.platform_data);
- BUG_ON(IS_ERR(c));
-
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables),
- GFP_KERNEL);
-
- pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000;
-
- for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
- pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
-
- pdata->num_tables = 1;
-
- khz = pdata->tables[0].rate;
- dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
- "%ld kHz mem\n", khz * 2, khz);
-
- return pdata;
-}
-
-static int tegra_emc_probe(struct platform_device *pdev)
-{
- struct tegra_emc_pdata *pdata;
- struct resource *res;
-
- if (!emc_enable) {
- dev_err(&pdev->dev, "disabled per module parameter\n");
- return -ENODEV;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- emc_regbase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(emc_regbase))
- return PTR_ERR(emc_regbase);
-
- pdata = pdev->dev.platform_data;
-
- if (!pdata)
- pdata = tegra_emc_dt_parse_pdata(pdev);
-
- if (!pdata)
- pdata = tegra_emc_fill_pdata(pdev);
-
- pdev->dev.platform_data = pdata;
-
- emc_pdev = pdev;
-
- return 0;
-}
-
-static struct of_device_id tegra_emc_of_match[] = {
- { .compatible = "nvidia,tegra20-emc", },
- { },
-};
-
-static struct platform_driver tegra_emc_driver = {
- .driver = {
- .name = "tegra-emc",
- .owner = THIS_MODULE,
- .of_match_table = tegra_emc_of_match,
- },
- .probe = tegra_emc_probe,
-};
-
-static int __init tegra_emc_init(void)
-{
- return platform_driver_register(&tegra_emc_driver);
-}
-device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
deleted file mode 100644
index f61409b54cb..00000000000
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc.
- *
- * Author:
- * Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
-#define __MACH_TEGRA_TEGRA2_EMC_H
-
-int tegra_emc_set_rate(unsigned long rate);
-long tegra_emc_round_rate(unsigned long rate);
-
-#endif