1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2025 NXP. 4 */ 5 6 #include <linux/bitfield.h> 7 #include <linux/clk.h> 8 #include <linux/err.h> 9 #include <linux/interrupt.h> 10 #include <linux/iopoll.h> 11 #include <linux/nvmem-consumer.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/of_device.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/thermal.h> 18 #include <linux/units.h> 19 20 #include "thermal_hwmon.h" 21 22 #define REG_SET 0x4 23 #define REG_CLR 0x8 24 #define REG_TOG 0xc 25 26 #define IMX91_TMU_CTRL0 0x0 27 #define IMX91_TMU_CTRL0_THR1_IE BIT(9) 28 #define IMX91_TMU_CTRL0_THR1_MASK GENMASK(3, 2) 29 #define IMX91_TMU_CTRL0_CLR_FLT1 BIT(21) 30 31 #define IMX91_TMU_THR_MODE_LE 0 32 #define IMX91_TMU_THR_MODE_GE 1 33 34 #define IMX91_TMU_STAT0 0x10 35 #define IMX91_TMU_STAT0_THR1_IF BIT(9) 36 #define IMX91_TMU_STAT0_THR1_STAT BIT(13) 37 #define IMX91_TMU_STAT0_DRDY0_IF_MASK BIT(16) 38 39 #define IMX91_TMU_DATA0 0x20 40 41 #define IMX91_TMU_CTRL1 0x200 42 #define IMX91_TMU_CTRL1_EN BIT(31) 43 #define IMX91_TMU_CTRL1_START BIT(30) 44 #define IMX91_TMU_CTRL1_STOP BIT(29) 45 #define IMX91_TMU_CTRL1_RES_MASK GENMASK(19, 18) 46 #define IMX91_TMU_CTRL1_MEAS_MODE_MASK GENMASK(25, 24) 47 #define IMX91_TMU_CTRL1_MEAS_MODE_SINGLE 0 48 #define IMX91_TMU_CTRL1_MEAS_MODE_CONTINUES 1 49 #define IMX91_TMU_CTRL1_MEAS_MODE_PERIODIC 2 50 51 #define IMX91_TMU_THR_CTRL01 0x30 52 #define IMX91_TMU_THR_CTRL01_THR1_MASK GENMASK(31, 16) 53 54 #define IMX91_TMU_REF_DIV 0x280 55 #define IMX91_TMU_DIV_EN BIT(31) 56 #define IMX91_TMU_DIV_MASK GENMASK(23, 16) 57 #define IMX91_TMU_DIV_MAX 255 58 59 #define IMX91_TMU_PUD_ST_CTRL 0x2b0 60 #define IMX91_TMU_PUDL_MASK GENMASK(23, 16) 61 62 #define IMX91_TMU_TRIM1 0x2e0 63 #define IMX91_TMU_TRIM2 0x2f0 64 65 #define IMX91_TMU_TEMP_LOW_LIMIT -40000 66 #define IMX91_TMU_TEMP_HIGH_LIMIT 125000 67 68 #define IMX91_TMU_DEFAULT_TRIM1_CONFIG 0xb561bc2d 69 #define IMX91_TMU_DEFAULT_TRIM2_CONFIG 0x65d4 70 71 #define IMX91_TMU_PERIOD_CTRL 0x270 72 #define IMX91_TMU_PERIOD_CTRL_MEAS_MASK GENMASK(23, 0) 73 74 #define IMX91_TMP_FRAC 64 75 76 struct imx91_tmu { 77 void __iomem *base; 78 struct clk *clk; 79 struct device *dev; 80 struct thermal_zone_device *tzd; 81 }; 82 83 static void imx91_tmu_start(struct imx91_tmu *tmu, bool start) 84 { 85 u32 val = start ? IMX91_TMU_CTRL1_START : IMX91_TMU_CTRL1_STOP; 86 87 writel_relaxed(val, tmu->base + IMX91_TMU_CTRL1 + REG_SET); 88 } 89 90 static void imx91_tmu_enable(struct imx91_tmu *tmu, bool enable) 91 { 92 u32 reg = IMX91_TMU_CTRL1; 93 94 reg += enable ? REG_SET : REG_CLR; 95 96 writel_relaxed(IMX91_TMU_CTRL1_EN, tmu->base + reg); 97 } 98 99 static int imx91_tmu_to_mcelsius(int x) 100 { 101 return x * MILLIDEGREE_PER_DEGREE / IMX91_TMP_FRAC; 102 } 103 104 static int imx91_tmu_from_mcelsius(int x) 105 { 106 return x * IMX91_TMP_FRAC / MILLIDEGREE_PER_DEGREE; 107 } 108 109 static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp) 110 { 111 struct imx91_tmu *tmu = thermal_zone_device_priv(tz); 112 s16 data; 113 114 /* DATA0 is 16bit signed number */ 115 data = readw_relaxed(tmu->base + IMX91_TMU_DATA0); 116 *temp = imx91_tmu_to_mcelsius(data); 117 118 return 0; 119 } 120 121 static int imx91_tmu_set_trips(struct thermal_zone_device *tz, int low, int high) 122 { 123 struct imx91_tmu *tmu = thermal_zone_device_priv(tz); 124 int val; 125 126 if (high >= IMX91_TMU_TEMP_HIGH_LIMIT) 127 return -EINVAL; 128 129 writel_relaxed(IMX91_TMU_CTRL0_THR1_IE, tmu->base + IMX91_TMU_CTRL0 + REG_CLR); 130 131 /* Comparator1 for temperature threshold */ 132 writel_relaxed(IMX91_TMU_THR_CTRL01_THR1_MASK, tmu->base + IMX91_TMU_THR_CTRL01 + REG_CLR); 133 val = FIELD_PREP(IMX91_TMU_THR_CTRL01_THR1_MASK, imx91_tmu_from_mcelsius(high)); 134 135 writel_relaxed(val, tmu->base + IMX91_TMU_THR_CTRL01 + REG_SET); 136 137 writel_relaxed(IMX91_TMU_STAT0_THR1_IF, tmu->base + IMX91_TMU_STAT0 + REG_CLR); 138 139 writel_relaxed(IMX91_TMU_CTRL0_THR1_IE, tmu->base + IMX91_TMU_CTRL0 + REG_SET); 140 141 return 0; 142 } 143 144 static int imx91_init_from_nvmem_cells(struct imx91_tmu *tmu) 145 { 146 struct device *dev = tmu->dev; 147 u32 trim1, trim2; 148 int ret; 149 150 ret = nvmem_cell_read_u32(dev, "trim1", &trim1); 151 if (ret) 152 return ret; 153 154 ret = nvmem_cell_read_u32(dev, "trim2", &trim2); 155 if (ret) 156 return ret; 157 158 if (trim1 == 0 || trim2 == 0) 159 return -EINVAL; 160 161 writel_relaxed(trim1, tmu->base + IMX91_TMU_TRIM1); 162 writel_relaxed(trim2, tmu->base + IMX91_TMU_TRIM2); 163 164 return 0; 165 } 166 167 static void imx91_tmu_action_remove(void *data) 168 { 169 struct imx91_tmu *tmu = data; 170 171 /* disable tmu */ 172 imx91_tmu_enable(tmu, false); 173 } 174 175 static irqreturn_t imx91_tmu_alarm_irq(int irq, void *data) 176 { 177 struct imx91_tmu *tmu = data; 178 u32 val; 179 180 val = readl_relaxed(tmu->base + IMX91_TMU_STAT0); 181 182 /* Check if comparison interrupt occurred */ 183 if (val & IMX91_TMU_STAT0_THR1_IF) { 184 /* Clear irq flag and disable interrupt until reconfigured */ 185 writel(IMX91_TMU_STAT0_THR1_IF, tmu->base + IMX91_TMU_STAT0 + REG_CLR); 186 writel_relaxed(IMX91_TMU_CTRL0_THR1_IE, tmu->base + IMX91_TMU_CTRL0 + REG_CLR); 187 188 return IRQ_WAKE_THREAD; 189 } 190 191 return IRQ_NONE; 192 } 193 194 static irqreturn_t imx91_tmu_alarm_irq_thread(int irq, void *data) 195 { 196 struct imx91_tmu *tmu = data; 197 198 thermal_zone_device_update(tmu->tzd, THERMAL_EVENT_UNSPECIFIED); 199 200 return IRQ_HANDLED; 201 } 202 203 static int imx91_tmu_change_mode(struct thermal_zone_device *tz, enum thermal_device_mode mode) 204 { 205 struct imx91_tmu *tmu = thermal_zone_device_priv(tz); 206 int ret; 207 208 if (mode == THERMAL_DEVICE_ENABLED) { 209 ret = pm_runtime_get(tmu->dev); 210 if (ret < 0) 211 return ret; 212 213 writel_relaxed(IMX91_TMU_CTRL0_THR1_IE | IMX91_TMU_CTRL0_THR1_MASK, 214 tmu->base + IMX91_TMU_CTRL0 + REG_CLR); 215 216 writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL0_THR1_MASK, IMX91_TMU_THR_MODE_GE), 217 tmu->base + IMX91_TMU_CTRL0 + REG_SET); 218 imx91_tmu_start(tmu, true); 219 } else { 220 writel_relaxed(IMX91_TMU_CTRL0_THR1_IE, tmu->base + IMX91_TMU_CTRL0 + REG_CLR); 221 imx91_tmu_start(tmu, false); 222 pm_runtime_put(tmu->dev); 223 } 224 225 return 0; 226 } 227 228 static struct thermal_zone_device_ops tmu_tz_ops = { 229 .get_temp = imx91_tmu_get_temp, 230 .change_mode = imx91_tmu_change_mode, 231 .set_trips = imx91_tmu_set_trips, 232 }; 233 234 static int imx91_tmu_probe(struct platform_device *pdev) 235 { 236 struct device *dev = &pdev->dev; 237 struct imx91_tmu *tmu; 238 unsigned long rate; 239 int irq, ret; 240 u32 div; 241 242 tmu = devm_kzalloc(dev, sizeof(struct imx91_tmu), GFP_KERNEL); 243 if (!tmu) 244 return -ENOMEM; 245 246 tmu->dev = dev; 247 248 tmu->base = devm_platform_ioremap_resource(pdev, 0); 249 if (IS_ERR(tmu->base)) 250 return dev_err_probe(dev, PTR_ERR(tmu->base), "failed to get io resource"); 251 252 tmu->clk = devm_clk_get_enabled(dev, NULL); 253 if (IS_ERR(tmu->clk)) 254 return dev_err_probe(dev, PTR_ERR(tmu->clk), "failed to get tmu clock\n"); 255 256 platform_set_drvdata(pdev, tmu); 257 258 /* disable the monitor during initialization */ 259 imx91_tmu_enable(tmu, false); 260 imx91_tmu_start(tmu, false); 261 262 ret = imx91_init_from_nvmem_cells(tmu); 263 if (ret) { 264 dev_warn(dev, "can't get trim value, use default settings\n"); 265 266 writel_relaxed(IMX91_TMU_DEFAULT_TRIM1_CONFIG, tmu->base + IMX91_TMU_TRIM1); 267 writel_relaxed(IMX91_TMU_DEFAULT_TRIM2_CONFIG, tmu->base + IMX91_TMU_TRIM2); 268 } 269 270 /* The typical conv clk is 4MHz, the output freq is 'rate / (div + 1)' */ 271 rate = clk_get_rate(tmu->clk); 272 div = (rate / (4 * HZ_PER_MHZ)) - 1; 273 if (div > IMX91_TMU_DIV_MAX) 274 return dev_err_probe(dev, -EINVAL, "clock divider exceed hardware limitation"); 275 276 /* Set divider value and enable divider */ 277 writel_relaxed(IMX91_TMU_DIV_EN | FIELD_PREP(IMX91_TMU_DIV_MASK, div), 278 tmu->base + IMX91_TMU_REF_DIV); 279 280 /* Set max power up delay: 'Tpud(ms) = 0xFF * 1000 / 4000000' */ 281 writel_relaxed(FIELD_PREP(IMX91_TMU_PUDL_MASK, 100U), tmu->base + IMX91_TMU_PUD_ST_CTRL); 282 283 /* 284 * Set resolution mode 285 * 00b - Conversion time = 0.59325 ms 286 * 01b - Conversion time = 1.10525 ms 287 * 10b - Conversion time = 2.12925 ms 288 * 11b - Conversion time = 4.17725 ms 289 */ 290 writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x3), 291 tmu->base + IMX91_TMU_CTRL1 + REG_CLR); 292 writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_RES_MASK, 0x1), 293 tmu->base + IMX91_TMU_CTRL1 + REG_SET); 294 295 writel_relaxed(IMX91_TMU_CTRL1_MEAS_MODE_MASK, tmu->base + IMX91_TMU_CTRL1 + REG_CLR); 296 writel_relaxed(FIELD_PREP(IMX91_TMU_CTRL1_MEAS_MODE_MASK, 297 IMX91_TMU_CTRL1_MEAS_MODE_PERIODIC), 298 tmu->base + IMX91_TMU_CTRL1 + REG_SET); 299 300 /* 301 * Set Periodic Measurement Frequency to 25Hz: 302 * tMEAS_FREQ = tCONV_CLK * PERIOD_CTRL[MEAS_FREQ] 303 */ 304 writel_relaxed(FIELD_PREP(IMX91_TMU_PERIOD_CTRL_MEAS_MASK, 4 * HZ_PER_MHZ / 25), 305 tmu->base + IMX91_TMU_PERIOD_CTRL); 306 307 imx91_tmu_enable(tmu, true); 308 ret = devm_add_action(dev, imx91_tmu_action_remove, tmu); 309 if (ret) 310 return dev_err_probe(dev, ret, "Failure to add action imx91_tmu_action_remove()\n"); 311 312 pm_runtime_set_active(dev); 313 pm_runtime_get_noresume(dev); 314 ret = devm_pm_runtime_enable(dev); 315 if (ret) 316 return ret; 317 318 tmu->tzd = devm_thermal_of_zone_register(dev, 0, tmu, &tmu_tz_ops); 319 if (IS_ERR(tmu->tzd)) 320 return dev_err_probe(dev, PTR_ERR(tmu->tzd), 321 "failed to register thermal zone sensor\n"); 322 323 devm_thermal_add_hwmon_sysfs(dev, tmu->tzd); 324 325 irq = platform_get_irq(pdev, 0); 326 if (irq < 0) 327 return irq; 328 329 ret = devm_request_threaded_irq(dev, irq, imx91_tmu_alarm_irq, 330 imx91_tmu_alarm_irq_thread, 331 IRQF_ONESHOT, "imx91_thermal", tmu); 332 333 if (ret < 0) 334 return dev_err_probe(dev, ret, "failed to request alarm irq\n"); 335 336 pm_runtime_put(dev); 337 338 return 0; 339 } 340 341 static int imx91_tmu_runtime_suspend(struct device *dev) 342 { 343 struct imx91_tmu *tmu = dev_get_drvdata(dev); 344 345 /* disable tmu */ 346 imx91_tmu_enable(tmu, false); 347 348 clk_disable_unprepare(tmu->clk); 349 350 return 0; 351 } 352 353 static int imx91_tmu_runtime_resume(struct device *dev) 354 { 355 struct imx91_tmu *tmu = dev_get_drvdata(dev); 356 int ret; 357 358 ret = clk_prepare_enable(tmu->clk); 359 if (ret) 360 return ret; 361 362 imx91_tmu_enable(tmu, true); 363 364 return 0; 365 } 366 367 static DEFINE_RUNTIME_DEV_PM_OPS(imx91_tmu_pm_ops, imx91_tmu_runtime_suspend, 368 imx91_tmu_runtime_resume, NULL); 369 370 static const struct of_device_id imx91_tmu_table[] = { 371 { .compatible = "fsl,imx91-tmu", }, 372 { }, 373 }; 374 MODULE_DEVICE_TABLE(of, imx91_tmu_table); 375 376 static struct platform_driver imx91_tmu = { 377 .driver = { 378 .name = "imx91_thermal", 379 .pm = pm_ptr(&imx91_tmu_pm_ops), 380 .of_match_table = imx91_tmu_table, 381 }, 382 .probe = imx91_tmu_probe, 383 }; 384 module_platform_driver(imx91_tmu); 385 386 MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); 387 MODULE_DESCRIPTION("i.MX91 Thermal Monitor Unit driver"); 388 MODULE_LICENSE("GPL"); 389