1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright 2016 Freescale Semiconductor, Inc. 4 5 #include <linux/module.h> 6 #include <linux/platform_device.h> 7 #include <linux/err.h> 8 #include <linux/io.h> 9 #include <linux/of.h> 10 #include <linux/of_address.h> 11 #include <linux/thermal.h> 12 13 #include "thermal_core.h" 14 15 #define SITES_MAX 16 16 17 /* 18 * QorIQ TMU Registers 19 */ 20 struct qoriq_tmu_site_regs { 21 u32 tritsr; /* Immediate Temperature Site Register */ 22 u32 tratsr; /* Average Temperature Site Register */ 23 u8 res0[0x8]; 24 }; 25 26 struct qoriq_tmu_regs { 27 u32 tmr; /* Mode Register */ 28 #define TMR_DISABLE 0x0 29 #define TMR_ME 0x80000000 30 #define TMR_ALPF 0x0c000000 31 u32 tsr; /* Status Register */ 32 u32 tmtmir; /* Temperature measurement interval Register */ 33 #define TMTMIR_DEFAULT 0x0000000f 34 u8 res0[0x14]; 35 u32 tier; /* Interrupt Enable Register */ 36 #define TIER_DISABLE 0x0 37 u32 tidr; /* Interrupt Detect Register */ 38 u32 tiscr; /* Interrupt Site Capture Register */ 39 u32 ticscr; /* Interrupt Critical Site Capture Register */ 40 u8 res1[0x10]; 41 u32 tmhtcrh; /* High Temperature Capture Register */ 42 u32 tmhtcrl; /* Low Temperature Capture Register */ 43 u8 res2[0x8]; 44 u32 tmhtitr; /* High Temperature Immediate Threshold */ 45 u32 tmhtatr; /* High Temperature Average Threshold */ 46 u32 tmhtactr; /* High Temperature Average Crit Threshold */ 47 u8 res3[0x24]; 48 u32 ttcfgr; /* Temperature Configuration Register */ 49 u32 tscfgr; /* Sensor Configuration Register */ 50 u8 res4[0x78]; 51 struct qoriq_tmu_site_regs site[SITES_MAX]; 52 u8 res5[0x9f8]; 53 u32 ipbrr0; /* IP Block Revision Register 0 */ 54 u32 ipbrr1; /* IP Block Revision Register 1 */ 55 u8 res6[0x310]; 56 u32 ttr0cr; /* Temperature Range 0 Control Register */ 57 u32 ttr1cr; /* Temperature Range 1 Control Register */ 58 u32 ttr2cr; /* Temperature Range 2 Control Register */ 59 u32 ttr3cr; /* Temperature Range 3 Control Register */ 60 }; 61 62 struct qoriq_tmu_data; 63 64 /* 65 * Thermal zone data 66 */ 67 struct qoriq_sensor { 68 struct thermal_zone_device *tzd; 69 struct qoriq_tmu_data *qdata; 70 int id; 71 }; 72 73 struct qoriq_tmu_data { 74 struct qoriq_tmu_regs __iomem *regs; 75 bool little_endian; 76 struct qoriq_sensor *sensor[SITES_MAX]; 77 }; 78 79 static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr) 80 { 81 if (p->little_endian) 82 iowrite32(val, addr); 83 else 84 iowrite32be(val, addr); 85 } 86 87 static u32 tmu_read(struct qoriq_tmu_data *p, void __iomem *addr) 88 { 89 if (p->little_endian) 90 return ioread32(addr); 91 else 92 return ioread32be(addr); 93 } 94 95 static int tmu_get_temp(void *p, int *temp) 96 { 97 struct qoriq_sensor *qsensor = p; 98 struct qoriq_tmu_data *qdata = qsensor->qdata; 99 u32 val; 100 101 val = tmu_read(qdata, &qdata->regs->site[qsensor->id].tritsr); 102 *temp = (val & 0xff) * 1000; 103 104 return 0; 105 } 106 107 static const struct thermal_zone_of_device_ops tmu_tz_ops = { 108 .get_temp = tmu_get_temp, 109 }; 110 111 static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev) 112 { 113 struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev); 114 int id, sites = 0; 115 116 for (id = 0; id < SITES_MAX; id++) { 117 qdata->sensor[id] = devm_kzalloc(&pdev->dev, 118 sizeof(struct qoriq_sensor), GFP_KERNEL); 119 if (!qdata->sensor[id]) 120 return -ENOMEM; 121 122 qdata->sensor[id]->id = id; 123 qdata->sensor[id]->qdata = qdata; 124 qdata->sensor[id]->tzd = devm_thermal_zone_of_sensor_register( 125 &pdev->dev, id, qdata->sensor[id], &tmu_tz_ops); 126 if (IS_ERR(qdata->sensor[id]->tzd)) { 127 if (PTR_ERR(qdata->sensor[id]->tzd) == -ENODEV) 128 continue; 129 else 130 return PTR_ERR(qdata->sensor[id]->tzd); 131 } 132 133 sites |= 0x1 << (15 - id); 134 } 135 136 /* Enable monitoring */ 137 if (sites != 0) 138 tmu_write(qdata, sites | TMR_ME | TMR_ALPF, &qdata->regs->tmr); 139 140 return 0; 141 } 142 143 static int qoriq_tmu_calibration(struct platform_device *pdev) 144 { 145 int i, val, len; 146 u32 range[4]; 147 const u32 *calibration; 148 struct device_node *np = pdev->dev.of_node; 149 struct qoriq_tmu_data *data = platform_get_drvdata(pdev); 150 151 if (of_property_read_u32_array(np, "fsl,tmu-range", range, 4)) { 152 dev_err(&pdev->dev, "missing calibration range.\n"); 153 return -ENODEV; 154 } 155 156 /* Init temperature range registers */ 157 tmu_write(data, range[0], &data->regs->ttr0cr); 158 tmu_write(data, range[1], &data->regs->ttr1cr); 159 tmu_write(data, range[2], &data->regs->ttr2cr); 160 tmu_write(data, range[3], &data->regs->ttr3cr); 161 162 calibration = of_get_property(np, "fsl,tmu-calibration", &len); 163 if (calibration == NULL || len % 8) { 164 dev_err(&pdev->dev, "invalid calibration data.\n"); 165 return -ENODEV; 166 } 167 168 for (i = 0; i < len; i += 8, calibration += 2) { 169 val = of_read_number(calibration, 1); 170 tmu_write(data, val, &data->regs->ttcfgr); 171 val = of_read_number(calibration + 1, 1); 172 tmu_write(data, val, &data->regs->tscfgr); 173 } 174 175 return 0; 176 } 177 178 static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) 179 { 180 /* Disable interrupt, using polling instead */ 181 tmu_write(data, TIER_DISABLE, &data->regs->tier); 182 183 /* Set update_interval */ 184 tmu_write(data, TMTMIR_DEFAULT, &data->regs->tmtmir); 185 186 /* Disable monitoring */ 187 tmu_write(data, TMR_DISABLE, &data->regs->tmr); 188 } 189 190 static int qoriq_tmu_probe(struct platform_device *pdev) 191 { 192 int ret; 193 struct qoriq_tmu_data *data; 194 struct device_node *np = pdev->dev.of_node; 195 196 data = devm_kzalloc(&pdev->dev, sizeof(struct qoriq_tmu_data), 197 GFP_KERNEL); 198 if (!data) 199 return -ENOMEM; 200 201 platform_set_drvdata(pdev, data); 202 203 data->little_endian = of_property_read_bool(np, "little-endian"); 204 205 data->regs = of_iomap(np, 0); 206 if (!data->regs) { 207 dev_err(&pdev->dev, "Failed to get memory region\n"); 208 ret = -ENODEV; 209 goto err_iomap; 210 } 211 212 qoriq_tmu_init_device(data); /* TMU initialization */ 213 214 ret = qoriq_tmu_calibration(pdev); /* TMU calibration */ 215 if (ret < 0) 216 goto err_tmu; 217 218 ret = qoriq_tmu_register_tmu_zone(pdev); 219 if (ret < 0) { 220 dev_err(&pdev->dev, "Failed to register sensors\n"); 221 ret = -ENODEV; 222 goto err_iomap; 223 } 224 225 return 0; 226 227 err_tmu: 228 iounmap(data->regs); 229 230 err_iomap: 231 platform_set_drvdata(pdev, NULL); 232 233 return ret; 234 } 235 236 static int qoriq_tmu_remove(struct platform_device *pdev) 237 { 238 struct qoriq_tmu_data *data = platform_get_drvdata(pdev); 239 240 /* Disable monitoring */ 241 tmu_write(data, TMR_DISABLE, &data->regs->tmr); 242 243 iounmap(data->regs); 244 platform_set_drvdata(pdev, NULL); 245 246 return 0; 247 } 248 249 #ifdef CONFIG_PM_SLEEP 250 static int qoriq_tmu_suspend(struct device *dev) 251 { 252 u32 tmr; 253 struct qoriq_tmu_data *data = dev_get_drvdata(dev); 254 255 /* Disable monitoring */ 256 tmr = tmu_read(data, &data->regs->tmr); 257 tmr &= ~TMR_ME; 258 tmu_write(data, tmr, &data->regs->tmr); 259 260 return 0; 261 } 262 263 static int qoriq_tmu_resume(struct device *dev) 264 { 265 u32 tmr; 266 struct qoriq_tmu_data *data = dev_get_drvdata(dev); 267 268 /* Enable monitoring */ 269 tmr = tmu_read(data, &data->regs->tmr); 270 tmr |= TMR_ME; 271 tmu_write(data, tmr, &data->regs->tmr); 272 273 return 0; 274 } 275 #endif 276 277 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, 278 qoriq_tmu_suspend, qoriq_tmu_resume); 279 280 static const struct of_device_id qoriq_tmu_match[] = { 281 { .compatible = "fsl,qoriq-tmu", }, 282 { .compatible = "fsl,imx8mq-tmu", }, 283 {}, 284 }; 285 MODULE_DEVICE_TABLE(of, qoriq_tmu_match); 286 287 static struct platform_driver qoriq_tmu = { 288 .driver = { 289 .name = "qoriq_thermal", 290 .pm = &qoriq_tmu_pm_ops, 291 .of_match_table = qoriq_tmu_match, 292 }, 293 .probe = qoriq_tmu_probe, 294 .remove = qoriq_tmu_remove, 295 }; 296 module_platform_driver(qoriq_tmu); 297 298 MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>"); 299 MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver"); 300 MODULE_LICENSE("GPL v2"); 301