Merge tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorArnd Bergmann <arnd@arndb.de>
Tue, 9 Apr 2013 13:27:52 +0000 (15:27 +0200)
committerArnd Bergmann <arnd@arndb.de>
Tue, 9 Apr 2013 13:27:52 +0000 (15:27 +0200)
From Stephen Warren <swarren@wwwdotorg.org>:

ARM: tegra: cleanup

This branch includes various cleanup of the core Tegra support.

* Unification of the separate board-dt-tegra*.c files into a single
  tegra.c, now that everything is DT-driven and basically identical.
* Use of_clk_get() in the Tegra clocksource driver so that clocks are
  described in DT rather than hard-coding clock names.
* Some cleanup of the PMC-related code, with the aim that the PMC
  "driver" contains more of the code that touches PMC registers, rather
  than spreading PMC register accesses through other files.
* Conversion of the "PMC" driver to acquire resources describe in device
  tree rather than hard-coding them.
* Use of common code for the CPU sleep TLB invalidation.

This branch is based on the previous fixes pull request.

* tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
  ARM: tegra: use setup_mm_for_reboot rather than explicit pgd switch
  ARM: tegra: replace the CPU power on function with PMC call
  ARM: tegra: pmc: add power on function for secondary CPUs
  ARM: tegra: pmc: convert PMC driver to support DT only
  ARM: tegra: fix the PMC compatible string in DT
  ARM: tegra: pmc: add specific compatible DT string for Tegra30 and Tegra114
  ARM: tegra: refactor tegra{20,30}_boot_secondary
  clocksource: tegra: move to of_clk_get
  ARM: tegra: Unify Device tree board files
  ARM: tegra: Rename board-dt-tegra20.c to tegra.c
  ARM: tegra: Unify tegra{20,30,114}_init_early()

Conflicts:
drivers/clocksource/tegra20_timer.c

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
17 files changed:
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-dt-tegra114.c [deleted file]
arch/arm/mach-tegra/board-dt-tegra20.c [deleted file]
arch/arm/mach-tegra/board-dt-tegra30.c [deleted file]
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pmc.c
arch/arm/mach-tegra/pmc.h
arch/arm/mach-tegra/sleep.h
arch/arm/mach-tegra/tegra.c [new file with mode: 0644]
drivers/clocksource/tegra20_timer.c

index 1dfaf2874c57261a2c108073ed47d2131c3188eb..e4ddeddcd437459f70faa3787aa28f13b4f926e1 100644 (file)
@@ -99,7 +99,7 @@
        };
 
        pmc {
-               compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc";
+               compatible = "nvidia,tegra114-pmc";
                reg = <0x7000e400 0x400>;
        };
 
index 48d00a099ce38d75d0df6ceb513078383c8d54e5..de3f5d7530bc6d2d24b3a2b6e67133cc2ce4c2c1 100644 (file)
                              0 1 0x04
                              0 41 0x04
                              0 42 0x04>;
+               clocks = <&tegra_car 5>;
        };
 
        tegra_car: clock {
                compatible = "nvidia,tegra20-rtc";
                reg = <0x7000e000 0x100>;
                interrupts = <0 2 0x04>;
+               clocks = <&tegra_car 4>;
        };
 
        i2c@7000c000 {
index 9d87a3ffe9980a140585d063dbb9be5f2fbfa482..eddd0f9f7b5ee38932d97b6e7cf2443c34377a85 100644 (file)
                              0 42 0x04
                              0 121 0x04
                              0 122 0x04>;
+               clocks = <&tegra_car 5>;
        };
 
        tegra_car: clock {
                compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
                reg = <0x7000e000 0x100>;
                interrupts = <0 2 0x04>;
+               clocks = <&tegra_car 4>;
        };
 
        i2c@7000c000 {
        };
 
        pmc {
-               compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+               compatible = "nvidia,tegra30-pmc";
                reg = <0x7000e400 0x400>;
        };
 
index f6b46ae2b7f868829310fa22295d251eda20b95b..92703f955a373831cf92d796240ee998a4f0fadf 100644 (file)
@@ -10,6 +10,7 @@ obj-y                                 += pm.o
 obj-y                                  += reset.o
 obj-y                                  += reset-handler.o
 obj-y                                  += sleep.o
