summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra11_soctherm.c
diff options
context:
space:
mode:
authorDiwakar Tundlam <dtundlam@nvidia.com>2013-12-11 14:54:38 -0800
committerDiwakar Tundlam <dtundlam@nvidia.com>2013-12-12 13:16:30 -0800
commitb6bee6cd1056f4912028dbc003b637be78cc2b43 (patch)
treee17e6d2d69066e042dea6ac5f2738a74bb8dd721 /arch/arm/mach-tegra/tegra11_soctherm.c
parentfa72b15a68bad518d55e8815414ce5827cc1d51f (diff)
arm: tegra12: Fix light thermal HW throttling
Fix light thermal HW throttling cdev registration and its cur_status Bug 1342361 Change-Id: Ie1ac458539d1525772089724caaad58eae85eca9 Signed-off-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-on: http://git-master/r/344514 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'arch/arm/mach-tegra/tegra11_soctherm.c')
-rw-r--r--arch/arm/mach-tegra/tegra11_soctherm.c127
1 files changed, 75 insertions, 52 deletions
diff --git a/arch/arm/mach-tegra/tegra11_soctherm.c b/arch/arm/mach-tegra/tegra11_soctherm.c
index 4db76517d32c..a6e01180b569 100644
--- a/arch/arm/mach-tegra/tegra11_soctherm.c
+++ b/arch/arm/mach-tegra/tegra11_soctherm.c
@@ -886,16 +886,18 @@ static int soctherm_hw_action_get_cur_state(struct thermal_cooling_device *cdev,
if (REG_GET(r, XPU_PSKIP_STATUS_ENABLED) && devs->enable) {
m = REG_GET(r, XPU_PSKIP_STATUS_M);
n = REG_GET(r, XPU_PSKIP_STATUS_N);
- if (tegra_chip_id == TEGRA_CHIPID_TEGRA12)
/*
- * OC5 is a reserved alarm on Tegra12x. Hence
- * the *GPU 'PSKIP' state will always be ON.
- * The real status is in 'NV_THERM_CLK_STATUS'
- * register, and cannot be read safely.
+ * On Tegra12x OC5 is a reserved alarm. Hence
+ * GPU 'PSKIP' state always shows ON. The real
+ * status register 'NV_THERM_CLK_STATUS' can't
+ * be read safely. So we mirror the CPU status.
*/
- ;
- else if (m == devs->dividend && n == devs->divisor)
- *cur_state |= (1 << THROTTLE_DEV_GPU);
+ *cur_state |=
+ (tegra_chip_id == TEGRA_CHIPID_TEGRA12) ?
+ ((*cur_state & (1 << THROTTLE_DEV_CPU)) ?
+ (1 << THROTTLE_DEV_GPU) : 0) :
+ ((m == devs->dividend && n == devs->divisor) ?
+ (1 << THROTTLE_DEV_GPU) : 0);
}
}
return 0;
@@ -908,7 +910,8 @@ static int soctherm_hw_action_set_cur_state(struct thermal_cooling_device *cdev,
}
static struct thermal_cooling_device *soctherm_hw_critical_cdev;
-static struct thermal_cooling_device *soctherm_hw_hot_cdev;
+static struct thermal_cooling_device *soctherm_hw_heavy_cdev;
+static struct thermal_cooling_device *soctherm_hw_light_cdev;
static struct thermal_cooling_device_ops soctherm_hw_action_ops = {
.get_max_state = soctherm_hw_action_get_max_state,
.get_cur_state = soctherm_hw_action_get_cur_state,
@@ -1218,12 +1221,71 @@ static struct thermal_zone_device_ops soctherm_ops = {
.get_trend = soctherm_get_trend,
};
+static void __init soctherm_hot_cdev_register(int i, int trip)
+{
+ struct soctherm_therm *therm;
+ int k;
+
+ therm = &plat_data.therm[i];
+
+ for (k = 0; k < THROTTLE_SIZE; k++) {
+ if ((therm2dev[i] == THROTTLE_DEV_NONE)
+ || (!plat_data.throttle[k].
+ devs[therm2dev[i]].enable))
+ continue;
+
+ if ((strnstr(therm->trips[trip].cdev_type,
+ "oc1",
+ THERMAL_NAME_LENGTH)
+ && k == THROTTLE_OC1) ||
+ (strnstr(therm->trips[trip].cdev_type,
+ "oc2",
+ THERMAL_NAME_LENGTH)
+ && k == THROTTLE_OC2) ||
+ (strnstr(therm->trips[trip].cdev_type,
+ "oc3",
+ THERMAL_NAME_LENGTH)
+ && k == THROTTLE_OC3) ||
+ (strnstr(therm->trips[trip].cdev_type,
+ "oc4",
+ THERMAL_NAME_LENGTH)
+ && k == THROTTLE_OC4))
+ continue;
+
+ if (strnstr(therm->trips[trip].cdev_type,
+ "heavy",
+ THERMAL_NAME_LENGTH) &&
+ k == THROTTLE_HEAVY &&
+ !soctherm_hw_heavy_cdev) {
+ soctherm_hw_heavy_cdev =
+ thermal_cooling_device_register(
+ therm->trips[trip].cdev_type,
+ &therm->trips[trip],
+ &soctherm_hw_action_ops);
+ continue;
+ }
+
+ if (strnstr(therm->trips[trip].cdev_type,
+ "light",
+ THERMAL_NAME_LENGTH) &&
+ k == THROTTLE_LIGHT &&
+ !soctherm_hw_light_cdev) {
+ soctherm_hw_light_cdev =
+ thermal_cooling_device_register(
+ therm->trips[trip].cdev_type,
+ &therm->trips[trip],
+ &soctherm_hw_action_ops);
+ continue;
+ }
+ }
+}
+
static int __init soctherm_thermal_sys_init(void)
{
char name[THERMAL_NAME_LENGTH];
struct soctherm_therm *therm;
bool oc_en = false;
- int i, j, k;
+ int i, j;
if (!soctherm_init_platform_done)
return 0;
@@ -1263,46 +1325,7 @@ static int __init soctherm_thermal_sys_init(void)
break;
case THERMAL_TRIP_HOT:
- for (k = 0; k < THROTTLE_SIZE; k++) {
- if ((therm2dev[i] == THROTTLE_DEV_NONE)
- || (!plat_data.throttle[k].
- devs[therm2dev[i]].enable))
- continue;
-
- if ((strnstr(therm->trips[j].cdev_type,
- "heavy",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_LIGHT) ||
- (strnstr(therm->trips[j].cdev_type,
- "light",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_HEAVY) ||
- (strnstr(therm->trips[j].cdev_type,
- "oc1",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_OC1) ||
- (strnstr(therm->trips[j].cdev_type,
- "oc2",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_OC2) ||
- (strnstr(therm->trips[j].cdev_type,
- "oc3",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_OC3) ||
- (strnstr(therm->trips[j].cdev_type,
- "oc4",
- THERMAL_NAME_LENGTH)
- && k == THROTTLE_OC4))
- continue;
-
- if (soctherm_hw_hot_cdev)
- continue;
- soctherm_hw_hot_cdev =
- thermal_cooling_device_register(
- therm->trips[j].cdev_type,
- &therm->trips[j],
- &soctherm_hw_action_ops);
- }
+ soctherm_hot_cdev_register(i, j);
break;
case THERMAL_TRIP_PASSIVE:
@@ -1323,9 +1346,9 @@ static int __init soctherm_thermal_sys_init(void)
therm->passive_delay,
0);
- for (k = THROTTLE_OC1; !oc_en && k < THROTTLE_SIZE; k++)
+ for (j = THROTTLE_OC1; !oc_en && j < THROTTLE_SIZE; j++)
if ((therm2dev[i] != THROTTLE_DEV_NONE) &&
- (plat_data.throttle[k].devs[therm2dev[i]].enable))
+ (plat_data.throttle[j].devs[therm2dev[i]].enable))
oc_en = true;
}