diff options
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/thermal.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_thermal.c | 185 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_throttle.c | 6 |
5 files changed, 141 insertions, 80 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index 3fc0420c57c1..0d69eb6165b7 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -69,11 +69,17 @@ static struct tegra_thermal_data thermal_data = { .temp_throttle = 85000, .temp_shutdown = 90000, .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */ +#ifdef CONFIG_TEGRA_EDP_LIMITS .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */ -#ifndef CONFIG_TEGRA_THERMAL_SYSFS + .hysteresis_edp = 3000, +#endif +#ifdef CONFIG_TEGRA_THERMAL_SYSFS + .tc1 = 0, + .tc2 = 1, + .passive_delay = 2000, +#else .hysteresis_throttle = 1000, #endif - .hysteresis_edp = 3000, }; /* !!!TODO: Change for cardhu (Taken from Ventana) */ diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c index 952ffc2f4c97..5ef53a83fdd3 100644 --- a/arch/arm/mach-tegra/board-enterprise.c +++ b/arch/arm/mach-tegra/board-enterprise.c @@ -68,11 +68,17 @@ static struct tegra_thermal_data thermal_data = { .temp_throttle = 85000, .temp_shutdown = 90000, .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */ +#ifdef CONFIG_TEGRA_EDP_LIMITS .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */ -#ifndef CONFIG_TEGRA_THERMAL_SYSFS + .hysteresis_edp = 3000, +#endif +#ifdef CONFIG_TEGRA_THERMAL_SYSFS + .tc1 = 0, + .tc2 = 1, + .passive_delay = 2000, +#else .hysteresis_throttle = 1000, #endif - .hysteresis_edp = 3000, }; /* !!!TODO: Change for enterprise (Taken from Cardhu) */ diff --git a/arch/arm/mach-tegra/include/mach/thermal.h b/arch/arm/mach-tegra/include/mach/thermal.h index 6b5e74bf4bfb..714b63370b06 100644 --- a/arch/arm/mach-tegra/include/mach/thermal.h +++ b/arch/arm/mach-tegra/include/mach/thermal.h @@ -22,11 +22,17 @@ struct tegra_thermal_data { long temp_throttle; long temp_shutdown; long temp_offset; +#ifdef CONFIG_TEGRA_EDP_LIMITS long edp_offset; -#ifndef CONFIG_TEGRA_THERMAL_SYSFS + long hysteresis_edp; +#endif +#ifdef CONFIG_TEGRA_THERMAL_SYSFS + int tc1; + int tc2; + long passive_delay; +#else long hysteresis_throttle; #endif - long hysteresis_edp; }; struct tegra_thermal_device { diff --git a/arch/arm/mach-tegra/tegra3_thermal.c b/arch/arm/mach-tegra/tegra3_thermal.c index f6f3c40007e6..27e09545806d 100644 --- a/arch/arm/mach-tegra/tegra3_thermal.c +++ b/arch/arm/mach-tegra/tegra3_thermal.c @@ -36,13 +36,21 @@ #define MAX_ZONES (16) struct tegra_thermal { - struct tegra_thermal_data data; struct tegra_thermal_device *device; + long temp_throttle_tj; + long temp_shutdown_tj; #ifdef CONFIG_TEGRA_THERMAL_SYSFS struct thermal_zone_device *thz; + int tc1; + int tc2; + long passive_delay; +#else + long temp_throttle_low_tj; #endif #ifdef CONFIG_TEGRA_EDP_LIMITS int edp_thermal_zone_val; + long edp_offset; + long hysteresis_edp; #endif }; @@ -58,6 +66,32 @@ static bool throttle_enb; struct mutex mutex; #endif +#ifdef CONFIG_TEGRA_EDP_LIMITS +static inline long edp2tj(struct tegra_thermal *thermal, + long edp_temp) +{ + return edp_temp + thermal->edp_offset; +} + +static inline long tj2edp(struct tegra_thermal *thermal, + long temp_tj) +{ + return temp_tj - thermal->edp_offset; +} +#endif + +static inline long dev2tj(struct tegra_thermal_device *dev, + long dev_temp) +{ + return dev_temp + dev->offset; +} + +static inline long tj2dev(struct tegra_thermal_device *dev, + long tj_temp) +{ + return tj_temp - dev->offset; +} + #ifdef CONFIG_TEGRA_THERMAL_SYSFS static int tegra_thermal_zone_bind(struct thermal_zone_device *thermal, @@ -76,7 +110,7 @@ static int tegra_thermal_zone_get_temp(struct thermal_zone_device *thz, long *temp) { struct tegra_thermal *thermal = thz->devdata; - thermal->device->get_temp(thermal->device_client, temp); + thermal->device->get_temp(thermal->device->data, temp); return 0; } @@ -95,16 +129,16 @@ static int tegra_thermal_zone_get_trip_type( return 0; } -static int tegra_thermal_zone_get_trip_temp(struct thermal_zone_device *thermal, +static int tegra_thermal_zone_get_trip_temp(struct thermal_zone_device *thz, int trip, long *temp) { + struct tegra_thermal *thermal = thz->devdata; + /* Support only Thermal Throttling (1 trip) for now */ if (trip != 0) return -EINVAL; - *temp = thermal->data.temp_throttle + - thermal->data.temp_offset - - thermal->device->offset; + *temp = tj2dev(thermal->device, thermal->temp_throttle_tj); return 0; } @@ -132,20 +166,20 @@ static void tegra_therm_throttle(bool enable) } #endif +/* Make sure this function remains stateless */ void tegra_thermal_alert(void *data) { struct tegra_thermal *thermal = data; int err; - long temp; - long lo_limit_throttle, hi_limit_throttle; - long lo_limit_edp = 0, hi_limit_edp = 0; - long tj_temp, tj_throttle_temp, tj_shutdown_temp; + long temp_dev, temp_tj; + long lo_limit_throttle_tj, hi_limit_throttle_tj; + long lo_limit_edp_tj = 0, hi_limit_edp_tj = 0; int lo_limit_tj = 0, hi_limit_tj = 0; - int lo_limit = 0, hi_limit = 0; +#ifdef CONFIG_TEGRA_EDP_LIMITS const struct tegra_edp_limits *z; int zones_sz; int i; - +#endif if (thermal != &thermal_state) BUG(); @@ -157,78 +191,73 @@ void tegra_thermal_alert(void *data) } #endif - err = thermal->device->get_temp(thermal->device->data, &temp); + err = thermal->device->get_temp(thermal->device->data, &temp_dev); if (err) { pr_err("%s: get temp fail(%d)", __func__, err); return; } - tj_temp = temp + thermal->device->offset; - tj_throttle_temp = thermal->data.temp_throttle - + thermal->data.temp_offset; - tj_shutdown_temp = thermal->data.temp_shutdown - + thermal->data.temp_offset; + /* Convert all temps to tj and then do all work/logic in terms of + tj in order to avoid confusion */ + temp_tj = dev2tj(thermal->device, temp_dev); + + lo_limit_throttle_tj = dev2tj(thermal->device, 0); + hi_limit_throttle_tj = thermal->temp_throttle_tj; +#ifndef CONFIG_TEGRA_THERMAL_SYSFS + /* Check to see if we are currently throttling */ if ((tegra_is_throttling() && - (tj_temp > - (tj_throttle_temp - thermal->data.hysteresis_throttle))) - || (tj_temp >= tj_throttle_temp)) { - lo_limit_throttle = tj_throttle_temp - - thermal->data.hysteresis_throttle; - hi_limit_throttle = tj_shutdown_temp; - } else { - lo_limit_throttle = 0; - hi_limit_throttle = tj_throttle_temp; + (temp_tj > thermal->temp_throttle_low_tj)) + || (temp_tj >= thermal->temp_throttle_tj)) { + lo_limit_throttle_tj = thermal->temp_throttle_low_tj; + hi_limit_throttle_tj = thermal->temp_shutdown_tj; } +#endif #ifdef CONFIG_TEGRA_EDP_LIMITS tegra_get_cpu_edp_limits(&z, &zones_sz); /* edp table based off of tdiode measurements */ -#define EDP_TEMP(_index) ((z[_index].temperature * 1000)\ - + thermal->data.edp_offset) - if (tj_temp < EDP_TEMP(0)) { - lo_limit_edp = 0; - hi_limit_edp = EDP_TEMP(0); - } else if (tj_temp >= EDP_TEMP(zones_sz-1)) { - lo_limit_edp = EDP_TEMP(zones_sz-1) - - thermal->data.hysteresis_edp; - hi_limit_edp = tj_shutdown_temp; +#define EDP_TEMP_TJ(_index) edp2tj(thermal, z[_index].temperature * 1000) + + if (temp_tj < EDP_TEMP_TJ(0)) { + lo_limit_edp_tj = dev2tj(thermal->device, 0); + hi_limit_edp_tj = EDP_TEMP_TJ(0); + } else if (temp_tj >= EDP_TEMP_TJ(zones_sz-1)) { + lo_limit_edp_tj = EDP_TEMP_TJ(zones_sz-1) - + thermal->hysteresis_edp; + hi_limit_edp_tj = thermal->temp_shutdown_tj; } else { for (i = 0; (i + 1) < zones_sz; i++) { - if ((tj_temp >= EDP_TEMP(i)) && - (tj_temp < EDP_TEMP(i+1))) { - lo_limit_edp = EDP_TEMP(i) - - thermal->data.hysteresis_edp; - hi_limit_edp = EDP_TEMP(i+1); + if ((temp_tj >= EDP_TEMP_TJ(i)) && + (temp_tj < EDP_TEMP_TJ(i+1))) { + lo_limit_edp_tj = EDP_TEMP_TJ(i) - + thermal->hysteresis_edp; + hi_limit_edp_tj = EDP_TEMP_TJ(i+1); break; } } } -#undef EDP_TEMP +#undef EDP_TEMP_TJ #else - lo_limit_edp = 0; - hi_limit_edp = tj_shutdown_temp; + lo_limit_edp_tj = 0; + hi_limit_edp_tj = thermal->temp_shutdown_tj; #endif /* Get smallest window size */ - lo_limit_tj = max(lo_limit_throttle, lo_limit_edp); - hi_limit_tj = min(hi_limit_throttle, hi_limit_edp); - - /* Get corresponding device temps */ - lo_limit = lo_limit_tj ? (lo_limit_tj - thermal->device->offset) : 0; - hi_limit = hi_limit_tj ? (hi_limit_tj - thermal->device->offset) : 0; + lo_limit_tj = max(lo_limit_throttle_tj, lo_limit_edp_tj); + hi_limit_tj = min(hi_limit_throttle_tj, hi_limit_edp_tj); - thermal->device->set_limits(thermal->device->data, lo_limit, hi_limit); + thermal->device->set_limits(thermal->device->data, + tj2dev(thermal->device, lo_limit_tj), + tj2dev(thermal->device, hi_limit_tj)); #ifndef CONFIG_TEGRA_THERMAL_SYSFS - if (tj_temp >= tj_throttle_temp) { + if (temp_tj >= thermal->temp_throttle_tj) { /* start throttling */ if (!tegra_is_throttling()) tegra_therm_throttle(true); - } else if (tj_temp <= - (tj_throttle_temp - - thermal->data.hysteresis_throttle)) { + } else if (temp_tj <= thermal->temp_throttle_low_tj) { /* switch off throttling */ if (tegra_is_throttling()) tegra_therm_throttle(false); @@ -237,17 +266,16 @@ void tegra_thermal_alert(void *data) #ifdef CONFIG_TEGRA_EDP_LIMITS /* inform edp governor */ - if (thermal->edp_thermal_zone_val != tj_temp) - tegra_edp_update_thermal_zone( - (tj_temp - thermal->data.edp_offset)/1000); + if (thermal->edp_thermal_zone_val != temp_tj) + tegra_edp_update_thermal_zone(tj2edp(thermal, temp_tj)/1000); - thermal->edp_thermal_zone_val = tj_temp; + thermal->edp_thermal_zone_val = temp_tj; #endif } int tegra_thermal_set_device(struct tegra_thermal_device *device) { -#ifdef CONFIG_THERMAL_SYSFS +#ifdef CONFIG_TEGRA_THERMAL_SYSFS struct thermal_zone_device *thz; #endif @@ -262,27 +290,25 @@ int tegra_thermal_set_device(struct tegra_thermal_device *device) 1, /* trips */ &thermal_state, &tegra_thermal_zone_ops, - 2, /* tc1 */ - 1, /* tc2 */ - 2000, /* passive delay */ + thermal_state.tc1, /* dT/dt */ + thermal_state.tc2, /* throttle */ + thermal_state.passive_delay, 0); /* polling delay */ if (IS_ERR(thz)) { thz = NULL; - kfree(thermal); return -ENODEV; } thermal_state.thz = thz; #endif - thermal_state.device->set_alert(thermal_state.device->data, tegra_thermal_alert, &thermal_state); + thermal_state.device->set_shutdown_temp(thermal_state.device->data, - thermal_state.data.temp_shutdown + - thermal_state.data.temp_offset - - thermal_state.device->offset); + tj2dev(device, thermal_state.temp_shutdown_tj)); + /* initialize limits */ tegra_thermal_alert(&thermal_state); @@ -291,11 +317,24 @@ int tegra_thermal_set_device(struct tegra_thermal_device *device) int __init tegra_thermal_init(struct tegra_thermal_data *data) { -#ifndef CONFIG_TEGRA_THERMAL_SYSFS +#ifdef CONFIG_TEGRA_THERMAL_SYSFS + thermal_state.tc1 = data->tc1; + thermal_state.tc2 = data->tc2; + thermal_state.passive_delay = data->passive_delay; +#else mutex_init(&mutex); + thermal_state.temp_throttle_low_tj = data->temp_throttle + + data->temp_offset - + data->hysteresis_throttle; #endif - - memcpy(&thermal_state.data, data, sizeof(struct tegra_thermal_data)); +#ifdef CONFIG_TEGRA_EDP_LIMITS + thermal_state.edp_offset = data->edp_offset; + thermal_state.hysteresis_edp = data->hysteresis_edp; +#endif + thermal_state.temp_throttle_tj = data->temp_throttle + + data->temp_offset; + thermal_state.temp_shutdown_tj = data->temp_shutdown + + data->temp_offset; return 0; } @@ -303,8 +342,8 @@ int __init tegra_thermal_init(struct tegra_thermal_data *data) int tegra_thermal_exit(void) { #ifdef CONFIG_TEGRA_THERMAL_SYSFS - if (thermal->thz) - thermal_zone_device_unregister(thermal->thz); + if (thermal_state.thz) + thermal_zone_device_unregister(thermal_state.thz); #endif return 0; diff --git a/arch/arm/mach-tegra/tegra3_throttle.c b/arch/arm/mach-tegra/tegra3_throttle.c index 6f4a3bc1a28d..f927be7800d6 100644 --- a/arch/arm/mach-tegra/tegra3_throttle.c +++ b/arch/arm/mach-tegra/tegra3_throttle.c @@ -42,7 +42,11 @@ static struct { int ms; } throttle_table[] = { { 0, 1000, 2000 }, /* placeholder for cpu floor rate */ - { 640000, 1000, 10000 }, + { 640000, 1000, 2000 }, + { 640000, 1000, 2000 }, + { 640000, 1000, 2000 }, + { 640000, 1000, 2000 }, + { 640000, 1000, 2000 }, { 760000, 1000, 2000 }, { 760000, 1050, 2000 }, {1000000, 1050, 2000 }, |