summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-03-02 11:43:57 -0800
committerGary King <gking@nvidia.com>2010-03-02 13:19:54 -0800
commit67ef90803f261db3999f89402b29618c571d7326 (patch)
treef095ee90bfb481a14923bbf62e9dec214b8b2e11
parent5198c8c472aca4743bf140908eb53b8a10eac41a (diff)
tegra RM: Added NO-MIPI-PLL HDMI clocks configuration.
Added support for HDMI clocks configuration from PLLP (SD HDMI) or PLLC (HD HDMI). This option is selected automatically when DDK does *not* explicitly request MIPI PLLD as HDMI source. No changes in the PLLD based HDMI clock configuration when it is explicitly requested by DDK. Bug 656706. Change-Id: I3da656b6e5127fcd9f08ff48180584866c5c6b2f Reviewed-on: http://git-master/r/725 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Arthur Spence <aspence@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c120
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clocks.h14
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c13
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h11
4 files changed, 108 insertions, 50 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 70138eae4d7c..d19a99b3f08b 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
@@ -673,6 +673,42 @@ NvRmPrivAp15PllConfigureSimple(
*pPllOutKHz = NvRmPrivGetClockSourceFreq(pCinfo->SourceId);
}
+
+// Fixed list of PLL HDMI configurations for different reference frequencies
+// arranged according to CLK_RST_CONTROLLER_OSC_CTRL_0_OSC_FREQ_FIELD enum
+static const NvRmPllFixedConfig s_Ap15HdmiPllConfigurations[] =
+{
+ NVRM_PLLHD_AT_13MHZ,
+ NVRM_PLLHD_AT_19MHZ,
+ NVRM_PLLHD_AT_12MHZ,
+ NVRM_PLLHD_AT_26MHZ
+};
+
+void
+NvRmPrivAp15PllConfigureHdmi(
+ NvRmDeviceHandle hRmDevice,
+ NvRmClockSource PllId,
+ NvRmFreqKHz* pPllOutKHz)
+{
+ NvU32 reg;
+ NvRmPllFixedConfig HdmiConfig = {0};
+ const NvRmPllClockInfo* pCinfo =
+ NvRmPrivGetClockSourceHandle(PllId)->pInfo.pPll;
+
+ // Only PLLD or PLLC should be configured here
+ NV_ASSERT((PllId == NvRmClockSource_PllD0) ||
+ (PllId == NvRmClockSource_PllC0));
+
+ reg = NV_REGR(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0,
+ CLK_RST_CONTROLLER_OSC_CTRL_0);
+ HdmiConfig = s_Ap15HdmiPllConfigurations[NV_DRF_VAL(
+ CLK_RST_CONTROLLER, OSC_CTRL, OSC_FREQ, reg)];
+
+ NvRmPrivAp15PllSet(hRmDevice, pCinfo, HdmiConfig.M, HdmiConfig.N,
+ HdmiConfig.P, (NvU32)-1, 0, 0, NV_TRUE, 0);
+ *pPllOutKHz = NvRmPrivGetClockSourceFreq(pCinfo->SourceId);
+}
+
/*****************************************************************************/
// Fixed list of PLLP configurations for different reference frequencies
@@ -992,16 +1028,6 @@ Ap15PllDControl(
NvRmPrivGetClockSourceFreq(NvRmClockSource_PllD0);
}
-// Fixed list of PLL HDMI configurations for different reference frequencies
-// arranged according to CLK_RST_CONTROLLER_OSC_CTRL_0_OSC_FREQ_FIELD enum
-static const NvRmPllFixedConfig s_Ap15HdmiPllConfigurations[] =
-{
- NVRM_PLLHD_AT_13MHZ,
- NVRM_PLLHD_AT_19MHZ,
- NVRM_PLLHD_AT_12MHZ,
- NVRM_PLLHD_AT_26MHZ
-};
-
static void
Ap15PllDConfigure(
NvRmDeviceHandle hRmDevice,
@@ -1017,23 +1043,11 @@ Ap15PllDConfigure(
* PLLD is adjusted when DDK/ODM is initializing DSI or reconfiguring
* display clock (for HDMI, DSI, or in some cases CRT).
*/
- if ((TargetFreq == NVRM_HDMI_720p_1080i_FIXED_FREQ_KHZ) ||
- (TargetFreq == NVRM_HDMI_720p_1080p_FIXED_FREQ_KHZ) ||
- (TargetFreq == NVRM_HDMI_480_FIXED_FREQ_KHZ))
+ if (NvRmIsFixedHdmiKHz(TargetFreq))
{
// 480p or 720p or 1080i/1080p HDMI - use fixed PLLD configuration
- NvU32 reg;
- NvRmPllFixedConfig HdmiConfig = {0};
- const NvRmPllClockInfo* pCinfo =
- NvRmPrivGetClockSourceHandle(NvRmClockSource_PllD0)->pInfo.pPll;
-
- reg = NV_REGR(hRmDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_OSC_CTRL_0);
- HdmiConfig = s_Ap15HdmiPllConfigurations[NV_DRF_VAL(
- CLK_RST_CONTROLLER, OSC_CTRL, OSC_FREQ, reg)];
-
- NvRmPrivAp15PllSet(hRmDevice, pCinfo, HdmiConfig.M, HdmiConfig.N,
- HdmiConfig.P, (NvU32)-1, 0, 0, NV_TRUE, 0);
+ NvRmPrivAp15PllConfigureHdmi(
+ hRmDevice, NvRmClockSource_PllD0, &TargetFreq);
}
else
{
@@ -1116,11 +1130,14 @@ Ap15DisplayClockConfigure(
{
// PLLC is available - use it
SourceId = NvRmClockSource_PllC0;
- TargetFreq = NvRmPrivGetMaxFreqPllC(hRmDevice); // Target PLLC max
- if (!NvRmIsFreqRangeReachable(
- TargetFreq, MinFreq, MaxFreq, NVRM_DISPLAY_DIVIDER_MAX))
+ if (!NvRmIsFixedHdmiKHz(TargetFreq)) // don't touch HDMI targets
{
- TargetFreq = MaxFreq; // Target pixel range max
+ TargetFreq = NvRmPrivGetMaxFreqPllC(hRmDevice); // Target PLLC max
+ if (!NvRmIsFreqRangeReachable(
+ TargetFreq, MinFreq, MaxFreq, NVRM_DISPLAY_DIVIDER_MAX))
+ {
+ TargetFreq = MaxFreq; // Target pixel range max
+ }
}
NvRmPrivReConfigurePllC(hRmDevice, TargetFreq);
}
@@ -1188,6 +1205,10 @@ NvRmPrivAp15IsModuleClockException(
NvRmModuleClockState* pCstate,
NvU32 flags)
{
+ NvU32 i;
+ NvRmFreqKHz FreqKHz;
+ NvRmClockSource SourceId;
+
NV_ASSERT(hRmDevice);
NV_ASSERT(pCinfo && PrefFreqList && pCstate);
@@ -1217,25 +1238,34 @@ NvRmPrivAp15IsModuleClockException(
case NvRmModuleID_Hdmi:
/*
- * Complete configuration from PLLD if requested (PLLD should be already
- * configured properly for display)
+ * Complete HDMI configuration; choose among possible sources:
+ * PLLP, PLLD, PLLC in the same order as for display (PLLD or
+ * PLLC should be already configured properly for display)
*/
if (flags & NvRmClockConfig_MipiSync)
+ SourceId = NvRmClockSource_PllD0;
+ else if (NvRmIsFreqRangeReachable(NVRM_PLLP_FIXED_FREQ_KHZ,
+ MinFreq, MaxFreq, NVRM_DISPLAY_DIVIDER_MAX))
+ SourceId = NvRmClockSource_PllP0;
+ else
+ SourceId = NvRmClockSource_PllC0;
+
+ // HDMI clock state with selected source
+ for (i = 0; i < NvRmClockSource_Num; i++)
{
- NvRmFreqKHz FreqKHz =
- NvRmPrivGetClockSourceFreq(NvRmClockSource_PllD0);
- pCstate->SourceClock = 1; // PLLD source index
- pCstate->Divider = ((FreqKHz << 2) + PrefFreqList[0]) /
- (PrefFreqList[0] << 1) - 2;
- pCstate->actual_freq = (FreqKHz << 1) / (pCstate->Divider + 2);
- NV_ASSERT(pCinfo->Sources[pCstate->SourceClock] ==
- NvRmClockSource_PllD0);
- NV_ASSERT(pCstate->Divider <= pCinfo->DivisorFieldMask);
- NV_ASSERT((MinFreq <= pCstate->actual_freq) &&
- (pCstate->actual_freq <= MaxFreq));
- return NV_TRUE;
+ if (pCinfo->Sources[i] == SourceId)
+ break;
}
- return NV_FALSE;
+ NV_ASSERT(i < NvRmClockSource_Num);
+ pCstate->SourceClock = i; // source index
+ FreqKHz = NvRmPrivGetClockSourceFreq(SourceId);
+ pCstate->Divider = ((FreqKHz << 2) + PrefFreqList[0]) /
+ (PrefFreqList[0] << 1) - 2;
+ pCstate->actual_freq = (FreqKHz << 1) / (pCstate->Divider + 2);
+ NV_ASSERT(pCstate->Divider <= pCinfo->DivisorFieldMask);
+ NV_ASSERT((MinFreq <= pCstate->actual_freq) &&
+ (pCstate->actual_freq <= MaxFreq));
+ return NV_TRUE;
case NvRmModuleID_Spdif:
if (flags & NvRmClockConfig_SubConfig)
@@ -1250,7 +1280,7 @@ NvRmPrivAp15IsModuleClockException(
*/
if (flags & NvRmClockConfig_AudioAdjust)
{
- NvRmFreqKHz FreqKHz = PrefFreqList[0];
+ FreqKHz = PrefFreqList[0];
Ap15PllAConfigure(hRmDevice, &FreqKHz);
pCstate->SourceClock = 0; // PLLA source index
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clocks.h b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clocks.h
index 92f4650ae19c..9033261ba9ac 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clocks.h
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clocks.h
@@ -214,6 +214,7 @@ NvRmPrivAp15PllSet(
/**
* Configures output frequency for specified PLL.
*
+ * @param hRmDevice The RM device handle.
* @param PllId Targeted PLL ID.
* @param MaxOutKHz Upper limit for PLL output frequency.
* @param pPllOutKHz A pointer to the requested PLL frequency on entry,
@@ -227,6 +228,19 @@ NvRmPrivAp15PllConfigureSimple(
NvRmFreqKHz* pPllOutKHz);
/**
+ * Configures specified PLL output to the CM of fixed HDMI frequencies.
+ *
+ * @param hRmDevice The RM device handle.
+ * @param PllId Targeted PLL ID.
+ * @param pPllOutKHz A pointer to the actually configured frequency on exit.
+ */
+void
+NvRmPrivAp15PllConfigureHdmi(
+ NvRmDeviceHandle hRmDevice,
+ NvRmClockSource PllId,
+ NvRmFreqKHz* pPllOutKHz);
+
+/**
* Gets PLL output frequency.
*
* @param hRmDevice The RM device handle.
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
index 8ae5c9dfba72..ff4ac1962349 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
@@ -2682,6 +2682,7 @@ static const NvRmModuleID s_Ap15PllC0UsagePolicy[] =
NvRmModuleID_3D,
NvRmModuleID_2D,
NvRmModuleID_Mpe,
+ NvRmModuleID_Hdmi,
};
static const NvRmModuleID s_Ap20PllC0UsagePolicy[] =
@@ -2691,6 +2692,7 @@ static const NvRmModuleID s_Ap20PllC0UsagePolicy[] =
NvRmModuleID_3D,
NvRmModuleID_2D,
NvRmModuleID_Mpe,
+ NvRmModuleID_Hdmi,
NvRmModuleID_Vde
};
@@ -3175,6 +3177,7 @@ NvRmPrivReConfigurePllC(
NvRmFreqKHz CpuFreq, SysFreq, MaxFreq;
const NvRmCoreClockInfo* pCinfo =
NvRmPrivGetClockSourceHandle(NvRmClockSource_CpuBus)->pInfo.pCore;
+ NvBool IsHdmi = NvRmIsFixedHdmiKHz(TargetFreq);
// If maximum PLLC target is requested, and current PLLC output is close
// enough - exit without adjusting PLLC (use CPU divider resolution as
@@ -3203,8 +3206,14 @@ NvRmPrivReConfigurePllC(
SysFreq = PllCBackupSystemClock(hRmDevice);
PllCBackupModuleClocks(hRmDevice);
- NvRmPrivAp15PllConfigureSimple(
- hRmDevice, NvRmClockSource_PllC0, TargetFreq, &TargetFreq);
+ // For 720p or 1080i/1080p HDMI - use fixed PLLC configuration;
+ // for other targets use simple variable configuration
+ if (IsHdmi)
+ NvRmPrivAp15PllConfigureHdmi(
+ hRmDevice, NvRmClockSource_PllC0, &TargetFreq);
+ else
+ NvRmPrivAp15PllConfigureSimple(
+ hRmDevice, NvRmClockSource_PllC0, TargetFreq, &TargetFreq);
PllCRestoreCpuClock(hRmDevice, TargetFreq, CpuFreq);
PllCRestoreSystemClock(hRmDevice, TargetFreq, SysFreq);
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
index c2ee7d82734a..88b5292cb44a 100644
--- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
@@ -47,9 +47,14 @@ extern "C"
#define NVRM_VARIABLE_DIVIDER ((NvU32)-1)
// Fixed HDMI frequencies
-#define NVRM_HDMI_480_FIXED_FREQ_KHZ (27000)
-#define NVRM_HDMI_720p_1080i_FIXED_FREQ_KHZ (74250)
-#define NVRM_HDMI_720p_1080p_FIXED_FREQ_KHZ (148500)
+#define NVRM_HDMI_480p_FIXED_FREQ_KHZ (27000)
+#define NVRM_HDMI_720p_FIXED_FREQ_KHZ (74250)
+#define NVRM_HDMI_1080p_FIXED_FREQ_KHZ (148500)
+
+#define NvRmIsFixedHdmiKHz(KHz) \
+ (((KHz) == NVRM_HDMI_480p_FIXED_FREQ_KHZ) || \
+ ((KHz) == NVRM_HDMI_720p_FIXED_FREQ_KHZ) || \
+ ((KHz) == NVRM_HDMI_1080p_FIXED_FREQ_KHZ))
// BR-fixed PLLP output frequency in kHz (override disabled)
#define NV_BOOT_PLLP_FIXED_FREQ_KHZ (432000)