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