diff options
author | Alex Frid <afrid@nvidia.com> | 2010-09-28 16:13:48 -0700 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2010-10-29 18:18:10 -0700 |
commit | f29026d4d357ee1f1ec40df2d5b3673fc2bacf41 (patch) | |
tree | 560c54a1d1687479c5d29e6bcd8fab3703354733 | |
parent | d175dbe57f746e8f6ceebff1f2c3af58c77834bd (diff) |
[ARM/tegra] RM: Updated PLL configuration procedure.
Updated PLL configuration procedure to stop PLL before new settings
are loaded and to keep PLL's differential output disabled after PLL
is re-started until it is locked.
(cherry picked from commit cf47eb637bb505bf199710bdc2f8158b8ac9223c)
Change-Id: I29ba04ea6d931b168eb47a11f12d0a1241d4a266
Reviewed-on: http://git-master/r/9788
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Chih-Lung Huang <lhuang@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c index b52e882b3650..864a8953631b 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c @@ -314,6 +314,7 @@ NvRmPrivAp15PllSet( NvU32 old_base, old_misc; NvU32 delay = 0; NvU32 override = 0; + NvBool diff_clock = NV_FALSE; NV_ASSERT(hRmDevice); NV_ASSERT(pCinfo); @@ -442,17 +443,34 @@ NvRmPrivAp15PllSet( } // If PLL is not bypassed, and new configurations is the same as the old - // one - exit without overwriting h/w. Otherwise, bypass PLL before - // changing configuration. + // one - exit without overwriting h/w. Otherwise, bypass and disable PLL + // outputs before changing configuration. if ((base == old_base) && (misc == old_misc)) { NvRmPrivPllFreqUpdate(hRmDevice, pCinfo); return; } + if (pCinfo->SourceId == NvRmClockSource_PllD0) + { + old_misc = NV_FLD_SET_DRF_NUM( + CLK_RST_CONTROLLER, PLLD_MISC, PLLD_CLKENABLE, 0, old_misc); + NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, + pCinfo->PllMiscOffset, old_misc); + if (NV_DRF_VAL(CLK_RST_CONTROLLER, PLLD_MISC, PLLD_CLKENABLE, misc)) + { + diff_clock = NV_TRUE; + misc = NV_FLD_SET_DRF_NUM( + CLK_RST_CONTROLLER, PLLD_MISC, PLLD_CLKENABLE, 0, misc); + } + } old_base = NV_FLD_SET_DRF_DEF( CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, ENABLE, old_base); NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, pCinfo->PllBaseOffset, old_base); + old_base = NV_FLD_SET_DRF_DEF( + CLK_RST_CONTROLLER, PLLP_BASE, PLLP_ENABLE, DISABLE, old_base); + NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, + pCinfo->PllBaseOffset, old_base); // Configure and enable PLL, keep it bypassed base = NV_FLD_SET_DRF_DEF( @@ -474,6 +492,13 @@ NvRmPrivAp15PllSet( StableDelayUs = delay; NvOsWaitUS(StableDelayUs); + if (diff_clock) + { + misc = NV_FLD_SET_DRF_NUM( + CLK_RST_CONTROLLER, PLLD_MISC, PLLD_CLKENABLE, 1, misc); + NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, + pCinfo->PllMiscOffset, misc); + } base = NV_FLD_SET_DRF_DEF( CLK_RST_CONTROLLER, PLLP_BASE, PLLP_BYPASS, DISABLE, base); NV_REGW(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, |