stm_thermal.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
  4. * Author: David Hernandez Sanchez <[email protected]> for
  5. * STMicroelectronics.
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/clk-provider.h>
  9. #include <linux/delay.h>
  10. #include <linux/err.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/io.h>
  13. #include <linux/iopoll.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_device.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/thermal.h>
  20. #include "../thermal_core.h"
  21. #include "../thermal_hwmon.h"
  22. /* DTS register offsets */
  23. #define DTS_CFGR1_OFFSET 0x0
  24. #define DTS_T0VALR1_OFFSET 0x8
  25. #define DTS_RAMPVALR_OFFSET 0X10
  26. #define DTS_ITR1_OFFSET 0x14
  27. #define DTS_DR_OFFSET 0x1C
  28. #define DTS_SR_OFFSET 0x20
  29. #define DTS_ITENR_OFFSET 0x24
  30. #define DTS_ICIFR_OFFSET 0x28
  31. /* DTS_CFGR1 register mask definitions */
  32. #define HSREF_CLK_DIV_MASK GENMASK(30, 24)
  33. #define TS1_SMP_TIME_MASK GENMASK(19, 16)
  34. #define TS1_INTRIG_SEL_MASK GENMASK(11, 8)
  35. /* DTS_T0VALR1 register mask definitions */
  36. #define TS1_T0_MASK GENMASK(17, 16)
  37. #define TS1_FMT0_MASK GENMASK(15, 0)
  38. /* DTS_RAMPVALR register mask definitions */
  39. #define TS1_RAMP_COEFF_MASK GENMASK(15, 0)
  40. /* DTS_ITR1 register mask definitions */
  41. #define TS1_HITTHD_MASK GENMASK(31, 16)
  42. #define TS1_LITTHD_MASK GENMASK(15, 0)
  43. /* DTS_DR register mask definitions */
  44. #define TS1_MFREQ_MASK GENMASK(15, 0)
  45. /* DTS_ITENR register mask definitions */
  46. #define ITENR_MASK (GENMASK(2, 0) | GENMASK(6, 4))
  47. /* DTS_ICIFR register mask definitions */
  48. #define ICIFR_MASK (GENMASK(2, 0) | GENMASK(6, 4))
  49. /* Less significant bit position definitions */
  50. #define TS1_T0_POS 16
  51. #define TS1_HITTHD_POS 16
  52. #define TS1_LITTHD_POS 0
  53. #define HSREF_CLK_DIV_POS 24
  54. /* DTS_CFGR1 bit definitions */
  55. #define TS1_EN BIT(0)
  56. #define TS1_START BIT(4)
  57. #define REFCLK_SEL BIT(20)
  58. #define REFCLK_LSE REFCLK_SEL
  59. #define Q_MEAS_OPT BIT(21)
  60. #define CALIBRATION_CONTROL Q_MEAS_OPT
  61. /* DTS_SR bit definitions */
  62. #define TS_RDY BIT(15)
  63. /* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
  64. #define HIGH_THRESHOLD BIT(2)
  65. #define LOW_THRESHOLD BIT(1)
  66. /* Constants */
  67. #define ADJUST 100
  68. #define ONE_MHZ 1000000
  69. #define POLL_TIMEOUT 5000
  70. #define STARTUP_TIME 40
  71. #define TS1_T0_VAL0 30000 /* 30 celsius */
  72. #define TS1_T0_VAL1 130000 /* 130 celsius */
  73. #define NO_HW_TRIG 0
  74. #define SAMPLING_TIME 15
  75. struct stm_thermal_sensor {
  76. struct device *dev;
  77. struct thermal_zone_device *th_dev;
  78. enum thermal_device_mode mode;
  79. struct clk *clk;
  80. unsigned int low_temp_enabled;
  81. unsigned int high_temp_enabled;
  82. int irq;
  83. void __iomem *base;
  84. int t0, fmt0, ramp_coeff;
  85. };
  86. static int stm_enable_irq(struct stm_thermal_sensor *sensor)
  87. {
  88. u32 value;
  89. dev_dbg(sensor->dev, "low:%d high:%d\n", sensor->low_temp_enabled,
  90. sensor->high_temp_enabled);
  91. /* Disable IT generation for low and high thresholds */
  92. value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
  93. value &= ~(LOW_THRESHOLD | HIGH_THRESHOLD);
  94. if (sensor->low_temp_enabled)
  95. value |= HIGH_THRESHOLD;
  96. if (sensor->high_temp_enabled)
  97. value |= LOW_THRESHOLD;
  98. /* Enable interrupts */
  99. writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
  100. return 0;
  101. }
  102. static irqreturn_t stm_thermal_irq_handler(int irq, void *sdata)
  103. {
  104. struct stm_thermal_sensor *sensor = sdata;
  105. dev_dbg(sensor->dev, "sr:%d\n",
  106. readl_relaxed(sensor->base + DTS_SR_OFFSET));
  107. thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
  108. stm_enable_irq(sensor);
  109. /* Acknoledge all DTS irqs */
  110. writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
  111. return IRQ_HANDLED;
  112. }
  113. static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
  114. {
  115. int ret;
  116. u32 value;
  117. /* Enable sensor */
  118. value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
  119. value |= TS1_EN;
  120. writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
  121. /*
  122. * The DTS block can be enabled by setting TSx_EN bit in
  123. * DTS_CFGRx register. It requires a startup time of
  124. * 40μs. Use 5 ms as arbitrary timeout.
  125. */
  126. ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
  127. value, (value & TS_RDY),
  128. STARTUP_TIME, POLL_TIMEOUT);
  129. if (ret)
  130. return ret;
  131. /* Start continuous measuring */
  132. value = readl_relaxed(sensor->base +
  133. DTS_CFGR1_OFFSET);
  134. value |= TS1_START;
  135. writel_relaxed(value, sensor->base +
  136. DTS_CFGR1_OFFSET);
  137. sensor->mode = THERMAL_DEVICE_ENABLED;
  138. return 0;
  139. }
  140. static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
  141. {
  142. u32 value;
  143. sensor->mode = THERMAL_DEVICE_DISABLED;
  144. /* Stop measuring */
  145. value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
  146. value &= ~TS1_START;
  147. writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
  148. /* Ensure stop is taken into account */
  149. usleep_range(STARTUP_TIME, POLL_TIMEOUT);
  150. /* Disable sensor */
  151. value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
  152. value &= ~TS1_EN;
  153. writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
  154. /* Ensure disable is taken into account */
  155. return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
  156. !(value & TS_RDY),
  157. STARTUP_TIME, POLL_TIMEOUT);
  158. }
  159. static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
  160. {
  161. u32 value, clk_freq;
  162. u32 prescaler;
  163. /* Figure out prescaler value for PCLK during calibration */
  164. clk_freq = clk_get_rate(sensor->clk);
  165. if (!clk_freq)
  166. return -EINVAL;
  167. prescaler = 0;
  168. clk_freq /= ONE_MHZ;
  169. if (clk_freq) {
  170. while (prescaler <= clk_freq)
  171. prescaler++;
  172. }
  173. value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
  174. /* Clear prescaler */
  175. value &= ~HSREF_CLK_DIV_MASK;
  176. /* Set prescaler. pclk_freq/prescaler < 1MHz */
  177. value |= (prescaler << HSREF_CLK_DIV_POS);
  178. /* Select PCLK as reference clock */
  179. value &= ~REFCLK_SEL;
  180. /* Set maximal sampling time for better precision */
  181. value |= TS1_SMP_TIME_MASK;
  182. /* Measure with calibration */
  183. value &= ~CALIBRATION_CONTROL;
  184. /* select trigger */
  185. value &= ~TS1_INTRIG_SEL_MASK;
  186. value |= NO_HW_TRIG;
  187. writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
  188. return 0;
  189. }
  190. /* Fill in DTS structure with factory sensor values */
  191. static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
  192. {
  193. /* Retrieve engineering calibration temperature */
  194. sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
  195. TS1_T0_MASK;
  196. if (!sensor->t0)
  197. sensor->t0 = TS1_T0_VAL0;
  198. else
  199. sensor->t0 = TS1_T0_VAL1;
  200. /* Retrieve fmt0 and put it on Hz */
  201. sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base +
  202. DTS_T0VALR1_OFFSET) & TS1_FMT0_MASK);
  203. /* Retrieve ramp coefficient */
  204. sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
  205. TS1_RAMP_COEFF_MASK;
  206. if (!sensor->fmt0 || !sensor->ramp_coeff) {
  207. dev_err(sensor->dev, "%s: wrong setting\n", __func__);
  208. return -EINVAL;
  209. }
  210. dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
  211. __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
  212. return 0;
  213. }
  214. static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
  215. int temp, u32 *th)
  216. {
  217. int freqM;
  218. /* Figure out the CLK_PTAT frequency for a given temperature */
  219. freqM = ((temp - sensor->t0) * sensor->ramp_coeff) / 1000 +
  220. sensor->fmt0;
  221. /* Figure out the threshold sample number */
  222. *th = clk_get_rate(sensor->clk) * SAMPLING_TIME / freqM;
  223. if (!*th)
  224. return -EINVAL;
  225. dev_dbg(sensor->dev, "freqM=%d Hz, threshold=0x%x", freqM, *th);
  226. return 0;
  227. }
  228. /* Disable temperature interrupt */
  229. static int stm_disable_irq(struct stm_thermal_sensor *sensor)
  230. {
  231. u32 value;
  232. /* Disable IT generation */
  233. value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
  234. value &= ~ITENR_MASK;
  235. writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
  236. return 0;
  237. }
  238. static int stm_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
  239. {
  240. struct stm_thermal_sensor *sensor = tz->devdata;
  241. u32 itr1, th;
  242. int ret;
  243. dev_dbg(sensor->dev, "set trips %d <--> %d\n", low, high);
  244. /* Erase threshold content */
  245. itr1 = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
  246. itr1 &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
  247. /*
  248. * Disable low-temp if "low" is too small. As per thermal framework
  249. * API, we use -INT_MAX rather than INT_MIN.
  250. */
  251. if (low > -INT_MAX) {
  252. sensor->low_temp_enabled = 1;
  253. /* add 0.5 of hysteresis due to measurement error */
  254. ret = stm_thermal_calculate_threshold(sensor, low - 500, &th);
  255. if (ret)
  256. return ret;
  257. itr1 |= (TS1_HITTHD_MASK & (th << TS1_HITTHD_POS));
  258. } else {
  259. sensor->low_temp_enabled = 0;
  260. }
  261. /* Disable high-temp if "high" is too big. */
  262. if (high < INT_MAX) {
  263. sensor->high_temp_enabled = 1;
  264. ret = stm_thermal_calculate_threshold(sensor, high, &th);
  265. if (ret)
  266. return ret;
  267. itr1 |= (TS1_LITTHD_MASK & (th << TS1_LITTHD_POS));
  268. } else {
  269. sensor->high_temp_enabled = 0;
  270. }
  271. /* Write new threshod values*/
  272. writel_relaxed(itr1, sensor->base + DTS_ITR1_OFFSET);
  273. return 0;
  274. }
  275. /* Callback to get temperature from HW */
  276. static int stm_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
  277. {
  278. struct stm_thermal_sensor *sensor = tz->devdata;
  279. u32 periods;
  280. int freqM, ret;
  281. if (sensor->mode != THERMAL_DEVICE_ENABLED)
  282. return -EAGAIN;
  283. /* Retrieve the number of periods sampled */
  284. ret = readl_relaxed_poll_timeout(sensor->base + DTS_DR_OFFSET, periods,
  285. (periods & TS1_MFREQ_MASK),
  286. STARTUP_TIME, POLL_TIMEOUT);
  287. if (ret)
  288. return ret;
  289. /* Figure out the CLK_PTAT frequency */
  290. freqM = (clk_get_rate(sensor->clk) * SAMPLING_TIME) / periods;
  291. if (!freqM)
  292. return -EINVAL;
  293. /* Figure out the temperature in mili celsius */
  294. *temp = (freqM - sensor->fmt0) * 1000 / sensor->ramp_coeff + sensor->t0;
  295. return 0;
  296. }
  297. /* Registers DTS irq to be visible by GIC */
  298. static int stm_register_irq(struct stm_thermal_sensor *sensor)
  299. {
  300. struct device *dev = sensor->dev;
  301. struct platform_device *pdev = to_platform_device(dev);
  302. int ret;
  303. sensor->irq = platform_get_irq(pdev, 0);
  304. if (sensor->irq < 0)
  305. return sensor->irq;
  306. ret = devm_request_threaded_irq(dev, sensor->irq,
  307. NULL,
  308. stm_thermal_irq_handler,
  309. IRQF_ONESHOT,
  310. dev->driver->name, sensor);
  311. if (ret) {
  312. dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
  313. sensor->irq);
  314. return ret;
  315. }
  316. dev_dbg(dev, "%s: thermal IRQ registered", __func__);
  317. return 0;
  318. }
  319. static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
  320. {
  321. int ret;
  322. stm_disable_irq(sensor);
  323. ret = stm_sensor_power_off(sensor);
  324. if (ret)
  325. return ret;
  326. clk_disable_unprepare(sensor->clk);
  327. return 0;
  328. }
  329. static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
  330. {
  331. int ret;
  332. ret = clk_prepare_enable(sensor->clk);
  333. if (ret)
  334. return ret;
  335. ret = stm_thermal_read_factory_settings(sensor);
  336. if (ret)
  337. goto thermal_unprepare;
  338. ret = stm_thermal_calibration(sensor);
  339. if (ret)
  340. goto thermal_unprepare;
  341. return 0;
  342. thermal_unprepare:
  343. clk_disable_unprepare(sensor->clk);
  344. return ret;
  345. }
  346. #ifdef CONFIG_PM_SLEEP
  347. static int stm_thermal_suspend(struct device *dev)
  348. {
  349. struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
  350. return stm_thermal_sensor_off(sensor);
  351. }
  352. static int stm_thermal_resume(struct device *dev)
  353. {
  354. int ret;
  355. struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
  356. ret = stm_thermal_prepare(sensor);
  357. if (ret)
  358. return ret;
  359. ret = stm_sensor_power_on(sensor);
  360. if (ret)
  361. return ret;
  362. thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
  363. stm_enable_irq(sensor);
  364. return 0;
  365. }
  366. #endif /* CONFIG_PM_SLEEP */
  367. static SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops,
  368. stm_thermal_suspend, stm_thermal_resume);
  369. static const struct thermal_zone_device_ops stm_tz_ops = {
  370. .get_temp = stm_thermal_get_temp,
  371. .set_trips = stm_thermal_set_trips,
  372. };
  373. static const struct of_device_id stm_thermal_of_match[] = {
  374. { .compatible = "st,stm32-thermal"},
  375. { /* sentinel */ }
  376. };
  377. MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
  378. static int stm_thermal_probe(struct platform_device *pdev)
  379. {
  380. struct stm_thermal_sensor *sensor;
  381. struct resource *res;
  382. void __iomem *base;
  383. int ret;
  384. if (!pdev->dev.of_node) {
  385. dev_err(&pdev->dev, "%s: device tree node not found\n",
  386. __func__);
  387. return -EINVAL;
  388. }
  389. sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
  390. if (!sensor)
  391. return -ENOMEM;
  392. platform_set_drvdata(pdev, sensor);
  393. sensor->dev = &pdev->dev;
  394. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  395. base = devm_ioremap_resource(&pdev->dev, res);
  396. if (IS_ERR(base))
  397. return PTR_ERR(base);
  398. /* Populate sensor */
  399. sensor->base = base;
  400. sensor->clk = devm_clk_get(&pdev->dev, "pclk");
  401. if (IS_ERR(sensor->clk)) {
  402. dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
  403. __func__);
  404. return PTR_ERR(sensor->clk);
  405. }
  406. stm_disable_irq(sensor);
  407. /* Clear irq flags */
  408. writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
  409. /* Configure and enable HW sensor */
  410. ret = stm_thermal_prepare(sensor);
  411. if (ret) {
  412. dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret);
  413. return ret;
  414. }
  415. ret = stm_sensor_power_on(sensor);
  416. if (ret) {
  417. dev_err(&pdev->dev, "Error power on sensor: %d\n", ret);
  418. return ret;
  419. }
  420. sensor->th_dev = devm_thermal_of_zone_register(&pdev->dev, 0,
  421. sensor,
  422. &stm_tz_ops);
  423. if (IS_ERR(sensor->th_dev)) {
  424. dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
  425. __func__);
  426. ret = PTR_ERR(sensor->th_dev);
  427. return ret;
  428. }
  429. /* Register IRQ into GIC */
  430. ret = stm_register_irq(sensor);
  431. if (ret)
  432. goto err_tz;
  433. stm_enable_irq(sensor);
  434. /*
  435. * Thermal_zone doesn't enable hwmon as default,
  436. * enable it here
  437. */
  438. sensor->th_dev->tzp->no_hwmon = false;
  439. ret = thermal_add_hwmon_sysfs(sensor->th_dev);
  440. if (ret)
  441. goto err_tz;
  442. dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
  443. __func__);
  444. return 0;
  445. err_tz:
  446. return ret;
  447. }
  448. static int stm_thermal_remove(struct platform_device *pdev)
  449. {
  450. struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
  451. stm_thermal_sensor_off(sensor);
  452. thermal_remove_hwmon_sysfs(sensor->th_dev);
  453. return 0;
  454. }
  455. static struct platform_driver stm_thermal_driver = {
  456. .driver = {
  457. .name = "stm_thermal",
  458. .pm = &stm_thermal_pm_ops,
  459. .of_match_table = stm_thermal_of_match,
  460. },
  461. .probe = stm_thermal_probe,
  462. .remove = stm_thermal_remove,
  463. };
  464. module_platform_driver(stm_thermal_driver);
  465. MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
  466. MODULE_AUTHOR("David Hernandez Sanchez <[email protected]>");
  467. MODULE_LICENSE("GPL v2");
  468. MODULE_ALIAS("platform:stm_thermal");