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; }
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; }