Add NVIDIA Tegra FUSE driver
Subsystems (6)
cover Add NVIDIA Tegra FUSE driver
From: Thierry Reding <[email protected]>
This series is an extension of Peter's original series to add a proper driver for the FUSE block on Tegra.
Patches 1 and 2 are preparatory work that cleans up include lists and introduces a function to query the Tegra chip ID rather than accessing a simple variable. This is used by subsequent patches to allow us to execute code when the variable is accessed to help in pin-pointing locations where it's accessed before the driver had a chance to initialize.
Patches 3 through 8 are Peter's series with a fixup patch by Stephen. I also moved the driver to drivers/soc/tegra/fuse as requested by Olof.
Patches 9 and 10 defer usages of the tegra_get_chip_id() function to a later stage (pure_initcall). This allows patch 11 to set up the early FUSE support code from an early initcall. This has the advantage of not requiring an explicit call from SoC setup code in arch/arm/mach-tegra and will allow the code to be shared on 64-bit variants of Tegra.
Patch 12 finally turns the PMC and powergate support code into a proper driver which also sets up a minimal environment from an early initcall. The driver isn't moved out of arch/arm/mach-tegra yet because people have suggested drivers/power as a good home, but that whole directory depends on the POWER_SUPPLY Kconfig symbol yet this driver doesn't have anything to do with that. Once that debate has been settled the driver can easily be moved out in a separate patch.
Some of the patches in this series introduce diagnostic WARN() messages if functions are called without setup having completed. I've booted the v3.16-rc1 kernel with these changes on top on Tegra20 (TrimSlice), Tegra30 (Beaver), Tegra114 (Dalmore) and Tegra124 (Jetson TK1) without encountering any of the diagnostic warnings and without noticing any breakage.
Olof, this series should address the concerns you expressed after reviewing Stephen's earlier pull request for Peter's FUSE driver series. It would be great if you could take another look to see if this is more according to your taste. I'll see if I can take this through linux-next for a little and if you have no objections will submit another pull request next week.
Thierry
Peter De Schrijver (5):
ARM: tegra: export apb dma readl/writel
ARM: tegra: move fuse exports to tegra-soc.h soc/tegra: Add efuse driver for Tegra soc/tegra: Add efuse and apbmisc bindings soc/tegra: fuse: move APB DMA into Tegra20 fuse driver
Stephen Warren (1):
misc: fuse: fix dummy functions
Thierry Reding (6):
ARM: tegra: Sort includes alphabetically
ARM: tegra: Use a function to get the chip ID
ARM: tegra: Setup CPU hotplug in a pure initcall
ARM: tegra: Always lock the CPU reset vector soc/tegra: fuse: Set up in early initcall
ARM: tegra: Convert PMC to a driver
Documentation/ABI/testing/sysfs-driver-tegra-fuse | 11 + .../bindings/fuse/nvidia,tegra20-fuse.txt | 40 + .../bindings/misc/nvidia,tegra20-apbmisc.txt | 13 + arch/arm/boot/dts/tegra114.dtsi | 15 + arch/arm/boot/dts/tegra124.dtsi | 15 + arch/arm/boot/dts/tegra20.dtsi | 15 + arch/arm/boot/dts/tegra30.dtsi | 15 + arch/arm/mach-tegra/Makefile | 8 +- arch/arm/mach-tegra/apbio.c | 206 ----- arch/arm/mach-tegra/apbio.h | 22 - arch/arm/mach-tegra/board-paz00.c | 3 +- arch/arm/mach-tegra/board.h | 7 - arch/arm/mach-tegra/cpuidle-tegra114.c | 10 +- arch/arm/mach-tegra/cpuidle-tegra20.c | 16 +- arch/arm/mach-tegra/cpuidle-tegra30.c | 10 +- arch/arm/mach-tegra/cpuidle.c | 6 +- arch/arm/mach-tegra/flowctrl.c | 10 +- arch/arm/mach-tegra/fuse.c | 252 ------ arch/arm/mach-tegra/fuse.h | 79 -- arch/arm/mach-tegra/hotplug.c | 25 +- arch/arm/mach-tegra/io.c | 8 +- arch/arm/mach-tegra/irq.c | 8 +- arch/arm/mach-tegra/platsmp.c | 27 +- arch/arm/mach-tegra/pm-tegra20.c | 1 + arch/arm/mach-tegra/pm-tegra30.c | 1 + arch/arm/mach-tegra/pm.c | 60 +- arch/arm/mach-tegra/pm.h | 10 +- arch/arm/mach-tegra/pmc.c | 413 --------- arch/arm/mach-tegra/pmc.h | 49 -- arch/arm/mach-tegra/powergate.c | 515 ----------- arch/arm/mach-tegra/reset-handler.S | 6 +- arch/arm/mach-tegra/reset.c | 18 +- arch/arm/mach-tegra/sleep-tegra30.S | 6 +- arch/arm/mach-tegra/sleep.h | 3 - arch/arm/mach-tegra/tegra-pmc.c | 948 +++++++++++++++++++++ arch/arm/mach-tegra/tegra.c | 35 +- drivers/misc/fuse/Makefile | 1 + drivers/soc/Makefile | 1 + drivers/soc/tegra/Makefile | 1 + drivers/soc/tegra/fuse/Makefile | 8 + drivers/soc/tegra/fuse/fuse-tegra.c | 158 ++++ drivers/soc/tegra/fuse/fuse-tegra20.c | 214 +++++ drivers/soc/tegra/fuse/fuse-tegra30.c | 223 +++++ drivers/soc/tegra/fuse/fuse.h | 71 ++ .../soc/tegra/fuse/speedo-tegra114.c | 53 +- drivers/soc/tegra/fuse/speedo-tegra124.c | 167 ++++ .../soc/tegra/fuse/speedo-tegra20.c | 42 +- .../soc/tegra/fuse/speedo-tegra30.c | 173 ++-- drivers/soc/tegra/fuse/tegra-apbmisc.c | 114 +++ include/linux/tegra-soc.h | 89 ++ 50 files changed, 2387 insertions(+), 1814 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-driver-tegra-fuse create mode 100644 Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt delete mode 100644 arch/arm/mach-tegra/apbio.c delete mode 100644 arch/arm/mach-tegra/apbio.h delete mode 100644 arch/arm/mach-tegra/fuse.c delete mode 100644 arch/arm/mach-tegra/fuse.h delete mode 100644 arch/arm/mach-tegra/pmc.c delete mode 100644 arch/arm/mach-tegra/pmc.h delete mode 100644 arch/arm/mach-tegra/powergate.c create mode 100644 arch/arm/mach-tegra/tegra-pmc.c create mode 100644 drivers/misc/fuse/Makefile create mode 100644 drivers/soc/tegra/Makefile create mode 100644 drivers/soc/tegra/fuse/Makefile create mode 100644 drivers/soc/tegra/fuse/fuse-tegra.c create mode 100644 drivers/soc/tegra/fuse/fuse-tegra20.c create mode 100644 drivers/soc/tegra/fuse/fuse-tegra30.c create mode 100644 drivers/soc/tegra/fuse/fuse.h rename arch/arm/mach-tegra/tegra114_speedo.c => drivers/soc/tegra/fuse/speedo-tegra114.c (55%) create mode 100644 drivers/soc/tegra/fuse/speedo-tegra124.c rename arch/arm/mach-tegra/tegra20_speedo.c => drivers/soc/tegra/fuse/speedo-tegra20.c (67%) rename arch/arm/mach-tegra/tegra30_speedo.c => drivers/soc/tegra/fuse/speedo-tegra30.c (52%) create mode 100644 drivers/soc/tegra/fuse/tegra-apbmisc.c
Signature · 1 line
2.0.1
PATCH 1/12 ARM: tegra: Sort includes alphabetically
From: Thierry Reding <[email protected]>
If these aren't sorted alphabetically, then the logical choice is to append new ones, however that creates a lot of potential for conflicts because every change will then add new includes in the same location.
--- arch/arm/mach-tegra/apbio.c | 12 ++++++------ arch/arm/mach-tegra/board-paz00.c | 3 ++- arch/arm/mach-tegra/cpuidle-tegra114.c | 10 +++++----- arch/arm/mach-tegra/cpuidle-tegra20.c | 16 ++++++++-------- arch/arm/mach-tegra/cpuidle-tegra30.c | 10 +++++----- arch/arm/mach-tegra/flowctrl.c | 4 ++-- arch/arm/mach-tegra/fuse.c | 8 ++++---- arch/arm/mach-tegra/hotplug.c | 3 ++- arch/arm/mach-tegra/io.c | 8 ++++---- arch/arm/mach-tegra/irq.c | 8 ++++---- arch/arm/mach-tegra/platsmp.c | 20 ++++++++++---------- arch/arm/mach-tegra/pm-tegra20.c | 1 + arch/arm/mach-tegra/pm-tegra30.c | 1 + arch/arm/mach-tegra/pm.c | 22 +++++++++++----------- arch/arm/mach-tegra/pmc.c | 2 +- arch/arm/mach-tegra/powergate.c | 4 ++-- arch/arm/mach-tegra/reset-handler.S | 4 ++-- arch/arm/mach-tegra/reset.c | 8 ++++---- arch/arm/mach-tegra/sleep-tegra30.S | 6 +++--- arch/arm/mach-tegra/tegra.c | 18 +++++++++--------- arch/arm/mach-tegra/tegra114_speedo.c | 2 +- arch/arm/mach-tegra/tegra20_speedo.c | 2 +- arch/arm/mach-tegra/tegra30_speedo.c | 2 +- 23 files changed, 89 insertions(+), 85 deletions(-)
arch/arm/mach-tegra/apbio.c +6 -6
@@ -13,15 +13,15 @@* */ -#include <linux/kernel.h> -#include <linux/io.h> -#include <linux/of.h> +#include <linux/completion.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> -#include <linux/spinlock.h> -#include <linux/completion.h> -#include <linux/sched.h> +#include <linux/io.h> +#include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/of.h> +#include <linux/sched.h> +#include <linux/spinlock.h> #include "apbio.h" #include "iomap.h"
arch/arm/mach-tegra/board-paz00.c +2 -1
@@ -17,9 +17,10 @@* */ -#include <linux/platform_device.h> #include <linux/gpio/driver.h> +#include <linux/platform_device.h> #include <linux/rfkill-gpio.h> +#include "board.h" static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = {
arch/arm/mach-tegra/cpuidle-tegra114.c +5 -5
@@ -14,16 +14,16 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/kernel.h> -#include <linux/module.h> +#include <asm/firmware.h> +#include <linux/clockchips.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> -#include <linux/clockchips.h> -#include <asm/firmware.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <asm/cpuidle.h> -#include <asm/suspend.h> #include <asm/smp_plat.h> +#include <asm/suspend.h> #include "pm.h" #include "sleep.h"
arch/arm/mach-tegra/cpuidle-tegra20.c +8 -8
@@ -19,23 +19,23 @@* more details. */ -#include <linux/kernel.h> -#include <linux/module.h> +#include <linux/clk/tegra.h> +#include <linux/clockchips.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> -#include <linux/clockchips.h> -#include <linux/clk/tegra.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <asm/cpuidle.h> #include <asm/proc-fns.h> -#include <asm/suspend.h> #include <asm/smp_plat.h> +#include <asm/suspend.h> -#include "pm.h" -#include "sleep.h" +#include "flowctrl.h" #include "iomap.h" #include "irq.h" -#include "flowctrl.h" +#include "pm.h" +#include "sleep.h" #ifdef CONFIG_PM_SLEEP static bool abort_flag;
arch/arm/mach-tegra/cpuidle-tegra30.c +5 -5
@@ -19,17 +19,17 @@* more details. */ -#include <linux/kernel.h> -#include <linux/module.h> +#include <linux/clk/tegra.h> +#include <linux/clockchips.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> -#include <linux/clockchips.h> -#include <linux/clk/tegra.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <asm/cpuidle.h> #include <asm/proc-fns.h> -#include <asm/suspend.h> #include <asm/smp_plat.h> +#include <asm/suspend.h> #include "pm.h" #include "sleep.h"
arch/arm/mach-tegra/flowctrl.c +2 -2
@@ -18,10 +18,10 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/cpumask.h> #include <linux/init.h> -#include <linux/kernel.h> #include <linux/io.h> -#include <linux/cpumask.h> +#include <linux/kernel.h> #include "flowctrl.h" #include "iomap.h"
arch/arm/mach-tegra/fuse.c +4 -4
@@ -18,16 +18,16 @@* */ -#include <linux/kernel.h> -#include <linux/io.h> +#include <linux/clk.h> #include <linux/export.h> +#include <linux/io.h> +#include <linux/kernel.h> #include <linux/random.h> -#include <linux/clk.h> #include <linux/tegra-soc.h> +#include "apbio.h" #include "fuse.h" #include "iomap.h" -#include "apbio.h" /* Tegra20 only */ #define FUSE_UID_LOW 0x108
arch/arm/mach-tegra/hotplug.c +2 -1
@@ -7,9 +7,10 @@* it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#include <linux/clk/tegra.h> #include <linux/kernel.h> #include <linux/smp.h> -#include <linux/clk/tegra.h> #include <asm/smp_plat.h>
arch/arm/mach-tegra/io.c +4 -4
@@ -18,14 +18,14 @@* */ -#include <linux/kernel.h> -#include <linux/module.h> #include <linux/init.h> -#include <linux/mm.h> #include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> -#include <asm/page.h> #include <asm/mach/map.h> +#include <asm/page.h> #include "board.h" #include "iomap.h"
arch/arm/mach-tegra/irq.c +4 -4
@@ -17,14 +17,14 @@* */ -#include <linux/kernel.h> #include <linux/cpu_pm.h> #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> #include <linux/irqchip/arm-gic.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/of_address.h> +#include <linux/of.h> #include <linux/syscore_ops.h> #include "board.h"
arch/arm/mach-tegra/platsmp.c +10 -10
@@ -11,27 +11,27 @@* it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/init.h> -#include <linux/errno.h> + +#include <linux/clk/tegra.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/io.h> #include <linux/jiffies.h> #include <linux/smp.h> -#include <linux/io.h> -#include <linux/clk/tegra.h> #include <asm/cacheflush.h> #include <asm/mach-types.h> -#include <asm/smp_scu.h> #include <asm/smp_plat.h> - -#include "fuse.h" -#include "flowctrl.h" -#include "reset.h" -#include "pmc.h" +#include <asm/smp_scu.h> #include "common.h" +#include "flowctrl.h" +#include "fuse.h" #include "iomap.h" +#include "pmc.h" +#include "reset.h" static cpumask_t tegra_cpu_init_mask;
arch/arm/mach-tegra/pm-tegra20.c +1 -0
@@ -13,6 +13,7 @@* You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/kernel.h> #include "pm.h"
arch/arm/mach-tegra/pm-tegra30.c +1 -0
@@ -13,6 +13,7 @@* You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/kernel.h> #include "pm.h"
arch/arm/mach-tegra/pm.c +11 -11
@@ -16,30 +16,30 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/io.h> +#include <linux/clk/tegra.h> #include <linux/cpumask.h> -#include <linux/delay.h> #include <linux/cpu_pm.h> -#include <linux/suspend.h> +#include <linux/delay.h> #include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> #include <linux/slab.h> -#include <linux/clk/tegra.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> -#include <asm/smp_plat.h> #include <asm/cacheflush.h> -#include <asm/suspend.h> #include <asm/idmap.h> #include <asm/proc-fns.h> +#include <asm/smp_plat.h> +#include <asm/suspend.h> #include <asm/tlbflush.h> -#include "iomap.h" -#include "reset.h" #include "flowctrl.h" #include "fuse.h" -#include "pm.h" +#include "iomap.h" #include "pmc.h" +#include "pm.h" +#include "reset.h" #include "sleep.h" #ifdef CONFIG_PM_SLEEP
arch/arm/mach-tegra/pmc.c +1 -1
@@ -15,9 +15,9 @@* */ -#include <linux/kernel.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/kernel.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/tegra-powergate.h>
arch/arm/mach-tegra/powergate.c +2 -2
@@ -17,18 +17,18 @@* */ -#include <linux/kernel.h> #include <linux/clk.h> +#include <linux/clk/tegra.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/export.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/kernel.h> #include <linux/reset.h> #include <linux/seq_file.h> #include <linux/spinlock.h> -#include <linux/clk/tegra.h> #include <linux/tegra-powergate.h> #include "fuse.h"
arch/arm/mach-tegra/reset-handler.S +2 -2
@@ -14,11 +14,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/linkage.h> #include <linux/init.h> +#include <linux/linkage.h> -#include <asm/cache.h> #include <asm/asm-offsets.h> +#include <asm/cache.h> #include "flowctrl.h" #include "fuse.h"
arch/arm/mach-tegra/reset.c +4 -4
@@ -14,20 +14,20 @@* */ +#include <linux/bitops.h> +#include <linux/cpumask.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/cpumask.h> -#include <linux/bitops.h> #include <asm/cacheflush.h> -#include <asm/hardware/cache-l2x0.h> #include <asm/firmware.h> +#include <asm/hardware/cache-l2x0.h> +#include "fuse.h" #include "iomap.h" #include "irammap.h" #include "reset.h" #include "sleep.h" -#include "fuse.h" #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \ TEGRA_IRAM_RESET_HANDLER_OFFSET)
arch/arm/mach-tegra/sleep-tegra30.S +3 -3
@@ -16,14 +16,14 @@ #include <linux/linkage.h> -#include <asm/assembler.h> #include <asm/asm-offsets.h> +#include <asm/assembler.h> #include <asm/cache.h> -#include "irammap.h" +#include "flowctrl.h" #include "fuse.h" +#include "irammap.h" #include "sleep.h" -#include "flowctrl.h" #define EMC_CFG 0xc #define EMC_ADR_CFG 0x10
arch/arm/mach-tegra/tegra.c +9 -9
@@ -16,29 +16,29 @@* */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/serial_8250.h> #include <linux/clk.h> +#include <linux/clk/tegra.h> #include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> -#include <linux/of.h> +#include <linux/kernel.h> #include <linux/of_address.h> #include <linux/of_fdt.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/pda_power.h> -#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> #include <linux/slab.h> #include <linux/sys_soc.h> #include <linux/usb/tegra_usb_phy.h> -#include <linux/clk/tegra.h> -#include <linux/irqchip.h> #include <asm/hardware/cache-l2x0.h> -#include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> +#include <asm/mach-types.h> #include <asm/setup.h> #include <asm/trusted_foundations.h>
arch/arm/mach-tegra/tegra114_speedo.c +1 -1
@@ -14,8 +14,8 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/kernel.h> #include <linux/bug.h> +#include <linux/kernel.h> #include "fuse.h"
arch/arm/mach-tegra/tegra20_speedo.c +1 -1
@@ -14,8 +14,8 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/kernel.h> #include <linux/bug.h> +#include <linux/kernel.h> #include "fuse.h"
arch/arm/mach-tegra/tegra30_speedo.c +1 -1
@@ -14,8 +14,8 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/kernel.h> #include <linux/bug.h> +#include <linux/kernel.h> #include "fuse.h"
Signature · 1 line
2.0.1
PATCH 2/12 ARM: tegra: Use a function to get the chip ID
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
Instead of using a simple variable access to get at the Tegra chip ID, use a function so that we can run additional code. This can be used to determine where the chip ID is being accessed without being available. That in turn will be handy for resolving boot sequence dependencies in order to convert more code to regular initcalls rather than a sequence fixed by Tegra SoC setup code.
--- arch/arm/mach-tegra/cpuidle.c | 6 +++--- arch/arm/mach-tegra/flowctrl.c | 6 +++--- arch/arm/mach-tegra/fuse.c | 19 +++++++++++++------ arch/arm/mach-tegra/fuse.h | 6 ------ arch/arm/mach-tegra/hotplug.c | 10 +++++----- arch/arm/mach-tegra/platsmp.c | 10 +++++----- arch/arm/mach-tegra/pm.c | 10 +++++----- arch/arm/mach-tegra/pmc.c | 4 ++-- arch/arm/mach-tegra/powergate.c | 8 ++++---- arch/arm/mach-tegra/reset-handler.S | 2 +- arch/arm/mach-tegra/reset.c | 3 ++- arch/arm/mach-tegra/sleep-tegra30.S | 2 +- arch/arm/mach-tegra/tegra.c | 3 ++- include/linux/tegra-soc.h | 10 ++++++++++ 14 files changed, 56 insertions(+), 43 deletions(-)
arch/arm/mach-tegra/cpuidle.c +3 -3
@@ -23,13 +23,13 @@#include <linux/kernel.h> #include <linux/module.h> +#include <linux/tegra-soc.h> -#include "fuse.h" #include "cpuidle.h" void __init tegra_cpuidle_init (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC))tegra20_cpuidle_init ();
@@ -49,7 +49,7 @@ void __init tegra_cpuidle_init(void)void tegra_cpuidle_pcie_irqs_in_use (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC))tegra20_cpuidle_pcie_irqs_in_use ();
arch/arm/mach-tegra/flowctrl.c +3 -3
@@ -22,10 +22,10 @@#include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/tegra-soc.h> #include "flowctrl.h" #include "iomap.h" -#include "fuse.h" static u8 flowctrl_offset_halt_cpu[] = {FLOW_CTRL_HALT_CPU0_EVENTS ,
@@ -76,7 +76,7 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)int i; reg =flowctrl_read_cpu_csr (cpuid); -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :/* clear wfe bitmap */ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP ;
@@ -117,7 +117,7 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)/* Disable powergating via flow controller for CPU0 */ reg =flowctrl_read_cpu_csr (cpuid); -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :/* clear wfe bitmap */ reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP ;
arch/arm/mach-tegra/fuse.c +13 -6
@@ -50,7 +50,6 @@int tegra_sku_id;int tegra_cpu_process_id;int tegra_core_process_id; -int tegra_chip_id;int tegra_cpu_speedo_id;/* only exist in Tegra30 and later */ int tegra_soc_speedo_id;enum tegra_revision tegra_revision;
@@ -123,7 +122,7 @@ static enum tegra_revision tegra_get_revision(u32 id)case 2 :return TEGRA_REVISION_A02 ;case 3 : -if (tegra_chip_id ==TEGRA20 && +if (tegra_get_chip_id () ==TEGRA20 && (tegra_spare_fuse (18 ) ||tegra_spare_fuse (19 )))return TEGRA_REVISION_A03p;else
@@ -154,6 +153,13 @@ u32 tegra_read_chipid(void)return readl_relaxed (IO_ADDRESS (TEGRA_APB_MISC_BASE ) +0x804 ); } +u8 tegra_get_chip_id (void ) +{ +u32 id =tegra_read_chipid (); + +return (id >>8 ) &0xff ; +} +static void __init tegra20_fuse_init_randomness (void ) {u32 randomness[2 ];
@@ -184,6 +190,7 @@ void __init tegra_init_fuse(void) {u32 id;u32 randomness[5 ]; +u8 chip_id;u32 reg =readl (IO_ADDRESS (TEGRA_CLK_RESET_BASE +0x48 )); reg |=1 <<28 ;
@@ -208,9 +215,9 @@ void __init tegra_init_fuse(void) id =tegra_read_chipid (); randomness[2 ] = id; - tegra_chip_id = (id >>8 ) &0xff ; + chip_id = (id >>8 ) &0xff ; -switch (tegra_chip_id) { +switch (chip_id) {case TEGRA20 : tegra_fuse_spare_bit =TEGRA20_FUSE_SPARE_BIT ; tegra_init_speedo_data = &tegra20_init_speedo_data;
@@ -223,7 +230,7 @@ void __init tegra_init_fuse(void) tegra_init_speedo_data = &tegra114_init_speedo_data;break ;default : -pr_warn ("Tegra: unknown chip id %d\n" , tegra_chip_id); +pr_warn ("Tegra: unknown chip id %d\n" , chip_id); tegra_fuse_spare_bit =TEGRA20_FUSE_SPARE_BIT ; tegra_init_speedo_data = &tegra_get_process_id; }
@@ -234,7 +241,7 @@ void __init tegra_init_fuse(void) randomness[4 ] = (tegra_cpu_speedo_id <<16 ) | tegra_soc_speedo_id;add_device_randomness (randomness,sizeof (randomness)); -switch (tegra_chip_id) { +switch (chip_id) {case TEGRA20 :tegra20_fuse_init_randomness ();break ;
arch/arm/mach-tegra/fuse.h +0 -6
@@ -26,11 +26,6 @@#define SKU_ID_AP25E 27#define SKU_ID_T25E 28 -#define TEGRA20 0x20 -#define TEGRA30 0x30 -#define TEGRA114 0x35 -#define TEGRA124 0x40 -#ifndef __ASSEMBLY__enum tegra_revision { TEGRA_REVISION_UNKNOWN = 0,
@@ -45,7 +40,6 @@ enum tegra_revision {extern int tegra_sku_id;extern int tegra_cpu_process_id;extern int tegra_core_process_id; -extern int tegra_chip_id;extern int tegra_cpu_speedo_id;/* only exist in Tegra30 and later */ extern int tegra_soc_speedo_id;extern enum tegra_revision tegra_revision;
arch/arm/mach-tegra/hotplug.c +5 -5
@@ -11,10 +11,10 @@#include <linux/clk/tegra.h> #include <linux/kernel.h> #include <linux/smp.h> +#include <linux/tegra-soc.h> #include <asm/smp_plat.h> -#include "fuse.h" #include "sleep.h" static void (*tegra_hotplug_shutdown)(void );
@@ -52,12 +52,12 @@ void __init tegra_hotplug_init(void)if (!IS_ENABLED (CONFIG_HOTPLUG_CPU ))return ; -if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id ==TEGRA20 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC) &&tegra_get_chip_id () ==TEGRA20 ) tegra_hotplug_shutdown = tegra20_hotplug_shutdown; -if (IS_ENABLED (CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id ==TEGRA30 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_3x_SOC) &&tegra_get_chip_id () ==TEGRA30 ) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; -if (IS_ENABLED (CONFIG_ARCH_TEGRA_114_SOC ) && tegra_chip_id ==TEGRA114 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_114_SOC ) &&tegra_get_chip_id () ==TEGRA114 ) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; -if (IS_ENABLED (CONFIG_ARCH_TEGRA_124_SOC ) && tegra_chip_id ==TEGRA124 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_124_SOC ) &&tegra_get_chip_id () ==TEGRA124 ) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; }
arch/arm/mach-tegra/platsmp.c +5 -5
@@ -20,6 +20,7 @@#include <linux/io.h> #include <linux/jiffies.h> #include <linux/smp.h> +#include <linux/tegra-soc.h> #include <asm/cacheflush.h> #include <asm/mach-types.h>
@@ -28,7 +29,6 @@#include "common.h" #include "flowctrl.h" -#include "fuse.h" #include "iomap.h" #include "pmc.h" #include "reset.h"
@@ -170,13 +170,13 @@ static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)static int tegra_boot_secondary (unsigned int cpu,struct task_struct *idle) { -if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id ==TEGRA20 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC) &&tegra_get_chip_id () ==TEGRA20 )return tegra20_boot_secondary (cpu, idle); -if (IS_ENABLED (CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id ==TEGRA30 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_3x_SOC) &&tegra_get_chip_id () ==TEGRA30 )return tegra30_boot_secondary (cpu, idle); -if (IS_ENABLED (CONFIG_ARCH_TEGRA_114_SOC ) && tegra_chip_id ==TEGRA114 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_114_SOC ) &&tegra_get_chip_id () ==TEGRA114 )return tegra114_boot_secondary (cpu, idle); -if (IS_ENABLED (CONFIG_ARCH_TEGRA_124_SOC ) && tegra_chip_id ==TEGRA124 ) +if (IS_ENABLED (CONFIG_ARCH_TEGRA_124_SOC ) &&tegra_get_chip_id () ==TEGRA124 )return tegra114_boot_secondary (cpu, idle);return -EINVAL ;
arch/arm/mach-tegra/pm.c +5 -5
@@ -26,6 +26,7 @@#include <linux/slab.h> #include <linux/spinlock.h> #include <linux/suspend.h> +#include <linux/tegra-soc.h> #include <asm/cacheflush.h> #include <asm/idmap.h>
@@ -35,7 +36,6 @@#include <asm/tlbflush.h> #include "flowctrl.h" -#include "fuse.h" #include "iomap.h" #include "pmc.h" #include "pm.h"
@@ -53,7 +53,7 @@ static int (*tegra_sleep_func)(unsigned long v2p);static void tegra_tear_down_cpu_init (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC)) tegra_tear_down_cpu = tegra20_tear_down_cpu;
@@ -143,7 +143,7 @@ bool tegra_set_cpu_in_lp2(void)if ((phy_cpu_id ==0 ) &&cpumask_equal (cpu_lp2_mask, cpu_online_mask)) last_cpu = true; -else if (tegra_chip_id ==TEGRA20 && phy_cpu_id ==1 ) +else if (tegra_get_chip_id () ==TEGRA20 && phy_cpu_id ==1 )tegra20_cpu_set_resettable_soon ();spin_unlock (&tegra_lp2_lock);
@@ -212,7 +212,7 @@ static int tegra_sleep_core(unsigned long v2p)*/ static bool tegra_lp1_iram_hook (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC))tegra20_lp1_iram_hook ();
@@ -242,7 +242,7 @@ static bool tegra_lp1_iram_hook(void)static bool tegra_sleep_core_init (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC))tegra20_sleep_core_init ();
arch/arm/mach-tegra/pmc.c +2 -2
@@ -21,9 +21,9 @@#include <linux/of.h> #include <linux/of_address.h> #include <linux/tegra-powergate.h> +#include <linux/tegra-soc.h> #include "flowctrl.h" -#include "fuse.h" #include "pm.h" #include "pmc.h" #include "sleep.h"
@@ -251,7 +251,7 @@ void tegra_pmc_pm_set(enum tegra_suspend_mode mode) reg |=TEGRA_POWER_CPU_PWRREQ_OE ; reg &= ~TEGRA_POWER_EFFECT_LP0 ; -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 :case TEGRA30 :break ;
arch/arm/mach-tegra/powergate.c +4 -4
@@ -30,8 +30,8 @@#include <linux/seq_file.h> #include <linux/spinlock.h> #include <linux/tegra-powergate.h> +#include <linux/tegra-soc.h> -#include "fuse.h" #include "iomap.h" #define DPD_SAMPLE 0x020
@@ -157,7 +157,7 @@ int tegra_powergate_remove_clamping(int id)* The Tegra124 GPU has a separate register (with different semantics) * to remove clamps. */ -if (tegra_chip_id ==TEGRA124 ) { +if (tegra_get_chip_id () ==TEGRA124 ) {if (id ==TEGRA_POWERGATE_3D ) {pmc_write (0 ,GPU_RG_CNTRL );return 0 ;
@@ -227,7 +227,7 @@ int tegra_cpu_powergate_id(int cpuid)int __init tegra_powergate_init (void ) { -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 : tegra_num_powerdomains =7 ;break ;
@@ -368,7 +368,7 @@ int __init tegra_powergate_debugfs_init(void) {struct dentry *d; -switch (tegra_chip_id) { +switch (tegra_get_chip_id ()) {case TEGRA20 : powergate_name = powergate_name_t20;break ;
arch/arm/mach-tegra/reset-handler.S +1 -1
@@ -16,12 +16,12 @@ #include <linux/init.h> #include <linux/linkage.h> +#include <linux/tegra-soc.h> #include <asm/asm-offsets.h> #include <asm/cache.h> #include "flowctrl.h" -#include "fuse.h" #include "iomap.h" #include "reset.h" #include "sleep.h"
arch/arm/mach-tegra/reset.c +2 -1
@@ -18,6 +18,7 @@#include <linux/cpumask.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/tegra-soc.h> #include <asm/cacheflush.h> #include <asm/firmware.h>
@@ -53,7 +54,7 @@ static void __init tegra_cpu_reset_handler_set(const u32 reset_address)* Prevent further modifications to the physical reset vector. * NOTE: Has no effect on chips prior to Tegra30. */ -if (tegra_chip_id !=TEGRA20 ) { +if (tegra_get_chip_id () !=TEGRA20 ) { reg =readl (sb_ctrl); reg |=2 ;writel (reg, sb_ctrl);
arch/arm/mach-tegra/sleep-tegra30.S +1 -1
@@ -15,13 +15,13 @@ */ #include <linux/linkage.h> +#include <linux/tegra-soc.h> #include <asm/asm-offsets.h> #include <asm/assembler.h> #include <asm/cache.h> #include "flowctrl.h" -#include "fuse.h" #include "irammap.h" #include "sleep.h"
arch/arm/mach-tegra/tegra.c +2 -1
@@ -33,6 +33,7 @@#include <linux/serial_8250.h> #include <linux/slab.h> #include <linux/sys_soc.h> +#include <linux/tegra-soc.h> #include <linux/usb/tegra_usb_phy.h> #include <asm/hardware/cache-l2x0.h>
@@ -104,7 +105,7 @@ static void __init tegra_dt_init(void) soc_dev_attr->family =kasprintf (GFP_KERNEL ,"Tegra" ); soc_dev_attr->revision =kasprintf (GFP_KERNEL ,"%d" , tegra_revision); - soc_dev_attr->soc_id =kasprintf (GFP_KERNEL ,"%d" , tegra_chip_id); + soc_dev_attr->soc_id =kasprintf (GFP_KERNEL ,"%u" ,tegra_get_chip_id ()); soc_dev =soc_device_register (soc_dev_attr);if (IS_ERR (soc_dev)) {
include/linux/tegra-soc.h +10 -0
@@ -17,6 +17,16 @@#ifndef __LINUX_TEGRA_SOC_H_#define __LINUX_TEGRA_SOC_H_ +#define TEGRA20 0x20 +#define TEGRA30 0x30 +#define TEGRA114 0x35 +#define TEGRA124 0x40 + +#ifndef __ASSEMBLY__ +u32 tegra_read_chipid (void ); +u8 tegra_get_chip_id (void ); + +#endif /* __ASSEMBLY__ */ #endif /* __LINUX_TEGRA_SOC_H_ */
Signature · 1 line
2.0.1
PATCH 3/12 ARM: tegra: export apb dma readl/writel
In reply to Thierry RedingFrom: Peter De Schrijver <[email protected]>
Export APB DMA readl and writel. These are needed because we can't access the fuses directly on Tegra20 without potentially causing a system hang. Also have the APB DMA readl and writel return an error in case of a read failure instead of just returning zero or ignore write failures.
--- arch/arm/mach-tegra/apbio.c | 51 +++++++++++++++++++++++++++------------------ include/linux/tegra-soc.h | 14 +++++++++++++ 2 files changed, 45 insertions(+), 20 deletions(-)
arch/arm/mach-tegra/apbio.c +31 -20
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;static dma_addr_t tegra_apb_bb_phys;static DECLARE_COMPLETION (tegra_apb_wait); -static u32 tegra_apb_readl_direct (unsigned long offset); -static void tegra_apb_writel_direct (u32 value,unsigned long offset); +static int tegra_apb_readl_direct (unsigned long offset,u32 *value); +static int tegra_apb_writel_direct (u32 value,unsigned long offset);static struct dma_chan *tegra_apb_dma_chan;static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,return 0 ; } -static u32 tegra_apb_readl_using_dma (unsigned long offset) +int tegra_apb_readl_using_dma (unsigned long offset,u32 *value) {int ret;if (!tegra_apb_dma_chan && !tegra_apb_dma_init ()) -return tegra_apb_readl_direct (offset); +return tegra_apb_readl_direct (offset, value);mutex_lock (&tegra_apb_dma_lock); ret =do_dma_transfer (offset,DMA_DEV_TO_MEM ); -if (ret <0 ) { +if (ret <0 )pr_err ("error in reading offset 0x%08lx using dma\n" , offset); - *(u32 *)tegra_apb_bb =0 ; - } +else + *value = *tegra_apb_bb; +mutex_unlock (&tegra_apb_dma_lock); -return *((u32 *)tegra_apb_bb); + +return ret; } -static void tegra_apb_writel_using_dma (u32 value,unsigned long offset) +int tegra_apb_writel_using_dma (u32 value,unsigned long offset) {int ret; -if (!tegra_apb_dma_chan && !tegra_apb_dma_init ()) { -tegra_apb_writel_direct (value, offset); -return ; - } +if (!tegra_apb_dma_chan && !tegra_apb_dma_init ()) +return tegra_apb_writel_direct (value, offset);mutex_lock (&tegra_apb_dma_lock); *((u32 *)tegra_apb_bb) = value; ret =do_dma_transfer (offset,DMA_MEM_TO_DEV ); +mutex_unlock (&tegra_apb_dma_lock);if (ret <0 )pr_err ("error in writing offset 0x%08lx using dma\n" , offset); -mutex_unlock (&tegra_apb_dma_lock); + +return ret; }#else #define tegra_apb_readl_using_dma tegra_apb_readl_direct#define tegra_apb_writel_using_dma tegra_apb_writel_direct#endif -typedef u32 (*apbio_read_fptr )(unsigned long offset); -typedef void (*apbio_write_fptr )(u32 value,unsigned long offset); +typedef int (*apbio_read_fptr )(unsigned long offset,u32 *value); +typedef int (*apbio_write_fptr )(u32 value,unsigned long offset);static apbio_read_fptr apbio_read;static apbio_write_fptr apbio_write; -static u32 tegra_apb_readl_direct (unsigned long offset) +static int tegra_apb_readl_direct (unsigned long offset,u32 *value) { -return readl (IO_ADDRESS (offset)); + *value =readl (IO_ADDRESS (offset)); + +return 0 ; } -static void tegra_apb_writel_direct (u32 value,unsigned long offset) +static int tegra_apb_writel_direct (u32 value,unsigned long offset) {writel (value,IO_ADDRESS (offset)); + +return 0 ; }void tegra_apb_io_init (void )
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)u32 tegra_apb_readl (unsigned long offset) { -return apbio_read (offset); +u32 val; + +if (apbio_read (offset, &val) <0 ) +return 0 ; +else +return val; }void tegra_apb_writel (u32 value,unsigned long offset)
include/linux/tegra-soc.h +14 -0
@@ -27,6 +27,20 @@u32 tegra_read_chipid (void );u8 tegra_get_chip_id (void ); +#if defined(CONFIG_TEGRA20_APB_DMA ) +int tegra_apb_readl_using_dma (unsigned long offset,u32 *value); +int tegra_apb_writel_using_dma (u32 value,unsigned long offset); +#else +static inline int tegra_apb_readl_using_dma (unsigned long offset,u32 *value) +{ +return -EINVAL ; +} +static inline int tegra_apb_writel_using_dma (u32 value,unsigned long offset) +{ +return -EINVAL ; +} +#endif /* CONFIG_TEGRA20_APB_DMA */ +#endif /* __ASSEMBLY__ */ #endif /* __LINUX_TEGRA_SOC_H_ */
Signature · 1 line
2.0.1
PATCH 4/12 ARM: tegra: move fuse exports to tegra-soc.h
In reply to Thierry RedingFrom: Peter De Schrijver <[email protected]>
All fuse related functionality will move to a driver in the following patches. To prepare for this, export all the required functionality in a global header file and move all users of fuse.h to tegra-soc.h. While we're at it, remove tegra_bct_strapping, as its only user was removed in Commit a7cbe92cef27 ("ARM: tegra: remove tegra EMC scaling driver").
--- arch/arm/mach-tegra/fuse.h | 13 ------------- arch/arm/mach-tegra/tegra.c | 1 - arch/arm/mach-tegra/tegra114_speedo.c | 1 + arch/arm/mach-tegra/tegra20_speedo.c | 1 + arch/arm/mach-tegra/tegra30_speedo.c | 1 + include/linux/tegra-soc.h | 16 ++++++++++++++++ 6 files changed, 19 insertions(+), 14 deletions(-)
arch/arm/mach-tegra/fuse.h +0 -13
@@ -27,27 +27,14 @@#define SKU_ID_T25E 28#ifndef __ASSEMBLY__ -enum tegra_revision { -TEGRA_REVISION_UNKNOWN =0 , -TEGRA_REVISION_A01 , -TEGRA_REVISION_A02 , -TEGRA_REVISION_A03 , - TEGRA_REVISION_A03p, -TEGRA_REVISION_A04 , -TEGRA_REVISION_MAX , -};extern int tegra_sku_id;extern int tegra_cpu_process_id;extern int tegra_core_process_id;extern int tegra_cpu_speedo_id;/* only exist in Tegra30 and later */ extern int tegra_soc_speedo_id; -extern enum tegra_revision tegra_revision; - -extern int tegra_bct_strapping;unsigned long long tegra_chip_uid (void ); -void tegra_init_fuse (void );bool tegra_spare_fuse (int bit);u32 tegra_fuse_readl (unsigned long offset);
arch/arm/mach-tegra/tegra.c +0 -1
@@ -47,7 +47,6 @@#include "board.h" #include "common.h" #include "cpuidle.h" -#include "fuse.h" #include "iomap.h" #include "irq.h" #include "pmc.h"
arch/arm/mach-tegra/tegra114_speedo.c +1 -0
@@ -16,6 +16,7 @@#include <linux/bug.h> #include <linux/kernel.h> +#include <linux/tegra-soc.h> #include "fuse.h"
arch/arm/mach-tegra/tegra20_speedo.c +1 -0
@@ -16,6 +16,7 @@#include <linux/bug.h> #include <linux/kernel.h> +#include <linux/tegra-soc.h> #include "fuse.h"
arch/arm/mach-tegra/tegra30_speedo.c +1 -0
@@ -16,6 +16,7 @@#include <linux/bug.h> #include <linux/kernel.h> +#include <linux/tegra-soc.h> #include "fuse.h"
include/linux/tegra-soc.h +16 -0
@@ -27,6 +27,22 @@u32 tegra_read_chipid (void );u8 tegra_get_chip_id (void ); +enum tegra_revision { +TEGRA_REVISION_UNKNOWN =0 , +TEGRA_REVISION_A01 , +TEGRA_REVISION_A02 , +TEGRA_REVISION_A03 , + TEGRA_REVISION_A03p, +TEGRA_REVISION_A04 , +TEGRA_REVISION_MAX , +}; + +u32 tegra_read_straps (void ); +u32 tegra_read_chipid (void ); +void tegra_init_fuse (void ); + +extern enum tegra_revision tegra_revision; +#if defined(CONFIG_TEGRA20_APB_DMA )int tegra_apb_readl_using_dma (unsigned long offset,u32 *value);int tegra_apb_writel_using_dma (u32 value,unsigned long offset);
Signature · 1 line
2.0.1
PATCH 5/12 soc/tegra: Add efuse driver for Tegra
In reply to Thierry RedingFrom: Peter De Schrijver <[email protected]>
Implement fuse driver for Tegra20, Tegra30, Tegra114 and Tegra124. This replaces functionality previously provided in arch/arm/mach-tegra, which is removed in this patch.
While at it, move the only user of the global tegra_revision variable over to tegra_sku_info.revision and export tegra_fuse_readl() to allow drivers to read calibration fuses.
--- Documentation/ABI/testing/sysfs-driver-tegra-fuse | 11 + arch/arm/mach-tegra/Makefile | 4 - arch/arm/mach-tegra/fuse.c | 259 --------------------- arch/arm/mach-tegra/fuse.h | 60 ----- arch/arm/mach-tegra/reset.c | 1 - arch/arm/mach-tegra/tegra.c | 3 +- drivers/misc/fuse/Makefile | 1 + drivers/soc/Makefile | 1 + drivers/soc/tegra/Makefile | 1 + drivers/soc/tegra/fuse/Makefile | 8 + drivers/soc/tegra/fuse/fuse-tegra.c | 155 ++++++++++++ drivers/soc/tegra/fuse/fuse-tegra20.c | 141 +++++++++++ drivers/soc/tegra/fuse/fuse-tegra30.c | 223 ++++++++++++++++++ drivers/soc/tegra/fuse/fuse.h | 71 ++++++ .../soc/tegra/fuse/speedo-tegra114.c | 54 +++-- drivers/soc/tegra/fuse/speedo-tegra124.c | 167 +++++++++++++ .../soc/tegra/fuse/speedo-tegra20.c | 43 ++-- .../soc/tegra/fuse/speedo-tegra30.c | 174 +++++++------- drivers/soc/tegra/fuse/tegra-apbmisc.c | 111 +++++++++ include/linux/tegra-soc.h | 20 +- 20 files changed, 1045 insertions(+), 463 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-driver-tegra-fuse delete mode 100644 arch/arm/mach-tegra/fuse.c delete mode 100644 arch/arm/mach-tegra/fuse.h create mode 100644 drivers/misc/fuse/Makefile create mode 100644 drivers/soc/tegra/Makefile create mode 100644 drivers/soc/tegra/fuse/Makefile create mode 100644 drivers/soc/tegra/fuse/fuse-tegra.c create mode 100644 drivers/soc/tegra/fuse/fuse-tegra20.c create mode 100644 drivers/soc/tegra/fuse/fuse-tegra30.c create mode 100644 drivers/soc/tegra/fuse/fuse.h rename arch/arm/mach-tegra/tegra114_speedo.c => drivers/soc/tegra/fuse/speedo-tegra114.c (56%) create mode 100644 drivers/soc/tegra/fuse/speedo-tegra124.c rename arch/arm/mach-tegra/tegra20_speedo.c => drivers/soc/tegra/fuse/speedo-tegra20.c (68%) rename arch/arm/mach-tegra/tegra30_speedo.c => drivers/soc/tegra/fuse/speedo-tegra30.c (53%) create mode 100644 drivers/soc/tegra/fuse/tegra-apbmisc.c
Documentation/ABI/testing/sysfs-driver-tegra-fuse new file +11 -0
@@ -0,0 +1,11 @@ +What: /sys/devices/*/<our-device>/fuse +Date: February 2014 +Contact: Peter De Schrijver <[email protected]> +Description: read-only access to the efuses on Tegra20, Tegra30, Tegra114 + and Tegra124 SoC's from NVIDIA. The efuses contain write once + data programmed at the factory. The data is layed out in 32bit + words in LSB first format. Each bit represents a single value + as decoded from the fuse registers. Bits order/assignment + exactly matches the HW registers, including any unused bits. +Users: any user space application which wants to read the efuses on + Tegra SoC's
arch/arm/mach-tegra/Makefile +0 -4
@@ -2,7 +2,6 @@ asflags-y += -march=armv7-a obj-y += io.o obj-y += irq.o -obj-y += fuse.o obj-y += pmc.o obj-y += flowctrl.o obj-y += powergate.o
@@ -13,13 +12,11 @@ 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) += sleep-tegra20.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o ifeq ($(CONFIG_CPU_IDLE),y) obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o endif -obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pm-tegra30.o ifeq ($(CONFIG_CPU_IDLE),y)
@@ -28,7 +25,6 @@ endif obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114_speedo.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o ifeq ($(CONFIG_CPU_IDLE),y)
arch/arm/mach-tegra/fuse.c deleted +0 -259
259 lines not on this page · raw message
arch/arm/mach-tegra/fuse.h deleted +0 -60
60 lines not on this page · raw message
arch/arm/mach-tegra/reset.c +0 -1
@@ -24,7 +24,6 @@#include <asm/firmware.h> #include <asm/hardware/cache-l2x0.h> -#include "fuse.h" #include "iomap.h" #include "irammap.h" #include "reset.h"
arch/arm/mach-tegra/tegra.c +2 -1
@@ -103,7 +103,8 @@ static void __init tegra_dt_init(void) goto out; soc_dev_attr->family =kasprintf (GFP_KERNEL ,"Tegra" ); - soc_dev_attr->revision =kasprintf (GFP_KERNEL ,"%d" , tegra_revision); + soc_dev_attr->revision =kasprintf (GFP_KERNEL ,"%d" , + tegra_sku_info.revision); soc_dev_attr->soc_id =kasprintf (GFP_KERNEL ,"%u" ,tegra_get_chip_id ()); soc_dev =soc_device_register (soc_dev_attr);
drivers/misc/fuse/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_TEGRA) += tegra/
drivers/soc/Makefile +1 -0
@@ -3,3 +3,4 @@ # obj-$(CONFIG_ARCH_QCOM) += qcom/ +obj-$(CONFIG_ARCH_TEGRA) += tegra/
drivers/soc/tegra/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_TEGRA) += fuse/
drivers/soc/tegra/fuse/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +obj-y += fuse-tegra.o +obj-y += fuse-tegra30.o +obj-y += tegra-apbmisc.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += fuse-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += speedo-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += speedo-tegra30.o +obj-$(CONFIG_ARCH_TEGRA_114_SOC) += speedo-tegra114.o +obj-$(CONFIG_ARCH_TEGRA_124_SOC) += speedo-tegra124.o
drivers/soc/tegra/fuse/fuse-tegra.c new file +155 -0
155 lines not on this page · raw message
drivers/soc/tegra/fuse/fuse-tegra20.c new file +141 -0
141 lines not on this page · raw message
drivers/soc/tegra/fuse/fuse-tegra30.c new file +223 -0
223 lines not on this page · raw message
drivers/soc/tegra/fuse/fuse.h new file +71 -0
71 lines not on this page · raw message
drivers/soc/tegra/fuse/speedo-tegra114.c renamed from arch/arm/mach-tegra/tegra114_speedo.c +29 -25
120 lines not on this page · raw message
drivers/soc/tegra/fuse/speedo-tegra124.c new file +167 -0
167 lines not on this page · raw message
drivers/soc/tegra/fuse/speedo-tegra20.c renamed from arch/arm/mach-tegra/tegra20_speedo.c +21 -22
95 lines not on this page · raw message
drivers/soc/tegra/fuse/speedo-tegra30.c renamed from arch/arm/mach-tegra/tegra30_speedo.c +84 -90
328 lines not on this page · raw message
drivers/soc/tegra/fuse/tegra-apbmisc.c new file +111 -0
111 lines not on this page · raw message
include/linux/tegra-soc.h +19 -1
@@ -22,6 +22,9 @@#define TEGRA114 0x35#define TEGRA124 0x40 +#define TEGRA_FUSE_SKU_CALIB_0 0xf0 +#define TEGRA30_FUSE_SATA_CALIB 0x124 +#ifndef __ASSEMBLY__u32 tegra_read_chipid (void );
@@ -37,11 +40,26 @@ enum tegra_revision { TEGRA_REVISION_MAX, }; +struct tegra_sku_info { +int sku_id; +int cpu_process_id; +int cpu_speedo_id; +int cpu_speedo_value; +int cpu_iddq_value; +int core_process_id; +int soc_speedo_id; +int gpu_speedo_id; +int gpu_process_id; +int gpu_speedo_value; +enum tegra_revision revision; +}; +u32 tegra_read_straps (void );u32 tegra_read_chipid (void );void tegra_init_fuse (void ); +int tegra_fuse_readl (unsigned long offset,u32 *value); -extern enum tegra_revision tegra_revision; +extern struct tegra_sku_info tegra_sku_info;#if defined(CONFIG_TEGRA20_APB_DMA )int tegra_apb_readl_using_dma (unsigned long offset,u32 *value);
Signature · 1 line
2.0.1
PATCH 5/12 soc/tegra: Add efuse driver for Tegra
drivers/misc/fuse/Makefile line 1
Quoted 7 lines · Thierry Reding
drivers/misc/fuse/Makefile new file +1
-0@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_TEGRA) += tegra/
I just happened to notice this change on linux-next introduced by this patch? It's a leftover from early version of the patch, I guess?
Shawn
PATCH 5/12 soc/tegra: Add efuse driver for Tegra
Quoted 11 lines · Shawn Guo
drivers/misc/fuse/Makefile line 1
Quoted 7 lines · Thierry Reding
drivers/misc/fuse/Makefile new file +1
-0@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_TEGRA) += tegra/I just happened to notice this change on linux-next introduced by this patch? It's a leftover from early version of the patch, I guess?
Indeed so. I've sent out a patch to fix this.
Thanks,
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141110/842be9cd/attachment.sig>
PATCH 6/12 soc/tegra: Add efuse and apbmisc bindings
In reply to Thierry RedingFrom: Peter De Schrijver <[email protected]>
Add efuse and apbmisc bindings for Tegra20, Tegra30, Tegra114 and Tegra124.
--- .../bindings/fuse/nvidia,tegra20-fuse.txt | 40 ++++++++++++++++++++++ .../bindings/misc/nvidia,tegra20-apbmisc.txt | 13 +++++++ arch/arm/boot/dts/tegra114.dtsi | 15 ++++++++ arch/arm/boot/dts/tegra124.dtsi | 15 ++++++++ arch/arm/boot/dts/tegra20.dtsi | 15 ++++++++ arch/arm/boot/dts/tegra30.dtsi | 15 ++++++++ 6 files changed, 113 insertions(+) create mode 100644 Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt new file +40 -0
@@ -0,0 +1,40 @@ +NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block. + +Required properties: +- compatible : should be: + "nvidia,tegra20-efuse" + "nvidia,tegra30-efuse" + "nvidia,tegra114-efuse" + "nvidia,tegra124-efuse" + Details: + nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data + due to a hardware bug. Tegra20 also lacks certain information which is + available in later generations such as fab code, lot code, wafer id,.. + nvidia,tegra30-efuse, nvidia,tegra114-efuse and nvidia,tegra124-efuse: + The differences between these SoCs are the size of the efuse array, + the location of the spare (OEM programmable) bits and the location of + the speedo data. +- reg: Should contain 1 entry: the entry gives the physical address and length + of the fuse registers. +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: Must include the following entries: + - fuse +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - fuse + +Example: + + fuse at 7000f800 { + compatible = "nvidia,tegra20-efuse"; + reg = <0x7000F800 0x400>, + <0x70000000 0x400>; + clocks = <&tegra_car TEGRA20_CLK_FUSE>; + clock-names = "fuse"; + resets = <&tegra_car 39>; + reset-names = "fuse"; + }; + +
Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt new file +13 -0
@@ -0,0 +1,13 @@ +NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block + +Required properties: +- compatible : should be: + "nvidia,tegra20-apbmisc" + "nvidia,tegra30-apbmisc" + "nvidia,tegra114-apbmisc" + "nvidia,tegra124-apbmisc" +- reg: Should contain 2 entries: the first entry gives the physical address + and length of the registers which contain revision and debug features. + The second entry gives the physical address and length of the + registers indicating the strapping options. +
arch/arm/boot/dts/tegra114.dtsi +15 -0
@@ -220,6 +220,12 @@ interrupt-controller; }; + apbmisc at 70000800 { + compatible = "nvidia,tegra114-apbmisc", "nvidia,tegra20-apbmisc"; + reg = <0x70000800 0x64 /* Chip revision */ + 0x70000008 0x04>; /* Strapping options */ + }; + pinmux: pinmux at 70000868 { compatible = "nvidia,tegra114-pinmux"; reg = <0x70000868 0x148 /* Pad control registers */
@@ -485,6 +491,15 @@ clock-names = "pclk", "clk32k_in"; }; + fuse@7000f800 { + compatible = "nvidia,tegra114-efuse"; + reg = <0x7000f800 0x400>; + clocks = <&tegra_car TEGRA114_CLK_FUSE>; + clock-names = "fuse"; + resets = <&tegra_car 39>; + reset-names = "fuse"; + }; + iommu at 70019010 { compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu"; reg = <0x70019010 0x02c
arch/arm/boot/dts/tegra124.dtsi +15 -0
@@ -179,6 +179,12 @@ #dma-cells = <1>; }; + apbmisc at 0,70000800 { + compatible = "nvidia,tegra124-apbmisc", "nvidia,tegra20-apbmisc"; + reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */ + <0x0 0x7000E864 0x0 0x04>; /* Strapping options */ + }; + pinmux: pinmux at 0,70000868 { compatible = "nvidia,tegra124-pinmux"; reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
@@ -449,6 +455,15 @@ clock-names = "pclk", "clk32k_in"; }; + fuse at 0,7000f800 { + compatible = "nvidia,tegra124-efuse"; + reg = <0x0 0x7000f800 0x0 0x400>; + clocks = <&tegra_car TEGRA124_CLK_FUSE>; + clock-names = "fuse"; + resets = <&tegra_car 39>; + reset-names = "fuse"; + }; + sdhci at 0,700b0000 { compatible = "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0000 0x0 0x200>;
arch/arm/boot/dts/tegra20.dtsi +15 -0
@@ -236,6 +236,12 @@ interrupt-controller; }; + apbmisc at 70000800 { + compatible = "nvidia,tegra20-apbmisc"; + reg = <0x70000800 0x64 /* Chip revision */ + 0x70000008 0x04>; /* Strapping options */ + }; + pinmux: pinmux at 70000014 { compatible = "nvidia,tegra20-pinmux"; reg = <0x70000014 0x10 /* Tri-state registers */
@@ -545,6 +551,15 @@ #size-cells = <0>; }; + fuse at 7000f800 { + compatible = "nvidia,tegra20-efuse"; + reg = <0x7000F800 0x400>; + clocks = <&tegra_car TEGRA20_CLK_FUSE>; + clock-names = "fuse"; + resets = <&tegra_car 39>; + reset-names = "fuse"; + }; + pcie-controller at 80003000 { compatible = "nvidia,tegra20-pcie"; device_type = "pci";
arch/arm/boot/dts/tegra30.dtsi +15 -0
@@ -335,6 +335,12 @@ interrupt-controller; }; + apbmisc at 70000800 { + compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc"; + reg = <0x70000800 0x64 /* Chip revision */ + 0x70000008 0x04>; /* Strapping options */ + }; + pinmux: pinmux at 70000868 { compatible = "nvidia,tegra30-pinmux"; reg = <0x70000868 0xd4 /* Pad control registers */
@@ -631,6 +637,15 @@ nvidia,ahb = <&ahb>; }; + fuse at 7000f800 { + compatible = "nvidia,tegra30-efuse"; + reg = <0x7000f800 0x400>; + clocks = <&tegra_car TEGRA30_CLK_FUSE>; + clock-names = "fuse"; + resets = <&tegra_car 39>; + reset-names = "fuse"; + }; + ahub at 70080000 { compatible = "nvidia,tegra30-ahub"; reg = <0x70080000 0x200
Signature · 1 line
2.0.1
PATCH 7/12 soc/tegra: fuse: move APB DMA into Tegra20 fuse driver
In reply to Thierry RedingFrom: Peter De Schrijver <[email protected]>
The Tegra20 fuse driver is the only user of tegra_apb_readl_using_dma(). Therefore we can simply the code by incorporating the APB DMA handling into the driver directly. tegra_apb_writel_using_dma() is dropped because there are no users.
--- arch/arm/mach-tegra/Makefile | 1 - arch/arm/mach-tegra/apbio.c | 217 ---------------------------------- arch/arm/mach-tegra/apbio.h | 22 ---- arch/arm/mach-tegra/tegra.c | 2 - drivers/soc/tegra/fuse/fuse-tegra20.c | 79 ++++++++++++- include/linux/tegra-soc.h | 14 --- 6 files changed, 76 insertions(+), 259 deletions(-) delete mode 100644 arch/arm/mach-tegra/apbio.c delete mode 100644 arch/arm/mach-tegra/apbio.h
arch/arm/mach-tegra/Makefile +0 -1
@@ -5,7 +5,6 @@ obj-y += irq.o obj-y += pmc.o obj-y += flowctrl.o obj-y += powergate.o -obj-y += apbio.o obj-y += pm.o obj-y += reset.o obj-y += reset-handler.o
arch/arm/mach-tegra/apbio.c deleted +0 -217
217 lines not on this page · raw message
arch/arm/mach-tegra/apbio.h deleted +0 -22
@@ -1,22 +0,0 @@ -/* -* Copyright (C) 2010 NVIDIA Corporation. -* 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. -* -*/ - -#ifndef __MACH_TEGRA_APBIO_H -#define __MACH_TEGRA_APBIO_H - -void tegra_apb_io_init (void ); -u32 tegra_apb_readl (unsigned long offset); -void tegra_apb_writel (u32 value,unsigned long offset); -#endif
arch/arm/mach-tegra/tegra.c +0 -2
@@ -43,7 +43,6 @@#include <asm/setup.h> #include <asm/trusted_foundations.h> -#include "apbio.h" #include "board.h" #include "common.h" #include "cpuidle.h"
@@ -73,7 +72,6 @@ u32 tegra_uart_config[3] = {static void __init tegra_init_early (void ) {of_register_trusted_foundations (); -tegra_apb_io_init ();tegra_init_fuse ();tegra_cpu_reset_handler_init ();tegra_powergate_init ();
drivers/soc/tegra/fuse/fuse-tegra20.c +76 -3
115 lines not on this page · raw message
include/linux/tegra-soc.h +0 -14
@@ -61,20 +61,6 @@ int tegra_fuse_readl(unsigned long offset, u32 *value);extern struct tegra_sku_info tegra_sku_info; -#if defined(CONFIG_TEGRA20_APB_DMA ) -int tegra_apb_readl_using_dma (unsigned long offset,u32 *value); -int tegra_apb_writel_using_dma (u32 value,unsigned long offset); -#else -static inline int tegra_apb_readl_using_dma (unsigned long offset,u32 *value) -{ -return -EINVAL ; -} -static inline int tegra_apb_writel_using_dma (u32 value,unsigned long offset) -{ -return -EINVAL ; -} -#endif /* CONFIG_TEGRA20_APB_DMA */ -#endif /* __ASSEMBLY__ */ #endif /* __LINUX_TEGRA_SOC_H_ */
Signature · 1 line
2.0.1
PATCH 8/12 misc: fuse: fix dummy functions
In reply to Thierry RedingFrom: Stephen Warren <[email protected]>
The Tegra fuse header's dummy functions for the case where Tegra20 is disabled are inconsistent with the correct prototypes, and have some syntax errors. Fix these. While at it, fix the indentation level of the dummy function bodies.
--- drivers/soc/tegra/fuse/fuse.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/soc/tegra/fuse/fuse.h +5 -5
@@ -38,14 +38,14 @@ void tegra20_init_fuse_early(void);u32 tegra20_fuse_early (const unsigned int offset);#else static inline void tegra20_init_speedo_data (struct tegra_sku_info *sku_info) {} -static inline bool tegra20_spare_fuse_early (int spare_bit,void *fuse_base) +static inline bool tegra20_spare_fuse_early (int spare_bit) { -return false; +return false; } -static inline void tegra20_init_fuse_early (void ); -static inline tegra20_fuse_early(const unsigned int offset); +static inline void tegra20_init_fuse_early (void ) {} +static inline u32 tegra20_fuse_early (const unsigned int offset) { -return 0 ; +return 0 ; }#endif
Signature · 1 line
2.0.1
PATCH 9/12 ARM: tegra: Setup CPU hotplug in a pure initcall
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
CPU hotplug support doesn't have to be set up until fairly late in the boot process, so it can be done in a regular initcall. To make sure that we don't miss any ordering problems in the future, output a warning if any of the functions are called before initialization has completed.
This is part of untangling the boot order dependencies on Tegra so that more code can be shared between 32-bit and 64-bit ARM.
--- arch/arm/mach-tegra/hotplug.c | 12 ++++++++++-- arch/arm/mach-tegra/sleep.h | 3 --- arch/arm/mach-tegra/tegra.c | 1 - 3 files changed, 10 insertions(+), 6 deletions(-)
arch/arm/mach-tegra/hotplug.c +10 -2
@@ -37,6 +37,11 @@ int tegra_cpu_kill(unsigned cpu)*/ void __ref tegra_cpu_die (unsigned int cpu) { +if (!tegra_hotplug_shutdown) { +WARN (1 ,"hotplug is not yet initialized\n" ); +return ; + } +/* Clean L1 data cache */ tegra_disable_clean_inv_dcache (TEGRA_FLUSH_CACHE_LOUIS );
@@ -47,10 +52,10 @@ void __ref tegra_cpu_die(unsigned int cpu)BUG (); } -void __init tegra_hotplug_init (void ) +static int __init tegra_hotplug_init (void ) {if (!IS_ENABLED (CONFIG_HOTPLUG_CPU )) -return ; +return 0 ;if (IS_ENABLED (CONFIG_ARCH_TEGRA_2x_SOC) &&tegra_get_chip_id () ==TEGRA20 ) tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
@@ -60,4 +65,7 @@ void __init tegra_hotplug_init(void) tegra_hotplug_shutdown = tegra30_hotplug_shutdown;if (IS_ENABLED (CONFIG_ARCH_TEGRA_124_SOC ) &&tegra_get_chip_id () ==TEGRA124 ) tegra_hotplug_shutdown = tegra30_hotplug_shutdown; + +return 0 ; } +pure_initcall (tegra_hotplug_init);
arch/arm/mach-tegra/sleep.h +0 -3
@@ -130,9 +130,6 @@ void tegra_disable_clean_inv_dcache(u32 flag);#ifdef CONFIG_HOTPLUG_CPU void tegra20_hotplug_shutdown (void );void tegra30_hotplug_shutdown (void ); -void tegra_hotplug_init (void ); -#else -static inline void tegra_hotplug_init (void ) {}#endif void tegra20_cpu_shutdown (int cpu);
arch/arm/mach-tegra/tegra.c +0 -1
@@ -75,7 +75,6 @@ static void __init tegra_init_early(void)tegra_init_fuse ();tegra_cpu_reset_handler_init ();tegra_powergate_init (); -tegra_hotplug_init (); }static void __init tegra_dt_init_irq (void )
Signature · 1 line
2.0.1
PATCH 10/12 ARM: tegra: Always lock the CPU reset vector
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
Currently the reset vector is not locked on Tegra20 because the hardware doesn't support it. However in order not to depend on the chip ID, which becomes available only later in the boot process, we set the bit anyway.
--- arch/arm/mach-tegra/reset.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
arch/arm/mach-tegra/reset.c +4 -6
@@ -53,12 +53,10 @@ static void __init tegra_cpu_reset_handler_set(const u32 reset_address)* Prevent further modifications to the physical reset vector. * NOTE: Has no effect on chips prior to Tegra30. */ -if (tegra_get_chip_id () !=TEGRA20 ) { - reg =readl (sb_ctrl); - reg |=2 ; -writel (reg, sb_ctrl); -wmb (); - } + reg =readl (sb_ctrl); + reg |=2 ; +writel (reg, sb_ctrl); +wmb (); }static void __init tegra_cpu_reset_handler_enable (void )
Signature · 1 line
2.0.1
PATCH 11/12 soc/tegra: fuse: Set up in early initcall
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
Rather than rely on explicit initialization order called from SoC setup code, use a plain initcall and rely on initcall ordering to take care of dependencies.
This driver exposes some functionality (querying the chip ID) needed at very early stages of the boot process. An early initcall is good enough provided that some of the dependencies are deferred to later stages. To make sure any abuses are easily caught, output a warning message if the chip ID is queried while it can't be read yet.
--- arch/arm/mach-tegra/tegra.c | 1 - drivers/soc/tegra/fuse/fuse-tegra.c | 7 +++++-- drivers/soc/tegra/fuse/tegra-apbmisc.c | 7 +++++-- include/linux/tegra-soc.h | 1 - 4 files changed, 10 insertions(+), 6 deletions(-)
arch/arm/mach-tegra/tegra.c +0 -1
@@ -72,7 +72,6 @@ u32 tegra_uart_config[3] = {static void __init tegra_init_early (void ) {of_register_trusted_foundations (); -tegra_init_fuse ();tegra_cpu_reset_handler_init ();tegra_powergate_init (); }
drivers/soc/tegra/fuse/fuse-tegra.c +5 -2
@@ -124,7 +124,7 @@ int tegra_fuse_create_sysfs(struct device *dev, int size,return device_create_bin_file (dev, &fuse_bin_attr); } -void __init tegra_init_fuse (void ) +static int __init tegra_init_fuse (void ) {struct device_node *np;void __iomem *car_base;
@@ -138,7 +138,7 @@ void __init tegra_init_fuse(void)iounmap (car_base); }else {pr_err ("Could not enable fuse clk. ioremap tegra car failed.\n" ); -return ; +return -ENXIO ; }if (tegra_get_chip_id () ==TEGRA20 )
@@ -152,4 +152,7 @@ void __init tegra_init_fuse(void) tegra_sku_info.core_process_id);pr_debug ("Tegra CPU Speedo ID %d, Soc Speedo ID %d\n" , tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id); + +return 0 ; } +early_initcall (tegra_init_fuse);
drivers/soc/tegra/fuse/tegra-apbmisc.c +5 -2
@@ -37,9 +37,12 @@ u32 tegra_read_chipid(void)u8 tegra_get_chip_id (void ) { -u32 id =tegra_read_chipid (); +if (!apbmisc_base) { +WARN (1 ,"Tegra Chip ID not yet available\n" ); +return 0 ; + } -return (id >>8 ) &0xff ; +return (tegra_read_chipid () >>8 ) &0xff ; }u32 tegra_read_straps (void )
include/linux/tegra-soc.h +0 -1
@@ -56,7 +56,6 @@ struct tegra_sku_info {u32 tegra_read_straps (void );u32 tegra_read_chipid (void ); -void tegra_init_fuse (void );int tegra_fuse_readl (unsigned long offset,u32 *value);extern struct tegra_sku_info tegra_sku_info;
Signature · 1 line
2.0.1
PATCH 12/12 ARM: tegra: Convert PMC to a driver
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
This commit converts the PMC support code to a platform driver. Because the boot process needs to cal into this driver very early, also set up a minimal environment via an early initcall.
--- arch/arm/mach-tegra/Makefile | 3 +- arch/arm/mach-tegra/board.h | 7 - arch/arm/mach-tegra/platsmp.c | 1 - arch/arm/mach-tegra/pm.c | 30 +- arch/arm/mach-tegra/pm.h | 10 +- arch/arm/mach-tegra/pmc.c | 413 ----------------- arch/arm/mach-tegra/pmc.h | 49 --- arch/arm/mach-tegra/powergate.c | 515 ---------------------- arch/arm/mach-tegra/tegra-pmc.c | 948 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-tegra/tegra.c | 6 - include/linux/tegra-soc.h | 46 ++ 11 files changed, 1018 insertions(+), 1010 deletions(-) delete mode 100644 arch/arm/mach-tegra/pmc.c delete mode 100644 arch/arm/mach-tegra/pmc.h delete mode 100644 arch/arm/mach-tegra/powergate.c create mode 100644 arch/arm/mach-tegra/tegra-pmc.c
arch/arm/mach-tegra/Makefile +1 -2
@@ -2,14 +2,13 @@ asflags-y += -march=armv7-a obj-y += io.o obj-y += irq.o -obj-y += pmc.o obj-y += flowctrl.o -obj-y += powergate.o obj-y += pm.o obj-y += reset.o obj-y += reset-handler.o obj-y += sleep.o obj-y += tegra.o +obj-y += tegra-pmc.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o
arch/arm/mach-tegra/board.h +0 -7
@@ -28,13 +28,6 @@void __init tegra_map_common_io (void );void __init tegra_init_irq (void ); -int __init tegra_powergate_init (void ); -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS ) -int __init tegra_powergate_debugfs_init (void ); -#else -static inline int tegra_powergate_debugfs_init (void ) {return 0 ; } -#endif -void __init tegra_paz00_wifikill_init (void );#endif
arch/arm/mach-tegra/platsmp.c +0 -1
@@ -30,7 +30,6 @@#include "common.h" #include "flowctrl.h" #include "iomap.h" -#include "pmc.h" #include "reset.h" static cpumask_t tegra_cpu_init_mask;
arch/arm/mach-tegra/pm.c +22 -8
@@ -37,7 +37,6 @@#include "flowctrl.h" #include "iomap.h" -#include "pmc.h" #include "pm.h" #include "reset.h" #include "sleep.h"
@@ -166,9 +165,29 @@ static int tegra_sleep_cpu(unsigned long v2p)return 0 ; } +static void tegra_pm_set (enum tegra_suspend_mode mode) +{ +u32 value; + +switch (tegra_get_chip_id ()) { +case TEGRA20 : +case TEGRA30 : +break ; +default : +/* Turn off CRAIL */ + value =flowctrl_read_cpu_csr (0 ); + value &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK ; + value |=FLOW_CTRL_CSR_ENABLE_EXT_CRAIL ; +flowctrl_write_cpu_csr (0 , value); +break ; + } + +tegra_pmc_enter_suspend_mode (mode); +} +void tegra_idle_lp2_last (void ) { -tegra_pmc_pm_set (TEGRA_SUSPEND_LP2 ); +tegra_pm_set (TEGRA_SUSPEND_LP2 );cpu_cluster_pm_enter ();suspend_cpu_complex ();
@@ -267,8 +286,6 @@ static bool tegra_sleep_core_init(void)static void tegra_suspend_enter_lp1 (void ) { -tegra_pmc_suspend (); -/* copy the reset vector & SDRAM shutdown code into IRAM */ memcpy (iram_save_addr,IO_ADDRESS (TEGRA_IRAM_LPx_RESUME_AREA), iram_save_size);
@@ -280,8 +297,6 @@ static void tegra_suspend_enter_lp1(void)static void tegra_suspend_exit_lp1 (void ) { -tegra_pmc_resume (); -/* restore IRAM */ memcpy (IO_ADDRESS (TEGRA_IRAM_LPx_RESUME_AREA), iram_save_addr, iram_save_size);
@@ -306,7 +321,7 @@ static int tegra_suspend_enter(suspend_state_t state)pr_info ("Entering suspend state %s\n" , lp_state[mode]); -tegra_pmc_pm_set (mode); +tegra_pm_set (mode);local_fiq_disable ();
@@ -354,7 +369,6 @@ void __init tegra_init_suspend(void)return ;tegra_tear_down_cpu_init (); -tegra_pmc_suspend_init ();if (mode >=TEGRA_SUSPEND_LP1 ) {if (!tegra_lp1_iram_hook () || !tegra_sleep_core_init ()) {
arch/arm/mach-tegra/pm.h +1 -9
@@ -21,12 +21,11 @@#ifndef _MACH_TEGRA_PM_H_#define _MACH_TEGRA_PM_H_ -#include "pmc.h" -struct tegra_lp1_iram {void *start_addr;void *end_addr; }; +extern struct tegra_lp1_iram tegra_lp1_iram;extern void (*tegra_sleep_core_finish)(unsigned long v2p);
@@ -42,15 +41,8 @@ void tegra_idle_lp2_last(void);extern void (*tegra_tear_down_cpu)(void );#ifdef CONFIG_PM_SLEEP -enum tegra_suspend_mode tegra_pm_validate_suspend_mode ( -enum tegra_suspend_mode mode);void tegra_init_suspend (void );#else -static inline enum tegra_suspend_mode tegra_pm_validate_suspend_mode ( -enum tegra_suspend_mode mode) -{ -return TEGRA_SUSPEND_NONE ; -}static inline void tegra_init_suspend (void ) {}#endif
arch/arm/mach-tegra/pmc.c deleted +0 -413
413 lines not on this page · raw message
arch/arm/mach-tegra/pmc.h deleted +0 -49
49 lines not on this page · raw message
arch/arm/mach-tegra/powergate.c deleted +0 -515
515 lines not on this page · raw message
arch/arm/mach-tegra/tegra-pmc.c new file +948 -0
948 lines not on this page · raw message
arch/arm/mach-tegra/tegra.c +0 -6
@@ -48,7 +48,6 @@#include "cpuidle.h" #include "iomap.h" #include "irq.h" -#include "pmc.h" #include "pm.h" #include "reset.h" #include "sleep.h"
@@ -73,12 +72,10 @@ static void __init tegra_init_early(void) {of_register_trusted_foundations ();tegra_cpu_reset_handler_init (); -tegra_powergate_init (); }static void __init tegra_dt_init_irq (void ) { -tegra_pmc_init_irq ();tegra_init_irq ();irqchip_init ();tegra_legacy_irq_syscore_init ();
@@ -90,8 +87,6 @@ static void __init tegra_dt_init(void)struct soc_device *soc_dev;struct device *parent =NULL ; -tegra_pmc_init (); -tegra_clocks_apply_init_table (); soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL );
@@ -141,7 +136,6 @@ static void __init tegra_dt_init_late(void)tegra_init_suspend ();tegra_cpuidle_init (); -tegra_powergate_debugfs_init ();for (i =0 ; i <ARRAY_SIZE (board_init_funcs); i++) {if (of_machine_is_compatible (board_init_funcs[i].machine)) {
include/linux/tegra-soc.h +46 -0
58 lines not on this page · raw message
Signature · 1 line
2.0.1
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 4 lines · Thierry Reding
From: Thierry Reding <[email protected]>
This commit converts the PMC support code to a platform driver. Because the boot process needs to cal into this driver very early, also set up a
Small typo: 'call' :)
Cheers,
Peter.
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 7 lines · Peter De Schrijver
Quoted 4 lines · Thierry Reding
From: Thierry Reding <[email protected]>
This commit converts the PMC support code to a platform driver. Because the boot process needs to cal into this driver very early, also set up a
Small typo: 'call' :)
Fixed, thanks.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140714/3c8483b4/attachment.sig>
Arnd Bergmann
maintainerPATCH 12/12 ARM: tegra: Convert PMC to a driver
In reply to Thierry RedingQuoted 14 lines · Thierry Reding
include/linux/tegra-soc.h +14
-0+/* +* PMC +*/ +enum tegra_suspend_mode { +TEGRA_SUSPEND_NONE =0 , +TEGRA_SUSPEND_LP2 ,/* CPU voltage off */ +TEGRA_SUSPEND_LP1 ,/* CPU voltage off, DRAM self-refresh */ +TEGRA_SUSPEND_LP0 ,/* CPU + core voltage off, DRAM self-refresh */ +TEGRA_MAX_SUSPEND_MODE , +}; + +#ifdef CONFIG_PM_SLEEP +enum tegra_suspend_mode tegra_pmc_get_suspend_mode (void ); +void tegra_pmc_set_suspend_mode (enum tegra_suspend_mode mode);
include/linux/tegra-soc.h int tegra_fuse_readl(unsigned long offset, u32 *value); · line 88
Quoted 10 lines
include/linux/tegra-soc.h +10
-0+void tegra_pmc_enter_suspend_mode (enum tegra_suspend_mode mode); + +bool tegra_pmc_cpu_is_powered (int cpuid); +int tegra_pmc_cpu_power_on (int cpuid); +int tegra_pmc_cpu_remove_clamping (int cpuid); + +void tegra_pmc_restart (enum reboot_mode mode,const char *cmd); +#endif + +/*
This part is causing multiple build failures in the randconfig tests. You can avoid them by removing the #ifdef.
On a more general note, why are you adding this stuff into a global header file in the first place? All users are in the same directory in which the functions are defined.
Arnd
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 20 lines · Arnd Bergmann
Quoted 19 lines · Thierry Reding
include/linux/tegra-soc.h +19
-0+/* +* PMC +*/ +enum tegra_suspend_mode { +TEGRA_SUSPEND_NONE =0 , +TEGRA_SUSPEND_LP2 ,/* CPU voltage off */ +TEGRA_SUSPEND_LP1 ,/* CPU voltage off, DRAM self-refresh */ +TEGRA_SUSPEND_LP0 ,/* CPU + core voltage off, DRAM self-refresh */ +TEGRA_MAX_SUSPEND_MODE , +}; + +#ifdef CONFIG_PM_SLEEP +enum tegra_suspend_mode tegra_pmc_get_suspend_mode (void ); +void tegra_pmc_set_suspend_mode (enum tegra_suspend_mode mode); +void tegra_pmc_enter_suspend_mode (enum tegra_suspend_mode mode); + +bool tegra_pmc_cpu_is_powered (int cpuid); +int tegra_pmc_cpu_power_on (int cpuid); +int tegra_pmc_cpu_remove_clamping (int cpuid);
Quoted 8 lines
include/linux/tegra-soc.h int tegra_fuse_readl(unsigned long offset, u32 *value); · line 88
Quoted 5 lines
include/linux/tegra-soc.h +5
-0+ +void tegra_pmc_restart (enum reboot_mode mode,const char *cmd); +#endif + +/* This part is causing multiple build failures in the randconfig tests. You can avoid them by removing the #ifdef.
How is this causing build failures? I only see them used wherever CONFIG_PM_SLEEP is defined.
Although I guess tegra-pmc.c could cause sparse warnings since it implements these functions regardless of CONFIG_PM_SLEEP, which probably is the bug that should be fixed.
Do you have a randconfig that I can use to reproduce this and come up with a fix?
Quoted 3 lines
On a more general note, why are you adding this stuff into a global header file in the first place? All users are in the same directory in which the functions are defined.
That's mostly preparatory work. We'll need to move tegra-pmc.c out of arch/arm/mach-tegra at some point. I've proposed two patches already to do that, one move the driver to drivers/soc/tegra and was massively NAK'ed (I'm still not sure I agree) and people requested that this be moved into drivers/power. I then posted a 2 patch series to move power supply drivers into a subdirectory (drivers/power/supply) so that drivers in drivers/power didn't have to depend on CONFIG_POWER_SUPPLY for no good reason.
The latter series didn't receive any comments whatsoever in over a week, so in order to keep things moving forward I respun the PMC patch to do the conversion without moving the code out of arch/arm/mach-tegra yet. That way moving the driver out of arch/arm/mach-tegra will be a simple matter of moving and the rework will already be done. You were Cc'ed on the second series, so if you want to take a look (and maybe help get things moving) the patches are called:
[PATCH 0/2] Restructure driver/power and add Tegra PMC driver [PATCH 1/2] power: Move power-supply drivers to subdirectory [PATCH 2/2] ARM: tegra: Convert PMC to a driver
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140716/3836f4bb/attachment.sig>
Arnd Bergmann
maintainerPATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 33 lines · On Wednesday 16 July 2014 15:22:41 Thierry Reding wrote:
Quoted 20 lines · Arnd Bergmann
Quoted 19 lines · Thierry Reding
(quoted diff) +19
-0+/* + * PMC + */ +enum tegra_suspend_mode { + TEGRA_SUSPEND_NONE = 0, + TEGRA_SUSPEND_LP2, /* CPU voltage off */ + TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ + TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ + TEGRA_MAX_SUSPEND_MODE, +}; + +#ifdef CONFIG_PM_SLEEP +enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); +void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); +void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); + +bool tegra_pmc_cpu_is_powered(int cpuid); +int tegra_pmc_cpu_power_on(int cpuid); +int tegra_pmc_cpu_remove_clamping(int cpuid);Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ +void tegra_pmc_restart(enum reboot_mode mode, const char *cmd); +#endif + +/*This part is causing multiple build failures in the randconfig tests. You can avoid them by removing the #ifdef.
How is this causing build failures? I only see them used wherever
CONFIG_PM_SLEEPis defined.
Quoted 6 lines
Although I guess
tegra-pmc.ccould cause sparse warnings since it implements these functions regardless ofCONFIG_PM_SLEEP, which probably is the bug that should be fixed.Do you have a randconfig that I can use to reproduce this and come up with a fix?
I got this error (always):
/git/arm-soc/arch/arm/mach-tegra/tegra.c:165:13: error: 'tegra_pmc_restart' undeclared here (not in a function)
.restart = tegra_pmc_restart,
^
make[3]: *** [arch/arm/mach-tegra/tegra.o] Error 1
when CONFIG_PM_SLEEP is disabled, and also this one when SMP is turned on in addition:
/git/arm-soc/arch/arm/mach-tegra/platsmp.c: In function 'tegra30_boot_secondary':
/git/arm-soc/arch/arm/mach-tegra/platsmp.c:97:4: error: implicit declaration of function 'tegra_pmc_cpu_is_powered' [-Werror=implicit-function-declaration]
if (tegra_pmc_cpu_is_powered(cpu))
^/git/arm-soc/arch/arm/mach-tegra/platsmp.c:110:3: error: implicit declaration of function 'tegra_pmc_cpu_power_on' [-Werror=implicit-function-declaration]
ret = tegra_pmc_cpu_power_on(cpu);
^
/git/arm-soc/arch/arm/mach-tegra/platsmp.c:129:2: error: implicit declaration of function 'tegra_pmc_cpu_remove_clamping' [-Werror=implicit-function-declaration]
ret = tegra_pmc_cpu_remove_clamping(cpu);
^
cc1: some warnings being treated as errors
I applied this hack locally to work around that:
include/linux/tegra-soc.h +0 -2
@@ -73,7 +73,6 @@ enum tegra_suspend_mode { TEGRA_MAX_SUSPEND_MODE, }; -#ifdef CONFIG_PM_SLEEP enum tegra_suspend_mode tegra_pmc_get_suspend_mode (void );void tegra_pmc_set_suspend_mode (enum tegra_suspend_mode mode);void tegra_pmc_enter_suspend_mode (enum tegra_suspend_mode mode);
@@ -83,7 +82,6 @@ int tegra_pmc_cpu_power_on(int cpuid);int tegra_pmc_cpu_remove_clamping (int cpuid);void tegra_pmc_restart (enum reboot_mode mode,const char *cmd); -#endif /* * PM
Quoted 21 lines
Quoted 3 lines
On a more general note, why are you adding this stuff into a global header file in the first place? All users are in the same directory in which the functions are defined.
That's mostly preparatory work. We'll need to move
tegra-pmc.cout ofarch/arm/mach-tegraat some point. I've proposed two patches already to do that, one move the driver todrivers/soc/tegraand was massively NAK'ed (I'm still not sure I agree) and people requested that this be moved intodrivers/power. I then posted a 2 patch series to move power supply drivers into a subdirectory (drivers/power/supply) so that drivers indrivers/powerdidn't have to depend onCONFIG_POWER_SUPPLYfor no good reason.The latter series didn't receive any comments whatsoever in over a week, so in order to keep things moving forward I respun the PMC patch to do the conversion without moving the code out of
arch/arm/mach-tegrayet. That way moving the driver out ofarch/arm/mach-tegrawill be a simple matter of moving and the rework will already be done. You were Cc'ed on the second series, so if you want to take a look (and maybe help get things moving) the patches are called:
Quoted 3 lines
[PATCH 0/2] Restructure driver/power and add Tegra PMC driver [PATCH 1/2] power: Move power-supply drivers to subdirectory [PATCH 2/2] ARM: tegra: Convert PMC to a driver
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Arnd
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 79 lines · Arnd Bergmann
Quoted 33 lines · On Wednesday 16 July 2014 15:22:41 Thierry Reding wrote:
Quoted 20 lines · Arnd Bergmann
Quoted 19 lines · Thierry Reding
(quoted diff) +19
-0+/* + * PMC + */ +enum tegra_suspend_mode { + TEGRA_SUSPEND_NONE = 0, + TEGRA_SUSPEND_LP2, /* CPU voltage off */ + TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ + TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ + TEGRA_MAX_SUSPEND_MODE, +}; + +#ifdef CONFIG_PM_SLEEP +enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); +void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); +void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); + +bool tegra_pmc_cpu_is_powered(int cpuid); +int tegra_pmc_cpu_power_on(int cpuid); +int tegra_pmc_cpu_remove_clamping(int cpuid);Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ +void tegra_pmc_restart(enum reboot_mode mode, const char *cmd); +#endif + +/*This part is causing multiple build failures in the randconfig tests. You can avoid them by removing the #ifdef.
How is this causing build failures? I only see them used wherever
CONFIG_PM_SLEEPis defined.Quoted 6 lines
Although I guess
tegra-pmc.ccould cause sparse warnings since it implements these functions regardless ofCONFIG_PM_SLEEP, which probably is the bug that should be fixed.Do you have a randconfig that I can use to reproduce this and come up with a fix?
I got this error (always):
/git/arm-soc/arch/arm/mach-tegra/tegra.c:165:13: error: '
tegra_pmc_restart' undeclared here (not in a function)
.restart =tegra_pmc_restart,^make[3]: *** [
arch/arm/mach-tegra/tegra.o] Error 1when
CONFIG_PM_SLEEPis disabled, and also this one when SMP is turned on in addition:/git/arm-soc/arch/arm/mach-tegra/platsmp.c: In function '
tegra30_boot_secondary':
/git/arm-soc/arch/arm/mach-tegra/platsmp.c:97:4: error: implicit declaration of function 'tegra_pmc_cpu_is_powered' [-Werror=implicit-function-declaration]if (tegra_pmc_cpu_is_powered(cpu)) ^ /git/arm-soc/arch/arm/mach-tegra/platsmp.c:110:3: error: implicit declaration of function 'tegra_pmc_cpu_power_on' [-Werror=implicit-function-declaration] ret = tegra_pmc_cpu_power_on(cpu); ^/git/arm-soc/arch/arm/mach-tegra/platsmp.c:129:2: error: implicit declaration of function '
tegra_pmc_cpu_remove_clamping' [-Werror=implicit-function-declaration]
ret =tegra_pmc_cpu_remove_clamping(cpu);
^
cc1: some warnings being treated as errorsI applied this hack locally to work around that:
include/linux/tegra-soc.h +0
-1@@ -73,7 +73,6 @@ enum tegra_suspend_mode { TEGRA_MAX_SUSPEND_MODE, }; -#ifdef CONFIG_PM_SLEEP enum tegra_suspend_mode tegra_pmc_get_suspend_mode (void );void tegra_pmc_set_suspend_mode (enum tegra_suspend_mode mode);void tegra_pmc_enter_suspend_mode (enum tegra_suspend_mode mode);
include/linux/tegra-soc.h int tegra_pmc_cpu_power_on(int cpuid); · line 87
Quoted 7 lines
include/linux/tegra-soc.h +0
-1@@ -83,7 +82,6 @@ int tegra_pmc_cpu_power_on(int cpuid);int tegra_pmc_cpu_remove_clamping (int cpuid);void tegra_pmc_restart (enum reboot_mode mode,const char *cmd); -#endif /* * PM
I pushed fixes for these to Tegra's for-next branch (and for-3.17/soc).
Quoted 22 lines
Quoted 22 lines
Quoted 4 lines
On a more general note, why are you adding this stuff into a global header file in the first place? All users are in the same directory in which the functions are defined.
That's mostly preparatory work. We'll need to move
tegra-pmc.cout ofarch/arm/mach-tegraat some point. I've proposed two patches already to do that, one move the driver todrivers/soc/tegraand was massively NAK'ed (I'm still not sure I agree) and people requested that this be moved intodrivers/power. I then posted a 2 patch series to move power supply drivers into a subdirectory (drivers/power/supply) so that drivers indrivers/powerdidn't have to depend onCONFIG_POWER_SUPPLYfor no good reason.The latter series didn't receive any comments whatsoever in over a week, so in order to keep things moving forward I respun the PMC patch to do the conversion without moving the code out of
arch/arm/mach-tegrayet. That way moving the driver out ofarch/arm/mach-tegrawill be a simple matter of moving and the rework will already be done. You were Cc'ed on the second series, so if you want to take a look (and maybe help get things moving) the patches are called:
Quoted 8 lines
Quoted 3 lines
[PATCH 0/2] Restructure driver/power and add Tegra PMC driver [PATCH 1/2] power: Move power-supply drivers to subdirectory [PATCH 2/2] ARM: tegra: Convert PMC to a driver
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Why do you think it should be a separate header? We already have a couple in include/linux and I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers into tegra-soc.h.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140716/1f01ff94/attachment.sig>
Arnd Bergmann
maintainerPATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 10 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.
I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
Arnd
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
The PMC driver also provides access to I/O rails and specifically a deep power down state. Some modules are in deep power down state by default, so they need to be brought out of that state. I suppose this would be easier to turn into a generic framework because there aren't any cross- dependencies like for powergates, but I'm not aware of any other SoC having a similar feature (or implementation thereof in the kernel). And adding a subsystem just for the sake of it if only one implementation is available isn't a good idea in my opinion because it will be naturally designed to work best (and therefore maybe only) for the one instance.
This issue is a fundamental one and there are bound to be other SoCs that have similarly unique blocks for which it's impractical to add a framework. I suspect the primary reason why we haven't run into it this frequently is because a lot of it is still hidden in arch/arm/mach-*.
I'm open to suggestions of course, but the best option I currently see is to collect these custom APIs in a central place so that we can easily compare various SoCs for commonalities as time goes by and factor them out into subsystems where appropriate.
For the same reason I think it's valid to put this type of code into drivers/soc. That way we have one subdirectory to look through for potential unification rather than various ones sprinkled across arch directories. It makes little sense in my opinion to move this code to drivers/power if there's no common framework anyway.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140716/11839690/attachment-0001.sig>
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 54 lines · Thierry Reding
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
The PMC driver also provides access to I/O rails and specifically a deep power down state. Some modules are in deep power down state by default, so they need to be brought out of that state. I suppose this would be easier to turn into a generic framework because there aren't any cross- dependencies like for powergates, but I'm not aware of any other SoC having a similar feature (or implementation thereof in the kernel). And adding a subsystem just for the sake of it if only one implementation is available isn't a good idea in my opinion because it will be naturally designed to work best (and therefore maybe only) for the one instance.
This issue is a fundamental one and there are bound to be other SoCs that have similarly unique blocks for which it's impractical to add a framework. I suspect the primary reason why we haven't run into it this frequently is because a lot of it is still hidden in
arch/arm/mach-*.I'm open to suggestions of course, but the best option I currently see is to collect these custom APIs in a central place so that we can easily compare various SoCs for commonalities as time goes by and factor them out into subsystems where appropriate.
Quoted 5 lines
For the same reason I think it's valid to put this type of code into
drivers/soc. That way we have one subdirectory to look through for potential unification rather than various ones sprinkled across arch directories. It makes little sense in my opinion to move this code todrivers/powerif there's no common framework anyway.
I agree. We can move them out and make them common them later if needed.
We're sometimes trying too hard to find proper homes for various new drivers, which means that we're proliferating the kernel with a lot of new driver directories that have only one or two drivers in them.
I'd rather collect stuff in drivers/soc, and move it out as needed later. Especially since we merge drivers/soc through one merge path (arm-soc) and can keep an eye on it, while the scatter-drivers-everywhere approach merges through various maintainers.
-Olof
Arnd Bergmann
maintainerPATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 24 lines · On Wednesday 16 July 2014 12:34:56 Olof Johansson wrote:
Quoted 22 lines · Thierry Reding
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 11 lines
Quoted 11 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
I don't completely follow, but that's ok ;-)
Quoted 32 lines
Quoted 20 lines
The PMC driver also provides access to I/O rails and specifically a deep power down state. Some modules are in deep power down state by default, so they need to be brought out of that state. I suppose this would be easier to turn into a generic framework because there aren't any cross- dependencies like for powergates, but I'm not aware of any other SoC having a similar feature (or implementation thereof in the kernel). And adding a subsystem just for the sake of it if only one implementation is available isn't a good idea in my opinion because it will be naturally designed to work best (and therefore maybe only) for the one instance.
This issue is a fundamental one and there are bound to be other SoCs that have similarly unique blocks for which it's impractical to add a framework. I suspect the primary reason why we haven't run into it this frequently is because a lot of it is still hidden in
arch/arm/mach-*.I'm open to suggestions of course, but the best option I currently see is to collect these custom APIs in a central place so that we can easily compare various SoCs for commonalities as time goes by and factor them out into subsystems where appropriate.
Quoted 5 lines
For the same reason I think it's valid to put this type of code into
drivers/soc. That way we have one subdirectory to look through for potential unification rather than various ones sprinkled across arch directories. It makes little sense in my opinion to move this code todrivers/powerif there's no common framework anyway.I agree. We can move them out and make them common them later if needed.
We're sometimes trying too hard to find proper homes for various new drivers, which means that we're proliferating the kernel with a lot of new driver directories that have only one or two drivers in them.
Quoted 5 lines
I'd rather collect stuff in
drivers/soc, and move it out as needed later. Especially since we mergedrivers/socthrough one merge path (arm-soc) and can keep an eye on it, while the scatter-drivers-everywhere approach merges through various maintainers.
Ok. I'm fine with having one driver in drivers/soc for the pmc (and a few associated bits if necessary) and a header file for that. If you end up with two separate drivers in drivers/soc, I'd also prefer two separate header files.
It may be a good idea to put these headers somewhere other than include/linux/*.h, which is completely overloaded by random stuff. We could use include/linux/soc/*.h or include/soc/*.h for those.
Arnd
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 77 lines · Arnd Bergmann
Quoted 24 lines · On Wednesday 16 July 2014 12:34:56 Olof Johansson wrote:
Quoted 22 lines · Thierry Reding
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 11 lines
Quoted 11 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
I don't completely follow, but that's ok ;-)
Quoted 32 lines
Quoted 20 lines
The PMC driver also provides access to I/O rails and specifically a deep power down state. Some modules are in deep power down state by default, so they need to be brought out of that state. I suppose this would be easier to turn into a generic framework because there aren't any cross- dependencies like for powergates, but I'm not aware of any other SoC having a similar feature (or implementation thereof in the kernel). And adding a subsystem just for the sake of it if only one implementation is available isn't a good idea in my opinion because it will be naturally designed to work best (and therefore maybe only) for the one instance.
This issue is a fundamental one and there are bound to be other SoCs that have similarly unique blocks for which it's impractical to add a framework. I suspect the primary reason why we haven't run into it this frequently is because a lot of it is still hidden in
arch/arm/mach-*.I'm open to suggestions of course, but the best option I currently see is to collect these custom APIs in a central place so that we can easily compare various SoCs for commonalities as time goes by and factor them out into subsystems where appropriate.
Quoted 5 lines
For the same reason I think it's valid to put this type of code into
drivers/soc. That way we have one subdirectory to look through for potential unification rather than various ones sprinkled across arch directories. It makes little sense in my opinion to move this code todrivers/powerif there's no common framework anyway.I agree. We can move them out and make them common them later if needed.
We're sometimes trying too hard to find proper homes for various new drivers, which means that we're proliferating the kernel with a lot of new driver directories that have only one or two drivers in them.
Quoted 5 lines
I'd rather collect stuff in
drivers/soc, and move it out as needed later. Especially since we mergedrivers/socthrough one merge path (arm-soc) and can keep an eye on it, while the scatter-drivers-everywhere approach merges through various maintainers.
Quoted 8 lines
Ok. I'm fine with having one driver in
drivers/socfor the pmc (and a few associated bits if necessary) and a header file for that. If you end up with two separate drivers indrivers/soc, I'd also prefer two separate header files.It may be a good idea to put these headers somewhere other than
include/linux/*.h, which is completely overloaded by random stuff. We could useinclude/linux/soc/*.horinclude/soc/*.hfor those.
We could go all the way and make it include/soc/tegra/*.h for better namespacing. I guess either way would be fine, really, since the number of files in those directories should be small by definition, so we should be able to do without the extra SoC directory, too. I have a slight preference for a separate SoC directory, do you have any objections?
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140717/afc16874/attachment-0001.sig>
Arnd Bergmann
maintainerPATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 7 lines · On Thursday 17 July 2014 13:06:53 Thierry Reding wrote:
We could go all the way and make it
include/soc/tegra/*.hfor better namespacing. I guess either way would be fine, really, since the number of files in those directories should be small by definition, so we should be able to do without the extra SoC directory, too. I have a slight preference for a separate SoC directory, do you have any objections?
I'm fine with it either way. I just noticed that you have now moved the file, which resulted in a build error:
../drivers/ata/ahci_tegra.c:27:35: fatal error: linux/tegra-powergate.h: No such file or directory
#include <linux/tegra-powergate.h>
^compilation terminated.
make[4]: *** [drivers/ata/ahci_tegra.o] Error 1
so somebody needs to pick up this patch:
drivers/ata/ahci_tegra.c +1 -1
@@ -24,8 +24,8 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> -#include <linux/tegra-powergate.h> #include <linux/regulator/consumer.h> +#include <soc/tegra/pmc.h> #include "ahci.h" #define SATA_CONFIGURATION_0 0x180
I haven't checked which trees are affected of if you have already posted a patch to do this.
Arnd
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 36 lines · Arnd Bergmann
Quoted 7 lines · On Thursday 17 July 2014 13:06:53 Thierry Reding wrote:
We could go all the way and make it
include/soc/tegra/*.hfor better namespacing. I guess either way would be fine, really, since the number of files in those directories should be small by definition, so we should be able to do without the extra SoC directory, too. I have a slight preference for a separate SoC directory, do you have any objections?I'm fine with it either way. I just noticed that you have now moved the file, which resulted in a build error:
../drivers/ata/ahci_tegra.c:27:35: fatal error:linux/tegra-powergate.h: No such file or directory#include <linux/tegra-powergate.h> ^compilation terminated.
make[4]: *** [drivers/ata/ahci_tegra.o] Error 1so somebody needs to pick up this patch:
drivers/ata/ahci_tegra.c +1
-1@@ -24,8 +24,8 @@#include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> -#include <linux/tegra-powergate.h> #include <linux/regulator/consumer.h> +#include <soc/tegra/pmc.h> #include "ahci.h" #define SATA_CONFIGURATION_0 0x180
Quoted 4 lines
I haven't checked which trees are affected of if you have already posted a patch to do this.
Arnd
Adding Tejun, since he took this into his tree on Friday I think, just a few hours after I sent out pull requests for this.
I hadn't considered this build dependency. We could resolve this in two ways I think:
- merge the for-3.17/fuse-move branch from the Tegra tree into the libata tree and apply Arnd's patch to the libata tree
- provide a dummy include/linux/tegra-powergate.h header that includes soc/tegra/powergate.h
In the latter case the dummy could possibly be removed right after v3.17-rc1 along with a patch to convert the AHCI driver to use the new header file. Or we could keep the compatibility header until the v3.18 merge window. I have a slight preference for this, even though it's a wee bit of churn.
The problem is that we can't simply apply the patch that Arnd provided because it would break the standalone libata tree if somebody were to build Tegra with the new driver enabled.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140721/90b6b262/attachment-0001.sig>
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 8 lines · Thierry Reding
Adding Tejun, since he took this into his tree on Friday I think, just a few hours after I sent out pull requests for this.
I hadn't considered this build dependency. We could resolve this in two ways I think:
- merge the for-3.17/fuse-move branch from the Tegra tree into the libata tree and apply Arnd's patch to the libata tree
I can pull the tegra tree into the libata if the tegra maintainer is okay with it.
Thanks.
Signature · 1 line
tejun
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 4 lines · Tejun Heo
Quoted 3 lines · Thierry Reding
Adding Tejun, since he took this into his tree on Friday I think, just a few hours after I sent out pull requests for this.
Quoted 8 lines
Quoted 5 lines
I hadn't considered this build dependency. We could resolve this in two ways I think:
- merge the for-3.17/fuse-move branch from the Tegra tree into the libata tree and apply Arnd's patch to the libata tree
I can pull the tegra tree into the libata if the tegra maintainer is okay with it.
It's fine with me, but maybe give Stephen, Arnd and Olof an opportunity to object.
If you plan to go ahead with merging it in, this would be the right signed tag to use:
https://git.kernel.org/cgit/linux/kernel/git/tegra/linux.git/tag/?id=tegra-for-3.17-soc
And then you simply need to replace #include <linux/tegra-powergate.h> with #include <soc/tegra/pmc.h> as Arnd showed.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140721/11965731/attachment.sig>
PATCH 12/12 ARM: tegra: Convert PMC to a driver
In reply to Thierry RedingQuoted 24 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Which won't work if you have domains which contain several modules.
Peter.
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 41 lines · Peter De Schrijver
Quoted 24 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 6 lines
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Which won't work if you have domains which contain several modules.
We also need to control the memory clients in the domains using MC_CLIENT_HOTRESET_CTRL.
Cheers,
Peter.
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 47 lines · Peter De Schrijver
Quoted 46 lines · Peter De Schrijver
Quoted 24 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 7 lines · Arnd Bergmann
Quoted 6 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 5 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 8 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Quoted 4 lines
Quoted 1 line
Which won't work if you have domains which contain several modules.
We also need to control the memory clients in the domains using
MC_CLIENT_HOTRESET_CTRL.
Oh, great. More interdependencies...
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140717/1fca334e/attachment.sig>
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 39 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 36 lines · Peter De Schrijver
Quoted 35 lines · Peter De Schrijver
Quoted 19 lines · Thierry Reding
Quoted 1 line
Old Signed by an unknown key
Quoted 5 lines · Arnd Bergmann
Quoted 4 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 4 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 7 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Which won't work if you have domains which contain several modules.
We also need to control the memory clients in the domains using
MC_CLIENT_HOTRESET_CTRL.Oh, great. More interdependencies...
Some domains depend on others. Can we take this into account?
Thanks,
Vince
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 45 lines · Vince Hsu
Quoted 43 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 40 lines · Peter De Schrijver
Quoted 39 lines · Peter De Schrijver
Quoted 19 lines · Thierry Reding
Quoted 1 line
Old Signed by an unknown key
Quoted 5 lines · Arnd Bergmann
Quoted 4 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 4 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 7 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Quoted 5 lines
Quoted 4 lines
Quoted 3 lines
Quoted 1 line
Which won't work if you have domains which contain several modules.
We also need to control the memory clients in the domains using
MC_CLIENT_HOTRESET_CTRL.Oh, great. More interdependencies...
Some domains depend on others. Can we take this into account?
I'm not aware of any dependencies. Can you point me at the relevant section in the TRM?
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140721/6ddc88eb/attachment.sig>
PATCH 12/12 ARM: tegra: Convert PMC to a driver
Quoted 46 lines · Thierry Reding
* PGP Signed by an unknown key
Quoted 43 lines · Vince Hsu
Quoted 42 lines · Thierry Reding
Quoted 1 line
Old Signed by an unknown key
Quoted 40 lines · Peter De Schrijver
Quoted 39 lines · Peter De Schrijver
Quoted 19 lines · Thierry Reding
Quoted 1 line
Old Signed by an unknown key
Quoted 5 lines · Arnd Bergmann
Quoted 4 lines · On Wednesday 16 July 2014 17:14:29 Thierry Reding wrote:
Quoted 4 lines
Ok, I'll have a look. I think when this becomes a separate driver, it should also have its own header file, so maybe you can in the meantime make it a local header file in mach-tegra until we have found a good place for it.
Quoted 7 lines
Quoted 4 lines
Why do you think it should be a separate header? We already have a couple in
include/linuxand I'm not sure it's useful to add even more. If anything I would've thought it made sense to move the content of the other headers intotegra-soc.h.I very much dislike the idea of having a per-vendor header file that everything gets crammed into. We should try to have proper subsystems and generic interfaces for these wherever possible.
I completely agree. However spreading the SoC-specific functions across multiple header files isn't going to help. If we keep all the per-vendor APIs in one file it makes it easier to see what could still be moved off into a separate subsystem.
Quoted 8 lines
Now for PMC specifically, we've investigated converting the powergate API to power domains. I don't think it will be possible to make that work. The issue is that there's a defined sequence that needs to be respected to make sure the device is powered up properly. That sequence involves the primary clock and reset of the device. It's been proposed to make these clocks available to the PMC driver so that it can control them, but then we can't make sure that clocks are really off if they need to be, since we have two drivers accessing them. The only way I see
resets do not have reference counts, so they can be controlled by a powerdomain driver without any problems. For clocks, there would only be a problem for the module clocks if the drivers don't use runtime PM. If we move all drivers to runtime PM, the clock control can move into the powerdomain code and runtime PM will ensure domains are not turned off with active modules.
Quoted 4 lines
to make that work reliably is by moving complete control of the powergate into drivers so that they can make sure clocks and resets are in the correct states.
Quoted 7 lines
Quoted 5 lines
Quoted 4 lines
Quoted 3 lines
Quoted 1 line
Which won't work if you have domains which contain several modules.
We also need to control the memory clients in the domains using
MC_CLIENT_HOTRESET_CTRL.Oh, great. More interdependencies...
Some domains depend on others. Can we take this into account?
I'm not aware of any dependencies. Can you point me at the relevant section in the TRM?
As we talked offline yesterday, that's in 5.6.6.7 - 5.6.6.9.
Thanks,
Vince
cover Add NVIDIA Tegra FUSE driver
In reply to Thierry RedingQuoted 36 lines · Thierry Reding
From: Thierry Reding <[email protected]>
This series is an extension of Peter's original series to add a proper driver for the FUSE block on Tegra.
Patches 1 and 2 are preparatory work that cleans up include lists and introduces a function to query the Tegra chip ID rather than accessing a simple variable. This is used by subsequent patches to allow us to execute code when the variable is accessed to help in pin-pointing locations where it's accessed before the driver had a chance to initialize.
Patches 3 through 8 are Peter's series with a fixup patch by Stephen. I also moved the driver to
drivers/soc/tegra/fuseas requested by Olof.Patches 9 and 10 defer usages of the
tegra_get_chip_id()function to a later stage (pure_initcall). This allows patch 11 to set up the early FUSE support code from an early initcall. This has the advantage of not requiring an explicit call from SoC setup code inarch/arm/mach-tegraand will allow the code to be shared on 64-bit variants of Tegra.Patch 12 finally turns the PMC and powergate support code into a proper driver which also sets up a minimal environment from an early initcall. The driver isn't moved out of
arch/arm/mach-tegrayet because people have suggesteddrivers/poweras a good home, but that whole directory depends on thePOWER_SUPPLYKconfigsymbol yet this driver doesn't have anything to do with that. Once that debate has been settled the driver can easily be moved out in a separate patch.Some of the patches in this series introduce diagnostic
WARN()messages if functions are called without setup having completed. I've booted the v3.16-rc1 kernel with these changes on top on Tegra20 (TrimSlice), Tegra30 (Beaver), Tegra114 (Dalmore) and Tegra124 (Jetson TK1) without encountering any of the diagnostic warnings and without noticing any breakage.
Quoted 6 lines
Olof, this series should address the concerns you expressed after reviewing Stephen's earlier pull request for Peter's FUSE driver series. It would be great if you could take another look to see if this is more according to your taste. I'll see if I can take this through linux-next for a little and if you have no objections will submit another pull request next week.
I haven't looked at all the patches in detail yet, but I do like the approach in general. I've also applied and pushed them out for build+test here, but they're queued behind a couple of other builds so I won't have it until morning (you can poll for boot logs at arm-soc.lixom.net/bootlogs/misc/v3.16-rc4-371-g2c9d948 if you want to preempt me).
Quoted 2 lines
Peter De Schrijver (5):
ARM: tegra: export apb dma readl/writel
I thought I saw a patch from Peter that moved the apbio read code to the fuse driver since there are no other consumers. I think that's a reasonable thing to do.
-Olof
cover Add NVIDIA Tegra FUSE driver
Quoted 44 lines · Olof Johansson
Quoted 36 lines · Thierry Reding
From: Thierry Reding <[email protected]>
This series is an extension of Peter's original series to add a proper driver for the FUSE block on Tegra.
Patches 1 and 2 are preparatory work that cleans up include lists and introduces a function to query the Tegra chip ID rather than accessing a simple variable. This is used by subsequent patches to allow us to execute code when the variable is accessed to help in pin-pointing locations where it's accessed before the driver had a chance to initialize.
Patches 3 through 8 are Peter's series with a fixup patch by Stephen. I also moved the driver to
drivers/soc/tegra/fuseas requested by Olof.Patches 9 and 10 defer usages of the
tegra_get_chip_id()function to a later stage (pure_initcall). This allows patch 11 to set up the early FUSE support code from an early initcall. This has the advantage of not requiring an explicit call from SoC setup code inarch/arm/mach-tegraand will allow the code to be shared on 64-bit variants of Tegra.Patch 12 finally turns the PMC and powergate support code into a proper driver which also sets up a minimal environment from an early initcall. The driver isn't moved out of
arch/arm/mach-tegrayet because people have suggesteddrivers/poweras a good home, but that whole directory depends on thePOWER_SUPPLYKconfigsymbol yet this driver doesn't have anything to do with that. Once that debate has been settled the driver can easily be moved out in a separate patch.Some of the patches in this series introduce diagnostic
WARN()messages if functions are called without setup having completed. I've booted the v3.16-rc1 kernel with these changes on top on Tegra20 (TrimSlice), Tegra30 (Beaver), Tegra114 (Dalmore) and Tegra124 (Jetson TK1) without encountering any of the diagnostic warnings and without noticing any breakage.Quoted 6 lines
Olof, this series should address the concerns you expressed after reviewing Stephen's earlier pull request for Peter's FUSE driver series. It would be great if you could take another look to see if this is more according to your taste. I'll see if I can take this through linux-next for a little and if you have no objections will submit another pull request next week.
Quoted 6 lines
I haven't looked at all the patches in detail yet, but I do like the approach in general. I've also applied and pushed them out for build+test here, but they're queued behind a couple of other builds so I won't have it until morning (you can poll for boot logs at arm-soc.lixom.net/bootlogs/misc/v3.16-rc4-371-g2c9d948 if you want to preempt me).
Looks like Tegra boards are all fine. Thanks for testing these.
Quoted 6 lines
Quoted 2 lines
Peter De Schrijver (5):
ARM: tegra: export apb dma readl/writelI thought I saw a patch from Peter that moved the apbio read code to the fuse driver since there are no other consumers. I think that's a reasonable thing to do.
That's a later patch in this series:
soc/tegra: fuse: move APB DMA into Tegra20 fuse driver
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140714/39e3fcd8/attachment-0001.sig>