diff options
author | Mayuresh Kulkarni <mkulkarni@nvidia.com> | 2013-07-12 22:23:55 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:37:38 -0700 |
commit | ed905c196c283e8d9b474b3ad669e9bd732a387e (patch) | |
tree | 5cc793c2f85347361526f77f8bdbe8445120f999 /arch/arm/mach-tegra/powergate-t12x.c | |
parent | bc2cc175f0de71fd575cce1a67f7cca8ae6889e8 (diff) |
video: tegra: host: fix gk20a rail gate/ungate sequence
bug 1324512
Change-Id: I6d95c5ae454be6e5a3c377a23fc0283d576aa016
Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Reviewed-on: http://git-master/r/253397
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/powergate-t12x.c')
-rw-r--r-- | arch/arm/mach-tegra/powergate-t12x.c | 103 |
1 files changed, 35 insertions, 68 deletions
diff --git a/arch/arm/mach-tegra/powergate-t12x.c b/arch/arm/mach-tegra/powergate-t12x.c index 8f4172e18f0c..2aba6a1a90d8 100644 --- a/arch/arm/mach-tegra/powergate-t12x.c +++ b/arch/arm/mach-tegra/powergate-t12x.c @@ -240,6 +240,8 @@ static struct powergate_partition_info tegra12x_powergate_partition_info[] = { static DEFINE_SPINLOCK(tegra12x_powergate_lock); +static struct regulator *gpu_reg; + #define HOTRESET_READ_COUNT 5 static bool tegra12x_stable_hotreset_check(u32 stat_reg, u32 *stat) { @@ -380,9 +382,12 @@ static int tegra12x_gpu_powergate(int id, struct powergate_partition_info *pg_in udelay(10); - /* TBD: call regulator api to turn off VDD_GPU */ - if (0) - goto err_power_off; + if (gpu_reg && tegra_powergate_is_powered(id)) { + ret = regulator_disable(gpu_reg); + if (ret) + goto err_power_off; + } else + pr_info("No GPU regulator?\n"); return 0; @@ -391,30 +396,22 @@ err_power_off: return ret; } -int hack_tegra12x_gpu_unpowergate(void) +static int tegra12x_gpu_unpowergate(int id, + struct powergate_partition_info *pg_info) { - int ret; - int id = TEGRA_POWERGATE_GPU; - struct powergate_partition_info *pg_info = - &tegra12x_powergate_partition_info[id]; - struct regulator * gpu_reg; - - if (!tegra_platform_is_silicon()) - return 0; + int ret = 0; - printk("%s(): start\n", __func__); - gpu_reg = regulator_get(NULL, "vdd_gpu"); - if (IS_ERR_OR_NULL(gpu_reg)) - BUG_ON(1); + if (!gpu_reg) { + gpu_reg = regulator_get(NULL, "vdd_gpu"); + if (IS_ERR_OR_NULL(gpu_reg)) { + WARN(1, "No GPU regulator?\n"); + goto err_power; + } + } - regulator_set_voltage(gpu_reg, 900000, 900000); ret = regulator_enable(gpu_reg); if (ret) - BUG_ON(1); - - /* TBD: call regulator api to turn on VDD_GPU */ - if (0) - goto err_power; + goto err_power; /* If first clk_ptr is null, fill clk info for the partition */ if (!pg_info->clk_info[0].clk_ptr) @@ -443,52 +440,6 @@ int hack_tegra12x_gpu_unpowergate(void) udelay(10); /* Disable all clks enabled earlier. Drivers should enable clks */ - // partition_clk_disable(pg_info); - - printk("%s(): end\n", __func__); - return 0; - -err_clk_on: - powergate_module(id); -err_power: - WARN(1, "Could not Un-Railgate %d", id); - return ret; -} -EXPORT_SYMBOL(hack_tegra12x_gpu_unpowergate); - -static int tegra12x_gpu_unpowergate(int id, struct powergate_partition_info *pg_info) -{ - int ret; - - /* TBD: call regulator api to turn on VDD_GPU */ - if (0) - goto err_power; - - /* If first clk_ptr is null, fill clk info for the partition */ - if (!pg_info->clk_info[0].clk_ptr) - get_clk_info(pg_info); - - /* Un-Powergating fails if all clks are not enabled */ - ret = partition_clk_enable(pg_info); - if (ret) - goto err_clk_on; - - udelay(10); - - /* disable clamp */ - pmc_write(0, PMC_GPU_RG_CNTRL_0); - - udelay(10); - - powergate_partition_deassert_reset(pg_info); - - udelay(10); - - tegra_powergate_mc_flush_done(id); - - udelay(10); - - /* Disable all clks enabled earlier. Drivers should enable clks */ partition_clk_disable(pg_info); return 0; @@ -646,6 +597,20 @@ bool tegra12x_powergate_skip(int id) } } +bool tegra12x_powergate_is_powered(int id) +{ + u32 status = 0; + + if (TEGRA_IS_GPU_POWERGATE_ID(id)) { + if (gpu_reg) + return regulator_is_enabled(gpu_reg); + } else { + status = pmc_read(PWRGATE_STATUS) & (1 << id); + return !!status; + } + return status; +} + static struct powergate_ops tegra12x_powergate_ops = { .soc_name = "tegra12x", @@ -667,6 +632,8 @@ static struct powergate_ops tegra12x_powergate_ops = { .powergate_mc_flush_done = tegra12x_powergate_mc_flush_done, .powergate_skip = tegra12x_powergate_skip, + + .powergate_is_powered = tegra12x_powergate_is_powered, }; struct powergate_ops *tegra12x_powergate_init_chip_support(void) |