0001
0002
0003
0004
0005 #include <linux/clk.h>
0006 #include <linux/err.h>
0007 #include <linux/io.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/regmap.h>
0012 #include <linux/sizes.h>
0013 #include <linux/thermal.h>
0014 #include <linux/units.h>
0015
0016 #include "thermal_core.h"
0017 #include "thermal_hwmon.h"
0018
0019 #define SITES_MAX 16
0020 #define TMR_DISABLE 0x0
0021 #define TMR_ME 0x80000000
0022 #define TMR_ALPF 0x0c000000
0023 #define TMR_ALPF_V2 0x03000000
0024 #define TMTMIR_DEFAULT 0x0000000f
0025 #define TIER_DISABLE 0x0
0026 #define TEUMR0_V2 0x51009c00
0027 #define TMSARA_V2 0xe
0028 #define TMU_VER1 0x1
0029 #define TMU_VER2 0x2
0030
0031 #define REGS_TMR 0x000
0032 #define TMR_DISABLE 0x0
0033 #define TMR_ME 0x80000000
0034 #define TMR_ALPF 0x0c000000
0035 #define TMR_MSITE_ALL GENMASK(15, 0)
0036
0037 #define REGS_TMTMIR 0x008
0038 #define TMTMIR_DEFAULT 0x0000000f
0039
0040 #define REGS_V2_TMSR 0x008
0041
0042 #define REGS_V2_TMTMIR 0x00c
0043
0044 #define REGS_TIER 0x020
0045 #define TIER_DISABLE 0x0
0046
0047
0048 #define REGS_TTCFGR 0x080
0049 #define REGS_TSCFGR 0x084
0050
0051 #define REGS_TRITSR(n) (0x100 + 16 * (n))
0052
0053
0054 #define TRITSR_V BIT(31)
0055 #define REGS_V2_TMSAR(n) (0x304 + 16 * (n))
0056
0057
0058 #define REGS_TTRnCR(n) (0xf10 + 4 * (n))
0059
0060
0061 #define REGS_IPBRR(n) (0xbf8 + 4 * (n))
0062
0063
0064 #define REGS_V2_TEUMR(n) (0xf00 + 4 * (n))
0065
0066
0067
0068
0069 struct qoriq_sensor {
0070 int id;
0071 };
0072
0073 struct qoriq_tmu_data {
0074 int ver;
0075 struct regmap *regmap;
0076 struct clk *clk;
0077 struct qoriq_sensor sensor[SITES_MAX];
0078 };
0079
0080 static struct qoriq_tmu_data *qoriq_sensor_to_data(struct qoriq_sensor *s)
0081 {
0082 return container_of(s, struct qoriq_tmu_data, sensor[s->id]);
0083 }
0084
0085 static int tmu_get_temp(void *p, int *temp)
0086 {
0087 struct qoriq_sensor *qsensor = p;
0088 struct qoriq_tmu_data *qdata = qoriq_sensor_to_data(qsensor);
0089 u32 val;
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 if (regmap_read_poll_timeout(qdata->regmap,
0110 REGS_TRITSR(qsensor->id),
0111 val,
0112 val & TRITSR_V,
0113 USEC_PER_MSEC,
0114 10 * USEC_PER_MSEC))
0115 return -ENODATA;
0116
0117 if (qdata->ver == TMU_VER1)
0118 *temp = (val & GENMASK(7, 0)) * MILLIDEGREE_PER_DEGREE;
0119 else
0120 *temp = kelvin_to_millicelsius(val & GENMASK(8, 0));
0121
0122 return 0;
0123 }
0124
0125 static const struct thermal_zone_of_device_ops tmu_tz_ops = {
0126 .get_temp = tmu_get_temp,
0127 };
0128
0129 static int qoriq_tmu_register_tmu_zone(struct device *dev,
0130 struct qoriq_tmu_data *qdata)
0131 {
0132 int id;
0133
0134 if (qdata->ver == TMU_VER1) {
0135 regmap_write(qdata->regmap, REGS_TMR,
0136 TMR_MSITE_ALL | TMR_ME | TMR_ALPF);
0137 } else {
0138 regmap_write(qdata->regmap, REGS_V2_TMSR, TMR_MSITE_ALL);
0139 regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
0140 }
0141
0142 for (id = 0; id < SITES_MAX; id++) {
0143 struct thermal_zone_device *tzd;
0144 struct qoriq_sensor *sensor = &qdata->sensor[id];
0145 int ret;
0146
0147 sensor->id = id;
0148
0149 tzd = devm_thermal_zone_of_sensor_register(dev, id,
0150 sensor,
0151 &tmu_tz_ops);
0152 ret = PTR_ERR_OR_ZERO(tzd);
0153 if (ret) {
0154 if (ret == -ENODEV)
0155 continue;
0156
0157 regmap_write(qdata->regmap, REGS_TMR, TMR_DISABLE);
0158 return ret;
0159 }
0160
0161 if (devm_thermal_add_hwmon_sysfs(tzd))
0162 dev_warn(dev,
0163 "Failed to add hwmon sysfs attributes\n");
0164
0165 }
0166
0167 return 0;
0168 }
0169
0170 static int qoriq_tmu_calibration(struct device *dev,
0171 struct qoriq_tmu_data *data)
0172 {
0173 int i, val, len;
0174 u32 range[4];
0175 const u32 *calibration;
0176 struct device_node *np = dev->of_node;
0177
0178 len = of_property_count_u32_elems(np, "fsl,tmu-range");
0179 if (len < 0 || len > 4) {
0180 dev_err(dev, "invalid range data.\n");
0181 return len;
0182 }
0183
0184 val = of_property_read_u32_array(np, "fsl,tmu-range", range, len);
0185 if (val != 0) {
0186 dev_err(dev, "failed to read range data.\n");
0187 return val;
0188 }
0189
0190
0191 for (i = 0; i < len; i++)
0192 regmap_write(data->regmap, REGS_TTRnCR(i), range[i]);
0193
0194 calibration = of_get_property(np, "fsl,tmu-calibration", &len);
0195 if (calibration == NULL || len % 8) {
0196 dev_err(dev, "invalid calibration data.\n");
0197 return -ENODEV;
0198 }
0199
0200 for (i = 0; i < len; i += 8, calibration += 2) {
0201 val = of_read_number(calibration, 1);
0202 regmap_write(data->regmap, REGS_TTCFGR, val);
0203 val = of_read_number(calibration + 1, 1);
0204 regmap_write(data->regmap, REGS_TSCFGR, val);
0205 }
0206
0207 return 0;
0208 }
0209
0210 static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
0211 {
0212 int i;
0213
0214
0215 regmap_write(data->regmap, REGS_TIER, TIER_DISABLE);
0216
0217
0218
0219 if (data->ver == TMU_VER1) {
0220 regmap_write(data->regmap, REGS_TMTMIR, TMTMIR_DEFAULT);
0221 } else {
0222 regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT);
0223 regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2);
0224 for (i = 0; i < SITES_MAX; i++)
0225 regmap_write(data->regmap, REGS_V2_TMSAR(i), TMSARA_V2);
0226 }
0227
0228
0229 regmap_write(data->regmap, REGS_TMR, TMR_DISABLE);
0230 }
0231
0232 static const struct regmap_range qoriq_yes_ranges[] = {
0233 regmap_reg_range(REGS_TMR, REGS_TSCFGR),
0234 regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)),
0235 regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)),
0236 regmap_reg_range(REGS_V2_TMSAR(0), REGS_V2_TMSAR(15)),
0237 regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)),
0238
0239 regmap_reg_range(REGS_TRITSR(0), REGS_TRITSR(15)),
0240 };
0241
0242 static const struct regmap_access_table qoriq_wr_table = {
0243 .yes_ranges = qoriq_yes_ranges,
0244 .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges) - 1,
0245 };
0246
0247 static const struct regmap_access_table qoriq_rd_table = {
0248 .yes_ranges = qoriq_yes_ranges,
0249 .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges),
0250 };
0251
0252 static void qoriq_tmu_action(void *p)
0253 {
0254 struct qoriq_tmu_data *data = p;
0255
0256 regmap_write(data->regmap, REGS_TMR, TMR_DISABLE);
0257 clk_disable_unprepare(data->clk);
0258 }
0259
0260 static int qoriq_tmu_probe(struct platform_device *pdev)
0261 {
0262 int ret;
0263 u32 ver;
0264 struct qoriq_tmu_data *data;
0265 struct device_node *np = pdev->dev.of_node;
0266 struct device *dev = &pdev->dev;
0267 const bool little_endian = of_property_read_bool(np, "little-endian");
0268 const enum regmap_endian format_endian =
0269 little_endian ? REGMAP_ENDIAN_LITTLE : REGMAP_ENDIAN_BIG;
0270 const struct regmap_config regmap_config = {
0271 .reg_bits = 32,
0272 .val_bits = 32,
0273 .reg_stride = 4,
0274 .rd_table = &qoriq_rd_table,
0275 .wr_table = &qoriq_wr_table,
0276 .val_format_endian = format_endian,
0277 .max_register = SZ_4K,
0278 };
0279 void __iomem *base;
0280
0281 data = devm_kzalloc(dev, sizeof(struct qoriq_tmu_data),
0282 GFP_KERNEL);
0283 if (!data)
0284 return -ENOMEM;
0285
0286 base = devm_platform_ioremap_resource(pdev, 0);
0287 ret = PTR_ERR_OR_ZERO(base);
0288 if (ret) {
0289 dev_err(dev, "Failed to get memory region\n");
0290 return ret;
0291 }
0292
0293 data->regmap = devm_regmap_init_mmio(dev, base, ®map_config);
0294 ret = PTR_ERR_OR_ZERO(data->regmap);
0295 if (ret) {
0296 dev_err(dev, "Failed to init regmap (%d)\n", ret);
0297 return ret;
0298 }
0299
0300 data->clk = devm_clk_get_optional(dev, NULL);
0301 if (IS_ERR(data->clk))
0302 return PTR_ERR(data->clk);
0303
0304 ret = clk_prepare_enable(data->clk);
0305 if (ret) {
0306 dev_err(dev, "Failed to enable clock\n");
0307 return ret;
0308 }
0309
0310 ret = devm_add_action_or_reset(dev, qoriq_tmu_action, data);
0311 if (ret)
0312 return ret;
0313
0314
0315 ret = regmap_read(data->regmap, REGS_IPBRR(0), &ver);
0316 if (ret) {
0317 dev_err(&pdev->dev, "Failed to read IP block version\n");
0318 return ret;
0319 }
0320 data->ver = (ver >> 8) & 0xff;
0321
0322 qoriq_tmu_init_device(data);
0323
0324 ret = qoriq_tmu_calibration(dev, data);
0325 if (ret < 0)
0326 return ret;
0327
0328 ret = qoriq_tmu_register_tmu_zone(dev, data);
0329 if (ret < 0) {
0330 dev_err(dev, "Failed to register sensors\n");
0331 return ret;
0332 }
0333
0334 platform_set_drvdata(pdev, data);
0335
0336 return 0;
0337 }
0338
0339 static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
0340 {
0341 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
0342 int ret;
0343
0344 ret = regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, 0);
0345 if (ret)
0346 return ret;
0347
0348 clk_disable_unprepare(data->clk);
0349
0350 return 0;
0351 }
0352
0353 static int __maybe_unused qoriq_tmu_resume(struct device *dev)
0354 {
0355 int ret;
0356 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
0357
0358 ret = clk_prepare_enable(data->clk);
0359 if (ret)
0360 return ret;
0361
0362
0363 return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);
0364 }
0365
0366 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
0367 qoriq_tmu_suspend, qoriq_tmu_resume);
0368
0369 static const struct of_device_id qoriq_tmu_match[] = {
0370 { .compatible = "fsl,qoriq-tmu", },
0371 { .compatible = "fsl,imx8mq-tmu", },
0372 {},
0373 };
0374 MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
0375
0376 static struct platform_driver qoriq_tmu = {
0377 .driver = {
0378 .name = "qoriq_thermal",
0379 .pm = &qoriq_tmu_pm_ops,
0380 .of_match_table = qoriq_tmu_match,
0381 },
0382 .probe = qoriq_tmu_probe,
0383 };
0384 module_platform_driver(qoriq_tmu);
0385
0386 MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
0387 MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
0388 MODULE_LICENSE("GPL v2");