diff options
Diffstat (limited to 'drivers/thermal/imx_thermal.c')
-rw-r--r-- | drivers/thermal/imx_thermal.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c8fe3cac2e0e..c5547bd711db 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #define TEMPSENSE2_PANIC_VALUE_SHIFT 16 | 55 | #define TEMPSENSE2_PANIC_VALUE_SHIFT 16 |
56 | #define TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000 | 56 | #define TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000 |
57 | 57 | ||
58 | #define OCOTP_MEM0 0x0480 | ||
58 | #define OCOTP_ANA1 0x04e0 | 59 | #define OCOTP_ANA1 0x04e0 |
59 | 60 | ||
60 | /* The driver supports 1 passive trip point and 1 critical trip point */ | 61 | /* The driver supports 1 passive trip point and 1 critical trip point */ |
@@ -64,12 +65,6 @@ enum imx_thermal_trip { | |||
64 | IMX_TRIP_NUM, | 65 | IMX_TRIP_NUM, |
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* | ||
68 | * It defines the temperature in millicelsius for passive trip point | ||
69 | * that will trigger cooling action when crossed. | ||
70 | */ | ||
71 | #define IMX_TEMP_PASSIVE 85000 | ||
72 | |||
73 | #define IMX_POLLING_DELAY 2000 /* millisecond */ | 68 | #define IMX_POLLING_DELAY 2000 /* millisecond */ |
74 | #define IMX_PASSIVE_DELAY 1000 | 69 | #define IMX_PASSIVE_DELAY 1000 |
75 | 70 | ||
@@ -100,12 +95,14 @@ struct imx_thermal_data { | |||
100 | u32 c1, c2; /* See formula in imx_get_sensor_data() */ | 95 | u32 c1, c2; /* See formula in imx_get_sensor_data() */ |
101 | int temp_passive; | 96 | int temp_passive; |
102 | int temp_critical; | 97 | int temp_critical; |
98 | int temp_max; | ||
103 | int alarm_temp; | 99 | int alarm_temp; |
104 | int last_temp; | 100 | int last_temp; |
105 | bool irq_enabled; | 101 | bool irq_enabled; |
106 | int irq; | 102 | int irq; |
107 | struct clk *thermal_clk; | 103 | struct clk *thermal_clk; |
108 | const struct thermal_soc_data *socdata; | 104 | const struct thermal_soc_data *socdata; |
105 | const char *temp_grade; | ||
109 | }; | 106 | }; |
110 | 107 | ||
111 | static void imx_set_panic_temp(struct imx_thermal_data *data, | 108 | static void imx_set_panic_temp(struct imx_thermal_data *data, |
@@ -285,10 +282,12 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, | |||
285 | { | 282 | { |
286 | struct imx_thermal_data *data = tz->devdata; | 283 | struct imx_thermal_data *data = tz->devdata; |
287 | 284 | ||
285 | /* do not allow changing critical threshold */ | ||
288 | if (trip == IMX_TRIP_CRITICAL) | 286 | if (trip == IMX_TRIP_CRITICAL) |
289 | return -EPERM; | 287 | return -EPERM; |
290 | 288 | ||
291 | if (temp < 0 || temp > IMX_TEMP_PASSIVE) | 289 | /* do not allow passive to be set higher than critical */ |
290 | if (temp < 0 || temp > data->temp_critical) | ||
292 | return -EINVAL; | 291 | return -EINVAL; |
293 | 292 | ||
294 | data->temp_passive = temp; | 293 | data->temp_passive = temp; |
@@ -404,17 +403,39 @@ static int imx_get_sensor_data(struct platform_device *pdev) | |||
404 | data->c1 = temp64; | 403 | data->c1 = temp64; |
405 | data->c2 = n1 * data->c1 + 1000 * t1; | 404 | data->c2 = n1 * data->c1 + 1000 * t1; |
406 | 405 | ||
407 | /* | 406 | /* use OTP for thermal grade */ |
408 | * Set the default passive cooling trip point, | 407 | ret = regmap_read(map, OCOTP_MEM0, &val); |
409 | * can be changed from userspace. | 408 | if (ret) { |
410 | */ | 409 | dev_err(&pdev->dev, "failed to read temp grade: %d\n", ret); |
411 | data->temp_passive = IMX_TEMP_PASSIVE; | 410 | return ret; |
411 | } | ||
412 | |||
413 | /* The maximum die temp is specified by the Temperature Grade */ | ||
414 | switch ((val >> 6) & 0x3) { | ||
415 | case 0: /* Commercial (0 to 95C) */ | ||
416 | data->temp_grade = "Commercial"; | ||
417 | data->temp_max = 95000; | ||
418 | break; | ||
419 | case 1: /* Extended Commercial (-20 to 105C) */ | ||
420 | data->temp_grade = "Extended Commercial"; | ||
421 | data->temp_max = 105000; | ||
422 | break; | ||
423 | case 2: /* Industrial (-40 to 105C) */ | ||
424 | data->temp_grade = "Industrial"; | ||
425 | data->temp_max = 105000; | ||
426 | break; | ||
427 | case 3: /* Automotive (-40 to 125C) */ | ||
428 | data->temp_grade = "Automotive"; | ||
429 | data->temp_max = 125000; | ||
430 | break; | ||
431 | } | ||
412 | 432 | ||
413 | /* | 433 | /* |
414 | * The maximum die temperature set to 20 C higher than | 434 | * Set the critical trip point at 5C under max |
415 | * IMX_TEMP_PASSIVE. | 435 | * Set the passive trip point at 10C under max (can change via sysfs) |
416 | */ | 436 | */ |
417 | data->temp_critical = 1000 * 20 + data->temp_passive; | 437 | data->temp_critical = data->temp_max - (1000 * 5); |
438 | data->temp_passive = data->temp_max - (1000 * 10); | ||
418 | 439 | ||
419 | return 0; | 440 | return 0; |
420 | } | 441 | } |
@@ -551,6 +572,11 @@ static int imx_thermal_probe(struct platform_device *pdev) | |||
551 | return ret; | 572 | return ret; |
552 | } | 573 | } |
553 | 574 | ||
575 | dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" | ||
576 | " critical:%dC passive:%dC\n", data->temp_grade, | ||
577 | data->temp_max / 1000, data->temp_critical / 1000, | ||
578 | data->temp_passive / 1000); | ||
579 | |||
554 | /* Enable measurements at ~ 10 Hz */ | 580 | /* Enable measurements at ~ 10 Hz */ |
555 | regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); | 581 | regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); |
556 | measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ | 582 | measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ |