diff options
Diffstat (limited to 'arch/arm/mach-tegra/flowctrl.c')
-rw-r--r-- | arch/arm/mach-tegra/flowctrl.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index ce8ab8abf061..475e783992fd 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c @@ -18,14 +18,16 @@ * 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 <linux/of.h> +#include <linux/of_address.h> + +#include <soc/tegra/fuse.h> #include "flowctrl.h" -#include "iomap.h" -#include "fuse.h" static u8 flowctrl_offset_halt_cpu[] = { FLOW_CTRL_HALT_CPU0_EVENTS, @@ -41,23 +43,22 @@ static u8 flowctrl_offset_cpu_csr[] = { FLOW_CTRL_CPU1_CSR + 16, }; +static void __iomem *tegra_flowctrl_base; + static void flowctrl_update(u8 offset, u32 value) { - void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset; - - writel(value, addr); + writel(value, tegra_flowctrl_base + offset); /* ensure the update has reached the flow controller */ wmb(); - readl_relaxed(addr); + readl_relaxed(tegra_flowctrl_base + offset); } u32 flowctrl_read_cpu_csr(unsigned int cpuid) { u8 offset = flowctrl_offset_cpu_csr[cpuid]; - void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset; - return readl(addr); + return readl(tegra_flowctrl_base + offset); } void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) @@ -76,7 +77,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 +118,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; @@ -138,3 +139,33 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid) reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */ flowctrl_write_cpu_csr(cpuid, reg); } + +static const struct of_device_id matches[] __initconst = { + { .compatible = "nvidia,tegra124-flowctrl" }, + { .compatible = "nvidia,tegra114-flowctrl" }, + { .compatible = "nvidia,tegra30-flowctrl" }, + { .compatible = "nvidia,tegra20-flowctrl" }, + { } +}; + +void __init tegra_flowctrl_init(void) +{ + /* hardcoded fallback if device tree node is missing */ + unsigned long base = 0x60007000; + unsigned long size = SZ_4K; + struct device_node *np; + + np = of_find_matching_node(NULL, matches); + if (np) { + struct resource res; + + if (of_address_to_resource(np, 0, &res) == 0) { + size = resource_size(&res); + base = res.start; + } + + of_node_put(np); + } + + tegra_flowctrl_base = ioremap_nocache(base, size); +} |