diff options
author | Alex Frid <afrid@nvidia.com> | 2011-10-21 22:02:53 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:49:46 -0800 |
commit | 1ab4a78e1a998cbe33fed78b5365e518f1f0cf25 (patch) | |
tree | 09fc960dd10593274cf223d498b076cb442e1d72 /arch/arm/mach-tegra/tegra3_dvfs.c | |
parent | 8eb7374dbf3c7b312d23e36f80dcd685e09a3738 (diff) |
ARM: tegra: dvfs: Enable EMC bridge if rail is disabled
When core rail is disabled it is set to nominal voltage underneath
clock framework. On Tegra3 DDR3 platforms low EMC rates are not safe
at high voltage that exceeds EMC bridge minimum level. Enable EMC
bridge explicitly in this case to set safe floor for EMC. Similarly
need to enable EMC bridge when CPU rail is disabled and pushing core
voltage (cpu-to-core voltage dependency) over bridge minimum level.
(cherry picked from commit bff814b2e46e67defde178b72bd379003b5429c2)
(cherry picked from commit e5567cb8dafcbd30797237e7bb91d77ce57de66a)
Change-Id: Ibb8dad5132f69e3325d793658b3dcc8b887974bf
Reviewed-on: http://git-master/r/62031
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Rebase-Id: R56f360c3b1ee25bf2dae4b886399b83e357f0225
Diffstat (limited to 'arch/arm/mach-tegra/tegra3_dvfs.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra3_dvfs.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c index d07195366bf6..1acc76a3eda3 100644 --- a/arch/arm/mach-tegra/tegra3_dvfs.c +++ b/arch/arm/mach-tegra/tegra3_dvfs.c @@ -26,6 +26,7 @@ #include "dvfs.h" #include "fuse.h" #include "board.h" +#include "tegra3_emc.h" static bool tegra_dvfs_cpu_disabled; static bool tegra_dvfs_core_disabled; @@ -518,6 +519,48 @@ void __init tegra_soc_init_dvfs(void) tegra_dvfs_core_disabled ? "disabled" : "enabled"); } +int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail) +{ + int ret = 0; + + if (tegra_emc_get_dram_type() != DRAM_TYPE_DDR3) + return ret; + + if (((&tegra3_dvfs_rail_vdd_core == rail) && + (rail->nominal_millivolts > TEGRA_EMC_BRIDGE_MVOLTS_MIN)) || + ((&tegra3_dvfs_rail_vdd_cpu == rail) && + (tegra3_get_core_floor_mv(rail->nominal_millivolts) > + TEGRA_EMC_BRIDGE_MVOLTS_MIN))) { + struct clk *bridge = tegra_get_clock_by_name("bridge.emc"); + BUG_ON(!bridge); + + ret = clk_enable(bridge); + pr_info("%s: %s: %s bridge.emc\n", __func__, + rail->reg_id, ret ? "failed to enable" : "enabled"); + } + return ret; +} + +int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail) +{ + if (tegra_emc_get_dram_type() != DRAM_TYPE_DDR3) + return 0; + + if (((&tegra3_dvfs_rail_vdd_core == rail) && + (rail->nominal_millivolts > TEGRA_EMC_BRIDGE_MVOLTS_MIN)) || + ((&tegra3_dvfs_rail_vdd_cpu == rail) && + (tegra3_get_core_floor_mv(rail->nominal_millivolts) > + TEGRA_EMC_BRIDGE_MVOLTS_MIN))) { + struct clk *bridge = tegra_get_clock_by_name("bridge.emc"); + BUG_ON(!bridge); + + clk_disable(bridge); + pr_info("%s: %s: disabled bridge.emc\n", + __func__, rail->reg_id); + } + return 0; +} + /* * sysfs and dvfs interfaces to cap tegra core domains frequencies */ |