aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2013-08-21 13:16:55 -0400
committerKevin Hilman <khilman@linaro.org>2013-08-21 13:17:18 -0400
commitbfa664f21b0357f2ad9cdf519f594ece36ec8f64 (patch)
treef377028eba58633d917d65c1141977b2e8ca9529 /arch/arm
parent5515d9981f5f30e82d096921f86ba016911c9ea8 (diff)
parentb4f173752a56187bd55752b0474429202f2ab1d3 (diff)
Merge tag 'tegra-for-3.12-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/soc
From: Stephen Warren: ARM: tegra: core SoC enhancements for 3.12 This branch includes a number of enhancements to core SoC support for Tegra devices. The major new features are: * Adds a new CPU-power-gated cpuidle state for Tegra114. * Adds initial system suspend support for Tegra114, initially supporting just CPU-power-gating during suspend. * Adds "LP1" suspend mode support for all of Tegra20/30/114. This mode both gates CPU power, and places the DRAM into self-refresh mode. * A new DT-driven PCIe driver to Tegra20/30. The driver is also moved from arch/arm/mach-tegra/ to drivers/pci/host/. The PCIe driver work depends on the following tag from Thomas Petazzoni: git://git.infradead.org/linux-mvebu.git mis-3.12.2 ... which is merged into the middle of this pull request. * tag 'tegra-for-3.12-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra: (33 commits) ARM: tegra: disable LP2 cpuidle state if PCIe is enabled MAINTAINERS: Add myself as Tegra PCIe maintainer PCI: tegra: set up PADS_REFCLK_CFG1 PCI: tegra: Add Tegra 30 PCIe support PCI: tegra: Move PCIe driver to drivers/pci/host PCI: msi: add default MSI operations for !HAVE_GENERIC_HARDIRQS platforms ARM: tegra: add LP1 suspend support for Tegra114 ARM: tegra: add LP1 suspend support for Tegra20 ARM: tegra: add LP1 suspend support for Tegra30 ARM: tegra: add common LP1 suspend support clk: tegra114: add LP1 suspend/resume support ARM: tegra: config the polarity of the request of sys clock ARM: tegra: add common resume handling code for LP1 resuming ARM: pci: add ->add_bus() and ->remove_bus() hooks to hw_pci of: pci: add registry of MSI chips PCI: Introduce new MSI chip infrastructure PCI: remove ARCH_SUPPORTS_MSI kconfig option PCI: use weak functions for MSI arch-specific functions ARM: tegra: unify Tegra's Kconfig a bit more ARM: tegra: remove the limitation that Tegra114 can't support suspend ... Signed-off-by: Kevin Hilman <khilman@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/include/asm/mach/pci.h4
-rw-r--r--arch/arm/kernel/bios32.c16
-rw-r--r--arch/arm/mach-tegra/Kconfig29
-rw-r--r--arch/arm/mach-tegra/Makefile6
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c89
-rw-r--r--arch/arm/mach-tegra/board.h8
-rw-r--r--arch/arm/mach-tegra/common.h1
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c51
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra20.c12
-rw-r--r--arch/arm/mach-tegra/cpuidle.c10
-rw-r--r--arch/arm/mach-tegra/cpuidle.h1
-rw-r--r--arch/arm/mach-tegra/flowctrl.c2
-rw-r--r--arch/arm/mach-tegra/flowctrl.h9
-rw-r--r--arch/arm/mach-tegra/headsmp.S3
-rw-r--r--arch/arm/mach-tegra/hotplug.c13
-rw-r--r--arch/arm/mach-tegra/iomap.h11
-rw-r--r--arch/arm/mach-tegra/irq.c40
-rw-r--r--arch/arm/mach-tegra/pcie.c886
-rw-r--r--arch/arm/mach-tegra/platsmp.c1
-rw-r--r--arch/arm/mach-tegra/pm-tegra20.c34
-rw-r--r--arch/arm/mach-tegra/pm-tegra30.c34
-rw-r--r--arch/arm/mach-tegra/pm.c148
-rw-r--r--arch/arm/mach-tegra/pm.h12
-rw-r--r--arch/arm/mach-tegra/pmc.c53
-rw-r--r--arch/arm/mach-tegra/pmc.h3
-rw-r--r--arch/arm/mach-tegra/reset-handler.S21
-rw-r--r--arch/arm/mach-tegra/reset.c2
-rw-r--r--arch/arm/mach-tegra/reset.h4
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S297
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S616
-rw-r--r--arch/arm/mach-tegra/sleep.S37
-rw-r--r--arch/arm/mach-tegra/sleep.h14
-rw-r--r--arch/arm/mach-tegra/tegra.c24
34 files changed, 1422 insertions, 1070 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50eada8260a9..a3267d795c77 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -441,7 +441,6 @@ config ARCH_NETX
441config ARCH_IOP13XX 441config ARCH_IOP13XX
442 bool "IOP13xx-based" 442 bool "IOP13xx-based"
443 depends on MMU 443 depends on MMU
444 select ARCH_SUPPORTS_MSI
445 select CPU_XSC3 444 select CPU_XSC3
446 select NEED_MACH_MEMORY_H 445 select NEED_MACH_MEMORY_H
447 select NEED_RET_TO_USER 446 select NEED_RET_TO_USER
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index a1c90d7feb0e..454d642a4070 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -36,6 +36,8 @@ struct hw_pci {
36 resource_size_t start, 36 resource_size_t start,
37 resource_size_t size, 37 resource_size_t size,
38 resource_size_t align); 38 resource_size_t align);
39 void (*add_bus)(struct pci_bus *bus);
40 void (*remove_bus)(struct pci_bus *bus);
39}; 41};
40 42
41/* 43/*
@@ -63,6 +65,8 @@ struct pci_sys_data {
63 resource_size_t start, 65 resource_size_t start,
64 resource_size_t size, 66 resource_size_t size,
65 resource_size_t align); 67 resource_size_t align);
68 void (*add_bus)(struct pci_bus *bus);
69 void (*remove_bus)(struct pci_bus *bus);
66 void *private_data; /* platform controller private data */ 70 void *private_data; /* platform controller private data */
67}; 71};
68 72
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 261fcc826169..1ec9c8701c26 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -363,6 +363,20 @@ void pcibios_fixup_bus(struct pci_bus *bus)
363} 363}
364EXPORT_SYMBOL(pcibios_fixup_bus); 364EXPORT_SYMBOL(pcibios_fixup_bus);
365 365
366void pcibios_add_bus(struct pci_bus *bus)
367{
368 struct pci_sys_data *sys = bus->sysdata;
369 if (sys->add_bus)
370 sys->add_bus(bus);
371}
372
373void pcibios_remove_bus(struct pci_bus *bus)
374{
375 struct pci_sys_data *sys = bus->sysdata;
376 if (sys->remove_bus)
377 sys->remove_bus(bus);
378}
379
366/* 380/*
367 * Swizzle the device pin each time we cross a bridge. If a platform does 381 * Swizzle the device pin each time we cross a bridge. If a platform does
368 * not provide a swizzle function, we perform the standard PCI swizzling. 382 * not provide a swizzle function, we perform the standard PCI swizzling.
@@ -464,6 +478,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
464 sys->swizzle = hw->swizzle; 478 sys->swizzle = hw->swizzle;
465 sys->map_irq = hw->map_irq; 479 sys->map_irq = hw->map_irq;
466 sys->align_resource = hw->align_resource; 480 sys->align_resource = hw->align_resource;
481 sys->add_bus = hw->add_bus;
482 sys->remove_bus = hw->remove_bus;
467 INIT_LIST_HEAD(&sys->resources); 483 INIT_LIST_HEAD(&sys->resources);
468 484
469 if (hw->private_data) 485 if (hw->private_data)
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index ef3a8da49b2d..def056493260 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -2,19 +2,27 @@ config ARCH_TEGRA
2 bool "NVIDIA Tegra" if ARCH_MULTI_V7 2 bool "NVIDIA Tegra" if ARCH_MULTI_V7
3 select ARCH_HAS_CPUFREQ 3 select ARCH_HAS_CPUFREQ
4 select ARCH_REQUIRE_GPIOLIB 4 select ARCH_REQUIRE_GPIOLIB
5 select ARM_GIC
5 select CLKDEV_LOOKUP 6 select CLKDEV_LOOKUP
6 select CLKSRC_MMIO 7 select CLKSRC_MMIO
7 select CLKSRC_OF 8 select CLKSRC_OF
8 select COMMON_CLK 9 select COMMON_CLK
10 select CPU_V7
9 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
10 select HAVE_ARM_SCU if SMP 12 select HAVE_ARM_SCU if SMP
11 select HAVE_ARM_TWD if LOCAL_TIMERS 13 select HAVE_ARM_TWD if LOCAL_TIMERS
12 select HAVE_CLK 14 select HAVE_CLK
13 select HAVE_SMP 15 select HAVE_SMP
14 select MIGHT_HAVE_CACHE_L2X0 16 select MIGHT_HAVE_CACHE_L2X0
17 select PINCTRL
15 select SOC_BUS 18 select SOC_BUS
16 select SPARSE_IRQ 19 select SPARSE_IRQ
20 select USB_ARCH_HAS_EHCI if USB_SUPPORT
21 select USB_ULPI if USB_PHY
22 select USB_ULPI_VIEWPORT if USB_PHY
17 select USE_OF 23 select USE_OF
24 select MIGHT_HAVE_PCI
25 select ARCH_SUPPORTS_MSI
18 help 26 help
19 This enables support for NVIDIA Tegra based systems. 27 This enables support for NVIDIA Tegra based systems.
20 28
@@ -27,15 +35,9 @@ config ARCH_TEGRA_2x_SOC
27 select ARM_ERRATA_720789 35 select ARM_ERRATA_720789
28 select ARM_ERRATA_754327 if SMP 36 select ARM_ERRATA_754327 if SMP
29 select ARM_ERRATA_764369 if SMP 37 select ARM_ERRATA_764369 if SMP
30 select ARM_GIC
31 select CPU_V7
32 select PINCTRL
33 select PINCTRL_TEGRA20 38 select PINCTRL_TEGRA20
34 select PL310_ERRATA_727915 if CACHE_L2X0 39 select PL310_ERRATA_727915 if CACHE_L2X0
35 select PL310_ERRATA_769419 if CACHE_L2X0 40 select PL310_ERRATA_769419 if CACHE_L2X0
36 select USB_ARCH_HAS_EHCI if USB_SUPPORT
37 select USB_ULPI if USB_PHY
38 select USB_ULPI_VIEWPORT if USB_PHY
39 help 41 help
40 Support for NVIDIA Tegra AP20 and T20 processors, based on the 42 Support for NVIDIA Tegra AP20 and T20 processors, based on the
41 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller 43 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -44,14 +46,8 @@ config ARCH_TEGRA_3x_SOC
44 bool "Enable support for Tegra30 family" 46 bool "Enable support for Tegra30 family"
45 select ARM_ERRATA_754322 47 select ARM_ERRATA_754322
46 select ARM_ERRATA_764369 if SMP 48 select ARM_ERRATA_764369 if SMP
47 select ARM_GIC
48 select CPU_V7
49 select PINCTRL
50 select PINCTRL_TEGRA30 49 select PINCTRL_TEGRA30
51 select PL310_ERRATA_769419 if CACHE_L2X0 50 select PL310_ERRATA_769419 if CACHE_L2X0
52 select USB_ARCH_HAS_EHCI if USB_SUPPORT
53 select USB_ULPI if USB_PHY
54 select USB_ULPI_VIEWPORT if USB_PHY
55 help 51 help
56 Support for NVIDIA Tegra T30 processor family, based on the 52 Support for NVIDIA Tegra T30 processor family, based on the
57 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller 53 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -59,20 +55,13 @@ config ARCH_TEGRA_3x_SOC
59config ARCH_TEGRA_114_SOC 55config ARCH_TEGRA_114_SOC
60 bool "Enable support for Tegra114 family" 56 bool "Enable support for Tegra114 family"
61 select HAVE_ARM_ARCH_TIMER 57 select HAVE_ARM_ARCH_TIMER
62 select ARM_GIC 58 select ARM_ERRATA_798181
63 select ARM_L1_CACHE_SHIFT_6 59 select ARM_L1_CACHE_SHIFT_6
64 select CPU_V7
65 select PINCTRL
66 select PINCTRL_TEGRA114 60 select PINCTRL_TEGRA114
67 help 61 help
68 Support for NVIDIA Tegra T114 processor family, based on the 62 Support for NVIDIA Tegra T114 processor family, based on the
69 ARM CortexA15MP CPU 63 ARM CortexA15MP CPU
70 64
71config TEGRA_PCI
72 bool "PCI Express support"
73 depends on ARCH_TEGRA_2x_SOC
74 select PCI
75
76config TEGRA_AHB 65config TEGRA_AHB
77 bool "Enable AHB driver for NVIDIA Tegra SoCs" 66 bool "Enable AHB driver for NVIDIA Tegra SoCs"
78 default y 67 default y
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 98b184efc110..e7e5f45c6558 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -17,24 +17,24 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 17obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 18obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
19obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o 19obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
20obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
20ifeq ($(CONFIG_CPU_IDLE),y) 21ifeq ($(CONFIG_CPU_IDLE),y)
21obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o 22obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o
22endif 23endif
23obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o 24obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o
24obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o 25obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
26obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o
25ifeq ($(CONFIG_CPU_IDLE),y) 27ifeq ($(CONFIG_CPU_IDLE),y)
26obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o 28obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
27endif 29endif
28obj-$(CONFIG_SMP) += platsmp.o headsmp.o 30obj-$(CONFIG_SMP) += platsmp.o headsmp.o
29obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 31obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
30obj-$(CONFIG_TEGRA_PCI) += pcie.o
31 32
32obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o 33obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o
33obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o 34obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o
35obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o
34ifeq ($(CONFIG_CPU_IDLE),y) 36ifeq ($(CONFIG_CPU_IDLE),y)
35obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o 37obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
36endif 38endif
37 39
38obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o
39
40obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o 40obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-paz00.o
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
deleted file mode 100644
index 035b240b9e15..000000000000
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ /dev/null
@@ -1,89 +0,0 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-pcie.c
3 *
4 * Copyright (C) 2010 CompuLab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/gpio.h>
20#include <linux/err.h>
21#include <linux/of_gpio.h>
22#include <linux/regulator/consumer.h>
23
24#include <asm/mach-types.h>
25
26#include "board.h"
27
28#ifdef CONFIG_TEGRA_PCI
29
30int __init harmony_pcie_init(void)
31{
32 struct device_node *np;
33 int en_vdd_1v05;
34 struct regulator *regulator = NULL;
35 int err;
36
37 np = of_find_node_by_path("/regulators/regulator@3");
38 if (!np) {
39 pr_err("%s: of_find_node_by_path failed\n", __func__);
40 return -ENODEV;
41 }
42
43 en_vdd_1v05 = of_get_named_gpio(np, "gpio", 0);
44 if (en_vdd_1v05 < 0) {
45 pr_err("%s: of_get_named_gpio failed: %d\n", __func__,
46 en_vdd_1v05);
47 return en_vdd_1v05;
48 }
49
50 err = gpio_request(en_vdd_1v05, "EN_VDD_1V05");
51 if (err) {
52 pr_err("%s: gpio_request failed: %d\n", __func__, err);
53 return err;
54 }
55
56 gpio_direction_output(en_vdd_1v05, 1);
57
58 regulator = regulator_get(NULL, "vdd_ldo0,vddio_pex_clk");
59 if (IS_ERR(regulator)) {
60 err = PTR_ERR(regulator);
61 pr_err("%s: regulator_get failed: %d\n", __func__, err);
62 goto err_reg;
63 }
64
65 err = regulator_enable(regulator);
66 if (err) {
67 pr_err("%s: regulator_enable failed: %d\n", __func__, err);
68 goto err_en;
69 }
70
71 err = tegra_pcie_init(true, true);
72 if (err) {
73 pr_err("%s: tegra_pcie_init failed: %d\n", __func__, err);
74 goto err_pcie;
75 }
76
77 return 0;
78
79err_pcie:
80 regulator_disable(regulator);
81err_en:
82 regulator_put(regulator);
83err_reg:
84 gpio_free(en_vdd_1v05);
85
86 return err;
87}
88
89#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 9a6659fe2dc2..db6810dc0b3d 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -31,7 +31,6 @@ void __init tegra_init_early(void);
31void __init tegra_map_common_io(void); 31void __init tegra_map_common_io(void);
32void __init tegra_init_irq(void); 32void __init tegra_init_irq(void);
33void __init tegra_dt_init_irq(void); 33void __init tegra_dt_init_irq(void);
34int __init tegra_pcie_init(bool init_port0, bool init_port1);
35 34
36void tegra_init_late(void); 35void tegra_init_late(void);
37 36
@@ -48,13 +47,6 @@ int __init tegra_powergate_debugfs_init(void);
48static inline int tegra_powergate_debugfs_init(void) { return 0; } 47static inline int tegra_powergate_debugfs_init(void) { return 0; }
49#endif 48#endif
50 49
51int __init harmony_regulator_init(void);
52#ifdef CONFIG_TEGRA_PCI
53int __init harmony_pcie_init(void);
54#else
55static inline int harmony_pcie_init(void) { return 0; }
56#endif
57
58void __init tegra_paz00_wifikill_init(void); 50void __init tegra_paz00_wifikill_init(void);
59 51
60#endif 52#endif
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
index 32f8eb3fe344..5900cc44f780 100644
--- a/arch/arm/mach-tegra/common.h
+++ b/arch/arm/mach-tegra/common.h
@@ -2,4 +2,3 @@ extern struct smp_operations tegra_smp_ops;
2 2
3extern int tegra_cpu_kill(unsigned int cpu); 3extern int tegra_cpu_kill(unsigned int cpu);
4extern void tegra_cpu_die(unsigned int cpu); 4extern void tegra_cpu_die(unsigned int cpu);
5extern int tegra_cpu_disable(unsigned int cpu);
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index 1d1c6023f4a2..e0b87300243d 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -17,15 +17,64 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <linux/cpu_pm.h>
21#include <linux/clockchips.h>
20 22
21#include <asm/cpuidle.h> 23#include <asm/cpuidle.h>
24#include <asm/suspend.h>
25#include <asm/smp_plat.h>
26
27#include "pm.h"
28#include "sleep.h"
29
30#ifdef CONFIG_PM_SLEEP
31#define TEGRA114_MAX_STATES 2
32#else
33#define TEGRA114_MAX_STATES 1
34#endif
35
36#ifdef CONFIG_PM_SLEEP
37static int tegra114_idle_power_down(struct cpuidle_device *dev,
38 struct cpuidle_driver *drv,
39 int index)
40{
41 local_fiq_disable();
42
43 tegra_set_cpu_in_lp2();
44 cpu_pm_enter();
45
46 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
47
48 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
49
50 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
51
52 cpu_pm_exit();
53 tegra_clear_cpu_in_lp2();
54
55 local_fiq_enable();
56
57 return index;
58}
59#endif
22 60
23static struct cpuidle_driver tegra_idle_driver = { 61static struct cpuidle_driver tegra_idle_driver = {
24 .name = "tegra_idle", 62 .name = "tegra_idle",
25 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
26 .state_count = 1, 64 .state_count = TEGRA114_MAX_STATES,
27 .states = { 65 .states = {
28 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), 66 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
67#ifdef CONFIG_PM_SLEEP
68 [1] = {
69 .enter = tegra114_idle_power_down,
70 .exit_latency = 500,
71 .target_residency = 1000,
72 .power_usage = 0,
73 .flags = CPUIDLE_FLAG_TIME_VALID,
74 .name = "powered-down",
75 .desc = "CPU power gated",
76 },
77#endif
29 }, 78 },
30}; 79};
31 80
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index 706aa4215c36..b82dcaee2ef4 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -211,6 +211,18 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
211} 211}
212#endif 212#endif
213 213
214/*
215 * Tegra20 HW appears to have a bug such that PCIe device interrupts, whether
216 * they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around
217 * this, simply disable LP2 if the PCI driver and DT node are both enabled.
218 */
219void tegra20_cpuidle_pcie_irqs_in_use(void)
220{
221 pr_info_once(
222 "Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
223 tegra_idle_driver.states[1].disabled = true;
224}
225
214int __init tegra20_cpuidle_init(void) 226int __init tegra20_cpuidle_init(void)
215{ 227{
216 return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); 228 return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index e85973cef037..0961dfcf83a4 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -44,3 +44,13 @@ void __init tegra_cpuidle_init(void)
44 break; 44 break;
45 } 45 }
46} 46}
47
48void tegra_cpuidle_pcie_irqs_in_use(void)
49{
50 switch (tegra_chip_id) {
51 case TEGRA20:
52 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
53 tegra20_cpuidle_pcie_irqs_in_use();
54 break;
55 }
56}
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
index 9ec2c1ab0fa4..c017dab60ffa 100644
--- a/arch/arm/mach-tegra/cpuidle.h
+++ b/arch/arm/mach-tegra/cpuidle.h
@@ -19,6 +19,7 @@
19 19
20#ifdef CONFIG_CPU_IDLE 20#ifdef CONFIG_CPU_IDLE
21int tegra20_cpuidle_init(void); 21int tegra20_cpuidle_init(void);
22void tegra20_cpuidle_pcie_irqs_in_use(void);
22int tegra30_cpuidle_init(void); 23int tegra30_cpuidle_init(void);
23int tegra114_cpuidle_init(void); 24int tegra114_cpuidle_init(void);
24void tegra_cpuidle_init(void); 25void tegra_cpuidle_init(void);
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index b477ef310dcd..5348543382bf 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -86,6 +86,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
86 reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid; 86 reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
87 break; 87 break;
88 case TEGRA30: 88 case TEGRA30:
89 case TEGRA114:
89 /* clear wfe bitmap */ 90 /* clear wfe bitmap */
90 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; 91 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
91 /* clear wfi bitmap */ 92 /* clear wfi bitmap */
@@ -123,6 +124,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
123 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP; 124 reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
124 break; 125 break;
125 case TEGRA30: 126 case TEGRA30:
127 case TEGRA114:
126 /* clear wfe bitmap */ 128 /* clear wfe bitmap */
127 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; 129 reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
128 /* clear wfi bitmap */ 130 /* clear wfi bitmap */
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
index 7a29bae799a7..c89aac60a143 100644
--- a/arch/arm/mach-tegra/flowctrl.h
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -28,9 +28,18 @@
28#define FLOW_CTRL_SCLK_RESUME (1 << 27) 28#define FLOW_CTRL_SCLK_RESUME (1 << 27)
29#define FLOW_CTRL_HALT_CPU_IRQ (1 << 10) 29#define FLOW_CTRL_HALT_CPU_IRQ (1 << 10)
30#define FLOW_CTRL_HALT_CPU_FIQ (1 << 8) 30#define FLOW_CTRL_HALT_CPU_FIQ (1 << 8)
31#define FLOW_CTRL_HALT_LIC_IRQ (1 << 11)
32#define FLOW_CTRL_HALT_LIC_FIQ (1 << 10)
33#define FLOW_CTRL_HALT_GIC_IRQ (1 << 9)
34#define FLOW_CTRL_HALT_GIC_FIQ (1 << 8)
31#define FLOW_CTRL_CPU0_CSR 0x8 35#define FLOW_CTRL_CPU0_CSR 0x8
32#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15) 36#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15)
33#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14) 37#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14)
38#define FLOW_CTRL_CSR_ENABLE_EXT_CRAIL (1 << 13)
39#define FLOW_CTRL_CSR_ENABLE_EXT_NCPU (1 << 12)
40#define FLOW_CTRL_CSR_ENABLE_EXT_MASK ( \
41 FLOW_CTRL_CSR_ENABLE_EXT_NCPU | \
42 FLOW_CTRL_CSR_ENABLE_EXT_CRAIL)
34#define FLOW_CTRL_CSR_ENABLE (1 << 0) 43#define FLOW_CTRL_CSR_ENABLE (1 << 0)
35#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 44#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
36#define FLOW_CTRL_CPU1_CSR 0x18 45#define FLOW_CTRL_CPU1_CSR 0x18
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 045c16f2dd51..2072e7322c39 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -6,6 +6,7 @@
6 .section ".text.head", "ax" 6 .section ".text.head", "ax"
7 7
8ENTRY(tegra_secondary_startup) 8ENTRY(tegra_secondary_startup)
9 bl v7_invalidate_l1 9 check_cpu_part_num 0xc09, r8, r9
10 bleq v7_invalidate_l1
10 b secondary_startup 11 b secondary_startup
11ENDPROC(tegra_secondary_startup) 12ENDPROC(tegra_secondary_startup)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index a52c10e0a857..04de2e860923 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -37,7 +37,7 @@ int tegra_cpu_kill(unsigned cpu)
37void __ref tegra_cpu_die(unsigned int cpu) 37void __ref tegra_cpu_die(unsigned int cpu)
38{ 38{
39 /* Clean L1 data cache */ 39 /* Clean L1 data cache */
40 tegra_disable_clean_inv_dcache(); 40 tegra_disable_clean_inv_dcache(TEGRA_FLUSH_CACHE_LOUIS);
41 41
42 /* Shut down the current CPU. */ 42 /* Shut down the current CPU. */
43 tegra_hotplug_shutdown(); 43 tegra_hotplug_shutdown();
@@ -46,17 +46,6 @@ void __ref tegra_cpu_die(unsigned int cpu)
46 BUG(); 46 BUG();
47} 47}
48 48
49int tegra_cpu_disable(unsigned int cpu)
50{
51 switch (tegra_chip_id) {
52 case TEGRA20:
53 case TEGRA30:
54 return cpu == 0 ? -EPERM : 0;
55 default:
56 return 0;
57 }
58}
59
60void __init tegra_hotplug_init(void) 49void __init tegra_hotplug_init(void)
61{ 50{
62 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) 51 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
index 399fbca27102..3f5fa0749bde 100644
--- a/arch/arm/mach-tegra/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -24,6 +24,8 @@
24#define TEGRA_IRAM_BASE 0x40000000 24#define TEGRA_IRAM_BASE 0x40000000
25#define TEGRA_IRAM_SIZE SZ_256K 25#define TEGRA_IRAM_SIZE SZ_256K
26 26
27#define TEGRA_IRAM_CODE_AREA (TEGRA_IRAM_BASE + SZ_4K)
28
27#define TEGRA_HOST1X_BASE 0x50000000 29#define TEGRA_HOST1X_BASE 0x50000000
28#define TEGRA_HOST1X_SIZE 0x24000 30#define TEGRA_HOST1X_SIZE 0x24000
29 31
@@ -237,6 +239,12 @@
237#define TEGRA_KFUSE_BASE 0x7000FC00 239#define TEGRA_KFUSE_BASE 0x7000FC00
238#define TEGRA_KFUSE_SIZE SZ_1K 240#define TEGRA_KFUSE_SIZE SZ_1K
239 241
242#define TEGRA_EMC0_BASE 0x7001A000
243#define TEGRA_EMC0_SIZE SZ_2K
244
245#define TEGRA_EMC1_BASE 0x7001A800
246#define TEGRA_EMC1_SIZE SZ_2K
247
240#define TEGRA_CSITE_BASE 0x70040000 248#define TEGRA_CSITE_BASE 0x70040000
241#define TEGRA_CSITE_SIZE SZ_256K 249#define TEGRA_CSITE_SIZE SZ_256K
242 250
@@ -278,9 +286,6 @@
278#define IO_APB_VIRT IOMEM(0xFE300000) 286#define IO_APB_VIRT IOMEM(0xFE300000)
279#define IO_APB_SIZE SZ_1M 287#define IO_APB_SIZE SZ_1M
280 288
281#define TEGRA_PCIE_BASE 0x80000000
282#define TEGRA_PCIE_IO_BASE (TEGRA_PCIE_BASE + SZ_4M)
283
284#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) 289#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
285#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) 290#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
286 291
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 0de4eed1493d..1a74d562dca1 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -18,10 +18,12 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/cpu_pm.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22#include <linux/irq.h> 23#include <linux/irq.h>
23#include <linux/io.h> 24#include <linux/io.h>
24#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/of_address.h>
25#include <linux/irqchip/arm-gic.h> 27#include <linux/irqchip/arm-gic.h>
26#include <linux/syscore_ops.h> 28#include <linux/syscore_ops.h>
27 29
@@ -65,6 +67,7 @@ static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
65static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS]; 67static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];
66 68
67static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; 69static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
70static void __iomem *tegra_gic_cpu_base;
68#endif 71#endif
69 72
70bool tegra_pending_sgi(void) 73bool tegra_pending_sgi(void)
@@ -213,8 +216,43 @@ int tegra_legacy_irq_syscore_init(void)
213 216
214 return 0; 217 return 0;
215} 218}
219
220static int tegra_gic_notifier(struct notifier_block *self,
221 unsigned long cmd, void *v)
222{
223 switch (cmd) {
224 case CPU_PM_ENTER:
225 writel_relaxed(0x1E0, tegra_gic_cpu_base + GIC_CPU_CTRL);
226 break;
227 }
228
229 return NOTIFY_OK;
230}
231
232static struct notifier_block tegra_gic_notifier_block = {
233 .notifier_call = tegra_gic_notifier,
234};
235
236static const struct of_device_id tegra114_dt_gic_match[] __initconst = {
237 { .compatible = "arm,cortex-a15-gic" },
238 { }
239};
240
241static void tegra114_gic_cpu_pm_registration(void)
242{
243 struct device_node *dn;
244
245 dn = of_find_matching_node(NULL, tegra114_dt_gic_match);
246 if (!dn)
247 return;
248
249 tegra_gic_cpu_base = of_iomap(dn, 1);
250
251 cpu_pm_register_notifier(&tegra_gic_notifier_block);
252}
216#else 253#else
217#define tegra_set_wake NULL 254#define tegra_set_wake NULL
255static void tegra114_gic_cpu_pm_registration(void) { }
218#endif 256#endif
219 257
220void __init tegra_init_irq(void) 258void __init tegra_init_irq(void)
@@ -252,4 +290,6 @@ void __init tegra_init_irq(void)
252 if (!of_have_populated_dt()) 290 if (!of_have_populated_dt())
253 gic_init(0, 29, distbase, 291 gic_init(0, 29, distbase,
254 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 292 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
293
294 tegra114_gic_cpu_pm_registration();
255} 295}
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
deleted file mode 100644
index 46144a19a7e7..000000000000
--- a/arch/arm/mach-tegra/pcie.c
+++ /dev/null
@@ -1,886 +0,0 @@
1/*
2 * arch/arm/mach-tegra/pci.c
3 *
4 * PCIe host controller driver for TEGRA(2) SOCs
5 *
6 * Copyright (c) 2010, CompuLab, Ltd.
7 * Author: Mike Rapoport <mike@compulab.co.il>
8 *
9 * Based on NVIDIA PCIe driver
10 * Copyright (c) 2008-2009, NVIDIA Corporation.
11 *
12 * Bits taken from arch/arm/mach-dove/pcie.c
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 */
28
29#include <linux/kernel.h>
30#include <linux/pci.h>
31#include <linux/interrupt.h>
32#include <linux/irq.h>
33#include <linux/clk.h>
34#include <linux/delay.h>
35#include <linux/export.h>
36#include <linux/clk/tegra.h>
37#include <linux/tegra-powergate.h>
38
39#include <asm/sizes.h>
40#include <asm/mach/pci.h>
41
42#include "board.h"
43#include "iomap.h"
44
45/* Hack - need to parse this from DT */
46#define INT_PCIE_INTR 130
47
48/* register definitions */
49#define AFI_OFFSET 0x3800
50#define PADS_OFFSET 0x3000
51#define RP0_OFFSET 0x0000
52#define RP1_OFFSET 0x1000
53
54#define AFI_AXI_BAR0_SZ 0x00
55#define AFI_AXI_BAR1_SZ 0x04
56#define AFI_AXI_BAR2_SZ 0x08
57#define AFI_AXI_BAR3_SZ 0x0c
58#define AFI_AXI_BAR4_SZ 0x10
59#define AFI_AXI_BAR5_SZ 0x14
60
61#define AFI_AXI_BAR0_START 0x18
62#define AFI_AXI_BAR1_START 0x1c
63#define AFI_AXI_BAR2_START 0x20
64#define AFI_AXI_BAR3_START 0x24
65#define AFI_AXI_BAR4_START 0x28
66#define AFI_AXI_BAR5_START 0x2c
67
68#define AFI_FPCI_BAR0 0x30
69#define AFI_FPCI_BAR1 0x34
70#define AFI_FPCI_BAR2 0x38
71#define AFI_FPCI_BAR3 0x3c
72#define AFI_FPCI_BAR4 0x40
73#define AFI_FPCI_BAR5 0x44
74
75#define AFI_CACHE_BAR0_SZ 0x48
76#define AFI_CACHE_BAR0_ST 0x4c
77#define AFI_CACHE_BAR1_SZ 0x50
78#define AFI_CACHE_BAR1_ST 0x54
79
80#define AFI_MSI_BAR_SZ 0x60
81#define AFI_MSI_FPCI_BAR_ST 0x64
82#define AFI_MSI_AXI_BAR_ST 0x68
83
84#define AFI_CONFIGURATION 0xac
85#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
86
87#define AFI_FPCI_ERROR_MASKS 0xb0
88
89#define AFI_INTR_MASK 0xb4
90#define AFI_INTR_MASK_INT_MASK (1 << 0)
91#define AFI_INTR_MASK_MSI_MASK (1 << 8)
92
93#define AFI_INTR_CODE 0xb8
94#define AFI_INTR_CODE_MASK 0xf
95#define AFI_INTR_MASTER_ABORT 4
96#define AFI_INTR_LEGACY 6
97
98#define AFI_INTR_SIGNATURE 0xbc
99#define AFI_SM_INTR_ENABLE 0xc4
100
101#define AFI_AFI_INTR_ENABLE 0xc8
102#define AFI_INTR_EN_INI_SLVERR (1 << 0)
103#define AFI_INTR_EN_INI_DECERR (1 << 1)
104#define AFI_INTR_EN_TGT_SLVERR (1 << 2)
105#define AFI_INTR_EN_TGT_DECERR (1 << 3)
106#define AFI_INTR_EN_TGT_WRERR (1 << 4)
107#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
108#define AFI_INTR_EN_AXI_DECERR (1 << 6)
109#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
110
111#define AFI_PCIE_CONFIG 0x0f8
112#define AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE (1 << 1)
113#define AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE (1 << 2)
114#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
115#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
116#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
117
118#define AFI_FUSE 0x104
119#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
120
121#define AFI_PEX0_CTRL 0x110
122#define AFI_PEX1_CTRL 0x118
123#define AFI_PEX_CTRL_RST (1 << 0)
124#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
125
126#define RP_VEND_XP 0x00000F00
127#define RP_VEND_XP_DL_UP (1 << 30)
128
129#define RP_LINK_CONTROL_STATUS 0x00000090
130#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
131
132#define PADS_CTL_SEL 0x0000009C
133
134#define PADS_CTL 0x000000A0
135#define PADS_CTL_IDDQ_1L (1 << 0)
136#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
137#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
138
139#define PADS_PLL_CTL 0x000000B8
140#define PADS_PLL_CTL_RST_B4SM (1 << 1)
141#define PADS_PLL_CTL_LOCKDET (1 << 8)
142#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
143#define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0 << 16)
144#define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (1 << 16)
145#define PADS_PLL_CTL_REFCLK_EXTERNAL (2 << 16)
146#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
147#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
148#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
149
150/* PMC access is required for PCIE xclk (un)clamping */
151#define PMC_SCRATCH42 0x144
152#define PMC_SCRATCH42_PCX_CLAMP (1 << 0)
153
154static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
155
156#define pmc_writel(value, reg) \
157 __raw_writel(value, reg_pmc_base + (reg))
158#define pmc_readl(reg) \
159 __raw_readl(reg_pmc_base + (reg))
160
161/*
162 * Tegra2 defines 1GB in the AXI address map for PCIe.
163 *
164 * That address space is split into different regions, with sizes and
165 * offsets as follows:
166 *
167 * 0x80000000 - 0x80003fff - PCI controller registers
168 * 0x80004000 - 0x80103fff - PCI configuration space
169 * 0x80104000 - 0x80203fff - PCI extended configuration space
170 * 0x80203fff - 0x803fffff - unused
171 * 0x80400000 - 0x8040ffff - downstream IO
172 * 0x80410000 - 0x8fffffff - unused
173 * 0x90000000 - 0x9fffffff - non-prefetchable memory
174 * 0xa0000000 - 0xbfffffff - prefetchable memory
175 */
176#define PCIE_REGS_SZ SZ_16K
177#define PCIE_CFG_OFF PCIE_REGS_SZ
178#define PCIE_CFG_SZ SZ_1M
179#define PCIE_EXT_CFG_OFF (PCIE_CFG_SZ + PCIE_CFG_OFF)
180#define PCIE_EXT_CFG_SZ SZ_1M
181#define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
182
183#define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M)
184#define MEM_SIZE_0 SZ_128M
185#define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0)
186#define MEM_SIZE_1 SZ_128M
187#define PREFETCH_MEM_BASE_0 (MEM_BASE_1 + MEM_SIZE_1)
188#define PREFETCH_MEM_SIZE_0 SZ_128M
189#define PREFETCH_MEM_BASE_1 (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
190#define PREFETCH_MEM_SIZE_1 SZ_128M
191
192#define PCIE_CONF_BUS(b) ((b) << 16)
193#define PCIE_CONF_DEV(d) ((d) << 11)
194#define PCIE_CONF_FUNC(f) ((f) << 8)
195#define PCIE_CONF_REG(r) \
196 (((r) & ~0x3) | (((r) < 256) ? PCIE_CFG_OFF : PCIE_EXT_CFG_OFF))
197
198struct tegra_pcie_port {
199 int index;
200 u8 root_bus_nr;
201 void __iomem *base;
202
203 bool link_up;
204
205 char mem_space_name[16];
206 char prefetch_space_name[20];
207 struct resource res[2];
208};
209
210struct tegra_pcie_info {
211 struct tegra_pcie_port port[2];
212 int num_ports;
213
214 void __iomem *regs;
215 struct resource res_mmio;
216
217 struct clk *pex_clk;
218 struct clk *afi_clk;
219 struct clk *pcie_xclk;
220 struct clk *pll_e;
221};
222
223static struct tegra_pcie_info tegra_pcie;
224
225static inline void afi_writel(u32 value, unsigned long offset)
226{
227 writel(value, offset + AFI_OFFSET + tegra_pcie.regs);
228}
229
230static inline u32 afi_readl(unsigned long offset)
231{
232 return readl(offset + AFI_OFFSET + tegra_pcie.regs);
233}
234
235static inline void pads_writel(u32 value, unsigned long offset)
236{
237 writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
238}
239
240static inline u32 pads_readl(unsigned long offset)
241{
242 return readl(offset + PADS_OFFSET + tegra_pcie.regs);
243}
244
245static struct tegra_pcie_port *bus_to_port(int bus)
246{
247 int i;
248
249 for (i = tegra_pcie.num_ports - 1; i >= 0; i--) {
250 int rbus = tegra_pcie.port[i].root_bus_nr;
251 if (rbus != -1 && rbus == bus)
252 break;
253 }
254
255 return i >= 0 ? tegra_pcie.port + i : NULL;
256}
257
258static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
259 int where, int size, u32 *val)
260{
261 struct tegra_pcie_port *pp = bus_to_port(bus->number);
262 void __iomem *addr;
263
264 if (pp) {
265 if (devfn != 0) {
266 *val = 0xffffffff;
267 return PCIBIOS_DEVICE_NOT_FOUND;
268 }
269
270 addr = pp->base + (where & ~0x3);
271 } else {
272 addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
273 PCIE_CONF_DEV(PCI_SLOT(devfn)) +
274 PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
275 PCIE_CONF_REG(where));
276 }
277
278 *val = readl(addr);
279
280 if (size == 1)
281 *val = (*val >> (8 * (where & 3))) & 0xff;
282 else if (size == 2)
283 *val = (*val >> (8 * (where & 3))) & 0xffff;
284
285 return PCIBIOS_SUCCESSFUL;
286}
287
288static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
289 int where, int size, u32 val)
290{
291 struct tegra_pcie_port *pp = bus_to_port(bus->number);
292 void __iomem *addr;
293
294 u32 mask;
295 u32 tmp;
296
297 if (pp) {
298 if (devfn != 0)
299 return PCIBIOS_DEVICE_NOT_FOUND;
300
301 addr = pp->base + (where & ~0x3);
302 } else {
303 addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
304 PCIE_CONF_DEV(PCI_SLOT(devfn)) +
305 PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
306 PCIE_CONF_REG(where));
307 }
308
309 if (size == 4) {
310 writel(val, addr);
311 return PCIBIOS_SUCCESSFUL;
312 }
313
314 if (size == 2)
315 mask = ~(0xffff << ((where & 0x3) * 8));
316 else if (size == 1)
317 mask = ~(0xff << ((where & 0x3) * 8));
318 else
319 return PCIBIOS_BAD_REGISTER_NUMBER;
320
321 tmp = readl(addr) & mask;
322 tmp |= val << ((where & 0x3) * 8);
323 writel(tmp, addr);
324
325 return PCIBIOS_SUCCESSFUL;
326}
327
328static struct pci_ops tegra_pcie_ops = {
329 .read = tegra_pcie_read_conf,
330 .write = tegra_pcie_write_conf,
331};
332
333static void tegra_pcie_fixup_bridge(struct pci_dev *dev)
334{
335 u16 reg;
336
337 if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
338 pci_read_config_word(dev, PCI_COMMAND, &reg);
339 reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
340 PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
341 pci_write_config_word(dev, PCI_COMMAND, reg);
342 }
343}
344DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
345
346/* Tegra PCIE root complex wrongly reports device class */
347static void tegra_pcie_fixup_class(struct pci_dev *dev)
348{
349 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
350}
351DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
352DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
353
354/* Tegra PCIE requires relaxed ordering */
355static void tegra_pcie_relax_enable(struct pci_dev *dev)
356{
357 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
358}
359DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
360
361static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
362{
363 struct tegra_pcie_port *pp;
364
365 if (nr >= tegra_pcie.num_ports)
366 return 0;
367
368 pp = tegra_pcie.port + nr;
369 pp->root_bus_nr = sys->busnr;
370
371 pci_ioremap_io(nr * SZ_64K, TEGRA_PCIE_IO_BASE);
372
373 /*
374 * IORESOURCE_MEM
375 */
376 snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
377 "PCIe %d MEM", pp->index);
378 pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
379 pp->res[0].name = pp->mem_space_name;
380 if (pp->index == 0) {
381 pp->res[0].start = MEM_BASE_0;
382 pp->res[0].end = pp->res[0].start + MEM_SIZE_0 - 1;
383 } else {
384 pp->res[0].start = MEM_BASE_1;
385 pp->res[0].end = pp->res[0].start + MEM_SIZE_1 - 1;
386 }
387 pp->res[0].flags = IORESOURCE_MEM;
388 if (request_resource(&iomem_resource, &pp->res[0]))
389 panic("Request PCIe Memory resource failed\n");
390 pci_add_resource_offset(&sys->resources, &pp->res[0], sys->mem_offset);
391
392 /*
393 * IORESOURCE_MEM | IORESOURCE_PREFETCH
394 */
395 snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
396 "PCIe %d PREFETCH MEM", pp->index);
397 pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
398 pp->res[1].name = pp->prefetch_space_name;
399 if (pp->index == 0) {
400 pp->res[1].start = PREFETCH_MEM_BASE_0;
401 pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_0 - 1;
402 } else {
403 pp->res[1].start = PREFETCH_MEM_BASE_1;
404 pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_1 - 1;
405 }
406 pp->res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
407 if (request_resource(&iomem_resource, &pp->res[1]))
408 panic("Request PCIe Prefetch Memory resource failed\n");
409 pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
410
411 return 1;
412}
413
414static int tegra_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
415{
416 return INT_PCIE_INTR;
417}
418
419static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
420 struct pci_sys_data *sys)
421{
422 struct tegra_pcie_port *pp;
423
424 if (nr >= tegra_pcie.num_ports)
425 return NULL;
426
427 pp = tegra_pcie.port + nr;
428 pp->root_bus_nr = sys->busnr;
429
430 return pci_scan_root_bus(NULL, sys->busnr, &tegra_pcie_ops, sys,
431 &sys->resources);
432}
433
434static struct hw_pci tegra_pcie_hw __initdata = {
435 .nr_controllers = 2,
436 .setup = tegra_pcie_setup,
437 .scan = tegra_pcie_scan_bus,
438 .map_irq = tegra_pcie_map_irq,
439};
440
441
442static irqreturn_t tegra_pcie_isr(int irq, void *arg)
443{
444 const char *err_msg[] = {
445 "Unknown",
446 "AXI slave error",
447 "AXI decode error",
448 "Target abort",
449 "Master abort",
450 "Invalid write",
451 "Response decoding error",
452 "AXI response decoding error",
453 "Transcation timeout",
454 };
455
456 u32 code, signature;
457
458 code = afi_readl(AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
459 signature = afi_readl(AFI_INTR_SIGNATURE);
460 afi_writel(0, AFI_INTR_CODE);
461
462 if (code == AFI_INTR_LEGACY)
463 return IRQ_NONE;
464
465 if (code >= ARRAY_SIZE(err_msg))
466 code = 0;
467
468 /*
469 * do not pollute kernel log with master abort reports since they
470 * happen a lot during enumeration
471 */
472 if (code == AFI_INTR_MASTER_ABORT)
473 pr_debug("PCIE: %s, signature: %08x\n", err_msg[code], signature);
474 else
475 pr_err("PCIE: %s, signature: %08x\n", err_msg[code], signature);
476
477 return IRQ_HANDLED;
478}
479
480static void tegra_pcie_setup_translations(void)
481{
482 u32 fpci_bar;
483 u32 size;
484 u32 axi_address;
485
486 /* Bar 0: config Bar */
487 fpci_bar = ((u32)0xfdff << 16);
488 size = PCIE_CFG_SZ;
489 axi_address = TEGRA_PCIE_BASE + PCIE_CFG_OFF;
490 afi_writel(axi_address, AFI_AXI_BAR0_START);
491 afi_writel(size >> 12, AFI_AXI_BAR0_SZ);
492 afi_writel(fpci_bar, AFI_FPCI_BAR0);
493
494 /* Bar 1: extended config Bar */
495 fpci_bar = ((u32)0xfe1 << 20);
496 size = PCIE_EXT_CFG_SZ;
497 axi_address = TEGRA_PCIE_BASE + PCIE_EXT_CFG_OFF;
498 afi_writel(axi_address, AFI_AXI_BAR1_START);
499 afi_writel(size >> 12, AFI_AXI_BAR1_SZ);
500 afi_writel(fpci_bar, AFI_FPCI_BAR1);
501
502 /* Bar 2: downstream IO bar */
503 fpci_bar = ((__u32)0xfdfc << 16);
504 size = SZ_128K;
505 axi_address = TEGRA_PCIE_IO_BASE;
506 afi_writel(axi_address, AFI_AXI_BAR2_START);
507 afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
508 afi_writel(fpci_bar, AFI_FPCI_BAR2);
509
510 /* Bar 3: prefetchable memory BAR */
511 fpci_bar = (((PREFETCH_MEM_BASE_0 >> 12) & 0x0fffffff) << 4) | 0x1;
512 size = PREFETCH_MEM_SIZE_0 + PREFETCH_MEM_SIZE_1;
513 axi_address = PREFETCH_MEM_BASE_0;
514 afi_writel(axi_address, AFI_AXI_BAR3_START);
515 afi_writel(size >> 12, AFI_AXI_BAR3_SZ);
516 afi_writel(fpci_bar, AFI_FPCI_BAR3);
517
518 /* Bar 4: non prefetchable memory BAR */
519 fpci_bar = (((MEM_BASE_0 >> 12) & 0x0FFFFFFF) << 4) | 0x1;
520 size = MEM_SIZE_0 + MEM_SIZE_1;
521 axi_address = MEM_BASE_0;
522 afi_writel(axi_address, AFI_AXI_BAR4_START);
523 afi_writel(size >> 12, AFI_AXI_BAR4_SZ);
524 afi_writel(fpci_bar, AFI_FPCI_BAR4);
525
526 /* Bar 5: NULL out the remaining BAR as it is not used */
527 fpci_bar = 0;
528 size = 0;
529 axi_address = 0;
530 afi_writel(axi_address, AFI_AXI_BAR5_START);
531 afi_writel(size >> 12, AFI_AXI_BAR5_SZ);
532 afi_writel(fpci_bar, AFI_FPCI_BAR5);
533
534 /* map all upstream transactions as uncached */
535 afi_writel(PHYS_OFFSET, AFI_CACHE_BAR0_ST);
536 afi_writel(0, AFI_CACHE_BAR0_SZ);
537 afi_writel(0, AFI_CACHE_BAR1_ST);
538 afi_writel(0, AFI_CACHE_BAR1_SZ);
539
540 /* No MSI */
541 afi_writel(0, AFI_MSI_FPCI_BAR_ST);
542 afi_writel(0, AFI_MSI_BAR_SZ);
543 afi_writel(0, AFI_MSI_AXI_BAR_ST);
544 afi_writel(0, AFI_MSI_BAR_SZ);
545}
546
547static int tegra_pcie_enable_controller(void)
548{
549 u32 val, reg;
550 int i, timeout;
551
552 /* Enable slot clock and pulse the reset signals */
553 for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
554 val = afi_readl(reg) | AFI_PEX_CTRL_REFCLK_EN;
555 afi_writel(val, reg);
556 val &= ~AFI_PEX_CTRL_RST;
557 afi_writel(val, reg);
558
559 val = afi_readl(reg) | AFI_PEX_CTRL_RST;
560 afi_writel(val, reg);
561 }
562
563 /* Enable dual controller and both ports */
564 val = afi_readl(AFI_PCIE_CONFIG);
565 val &= ~(AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE |
566 AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE |
567 AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK);
568 val |= AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
569 afi_writel(val, AFI_PCIE_CONFIG);
570
571 val = afi_readl(AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
572 afi_writel(val, AFI_FUSE);
573
574 /* Initialze internal PHY, enable up to 16 PCIE lanes */
575 pads_writel(0x0, PADS_CTL_SEL);
576
577 /* override IDDQ to 1 on all 4 lanes */
578 val = pads_readl(PADS_CTL) | PADS_CTL_IDDQ_1L;
579 pads_writel(val, PADS_CTL);
580
581 /*
582 * set up PHY PLL inputs select PLLE output as refclock,
583 * set TX ref sel to div10 (not div5)
584 */
585 val = pads_readl(PADS_PLL_CTL);
586 val &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
587 val |= (PADS_PLL_CTL_REFCLK_INTERNAL_CML | PADS_PLL_CTL_TXCLKREF_DIV10);
588 pads_writel(val, PADS_PLL_CTL);
589
590 /* take PLL out of reset */
591 val = pads_readl(PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
592 pads_writel(val, PADS_PLL_CTL);
593
594 /*
595 * Hack, set the clock voltage to the DEFAULT provided by hw folks.
596 * This doesn't exist in the documentation
597 */
598 pads_writel(0xfa5cfa5c, 0xc8);
599
600 /* Wait for the PLL to lock */
601 timeout = 300;
602 do {
603 val = pads_readl(PADS_PLL_CTL);
604 usleep_range(1000, 1000);
605 if (--timeout == 0) {
606 pr_err("Tegra PCIe error: timeout waiting for PLL\n");
607 return -EBUSY;
608 }
609 } while (!(val & PADS_PLL_CTL_LOCKDET));
610
611 /* turn off IDDQ override */
612 val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L;
613 pads_writel(val, PADS_CTL);
614
615 /* enable TX/RX data */
616 val = pads_readl(PADS_CTL);
617 val |= (PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
618 pads_writel(val, PADS_CTL);
619
620 /* Take the PCIe interface module out of reset */
621 tegra_periph_reset_deassert(tegra_pcie.pcie_xclk);
622
623 /* Finally enable PCIe */
624 val = afi_readl(AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
625 afi_writel(val, AFI_CONFIGURATION);
626
627 val = (AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
628 AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
629 AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR);
630 afi_writel(val, AFI_AFI_INTR_ENABLE);
631 afi_writel(0xffffffff, AFI_SM_INTR_ENABLE);
632
633 /* FIXME: No MSI for now, only INT */
634 afi_writel(AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
635
636 /* Disable all execptions */
637 afi_writel(0, AFI_FPCI_ERROR_MASKS);
638
639 return 0;
640}
641
642static void tegra_pcie_xclk_clamp(bool clamp)
643{
644 u32 reg;
645
646 reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
647
648 if (clamp)
649 reg |= PMC_SCRATCH42_PCX_CLAMP;
650
651 pmc_writel(reg, PMC_SCRATCH42);
652}
653
654static void tegra_pcie_power_off(void)
655{
656 tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
657 tegra_periph_reset_assert(tegra_pcie.afi_clk);
658 tegra_periph_reset_assert(tegra_pcie.pex_clk);
659
660 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
661 tegra_pcie_xclk_clamp(true);
662}
663
664static int tegra_pcie_power_regate(void)
665{
666 int err;
667
668 tegra_pcie_power_off();
669
670 tegra_pcie_xclk_clamp(true);
671
672 tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
673 tegra_periph_reset_assert(tegra_pcie.afi_clk);
674
675 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
676 tegra_pcie.pex_clk);
677 if (err) {
678 pr_err("PCIE: powerup sequence failed: %d\n", err);
679 return err;
680 }
681
682 tegra_periph_reset_deassert(tegra_pcie.afi_clk);
683
684 tegra_pcie_xclk_clamp(false);
685
686 clk_prepare_enable(tegra_pcie.afi_clk);
687 clk_prepare_enable(tegra_pcie.pex_clk);
688 return clk_prepare_enable(tegra_pcie.pll_e);
689}
690
691static int tegra_pcie_clocks_get(void)
692{
693 int err;
694
695 tegra_pcie.pex_clk = clk_get(NULL, "pex");
696 if (IS_ERR(tegra_pcie.pex_clk))
697 return PTR_ERR(tegra_pcie.pex_clk);
698
699 tegra_pcie.afi_clk = clk_get(NULL, "afi");
700 if (IS_ERR(tegra_pcie.afi_clk)) {
701 err = PTR_ERR(tegra_pcie.afi_clk);
702 goto err_afi_clk;
703 }
704
705 tegra_pcie.pcie_xclk = clk_get(NULL, "pcie_xclk");
706 if (IS_ERR(tegra_pcie.pcie_xclk)) {
707 err = PTR_ERR(tegra_pcie.pcie_xclk);
708 goto err_pcie_xclk;
709 }
710
711 tegra_pcie.pll_e = clk_get_sys(NULL, "pll_e");
712 if (IS_ERR(tegra_pcie.pll_e)) {
713 err = PTR_ERR(tegra_pcie.pll_e);
714 goto err_pll_e;
715 }
716
717 return 0;
718
719err_pll_e:
720 clk_put(tegra_pcie.pcie_xclk);
721err_pcie_xclk:
722 clk_put(tegra_pcie.afi_clk);
723err_afi_clk:
724 clk_put(tegra_pcie.pex_clk);
725
726 return err;
727}
728
729static void tegra_pcie_clocks_put(void)
730{
731 clk_put(tegra_pcie.pll_e);
732 clk_put(tegra_pcie.pcie_xclk);
733 clk_put(tegra_pcie.afi_clk);
734 clk_put(tegra_pcie.pex_clk);
735}
736
737static int __init tegra_pcie_get_resources(void)
738{
739 int err;
740
741 err = tegra_pcie_clocks_get();
742 if (err) {
743 pr_err("PCIE: failed to get clocks: %d\n", err);
744 return err;
745 }
746
747 err = tegra_pcie_power_regate();
748 if (err) {
749 pr_err("PCIE: failed to power up: %d\n", err);
750 goto err_pwr_on;
751 }
752
753 tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
754 if (tegra_pcie.regs == NULL) {
755 pr_err("PCIE: Failed to map PCI/AFI registers\n");
756 err = -ENOMEM;
757 goto err_map_reg;
758 }
759
760 err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
761 IRQF_SHARED, "PCIE", &tegra_pcie);
762 if (err) {
763 pr_err("PCIE: Failed to register IRQ: %d\n", err);
764 goto err_req_io;
765 }
766 set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
767
768 return 0;
769
770err_req_io:
771 iounmap(tegra_pcie.regs);
772err_map_reg:
773 tegra_pcie_power_off();
774err_pwr_on:
775 tegra_pcie_clocks_put();
776
777 return err;
778}
779
780/*
781 * FIXME: If there are no PCIe cards attached, then calling this function
782 * can result in the increase of the bootup time as there are big timeout
783 * loops.
784 */
785#define TEGRA_PCIE_LINKUP_TIMEOUT 200 /* up to 1.2 seconds */
786static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
787 u32 reset_reg)
788{
789 u32 reg;
790 int retries = 3;
791 int timeout;
792
793 do {
794 timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
795 while (timeout) {
796 reg = readl(pp->base + RP_VEND_XP);
797
798 if (reg & RP_VEND_XP_DL_UP)
799 break;
800
801 mdelay(1);
802 timeout--;
803 }
804
805 if (!timeout) {
806 pr_err("PCIE: port %d: link down, retrying\n", idx);
807 goto retry;
808 }
809
810 timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
811 while (timeout) {
812 reg = readl(pp->base + RP_LINK_CONTROL_STATUS);
813
814 if (reg & 0x20000000)
815 return true;
816
817 mdelay(1);
818 timeout--;
819 }
820
821retry:
822 /* Pulse the PEX reset */
823 reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
824 afi_writel(reg, reset_reg);
825 mdelay(1);
826 reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
827 afi_writel(reg, reset_reg);
828
829 retries--;
830 } while (retries);
831
832 return false;
833}
834
835static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg)
836{
837 struct tegra_pcie_port *pp;
838
839 pp = tegra_pcie.port + tegra_pcie.num_ports;
840
841 pp->index = -1;
842 pp->base = tegra_pcie.regs + offset;
843 pp->link_up = tegra_pcie_check_link(pp, index, reset_reg);
844
845 if (!pp->link_up) {
846 pp->base = NULL;
847 printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index);
848 return;
849 }
850
851 tegra_pcie.num_ports++;
852 pp->index = index;
853 pp->root_bus_nr = -1;
854 memset(pp->res, 0, sizeof(pp->res));
855}
856
857int __init tegra_pcie_init(bool init_port0, bool init_port1)
858{
859 int err;
860
861 if (!(init_port0 || init_port1))
862 return -ENODEV;
863
864 pcibios_min_mem = 0;
865
866 err = tegra_pcie_get_resources();
867 if (err)
868 return err;
869
870 err = tegra_pcie_enable_controller();
871 if (err)
872 return err;
873
874 /* setup the AFI address translations */
875 tegra_pcie_setup_translations();
876
877 if (init_port0)
878 tegra_pcie_add_port(0, RP0_OFFSET, AFI_PEX0_CTRL);
879
880 if (init_port1)
881 tegra_pcie_add_port(1, RP1_OFFSET, AFI_PEX1_CTRL);
882
883 pci_common_init(&tegra_pcie_hw);
884
885 return 0;
886}
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 97b33a2a2d75..2d0203627fbb 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -196,6 +196,5 @@ struct smp_operations tegra_smp_ops __initdata = {
196#ifdef CONFIG_HOTPLUG_CPU 196#ifdef CONFIG_HOTPLUG_CPU
197 .cpu_kill = tegra_cpu_kill, 197 .cpu_kill = tegra_cpu_kill,
198 .cpu_die = tegra_cpu_die, 198 .cpu_die = tegra_cpu_die,
199 .cpu_disable = tegra_cpu_disable,
200#endif 199#endif
201}; 200};
diff --git a/arch/arm/mach-tegra/pm-tegra20.c b/arch/arm/mach-tegra/pm-tegra20.c
new file mode 100644
index 000000000000..d65e1d786400
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-tegra20.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/kernel.h>
17
18#include "pm.h"
19
20#ifdef CONFIG_PM_SLEEP
21extern u32 tegra20_iram_start, tegra20_iram_end;
22extern void tegra20_sleep_core_finish(unsigned long);
23
24void tegra20_lp1_iram_hook(void)
25{
26 tegra_lp1_iram.start_addr = &tegra20_iram_start;
27 tegra_lp1_iram.end_addr = &tegra20_iram_end;
28}
29
30void tegra20_sleep_core_init(void)
31{
32 tegra_sleep_core_finish = tegra20_sleep_core_finish;
33}
34#endif
diff --git a/arch/arm/mach-tegra/pm-tegra30.c b/arch/arm/mach-tegra/pm-tegra30.c
new file mode 100644
index 000000000000..8fa326d6ff1a
--- /dev/null
+++ b/arch/arm/mach-tegra/pm-tegra30.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/kernel.h>
17
18#include "pm.h"
19
20#ifdef CONFIG_PM_SLEEP
21extern u32 tegra30_iram_start, tegra30_iram_end;
22extern void tegra30_sleep_core_finish(unsigned long);
23
24void tegra30_lp1_iram_hook(void)
25{
26 tegra_lp1_iram.start_addr = &tegra30_iram_start;
27 tegra_lp1_iram.end_addr = &tegra30_iram_end;
28}
29
30void tegra30_sleep_core_init(void)
31{
32 tegra_sleep_core_finish = tegra30_sleep_core_finish;
33}
34#endif
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 261fec140c06..ed294a04e1d3 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -37,12 +37,18 @@
37#include "reset.h" 37#include "reset.h"
38#include "flowctrl.h" 38#include "flowctrl.h"
39#include "fuse.h" 39#include "fuse.h"
40#include "pm.h"
40#include "pmc.h" 41#include "pmc.h"
41#include "sleep.h" 42#include "sleep.h"
42 43
43#ifdef CONFIG_PM_SLEEP 44#ifdef CONFIG_PM_SLEEP
44static DEFINE_SPINLOCK(tegra_lp2_lock); 45static DEFINE_SPINLOCK(tegra_lp2_lock);
46static u32 iram_save_size;
47static void *iram_save_addr;
48struct tegra_lp1_iram tegra_lp1_iram;
45void (*tegra_tear_down_cpu)(void); 49void (*tegra_tear_down_cpu)(void);
50void (*tegra_sleep_core_finish)(unsigned long v2p);
51static int (*tegra_sleep_func)(unsigned long v2p);
46 52
47static void tegra_tear_down_cpu_init(void) 53static void tegra_tear_down_cpu_init(void)
48{ 54{
@@ -52,7 +58,9 @@ static void tegra_tear_down_cpu_init(void)
52 tegra_tear_down_cpu = tegra20_tear_down_cpu; 58 tegra_tear_down_cpu = tegra20_tear_down_cpu;
53 break; 59 break;
54 case TEGRA30: 60 case TEGRA30:
55 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC)) 61 case TEGRA114:
62 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
63 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
56 tegra_tear_down_cpu = tegra30_tear_down_cpu; 64 tegra_tear_down_cpu = tegra30_tear_down_cpu;
57 break; 65 break;
58 } 66 }
@@ -171,19 +179,109 @@ void tegra_idle_lp2_last(void)
171enum tegra_suspend_mode tegra_pm_validate_suspend_mode( 179enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
172 enum tegra_suspend_mode mode) 180 enum tegra_suspend_mode mode)
173{ 181{
174 /* Tegra114 didn't support any suspending mode yet. */
175 if (tegra_chip_id == TEGRA114)
176 return TEGRA_SUSPEND_NONE;
177
178 /* 182 /*
179 * The Tegra devices only support suspending to LP2 currently. 183 * The Tegra devices support suspending to LP1 or lower currently.
180 */ 184 */
181 if (mode > TEGRA_SUSPEND_LP2) 185 if (mode > TEGRA_SUSPEND_LP1)
182 return TEGRA_SUSPEND_LP2; 186 return TEGRA_SUSPEND_LP1;
183 187
184 return mode; 188 return mode;
185} 189}
186 190
191static int tegra_sleep_core(unsigned long v2p)
192{
193 setup_mm_for_reboot();
194 tegra_sleep_core_finish(v2p);
195
196 /* should never here */
197 BUG();
198
199 return 0;
200}
201
202/*
203 * tegra_lp1_iram_hook
204 *
205 * Hooking the address of LP1 reset vector and SDRAM self-refresh code in
206 * SDRAM. These codes not be copied to IRAM in this fuction. We need to
207 * copy these code to IRAM before LP0/LP1 suspend and restore the content
208 * of IRAM after resume.
209 */
210static bool tegra_lp1_iram_hook(void)
211{
212 switch (tegra_chip_id) {
213 case TEGRA20:
214 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
215 tegra20_lp1_iram_hook();
216 break;
217 case TEGRA30:
218 case TEGRA114:
219 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
220 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
221 tegra30_lp1_iram_hook();
222 break;
223 default:
224 break;
225 }
226
227 if (!tegra_lp1_iram.start_addr || !tegra_lp1_iram.end_addr)
228 return false;
229
230 iram_save_size = tegra_lp1_iram.end_addr - tegra_lp1_iram.start_addr;
231 iram_save_addr = kmalloc(iram_save_size, GFP_KERNEL);
232 if (!iram_save_addr)
233 return false;
234
235 return true;
236}
237
238static bool tegra_sleep_core_init(void)
239{
240 switch (tegra_chip_id) {
241 case TEGRA20:
242 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
243 tegra20_sleep_core_init();
244 break;
245 case TEGRA30:
246 case TEGRA114:
247 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) ||
248 IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
249 tegra30_sleep_core_init();
250 break;
251 default:
252 break;
253 }
254
255 if (!tegra_sleep_core_finish)
256 return false;
257
258 return true;
259}
260
261static void tegra_suspend_enter_lp1(void)
262{
263 tegra_pmc_suspend();
264
265 /* copy the reset vector & SDRAM shutdown code into IRAM */
266 memcpy(iram_save_addr, IO_ADDRESS(TEGRA_IRAM_CODE_AREA),
267 iram_save_size);
268 memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), tegra_lp1_iram.start_addr,
269 iram_save_size);
270
271 *((u32 *)tegra_cpu_lp1_mask) = 1;
272}
273
274static void tegra_suspend_exit_lp1(void)
275{
276 tegra_pmc_resume();
277
278 /* restore IRAM */
279 memcpy(IO_ADDRESS(TEGRA_IRAM_CODE_AREA), iram_save_addr,
280 iram_save_size);
281
282 *(u32 *)tegra_cpu_lp1_mask = 0;
283}
284
187static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = { 285static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
188 [TEGRA_SUSPEND_NONE] = "none", 286 [TEGRA_SUSPEND_NONE] = "none",
189 [TEGRA_SUSPEND_LP2] = "LP2", 287 [TEGRA_SUSPEND_LP2] = "LP2",
@@ -207,6 +305,9 @@ static int tegra_suspend_enter(suspend_state_t state)
207 305
208 suspend_cpu_complex(); 306 suspend_cpu_complex();
209 switch (mode) { 307 switch (mode) {
308 case TEGRA_SUSPEND_LP1:
309 tegra_suspend_enter_lp1();
310 break;
210 case TEGRA_SUSPEND_LP2: 311 case TEGRA_SUSPEND_LP2:
211 tegra_set_cpu_in_lp2(); 312 tegra_set_cpu_in_lp2();
212 break; 313 break;
@@ -214,9 +315,12 @@ static int tegra_suspend_enter(suspend_state_t state)
214 break; 315 break;
215 } 316 }
216 317
217 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); 318 cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, tegra_sleep_func);
218 319
219 switch (mode) { 320 switch (mode) {
321 case TEGRA_SUSPEND_LP1:
322 tegra_suspend_exit_lp1();
323 break;
220 case TEGRA_SUSPEND_LP2: 324 case TEGRA_SUSPEND_LP2:
221 tegra_clear_cpu_in_lp2(); 325 tegra_clear_cpu_in_lp2();
222 break; 326 break;
@@ -237,12 +341,36 @@ static const struct platform_suspend_ops tegra_suspend_ops = {
237 341
238void __init tegra_init_suspend(void) 342void __init tegra_init_suspend(void)
239{ 343{
240 if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE) 344 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
345
346 if (mode == TEGRA_SUSPEND_NONE)
241 return; 347 return;
242 348
243 tegra_tear_down_cpu_init(); 349 tegra_tear_down_cpu_init();
244 tegra_pmc_suspend_init(); 350 tegra_pmc_suspend_init();
245 351
352 if (mode >= TEGRA_SUSPEND_LP1) {
353 if (!tegra_lp1_iram_hook() || !tegra_sleep_core_init()) {
354 pr_err("%s: unable to allocate memory for SDRAM"
355 "self-refresh -- LP0/LP1 unavailable\n",
356 __func__);
357 tegra_pmc_set_suspend_mode(TEGRA_SUSPEND_LP2);
358 mode = TEGRA_SUSPEND_LP2;
359 }
360 }
361
362 /* set up sleep function for cpu_suspend */
363 switch (mode) {
364 case TEGRA_SUSPEND_LP1:
365 tegra_sleep_func = tegra_sleep_core;
366 break;
367 case TEGRA_SUSPEND_LP2:
368 tegra_sleep_func = tegra_sleep_cpu;
369 break;
370 default:
371 break;
372 }
373
246 suspend_set_ops(&tegra_suspend_ops); 374 suspend_set_ops(&tegra_suspend_ops);
247} 375}
248#endif 376#endif
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 94c4b9d9077c..fe204e5256e7 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -23,6 +23,18 @@
23 23
24#include "pmc.h" 24#include "pmc.h"
25 25
26struct tegra_lp1_iram {
27 void *start_addr;
28 void *end_addr;
29};
30extern struct tegra_lp1_iram tegra_lp1_iram;
31extern void (*tegra_sleep_core_finish)(unsigned long v2p);
32
33void tegra20_lp1_iram_hook(void);
34void tegra20_sleep_core_init(void);
35void tegra30_lp1_iram_hook(void);
36void tegra30_sleep_core_init(void);
37
26extern unsigned long l2x0_saved_regs_addr; 38extern unsigned long l2x0_saved_regs_addr;
27 39
28void save_cpu_arch_register(void); 40void save_cpu_arch_register(void);
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index eb3fa4aee0e4..8acb881f7cfe 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -21,11 +21,14 @@
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23 23
24#include "flowctrl.h"
24#include "fuse.h" 25#include "fuse.h"
25#include "pm.h" 26#include "pm.h"
26#include "pmc.h" 27#include "pmc.h"
27#include "sleep.h" 28#include "sleep.h"
28 29
30#define TEGRA_POWER_SYSCLK_POLARITY (1 << 10) /* sys clk polarity */
31#define TEGRA_POWER_SYSCLK_OE (1 << 11) /* system clock enable */
29#define TEGRA_POWER_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */ 32#define TEGRA_POWER_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */
30#define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */ 33#define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */
31#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ 34#define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
@@ -193,16 +196,50 @@ enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
193 return pmc_pm_data.suspend_mode; 196 return pmc_pm_data.suspend_mode;
194} 197}
195 198
199void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
200{
201 if (mode < TEGRA_SUSPEND_NONE || mode >= TEGRA_MAX_SUSPEND_MODE)
202 return;
203
204 pmc_pm_data.suspend_mode = mode;
205}
206
207void tegra_pmc_suspend(void)
208{
209 tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41);
210}
211
212void tegra_pmc_resume(void)
213{
214 tegra_pmc_writel(0x0, PMC_SCRATCH41);
215}
216
196void tegra_pmc_pm_set(enum tegra_suspend_mode mode) 217void tegra_pmc_pm_set(enum tegra_suspend_mode mode)
197{ 218{
198 u32 reg; 219 u32 reg, csr_reg;
199 unsigned long rate = 0; 220 unsigned long rate = 0;
200 221
201 reg = tegra_pmc_readl(PMC_CTRL); 222 reg = tegra_pmc_readl(PMC_CTRL);
202 reg |= TEGRA_POWER_CPU_PWRREQ_OE; 223 reg |= TEGRA_POWER_CPU_PWRREQ_OE;
203 reg &= ~TEGRA_POWER_EFFECT_LP0; 224 reg &= ~TEGRA_POWER_EFFECT_LP0;
204 225
226 switch (tegra_chip_id) {
227 case TEGRA20:
228 case TEGRA30:
229 break;
230 default:
231 /* Turn off CRAIL */
232 csr_reg = flowctrl_read_cpu_csr(0);
233 csr_reg &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
234 csr_reg |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
235 flowctrl_write_cpu_csr(0, csr_reg);
236 break;
237 }
238
205 switch (mode) { 239 switch (mode) {
240 case TEGRA_SUSPEND_LP1:
241 rate = 32768;
242 break;
206 case TEGRA_SUSPEND_LP2: 243 case TEGRA_SUSPEND_LP2:
207 rate = clk_get_rate(tegra_pclk); 244 rate = clk_get_rate(tegra_pclk);
208 break; 245 break;
@@ -224,6 +261,20 @@ void tegra_pmc_suspend_init(void)
224 reg = tegra_pmc_readl(PMC_CTRL); 261 reg = tegra_pmc_readl(PMC_CTRL);
225 reg |= TEGRA_POWER_CPU_PWRREQ_OE; 262 reg |= TEGRA_POWER_CPU_PWRREQ_OE;
226 tegra_pmc_writel(reg, PMC_CTRL); 263 tegra_pmc_writel(reg, PMC_CTRL);
264
265 reg = tegra_pmc_readl(PMC_CTRL);
266
267 if (!pmc_pm_data.sysclkreq_high)
268 reg |= TEGRA_POWER_SYSCLK_POLARITY;
269 else
270 reg &= ~TEGRA_POWER_SYSCLK_POLARITY;
271
272 /* configure the output polarity while the request is tristated */
273 tegra_pmc_writel(reg, PMC_CTRL);
274
275 /* now enable the request */
276 reg |= TEGRA_POWER_SYSCLK_OE;
277 tegra_pmc_writel(reg, PMC_CTRL);
227} 278}
228#endif 279#endif
229 280
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index e1c2df272f7d..549f8c7b762c 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -28,6 +28,9 @@ enum tegra_suspend_mode {
28 28
29#ifdef CONFIG_PM_SLEEP 29#ifdef CONFIG_PM_SLEEP
30enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); 30enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
31void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
32void tegra_pmc_suspend(void);
33void tegra_pmc_resume(void);
31void tegra_pmc_pm_set(enum tegra_suspend_mode mode); 34void tegra_pmc_pm_set(enum tegra_suspend_mode mode);
32void tegra_pmc_suspend_init(void); 35void tegra_pmc_suspend_init(void);
33#endif 36#endif
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 39dc9e7834f3..f527b2c2dea7 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -40,9 +40,12 @@
40 * re-enabling sdram. 40 * re-enabling sdram.
41 * 41 *
42 * r6: SoC ID 42 * r6: SoC ID
43 * r8: CPU part number
43 */ 44 */
44ENTRY(tegra_resume) 45ENTRY(tegra_resume)
45 bl v7_invalidate_l1 46 check_cpu_part_num 0xc09, r8, r9
47 bleq v7_invalidate_l1
48 blne tegra_init_l2_for_a15
46 49
47 cpu_id r0 50 cpu_id r0
48 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 51 tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
@@ -70,7 +73,8 @@ no_cpu0_chk:
70 str r1, [r2] 73 str r1, [r2]
711: 741:
72 75
73 check_cpu_part_num 0xc09, r8, r9 76 mov32 r9, 0xc09
77 cmp r8, r9
74 bne not_ca9 78 bne not_ca9
75#ifdef CONFIG_HAVE_ARM_SCU 79#ifdef CONFIG_HAVE_ARM_SCU
76 /* enable SCU */ 80 /* enable SCU */
@@ -178,6 +182,19 @@ after_errata:
1781: 1821:
179#endif 183#endif
180 184
185 /* Waking up from LP1? */
186 ldr r8, [r12, #RESET_DATA(MASK_LP1)]
187 tst r8, r11 @ if in_lp1
188 beq __is_not_lp1
189 cmp r10, #0
190 bne __die @ only CPU0 can be here
191 ldr lr, [r12, #RESET_DATA(STARTUP_LP1)]
192 cmp lr, #0
193 bleq __die @ no LP1 startup handler
194 THUMB( add lr, lr, #1 ) @ switch to Thumb mode
195 bx lr
196__is_not_lp1:
197
181 /* Waking up from LP2? */ 198 /* Waking up from LP2? */
182 ldr r9, [r12, #RESET_DATA(MASK_LP2)] 199 ldr r9, [r12, #RESET_DATA(MASK_LP2)]
183 tst r9, r11 @ if in_lp2 200 tst r9, r11 @ if in_lp2
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 1ac434e0068f..fd0bbf8a6c94 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -81,6 +81,8 @@ void __init tegra_cpu_reset_handler_init(void)
81#endif 81#endif
82 82
83#ifdef CONFIG_PM_SLEEP 83#ifdef CONFIG_PM_SLEEP
84 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP1] =
85 TEGRA_IRAM_CODE_AREA;
84 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] = 86 __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
85 virt_to_phys((void *)tegra_resume); 87 virt_to_phys((void *)tegra_resume);
86#endif 88#endif
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index c90d8e9c4ad2..76a93434c6ee 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -39,6 +39,10 @@ void __tegra_cpu_reset_handler_end(void);
39void tegra_secondary_startup(void); 39void tegra_secondary_startup(void);
40 40
41#ifdef CONFIG_PM_SLEEP 41#ifdef CONFIG_PM_SLEEP
42#define tegra_cpu_lp1_mask \
43 (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
44 ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP1] - \
45 (u32)__tegra_cpu_reset_handler_start)))
42#define tegra_cpu_lp2_mask \ 46#define tegra_cpu_lp2_mask \
43 (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ 47 (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
44 ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \ 48 ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index e3f2417c420e..5c3bd11c9838 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -23,10 +23,49 @@
23#include <asm/assembler.h> 23#include <asm/assembler.h>
24#include <asm/proc-fns.h> 24#include <asm/proc-fns.h>
25#include <asm/cp15.h> 25#include <asm/cp15.h>
26#include <asm/cache.h>
26 27
27#include "sleep.h" 28#include "sleep.h"
28#include "flowctrl.h" 29#include "flowctrl.h"
29 30
31#define EMC_CFG 0xc
32#define EMC_ADR_CFG 0x10
33#define EMC_REFRESH 0x70
34#define EMC_NOP 0xdc
35#define EMC_SELF_REF 0xe0
36#define EMC_REQ_CTRL 0x2b0
37#define EMC_EMC_STATUS 0x2b4
38
39#define CLK_RESET_CCLK_BURST 0x20
40#define CLK_RESET_CCLK_DIVIDER 0x24
41#define CLK_RESET_SCLK_BURST 0x28
42#define CLK_RESET_SCLK_DIVIDER 0x2c
43#define CLK_RESET_PLLC_BASE 0x80
44#define CLK_RESET_PLLM_BASE 0x90
45#define CLK_RESET_PLLP_BASE 0xa0
46
47#define APB_MISC_XM2CFGCPADCTRL 0x8c8
48#define APB_MISC_XM2CFGDPADCTRL 0x8cc
49#define APB_MISC_XM2CLKCFGPADCTRL 0x8d0
50#define APB_MISC_XM2COMPPADCTRL 0x8d4
51#define APB_MISC_XM2VTTGENPADCTRL 0x8d8
52#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
53#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
54
55.macro pll_enable, rd, r_car_base, pll_base
56 ldr \rd, [\r_car_base, #\pll_base]
57 tst \rd, #(1 << 30)
58 orreq \rd, \rd, #(1 << 30)
59 streq \rd, [\r_car_base, #\pll_base]
60.endm
61
62.macro emc_device_mask, rd, base
63 ldr \rd, [\base, #EMC_ADR_CFG]
64 tst \rd, #(0x3 << 24)
65 moveq \rd, #(0x1 << 8) @ just 1 device
66 movne \rd, #(0x3 << 8) @ 2 devices
67.endm
68
30#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) 69#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
31/* 70/*
32 * tegra20_hotplug_shutdown(void) 71 * tegra20_hotplug_shutdown(void)
@@ -181,6 +220,28 @@ ENTRY(tegra20_cpu_is_resettable_soon)
181ENDPROC(tegra20_cpu_is_resettable_soon) 220ENDPROC(tegra20_cpu_is_resettable_soon)
182 221
183/* 222/*
223 * tegra20_sleep_core_finish(unsigned long v2p)
224 *
225 * Enters suspend in LP0 or LP1 by turning off the mmu and jumping to
226 * tegra20_tear_down_core in IRAM
227 */
228ENTRY(tegra20_sleep_core_finish)
229 /* Flush, disable the L1 data cache and exit SMP */
230 bl tegra_disable_clean_inv_dcache
231
232 mov32 r3, tegra_shut_off_mmu
233 add r3, r3, r0
234
235 mov32 r0, tegra20_tear_down_core
236 mov32 r1, tegra20_iram_start
237 sub r0, r0, r1
238 mov32 r1, TEGRA_IRAM_CODE_AREA
239 add r0, r0, r1
240
241 mov pc, r3
242ENDPROC(tegra20_sleep_core_finish)
243
244/*
184 * tegra20_sleep_cpu_secondary_finish(unsigned long v2p) 245 * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
185 * 246 *
186 * Enters WFI on secondary CPU by exiting coherency. 247 * Enters WFI on secondary CPU by exiting coherency.
@@ -191,6 +252,7 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
191 mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency 252 mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency
192 253
193 /* Flush and disable the L1 data cache */ 254 /* Flush and disable the L1 data cache */
255 mov r0, #TEGRA_FLUSH_CACHE_LOUIS
194 bl tegra_disable_clean_inv_dcache 256 bl tegra_disable_clean_inv_dcache
195 257
196 mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41 258 mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
@@ -250,6 +312,150 @@ ENTRY(tegra20_tear_down_cpu)
250 b tegra20_enter_sleep 312 b tegra20_enter_sleep
251ENDPROC(tegra20_tear_down_cpu) 313ENDPROC(tegra20_tear_down_cpu)
252 314
315/* START OF ROUTINES COPIED TO IRAM */
316 .align L1_CACHE_SHIFT
317 .globl tegra20_iram_start
318tegra20_iram_start:
319
320/*
321 * tegra20_lp1_reset
322 *
323 * reset vector for LP1 restore; copied into IRAM during suspend.
324 * Brings the system back up to a safe staring point (SDRAM out of
325 * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLP,
326 * system clock running on the same PLL that it suspended at), and
327 * jumps to tegra_resume to restore virtual addressing and PLLX.
328 * The physical address of tegra_resume expected to be stored in
329 * PMC_SCRATCH41.
330 *
331 * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
332 */
333ENTRY(tegra20_lp1_reset)
334 /*
335 * The CPU and system bus are running at 32KHz and executing from
336 * IRAM when this code is executed; immediately switch to CLKM and
337 * enable PLLM, PLLP, PLLC.
338 */
339 mov32 r0, TEGRA_CLK_RESET_BASE
340
341 mov r1, #(1 << 28)
342 str r1, [r0, #CLK_RESET_SCLK_BURST]
343 str r1, [r0, #CLK_RESET_CCLK_BURST]
344 mov r1, #0
345 str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
346 str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
347
348 pll_enable r1, r0, CLK_RESET_PLLM_BASE
349 pll_enable r1, r0, CLK_RESET_PLLP_BASE
350 pll_enable r1, r0, CLK_RESET_PLLC_BASE
351
352 adr r2, tegra20_sdram_pad_address
353 adr r4, tegra20_sdram_pad_save
354 mov r5, #0
355
356 ldr r6, tegra20_sdram_pad_size
357padload:
358 ldr r7, [r2, r5] @ r7 is the addr in the pad_address
359
360 ldr r1, [r4, r5]
361 str r1, [r7] @ restore the value in pad_save
362
363 add r5, r5, #4
364 cmp r6, r5
365 bne padload
366
367padload_done:
368 /* 255uS delay for PLL stabilization */
369 mov32 r7, TEGRA_TMRUS_BASE
370 ldr r1, [r7]
371 add r1, r1, #0xff
372 wait_until r1, r7, r9
373
374 adr r4, tegra20_sclk_save
375 ldr r4, [r4]
376 str r4, [r0, #CLK_RESET_SCLK_BURST]
377 mov32 r4, ((1 << 28) | (4)) @ burst policy is PLLP
378 str r4, [r0, #CLK_RESET_CCLK_BURST]
379
380 mov32 r0, TEGRA_EMC_BASE
381 ldr r1, [r0, #EMC_CFG]
382 bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP
383 str r1, [r0, #EMC_CFG]
384
385 mov r1, #0
386 str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
387 mov r1, #1
388 str r1, [r0, #EMC_NOP]
389 str r1, [r0, #EMC_NOP]
390 str r1, [r0, #EMC_REFRESH]
391
392 emc_device_mask r1, r0
393
394exit_selfrefresh_loop:
395 ldr r2, [r0, #EMC_EMC_STATUS]
396 ands r2, r2, r1
397 bne exit_selfrefresh_loop
398
399 mov r1, #0 @ unstall all transactions
400 str r1, [r0, #EMC_REQ_CTRL]
401
402 mov32 r0, TEGRA_PMC_BASE
403 ldr r0, [r0, #PMC_SCRATCH41]
404 mov pc, r0 @ jump to tegra_resume
405ENDPROC(tegra20_lp1_reset)
406
407/*
408 * tegra20_tear_down_core
409 *
410 * copied into and executed from IRAM
411 * puts memory in self-refresh for LP0 and LP1
412 */
413tegra20_tear_down_core:
414 bl tegra20_sdram_self_refresh
415 bl tegra20_switch_cpu_to_clk32k
416 b tegra20_enter_sleep
417
418/*
419 * tegra20_switch_cpu_to_clk32k
420 *
421 * In LP0 and LP1 all PLLs will be turned off. Switch the CPU and system clock
422 * to the 32KHz clock.
423 */
424tegra20_switch_cpu_to_clk32k:
425 /*
426 * start by switching to CLKM to safely disable PLLs, then switch to
427 * CLKS.
428 */
429 mov r0, #(1 << 28)
430 str r0, [r5, #CLK_RESET_SCLK_BURST]
431 str r0, [r5, #CLK_RESET_CCLK_BURST]
432 mov r0, #0
433 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
434 str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
435
436 /* 2uS delay delay between changing SCLK and disabling PLLs */
437 mov32 r7, TEGRA_TMRUS_BASE
438 ldr r1, [r7]
439 add r1, r1, #2
440 wait_until r1, r7, r9
441
442 /* disable PLLM, PLLP and PLLC */
443 ldr r0, [r5, #CLK_RESET_PLLM_BASE]
444 bic r0, r0, #(1 << 30)
445 str r0, [r5, #CLK_RESET_PLLM_BASE]
446 ldr r0, [r5, #CLK_RESET_PLLP_BASE]
447 bic r0, r0, #(1 << 30)
448 str r0, [r5, #CLK_RESET_PLLP_BASE]
449 ldr r0, [r5, #CLK_RESET_PLLC_BASE]
450 bic r0, r0, #(1 << 30)
451 str r0, [r5, #CLK_RESET_PLLC_BASE]
452
453 /* switch to CLKS */
454 mov r0, #0 /* brust policy = 32KHz */
455 str r0, [r5, #CLK_RESET_SCLK_BURST]
456
457 mov pc, lr
458
253/* 459/*
254 * tegra20_enter_sleep 460 * tegra20_enter_sleep
255 * 461 *
@@ -274,4 +480,95 @@ halted:
274 isb 480 isb
275 b halted 481 b halted
276 482
483/*
484 * tegra20_sdram_self_refresh
485 *
486 * called with MMU off and caches disabled
487 * puts sdram in self refresh
488 * must be executed from IRAM
489 */
490tegra20_sdram_self_refresh:
491 mov32 r1, TEGRA_EMC_BASE @ r1 reserved for emc base addr
492
493 mov r2, #3
494 str r2, [r1, #EMC_REQ_CTRL] @ stall incoming DRAM requests
495
496emcidle:
497 ldr r2, [r1, #EMC_EMC_STATUS]
498 tst r2, #4
499 beq emcidle
500
501 mov r2, #1
502 str r2, [r1, #EMC_SELF_REF]
503
504 emc_device_mask r2, r1
505
506emcself:
507 ldr r3, [r1, #EMC_EMC_STATUS]
508 and r3, r3, r2
509 cmp r3, r2
510 bne emcself @ loop until DDR in self-refresh
511
512 adr r2, tegra20_sdram_pad_address
513 adr r3, tegra20_sdram_pad_safe
514 adr r4, tegra20_sdram_pad_save
515 mov r5, #0
516
517 ldr r6, tegra20_sdram_pad_size
518padsave:
519 ldr r0, [r2, r5] @ r0 is the addr in the pad_address
520
521 ldr r1, [r0]
522 str r1, [r4, r5] @ save the content of the addr
523
524 ldr r1, [r3, r5]
525 str r1, [r0] @ set the save val to the addr
526
527 add r5, r5, #4
528 cmp r6, r5
529 bne padsave
530padsave_done:
531
532 mov32 r5, TEGRA_CLK_RESET_BASE
533 ldr r0, [r5, #CLK_RESET_SCLK_BURST]
534 adr r2, tegra20_sclk_save
535 str r0, [r2]
536 dsb
537 mov pc, lr
538
539tegra20_sdram_pad_address:
540 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL
541 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL
542 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CLKCFGPADCTRL
543 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2COMPPADCTRL
544 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2VTTGENPADCTRL
545 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGCPADCTRL2
546 .word TEGRA_APB_MISC_BASE + APB_MISC_XM2CFGDPADCTRL2
547
548tegra20_sdram_pad_size:
549 .word tegra20_sdram_pad_size - tegra20_sdram_pad_address
550
551tegra20_sdram_pad_safe:
552 .word 0x8
553 .word 0x8
554 .word 0x0
555 .word 0x8
556 .word 0x5500
557 .word 0x08080040
558 .word 0x0
559
560tegra20_sclk_save:
561 .word 0x0
562
563tegra20_sdram_pad_save:
564 .rept (tegra20_sdram_pad_size - tegra20_sdram_pad_address) / 4
565 .long 0
566 .endr
567
568 .ltorg
569/* dummy symbol for end of IRAM */
570 .align L1_CACHE_SHIFT
571 .globl tegra20_iram_end
572tegra20_iram_end:
573 b .
277#endif 574#endif
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index ada8821b48be..63fa91b5fafb 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -18,13 +18,118 @@
18 18
19#include <asm/assembler.h> 19#include <asm/assembler.h>
20#include <asm/asm-offsets.h> 20#include <asm/asm-offsets.h>
21#include <asm/cache.h>
21 22
22#include "fuse.h" 23#include "fuse.h"
23#include "sleep.h" 24#include "sleep.h"
24#include "flowctrl.h" 25#include "flowctrl.h"
25 26
27#define EMC_CFG 0xc
28#define EMC_ADR_CFG 0x10
29#define EMC_TIMING_CONTROL 0x28
30#define EMC_REFRESH 0x70
31#define EMC_NOP 0xdc
32#define EMC_SELF_REF 0xe0
33#define EMC_MRW 0xe8
34#define EMC_FBIO_CFG5 0x104
35#define EMC_AUTO_CAL_CONFIG 0x2a4
36#define EMC_AUTO_CAL_INTERVAL 0x2a8
37#define EMC_AUTO_CAL_STATUS 0x2ac
38#define EMC_REQ_CTRL 0x2b0
39#define EMC_CFG_DIG_DLL 0x2bc
40#define EMC_EMC_STATUS 0x2b4
41#define EMC_ZCAL_INTERVAL 0x2e0
42#define EMC_ZQ_CAL 0x2ec
43#define EMC_XM2VTTGENPADCTRL 0x310
44#define EMC_XM2VTTGENPADCTRL2 0x314
45
46#define PMC_CTRL 0x0
47#define PMC_CTRL_SIDE_EFFECT_LP0 (1 << 14) /* enter LP0 when CPU pwr gated */
48
49#define PMC_PLLP_WB0_OVERRIDE 0xf8
50#define PMC_IO_DPD_REQ 0x1b8
51#define PMC_IO_DPD_STATUS 0x1bc
52
53#define CLK_RESET_CCLK_BURST 0x20
54#define CLK_RESET_CCLK_DIVIDER 0x24
55#define CLK_RESET_SCLK_BURST 0x28
56#define CLK_RESET_SCLK_DIVIDER 0x2c
57
58#define CLK_RESET_PLLC_BASE 0x80
59#define CLK_RESET_PLLC_MISC 0x8c
60#define CLK_RESET_PLLM_BASE 0x90
61#define CLK_RESET_PLLM_MISC 0x9c
62#define CLK_RESET_PLLP_BASE 0xa0
63#define CLK_RESET_PLLP_MISC 0xac
64#define CLK_RESET_PLLA_BASE 0xb0
65#define CLK_RESET_PLLA_MISC 0xbc
66#define CLK_RESET_PLLX_BASE 0xe0
67#define CLK_RESET_PLLX_MISC 0xe4
68#define CLK_RESET_PLLX_MISC3 0x518
69#define CLK_RESET_PLLX_MISC3_IDDQ 3
70#define CLK_RESET_PLLM_MISC_IDDQ 5
71#define CLK_RESET_PLLC_MISC_IDDQ 26
72
73#define CLK_RESET_CLK_SOURCE_MSELECT 0x3b4
74
75#define MSELECT_CLKM (0x3 << 30)
76
77#define LOCK_DELAY 50 /* safety delay after lock is detected */
78
26#define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */ 79#define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */
27 80
81.macro emc_device_mask, rd, base
82 ldr \rd, [\base, #EMC_ADR_CFG]
83 tst \rd, #0x1
84 moveq \rd, #(0x1 << 8) @ just 1 device
85 movne \rd, #(0x3 << 8) @ 2 devices
86.endm
87
88.macro emc_timing_update, rd, base
89 mov \rd, #1
90 str \rd, [\base, #EMC_TIMING_CONTROL]
911001:
92 ldr \rd, [\base, #EMC_EMC_STATUS]
93 tst \rd, #(0x1<<23) @ wait EMC_STATUS_TIMING_UPDATE_STALLED is clear
94 bne 1001b
95.endm
96
97.macro pll_enable, rd, r_car_base, pll_base, pll_misc
98 ldr \rd, [\r_car_base, #\pll_base]
99 tst \rd, #(1 << 30)
100 orreq \rd, \rd, #(1 << 30)
101 streq \rd, [\r_car_base, #\pll_base]
102 /* Enable lock detector */
103 .if \pll_misc
104 ldr \rd, [\r_car_base, #\pll_misc]
105 bic \rd, \rd, #(1 << 18)
106 str \rd, [\r_car_base, #\pll_misc]
107 ldr \rd, [\r_car_base, #\pll_misc]
108 ldr \rd, [\r_car_base, #\pll_misc]
109 orr \rd, \rd, #(1 << 18)
110 str \rd, [\r_car_base, #\pll_misc]
111 .endif
112.endm
113
114.macro pll_locked, rd, r_car_base, pll_base
1151:
116 ldr \rd, [\r_car_base, #\pll_base]
117 tst \rd, #(1 << 27)
118 beq 1b
119.endm
120
121.macro pll_iddq_exit, rd, car, iddq, iddq_bit
122 ldr \rd, [\car, #\iddq]
123 bic \rd, \rd, #(1<<\iddq_bit)
124 str \rd, [\car, #\iddq]
125.endm
126
127.macro pll_iddq_entry, rd, car, iddq, iddq_bit
128 ldr \rd, [\car, #\iddq]
129 orr \rd, \rd, #(1<<\iddq_bit)
130 str \rd, [\car, #\iddq]
131.endm
132
28#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) 133#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
29/* 134/*
30 * tegra30_hotplug_shutdown(void) 135 * tegra30_hotplug_shutdown(void)
@@ -99,6 +204,8 @@ flow_ctrl_setting_for_lp2:
99 cmp r10, #TEGRA30 204 cmp r10, #TEGRA30
100 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2 205 moveq r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT @ For LP2
101 movne r3, #FLOW_CTRL_WAITEVENT 206 movne r3, #FLOW_CTRL_WAITEVENT
207 orrne r3, r3, #FLOW_CTRL_HALT_GIC_IRQ
208 orrne r3, r3, #FLOW_CTRL_HALT_GIC_FIQ
102flow_ctrl_done: 209flow_ctrl_done:
103 cmp r10, #TEGRA30 210 cmp r10, #TEGRA30
104 str r3, [r2] 211 str r3, [r2]
@@ -127,6 +234,41 @@ ENDPROC(tegra30_cpu_shutdown)
127 234
128#ifdef CONFIG_PM_SLEEP 235#ifdef CONFIG_PM_SLEEP
129/* 236/*
237 * tegra30_sleep_core_finish(unsigned long v2p)
238 *
239 * Enters suspend in LP0 or LP1 by turning off the MMU and jumping to
240 * tegra30_tear_down_core in IRAM
241 */
242ENTRY(tegra30_sleep_core_finish)
243 /* Flush, disable the L1 data cache and exit SMP */
244 bl tegra_disable_clean_inv_dcache
245
246 /*
247 * Preload all the address literals that are needed for the
248 * CPU power-gating process, to avoid loading from SDRAM which
249 * are not supported once SDRAM is put into self-refresh.
250 * LP0 / LP1 use physical address, since the MMU needs to be
251 * disabled before putting SDRAM into self-refresh to avoid
252 * memory access due to page table walks.
253 */
254 mov32 r4, TEGRA_PMC_BASE
255 mov32 r5, TEGRA_CLK_RESET_BASE
256 mov32 r6, TEGRA_FLOW_CTRL_BASE
257 mov32 r7, TEGRA_TMRUS_BASE
258
259 mov32 r3, tegra_shut_off_mmu
260 add r3, r3, r0
261
262 mov32 r0, tegra30_tear_down_core
263 mov32 r1, tegra30_iram_start
264 sub r0, r0, r1
265 mov32 r1, TEGRA_IRAM_CODE_AREA
266 add r0, r0, r1
267
268 mov pc, r3
269ENDPROC(tegra30_sleep_core_finish)
270
271/*
130 * tegra30_sleep_cpu_secondary_finish(unsigned long v2p) 272 * tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
131 * 273 *
132 * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU. 274 * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
@@ -135,6 +277,7 @@ ENTRY(tegra30_sleep_cpu_secondary_finish)
135 mov r7, lr 277 mov r7, lr
136 278
137 /* Flush and disable the L1 data cache */ 279 /* Flush and disable the L1 data cache */
280 mov r0, #TEGRA_FLUSH_CACHE_LOUIS
138 bl tegra_disable_clean_inv_dcache 281 bl tegra_disable_clean_inv_dcache
139 282
140 /* Powergate this CPU. */ 283 /* Powergate this CPU. */
@@ -155,6 +298,351 @@ ENTRY(tegra30_tear_down_cpu)
155 b tegra30_enter_sleep 298 b tegra30_enter_sleep
156ENDPROC(tegra30_tear_down_cpu) 299ENDPROC(tegra30_tear_down_cpu)
157 300
301/* START OF ROUTINES COPIED TO IRAM */
302 .align L1_CACHE_SHIFT
303 .globl tegra30_iram_start
304tegra30_iram_start:
305
306/*
307 * tegra30_lp1_reset
308 *
309 * reset vector for LP1 restore; copied into IRAM during suspend.
310 * Brings the system back up to a safe staring point (SDRAM out of
311 * self-refresh, PLLC, PLLM and PLLP reenabled, CPU running on PLLX,
312 * system clock running on the same PLL that it suspended at), and
313 * jumps to tegra_resume to restore virtual addressing.
314 * The physical address of tegra_resume expected to be stored in
315 * PMC_SCRATCH41.
316 *
317 * NOTE: THIS *MUST* BE RELOCATED TO TEGRA_IRAM_CODE_AREA.
318 */
319ENTRY(tegra30_lp1_reset)
320 /*
321 * The CPU and system bus are running at 32KHz and executing from
322 * IRAM when this code is executed; immediately switch to CLKM and
323 * enable PLLP, PLLM, PLLC, PLLA and PLLX.
324 */
325 mov32 r0, TEGRA_CLK_RESET_BASE
326
327 mov r1, #(1 << 28)
328 str r1, [r0, #CLK_RESET_SCLK_BURST]
329 str r1, [r0, #CLK_RESET_CCLK_BURST]
330 mov r1, #0
331 str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
332 str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
333
334 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
335 cmp r10, #TEGRA30
336 beq _no_pll_iddq_exit
337
338 pll_iddq_exit r1, r0, CLK_RESET_PLLM_MISC, CLK_RESET_PLLM_MISC_IDDQ
339 pll_iddq_exit r1, r0, CLK_RESET_PLLC_MISC, CLK_RESET_PLLC_MISC_IDDQ
340 pll_iddq_exit r1, r0, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
341
342 mov32 r7, TEGRA_TMRUS_BASE
343 ldr r1, [r7]
344 add r1, r1, #2
345 wait_until r1, r7, r3
346
347 /* enable PLLM via PMC */
348 mov32 r2, TEGRA_PMC_BASE
349 ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
350 orr r1, r1, #(1 << 12)
351 str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
352
353 pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0
354 pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0
355 pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0
356
357 b _pll_m_c_x_done
358
359_no_pll_iddq_exit:
360 /* enable PLLM via PMC */
361 mov32 r2, TEGRA_PMC_BASE
362 ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
363 orr r1, r1, #(1 << 12)
364 str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
365
366 pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC
367 pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC
368 pll_enable r1, r0, CLK_RESET_PLLX_BASE, CLK_RESET_PLLX_MISC
369
370_pll_m_c_x_done:
371 pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC
372 pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC
373
374 pll_locked r1, r0, CLK_RESET_PLLM_BASE
375 pll_locked r1, r0, CLK_RESET_PLLP_BASE
376 pll_locked r1, r0, CLK_RESET_PLLA_BASE
377 pll_locked r1, r0, CLK_RESET_PLLC_BASE
378 pll_locked r1, r0, CLK_RESET_PLLX_BASE
379
380 mov32 r7, TEGRA_TMRUS_BASE
381 ldr r1, [r7]
382 add r1, r1, #LOCK_DELAY
383 wait_until r1, r7, r3
384
385 adr r5, tegra30_sdram_pad_save
386
387 ldr r4, [r5, #0x18] @ restore CLK_SOURCE_MSELECT
388 str r4, [r0, #CLK_RESET_CLK_SOURCE_MSELECT]
389
390 ldr r4, [r5, #0x1C] @ restore SCLK_BURST
391 str r4, [r0, #CLK_RESET_SCLK_BURST]
392
393 cmp r10, #TEGRA30
394 movweq r4, #:lower16:((1 << 28) | (0x8)) @ burst policy is PLLX
395 movteq r4, #:upper16:((1 << 28) | (0x8))
396 movwne r4, #:lower16:((1 << 28) | (0xe))
397 movtne r4, #:upper16:((1 << 28) | (0xe))
398 str r4, [r0, #CLK_RESET_CCLK_BURST]
399
400 /* Restore pad power state to normal */
401 ldr r1, [r5, #0x14] @ PMC_IO_DPD_STATUS
402 mvn r1, r1
403 bic r1, r1, #(1 << 31)
404 orr r1, r1, #(1 << 30)
405 str r1, [r2, #PMC_IO_DPD_REQ] @ DPD_OFF
406
407 cmp r10, #TEGRA30
408 movweq r0, #:lower16:TEGRA_EMC_BASE @ r0 reserved for emc base
409 movteq r0, #:upper16:TEGRA_EMC_BASE
410 movwne r0, #:lower16:TEGRA_EMC0_BASE
411 movtne r0, #:upper16:TEGRA_EMC0_BASE
412
413exit_self_refresh:
414 ldr r1, [r5, #0xC] @ restore EMC_XM2VTTGENPADCTRL
415 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
416 ldr r1, [r5, #0x10] @ restore EMC_XM2VTTGENPADCTRL2
417 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
418 ldr r1, [r5, #0x8] @ restore EMC_AUTO_CAL_INTERVAL
419 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
420
421 /* Relock DLL */
422 ldr r1, [r0, #EMC_CFG_DIG_DLL]
423 orr r1, r1, #(1 << 30) @ set DLL_RESET
424 str r1, [r0, #EMC_CFG_DIG_DLL]
425
426 emc_timing_update r1, r0
427
428 cmp r10, #TEGRA114
429 movweq r1, #:lower16:TEGRA_EMC1_BASE
430 movteq r1, #:upper16:TEGRA_EMC1_BASE
431 cmpeq r0, r1
432
433 ldr r1, [r0, #EMC_AUTO_CAL_CONFIG]
434 orr r1, r1, #(1 << 31) @ set AUTO_CAL_ACTIVE
435 orreq r1, r1, #(1 << 27) @ set slave mode for channel 1
436 str r1, [r0, #EMC_AUTO_CAL_CONFIG]
437
438emc_wait_auto_cal_onetime:
439 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
440 tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
441 bne emc_wait_auto_cal_onetime
442
443 ldr r1, [r0, #EMC_CFG]
444 bic r1, r1, #(1 << 31) @ disable DRAM_CLK_STOP_PD
445 str r1, [r0, #EMC_CFG]
446
447 mov r1, #0
448 str r1, [r0, #EMC_SELF_REF] @ take DRAM out of self refresh
449 mov r1, #1
450 cmp r10, #TEGRA30
451 streq r1, [r0, #EMC_NOP]
452 streq r1, [r0, #EMC_NOP]
453 streq r1, [r0, #EMC_REFRESH]
454
455 emc_device_mask r1, r0
456
457exit_selfrefresh_loop:
458 ldr r2, [r0, #EMC_EMC_STATUS]
459 ands r2, r2, r1
460 bne exit_selfrefresh_loop
461
462 lsr r1, r1, #8 @ devSel, bit0:dev0, bit1:dev1
463
464 mov32 r7, TEGRA_TMRUS_BASE
465 ldr r2, [r0, #EMC_FBIO_CFG5]
466
467 and r2, r2, #3 @ check DRAM_TYPE
468 cmp r2, #2
469 beq emc_lpddr2
470
471 /* Issue a ZQ_CAL for dev0 - DDR3 */
472 mov32 r2, 0x80000011 @ DEV_SELECTION=2, LENGTH=LONG, CMD=1
473 str r2, [r0, #EMC_ZQ_CAL]
474 ldr r2, [r7]
475 add r2, r2, #10
476 wait_until r2, r7, r3
477
478 tst r1, #2
479 beq zcal_done
480
481 /* Issue a ZQ_CAL for dev1 - DDR3 */
482 mov32 r2, 0x40000011 @ DEV_SELECTION=1, LENGTH=LONG, CMD=1
483 str r2, [r0, #EMC_ZQ_CAL]
484 ldr r2, [r7]
485 add r2, r2, #10
486 wait_until r2, r7, r3
487 b zcal_done
488
489emc_lpddr2:
490 /* Issue a ZQ_CAL for dev0 - LPDDR2 */
491 mov32 r2, 0x800A00AB @ DEV_SELECTION=2, MA=10, OP=0xAB
492 str r2, [r0, #EMC_MRW]
493 ldr r2, [r7]
494 add r2, r2, #1
495 wait_until r2, r7, r3
496
497 tst r1, #2
498 beq zcal_done
499
500 /* Issue a ZQ_CAL for dev0 - LPDDR2 */
501 mov32 r2, 0x400A00AB @ DEV_SELECTION=1, MA=10, OP=0xAB
502 str r2, [r0, #EMC_MRW]
503 ldr r2, [r7]
504 add r2, r2, #1
505 wait_until r2, r7, r3
506
507zcal_done:
508 mov r1, #0 @ unstall all transactions
509 str r1, [r0, #EMC_REQ_CTRL]
510 ldr r1, [r5, #0x4] @ restore EMC_ZCAL_INTERVAL
511 str r1, [r0, #EMC_ZCAL_INTERVAL]
512 ldr r1, [r5, #0x0] @ restore EMC_CFG
513 str r1, [r0, #EMC_CFG]
514
515 /* Tegra114 had dual EMC channel, now config the other one */
516 cmp r10, #TEGRA114
517 bne __no_dual_emc_chanl
518 mov32 r1, TEGRA_EMC1_BASE
519 cmp r0, r1
520 movne r0, r1
521 addne r5, r5, #0x20
522 bne exit_self_refresh
523__no_dual_emc_chanl:
524
525 mov32 r0, TEGRA_PMC_BASE
526 ldr r0, [r0, #PMC_SCRATCH41]
527 mov pc, r0 @ jump to tegra_resume
528ENDPROC(tegra30_lp1_reset)
529
530 .align L1_CACHE_SHIFT
531tegra30_sdram_pad_address:
532 .word TEGRA_EMC_BASE + EMC_CFG @0x0
533 .word TEGRA_EMC_BASE + EMC_ZCAL_INTERVAL @0x4
534 .word TEGRA_EMC_BASE + EMC_AUTO_CAL_INTERVAL @0x8
535 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL @0xc
536 .word TEGRA_EMC_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
537 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
538 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
539 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
540
541tegra114_sdram_pad_address:
542 .word TEGRA_EMC0_BASE + EMC_CFG @0x0
543 .word TEGRA_EMC0_BASE + EMC_ZCAL_INTERVAL @0x4
544 .word TEGRA_EMC0_BASE + EMC_AUTO_CAL_INTERVAL @0x8
545 .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL @0xc
546 .word TEGRA_EMC0_BASE + EMC_XM2VTTGENPADCTRL2 @0x10
547 .word TEGRA_PMC_BASE + PMC_IO_DPD_STATUS @0x14
548 .word TEGRA_CLK_RESET_BASE + CLK_RESET_CLK_SOURCE_MSELECT @0x18
549 .word TEGRA_CLK_RESET_BASE + CLK_RESET_SCLK_BURST @0x1c
550 .word TEGRA_EMC1_BASE + EMC_CFG @0x20
551 .word TEGRA_EMC1_BASE + EMC_ZCAL_INTERVAL @0x24
552 .word TEGRA_EMC1_BASE + EMC_AUTO_CAL_INTERVAL @0x28
553 .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL @0x2c
554 .word TEGRA_EMC1_BASE + EMC_XM2VTTGENPADCTRL2 @0x30
555
556tegra30_sdram_pad_size:
557 .word tegra114_sdram_pad_address - tegra30_sdram_pad_address
558
559tegra114_sdram_pad_size:
560 .word tegra30_sdram_pad_size - tegra114_sdram_pad_address
561
562 .type tegra30_sdram_pad_save, %object
563tegra30_sdram_pad_save:
564 .rept (tegra30_sdram_pad_size - tegra114_sdram_pad_address) / 4
565 .long 0
566 .endr
567
568/*
569 * tegra30_tear_down_core
570 *
571 * copied into and executed from IRAM
572 * puts memory in self-refresh for LP0 and LP1
573 */
574tegra30_tear_down_core:
575 bl tegra30_sdram_self_refresh
576 bl tegra30_switch_cpu_to_clk32k
577 b tegra30_enter_sleep
578
579/*
580 * tegra30_switch_cpu_to_clk32k
581 *
582 * In LP0 and LP1 all PLLs will be turned off. Switching the CPU and System CLK
583 * to the 32KHz clock.
584 * r4 = TEGRA_PMC_BASE
585 * r5 = TEGRA_CLK_RESET_BASE
586 * r6 = TEGRA_FLOW_CTRL_BASE
587 * r7 = TEGRA_TMRUS_BASE
588 * r10= SoC ID
589 */
590tegra30_switch_cpu_to_clk32k:
591 /*
592 * start by jumping to CLKM to safely disable PLLs, then jump to
593 * CLKS.
594 */
595 mov r0, #(1 << 28)
596 str r0, [r5, #CLK_RESET_SCLK_BURST]
597 /* 2uS delay delay between changing SCLK and CCLK */
598 ldr r1, [r7]
599 add r1, r1, #2
600 wait_until r1, r7, r9
601 str r0, [r5, #CLK_RESET_CCLK_BURST]
602 mov r0, #0
603 str r0, [r5, #CLK_RESET_CCLK_DIVIDER]
604 str r0, [r5, #CLK_RESET_SCLK_DIVIDER]
605
606 /* switch the clock source of mselect to be CLK_M */
607 ldr r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
608 orr r0, r0, #MSELECT_CLKM
609 str r0, [r5, #CLK_RESET_CLK_SOURCE_MSELECT]
610
611 /* 2uS delay delay between changing SCLK and disabling PLLs */
612 ldr r1, [r7]
613 add r1, r1, #2
614 wait_until r1, r7, r9
615
616 /* disable PLLM via PMC in LP1 */
617 ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
618 bic r0, r0, #(1 << 12)
619 str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
620
621 /* disable PLLP, PLLA, PLLC and PLLX */
622 ldr r0, [r5, #CLK_RESET_PLLP_BASE]
623 bic r0, r0, #(1 << 30)
624 str r0, [r5, #CLK_RESET_PLLP_BASE]
625 ldr r0, [r5, #CLK_RESET_PLLA_BASE]
626 bic r0, r0, #(1 << 30)
627 str r0, [r5, #CLK_RESET_PLLA_BASE]
628 ldr r0, [r5, #CLK_RESET_PLLC_BASE]
629 bic r0, r0, #(1 << 30)
630 str r0, [r5, #CLK_RESET_PLLC_BASE]
631 ldr r0, [r5, #CLK_RESET_PLLX_BASE]
632 bic r0, r0, #(1 << 30)
633 str r0, [r5, #CLK_RESET_PLLX_BASE]
634
635 cmp r10, #TEGRA30
636 beq _no_pll_in_iddq
637 pll_iddq_entry r1, r5, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
638_no_pll_in_iddq:
639
640 /* switch to CLKS */
641 mov r0, #0 /* brust policy = 32KHz */
642 str r0, [r5, #CLK_RESET_SCLK_BURST]
643
644 mov pc, lr
645
158/* 646/*
159 * tegra30_enter_sleep 647 * tegra30_enter_sleep
160 * 648 *
@@ -172,8 +660,12 @@ tegra30_enter_sleep:
172 orr r0, r0, #FLOW_CTRL_CSR_ENABLE 660 orr r0, r0, #FLOW_CTRL_CSR_ENABLE
173 str r0, [r6, r2] 661 str r0, [r6, r2]
174 662
663 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
664 cmp r10, #TEGRA30
175 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT 665 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
176 orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ 666 orreq r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
667 orrne r0, r0, #FLOW_CTRL_HALT_LIC_IRQ | FLOW_CTRL_HALT_LIC_FIQ
668
177 cpu_to_halt_reg r2, r1 669 cpu_to_halt_reg r2, r1
178 str r0, [r6, r2] 670 str r0, [r6, r2]
179 dsb 671 dsb
@@ -187,4 +679,126 @@ halted:
187 /* !!!FIXME!!! Implement halt failure handler */ 679 /* !!!FIXME!!! Implement halt failure handler */
188 b halted 680 b halted
189 681
682/*
683 * tegra30_sdram_self_refresh
684 *
685 * called with MMU off and caches disabled
686 * must be executed from IRAM
687 * r4 = TEGRA_PMC_BASE
688 * r5 = TEGRA_CLK_RESET_BASE
689 * r6 = TEGRA_FLOW_CTRL_BASE
690 * r7 = TEGRA_TMRUS_BASE
691 * r10= SoC ID
692 */
693tegra30_sdram_self_refresh:
694
695 adr r8, tegra30_sdram_pad_save
696 tegra_get_soc_id TEGRA_APB_MISC_BASE, r10
697 cmp r10, #TEGRA30
698 adreq r2, tegra30_sdram_pad_address
699 ldreq r3, tegra30_sdram_pad_size
700 adrne r2, tegra114_sdram_pad_address
701 ldrne r3, tegra114_sdram_pad_size
702 mov r9, #0
703
704padsave:
705 ldr r0, [r2, r9] @ r0 is the addr in the pad_address
706
707 ldr r1, [r0]
708 str r1, [r8, r9] @ save the content of the addr
709
710 add r9, r9, #4
711 cmp r3, r9
712 bne padsave
713padsave_done:
714
715 dsb
716
717 cmp r10, #TEGRA30
718 ldreq r0, =TEGRA_EMC_BASE @ r0 reserved for emc base addr
719 ldrne r0, =TEGRA_EMC0_BASE
720
721enter_self_refresh:
722 cmp r10, #TEGRA30
723 mov r1, #0
724 str r1, [r0, #EMC_ZCAL_INTERVAL]
725 str r1, [r0, #EMC_AUTO_CAL_INTERVAL]
726 ldr r1, [r0, #EMC_CFG]
727 bic r1, r1, #(1 << 28)
728 bicne r1, r1, #(1 << 29)
729 str r1, [r0, #EMC_CFG] @ disable DYN_SELF_REF
730
731 emc_timing_update r1, r0
732
733 ldr r1, [r7]
734 add r1, r1, #5
735 wait_until r1, r7, r2
736
737emc_wait_auto_cal:
738 ldr r1, [r0, #EMC_AUTO_CAL_STATUS]
739 tst r1, #(1 << 31) @ wait until AUTO_CAL_ACTIVE is cleared
740 bne emc_wait_auto_cal
741
742 mov r1, #3
743 str r1, [r0, #EMC_REQ_CTRL] @ stall incoming DRAM requests
744
745emcidle:
746 ldr r1, [r0, #EMC_EMC_STATUS]
747 tst r1, #4
748 beq emcidle
749
750 mov r1, #1
751 str r1, [r0, #EMC_SELF_REF]
752
753 emc_device_mask r1, r0
754
755emcself:
756 ldr r2, [r0, #EMC_EMC_STATUS]
757 and r2, r2, r1
758 cmp r2, r1
759 bne emcself @ loop until DDR in self-refresh
760
761 /* Put VTTGEN in the lowest power mode */
762 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL]
763 mov32 r2, 0xF8F8FFFF @ clear XM2VTTGEN_DRVUP and XM2VTTGEN_DRVDN
764 and r1, r1, r2
765 str r1, [r0, #EMC_XM2VTTGENPADCTRL]
766 ldr r1, [r0, #EMC_XM2VTTGENPADCTRL2]
767 cmp r10, #TEGRA30
768 orreq r1, r1, #7 @ set E_NO_VTTGEN
769 orrne r1, r1, #0x3f
770 str r1, [r0, #EMC_XM2VTTGENPADCTRL2]
771
772 emc_timing_update r1, r0
773
774 /* Tegra114 had dual EMC channel, now config the other one */
775 cmp r10, #TEGRA114
776 bne no_dual_emc_chanl
777 mov32 r1, TEGRA_EMC1_BASE
778 cmp r0, r1
779 movne r0, r1
780 bne enter_self_refresh
781no_dual_emc_chanl:
782
783 ldr r1, [r4, #PMC_CTRL]
784 tst r1, #PMC_CTRL_SIDE_EFFECT_LP0
785 bne pmc_io_dpd_skip
786 /*
787 * Put DDR_DATA, DISC_ADDR_CMD, DDR_ADDR_CMD, POP_ADDR_CMD, POP_CLK
788 * and COMP in the lowest power mode when LP1.
789 */
790 mov32 r1, 0x8EC00000
791 str r1, [r4, #PMC_IO_DPD_REQ]
792pmc_io_dpd_skip:
793
794 dsb
795
796 mov pc, lr
797
798 .ltorg
799/* dummy symbol for end of IRAM */
800 .align L1_CACHE_SHIFT
801 .global tegra30_iram_end
802tegra30_iram_end:
803 b .
190#endif 804#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 9daaef26b0f6..8d06213fbc47 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -56,7 +56,9 @@ ENTRY(tegra_disable_clean_inv_dcache)
56 isb 56 isb
57 57
58 /* Flush the D-cache */ 58 /* Flush the D-cache */
59 bl v7_flush_dcache_louis 59 cmp r0, #TEGRA_FLUSH_CACHE_ALL
60 blne v7_flush_dcache_louis
61 bleq v7_flush_dcache_all
60 62
61 /* Trun off coherency */ 63 /* Trun off coherency */
62 exit_smp r4, r5 64 exit_smp r4, r5
@@ -67,15 +69,40 @@ ENDPROC(tegra_disable_clean_inv_dcache)
67 69
68#ifdef CONFIG_PM_SLEEP 70#ifdef CONFIG_PM_SLEEP
69/* 71/*
72 * tegra_init_l2_for_a15
73 *
74 * set up the correct L2 cache data RAM latency
75 */
76ENTRY(tegra_init_l2_for_a15)
77 mrc p15, 0, r0, c0, c0, 5
78 ubfx r0, r0, #8, #4
79 tst r0, #1 @ only need for cluster 0
80 bne _exit_init_l2_a15
81
82 mrc p15, 0x1, r0, c9, c0, 2
83 and r0, r0, #7
84 cmp r0, #2
85 bicne r0, r0, #7
86 orrne r0, r0, #2
87 mcrne p15, 0x1, r0, c9, c0, 2
88_exit_init_l2_a15:
89
90 mov pc, lr
91ENDPROC(tegra_init_l2_for_a15)
92
93/*
70 * tegra_sleep_cpu_finish(unsigned long v2p) 94 * tegra_sleep_cpu_finish(unsigned long v2p)
71 * 95 *
72 * enters suspend in LP2 by turning off the mmu and jumping to 96 * enters suspend in LP2 by turning off the mmu and jumping to
73 * tegra?_tear_down_cpu 97 * tegra?_tear_down_cpu
74 */ 98 */
75ENTRY(tegra_sleep_cpu_finish) 99ENTRY(tegra_sleep_cpu_finish)
100 mov r4, r0
76 /* Flush and disable the L1 data cache */ 101 /* Flush and disable the L1 data cache */
102 mov r0, #TEGRA_FLUSH_CACHE_ALL
77 bl tegra_disable_clean_inv_dcache 103 bl tegra_disable_clean_inv_dcache
78 104
105 mov r0, r4
79 mov32 r6, tegra_tear_down_cpu 106 mov32 r6, tegra_tear_down_cpu
80 ldr r1, [r6] 107 ldr r1, [r6]
81 add r1, r1, r0 108 add r1, r1, r0
@@ -107,10 +134,10 @@ ENTRY(tegra_shut_off_mmu)
107#ifdef CONFIG_CACHE_L2X0 134#ifdef CONFIG_CACHE_L2X0
108 /* Disable L2 cache */ 135 /* Disable L2 cache */
109 check_cpu_part_num 0xc09, r9, r10 136 check_cpu_part_num 0xc09, r9, r10
110 movweq r4, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000) 137 movweq r2, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
111 movteq r4, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000) 138 movteq r2, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
112 moveq r5, #0 139 moveq r3, #0
113 streq r5, [r4, #L2X0_CTRL] 140 streq r3, [r2, #L2X0_CTRL]
114#endif 141#endif
115 mov pc, r0 142 mov pc, r0
116ENDPROC(tegra_shut_off_mmu) 143ENDPROC(tegra_shut_off_mmu)
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 98b7da698f2b..a4edbb3abd3d 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -41,7 +41,19 @@
41#define CPU_NOT_RESETTABLE 0 41#define CPU_NOT_RESETTABLE 0
42#endif 42#endif
43 43
44/* flag of tegra_disable_clean_inv_dcache to do LoUIS or all */
45#define TEGRA_FLUSH_CACHE_LOUIS 0
46#define TEGRA_FLUSH_CACHE_ALL 1
47
44#ifdef __ASSEMBLY__ 48#ifdef __ASSEMBLY__
49/* waits until the microsecond counter (base) is > rn */
50.macro wait_until, rn, base, tmp
51 add \rn, \rn, #1
521001: ldr \tmp, [\base]
53 cmp \tmp, \rn
54 bmi 1001b
55.endm
56
45/* returns the offset of the flow controller halt register for a cpu */ 57/* returns the offset of the flow controller halt register for a cpu */
46.macro cpu_to_halt_reg rd, rcpu 58.macro cpu_to_halt_reg rd, rcpu
47 cmp \rcpu, #0 59 cmp \rcpu, #0
@@ -144,7 +156,7 @@ void tegra_pen_lock(void);
144void tegra_pen_unlock(void); 156void tegra_pen_unlock(void);
145void tegra_resume(void); 157void tegra_resume(void);
146int tegra_sleep_cpu_finish(unsigned long); 158int tegra_sleep_cpu_finish(unsigned long);
147void tegra_disable_clean_inv_dcache(void); 159void tegra_disable_clean_inv_dcache(u32 flag);
148 160
149#ifdef CONFIG_HOTPLUG_CPU 161#ifdef CONFIG_HOTPLUG_CPU
150void tegra20_hotplug_shutdown(void); 162void tegra20_hotplug_shutdown(void);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 0d1e4128d460..fe56fcafdf15 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -116,28 +116,6 @@ out:
116 tegra20_auxdata_lookup, parent); 116 tegra20_auxdata_lookup, parent);
117} 117}
118 118
119static void __init trimslice_init(void)
120{
121#ifdef CONFIG_TEGRA_PCI
122 int ret;
123
124 ret = tegra_pcie_init(true, true);
125 if (ret)
126 pr_err("tegra_pci_init() failed: %d\n", ret);
127#endif
128}
129
130static void __init harmony_init(void)
131{
132#ifdef CONFIG_TEGRA_PCI
133 int ret;
134
135 ret = harmony_pcie_init();
136 if (ret)
137 pr_err("harmony_pcie_init() failed: %d\n", ret);
138#endif
139}
140
141static void __init paz00_init(void) 119static void __init paz00_init(void)
142{ 120{
143 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) 121 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
@@ -148,8 +126,6 @@ static struct {
148 char *machine; 126 char *machine;
149 void (*init)(void); 127 void (*init)(void);
150} board_init_funcs[] = { 128} board_init_funcs[] = {
151 { "compulab,trimslice", trimslice_init },
152 { "nvidia,harmony", harmony_init },
153 { "compal,paz00", paz00_init }, 129 { "compal,paz00", paz00_init },
154}; 130};
155 131