+obj-y                                  += tegra.o
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra20_speedo.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
@@ -27,9 +28,6 @@ obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 obj-$(CONFIG_TEGRA_PCI)                        += pcie.o
 
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += board-dt-tegra20.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += board-dt-tegra30.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += board-dt-tegra114.o
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += cpuidle-tegra114.o
 endif
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c
deleted file mode 100644 (file)
index 085d636..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * NVIDIA Tegra114 device tree board support
- *
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/clocksource.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-
-static void __init tegra114_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const tegra114_dt_board_compat[] = {
-       "nvidia,tegra114",
-       NULL,
-};
-
-DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
-       .smp            = smp_ops(tegra_smp_ops),
-       .map_io         = tegra_map_common_io,
-       .init_early     = tegra114_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra114_dt_init,
-       .init_late      = tegra_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra114_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
deleted file mode 100644 (file)
index a0edf25..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * nVidia Tegra device tree board support
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/irqdomain.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <linux/pda_power.h>
-#include <linux/platform_data/tegra_usb.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c-tegra.h>
-#include <linux/usb/tegra_usb_phy.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/setup.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
-       .operating_mode = TEGRA_USB_OTG,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
-       .reset_gpio = -1,
-       .clk = "cdev2",
-};
-
-static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
-       .phy_config = &tegra_ehci2_ulpi_phy_config,
-       .operating_mode = TEGRA_USB_HOST,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
-       .operating_mode = TEGRA_USB_HOST,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
-                      &tegra_ehci1_pdata),
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
-                      &tegra_ehci2_pdata),
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
-                      &tegra_ehci3_pdata),
-       {}
-};
-
-static void __init tegra_dt_init(void)
-{
-       /*
-        * Finished with the static registrations now; fill in the missing
-        * devices
-        */
-       of_platform_populate(NULL, of_default_bus_match_table,
-                               tegra20_auxdata_lookup, NULL);
-}
-
-static void __init trimslice_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
-       int ret;
-
-       ret = tegra_pcie_init(true, true);
-       if (ret)
-               pr_err("tegra_pci_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init harmony_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
-       int ret;
-
-       ret = harmony_pcie_init();
-       if (ret)
-               pr_err("harmony_pcie_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init paz00_init(void)
-{
-       tegra_paz00_wifikill_init();
-}
-
-static struct {
-       char *machine;
-       void (*init)(void);
-} board_init_funcs[] = {
-       { "compulab,trimslice", trimslice_init },
-       { "nvidia,harmony", harmony_init },
-       { "compal,paz00", paz00_init },
-};
-
-static void __init tegra_dt_init_late(void)
-{
-       int i;
-
-       tegra_init_late();
-
-       for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
-               if (of_machine_is_compatible(board_init_funcs[i].machine)) {
-                       board_init_funcs[i].init();
-                       break;
-               }
-       }
-}
-
-static const char *tegra20_dt_board_compat[] = {
-       "nvidia,tegra20",
-       NULL
-};
-
-DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
-       .map_io         = tegra_map_common_io,
-       .smp            = smp_ops(tegra_smp_ops),
-       .init_early     = tegra20_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra_dt_init,
-       .init_late      = tegra_dt_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra20_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
deleted file mode 100644 (file)
index bf68567..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/arm/mach-tegra/board-dt-tegra30.c
- *
- * NVIDIA Tegra30 device tree board support
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Derived from:
- *
- * arch/arm/mach-tegra/board-dt-tegra20.c
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static void __init tegra30_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *tegra30_dt_board_compat[] = {
-       "nvidia,tegra30",
-       NULL
-};
-
-DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
-       .smp            = smp_ops(tegra_smp_ops),
-       .map_io         = tegra_map_common_io,
-       .init_early     = tegra30_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra30_dt_init,
-       .init_late      = tegra_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra30_dt_board_compat,
-MACHINE_END
index 86851c81a35093a44df58a52472be5d9ed2d7229..60431de585ca71c5a42c3646227cf80338ec4aec 100644 (file)
@@ -26,9 +26,7 @@
 
 void tegra_assert_system_reset(char mode, const char *cmd);
 
-void __init tegra20_init_early(void);
-void __init tegra30_init_early(void);
-void __init tegra114_init_early(void);
+void __init tegra_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
 void __init tegra_dt_init_irq(void);
index 5449a3f2977bc5d642891e00ce93087947ed17d8..f0315c95c76d552485af66495c24fec61030faa1 100644 (file)
@@ -94,7 +94,7 @@ static void __init tegra_init_cache(void)
 
 }
 
