158b5b4231
This is a backport of a2291badc355d58ead5c19ae0609468947416040 from thermal-soc accepted upstream. The IMX6Q/IMX6DL SoC's have a 2-bit temperature grade stored in OTP. Instead of assuming 85C for passive cooling threshold and 100C for critical base these thresholds off the thermal gade max CPU temperature: - passive threshold: max - 10C - critical threshold: max - 5C Signed-off-by: Tim Harvey <tharvey@gateworks.com> SVN-Revision: 48011
115 lines
3.2 KiB
Plaintext
115 lines
3.2 KiB
Plaintext
Index: linux-4.3/drivers/thermal/imx_thermal.c
|
|
===================================================================
|
|
--- linux-4.3.orig/drivers/thermal/imx_thermal.c 2015-11-01 16:05:25.000000000 -0800
|
|
+++ linux-4.3/drivers/thermal/imx_thermal.c 2015-12-18 10:39:44.915158318 -0800
|
|
@@ -55,6 +55,7 @@
|
|
#define TEMPSENSE2_PANIC_VALUE_SHIFT 16
|
|
#define TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000
|
|
|
|
+#define OCOTP_MEM0 0x0480
|
|
#define OCOTP_ANA1 0x04e0
|
|
|
|
/* The driver supports 1 passive trip point and 1 critical trip point */
|
|
@@ -64,12 +65,6 @@
|
|
IMX_TRIP_NUM,
|
|
};
|
|
|
|
-/*
|
|
- * It defines the temperature in millicelsius for passive trip point
|
|
- * that will trigger cooling action when crossed.
|
|
- */
|
|
-#define IMX_TEMP_PASSIVE 85000
|
|
-
|
|
#define IMX_POLLING_DELAY 2000 /* millisecond */
|
|
#define IMX_PASSIVE_DELAY 1000
|
|
|
|
@@ -100,12 +95,14 @@
|
|
u32 c1, c2; /* See formula in imx_get_sensor_data() */
|
|
int temp_passive;
|
|
int temp_critical;
|
|
+ unsigned long temp_max;
|
|
int alarm_temp;
|
|
int last_temp;
|
|
bool irq_enabled;
|
|
int irq;
|
|
struct clk *thermal_clk;
|
|
const struct thermal_soc_data *socdata;
|
|
+ const char *temp_grade;
|
|
};
|
|
|
|
static void imx_set_panic_temp(struct imx_thermal_data *data,
|
|
@@ -285,10 +282,12 @@
|
|
{
|
|
struct imx_thermal_data *data = tz->devdata;
|
|
|
|
+ /* do not allow changing critical threshold */
|
|
if (trip == IMX_TRIP_CRITICAL)
|
|
return -EPERM;
|
|
|
|
- if (temp > IMX_TEMP_PASSIVE)
|
|
+ /* do not allow passive to be set higher than critical */
|
|
+ if (temp < 0 || temp > data->temp_critical)
|
|
return -EINVAL;
|
|
|
|
data->temp_passive = temp;
|
|
@@ -404,17 +403,39 @@
|
|
data->c1 = temp64;
|
|
data->c2 = n1 * data->c1 + 1000 * t1;
|
|
|
|
- /*
|
|
- * Set the default passive cooling trip point,
|
|
- * can be changed from userspace.
|
|
- */
|
|
- data->temp_passive = IMX_TEMP_PASSIVE;
|
|
+ /* use OTP for thermal grade */
|
|
+ ret = regmap_read(map, OCOTP_MEM0, &val);
|
|
+ if (ret) {
|
|
+ dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ /* The maximum die temp is specified by the Temperature Grade */
|
|
+ switch ((val >> 6) & 0x3) {
|
|
+ case 0: /* Commercial (0 to 95C) */
|
|
+ data->temp_grade = "Commercial";
|
|
+ data->temp_max = 95000;
|
|
+ break;
|
|
+ case 1: /* Extended Commercial (-20 to 105C) */
|
|
+ data->temp_grade = "Extended Commercial";
|
|
+ data->temp_max = 105000;
|
|
+ break;
|
|
+ case 2: /* Industrial (-40 to 105C) */
|
|
+ data->temp_grade = "Industrial";
|
|
+ data->temp_max = 105000;
|
|
+ break;
|
|
+ case 3: /* Automotive (-40 to 125C) */
|
|
+ data->temp_grade = "Automotive";
|
|
+ data->temp_max = 125000;
|
|
+ break;
|
|
+ }
|
|
|
|
/*
|
|
- * The maximum die temperature set to 20 C higher than
|
|
- * IMX_TEMP_PASSIVE.
|
|
+ * Set the critical trip point at 5C under max
|
|
+ * Set the passive trip point at 10C under max (can change via sysfs)
|
|
*/
|
|
- data->temp_critical = 1000 * 20 + data->temp_passive;
|
|
+ data->temp_critical = data->temp_max - (1000 * 5);
|
|
+ data->temp_passive = data->temp_max - (1000 * 10);
|
|
|
|
return 0;
|
|
}
|
|
@@ -559,6 +580,11 @@
|
|
return ret;
|
|
}
|
|
|
|
+ dev_info(&pdev->dev, "%s CPU temperature grade - max:%ldC"
|
|
+ " critical:%ldC passive:%ldC\n", data->temp_grade,
|
|
+ data->temp_max / 1000, data->temp_critical / 1000,
|
|
+ data->temp_passive / 1000);
|
|
+
|
|
/* Enable measurements at ~ 10 Hz */
|
|
regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
|
|
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
|