diff options
author | Max Krummenacher <max.krummenacher@toradex.com> | 2017-02-01 20:57:52 +0100 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2017-04-03 15:10:58 +0200 |
commit | 5ced941a66b48bf653f016c5851a14737163a7e3 (patch) | |
tree | 99c539631706afc0896f69b64555ea68d626e9f1 | |
parent | 1695ecff1b1aa1ac9fb6325de75ee855158aeab7 (diff) |
imx_thermal.c: set trip point depending on temp grade
Set the trip point temperature where a cooling device is set to maximized
cooling was set statically to 85°C.
For i.MX 6 set this dependend on the temperature grade of the device to
10°C below the maximum junction temperature.
Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
-rw-r--r-- | drivers/thermal/imx_thermal.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index fa8151882f87..80d0eb2bd85c 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -52,6 +52,17 @@ #define IMX6_TEMPSENSE1_MEASURE_FREQ 0xffff #define IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT 0 +#define IMX6_TEMPERATURE_FUSE_REG 0x480 +#define IMX6_TEMPERATURE_GRADE_MASK (0x3 << 6) +#define IMX6_TEMPERATURE_GRADE_COMMERCIAL (0x0 << 6) +#define IMX6_TEMPERATURE_GRADE_EXT_COMMERCIAL (0x1 << 6) +#define IMX6_TEMPERATURE_GRADE_INDUSTRIAL (0x2 << 6) +#define IMX6_TEMPERATURE_GRADE_AUTOMOTIVE (0x3 << 6) +#define IMX6_TEMP_PASSIVE_COMMERCIAL 85000 +#define IMX6_TEMP_PASSIVE_EXT_COMMERCIAL 95000 +#define IMX6_TEMP_PASSIVE_INDUSTRIAL 95000 +#define IMX6_TEMP_PASSIVE_AUTOMOTIVE 115000 + /* Below TEMPSENSE2 is only for TEMPMON_IMX6SX */ #define TEMPSENSE2 0x0290 #define TEMPSENSE2_LOW_VALUE_SHIFT 0 @@ -91,6 +102,7 @@ enum imx_thermal_trip { /* * It defines the temperature in millicelsius for passive trip point * that will trigger cooling action when crossed. + * Value is adapted in probe() to the SoC's temp grade for i.MX 6 */ #define IMX_TEMP_PASSIVE 85000 #define IMX_TEMP_PASSIVE_COOL_DELTA 10000 @@ -107,6 +119,8 @@ enum imx_thermal_trip { #define TEMPMON_IMX6SX 2 #define TEMPMON_IMX7 3 +static int imx_temp_passive = IMX_TEMP_PASSIVE; + /* the register offsets and bitfields may change across * i.MX SOCs, use below struct as a description of the * register. @@ -461,7 +475,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, } if (trip == IMX_TRIP_PASSIVE) { - if (temp > IMX_TEMP_PASSIVE) + if (temp > imx_temp_passive) return -EINVAL; data->temp_passive = temp; imx_set_alarm_temp(data, temp); @@ -622,16 +636,16 @@ static int imx_get_sensor_data(struct platform_device *pdev) imx6_calibrate_data(data, val); /* - * Set the default passive cooling trip point to IMX_TEMP_PASSIVE. + * Set the default passive cooling trip point to imx_temp_passive. * Can be changed from userspace. */ - data->temp_passive = IMX_TEMP_PASSIVE; + data->temp_passive = imx_temp_passive; /* * Set the default critical trip point to 20 C higher * than passive trip point. Can be changed from userspace. */ - data->temp_critical = IMX_TEMP_PASSIVE + 20 * 1000; + data->temp_critical = imx_temp_passive + 20 * 1000; return 0; } @@ -719,13 +733,48 @@ static int imx_thermal_probe(struct platform_device *pdev) struct imx_thermal_data *data; struct regmap *map; int measure_freq; - int ret, revision; + int val, ret, revision; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; imx_thermal_data = data; + data->socdata = of_id->data; + + /* adjust trip point according to i.MX 6 SoC temperature grade */ + map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "fsl,tempmon-data"); + if (IS_ERR(map)) { + ret = PTR_ERR(map); + dev_err(&pdev->dev, "failed to get ocotp regmap: %d\n", ret); + return ret; + } + if (data->socdata->version == TEMPMON_IMX6Q) { + ret = regmap_read(map, IMX6_TEMPERATURE_FUSE_REG, &val); + if (!ret) { + switch (val & IMX6_TEMPERATURE_GRADE_MASK) { + case IMX6_TEMPERATURE_GRADE_EXT_COMMERCIAL: + imx_temp_passive = + IMX6_TEMP_PASSIVE_EXT_COMMERCIAL; + break; + case IMX6_TEMPERATURE_GRADE_INDUSTRIAL: + imx_temp_passive = + IMX6_TEMP_PASSIVE_INDUSTRIAL; + break; + case IMX6_TEMPERATURE_GRADE_AUTOMOTIVE: + imx_temp_passive = + IMX6_TEMP_PASSIVE_AUTOMOTIVE; + break; + case IMX6_TEMPERATURE_GRADE_COMMERCIAL: + default: + imx_temp_passive = + IMX6_TEMP_PASSIVE_COMMERCIAL; + break; + } + } + } + map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); if (IS_ERR(map)) { ret = PTR_ERR(map); @@ -734,8 +783,6 @@ static int imx_thermal_probe(struct platform_device *pdev) } data->tempmon = map; - data->socdata = of_id->data; - /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */ if (data->socdata->version == TEMPMON_IMX6SX) { regmap_write(map, MISC1 + REG_CLR, MISC1_IRQ_TEMPHIGH | |