/* * convert_omap_sensor_temp_to_hotspot_temp() -Convert the temperature from the * OMAP on-die temp sensor into OMAP hot spot temperature. * This takes care of the existing temperature gradient between * the OMAP hot spot and the on-die temp sensor. * When PCB sensor is used, the temperature gradient is computed * from PCB and averaged on-die sensor temperatures. * * @sensor_temp: Raw temperature reported by the OMAP die temp sensor * * Returns the calculated hot spot temperature for the zone calculation */ static signed int convert_omap_sensor_temp_to_hotspot_temp(int sensor_temp) { int absolute_delta; if (pcb_sensor && (omap_gov->avg_is_valid == 1)) { omap_gov->pcb_temp = thermal_request_temp(pcb_sensor); if (omap_gov->pcb_temp < 0) return sensor_temp + omap_gov->absolute_delta; absolute_delta = ( ((omap_gov->avg_cpu_sensor_temp - omap_gov->pcb_temp) * OMAP_GRADIENT_SLOPE_WITH_PCB / 1000) + OMAP_GRADIENT_CONST_WITH_PCB); /* Ensure that this formula never returns negative value */ if (absolute_delta < 0) absolute_delta = 0; } else { absolute_delta = ((sensor_temp * OMAP_GRADIENT_SLOPE / 1000) + OMAP_GRADIENT_CONST); } omap_gov->absolute_delta = absolute_delta; pr_debug("%s:sensor %d avg sensor %d pcb %d, delta %d hot spot %d\n", __func__, sensor_temp, omap_gov->avg_cpu_sensor_temp, omap_gov->pcb_temp, omap_gov->absolute_delta, sensor_temp + absolute_delta); return sensor_temp + absolute_delta; }
static void decrease_mpu_freq_fn(struct work_struct *work) { struct omap_die_governor *omap_gov; omap_gov = container_of(work, struct omap_die_governor, decrease_mpu_freq_work.work); omap_gov->sensor_temp = thermal_request_temp(omap_gov->temp_sensor); thermal_sensor_set_temp(omap_gov->temp_sensor); }
/* * 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; }