From b0f2faa5ca02358ebfe404801e2ad604dc88c471 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 17 Dec 2014 18:18:14 +0100 Subject: ARM: sunxi: Add "allwinner,sun6i-a31s" to mach-sunxi So far the A31s is 100% compatible with the A31, still lets do the same as what we've done for the A13 / A10s and give it its own compatible string, in case we need to differentiate later. Signed-off-by: Hans de Goede [Maxime: Removed unusude CPU_OF_DECLARE_METHOD] Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sunxi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5702025..1818f40 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -1226,6 +1226,7 @@ static void __init sun6i_init_clocks(struct device_node *node) ARRAY_SIZE(sun6i_critical_clocks)); } CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); +CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks); CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); static void __init sun9i_init_clocks(struct device_node *node) -- cgit v1.1 From 2b20b6164ec737bec67641564e477aa6e008748b Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 9 Dec 2014 22:36:50 +0000 Subject: soc/tegra: pmc: restrict compilation of suspend-related support to ARM Tegra SoCs with 64-bit ARM support don't currently support deep CPU low-power states in mainline Linux. When this support is added in the future, it will probably look rather different from the existing 32-bit ARM support, since the ARM64 maintainers' strong preference is to use PSCI to implement it. So, for the time being, prevent the CPU suspend-related code and data in the Tegra PMC driver from compiling on ARM64. Signed-off-by: Paul Walmsley Signed-off-by: Paul Walmsley Cc: Thierry Reding Cc: Allen Martin Cc: Stephen Warren Cc: Alexandre Courbot Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index a2c0ceb..4bdc654 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -739,7 +739,7 @@ static int tegra_pmc_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) static int tegra_pmc_suspend(struct device *dev) { tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41); @@ -753,10 +753,11 @@ static int tegra_pmc_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume); +#endif + static const char * const tegra20_powergates[] = { [TEGRA_POWERGATE_CPU] = "cpu", [TEGRA_POWERGATE_3D] = "3d", @@ -894,7 +895,9 @@ static struct platform_driver tegra_pmc_driver = { .name = "tegra-pmc", .suppress_bind_attrs = true, .of_match_table = tegra_pmc_match, +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) .pm = &tegra_pmc_pm_ops, +#endif }, .probe = tegra_pmc_probe, }; -- cgit v1.1 From 910978e753d0be0b429cf75b5adaed55b90c96b2 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 7 Jul 2014 15:26:30 +0200 Subject: clocksource: Build Tegra timer on 32-bit ARM only Instead of directly using the ARCH_TEGRA Kconfig symbol to enable this driver, add a new, non-user-visible Kconfig symbol (TEGRA_TIMER) which can be selected by the various SoCs. This is useful to disable building the driver on Tegra132 (64-bit ARM) where it doesn't currently compile but also isn't needed (yet). Acked-by: Daniel Lezcano Signed-off-by: Thierry Reding --- drivers/clocksource/Kconfig | 3 +++ drivers/clocksource/Makefile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index fc01ec2..c062b61 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -47,6 +47,9 @@ config SUN5I_HSTIMER select CLKSRC_MMIO bool +config TEGRA_TIMER + bool + config VT8500_TIMER bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 94d90b2..ba9ebd8 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -27,7 +27,7 @@ obj-$(CONFIG_ARCH_U300) += timer-u300.o obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o -obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o +obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o -- cgit v1.1 From 200d876a5ad136e9d92a107a8190dd8d017d76fc Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 8 Jan 2015 08:24:46 +0100 Subject: soc/tegra: fuse: Constify tegra_fuse_info structures These structures contain read-only data and are never modified, so they can be const. Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra30.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 8646fa9..d1a4290 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -56,7 +56,7 @@ struct tegra_fuse_info { static void __iomem *fuse_base; static struct clk *fuse_clk; -static struct tegra_fuse_info *fuse_info; +static const struct tegra_fuse_info *fuse_info; u32 tegra30_fuse_readl(const unsigned int offset) { @@ -78,18 +78,18 @@ u32 tegra30_fuse_readl(const unsigned int offset) return val; } -static struct tegra_fuse_info tegra30_info = { +static const struct tegra_fuse_info tegra30_info = { .size = 0x2a4, .spare_bit = 0x144, .speedo_idx = SPEEDO_TEGRA30, }; -static struct tegra_fuse_info tegra114_info = { +static const struct tegra_fuse_info tegra114_info = { .size = 0x2a0, .speedo_idx = SPEEDO_TEGRA114, }; -static struct tegra_fuse_info tegra124_info = { +static const struct tegra_fuse_info tegra124_info = { .size = 0x300, .speedo_idx = SPEEDO_TEGRA124, }; -- cgit v1.1 From 9b07eb0537fb5f4d5fed1c2466febf59170f2b2e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 9 Jan 2015 11:49:33 +0100 Subject: soc/tegra: fuse: Add Tegra132 support Tegra132 is very similar to Tegra124 from a peripheral point of view and uses the same fuse controller. Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 1 + drivers/soc/tegra/fuse/fuse-tegra30.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 011a336..c0d660f 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -81,6 +81,7 @@ static const struct of_device_id car_match[] __initconst = { { .compatible = "nvidia,tegra30-car", }, { .compatible = "nvidia,tegra114-car", }, { .compatible = "nvidia,tegra124-car", }, + { .compatible = "nvidia,tegra132-car", }, {}, }; diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index d1a4290..4d2f71b 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -182,6 +182,7 @@ static void __init legacy_fuse_init(void) fuse_info = &tegra114_info; break; case TEGRA124: + case TEGRA132: fuse_info = &tegra124_info; break; default: -- cgit v1.1 From a9a40a4a58bac4ff92d0c7e5aa82043074533a6a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 9 Jan 2015 11:15:33 +0100 Subject: soc/tegra: pmc: Add Tegra132 support Tegra132 uses the same GPU as Tegra124 and therefore requires the same method to remove clamps. However Tegra132 has a separate chip ID, so in order to avoid having to extend the list of chip IDs for the special case, add a feature flag to the SoC data. Reviewed-by: Paul Walmsley Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 4bdc654..0f096e7 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -88,6 +88,8 @@ struct tegra_pmc_soc { const char *const *powergates; unsigned int num_cpu_powergates; const u8 *cpu_powergates; + + bool has_gpu_clamps; }; /** @@ -225,11 +227,11 @@ int tegra_powergate_remove_clamping(int id) return -EINVAL; /* - * The Tegra124 GPU has a separate register (with different semantics) - * to remove clamps. + * On Tegra124 and later, the clamps for the GPU are controlled by a + * separate register (with different semantics). */ - if (tegra_get_chip_id() == TEGRA124) { - if (id == TEGRA_POWERGATE_3D) { + if (id == TEGRA_POWERGATE_3D) { + if (pmc->soc->has_gpu_clamps) { tegra_pmc_writel(0, GPU_RG_CNTRL); return 0; } @@ -773,6 +775,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { .powergates = tegra20_powergates, .num_cpu_powergates = 0, .cpu_powergates = NULL, + .has_gpu_clamps = false, }; static const char * const tegra30_powergates[] = { @@ -804,6 +807,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .powergates = tegra30_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates), .cpu_powergates = tegra30_cpu_powergates, + .has_gpu_clamps = false, }; static const char * const tegra114_powergates[] = { @@ -839,6 +843,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .powergates = tegra114_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates), .cpu_powergates = tegra114_cpu_powergates, + .has_gpu_clamps = false, }; static const char * const tegra124_powergates[] = { @@ -880,6 +885,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .powergates = tegra124_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates), .cpu_powergates = tegra124_cpu_powergates, + .has_gpu_clamps = true, }; static const struct of_device_id tegra_pmc_match[] = { -- cgit v1.1 From 29ee506d0d56f6d39cc237de2512f9cb5629cbf7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 15 Jan 2015 15:59:31 +0100 Subject: ARM: at91: move at91rm9200_idle() to clk/at91/pmc.c Move at91rm9200_idle() along with at91sam9_idle() in clk/at91/pmc.c. Signed-off-by: Alexandre Belloni Acked-by: Michael Turquette Signed-off-by: Nicolas Ferre --- drivers/clk/at91/pmc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 386999b..f07c815 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -27,6 +27,15 @@ void __iomem *at91_pmc_base; EXPORT_SYMBOL_GPL(at91_pmc_base); +void at91rm9200_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); +} + void at91sam9_idle(void) { at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); -- cgit v1.1 From a0b5cd4ac2d6542d524d8063961bf914b5df1efa Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 16 Jan 2015 17:11:28 +0100 Subject: bus: mvebu-mbus: use automatic I/O synchronization barriers Instead of using explicit I/O synchronization barriers shoehorned inside the streaming DMA mappings API (in arch/arm/mach-mvebu/coherency.c), we are switching to use automatic I/O synchronization barrier. The primary motivation for this change is that explicit I/O synchronization barriers are not only needed for streaming DMA mappings (which can easily be done by overriding the dma_map_ops), but also for coherent DMA mappings (which is a lot less easy to do, since the kernel assumes such mappings are coherent and don't require any sort of cache maintenance operation to ensure the consistency of the buffers). Switching to automatic I/O synchronization barriers will also allow us to use the existing arm_coherent_dma_ops instead of our custom arm_dma_ops. In order to use automatic I/O synchronization barriers, this commit changes mvebu-mbus in two ways: - It enables automatic I/O synchronization barriers in the 0x84 register of the MBus bridge, by enabling such barriers for all MBus units. This enables automatic barriers for the on-SoC peripherals that are doing DMA. - It enables the SyncEnable bit in the MBus windows, so that PCIe devices also use automatic I/O synchronization barrier. This automatic synchronization barrier relies on the assumption that at least one register of a given hardware unit is read before the driver accesses the DMA mappings modified by this unit. This assumption is guaranteed for PCI devices by vertue of the PCI standard, and we can reasonably verify that this assumption is also true for the limited number of platform drivers doing DMA used on Marvell EBU platforms. Signed-off-by: Thomas Petazzoni Signed-off-by: Andrew Lunn --- drivers/bus/mvebu-mbus.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 81bf297..061b5cf 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -69,6 +69,7 @@ */ #define WIN_CTRL_OFF 0x0000 #define WIN_CTRL_ENABLE BIT(0) +#define WIN_CTRL_SYNCBARRIER BIT(1) #define WIN_CTRL_TGT_MASK 0xf0 #define WIN_CTRL_TGT_SHIFT 4 #define WIN_CTRL_ATTR_MASK 0xff00 @@ -82,6 +83,9 @@ #define WIN_REMAP_LOW 0xffff0000 #define WIN_REMAP_HI_OFF 0x000c +#define UNIT_SYNC_BARRIER_OFF 0x84 +#define UNIT_SYNC_BARRIER_ALL 0xFFFF + #define ATTR_HW_COHERENCY (0x1 << 4) #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) @@ -316,6 +320,7 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | (attr << WIN_CTRL_ATTR_SHIFT) | (target << WIN_CTRL_TGT_SHIFT) | + WIN_CTRL_SYNCBARRIER | WIN_CTRL_ENABLE; writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); @@ -857,7 +862,8 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, phys_addr_t sdramwins_phys_base, size_t sdramwins_size, phys_addr_t mbusbridge_phys_base, - size_t mbusbridge_size) + size_t mbusbridge_size, + bool is_coherent) { int win; @@ -889,6 +895,10 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, mbus->soc->setup_cpu_target(mbus); + if (is_coherent) + writel(UNIT_SYNC_BARRIER_ALL, + mbus->mbuswins_base + UNIT_SYNC_BARRIER_OFF); + register_syscore_ops(&mvebu_mbus_syscore_ops); return 0; @@ -916,7 +926,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base, mbuswins_phys_base, mbuswins_size, sdramwins_phys_base, - sdramwins_size, 0, 0); + sdramwins_size, 0, 0, false); } #ifdef CONFIG_OF @@ -1118,7 +1128,8 @@ int __init mvebu_mbus_dt_init(bool is_coherent) sdramwins_res.start, resource_size(&sdramwins_res), mbusbridge_res.start, - resource_size(&mbusbridge_res)); + resource_size(&mbusbridge_res), + is_coherent); if (ret) return ret; -- cgit v1.1 From 7fdf3d8a0316ce31f87513f903addcb8f3b0dfb2 Mon Sep 17 00:00:00 2001 From: Michal Mazur Date: Tue, 30 Dec 2014 13:43:43 +0100 Subject: bus: mvebu-mbus: fix support of MBus window 13 on Armada XP/375/38x On Armada XP, 375 and 38x the MBus window 13 has the remap capability, like windows 0 to 7. However, the mvebu-mbus driver isn't currently taking into account this special case, which means that when window 13 is actually used, the remap registers are left to 0, making the device using this MBus window unavailable. To make things even more fun, the hardware designers have chosen to put the window 13 remap registers in a completely custom location, using a logic that differs from the one used for all other remappable windows. To solve this problem, this commit: * Adds a SoC specific function to calculate offset of remap registers to the mvebu_mbus_soc_data structure. This function, ->win_remap_offset(), returns the offset of the remap registers, or MVEBU_MBUS_NO_REMAP if the window does not have the remap capability. This new function replaces the previous integer field num_remappable_wins, which was insufficient to encode the special case of window 13. * Adds an implementation of the ->win_remap_offset() function for the various SoC families. Some have 2 first windows that are remapable, some the 4 first, some the 8 first, and then the Armada XP/375/38x case where the 8 first are remapable plus the special window 13. This is implemented in functions generic_mbus_win_remap_2_offset(), generic_mbus_win_remap_4_offset(), generic_mbus_win_remap_8_offset() and armada_xp_mbus_win_remap_offset() respectively. * Change the code to use the ->win_remap_offset() function when accessing the remap registers, and also to use a newly introduced mvebu_mbus_window_is_remappable() helper function that tells whether a given window is remapable or not. * Separate Armada 370 from XP/375/38X because the window 13 of Armada 370 does not support the remap capability. [Thomas: adapted for the mainline kernel, minor clarifications in the code, reword the commit log.] Signed-off-by: Michal Mazur Signed-off-by: Thomas Petazzoni [Andrew Lunn : Undo the simple fix for stable] Signed-off-by: Andrew Lunn --- drivers/bus/mvebu-mbus.c | 164 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 116 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 061b5cf..a62c8ae 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -110,9 +110,9 @@ struct mvebu_mbus_state; struct mvebu_mbus_soc_data { unsigned int num_wins; - unsigned int num_remappable_wins; bool has_mbus_bridge; unsigned int (*win_cfg_offset)(const int win); + unsigned int (*win_remap_offset)(const int win); void (*setup_cpu_target)(struct mvebu_mbus_state *s); int (*save_cpu_target)(struct mvebu_mbus_state *s, u32 *store_addr); @@ -158,6 +158,13 @@ const struct mbus_dram_target_info *mv_mbus_dram_info(void) } EXPORT_SYMBOL_GPL(mv_mbus_dram_info); +/* Checks whether the given window has remap capability */ +static bool mvebu_mbus_window_is_remappable(struct mvebu_mbus_state *mbus, + const int win) +{ + return mbus->soc->win_remap_offset(win) != MVEBU_MBUS_NO_REMAP; +} + /* * Functions to manipulate the address decoding windows */ @@ -189,9 +196,12 @@ static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus, *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT; if (remap) { - if (win < mbus->soc->num_remappable_wins) { - u32 remap_low = readl(addr + WIN_REMAP_LO_OFF); - u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF); + if (mvebu_mbus_window_is_remappable(mbus, win)) { + u32 remap_low, remap_hi; + void __iomem *addr_rmp = mbus->mbuswins_base + + mbus->soc->win_remap_offset(win); + remap_low = readl(addr_rmp + WIN_REMAP_LO_OFF); + remap_hi = readl(addr_rmp + WIN_REMAP_HI_OFF); *remap = ((u64)remap_hi << 32) | remap_low; } else *remap = 0; @@ -204,10 +214,11 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, void __iomem *addr; addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win); - writel(0, addr + WIN_BASE_OFF); writel(0, addr + WIN_CTRL_OFF); - if (win < mbus->soc->num_remappable_wins) { + + if (mvebu_mbus_window_is_remappable(mbus, win)) { + addr = mbus->mbuswins_base + mbus->soc->win_remap_offset(win); writel(0, addr + WIN_REMAP_LO_OFF); writel(0, addr + WIN_REMAP_HI_OFF); } @@ -215,14 +226,6 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, /* Checks whether the given window number is available */ -/* On Armada XP, 375 and 38x the MBus window 13 has the remap - * capability, like windows 0 to 7. However, the mvebu-mbus driver - * isn't currently taking into account this special case, which means - * that when window 13 is actually used, the remap registers are left - * to 0, making the device using this MBus window unavailable. The - * quick fix for stable is to not use window 13. A follow up patch - * will correctly handle this window. -*/ static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, const int win) { @@ -230,9 +233,6 @@ static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, mbus->soc->win_cfg_offset(win); u32 ctrl = readl(addr + WIN_CTRL_OFF); - if (win == 13) - return false; - return !(ctrl & WIN_CTRL_ENABLE); } @@ -325,13 +325,17 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); writel(ctrl, addr + WIN_CTRL_OFF); - if (win < mbus->soc->num_remappable_wins) { + + if (mvebu_mbus_window_is_remappable(mbus, win)) { + void __iomem *addr_rmp = mbus->mbuswins_base + + mbus->soc->win_remap_offset(win); + if (remap == MVEBU_MBUS_NO_REMAP) remap_addr = base; else remap_addr = remap; - writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF); - writel(0, addr + WIN_REMAP_HI_OFF); + writel(remap_addr & WIN_REMAP_LOW, addr_rmp + WIN_REMAP_LO_OFF); + writel(0, addr_rmp + WIN_REMAP_HI_OFF); } return 0; @@ -345,19 +349,27 @@ static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus, int win; if (remap == MVEBU_MBUS_NO_REMAP) { - for (win = mbus->soc->num_remappable_wins; - win < mbus->soc->num_wins; win++) + for (win = 0; win < mbus->soc->num_wins; win++) { + if (mvebu_mbus_window_is_remappable(mbus, win)) + continue; + if (mvebu_mbus_window_is_free(mbus, win)) return mvebu_mbus_setup_window(mbus, win, base, size, remap, target, attr); + } } + for (win = 0; win < mbus->soc->num_wins; win++) { + /* Skip window if need remap but is not supported */ + if ((remap != MVEBU_MBUS_NO_REMAP) && + !mvebu_mbus_window_is_remappable(mbus, win)) + continue; - for (win = 0; win < mbus->soc->num_wins; win++) if (mvebu_mbus_window_is_free(mbus, win)) return mvebu_mbus_setup_window(mbus, win, base, size, remap, target, attr); + } return -ENOMEM; } @@ -469,7 +481,7 @@ static int mvebu_devs_debug_show(struct seq_file *seq, void *v) ((wbase & (u64)(wsize - 1)) != 0)) seq_puts(seq, " (Invalid base/size!!)"); - if (win < mbus->soc->num_remappable_wins) { + if (mvebu_mbus_window_is_remappable(mbus, win)) { seq_printf(seq, " (remap %016llx)\n", (unsigned long long)wremap); } else @@ -495,12 +507,12 @@ static const struct file_operations mvebu_devs_debug_fops = { * SoC-specific functions and definitions */ -static unsigned int orion_mbus_win_offset(int win) +static unsigned int generic_mbus_win_cfg_offset(int win) { return win << 4; } -static unsigned int armada_370_xp_mbus_win_offset(int win) +static unsigned int armada_370_xp_mbus_win_cfg_offset(int win) { /* The register layout is a bit annoying and the below code * tries to cope with it. @@ -520,7 +532,7 @@ static unsigned int armada_370_xp_mbus_win_offset(int win) return 0x90 + ((win - 8) << 3); } -static unsigned int mv78xx0_mbus_win_offset(int win) +static unsigned int mv78xx0_mbus_win_cfg_offset(int win) { if (win < 8) return win << 4; @@ -528,6 +540,40 @@ static unsigned int mv78xx0_mbus_win_offset(int win) return 0x900 + ((win - 8) << 4); } +static unsigned int generic_mbus_win_remap_2_offset(int win) +{ + if (win < 2) + return generic_mbus_win_cfg_offset(win); + else + return MVEBU_MBUS_NO_REMAP; +} + +static unsigned int generic_mbus_win_remap_4_offset(int win) +{ + if (win < 4) + return generic_mbus_win_cfg_offset(win); + else + return MVEBU_MBUS_NO_REMAP; +} + +static unsigned int generic_mbus_win_remap_8_offset(int win) +{ + if (win < 8) + return generic_mbus_win_cfg_offset(win); + else + return MVEBU_MBUS_NO_REMAP; +} + +static unsigned int armada_xp_mbus_win_remap_offset(int win) +{ + if (win < 8) + return generic_mbus_win_cfg_offset(win); + else if (win == 13) + return 0xF0 - WIN_REMAP_LO_OFF; + else + return MVEBU_MBUS_NO_REMAP; +} + static void __init mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) { @@ -637,30 +683,40 @@ int mvebu_mbus_save_cpu_target(u32 *store_addr) return mbus_state.soc->save_cpu_target(&mbus_state, store_addr); } -static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { +static const struct mvebu_mbus_soc_data armada_370_mbus_data = { .num_wins = 20, - .num_remappable_wins = 8, .has_mbus_bridge = true, - .win_cfg_offset = armada_370_xp_mbus_win_offset, + .win_cfg_offset = armada_370_xp_mbus_win_cfg_offset, + .win_remap_offset = generic_mbus_win_remap_8_offset, + .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, + .show_cpu_target = mvebu_sdram_debug_show_orion, .save_cpu_target = mvebu_mbus_default_save_cpu_target, +}; + +static const struct mvebu_mbus_soc_data armada_xp_mbus_data = { + .num_wins = 20, + .has_mbus_bridge = true, + .win_cfg_offset = armada_370_xp_mbus_win_cfg_offset, + .win_remap_offset = armada_xp_mbus_win_remap_offset, .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_orion, + .save_cpu_target = mvebu_mbus_default_save_cpu_target, }; static const struct mvebu_mbus_soc_data kirkwood_mbus_data = { .num_wins = 8, - .num_remappable_wins = 4, - .win_cfg_offset = orion_mbus_win_offset, + .win_cfg_offset = generic_mbus_win_cfg_offset, .save_cpu_target = mvebu_mbus_default_save_cpu_target, + .win_remap_offset = generic_mbus_win_remap_4_offset, .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_orion, }; static const struct mvebu_mbus_soc_data dove_mbus_data = { .num_wins = 8, - .num_remappable_wins = 4, - .win_cfg_offset = orion_mbus_win_offset, + .win_cfg_offset = generic_mbus_win_cfg_offset, .save_cpu_target = mvebu_mbus_dove_save_cpu_target, + .win_remap_offset = generic_mbus_win_remap_4_offset, .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_dove, }; @@ -671,36 +727,40 @@ static const struct mvebu_mbus_soc_data dove_mbus_data = { */ static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = { .num_wins = 8, - .num_remappable_wins = 4, - .win_cfg_offset = orion_mbus_win_offset, + .win_cfg_offset = generic_mbus_win_cfg_offset, .save_cpu_target = mvebu_mbus_default_save_cpu_target, + .win_remap_offset = generic_mbus_win_remap_4_offset, .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_orion, }; static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = { .num_wins = 8, - .num_remappable_wins = 2, - .win_cfg_offset = orion_mbus_win_offset, + .win_cfg_offset = generic_mbus_win_cfg_offset, .save_cpu_target = mvebu_mbus_default_save_cpu_target, + .win_remap_offset = generic_mbus_win_remap_2_offset, .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_orion, }; static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = { .num_wins = 14, - .num_remappable_wins = 8, - .win_cfg_offset = mv78xx0_mbus_win_offset, + .win_cfg_offset = mv78xx0_mbus_win_cfg_offset, .save_cpu_target = mvebu_mbus_default_save_cpu_target, + .win_remap_offset = generic_mbus_win_remap_8_offset, .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, .show_cpu_target = mvebu_sdram_debug_show_orion, }; static const struct of_device_id of_mvebu_mbus_ids[] = { { .compatible = "marvell,armada370-mbus", - .data = &armada_370_xp_mbus_data, }, + .data = &armada_370_mbus_data, }, + { .compatible = "marvell,armada375-mbus", + .data = &armada_xp_mbus_data, }, + { .compatible = "marvell,armada380-mbus", + .data = &armada_xp_mbus_data, }, { .compatible = "marvell,armadaxp-mbus", - .data = &armada_370_xp_mbus_data, }, + .data = &armada_xp_mbus_data, }, { .compatible = "marvell,kirkwood-mbus", .data = &kirkwood_mbus_data, }, { .compatible = "marvell,dove-mbus", @@ -807,15 +867,19 @@ static int mvebu_mbus_suspend(void) for (win = 0; win < s->soc->num_wins; win++) { void __iomem *addr = s->mbuswins_base + s->soc->win_cfg_offset(win); + void __iomem *addr_rmp; s->wins[win].base = readl(addr + WIN_BASE_OFF); s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF); - if (win >= s->soc->num_remappable_wins) + if (!mvebu_mbus_window_is_remappable(s, win)) continue; - s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF); - s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF); + addr_rmp = s->mbuswins_base + + s->soc->win_remap_offset(win); + + s->wins[win].remap_lo = readl(addr_rmp + WIN_REMAP_LO_OFF); + s->wins[win].remap_hi = readl(addr_rmp + WIN_REMAP_HI_OFF); } s->mbus_bridge_ctrl = readl(s->mbusbridge_base + @@ -839,15 +903,19 @@ static void mvebu_mbus_resume(void) for (win = 0; win < s->soc->num_wins; win++) { void __iomem *addr = s->mbuswins_base + s->soc->win_cfg_offset(win); + void __iomem *addr_rmp; writel(s->wins[win].base, addr + WIN_BASE_OFF); writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF); - if (win >= s->soc->num_remappable_wins) + if (!mvebu_mbus_window_is_remappable(s, win)) continue; - writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF); - writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF); + addr_rmp = s->mbuswins_base + + s->soc->win_remap_offset(win); + + writel(s->wins[win].remap_lo, addr_rmp + WIN_REMAP_LO_OFF); + writel(s->wins[win].remap_hi, addr_rmp + WIN_REMAP_HI_OFF); } } -- cgit v1.1 From 1737cac6936938a9bc52c03c4a3ff2032c702fa5 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 9 Jan 2015 10:59:04 -0600 Subject: bus: mvebu-mbus: make sure SDRAM CS for DMA don't overlap the MBus bridge window The mvebu-mbus driver reads the SDRAM window registers, and make the information about the DRAM CS configuration available to device drivers using the mv_mbus_dram_info() API. This information is used by the DMA-capable device drivers to program their address decoding windows. Until now, we were basically providing the SDRAM window register details as is. However, it turns out that the DMA capability of the CESA cryptographic engine consists in doing DMA being the DRAM and the crypto SRAM mapped as a MBus window. For this case, it is very important that the SDRAM CS information does not overlap with the MBus bridge window. Therefore, this commit improves the mvebu-mbus driver to make sure we adjust the SDRAM CS information so that it doesn't overlap with the MBus bridge window. This problem was reported by Boris Brezillon, while working on the mv_cesa driver for Armada 37x/38x/XP. We use the memblock memory information to know where the usable RAM is located, as this information is guaranteed to be correct on all SoC variants. We could have used the MBus bridge window registers on Armada 370/XP, but they are not really used on Armada 375/38x (Cortex-A9 based), since the PL310 L2 filtering is used instead to discriminate between RAM accesses and I/O accesses. Therefore, using the memblock information is more generic and works accross the different platforms. Reported-by: Boris Brezillon Signed-off-by: Thomas Petazzoni [Andrew Lunn : Fixed merge conflict] Signed-off-by: Andrew Lunn --- drivers/bus/mvebu-mbus.c | 105 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index a62c8ae..fb9ec62 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -58,6 +58,7 @@ #include #include #include +#include /* * DDR target is the same on all platforms. @@ -101,7 +102,9 @@ /* Relative to mbusbridge_base */ #define MBUS_BRIDGE_CTRL_OFF 0x0 +#define MBUS_BRIDGE_SIZE_MASK 0xffff0000 #define MBUS_BRIDGE_BASE_OFF 0x4 +#define MBUS_BRIDGE_BASE_MASK 0xffff0000 /* Maximum number of windows, for all known platforms */ #define MBUS_WINS_MAX 20 @@ -574,36 +577,106 @@ static unsigned int armada_xp_mbus_win_remap_offset(int win) return MVEBU_MBUS_NO_REMAP; } +/* + * Use the memblock information to find the MBus bridge hole in the + * physical address space. + */ +static void __init +mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end) +{ + struct memblock_region *r; + uint64_t s = 0; + + for_each_memblock(memory, r) { + /* + * This part of the memory is above 4 GB, so we don't + * care for the MBus bridge hole. + */ + if (r->base >= 0x100000000) + continue; + + /* + * The MBus bridge hole is at the end of the RAM under + * the 4 GB limit. + */ + if (r->base + r->size > s) + s = r->base + r->size; + } + + *start = s; + *end = 0x100000000; +} + static void __init mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) { int i; int cs; + uint64_t mbus_bridge_base, mbus_bridge_end; mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end); + for (i = 0, cs = 0; i < 4; i++) { - u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); - u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); + u64 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); + u64 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); + u64 end; + struct mbus_dram_window *w; + + /* Ignore entries that are not enabled */ + if (!(size & DDR_SIZE_ENABLED)) + continue; /* - * We only take care of entries for which the chip - * select is enabled, and that don't have high base - * address bits set (devices can only access the first - * 32 bits of the memory). + * Ignore entries whose base address is above 2^32, + * since devices cannot DMA to such high addresses */ - if ((size & DDR_SIZE_ENABLED) && - !(base & DDR_BASE_CS_HIGH_MASK)) { - struct mbus_dram_window *w; + if (base & DDR_BASE_CS_HIGH_MASK) + continue; - w = &mvebu_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0xf & ~(1 << i); - if (mbus->hw_io_coherency) - w->mbus_attr |= ATTR_HW_COHERENCY; - w->base = base & DDR_BASE_CS_LOW_MASK; - w->size = (size | ~DDR_SIZE_MASK) + 1; + base = base & DDR_BASE_CS_LOW_MASK; + size = (size | ~DDR_SIZE_MASK) + 1; + end = base + size; + + /* + * Adjust base/size of the current CS to make sure it + * doesn't overlap with the MBus bridge hole. This is + * particularly important for devices that do DMA from + * DRAM to a SRAM mapped in a MBus window, such as the + * CESA cryptographic engine. + */ + + /* + * The CS is fully enclosed inside the MBus bridge + * area, so ignore it. + */ + if (base >= mbus_bridge_base && end <= mbus_bridge_end) + continue; + + /* + * Beginning of CS overlaps with end of MBus, raise CS + * base address, and shrink its size. + */ + if (base >= mbus_bridge_base && end > mbus_bridge_end) { + size -= mbus_bridge_end - base; + base = mbus_bridge_end; } + + /* + * End of CS overlaps with beginning of MBus, shrink + * CS size. + */ + if (base < mbus_bridge_base && end > mbus_bridge_base) + size -= end - mbus_bridge_base; + + w = &mvebu_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + if (mbus->hw_io_coherency) + w->mbus_attr |= ATTR_HW_COHERENCY; + w->base = base; + w->size = size; } mvebu_mbus_dram_info.num_cs = cs; } -- cgit v1.1 From 3568df3d31d62b4368830cc6aac868cecdefd187 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 6 Jan 2015 12:52:58 +0200 Subject: soc: tegra: Add thermal reset (thermtrip) support to PMC This adds a device tree controlled option to enable PMC-based thermal reset in overheating situations. Thermtrip is supported on Tegra30, Tegra114 and Tegra124. The thermal reset only works when the thermal sensors are calibrated, so a soctherm driver is also required. The thermtrip event is triggered by the soctherm block, and all soctherm sensors default to showing a temperature of zero Celsius before they are initialized. Because of this, it is safe to initialize thermtrip and soctherm in any order. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 0f096e7..c956395 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -70,6 +70,10 @@ #define PMC_SCRATCH41 0x140 +#define PMC_SENSOR_CTRL 0x1b0 +#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2) +#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1) + #define IO_DPD_REQ 0x1b8 #define IO_DPD_REQ_CODE_IDLE (0 << 30) #define IO_DPD_REQ_CODE_OFF (1 << 30) @@ -81,6 +85,18 @@ #define IO_DPD2_STATUS 0x1c4 #define SEL_DPD_TIM 0x1c8 +#define PMC_SCRATCH54 0x258 +#define PMC_SCRATCH54_DATA_SHIFT 8 +#define PMC_SCRATCH54_ADDR_SHIFT 0 + +#define PMC_SCRATCH55 0x25c +#define PMC_SCRATCH55_RESET_TEGRA (1 << 31) +#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27 +#define PMC_SCRATCH55_PINMUX_SHIFT 24 +#define PMC_SCRATCH55_16BITOP (1 << 15) +#define PMC_SCRATCH55_CHECKSUM_SHIFT 16 +#define PMC_SCRATCH55_I2CSLV1_SHIFT 0 + #define GPU_RG_CNTRL 0x2d4 struct tegra_pmc_soc { @@ -89,6 +105,7 @@ struct tegra_pmc_soc { unsigned int num_cpu_powergates; const u8 *cpu_powergates; + bool has_tsense_reset; bool has_gpu_clamps; }; @@ -112,6 +129,7 @@ struct tegra_pmc_soc { * @powergates_lock: mutex for power gate register access */ struct tegra_pmc { + struct device *dev; void __iomem *base; struct clk *clk; @@ -705,6 +723,83 @@ static void tegra_pmc_init(struct tegra_pmc *pmc) tegra_pmc_writel(value, PMC_CNTRL); } +void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) +{ + static const char disabled[] = "emergency thermal reset disabled"; + u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux; + struct device *dev = pmc->dev; + struct device_node *np; + u32 value, checksum; + + if (!pmc->soc->has_tsense_reset) + goto out; + + np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip"); + if (!np) { + dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled); + goto out; + } + + if (of_property_read_u32(np, "nvidia,i2c-controller-id", &ctrl_id)) { + dev_err(dev, "I2C controller ID missing, %s.\n", disabled); + goto out; + } + + if (of_property_read_u32(np, "nvidia,bus-addr", &pmu_addr)) { + dev_err(dev, "nvidia,bus-addr missing, %s.\n", disabled); + goto out; + } + + if (of_property_read_u32(np, "nvidia,reg-addr", ®_addr)) { + dev_err(dev, "nvidia,reg-addr missing, %s.\n", disabled); + goto out; + } + + if (of_property_read_u32(np, "nvidia,reg-data", ®_data)) { + dev_err(dev, "nvidia,reg-data missing, %s.\n", disabled); + goto out; + } + + if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux)) + pinmux = 0; + + value = tegra_pmc_readl(PMC_SENSOR_CTRL); + value |= PMC_SENSOR_CTRL_SCRATCH_WRITE; + tegra_pmc_writel(value, PMC_SENSOR_CTRL); + + value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) | + (reg_addr << PMC_SCRATCH54_ADDR_SHIFT); + tegra_pmc_writel(value, PMC_SCRATCH54); + + value = PMC_SCRATCH55_RESET_TEGRA; + value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT; + value |= pinmux << PMC_SCRATCH55_PINMUX_SHIFT; + value |= pmu_addr << PMC_SCRATCH55_I2CSLV1_SHIFT; + + /* + * Calculate checksum of SCRATCH54, SCRATCH55 fields. Bits 23:16 will + * contain the checksum and are currently zero, so they are not added. + */ + checksum = reg_addr + reg_data + (value & 0xff) + ((value >> 8) & 0xff) + + ((value >> 24) & 0xff); + checksum &= 0xff; + checksum = 0x100 - checksum; + + value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT; + + tegra_pmc_writel(value, PMC_SCRATCH55); + + value = tegra_pmc_readl(PMC_SENSOR_CTRL); + value |= PMC_SENSOR_CTRL_ENABLE_RST; + tegra_pmc_writel(value, PMC_SENSOR_CTRL); + + dev_info(pmc->dev, "emergency thermal reset enabled\n"); + +out: + of_node_put(np); + return; +} + static int tegra_pmc_probe(struct platform_device *pdev) { void __iomem *base = pmc->base; @@ -730,8 +825,12 @@ static int tegra_pmc_probe(struct platform_device *pdev) return err; } + pmc->dev = &pdev->dev; + tegra_pmc_init(pmc); + tegra_pmc_init_tsense_reset(pmc); + if (IS_ENABLED(CONFIG_DEBUG_FS)) { err = tegra_powergate_debugfs_init(); if (err < 0) @@ -775,6 +874,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { .powergates = tegra20_powergates, .num_cpu_powergates = 0, .cpu_powergates = NULL, + .has_tsense_reset = false, .has_gpu_clamps = false, }; @@ -807,6 +907,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .powergates = tegra30_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates), .cpu_powergates = tegra30_cpu_powergates, + .has_tsense_reset = true, .has_gpu_clamps = false, }; @@ -843,6 +944,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .powergates = tegra114_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates), .cpu_powergates = tegra114_cpu_powergates, + .has_tsense_reset = true, .has_gpu_clamps = false, }; @@ -885,6 +987,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .powergates = tegra124_powergates, .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates), .cpu_powergates = tegra124_cpu_powergates, + .has_tsense_reset = true, .has_gpu_clamps = true, }; -- cgit v1.1