diff options
author | Joshua Primero <jprimero@nvidia.com> | 2012-08-09 17:05:14 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:32:18 -0700 |
commit | fa5a6867c771ec237b20c36426fbcd4952053072 (patch) | |
tree | 4196ce6f926f0475ff22929ea8cbea1de4c46b86 /arch | |
parent | 4e3129c0e621894cdddfb0d6b2ab5ccb3587ccdb (diff) |
ARM: tegra: thermal: Edp into cooling device
Removed EDP specific code from tegra thermal layer. It is
now implemented as a cooling device.
Change-Id: Ica9602569367e07deb04cf3cb8064a1c4101a7a4
Signed-off-by: Joshua Primero <jprimero@nvidia.com>
Reviewed-on: http://git-master/r/124501
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: Ra187adf6c66ac57ecd0049fde57a4c6617076206
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/cpu-tegra.c | 97 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/edp.h | 11 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_thermal.c | 19 |
3 files changed, 83 insertions, 44 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index 8fdfa4bc6faa..7906feddc696 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -35,6 +35,7 @@ #include <linux/cpu.h> #include <mach/edp.h> +#include <mach/thermal.h> #include "clock.h" #include "cpu-tegra.h" @@ -210,32 +211,60 @@ static unsigned int edp_governor_speed(unsigned int requested_speed) return edp_limit; } -int tegra_edp_update_thermal_zone(int temperature) +int tegra_edp_get_trip_temp(void *data, long trip) { - int i; - int ret = 0; - int nlimits = cpu_edp_limits_size; - int index; + tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size); + return cpu_edp_limits[trip].temperature * 1000; +} + +int tegra_edp_get_trip_size(void) +{ + tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size); + return cpu_edp_limits_size-1; +} + +int tegra_edp_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *max_state) +{ + *max_state = 1; + return 0; +} + +/* Bitmask for which edp trip points have been breached */ +static int edp_state_mask; + +int tegra_edp_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *cur_state) +{ + struct tegra_cooling_device *tegra_cdev = cdev->devdata; + int index = tegra_cdev->id && 0xffff; + *cur_state = !!((1 << index) & edp_state_mask); + return 0; +} + +int tegra_edp_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long cur_state) +{ + struct tegra_cooling_device *tegra_cdev = cdev->devdata; + int index, i; + if (!cpu_edp_limits) return -EINVAL; - index = nlimits - 1; + mutex_lock(&tegra_cpu_lock); + index = tegra_cdev->id & 0xffff; - if (temperature < cpu_edp_limits[0].temperature) { - index = 0; - } else { - for (i = 0; i < (nlimits - 1); i++) { - if (temperature >= cpu_edp_limits[i].temperature && - temperature < cpu_edp_limits[i + 1].temperature) { - index = i + 1; - break; - } - } - } + if (cur_state) + edp_state_mask |= 1 << index; + else + edp_state_mask &= ~(1 << index); - mutex_lock(&tegra_cpu_lock); - edp_thermal_index = index; + for (i=31; i>=0; i--) + if (edp_state_mask & (1 << i)) + break; + + edp_thermal_index = i + 1; /* Update cpu rate if cpufreq (at least on cpu0) is already started; alter cpu dvfs table for this thermal zone if necessary */ @@ -247,9 +276,14 @@ int tegra_edp_update_thermal_zone(int temperature) tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false, 0); mutex_unlock(&tegra_cpu_lock); - return ret; + return 0; } -EXPORT_SYMBOL_GPL(tegra_edp_update_thermal_zone); + +static struct thermal_cooling_device_ops tegra_edp_cooling_ops = { + .get_max_state = tegra_edp_get_max_state, + .get_cur_state = tegra_edp_get_cur_state, + .set_cur_state = tegra_edp_set_cur_state, +}; int tegra_system_edp_alarm(bool alarm) { @@ -353,6 +387,16 @@ static struct notifier_block tegra_cpu_edp_notifier = { .notifier_call = tegra_cpu_edp_notify, }; +static struct thermal_cooling_device *edp_cdev; +static struct tegra_cooling_device edp_cooling_devices[] = { + { .id = CDEV_EDPTABLE_ID_EDP_0 }, + { .id = CDEV_EDPTABLE_ID_EDP_1 }, + { .id = CDEV_EDPTABLE_ID_EDP_2 }, + { .id = CDEV_EDPTABLE_ID_EDP_3 }, + { .id = CDEV_EDPTABLE_ID_EDP_4 }, +}; + + static void tegra_cpu_edp_init(bool resume) { tegra_get_system_edp_limits(&system_edp_limits); @@ -376,6 +420,17 @@ static void tegra_cpu_edp_init(bool resume) register_hotcpu_notifier(&tegra_cpu_edp_notifier); pr_info("cpu-tegra: init EDP limit: %u MHz\n", edp_limit/1000); } + + if (!edp_cdev) { + int i; + for (i=0; i<cpu_edp_limits_size-1; i++) { + edp_cdev = thermal_cooling_device_register( + "edp", + &edp_cooling_devices[i], + &tegra_edp_cooling_ops); + } + } + } static void tegra_cpu_edp_exit(void) diff --git a/arch/arm/mach-tegra/include/mach/edp.h b/arch/arm/mach-tegra/include/mach/edp.h index 48321cae4959..cb1e213f49a5 100644 --- a/arch/arm/mach-tegra/include/mach/edp.h +++ b/arch/arm/mach-tegra/include/mach/edp.h @@ -42,9 +42,8 @@ struct system_edp_entry { }; #ifdef CONFIG_TEGRA_EDP_LIMITS - - -int tegra_edp_update_thermal_zone(int temperature); +int tegra_edp_get_trip_temp(void *, long trip); +int tegra_edp_get_trip_size(void); void tegra_init_cpu_edp_limits(unsigned int regulator_mA); void tegra_init_system_edp_limits(unsigned int power_limit_mW); void tegra_get_cpu_edp_limits(const struct tegra_edp_limits **limits, int *size); @@ -57,8 +56,10 @@ static inline void tegra_init_cpu_edp_limits(int regulator_mA) {} static inline void tegra_init_system_edp_limits(int power_limit_mW) {} -static inline int tegra_edp_update_thermal_zone(int temperature) -{ return -1; } +static inline int tegra_edp_get_trip_temp(void *data, long trip) +{ return 0; } +static inline int tegra_edp_get_trip_size(void) +{ return 0; } static inline void tegra_get_cpu_edp_limits(struct tegra_edp_limits **limits, int *size) {} diff --git a/arch/arm/mach-tegra/tegra3_thermal.c b/arch/arm/mach-tegra/tegra3_thermal.c index 56be98eb9ef1..32c817cfbbfe 100644 --- a/arch/arm/mach-tegra/tegra3_thermal.c +++ b/arch/arm/mach-tegra/tegra3_thermal.c @@ -27,7 +27,6 @@ #include <linux/thermal.h> #include <linux/module.h> #include <mach/thermal.h> -#include <mach/edp.h> #include <linux/slab.h> #include <linux/suspend.h> @@ -45,10 +44,6 @@ static int throttle_list_size; #define MAX_TEMP (120000) -#ifdef CONFIG_TEGRA_EDP_LIMITS -static long edp_thermal_zone_val; -#endif - #ifdef CONFIG_TEGRA_SKIN_THROTTLE static int skin_devs_bitmap; static struct therm_est_subdevice *skin_devs[THERMAL_DEVICE_MAX]; @@ -258,11 +253,8 @@ static void tegra_thermal_alert(void *data) } #ifdef CONFIG_TEGRA_EDP_LIMITS - tegra_get_cpu_edp_limits(&z, &zones_sz); - -/* edp table based off of tdiode measurements */ #define EDP_TEMP_TJ(_index) (z[_index].temperature * 1000 + therm->edp_offset) - + tegra_get_cpu_edp_limits(&z, &zones_sz); if (temp_tj < EDP_TEMP_TJ(0)) { lo_limit_edp_tj = temp_low_tj; hi_limit_edp_tj = EDP_TEMP_TJ(0); @@ -294,15 +286,6 @@ static void tegra_thermal_alert(void *data) device->set_limits(device->data, tj2dev(device, lo_limit_tj), tj2dev(device, hi_limit_tj)); - -#ifdef CONFIG_TEGRA_EDP_LIMITS - /* inform edp governor */ - if (edp_thermal_zone_val != temp_tj) { - long temp_edp = (temp_tj - therm->edp_offset) / 1000; - tegra_edp_update_thermal_zone(temp_edp); - edp_thermal_zone_val = temp_tj; - } -#endif } done: |