summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-05-21 21:44:54 -0700
committerGary King <gking@nvidia.com>2010-05-27 13:00:50 -0700
commit04766fad54fbc0dda7d726fc1e678c5cbb85171a (patch)
treec4f5e4bca45ad249df331c41a637542d7eb3138a
parentc3be44e23d3a57643cb12f8369cf26e9ad339988 (diff)
tegra ODM: Added PMU power off properties.
Added support for wake event delay, and CPU power off time controls. Exposed the respective settings as ODM PMU properties (bug 690326). Change-Id: I8a544546e8d65f3006bae2dfa4cebe8858610dd3 Reviewed-on: http://git-master/r/1568 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/nvodm_query.h9
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c12
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c2
-rwxr-xr-xarch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c2
-rw-r--r--arch/arm/mach-tegra/power-t2.c20
5 files changed, 41 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_query.h b/arch/arm/mach-tegra/include/nvodm_query.h
index a7656cfc7cae..9bc66d4f44a9 100644
--- a/arch/arm/mach-tegra/include/nvodm_query.h
+++ b/arch/arm/mach-tegra/include/nvodm_query.h
@@ -844,6 +844,15 @@ typedef struct NvOdmPmuPropertyRec
/// Specifies PMU Core and CPU voltage regulation accuracy in percent
NvU32 AccuracyPercent;
+ /// Specifies the minimum time required for core power request to be
+ /// inactive (in 32 kHz counts).
+ NvU32 PowerOffCount;
+
+ /// Specifies the minimum time required for CPU power request to be
+ /// inactive (in US). Relevant for SoC with separate CPU and core power
+ /// request outputs.
+ NvU32 CpuPowerOffUs;
+
} NvOdmPmuProperty;
/**
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 b28aac4e1b10..d02f68674d99 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
@@ -191,8 +191,9 @@ static struct Ap20CpuConfigRec
// PLLX frequency steps table pointer
const NvRmFreqKHz* pPllXStepsKHz;
- // CPU power good delay in microseconds
+ // CPU power good and power off delays in microseconds
NvU32 CpuPowerGoodUs;
+ NvU32 CpuPowerOffUs;
// Core over CPU voltage dependency parameters:
// Vcore >= CoreOverCpuSlope * Vcpu + CoreOverCpuOffset
@@ -1174,6 +1175,13 @@ Ap20SetCpuPowerGoodDelay(
reg = NV_DRF_NUM(APBDEV_PMC, CPUPWRGOOD_TIMER, DATA, reg);
NV_REGW(hRmDevice, NvRmModuleID_Pmif, 0,
APBDEV_PMC_CPUPWRGOOD_TIMER_0, reg);
+
+ // AP20 CPU power off delay is counted by h/w in APB clocks (use
+ // 1/1000 ~ 17/16384 with 3% margin)
+ reg = ((ApbKHz * 17) >> 14) * s_Ap20CpuConfig.CpuPowerOffUs;
+ reg = NV_DRF_NUM(APBDEV_PMC, CPUPWROFF_TIMER, DATA, reg);
+ NV_REGW(hRmDevice, NvRmModuleID_Pmif, 0,
+ APBDEV_PMC_CPUPWROFF_TIMER_0, reg);
}
/*****************************************************************************/
@@ -1196,12 +1204,14 @@ static void Ap20CpuConfigInit(NvRmDeviceHandle hRmDevice)
// parameters based on PMU property.
if (!NvOdmQueryGetPmuProperty(&PmuProperty))
{
+ PmuProperty.CpuPowerOffUs = 0; // No power off delay by default
PmuProperty.CpuPowerGoodUs = NVRM_DEFAULT_CPU_PWRGOOD_US;
PmuProperty.AccuracyPercent = NVRM_DEFAULT_PMU_ACCURACY_PCT;
}
NV_ASSERT(PmuProperty.CpuPowerGoodUs && PmuProperty.AccuracyPercent);
NV_ASSERT(PmuProperty.AccuracyPercent < 5); // 5% is a must for PMU
+ s_Ap20CpuConfig.CpuPowerOffUs = PmuProperty.CpuPowerOffUs;
s_Ap20CpuConfig.CpuPowerGoodUs = PmuProperty.CpuPowerGoodUs;
s_Ap20CpuConfig.CoreOverCpuOffset = (NV_AP20_CORE_OVER_CPU_MV * 100) /
(100 - PmuProperty.AccuracyPercent);
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
index 454a53c82bd6..5040e7004a77 100644
--- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
@@ -677,6 +677,8 @@ NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty)
pPmuProperty->CpuPowerGoodUs = 2000;
pPmuProperty->AccuracyPercent = 3;
pPmuProperty->VCpuOTPOnWakeup = NV_FALSE;
+ pPmuProperty->PowerOffCount = 0;
+ pPmuProperty->CpuPowerOffUs = 0;
return NV_TRUE;
}
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
index 9041be0a2c19..85cfc0918ee7 100755
--- a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
@@ -1189,6 +1189,8 @@ NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty)
else
pPmuProperty->VCpuOTPOnWakeup = NV_TRUE;
+ pPmuProperty->PowerOffCount = 0;
+ pPmuProperty->CpuPowerOffUs = 0;
return NV_TRUE;
}
diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c
index 2a15fc48e84a..d9235a8ca1ac 100644
--- a/arch/arm/mach-tegra/power-t2.c
+++ b/arch/arm/mach-tegra/power-t2.c
@@ -55,6 +55,7 @@ NvU32 g_wakeupCcbp = 0, g_ArmPerif = 0;
NvU32 g_enterLP2PA = 0;
NvU32 g_coreSightClock, g_currentCcbp, g_currentCcdiv;
NvU32 g_lp1CpuPwrGoodCnt, g_currentCpuPwrGoodCnt;
+NvU32 g_lp1CpuPwrOffCnt, g_currentCpuPwrOffCnt;
volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER;
volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pTimerus;
volatile void *g_pIRAM, *g_pRtc, *g_pPL310;
@@ -176,11 +177,16 @@ void cpu_ap20_do_lp1(void)
disable_irq(INT_SYS_STATS_MON);
do_suspend_prep();
- // Set/save CPU power good count
+ // Set/save CPU power good and power off counts
g_currentCpuPwrGoodCnt = NV_REGR(s_hRmGlobal,
NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWRGOOD_TIMER_0);
NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
APBDEV_PMC_CPUPWRGOOD_TIMER_0, g_lp1CpuPwrGoodCnt);
+
+ g_currentCpuPwrOffCnt = NV_REGR(s_hRmGlobal,
+ NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWROFF_TIMER_0);
+ NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
+ APBDEV_PMC_CPUPWROFF_TIMER_0, g_lp1CpuPwrOffCnt);
}
printk("entering lp1\n");
@@ -206,9 +212,11 @@ void cpu_ap20_do_lp1(void)
NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0,
CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, g_coreSightClock);
- // Restore CPU power good count
+ // Restore CPU power good and power Off counts
NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
APBDEV_PMC_CPUPWRGOOD_TIMER_0, g_currentCpuPwrGoodCnt);
+ NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
+ APBDEV_PMC_CPUPWROFF_TIMER_0, g_currentCpuPwrOffCnt);
}
NvOsMemcpy((void*)g_pIRAM, (void*)g_iramContextSaveVA,
@@ -338,8 +346,9 @@ void power_lp0_init(void)
}
}
- //Program the core power good timer
+ //Program the core power good and power off timers
NV_PMC_REGW(g_pPMC,PWRGOOD_TIMER,PmuProperty.PowerGoodCount);
+ NV_PMC_REGW(g_pPMC,WAKE_DELAY,PmuProperty.PowerOffCount);
}
// Get ready CPU power good count in 32.768 kHz clocks (don't set timer
@@ -351,6 +360,11 @@ void power_lp0_init(void)
g_lp1CpuPwrGoodCnt =
(4096 * g_lp1CpuPwrGoodCnt + 124999) / 125000;
+ // Similarly get ready CPU power off count in 32.768 kHz clocks
+ g_lp1CpuPwrOffCnt = HasPmuProperty ?
+ PmuProperty.CpuPowerOffUs : 0; // No delay by default
+ g_lp1CpuPwrOffCnt =
+ (4096 * g_lp1CpuPwrOffCnt + 124999) / 125000;
}
//Generate definitions of local variables to hold scratch register values.