Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
0004  * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for
0005  * STMicroelectronics.
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/delay.h>
0011 #include <linux/err.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/iopoll.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/of_address.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/thermal.h>
0021 
0022 #include "../thermal_core.h"
0023 #include "../thermal_hwmon.h"
0024 
0025 /* DTS register offsets */
0026 #define DTS_CFGR1_OFFSET    0x0
0027 #define DTS_T0VALR1_OFFSET  0x8
0028 #define DTS_RAMPVALR_OFFSET 0X10
0029 #define DTS_ITR1_OFFSET     0x14
0030 #define DTS_DR_OFFSET       0x1C
0031 #define DTS_SR_OFFSET       0x20
0032 #define DTS_ITENR_OFFSET    0x24
0033 #define DTS_ICIFR_OFFSET    0x28
0034 
0035 /* DTS_CFGR1 register mask definitions */
0036 #define HSREF_CLK_DIV_MASK  GENMASK(30, 24)
0037 #define TS1_SMP_TIME_MASK   GENMASK(19, 16)
0038 #define TS1_INTRIG_SEL_MASK GENMASK(11, 8)
0039 
0040 /* DTS_T0VALR1 register mask definitions */
0041 #define TS1_T0_MASK     GENMASK(17, 16)
0042 #define TS1_FMT0_MASK       GENMASK(15, 0)
0043 
0044 /* DTS_RAMPVALR register mask definitions */
0045 #define TS1_RAMP_COEFF_MASK GENMASK(15, 0)
0046 
0047 /* DTS_ITR1 register mask definitions */
0048 #define TS1_HITTHD_MASK     GENMASK(31, 16)
0049 #define TS1_LITTHD_MASK     GENMASK(15, 0)
0050 
0051 /* DTS_DR register mask definitions */
0052 #define TS1_MFREQ_MASK      GENMASK(15, 0)
0053 
0054 /* DTS_ITENR register mask definitions */
0055 #define ITENR_MASK      (GENMASK(2, 0) | GENMASK(6, 4))
0056 
0057 /* DTS_ICIFR register mask definitions */
0058 #define ICIFR_MASK      (GENMASK(2, 0) | GENMASK(6, 4))
0059 
0060 /* Less significant bit position definitions */
0061 #define TS1_T0_POS      16
0062 #define TS1_HITTHD_POS      16
0063 #define TS1_LITTHD_POS      0
0064 #define HSREF_CLK_DIV_POS   24
0065 
0066 /* DTS_CFGR1 bit definitions */
0067 #define TS1_EN          BIT(0)
0068 #define TS1_START       BIT(4)
0069 #define REFCLK_SEL      BIT(20)
0070 #define REFCLK_LSE      REFCLK_SEL
0071 #define Q_MEAS_OPT      BIT(21)
0072 #define CALIBRATION_CONTROL Q_MEAS_OPT
0073 
0074 /* DTS_SR bit definitions */
0075 #define TS_RDY          BIT(15)
0076 /* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
0077 #define HIGH_THRESHOLD      BIT(2)
0078 #define LOW_THRESHOLD       BIT(1)
0079 
0080 /* Constants */
0081 #define ADJUST          100
0082 #define ONE_MHZ         1000000
0083 #define POLL_TIMEOUT        5000
0084 #define STARTUP_TIME        40
0085 #define TS1_T0_VAL0     30000  /* 30 celsius */
0086 #define TS1_T0_VAL1     130000 /* 130 celsius */
0087 #define NO_HW_TRIG      0
0088 #define SAMPLING_TIME       15
0089 
0090 struct stm_thermal_sensor {
0091     struct device *dev;
0092     struct thermal_zone_device *th_dev;
0093     enum thermal_device_mode mode;
0094     struct clk *clk;
0095     unsigned int low_temp_enabled;
0096     unsigned int high_temp_enabled;
0097     int irq;
0098     void __iomem *base;
0099     int t0, fmt0, ramp_coeff;
0100 };
0101 
0102 static int stm_enable_irq(struct stm_thermal_sensor *sensor)
0103 {
0104     u32 value;
0105 
0106     dev_dbg(sensor->dev, "low:%d high:%d\n", sensor->low_temp_enabled,
0107         sensor->high_temp_enabled);
0108 
0109     /* Disable IT generation for low and high thresholds */
0110     value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
0111     value &= ~(LOW_THRESHOLD | HIGH_THRESHOLD);
0112 
0113     if (sensor->low_temp_enabled)
0114         value |= HIGH_THRESHOLD;
0115 
0116     if (sensor->high_temp_enabled)
0117         value |= LOW_THRESHOLD;
0118 
0119     /* Enable interrupts */
0120     writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
0121 
0122     return 0;
0123 }
0124 
0125 static irqreturn_t stm_thermal_irq_handler(int irq, void *sdata)
0126 {
0127     struct stm_thermal_sensor *sensor = sdata;
0128 
0129     dev_dbg(sensor->dev, "sr:%d\n",
0130         readl_relaxed(sensor->base + DTS_SR_OFFSET));
0131 
0132     thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
0133 
0134     stm_enable_irq(sensor);
0135 
0136     /* Acknoledge all DTS irqs */
0137     writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
0138 
0139     return IRQ_HANDLED;
0140 }
0141 
0142 static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
0143 {
0144     int ret;
0145     u32 value;
0146 
0147     /* Enable sensor */
0148     value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
0149     value |= TS1_EN;
0150     writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
0151 
0152     /*
0153      * The DTS block can be enabled by setting TSx_EN bit in
0154      * DTS_CFGRx register. It requires a startup time of
0155      * 40μs. Use 5 ms as arbitrary timeout.
0156      */
0157     ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
0158                  value, (value & TS_RDY),
0159                  STARTUP_TIME, POLL_TIMEOUT);
0160     if (ret)
0161         return ret;
0162 
0163     /* Start continuous measuring */
0164     value = readl_relaxed(sensor->base +
0165                   DTS_CFGR1_OFFSET);
0166     value |= TS1_START;
0167     writel_relaxed(value, sensor->base +
0168                DTS_CFGR1_OFFSET);
0169 
0170     sensor->mode = THERMAL_DEVICE_ENABLED;
0171 
0172     return 0;
0173 }
0174 
0175 static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
0176 {
0177     u32 value;
0178 
0179     sensor->mode = THERMAL_DEVICE_DISABLED;
0180 
0181     /* Stop measuring */
0182     value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
0183     value &= ~TS1_START;
0184     writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
0185 
0186     /* Ensure stop is taken into account */
0187     usleep_range(STARTUP_TIME, POLL_TIMEOUT);
0188 
0189     /* Disable sensor */
0190     value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
0191     value &= ~TS1_EN;
0192     writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
0193 
0194     /* Ensure disable is taken into account */
0195     return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
0196                   !(value & TS_RDY),
0197                   STARTUP_TIME, POLL_TIMEOUT);
0198 }
0199 
0200 static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
0201 {
0202     u32 value, clk_freq;
0203     u32 prescaler;
0204 
0205     /* Figure out prescaler value for PCLK during calibration */
0206     clk_freq = clk_get_rate(sensor->clk);
0207     if (!clk_freq)
0208         return -EINVAL;
0209 
0210     prescaler = 0;
0211     clk_freq /= ONE_MHZ;
0212     if (clk_freq) {
0213         while (prescaler <= clk_freq)
0214             prescaler++;
0215     }
0216 
0217     value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
0218 
0219     /* Clear prescaler */
0220     value &= ~HSREF_CLK_DIV_MASK;
0221 
0222     /* Set prescaler. pclk_freq/prescaler < 1MHz */
0223     value |= (prescaler << HSREF_CLK_DIV_POS);
0224 
0225     /* Select PCLK as reference clock */
0226     value &= ~REFCLK_SEL;
0227 
0228     /* Set maximal sampling time for better precision */
0229     value |= TS1_SMP_TIME_MASK;
0230 
0231     /* Measure with calibration */
0232     value &= ~CALIBRATION_CONTROL;
0233 
0234     /* select trigger */
0235     value &= ~TS1_INTRIG_SEL_MASK;
0236     value |= NO_HW_TRIG;
0237 
0238     writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
0239 
0240     return 0;
0241 }
0242 
0243 /* Fill in DTS structure with factory sensor values */
0244 static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
0245 {
0246     /* Retrieve engineering calibration temperature */
0247     sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
0248                     TS1_T0_MASK;
0249     if (!sensor->t0)
0250         sensor->t0 = TS1_T0_VAL0;
0251     else
0252         sensor->t0 = TS1_T0_VAL1;
0253 
0254     /* Retrieve fmt0 and put it on Hz */
0255     sensor->fmt0 = ADJUST * (readl_relaxed(sensor->base +
0256                  DTS_T0VALR1_OFFSET) & TS1_FMT0_MASK);
0257 
0258     /* Retrieve ramp coefficient */
0259     sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
0260                        TS1_RAMP_COEFF_MASK;
0261 
0262     if (!sensor->fmt0 || !sensor->ramp_coeff) {
0263         dev_err(sensor->dev, "%s: wrong setting\n", __func__);
0264         return -EINVAL;
0265     }
0266 
0267     dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
0268         __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
0269 
0270     return 0;
0271 }
0272 
0273 static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
0274                        int temp, u32 *th)
0275 {
0276     int freqM;
0277 
0278     /* Figure out the CLK_PTAT frequency for a given temperature */
0279     freqM = ((temp - sensor->t0) * sensor->ramp_coeff) / 1000 +
0280         sensor->fmt0;
0281 
0282     /* Figure out the threshold sample number */
0283     *th = clk_get_rate(sensor->clk) * SAMPLING_TIME / freqM;
0284     if (!*th)
0285         return -EINVAL;
0286 
0287     dev_dbg(sensor->dev, "freqM=%d Hz, threshold=0x%x", freqM, *th);
0288 
0289     return 0;
0290 }
0291 
0292 /* Disable temperature interrupt */
0293 static int stm_disable_irq(struct stm_thermal_sensor *sensor)
0294 {
0295     u32 value;
0296 
0297     /* Disable IT generation */
0298     value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
0299     value &= ~ITENR_MASK;
0300     writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
0301 
0302     return 0;
0303 }
0304 
0305 static int stm_thermal_set_trips(void *data, int low, int high)
0306 {
0307     struct stm_thermal_sensor *sensor = data;
0308     u32 itr1, th;
0309     int ret;
0310 
0311     dev_dbg(sensor->dev, "set trips %d <--> %d\n", low, high);
0312 
0313     /* Erase threshold content */
0314     itr1 = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
0315     itr1 &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
0316 
0317     /*
0318      * Disable low-temp if "low" is too small. As per thermal framework
0319      * API, we use -INT_MAX rather than INT_MIN.
0320      */
0321 
0322     if (low > -INT_MAX) {
0323         sensor->low_temp_enabled = 1;
0324         /* add 0.5 of hysteresis due to measurement error */
0325         ret = stm_thermal_calculate_threshold(sensor, low - 500, &th);
0326         if (ret)
0327             return ret;
0328 
0329         itr1 |= (TS1_HITTHD_MASK  & (th << TS1_HITTHD_POS));
0330     } else {
0331         sensor->low_temp_enabled = 0;
0332     }
0333 
0334     /* Disable high-temp if "high" is too big. */
0335     if (high < INT_MAX) {
0336         sensor->high_temp_enabled = 1;
0337         ret = stm_thermal_calculate_threshold(sensor, high, &th);
0338         if (ret)
0339             return ret;
0340 
0341         itr1 |= (TS1_LITTHD_MASK  & (th << TS1_LITTHD_POS));
0342     } else {
0343         sensor->high_temp_enabled = 0;
0344     }
0345 
0346     /* Write new threshod values*/
0347     writel_relaxed(itr1, sensor->base + DTS_ITR1_OFFSET);
0348 
0349     return 0;
0350 }
0351 
0352 /* Callback to get temperature from HW */
0353 static int stm_thermal_get_temp(void *data, int *temp)
0354 {
0355     struct stm_thermal_sensor *sensor = data;
0356     u32 periods;
0357     int freqM, ret;
0358 
0359     if (sensor->mode != THERMAL_DEVICE_ENABLED)
0360         return -EAGAIN;
0361 
0362     /* Retrieve the number of periods sampled */
0363     ret = readl_relaxed_poll_timeout(sensor->base + DTS_DR_OFFSET, periods,
0364                      (periods & TS1_MFREQ_MASK),
0365                      STARTUP_TIME, POLL_TIMEOUT);
0366     if (ret)
0367         return ret;
0368 
0369     /* Figure out the CLK_PTAT frequency */
0370     freqM = (clk_get_rate(sensor->clk) * SAMPLING_TIME) / periods;
0371     if (!freqM)
0372         return -EINVAL;
0373 
0374     /* Figure out the temperature in mili celsius */
0375     *temp = (freqM - sensor->fmt0) * 1000 / sensor->ramp_coeff + sensor->t0;
0376 
0377     return 0;
0378 }
0379 
0380 /* Registers DTS irq to be visible by GIC */
0381 static int stm_register_irq(struct stm_thermal_sensor *sensor)
0382 {
0383     struct device *dev = sensor->dev;
0384     struct platform_device *pdev = to_platform_device(dev);
0385     int ret;
0386 
0387     sensor->irq = platform_get_irq(pdev, 0);
0388     if (sensor->irq < 0)
0389         return sensor->irq;
0390 
0391     ret = devm_request_threaded_irq(dev, sensor->irq,
0392                     NULL,
0393                     stm_thermal_irq_handler,
0394                     IRQF_ONESHOT,
0395                     dev->driver->name, sensor);
0396     if (ret) {
0397         dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
0398             sensor->irq);
0399         return ret;
0400     }
0401 
0402     dev_dbg(dev, "%s: thermal IRQ registered", __func__);
0403 
0404     return 0;
0405 }
0406 
0407 static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
0408 {
0409     int ret;
0410 
0411     stm_disable_irq(sensor);
0412 
0413     ret = stm_sensor_power_off(sensor);
0414     if (ret)
0415         return ret;
0416 
0417     clk_disable_unprepare(sensor->clk);
0418 
0419     return 0;
0420 }
0421 
0422 static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
0423 {
0424     int ret;
0425 
0426     ret = clk_prepare_enable(sensor->clk);
0427     if (ret)
0428         return ret;
0429 
0430     ret = stm_thermal_read_factory_settings(sensor);
0431     if (ret)
0432         goto thermal_unprepare;
0433 
0434     ret = stm_thermal_calibration(sensor);
0435     if (ret)
0436         goto thermal_unprepare;
0437 
0438     return 0;
0439 
0440 thermal_unprepare:
0441     clk_disable_unprepare(sensor->clk);
0442 
0443     return ret;
0444 }
0445 
0446 #ifdef CONFIG_PM_SLEEP
0447 static int stm_thermal_suspend(struct device *dev)
0448 {
0449     struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
0450 
0451     return stm_thermal_sensor_off(sensor);
0452 }
0453 
0454 static int stm_thermal_resume(struct device *dev)
0455 {
0456     int ret;
0457     struct stm_thermal_sensor *sensor = dev_get_drvdata(dev);
0458 
0459     ret = stm_thermal_prepare(sensor);
0460     if (ret)
0461         return ret;
0462 
0463     ret = stm_sensor_power_on(sensor);
0464     if (ret)
0465         return ret;
0466 
0467     thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
0468     stm_enable_irq(sensor);
0469 
0470     return 0;
0471 }
0472 #endif /* CONFIG_PM_SLEEP */
0473 
0474 static SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops,
0475              stm_thermal_suspend, stm_thermal_resume);
0476 
0477 static const struct thermal_zone_of_device_ops stm_tz_ops = {
0478     .get_temp   = stm_thermal_get_temp,
0479     .set_trips  = stm_thermal_set_trips,
0480 };
0481 
0482 static const struct of_device_id stm_thermal_of_match[] = {
0483         { .compatible = "st,stm32-thermal"},
0484     { /* sentinel */ }
0485 };
0486 MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
0487 
0488 static int stm_thermal_probe(struct platform_device *pdev)
0489 {
0490     struct stm_thermal_sensor *sensor;
0491     struct resource *res;
0492     void __iomem *base;
0493     int ret;
0494 
0495     if (!pdev->dev.of_node) {
0496         dev_err(&pdev->dev, "%s: device tree node not found\n",
0497             __func__);
0498         return -EINVAL;
0499     }
0500 
0501     sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
0502     if (!sensor)
0503         return -ENOMEM;
0504 
0505     platform_set_drvdata(pdev, sensor);
0506 
0507     sensor->dev = &pdev->dev;
0508 
0509     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0510     base = devm_ioremap_resource(&pdev->dev, res);
0511     if (IS_ERR(base))
0512         return PTR_ERR(base);
0513 
0514     /* Populate sensor */
0515     sensor->base = base;
0516 
0517     sensor->clk = devm_clk_get(&pdev->dev, "pclk");
0518     if (IS_ERR(sensor->clk)) {
0519         dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
0520             __func__);
0521         return PTR_ERR(sensor->clk);
0522     }
0523 
0524     stm_disable_irq(sensor);
0525 
0526     /* Clear irq flags */
0527     writel_relaxed(ICIFR_MASK, sensor->base + DTS_ICIFR_OFFSET);
0528 
0529     /* Configure and enable HW sensor */
0530     ret = stm_thermal_prepare(sensor);
0531     if (ret) {
0532         dev_err(&pdev->dev, "Error prepare sensor: %d\n", ret);
0533         return ret;
0534     }
0535 
0536     ret = stm_sensor_power_on(sensor);
0537     if (ret) {
0538         dev_err(&pdev->dev, "Error power on sensor: %d\n", ret);
0539         return ret;
0540     }
0541 
0542     sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
0543                                   sensor,
0544                                   &stm_tz_ops);
0545 
0546     if (IS_ERR(sensor->th_dev)) {
0547         dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
0548             __func__);
0549         ret = PTR_ERR(sensor->th_dev);
0550         return ret;
0551     }
0552 
0553     /* Register IRQ into GIC */
0554     ret = stm_register_irq(sensor);
0555     if (ret)
0556         goto err_tz;
0557 
0558     stm_enable_irq(sensor);
0559 
0560     /*
0561      * Thermal_zone doesn't enable hwmon as default,
0562      * enable it here
0563      */
0564     sensor->th_dev->tzp->no_hwmon = false;
0565     ret = thermal_add_hwmon_sysfs(sensor->th_dev);
0566     if (ret)
0567         goto err_tz;
0568 
0569     dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
0570          __func__);
0571 
0572     return 0;
0573 
0574 err_tz:
0575     thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
0576     return ret;
0577 }
0578 
0579 static int stm_thermal_remove(struct platform_device *pdev)
0580 {
0581     struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
0582 
0583     stm_thermal_sensor_off(sensor);
0584     thermal_remove_hwmon_sysfs(sensor->th_dev);
0585     thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
0586 
0587     return 0;
0588 }
0589 
0590 static struct platform_driver stm_thermal_driver = {
0591     .driver = {
0592         .name   = "stm_thermal",
0593         .pm     = &stm_thermal_pm_ops,
0594         .of_match_table = stm_thermal_of_match,
0595     },
0596     .probe      = stm_thermal_probe,
0597     .remove     = stm_thermal_remove,
0598 };
0599 module_platform_driver(stm_thermal_driver);
0600 
0601 MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
0602 MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
0603 MODULE_LICENSE("GPL v2");
0604 MODULE_ALIAS("platform:stm_thermal");