-static void __init tegra_init_early(void)
+void __init tegra_init_early(void)
 {
        tegra_cpu_reset_handler_init();
        tegra_apb_io_init();
@@ -102,31 +102,9 @@ static void __init tegra_init_early(void)
        tegra_init_cache();
        tegra_pmc_init();
        tegra_powergate_init();
+       tegra_hotplug_init();
 }
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void __init tegra20_init_early(void)
-{
-       tegra_init_early();
-       tegra20_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void __init tegra30_init_early(void)
-{
-       tegra_init_early();
-       tegra30_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void __init tegra114_init_early(void)
-{
-       tegra_init_early();
-}
-#endif
-
 void __init tegra_init_late(void)
 {
        tegra_powergate_debugfs_init();
index a599f6e36dea49768c6eb18d9550b3d04fb9c1db..8da9f78475da21f81ef314bbd7e9e04939398378 100644 (file)
@@ -1,8 +1,7 @@
 /*
- *
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
+ *  Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -15,6 +14,7 @@
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 
+#include "fuse.h"
 #include "sleep.h"
 
 static void (*tegra_hotplug_shutdown)(void);
@@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
        return cpu == 0 ? -EPERM : 0;
 }
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-extern void tegra20_hotplug_shutdown(void);
-void __init tegra20_hotplug_init(void)
+void __init tegra_hotplug_init(void)
 {
-       tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
-}
-#endif
+       if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
+               return;
 
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-extern void tegra30_hotplug_shutdown(void);
-void __init tegra30_hotplug_init(void)
-{
-       tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+               tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+               tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
 }
-#endif
index fb86a00ce254cbef1dab3843024dbc51b6437961..c31db797e199243b7d40e98f30e8ded550e8d118 100644 (file)
 #include <asm/smp_scu.h>
 #include <asm/smp_plat.h>
 
-#include <mach/powergate.h>
-
 #include "fuse.h"
 #include "flowctrl.h"
 #include "reset.h"
+#include "pmc.h"
 
 #include "common.h"
 #include "iomap.h"
 
-extern void tegra_secondary_startup(void);
-
 static cpumask_t tegra_cpu_init_mask;
 
-#define EVP_CPU_RESET_VECTOR \
-       (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
-
 static void __cpuinit tegra_secondary_init(unsigned int cpu)
 {
        cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
 }
 
-static int tegra20_power_up_cpu(unsigned int cpu)
+
+static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       /* Enable the CPU clock. */
-       tegra_enable_cpu_clock(cpu);
+       cpu = cpu_logical_map(cpu);
 
-       /* Clear flow controller CSR. */
-       flowctrl_write_cpu_csr(cpu, 0);
+       /*
+        * Force the CPU into reset. The CPU must remain in reset when
+        * the flow controller state is cleared (which will cause the
+        * flow controller to stop driving reset if the CPU has been
+        * power-gated via the flow controller). This will have no
+        * effect on first boot of the CPU since it should already be
+        * in reset.
+        */
+       tegra_put_cpu_in_reset(cpu);
 
+       /*
+        * Unhalt the CPU. If the flow controller was used to
+        * power-gate the CPU this will cause the flow controller to
+        * stop driving reset. The CPU will remain in reset because the
+        * clock and reset block is now driving reset.
+        */
+       flowctrl_write_cpu_halt(cpu, 0);
+
+       tegra_enable_cpu_clock(cpu);
+       flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+       tegra_cpu_out_of_reset(cpu);
        return 0;
 }
 
-static int tegra30_power_up_cpu(unsigned int cpu)
+static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int ret, pwrgateid;
+       int ret;
        unsigned long timeout;
 
-       pwrgateid = tegra_cpu_powergate_id(cpu);
-       if (pwrgateid < 0)
-               return pwrgateid;
+       cpu = cpu_logical_map(cpu);
+       tegra_put_cpu_in_reset(cpu);
+       flowctrl_write_cpu_halt(cpu, 0);
 
        /*
         * The power up sequence of cold boot CPU and warm boot CPU
@@ -77,13 +89,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
         * the IO clamps.
         * For cold boot CPU, do not wait. After the cold boot CPU be
         * booted, it will run to tegra_secondary_init() and set
-        * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
+        * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
         * next time around.
         */
        if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
                timeout = jiffies + msecs_to_jiffies(50);
                do {
-                       if (tegra_powergate_is_powered(pwrgateid))
+                       if (tegra_pmc_cpu_is_powered(cpu))
                                goto remove_clamps;
                        udelay(10);
                } while (time_before(jiffies, timeout));
@@ -95,14 +107,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
         * be un-gated by un-toggling the power gate register
         * manually.
         */
-       if (!tegra_powergate_is_powered(pwrgateid)) {
-               ret = tegra_powergate_power_on(pwrgateid);
+       if (!tegra_pmc_cpu_is_powered(cpu)) {
+               ret = tegra_pmc_cpu_power_on(cpu);
                if (ret)
                        return ret;
 
                /* Wait for the power to come up. */
                timeout = jiffies + msecs_to_jiffies(100);
-               while (tegra_powergate_is_powered(pwrgateid)) {
+               while (tegra_pmc_cpu_is_powered(cpu)) {
                        if (time_after(jiffies, timeout))
                                return -ETIMEDOUT;
                        udelay(10);
@@ -115,60 +127,26 @@ remove_clamps:
        udelay(10);
 
        /* Remove I/O clamps. */
-       ret = tegra_powergate_remove_clamping(pwrgateid);
+       ret = tegra_pmc_cpu_remove_clamping(cpu);
        if (ret)
                return ret;
 
        udelay(10);
 
-       /* Clear flow controller CSR. */
-       flowctrl_write_cpu_csr(cpu, 0);
-
+       flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+       tegra_cpu_out_of_reset(cpu);
        return 0;
 }
 
-static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit tegra_boot_secondary(unsigned int cpu,
+                                         struct task_struct *idle)
 {
-       int status;
-
-       cpu = cpu_logical_map(cpu);
-
-       /*
-        * Force the CPU into reset. The CPU must remain in reset when the
-        * flow controller state is cleared (which will cause the flow
-        * controller to stop driving reset if the CPU has been power-gated
-        * via the flow controller). This will have no effect on first boot
-        * of the CPU since it should already be in reset.
-        */
-       tegra_put_cpu_in_reset(cpu);
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+               return tegra20_boot_secondary(cpu, idle);
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+               return tegra30_boot_secondary(cpu, idle);
 
-       /*
-        * Unhalt the CPU. If the flow controller was used to power-gate the
-        * CPU this will cause the flow controller to stop driving reset.
-        * The CPU will remain in reset because the clock and reset block
-        * is now driving reset.
-        */
-       flowctrl_write_cpu_halt(cpu, 0);
-
-       switch (tegra_chip_id) {
-       case TEGRA20:
-               status = tegra20_power_up_cpu(cpu);
-               break;
-       case TEGRA30:
-               status = tegra30_power_up_cpu(cpu);
-               break;
-       default:
-               status = -EINVAL;
-               break;
-       }
-
-       if (status)
-               goto done;
-
-       /* Take the CPU out of reset. */
-       tegra_cpu_out_of_reset(cpu);
-done:
-       return status;
+       return -EINVAL;
 }
 
 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
index 0494f739c95f935975787d563169d95eca40dbed..acacbe8d1afcc83d171206cc417db6f832aecd56 100644 (file)
@@ -164,12 +164,7 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id)
 
 static int tegra_sleep_cpu(unsigned long v2p)
 {
-       /* Switch to the identity mapping. */
-       cpu_switch_mm(idmap_pgd, &init_mm);
-
-       /* Flush the TLB. */
-       local_flush_tlb_all();
-
+       setup_mm_for_reboot();
        tegra_sleep_cpu_finish(v2p);
 
        /* should never here */
index d4fdb5fcec20955c95a4f0199efb1ae180f72409..b30e921cc3a9c88b5295cb825b9f3a162f1cd20c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 
-#include "iomap.h"
+#define PMC_CTRL                       0x0
+#define PMC_CTRL_INTR_LOW              (1 << 17)
+#define PMC_PWRGATE_TOGGLE             0x30
+#define PMC_PWRGATE_TOGGLE_START       (1 << 8)
+#define PMC_REMOVE_CLAMPING            0x34
+#define PMC_PWRGATE_STATUS             0x38
 
-#define PMC_CTRL               0x0
-#define PMC_CTRL_INTR_LOW      (1 << 17)
+#define TEGRA_POWERGATE_PCIE   3
+#define TEGRA_POWERGATE_VDEC   4
+#define TEGRA_POWERGATE_CPU1   9
+#define TEGRA_POWERGATE_CPU2   10
+#define TEGRA_POWERGATE_CPU3   11
+
+static u8 tegra_cpu_domains[] = {
+       0xFF,                   /* not available for CPU0 */
+       TEGRA_POWERGATE_CPU1,
+       TEGRA_POWERGATE_CPU2,
+       TEGRA_POWERGATE_CPU3,
+};
+static DEFINE_SPINLOCK(tegra_powergate_lock);
+
+static void __iomem *tegra_pmc_base;
+static bool tegra_pmc_invert_interrupt;
 
 static inline u32 tegra_pmc_readl(u32 reg)
 {
-       return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+       return readl(tegra_pmc_base + reg);
 }
 
 static inline void tegra_pmc_writel(u32 val, u32 reg)
 {
-       writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+       writel(val, tegra_pmc_base + reg);
+}
+
+static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
+{
+       if (cpuid <= 0 || cpuid >= num_possible_cpus())
+               return -EINVAL;
+       return tegra_cpu_domains[cpuid];
+}
+
+static bool tegra_pmc_powergate_is_powered(int id)
+{
+       return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
+}
+
+static int tegra_pmc_powergate_set(int id, bool new_state)
+{
+       bool old_state;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+       old_state = tegra_pmc_powergate_is_powered(id);
+       WARN_ON(old_state == new_state);
+
+       tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
+
+       spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+       return 0;
+}
+
+static int tegra_pmc_powergate_remove_clamping(int id)
+{
+       u32 mask;
+
+       /*
+        * Tegra has a bug where PCIE and VDE clamping masks are
+        * swapped relatively to the partition ids.
+        */
+       if (id ==  TEGRA_POWERGATE_VDEC)
+               mask = (1 << TEGRA_POWERGATE_PCIE);
+       else if (id == TEGRA_POWERGATE_PCIE)
+               mask = (1 << TEGRA_POWERGATE_VDEC);
+       else
+               mask = (1 << id);
+
+       tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
+
+       return 0;
+}
+
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return false;
+       return tegra_pmc_powergate_is_powered(id);
+}
+
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return id;
+       return tegra_pmc_powergate_set(id, true);
+}
+
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return id;
+       return tegra_pmc_powergate_remove_clamping(id);
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id matches[] __initconst = {
+       { .compatible = "nvidia,tegra114-pmc" },
+       { .compatible = "nvidia,tegra30-pmc" },
        { .compatible = "nvidia,tegra20-pmc" },
        { }
 };
-#endif
 
-void __init tegra_pmc_init(void)
+static void tegra_pmc_parse_dt(void)
 {
-       /*
-        * For now, Harmony is the only board that uses the PMC, and it wants
-        * the signal inverted. Seaboard would too if it used the PMC.
-        * Hopefully by the time other boards want to use the PMC, everything
-        * will be device-tree, or they also want it inverted.
-        */
-       bool invert_interrupt = true;
-       u32 val;
+       struct device_node *np;
 
-#ifdef CONFIG_OF
-       if (of_have_populated_dt()) {
-               struct device_node *np;
+       np = of_find_matching_node(NULL, matches);
+       BUG_ON(!np);
 
-               invert_interrupt = false;
+       tegra_pmc_base = of_iomap(np, 0);
+
+       tegra_pmc_invert_interrupt = of_property_read_bool(np,
+                                    "nvidia,invert-interrupt");
+}
+
+void __init tegra_pmc_init(void)
+{
+       u32 val;
 
-               np = of_find_matching_node(NULL, matches);
-               if (np) {
-                       if (of_find_property(np, "nvidia,invert-interrupt",
-                                               NULL))
-                               invert_interrupt = true;
-               }
-       }
-#endif
+       tegra_pmc_parse_dt();
 
        val = tegra_pmc_readl(PMC_CTRL);
-       if (invert_interrupt)
+       if (tegra_pmc_invert_interrupt)
                val |= PMC_CTRL_INTR_LOW;
        else
                val &= ~PMC_CTRL_INTR_LOW;
index 8995ee4a87681dd80a63c990b05c324955261f24..7d44710368bea565cd0b9f66022d25909d55ca5b 100644 (file)
 #ifndef __MACH_TEGRA_PMC_H
 #define __MACH_TEGRA_PMC_H
 
+bool tegra_pmc_cpu_is_powered(int cpuid);
+int tegra_pmc_cpu_power_on(int cpuid);
+int tegra_pmc_cpu_remove_clamping(int cpuid);
+
 void tegra_pmc_init(void);
 
 #endif
index 4ffae541726e1d258502007482e37585e33ad4ee..970ebd5138b99bf0a6d9cf682cee836b1f5cd5e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
 void tegra_disable_clean_inv_dcache(void);
 
 #ifdef CONFIG_HOTPLUG_CPU
-void tegra20_hotplug_init(void);
-void tegra30_hotplug_init(void);
+void tegra20_hotplug_shutdown(void);
+void tegra30_hotplug_shutdown(void);
+void tegra_hotplug_init(void);
 #else
-static inline void tegra20_hotplug_init(void) {}
-static inline void tegra30_hotplug_init(void) {}
+static inline void tegra_hotplug_init(void) {}
 #endif
 
 void tegra20_cpu_shutdown(int cpu);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
new file mode 100644 (file)
index 0000000..27232c9
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * NVIDIA Tegra SoC device tree board support
+ *
+ * Copyright (C) 2011, 2013, NVIDIA Corporation
+ * Copyright (C) 2010 Secret Lab Technologies, Ltd.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clocksource.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/pda_power.h>
+#include <linux/platform_data/tegra_usb.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+#include <linux/usb/tegra_usb_phy.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include "board.h"
+#include "common.h"
+#include "iomap.h"
+
+static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
+       .operating_mode = TEGRA_USB_OTG,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
+       .reset_gpio = -1,
+       .clk = "cdev2",
+};
+
+static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
+       .phy_config = &tegra_ehci2_ulpi_phy_config,
+       .operating_mode = TEGRA_USB_HOST,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
+       .operating_mode = TEGRA_USB_HOST,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
+                      &tegra_ehci1_pdata),
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
+                      &tegra_ehci2_pdata),
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
+                      &tegra_ehci3_pdata),
+       {}
+};
+
+static void __init tegra_dt_init(void)
+{
+       /*
+        * Finished with the static registrations now; fill in the missing
+        * devices
+        */
+       of_platform_populate(NULL, of_default_bus_match_table,
+                               tegra20_auxdata_lookup, NULL);
+}
+
+static void __init trimslice_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+       int ret;
+
+       ret = tegra_pcie_init(true, true);
+       if (ret)
+               pr_err("tegra_pci_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init harmony_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+       int ret;
+
+       ret = harmony_pcie_init();
+       if (ret)
+               pr_err("harmony_pcie_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init paz00_init(void)
+{
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+               tegra_paz00_wifikill_init();
+}
+
+static struct {
+       char *machine;
+       void (*init)(void);
+} board_init_funcs[] = {
+       { "compulab,trimslice", trimslice_init },
+       { "nvidia,harmony", harmony_init },
+       { "compal,paz00", paz00_init },
+};
+
+static void __init tegra_dt_init_late(void)
+{
+       int i;
+
+       tegra_init_late();
+
+       for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
+               if (of_machine_is_compatible(board_init_funcs[i].machine)) {
+                       board_init_funcs[i].init();
+                       break;
+               }
+       }
+}
+
+static const char * const tegra_dt_board_compat[] = {
+       "nvidia,tegra114",
+       "nvidia,tegra30",
+       "nvidia,tegra20",
+       NULL
+};
+
+DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
+       .map_io         = tegra_map_common_io,
+       .smp            = smp_ops(tegra_smp_ops),
+       .init_early     = tegra_init_early,
+       .init_irq       = tegra_dt_init_irq,
+       .init_time      = clocksource_of_init,
+       .init_machine   = tegra_dt_init,
+       .init_late      = tegra_dt_init_late,
+       .restart        = tegra_assert_system_reset,
+       .dt_compat      = tegra_dt_board_compat,
+MACHINE_END
index 2e4d8a666c36d6ee40db523408f34a8b5927bebf..ae877b021b54449219cef0d1f3e43fe442c54bca 100644 (file)
@@ -172,7 +172,7 @@ static void __init tegra20_init_timer(struct device_node *np)
                BUG();
        }
 
-       clk = clk_get_sys("timer", NULL);
+       clk = of_clk_get(np, 0);
        if (IS_ERR(clk)) {
                pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
                rate = 12000000;
@@ -235,7 +235,7 @@ static void __init tegra20_init_rtc(struct device_node *np)
         * rtc registers are used by read_persistent_clock, keep the rtc clock
         * enabled
         */
-       clk = clk_get_sys("rtc-tegra", NULL);
+       clk = of_clk_get(np, 0);
        if (IS_ERR(clk))
                pr_warn("Unable to get rtc-tegra clock\n");
        else