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