summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-03-31 20:06:27 -0700
committerGary King <gking@nvidia.com>2010-04-01 16:49:30 -0800
commitccbaa3ec2afb825c315d11e34b30faffa10c199e (patch)
tree7d5af2580e998a119baf149adfdb24cbde633659
parent0f29062f22c119d305eec613bfae1b2c8a6983f4 (diff)
tegra RM: Updated VDE clock configuration policy.
Updated VDE clock configuration policy - allowed to use high frequency PLLC for VDE targets within 100MHz-200MHz range. This range was covered by low frequency PLLP0, but better divider granularity achieved with PLLC results in lower voltage requirements. Change-Id: I922dbd8db19dc19339db5bfbf2651604e28e789d Reviewed-on: http://git-master/r/1007 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Sharad Ranjan <shranjan@nvidia.com> Tested-by: Sharad Ranjan <shranjan@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
index 46d6f4edd004..b28aac4e1b10 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
@@ -881,8 +881,8 @@ Ap20VdeClockSourceFind(
NvRmFreqKHz DomainKHz,
NvRmDfsSource* pDfsSource)
{
- NvU32 c, m;
- NvRmFreqKHz SourceKHz, ReachedKHzP, ReachedKHzC, ReachedKHzM;
+ NvU32 c, m, p;
+ NvRmFreqKHz SourceKHz, ReachedKHzP, ReachedKHzC, ReachedKHzM, BestKHz;
NV_ASSERT(DomainKHz <= MaxKHz);
// VDE clock is disabled - can not change configuration at all,
@@ -904,19 +904,27 @@ Ap20VdeClockSourceFind(
goto get_mv;
}
- // 2nd option - PLLP0 through VDE divider
+ // 2nd option - PLLP0 through VDE divider selected unconditionally if
+ // target is below half of PLLP0 output (divider granularity is "fair"
+ ReachedKHzP = DomainKHz;
SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllP0);
- if (DomainKHz <= SourceKHz)
+ p = NvRmPrivFindFreqMinAbove(
+ s_Ap20VdeConfig.pVdeInfo->Divider, SourceKHz, MaxKHz, &ReachedKHzP);
+ if (DomainKHz <= (SourceKHz >> 1))
{
pDfsSource->SourceId = NvRmClockSource_PllP0;
- pDfsSource->DividerSetting = NvRmPrivFindFreqMinAbove(
- s_Ap20VdeConfig.pVdeInfo->Divider, SourceKHz, MaxKHz, &DomainKHz);
+ pDfsSource->DividerSetting = p;
+ DomainKHz = ReachedKHzP;
goto get_mv;
}
- // PLLP0 does not "cover" the target - nevertheless, check it against
- // PLLC0 and PLLM0 - it may still provide the best approximation
- ReachedKHzP = SourceKHz;
+ /*
+ * For high target frequencies add 3rd and 4th options - PLLC0, or PLLM0
+ * through VDE divider, respectively. Select the option that provides
+ * minimum output frequency equal or above the target, if all output
+ * frequencies within domain maximum limit are below the target, select
+ * the option with maximum output frequency.
+ */
ReachedKHzC = ReachedKHzM = DomainKHz;
SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllC0);
c = NvRmPrivFindFreqMinAbove(
@@ -925,46 +933,35 @@ Ap20VdeClockSourceFind(
m = NvRmPrivFindFreqMinAbove(
s_Ap20VdeConfig.pVdeInfo->Divider, SourceKHz, MaxKHz, &ReachedKHzM);
- if ((ReachedKHzC <= ReachedKHzP) && (ReachedKHzM <= ReachedKHzP))
+ BestKHz = NV_MAX(NV_MAX(ReachedKHzP, ReachedKHzC), ReachedKHzM);
+ if ((DomainKHz <= ReachedKHzP) && (ReachedKHzP < BestKHz))
+ BestKHz = ReachedKHzP;
+ if ((DomainKHz <= ReachedKHzC) && (ReachedKHzC < BestKHz))
+ BestKHz = ReachedKHzC;
+ // PLLM0 may be selected as the last resort if two others are below target
+
+ // Set souce clock parameters for selected option
+ if (BestKHz == ReachedKHzP)
{
+ SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllP0);
pDfsSource->SourceId = NvRmClockSource_PllP0;
- pDfsSource->DividerSetting = 0;
- SourceKHz = DomainKHz = ReachedKHzP;
- goto get_mv;
+ pDfsSource->DividerSetting = p;
+ DomainKHz = ReachedKHzP; // use PLLP0 as source
}
-
- /*
- * 3rd option - PLLC0 through VDE divider or 4th option - PLLM0 through
- * VDE divider. Option selection is based on the following rule: select
- * the divider with smaller frequency if it is equal or above the target
- * frequency, otherwise select the divider with bigger output frequency.
- */
- if (ReachedKHzM > ReachedKHzC)
+ else if (BestKHz == ReachedKHzC)
{
- if (ReachedKHzC >= DomainKHz)
- {
- SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllC0);
- pDfsSource->SourceId = NvRmClockSource_PllC0;
- pDfsSource->DividerSetting = c;
- DomainKHz = ReachedKHzC; // use PLLC0 as source
- goto get_mv;
- }
+ SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllC0);
+ pDfsSource->SourceId = NvRmClockSource_PllC0;
+ pDfsSource->DividerSetting = c;
+ DomainKHz = ReachedKHzC; // use PLLC0 as source
}
- else // ReachedKHzM <= ReachedKHzC
+ else
{
- if (ReachedKHzM < DomainKHz)
- {
- SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllC0);
- pDfsSource->SourceId = NvRmClockSource_PllC0;
- pDfsSource->DividerSetting = c;
- DomainKHz = ReachedKHzC; // use PLLC0 as source
- goto get_mv;
- }
+ SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllM0);
+ pDfsSource->SourceId = NvRmClockSource_PllM0;
+ pDfsSource->DividerSetting = m;
+ DomainKHz = ReachedKHzM; // use PLLM0 as source
}
- SourceKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllM0);
- pDfsSource->SourceId = NvRmClockSource_PllM0;
- pDfsSource->DividerSetting = m;
- DomainKHz = ReachedKHzM; // use PLLM0 as source
get_mv:
// Finally update VDE v-scale references, get operational voltage for the