imx_thermal.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Copyright 2013 Freescale Semiconductor, Inc.
  4. #include <linux/clk.h>
  5. #include <linux/cpufreq.h>
  6. #include <linux/cpu_cooling.h>
  7. #include <linux/delay.h>
  8. #include <linux/device.h>
  9. #include <linux/init.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/io.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_device.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regmap.h>
  19. #include <linux/slab.h>
  20. #include <linux/thermal.h>
  21. #include <linux/types.h>
  22. #include <linux/nvmem-consumer.h>
  23. #define REG_SET 0x4
  24. #define REG_CLR 0x8
  25. #define REG_TOG 0xc
  26. /* i.MX6 specific */
  27. #define IMX6_MISC0 0x0150
  28. #define IMX6_MISC0_REFTOP_SELBIASOFF (1 << 3)
  29. #define IMX6_MISC1 0x0160
  30. #define IMX6_MISC1_IRQ_TEMPHIGH (1 << 29)
  31. /* Below LOW and PANIC bits are only for TEMPMON_IMX6SX */
  32. #define IMX6_MISC1_IRQ_TEMPLOW (1 << 28)
  33. #define IMX6_MISC1_IRQ_TEMPPANIC (1 << 27)
  34. #define IMX6_TEMPSENSE0 0x0180
  35. #define IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT 20
  36. #define IMX6_TEMPSENSE0_ALARM_VALUE_MASK (0xfff << 20)
  37. #define IMX6_TEMPSENSE0_TEMP_CNT_SHIFT 8
  38. #define IMX6_TEMPSENSE0_TEMP_CNT_MASK (0xfff << 8)
  39. #define IMX6_TEMPSENSE0_FINISHED (1 << 2)
  40. #define IMX6_TEMPSENSE0_MEASURE_TEMP (1 << 1)
  41. #define IMX6_TEMPSENSE0_POWER_DOWN (1 << 0)
  42. #define IMX6_TEMPSENSE1 0x0190
  43. #define IMX6_TEMPSENSE1_MEASURE_FREQ 0xffff
  44. #define IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT 0
  45. #define OCOTP_MEM0 0x0480
  46. #define OCOTP_ANA1 0x04e0
  47. /* Below TEMPSENSE2 is only for TEMPMON_IMX6SX */
  48. #define IMX6_TEMPSENSE2 0x0290
  49. #define IMX6_TEMPSENSE2_LOW_VALUE_SHIFT 0
  50. #define IMX6_TEMPSENSE2_LOW_VALUE_MASK 0xfff
  51. #define IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT 16
  52. #define IMX6_TEMPSENSE2_PANIC_VALUE_MASK 0xfff0000
  53. /* i.MX7 specific */
  54. #define IMX7_ANADIG_DIGPROG 0x800
  55. #define IMX7_TEMPSENSE0 0x300
  56. #define IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT 18
  57. #define IMX7_TEMPSENSE0_PANIC_ALARM_MASK (0x1ff << 18)
  58. #define IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT 9
  59. #define IMX7_TEMPSENSE0_HIGH_ALARM_MASK (0x1ff << 9)
  60. #define IMX7_TEMPSENSE0_LOW_ALARM_SHIFT 0
  61. #define IMX7_TEMPSENSE0_LOW_ALARM_MASK 0x1ff
  62. #define IMX7_TEMPSENSE1 0x310
  63. #define IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT 16
  64. #define IMX7_TEMPSENSE1_MEASURE_FREQ_MASK (0xffff << 16)
  65. #define IMX7_TEMPSENSE1_FINISHED (1 << 11)
  66. #define IMX7_TEMPSENSE1_MEASURE_TEMP (1 << 10)
  67. #define IMX7_TEMPSENSE1_POWER_DOWN (1 << 9)
  68. #define IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT 0
  69. #define IMX7_TEMPSENSE1_TEMP_VALUE_MASK 0x1ff
  70. /* The driver supports 1 passive trip point and 1 critical trip point */
  71. enum imx_thermal_trip {
  72. IMX_TRIP_PASSIVE,
  73. IMX_TRIP_CRITICAL,
  74. IMX_TRIP_NUM,
  75. };
  76. #define IMX_POLLING_DELAY 2000 /* millisecond */
  77. #define IMX_PASSIVE_DELAY 1000
  78. #define TEMPMON_IMX6Q 1
  79. #define TEMPMON_IMX6SX 2
  80. #define TEMPMON_IMX7D 3
  81. struct thermal_soc_data {
  82. u32 version;
  83. u32 sensor_ctrl;
  84. u32 power_down_mask;
  85. u32 measure_temp_mask;
  86. u32 measure_freq_ctrl;
  87. u32 measure_freq_mask;
  88. u32 measure_freq_shift;
  89. u32 temp_data;
  90. u32 temp_value_mask;
  91. u32 temp_value_shift;
  92. u32 temp_valid_mask;
  93. u32 panic_alarm_ctrl;
  94. u32 panic_alarm_mask;
  95. u32 panic_alarm_shift;
  96. u32 high_alarm_ctrl;
  97. u32 high_alarm_mask;
  98. u32 high_alarm_shift;
  99. u32 low_alarm_ctrl;
  100. u32 low_alarm_mask;
  101. u32 low_alarm_shift;
  102. };
  103. static struct thermal_soc_data thermal_imx6q_data = {
  104. .version = TEMPMON_IMX6Q,
  105. .sensor_ctrl = IMX6_TEMPSENSE0,
  106. .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
  107. .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
  108. .measure_freq_ctrl = IMX6_TEMPSENSE1,
  109. .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
  110. .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
  111. .temp_data = IMX6_TEMPSENSE0,
  112. .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
  113. .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
  114. .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
  115. .high_alarm_ctrl = IMX6_TEMPSENSE0,
  116. .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
  117. .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
  118. };
  119. static struct thermal_soc_data thermal_imx6sx_data = {
  120. .version = TEMPMON_IMX6SX,
  121. .sensor_ctrl = IMX6_TEMPSENSE0,
  122. .power_down_mask = IMX6_TEMPSENSE0_POWER_DOWN,
  123. .measure_temp_mask = IMX6_TEMPSENSE0_MEASURE_TEMP,
  124. .measure_freq_ctrl = IMX6_TEMPSENSE1,
  125. .measure_freq_shift = IMX6_TEMPSENSE1_MEASURE_FREQ_SHIFT,
  126. .measure_freq_mask = IMX6_TEMPSENSE1_MEASURE_FREQ,
  127. .temp_data = IMX6_TEMPSENSE0,
  128. .temp_value_mask = IMX6_TEMPSENSE0_TEMP_CNT_MASK,
  129. .temp_value_shift = IMX6_TEMPSENSE0_TEMP_CNT_SHIFT,
  130. .temp_valid_mask = IMX6_TEMPSENSE0_FINISHED,
  131. .high_alarm_ctrl = IMX6_TEMPSENSE0,
  132. .high_alarm_mask = IMX6_TEMPSENSE0_ALARM_VALUE_MASK,
  133. .high_alarm_shift = IMX6_TEMPSENSE0_ALARM_VALUE_SHIFT,
  134. .panic_alarm_ctrl = IMX6_TEMPSENSE2,
  135. .panic_alarm_mask = IMX6_TEMPSENSE2_PANIC_VALUE_MASK,
  136. .panic_alarm_shift = IMX6_TEMPSENSE2_PANIC_VALUE_SHIFT,
  137. .low_alarm_ctrl = IMX6_TEMPSENSE2,
  138. .low_alarm_mask = IMX6_TEMPSENSE2_LOW_VALUE_MASK,
  139. .low_alarm_shift = IMX6_TEMPSENSE2_LOW_VALUE_SHIFT,
  140. };
  141. static struct thermal_soc_data thermal_imx7d_data = {
  142. .version = TEMPMON_IMX7D,
  143. .sensor_ctrl = IMX7_TEMPSENSE1,
  144. .power_down_mask = IMX7_TEMPSENSE1_POWER_DOWN,
  145. .measure_temp_mask = IMX7_TEMPSENSE1_MEASURE_TEMP,
  146. .measure_freq_ctrl = IMX7_TEMPSENSE1,
  147. .measure_freq_shift = IMX7_TEMPSENSE1_MEASURE_FREQ_SHIFT,
  148. .measure_freq_mask = IMX7_TEMPSENSE1_MEASURE_FREQ_MASK,
  149. .temp_data = IMX7_TEMPSENSE1,
  150. .temp_value_mask = IMX7_TEMPSENSE1_TEMP_VALUE_MASK,
  151. .temp_value_shift = IMX7_TEMPSENSE1_TEMP_VALUE_SHIFT,
  152. .temp_valid_mask = IMX7_TEMPSENSE1_FINISHED,
  153. .panic_alarm_ctrl = IMX7_TEMPSENSE1,
  154. .panic_alarm_mask = IMX7_TEMPSENSE0_PANIC_ALARM_MASK,
  155. .panic_alarm_shift = IMX7_TEMPSENSE0_PANIC_ALARM_SHIFT,
  156. .high_alarm_ctrl = IMX7_TEMPSENSE0,
  157. .high_alarm_mask = IMX7_TEMPSENSE0_HIGH_ALARM_MASK,
  158. .high_alarm_shift = IMX7_TEMPSENSE0_HIGH_ALARM_SHIFT,
  159. .low_alarm_ctrl = IMX7_TEMPSENSE0,
  160. .low_alarm_mask = IMX7_TEMPSENSE0_LOW_ALARM_MASK,
  161. .low_alarm_shift = IMX7_TEMPSENSE0_LOW_ALARM_SHIFT,
  162. };
  163. struct imx_thermal_data {
  164. struct cpufreq_policy *policy;
  165. struct thermal_zone_device *tz;
  166. struct thermal_cooling_device *cdev;
  167. enum thermal_device_mode mode;
  168. struct regmap *tempmon;
  169. u32 c1, c2; /* See formula in imx_init_calib() */
  170. int temp_passive;
  171. int temp_critical;
  172. int temp_max;
  173. int alarm_temp;
  174. int last_temp;
  175. bool irq_enabled;
  176. int irq;
  177. struct clk *thermal_clk;
  178. const struct thermal_soc_data *socdata;
  179. const char *temp_grade;
  180. };
  181. static void imx_set_panic_temp(struct imx_thermal_data *data,
  182. int panic_temp)
  183. {
  184. const struct thermal_soc_data *soc_data = data->socdata;
  185. struct regmap *map = data->tempmon;
  186. int critical_value;
  187. critical_value = (data->c2 - panic_temp) / data->c1;
  188. regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
  189. soc_data->panic_alarm_mask);
  190. regmap_write(map, soc_data->panic_alarm_ctrl + REG_SET,
  191. critical_value << soc_data->panic_alarm_shift);
  192. }
  193. static void imx_set_alarm_temp(struct imx_thermal_data *data,
  194. int alarm_temp)
  195. {
  196. struct regmap *map = data->tempmon;
  197. const struct thermal_soc_data *soc_data = data->socdata;
  198. int alarm_value;
  199. data->alarm_temp = alarm_temp;
  200. if (data->socdata->version == TEMPMON_IMX7D)
  201. alarm_value = alarm_temp / 1000 + data->c1 - 25;
  202. else
  203. alarm_value = (data->c2 - alarm_temp) / data->c1;
  204. regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
  205. soc_data->high_alarm_mask);
  206. regmap_write(map, soc_data->high_alarm_ctrl + REG_SET,
  207. alarm_value << soc_data->high_alarm_shift);
  208. }
  209. static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
  210. {
  211. struct imx_thermal_data *data = tz->devdata;
  212. const struct thermal_soc_data *soc_data = data->socdata;
  213. struct regmap *map = data->tempmon;
  214. unsigned int n_meas;
  215. bool wait;
  216. u32 val;
  217. if (data->mode == THERMAL_DEVICE_ENABLED) {
  218. /* Check if a measurement is currently in progress */
  219. regmap_read(map, soc_data->temp_data, &val);
  220. wait = !(val & soc_data->temp_valid_mask);
  221. } else {
  222. /*
  223. * Every time we measure the temperature, we will power on the
  224. * temperature sensor, enable measurements, take a reading,
  225. * disable measurements, power off the temperature sensor.
  226. */
  227. regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
  228. soc_data->power_down_mask);
  229. regmap_write(map, soc_data->sensor_ctrl + REG_SET,
  230. soc_data->measure_temp_mask);
  231. wait = true;
  232. }
  233. /*
  234. * According to the temp sensor designers, it may require up to ~17us
  235. * to complete a measurement.
  236. */
  237. if (wait)
  238. usleep_range(20, 50);
  239. regmap_read(map, soc_data->temp_data, &val);
  240. if (data->mode != THERMAL_DEVICE_ENABLED) {
  241. regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
  242. soc_data->measure_temp_mask);
  243. regmap_write(map, soc_data->sensor_ctrl + REG_SET,
  244. soc_data->power_down_mask);
  245. }
  246. if ((val & soc_data->temp_valid_mask) == 0) {
  247. dev_dbg(&tz->device, "temp measurement never finished\n");
  248. return -EAGAIN;
  249. }
  250. n_meas = (val & soc_data->temp_value_mask)
  251. >> soc_data->temp_value_shift;
  252. /* See imx_init_calib() for formula derivation */
  253. if (data->socdata->version == TEMPMON_IMX7D)
  254. *temp = (n_meas - data->c1 + 25) * 1000;
  255. else
  256. *temp = data->c2 - n_meas * data->c1;
  257. /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
  258. if (data->socdata->version == TEMPMON_IMX6Q) {
  259. if (data->alarm_temp == data->temp_passive &&
  260. *temp >= data->temp_passive)
  261. imx_set_alarm_temp(data, data->temp_critical);
  262. if (data->alarm_temp == data->temp_critical &&
  263. *temp < data->temp_passive) {
  264. imx_set_alarm_temp(data, data->temp_passive);
  265. dev_dbg(&tz->device, "thermal alarm off: T < %d\n",
  266. data->alarm_temp / 1000);
  267. }
  268. }
  269. if (*temp != data->last_temp) {
  270. dev_dbg(&tz->device, "millicelsius: %d\n", *temp);
  271. data->last_temp = *temp;
  272. }
  273. /* Reenable alarm IRQ if temperature below alarm temperature */
  274. if (!data->irq_enabled && *temp < data->alarm_temp) {
  275. data->irq_enabled = true;
  276. enable_irq(data->irq);
  277. }
  278. return 0;
  279. }
  280. static int imx_get_mode(struct thermal_zone_device *tz,
  281. enum thermal_device_mode *mode)
  282. {
  283. struct imx_thermal_data *data = tz->devdata;
  284. *mode = data->mode;
  285. return 0;
  286. }
  287. static int imx_set_mode(struct thermal_zone_device *tz,
  288. enum thermal_device_mode mode)
  289. {
  290. struct imx_thermal_data *data = tz->devdata;
  291. struct regmap *map = data->tempmon;
  292. const struct thermal_soc_data *soc_data = data->socdata;
  293. if (mode == THERMAL_DEVICE_ENABLED) {
  294. tz->polling_delay = IMX_POLLING_DELAY;
  295. tz->passive_delay = IMX_PASSIVE_DELAY;
  296. regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
  297. soc_data->power_down_mask);
  298. regmap_write(map, soc_data->sensor_ctrl + REG_SET,
  299. soc_data->measure_temp_mask);
  300. if (!data->irq_enabled) {
  301. data->irq_enabled = true;
  302. enable_irq(data->irq);
  303. }
  304. } else {
  305. regmap_write(map, soc_data->sensor_ctrl + REG_CLR,
  306. soc_data->measure_temp_mask);
  307. regmap_write(map, soc_data->sensor_ctrl + REG_SET,
  308. soc_data->power_down_mask);
  309. tz->polling_delay = 0;
  310. tz->passive_delay = 0;
  311. if (data->irq_enabled) {
  312. disable_irq(data->irq);
  313. data->irq_enabled = false;
  314. }
  315. }
  316. data->mode = mode;
  317. thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
  318. return 0;
  319. }
  320. static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
  321. enum thermal_trip_type *type)
  322. {
  323. *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
  324. THERMAL_TRIP_CRITICAL;
  325. return 0;
  326. }
  327. static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
  328. {
  329. struct imx_thermal_data *data = tz->devdata;
  330. *temp = data->temp_critical;
  331. return 0;
  332. }
  333. static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
  334. int *temp)
  335. {
  336. struct imx_thermal_data *data = tz->devdata;
  337. *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
  338. data->temp_critical;
  339. return 0;
  340. }
  341. static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
  342. int temp)
  343. {
  344. struct imx_thermal_data *data = tz->devdata;
  345. /* do not allow changing critical threshold */
  346. if (trip == IMX_TRIP_CRITICAL)
  347. return -EPERM;
  348. /* do not allow passive to be set higher than critical */
  349. if (temp < 0 || temp > data->temp_critical)
  350. return -EINVAL;
  351. data->temp_passive = temp;
  352. imx_set_alarm_temp(data, temp);
  353. return 0;
  354. }
  355. static int imx_bind(struct thermal_zone_device *tz,
  356. struct thermal_cooling_device *cdev)
  357. {
  358. int ret;
  359. ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
  360. THERMAL_NO_LIMIT,
  361. THERMAL_NO_LIMIT,
  362. THERMAL_WEIGHT_DEFAULT);
  363. if (ret) {
  364. dev_err(&tz->device,
  365. "binding zone %s with cdev %s failed:%d\n",
  366. tz->type, cdev->type, ret);
  367. return ret;
  368. }
  369. return 0;
  370. }
  371. static int imx_unbind(struct thermal_zone_device *tz,
  372. struct thermal_cooling_device *cdev)
  373. {
  374. int ret;
  375. ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
  376. if (ret) {
  377. dev_err(&tz->device,
  378. "unbinding zone %s with cdev %s failed:%d\n",
  379. tz->type, cdev->type, ret);
  380. return ret;
  381. }
  382. return 0;
  383. }
  384. static struct thermal_zone_device_ops imx_tz_ops = {
  385. .bind = imx_bind,
  386. .unbind = imx_unbind,
  387. .get_temp = imx_get_temp,
  388. .get_mode = imx_get_mode,
  389. .set_mode = imx_set_mode,
  390. .get_trip_type = imx_get_trip_type,
  391. .get_trip_temp = imx_get_trip_temp,
  392. .get_crit_temp = imx_get_crit_temp,
  393. .set_trip_temp = imx_set_trip_temp,
  394. };
  395. static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
  396. {
  397. struct imx_thermal_data *data = platform_get_drvdata(pdev);
  398. int n1;
  399. u64 temp64;
  400. if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
  401. dev_err(&pdev->dev, "invalid sensor calibration data\n");
  402. return -EINVAL;
  403. }
  404. /*
  405. * On i.MX7D, we only use the calibration data at 25C to get the temp,
  406. * Tmeas = ( Nmeas - n1) + 25; n1 is the fuse value for 25C.
  407. */
  408. if (data->socdata->version == TEMPMON_IMX7D) {
  409. data->c1 = (ocotp_ana1 >> 9) & 0x1ff;
  410. return 0;
  411. }
  412. /*
  413. * The sensor is calibrated at 25 °C (aka T1) and the value measured
  414. * (aka N1) at this temperature is provided in bits [31:20] in the
  415. * i.MX's OCOTP value ANA1.
  416. * To find the actual temperature T, the following formula has to be used
  417. * when reading value n from the sensor:
  418. *
  419. * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
  420. * = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
  421. * = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
  422. * = c2 - c1 * N
  423. *
  424. * with
  425. *
  426. * T1' = 28.580661 °C
  427. * c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
  428. * c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
  429. * = T1' + N1 * c1
  430. */
  431. n1 = ocotp_ana1 >> 20;
  432. temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
  433. temp64 *= 1000; /* to get result in °mC */
  434. do_div(temp64, 15423 * n1 - 4148468);
  435. data->c1 = temp64;
  436. data->c2 = n1 * data->c1 + 28581;
  437. return 0;
  438. }
  439. static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
  440. {
  441. struct imx_thermal_data *data = platform_get_drvdata(pdev);
  442. /* The maximum die temp is specified by the Temperature Grade */
  443. switch ((ocotp_mem0 >> 6) & 0x3) {
  444. case 0: /* Commercial (0 to 95 °C) */
  445. data->temp_grade = "Commercial";
  446. data->temp_max = 95000;
  447. break;
  448. case 1: /* Extended Commercial (-20 °C to 105 °C) */
  449. data->temp_grade = "Extended Commercial";
  450. data->temp_max = 105000;
  451. break;
  452. case 2: /* Industrial (-40 °C to 105 °C) */
  453. data->temp_grade = "Industrial";
  454. data->temp_max = 105000;
  455. break;
  456. case 3: /* Automotive (-40 °C to 125 °C) */
  457. data->temp_grade = "Automotive";
  458. data->temp_max = 125000;
  459. break;
  460. }
  461. /*
  462. * Set the critical trip point at 5 °C under max
  463. * Set the passive trip point at 10 °C under max (changeable via sysfs)
  464. */
  465. data->temp_critical = data->temp_max - (1000 * 5);
  466. data->temp_passive = data->temp_max - (1000 * 10);
  467. }
  468. static int imx_init_from_tempmon_data(struct platform_device *pdev)
  469. {
  470. struct regmap *map;
  471. int ret;
  472. u32 val;
  473. map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
  474. "fsl,tempmon-data");
  475. if (IS_ERR(map)) {
  476. ret = PTR_ERR(map);
  477. dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
  478. return ret;
  479. }
  480. ret = regmap_read(map, OCOTP_ANA1, &val);
  481. if (ret) {
  482. dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
  483. return ret;
  484. }
  485. ret = imx_init_calib(pdev, val);
  486. if (ret)
  487. return ret;
  488. ret = regmap_read(map, OCOTP_MEM0, &val);
  489. if (ret) {
  490. dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
  491. return ret;
  492. }
  493. imx_init_temp_grade(pdev, val);
  494. return 0;
  495. }
  496. static int imx_init_from_nvmem_cells(struct platform_device *pdev)
  497. {
  498. int ret;
  499. u32 val;
  500. ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
  501. if (ret)
  502. return ret;
  503. imx_init_calib(pdev, val);
  504. ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
  505. if (ret)
  506. return ret;
  507. imx_init_temp_grade(pdev, val);
  508. return 0;
  509. }
  510. static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
  511. {
  512. struct imx_thermal_data *data = dev;
  513. disable_irq_nosync(irq);
  514. data->irq_enabled = false;
  515. return IRQ_WAKE_THREAD;
  516. }
  517. static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
  518. {
  519. struct imx_thermal_data *data = dev;
  520. dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n",
  521. data->alarm_temp / 1000);
  522. thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
  523. return IRQ_HANDLED;
  524. }
  525. static const struct of_device_id of_imx_thermal_match[] = {
  526. { .compatible = "fsl,imx6q-tempmon", .data = &thermal_imx6q_data, },
  527. { .compatible = "fsl,imx6sx-tempmon", .data = &thermal_imx6sx_data, },
  528. { .compatible = "fsl,imx7d-tempmon", .data = &thermal_imx7d_data, },
  529. { /* end */ }
  530. };
  531. MODULE_DEVICE_TABLE(of, of_imx_thermal_match);
  532. static int imx_thermal_probe(struct platform_device *pdev)
  533. {
  534. struct imx_thermal_data *data;
  535. struct regmap *map;
  536. int measure_freq;
  537. int ret;
  538. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  539. if (!data)
  540. return -ENOMEM;
  541. map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
  542. if (IS_ERR(map)) {
  543. ret = PTR_ERR(map);
  544. dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
  545. return ret;
  546. }
  547. data->tempmon = map;
  548. data->socdata = of_device_get_match_data(&pdev->dev);
  549. if (!data->socdata) {
  550. dev_err(&pdev->dev, "no device match found\n");
  551. return -ENODEV;
  552. }
  553. /* make sure the IRQ flag is clear before enabling irq on i.MX6SX */
  554. if (data->socdata->version == TEMPMON_IMX6SX) {
  555. regmap_write(map, IMX6_MISC1 + REG_CLR,
  556. IMX6_MISC1_IRQ_TEMPHIGH | IMX6_MISC1_IRQ_TEMPLOW
  557. | IMX6_MISC1_IRQ_TEMPPANIC);
  558. /*
  559. * reset value of LOW ALARM is incorrect, set it to lowest
  560. * value to avoid false trigger of low alarm.
  561. */
  562. regmap_write(map, data->socdata->low_alarm_ctrl + REG_SET,
  563. data->socdata->low_alarm_mask);
  564. }
  565. data->irq = platform_get_irq(pdev, 0);
  566. if (data->irq < 0)
  567. return data->irq;
  568. platform_set_drvdata(pdev, data);
  569. if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) {
  570. ret = imx_init_from_nvmem_cells(pdev);
  571. if (ret == -EPROBE_DEFER)
  572. return ret;
  573. if (ret) {
  574. dev_err(&pdev->dev, "failed to init from nvmem: %d\n",
  575. ret);
  576. return ret;
  577. }
  578. } else {
  579. ret = imx_init_from_tempmon_data(pdev);
  580. if (ret) {
  581. dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n");
  582. return ret;
  583. }
  584. }
  585. /* Make sure sensor is in known good state for measurements */
  586. regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
  587. data->socdata->power_down_mask);
  588. regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
  589. data->socdata->measure_temp_mask);
  590. regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
  591. data->socdata->measure_freq_mask);
  592. if (data->socdata->version != TEMPMON_IMX7D)
  593. regmap_write(map, IMX6_MISC0 + REG_SET,
  594. IMX6_MISC0_REFTOP_SELBIASOFF);
  595. regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
  596. data->socdata->power_down_mask);
  597. data->policy = cpufreq_cpu_get(0);
  598. if (!data->policy) {
  599. pr_debug("%s: CPUFreq policy not found\n", __func__);
  600. return -EPROBE_DEFER;
  601. }
  602. data->cdev = cpufreq_cooling_register(data->policy);
  603. if (IS_ERR(data->cdev)) {
  604. ret = PTR_ERR(data->cdev);
  605. dev_err(&pdev->dev,
  606. "failed to register cpufreq cooling device: %d\n", ret);
  607. cpufreq_cpu_put(data->policy);
  608. return ret;
  609. }
  610. data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
  611. if (IS_ERR(data->thermal_clk)) {
  612. ret = PTR_ERR(data->thermal_clk);
  613. if (ret != -EPROBE_DEFER)
  614. dev_err(&pdev->dev,
  615. "failed to get thermal clk: %d\n", ret);
  616. cpufreq_cooling_unregister(data->cdev);
  617. cpufreq_cpu_put(data->policy);
  618. return ret;
  619. }
  620. /*
  621. * Thermal sensor needs clk on to get correct value, normally
  622. * we should enable its clk before taking measurement and disable
  623. * clk after measurement is done, but if alarm function is enabled,
  624. * hardware will auto measure the temperature periodically, so we
  625. * need to keep the clk always on for alarm function.
  626. */
  627. ret = clk_prepare_enable(data->thermal_clk);
  628. if (ret) {
  629. dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
  630. cpufreq_cooling_unregister(data->cdev);
  631. cpufreq_cpu_put(data->policy);
  632. return ret;
  633. }
  634. data->tz = thermal_zone_device_register("imx_thermal_zone",
  635. IMX_TRIP_NUM,
  636. BIT(IMX_TRIP_PASSIVE), data,
  637. &imx_tz_ops, NULL,
  638. IMX_PASSIVE_DELAY,
  639. IMX_POLLING_DELAY);
  640. if (IS_ERR(data->tz)) {
  641. ret = PTR_ERR(data->tz);
  642. dev_err(&pdev->dev,
  643. "failed to register thermal zone device %d\n", ret);
  644. clk_disable_unprepare(data->thermal_clk);
  645. cpufreq_cooling_unregister(data->cdev);
  646. cpufreq_cpu_put(data->policy);
  647. return ret;
  648. }
  649. dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
  650. " critical:%dC passive:%dC\n", data->temp_grade,
  651. data->temp_max / 1000, data->temp_critical / 1000,
  652. data->temp_passive / 1000);
  653. /* Enable measurements at ~ 10 Hz */
  654. regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
  655. data->socdata->measure_freq_mask);
  656. measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
  657. regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
  658. measure_freq << data->socdata->measure_freq_shift);
  659. imx_set_alarm_temp(data, data->temp_passive);
  660. if (data->socdata->version == TEMPMON_IMX6SX)
  661. imx_set_panic_temp(data, data->temp_critical);
  662. regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
  663. data->socdata->power_down_mask);
  664. regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
  665. data->socdata->measure_temp_mask);
  666. data->irq_enabled = true;
  667. data->mode = THERMAL_DEVICE_ENABLED;
  668. ret = devm_request_threaded_irq(&pdev->dev, data->irq,
  669. imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
  670. 0, "imx_thermal", data);
  671. if (ret < 0) {
  672. dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
  673. clk_disable_unprepare(data->thermal_clk);
  674. thermal_zone_device_unregister(data->tz);
  675. cpufreq_cooling_unregister(data->cdev);
  676. cpufreq_cpu_put(data->policy);
  677. return ret;
  678. }
  679. return 0;
  680. }
  681. static int imx_thermal_remove(struct platform_device *pdev)
  682. {
  683. struct imx_thermal_data *data = platform_get_drvdata(pdev);
  684. struct regmap *map = data->tempmon;
  685. /* Disable measurements */
  686. regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
  687. data->socdata->power_down_mask);
  688. if (!IS_ERR(data->thermal_clk))
  689. clk_disable_unprepare(data->thermal_clk);
  690. thermal_zone_device_unregister(data->tz);
  691. cpufreq_cooling_unregister(data->cdev);
  692. cpufreq_cpu_put(data->policy);
  693. return 0;
  694. }
  695. #ifdef CONFIG_PM_SLEEP
  696. static int imx_thermal_suspend(struct device *dev)
  697. {
  698. struct imx_thermal_data *data = dev_get_drvdata(dev);
  699. struct regmap *map = data->tempmon;
  700. /*
  701. * Need to disable thermal sensor, otherwise, when thermal core
  702. * try to get temperature before thermal sensor resume, a wrong
  703. * temperature will be read as the thermal sensor is powered
  704. * down.
  705. */
  706. regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
  707. data->socdata->measure_temp_mask);
  708. regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
  709. data->socdata->power_down_mask);
  710. data->mode = THERMAL_DEVICE_DISABLED;
  711. clk_disable_unprepare(data->thermal_clk);
  712. return 0;
  713. }
  714. static int imx_thermal_resume(struct device *dev)
  715. {
  716. struct imx_thermal_data *data = dev_get_drvdata(dev);
  717. struct regmap *map = data->tempmon;
  718. int ret;
  719. ret = clk_prepare_enable(data->thermal_clk);
  720. if (ret)
  721. return ret;
  722. /* Enabled thermal sensor after resume */
  723. regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
  724. data->socdata->power_down_mask);
  725. regmap_write(map, data->socdata->sensor_ctrl + REG_SET,
  726. data->socdata->measure_temp_mask);
  727. data->mode = THERMAL_DEVICE_ENABLED;
  728. return 0;
  729. }
  730. #endif
  731. static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops,
  732. imx_thermal_suspend, imx_thermal_resume);
  733. static struct platform_driver imx_thermal = {
  734. .driver = {
  735. .name = "imx_thermal",
  736. .pm = &imx_thermal_pm_ops,
  737. .of_match_table = of_imx_thermal_match,
  738. },
  739. .probe = imx_thermal_probe,
  740. .remove = imx_thermal_remove,
  741. };
  742. module_platform_driver(imx_thermal);
  743. MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  744. MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
  745. MODULE_LICENSE("GPL v2");
  746. MODULE_ALIAS("platform:imx-thermal");