Пример #1
0
static int omap_cpu_thermal_manager(struct list_head *cooling_list, int temp)
{
	int cpu_temp;

	omap_gov->sensor_temp = temp;
	cpu_temp = convert_omap_sensor_temp_to_hotspot_temp(temp);

	pr_info("%s:sensor %d avg sensor %d pcb %d, delta %d hot spot %d\n",
			__func__, temp, omap_gov->avg_cpu_sensor_temp,
			omap_gov->pcb_temp, omap_gov->absolute_delta,
			cpu_temp);

	if (cpu_temp >= OMAP_FATAL_TEMP) {
		omap_fatal_zone(cpu_temp);
		return FATAL_ZONE;
	} else if (cpu_temp >= OMAP_PANIC_TEMP) {
		omap_panic_zone(cooling_list, cpu_temp);
		return PANIC_ZONE;
	} else if (cpu_temp < (OMAP_PANIC_TEMP - HYSTERESIS_VALUE)) {
		if (cpu_temp >= OMAP_ALERT_TEMP) {
			omap_alert_zone(cooling_list, cpu_temp);
			return ALERT_ZONE;
		} else if (cpu_temp < (OMAP_ALERT_TEMP - HYSTERESIS_VALUE)) {
			if (cpu_temp >= OMAP_MONITOR_TEMP) {
				omap_monitor_zone(cooling_list, cpu_temp);
				return MONITOR_ZONE;
			} else {
				/*
				 * this includes the case where :
				 * (OMAP_MONITOR_TEMP - HYSTERESIS_VALUE) <= T
				 * && T < OMAP_MONITOR_TEMP
				 */
				omap_safe_zone(cooling_list, cpu_temp);
				return SAFE_ZONE;
			}
		} else {
			/*
			 * this includes the case where :
			 * (OMAP_ALERT_TEMP - HYSTERESIS_VALUE) <= T
			 * && T < OMAP_ALERT_TEMP
			 */
			omap_monitor_zone(cooling_list, cpu_temp);
			return MONITOR_ZONE;
		}
	} else {
		/*
		 * this includes the case where :
		 * (OMAP_PANIC_TEMP - HYSTERESIS_VALUE) <= T < OMAP_PANIC_TEMP
		 */
		omap_alert_zone(cooling_list, cpu_temp);
		return ALERT_ZONE;
	}

	return NO_ACTION;
}
Пример #2
0
static int omap_cpu_thermal_manager(struct list_head *cooling_list, int temp)
{
	int cpu_temp;

	cpu_temp = convert_omap_sensor_temp_to_hotspot_temp(temp);
#if 0
	pr_info("%s: triggered with these temp: temp %d cpu_temp %d\n",
						__func__, temp, cpu_temp);
#endif
	if (cpu_temp >= OMAP_FATAL_TEMP) {
		omap_fatal_zone(cpu_temp);
		return FATAL_ZONE;
	} else if (cpu_temp >= OMAP_PANIC_TEMP) {
		omap_panic_zone(cooling_list, cpu_temp);
		return PANIC_ZONE;
	} else if (cpu_temp < (OMAP_PANIC_TEMP - HYSTERESIS_VALUE)) {
		if (cpu_temp >= OMAP_ALERT_TEMP) {
			omap_alert_zone(cooling_list, cpu_temp);
			return ALERT_ZONE;
		} else if (cpu_temp < (OMAP_ALERT_TEMP - HYSTERESIS_VALUE)) {
			if (cpu_temp >= OMAP_MONITOR_TEMP) {
				omap_monitor_zone(cooling_list, cpu_temp);
				return MONITOR_ZONE;
			} else {
				/*
				 * this includes the case where :
				 * (OMAP_MONITOR_TEMP - HYSTERESIS_VALUE) <= T
				 * && T < OMAP_MONITOR_TEMP
				 */
				omap_safe_zone(cooling_list, cpu_temp);
				return SAFE_ZONE;
			}
		} else {
			/*
			 * this includes the case where :
			 * (OMAP_ALERT_TEMP - HYSTERESIS_VALUE) <= T < OMAP_ALERT_TEMP
			 */
			omap_monitor_zone(cooling_list, cpu_temp);
			return MONITOR_ZONE;
		}
	} else {
		/*
		 * this includes the case where :
		 * (OMAP_PANIC_TEMP - HYSTERESIS_VALUE) <= T < OMAP_PANIC_TEMP
		 */
		omap_alert_zone(cooling_list, cpu_temp);
		return ALERT_ZONE;
	}

	return NO_ACTION;

}
/*
 * Make an average of the OMAP on-die temperature
 * this is helpful to handle burst activity of OMAP when extrapolating
 * the OMAP hot spot temperature from on-die sensor and PCB temperature
 * Re-evaluate the temperature gradient between hot spot and on-die sensor
 * (See absolute_delta) and reconfigure the thresholds if needed
 */
static void average_on_die_temperature(void)
{
	int i;
	int die_temp_lower = 0;
	int die_temp_upper = 0;
	int acc_temp;

	if (omap_gov->temp_sensor == NULL)
		return;

	/* Read current temperature */
	omap_gov->sensor_temp = thermal_request_temp(omap_gov->temp_sensor);

	/* if on-die sensor does not report a correct value, then return */
	if (omap_gov->sensor_temp == -EINVAL)
		return;

	/* Update historical buffer */
	for (i = 1; i < AVERAGE_NUMBER; i++) {
		cpu_sensor_temp_table[AVERAGE_NUMBER - i] =
		cpu_sensor_temp_table[AVERAGE_NUMBER - i - 1];
	}
	cpu_sensor_temp_table[0] = omap_gov->sensor_temp;

	if (cpu_sensor_temp_table[AVERAGE_NUMBER - 1] == 0)
		omap_gov->avg_is_valid = 0;
	else
		omap_gov->avg_is_valid = 1;

	/* Compute the new average value */
	acc_temp = 0;
	for (i = 0; i < AVERAGE_NUMBER; i++)
		acc_temp += cpu_sensor_temp_table[i];

	omap_gov->avg_cpu_sensor_temp =
		(acc_temp / AVERAGE_NUMBER);

	/*
	 * Reconfigure the current temperature thresholds according
	 * to the current PCB temperature
	 */
	convert_omap_sensor_temp_to_hotspot_temp(omap_gov->sensor_temp);
	die_temp_lower = hotspot_temp_to_sensor_temp(
		omap_gov->hotspot_temp_lower);
	die_temp_upper = hotspot_temp_to_sensor_temp(
		omap_gov->hotspot_temp_upper);
	thermal_device_call(omap_gov->temp_sensor, set_temp_thresh,
					die_temp_lower, die_temp_upper);

	return;
}
/*
 * Main CPU Thermal Governor:
 * It defines various thermal zones (safe, monitoring, alert, panic and fatal)
 * with associated thermal Thresholds including the hysteresis effect.
 */
