*
*/
+#include <dt-bindings/clock/tegra210-car.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/tegra-powergate.h>
#include <linux/tegra-soc.h>
-#include <linux/platform/tegra/dvfs.h>
#include <linux/tegra_soctherm.h>
+#include <soc/tegra/tegra-dvfs.h>
#include <trace/events/power.h>
#include "powergate-priv.h"
[TEGRA_POWERGATE_VE] = {
.name = "ve",
.clk_info = {
- [0] = { .clk_name = "ispa", .clk_type = CLK_AND_RST },
- [1] = { .clk_name = "vi", .clk_type = CLK_AND_RST },
- [2] = { .clk_name = "csi", .clk_type = CLK_AND_RST },
- [3] = { .clk_name = "vii2c", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "ispa", .clk_type = CLK_ONLY },
+ [1] = { .clk_name = "vi", .clk_type = CLK_ONLY },
+ [2] = { .clk_name = "csi", .clk_type = CLK_ONLY },
+ [3] = { .clk_name = "vii2c", .clk_type = CLK_ONLY },
[4] = { .clk_name = "cilab", .clk_type = CLK_ONLY },
[5] = { .clk_name = "cilcd", .clk_type = CLK_ONLY },
[6] = { .clk_name = "cile", .clk_type = CLK_ONLY },
[5] = { .clk_name = "vi_slcg_ovr" },
[6] = { .clk_name = "ispa_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_ISP, TEGRA210_CLK_VI,
+ TEGRA210_CLK_CSI, TEGRA210_CLK_VI_I2C },
+ .reset_id_num = 4,
},
#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
[TEGRA_POWERGATE_PCIE] = {
.name = "pcie",
.clk_info = {
- [0] = { .clk_name = "afi", .clk_type = CLK_AND_RST },
- [1] = { .clk_name = "pcie", .clk_type = CLK_AND_RST },
- [2] = { .clk_name = "pciex", .clk_type = RST_ONLY },
+ [0] = { .clk_name = "afi", .clk_type = CLK_ONLY },
+ [1] = { .clk_name = "pcie", .clk_type = CLK_ONLY },
},
+ .reset_id = { TEGRA210_CLK_AFI, TEGRA210_CLK_PCIE,
+ TEGRA210_CLK_PCIEX },
+ .reset_id_num = 3,
.skip_reset = true,
},
#endif
.name = "sata",
.disable_after_boot = true,
.clk_info = {
- [0] = { .clk_name = "sata_oob", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "sata_oob", .clk_type = CLK_ONLY },
[1] = { .clk_name = "cml1", .clk_type = CLK_ONLY },
- [2] = { .clk_name = "sata_cold", .clk_type = RST_ONLY },
[3] = { .clk_name = "sata_aux", .clk_type = CLK_ONLY },
- [4] = { .clk_name = "sata", .clk_type = CLK_AND_RST },
+ [4] = { .clk_name = "sata", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[5] = { .clk_name = "sata_slcg_ovr_ipfs" },
[6] = { .clk_name = "sata_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_SATA_COLD,
+ TEGRA210_CLK_SATA },
+ .reset_id_num = 3,
},
#endif
[TEGRA_POWERGATE_NVENC] = {
.name = "nvenc",
.clk_info = {
- [0] = { .clk_name = "msenc.cbus", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "msenc.cbus", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[3] = { .clk_name = "mc_cdpa" },
[4] = { .clk_name = "msenc_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_NVENC },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_SOR] = {
.name = "sor",
.clk_info = {
- [0] = { .clk_name = "sor0", .clk_type = CLK_AND_RST },
- [1] = { .clk_name = "dsia", .clk_type = CLK_AND_RST },
- [2] = { .clk_name = "dsib", .clk_type = CLK_AND_RST },
- [3] = { .clk_name = "sor1", .clk_type = CLK_AND_RST },
- [4] = { .clk_name = "mipi-cal", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "sor0", .clk_type = CLK_ONLY },
+ [1] = { .clk_name = "dsia", .clk_type = CLK_ONLY },
+ [2] = { .clk_name = "dsib", .clk_type = CLK_ONLY },
+ [3] = { .clk_name = "sor1", .clk_type = CLK_ONLY },
+ [4] = { .clk_name = "mipi-cal", .clk_type = CLK_ONLY },
[5] = { .clk_name = "dpaux", .clk_type = CLK_ONLY },
[6] = { .clk_name = "dpaux1", .clk_type = CLK_ONLY },
},
[8] = { .clk_name = "disp1_slcg_ovr" },
[9] = { .clk_name = "disp2_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_SOR0, TEGRA210_CLK_DISP1,
+ TEGRA210_CLK_DSIB, TEGRA210_CLK_SOR1,
+ TEGRA210_CLK_MIPI_CAL },
+ .reset_id_num = 5,
},
[TEGRA_POWERGATE_DISA] = {
.name = "disa",
.clk_info = {
- [0] = { .clk_name = "disp1", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "disp1", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[5] = { .clk_name = "host1x" },
[6] = { .clk_name = "disp1_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_DISP1 },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_DISB] = {
.name = "disb",
.disable_after_boot = true,
.clk_info = {
- [0] = { .clk_name = "disp2", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "disp2", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[5] = { .clk_name = "host1x" },
[6] = { .clk_name = "disp2_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_DISP2 },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_XUSBA] = {
.name = "xusba",
.clk_info = {
- [0] = { .clk_name = "xusb_ss", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "xusb_ss", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[6] = { .clk_name = "xusb_host_slcg_ovr" },
[7] = { .clk_name = "xusb_dev_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_XUSB_SS },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_XUSBB] = {
.name = "xusbb",
.clk_info = {
- [0] = { .clk_name = "xusb_dev", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "xusb_dev", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[6] = { .clk_name = "xusb_host_slcg_ovr" },
[7] = { .clk_name = "xusb_dev_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_XUSB_DEV },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_XUSBC] = {
.name = "xusbc",
.clk_info = {
- [0] = { .clk_name = "xusb_host", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "xusb_host", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[6] = { .clk_name = "xusb_dev_slcg_ovr" },
[7] = { .clk_name = "xusb_host_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_XUSB_HOST },
+ .reset_id_num = 1,
},
#ifdef CONFIG_ARCH_TEGRA_VIC
[TEGRA_POWERGATE_VIC] = {
.name = "vic",
.clk_info = {
- [0] = { .clk_name = "vic03.cbus", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "vic03.cbus", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[4] = { .clk_name = "vic03_slcg_ovr" },
[5] = { .clk_name = "host1x" },
},
+ .reset_id = { TEGRA210_CLK_VIC03 },
+ .reset_id_num = 1,
},
#endif
[TEGRA_POWERGATE_NVDEC] = {
.name = "nvdec",
.clk_info = {
- [0] = { .clk_name = "nvdec", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "nvdec", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[5] = { .clk_name = "nvjpg" },
[6] = { .clk_name = "nvjpg_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_NVDEC },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_NVJPG] = {
.name = "nvjpg",
.clk_info = {
- [0] = { .clk_name = "nvjpg", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "nvjpg", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[5] = { .clk_name = "nvdec" },
[6] = { .clk_name = "nvdec_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_NVJPG },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_APE] = {
.name = "ape",
.clk_info = {
- [0] = { .clk_name = "ape", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "ape", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[14] = { .clk_name = "d_audio_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_APE },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_VE2] = {
.name = "ve2",
.clk_info = {
- [0] = { .clk_name = "ispb", .clk_type = CLK_AND_RST },
+ [0] = { .clk_name = "ispb", .clk_type = CLK_ONLY },
},
.slcg_info = {
[0] = { .clk_name = "mc_capa" },
[3] = { .clk_name = "mc_cdpa" },
[4] = { .clk_name = "ispb_slcg_ovr" },
},
+ .reset_id = { TEGRA210_CLK_ISPB },
+ .reset_id_num = 1,
},
[TEGRA_POWERGATE_GPU] = {
.name = "gpu",
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/clk/tegra.h>
#include <linux/string.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/tegra-powergate.h>
-#include <linux/tegra-soc.h>
#include <soc/tegra/fuse.h>
+#include <soc/tegra/reset.h>
#include <trace/events/power.h>
#include <asm/atomic.h>
-#include <linux/platform/tegra/clock.h>
-#include <linux/platform/tegra/common.h>
#include "board.h"
#include "powergate-priv.h"
+#define TEGRA_PMC_BASE 0x7000E400
+#define TEGRA_MC_BASE 0x70019000
+
static struct powergate_ops *pg_ops;
+void __iomem *tegra_mc;
+void __iomem *tegra_pmc;
#if !defined(CONFIG_ARCH_TEGRA_18x_SOC)
static spinlock_t *tegra_get_powergate_lock(void)
for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
clk_info = &pg_info->clk_info[idx];
clk = clk_info->clk_ptr;
- if (!clk)
+ if (IS_ERR(clk))
break;
if (clk_info->clk_type != RST_ONLY) {
if (!pg_info->clk_info[idx].clk_name)
break;
- pg_info->clk_info[idx].clk_ptr = tegra_get_clock_by_name(
- pg_info->clk_info[idx].clk_name);
+ pg_info->clk_info[idx].clk_ptr =
+ clk_get_sys(NULL, pg_info->clk_info[idx].clk_name);
if (IS_ERR_OR_NULL(pg_info->clk_info[idx].clk_ptr))
WARN(1, "Could not find clock %s for %s partition\n",
if (!clk_ptr)
break;
-
- if (clk_info->clk_type != CLK_ONLY)
- tegra_periph_reset_assert(clk_ptr);
}
+
+ tegra_rst_assertv(&pg_info->reset_id[0], pg_info->reset_id_num);
}
void powergate_partition_deassert_reset(struct powergate_partition_info *pg_info)
if (!clk_ptr)
break;
-
- if (clk_info->clk_type != CLK_ONLY)
- tegra_periph_reset_deassert(clk_ptr);
}
+
+ tegra_rst_deassertv(&pg_info->reset_id[0], pg_info->reset_id_num);
}
int tegra_powergate_reset_module(struct powergate_partition_info *pg_info)
for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
slcg_info = &pg_info->slcg_info[idx];
clk = slcg_info->clk_ptr;
- if (!clk)
+ if (IS_ERR(clk))
break;
ret = clk_prepare_enable(clk);
slcg_info = &pg_info->slcg_info[idx];
clk = slcg_info->clk_ptr;
- if (!clk)
+ if (IS_ERR(clk))
break;
clk_disable_unprepare(clk);
if (!pg_info->slcg_info[idx].clk_name)
break;
- pg_info->slcg_info[idx].clk_ptr = tegra_get_clock_by_name(
- pg_info->slcg_info[idx].clk_name);
+ pg_info->slcg_info[idx].clk_ptr =
+ clk_get_sys(NULL, pg_info->slcg_info[idx].clk_name);
if (IS_ERR_OR_NULL(pg_info->slcg_info[idx].clk_ptr))
pr_err("### Could not find clock %s for %s partition\n",
int __init tegra_powergate_init(void)
{
+ tegra_pmc = ioremap(TEGRA_PMC_BASE, 4096);
+ tegra_mc = ioremap(TEGRA_MC_BASE, 4096);
switch (tegra_get_chip_id()) {
case TEGRA20:
pg_ops = tegra2_powergate_init_chip_support();
return (pg_ops ? 0 : -EINVAL);
}
-#if defined(CONFIG_ARCH_TEGRA_18x_SOC)
+#if defined(CONFIG_ARCH_TEGRA_18x_SOC) || defined (CONFIG_ARCH_TEGRA_210_SOC)
arch_initcall(tegra_powergate_init);
#endif
debugfs_remove_recursive(pg_debugfs_root);
return -ENOMEM;
}
-#if defined(CONFIG_ARCH_TEGRA_18x_SOC)
+#if defined(CONFIG_ARCH_TEGRA_18x_SOC) || defined (CONFIG_ARCH_TEGRA_210_SOC)
late_initcall(tegra_powergate_debugfs_init);
#endif