int cpu_thermal_governor(u32 omap_sensor_temp)
{
    cpu_temp = convert_omap_sensor_temp_to_hotspot_temp(OMAP_CPU, omap_sensor_temp);

    if (cpu_temp >= OMAP_CPU_THRESHOLD_FATAL) {
        fatal_zone();
        return FATAL_ZONE;
    } else if (cpu_temp >= config_file.omap_cpu_threshold_panic) {
        panic_zone();
        return PANIC_ZONE;
    } else if (cpu_temp < (config_file.omap_cpu_threshold_panic - HYSTERESIS_VALUE)) {
        if (cpu_temp >= config_file.omap_cpu_threshold_alert) {
            alert_zone();
            return ALERT_ZONE;
        } else if (cpu_temp < (config_file.omap_cpu_threshold_alert - HYSTERESIS_VALUE)) {
            if (cpu_temp >= config_file.omap_cpu_threshold_monitoring) {
                monitoring_zone();
                return MONITOR_ZONE;
            } else {
                /*
                 * this includes the case where :
                 * MONITORING_LOW <= T < MONITORING_HIGH
                 */
                safe_zone();
                return SAFE_ZONE;
            }
        } else {
               /*
                * this includes the case where :
                * ALERT_LOW <= T < ALERT_HIGH
                */
               monitoring_zone();
               return MONITOR_ZONE;
        }
    } else {
           /*
            * this includes the case where :
            * PANIC_LOW <= T < PANIC_HIGH
            */
           alert_zone();
           return ALERT_ZONE;
    }
}
static int omap_cpu_thermal_manager(struct list_head *cooling_list, int temp)
{
	int cpu_temp, zone = NO_ACTION;
	bool set_cooling_level = true;

	omap_gov->sensor_temp = temp;
	cpu_temp = convert_omap_sensor_temp_to_hotspot_temp(temp);

	if (cpu_temp >= OMAP_FATAL_TEMP) {
		omap_fatal_zone(cpu_temp);
		return FATAL_ZONE;
	} else if (cpu_temp >= OMAP_PANIC_TEMP) {
		int temp_upper;

		omap_gov->panic_zone_reached++;
		temp_upper = (((OMAP_FATAL_TEMP - OMAP_PANIC_TEMP) / 4) *
				omap_gov->panic_zone_reached) + OMAP_PANIC_TEMP;
		if (temp_upper >= OMAP_FATAL_TEMP)
			temp_upper = OMAP_FATAL_TEMP;
		omap_thermal_zones[PANIC_ZONE - 1].temp_upper = temp_upper;
		zone = PANIC_ZONE;
	} else if (cpu_temp < (OMAP_PANIC_TEMP - HYSTERESIS_VALUE)) {
		if (cpu_temp >= OMAP_ALERT_TEMP) {
			set_cooling_level = omap_gov->panic_zone_reached == 0;
			zone = ALERT_ZONE;
		} else if (cpu_temp < (OMAP_ALERT_TEMP - HYSTERESIS_VALUE)) {
			if (cpu_temp >= OMAP_MONITOR_TEMP) {
				omap_gov->panic_zone_reached = 0;
				zone = MONITOR_ZONE;
			} else {
				/*
				 * this includes the case where :
				 * (OMAP_MONITOR_TEMP - HYSTERESIS_VALUE) <= T
				 * && T < OMAP_MONITOR_TEMP
				 */
				omap_gov->panic_zone_reached = 0;
				zone = SAFE_ZONE;
			}
		} else {
			/*
			 * this includes the case where :
			 * (OMAP_ALERT_TEMP - HYSTERESIS_VALUE) <= T
			 * && T < OMAP_ALERT_TEMP
			 */
			omap_gov->panic_zone_reached = 0;
			zone = MONITOR_ZONE;
		}
	} else {
		/*
		 * this includes the case where :
		 * (OMAP_PANIC_TEMP - HYSTERESIS_VALUE) <= T < OMAP_PANIC_TEMP
		 */
		set_cooling_level = omap_gov->panic_zone_reached == 0;
		zone = ALERT_ZONE;
	}

	if (zone != NO_ACTION) {
		struct omap_thermal_zone *therm_zone;

		therm_zone = &omap_thermal_zones[zone - 1];
		if (omap_gov->panic_zone_reached)
			start_panic_guard();
		else
			cancel_delayed_work(&omap_gov->decrease_mpu_freq_work);

		if ((omap_gov->prev_zone != zone) || (zone == PANIC_ZONE)) {
			pr_info("%s:sensor %d avg sensor %d pcb ",
				 __func__, temp,
				 omap_gov->avg_cpu_sensor_temp);
			pr_info("%d, delta %d hot spot %d\n",
				 omap_gov->pcb_temp, omap_gov->absolute_delta,
				 cpu_temp);
			pr_info("%s: hot spot temp %d - going into %s zone\n",
				__func__, cpu_temp, therm_zone->name);
			omap_gov->prev_zone = zone;
		}
		omap_enter_zone(therm_zone, set_cooling_level,
				cooling_list, cpu_temp);
	}

	omap_gov->zone_info = zone;

	return zone;
}