thermal_hwmon: Add devres wrapper for thermal_add_hwmon_sysfs()
[linux-block.git] / drivers / thermal / qoriq_thermal.c
CommitLineData
2dfef650
FE
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright 2016 Freescale Semiconductor, Inc.
43528445 4
51904045 5#include <linux/clk.h>
43528445
JH
6#include <linux/module.h>
7#include <linux/platform_device.h>
8#include <linux/err.h>
9#include <linux/io.h>
10#include <linux/of.h>
11#include <linux/of_address.h>
4316237b
AS
12#include <linux/regmap.h>
13#include <linux/sizes.h>
43528445
JH
14#include <linux/thermal.h>
15
16#include "thermal_core.h"
17
9809797b
YT
18#define SITES_MAX 16
19#define TMR_DISABLE 0x0
20#define TMR_ME 0x80000000
21#define TMR_ALPF 0x0c000000
22#define TMR_ALPF_V2 0x03000000
23#define TMTMIR_DEFAULT 0x0000000f
24#define TIER_DISABLE 0x0
25#define TEUMR0_V2 0x51009c00
26#define TMU_VER1 0x1
27#define TMU_VER2 0x2
43528445 28
4316237b
AS
29#define REGS_TMR 0x000 /* Mode Register */
30#define TMR_DISABLE 0x0
31#define TMR_ME 0x80000000
32#define TMR_ALPF 0x0c000000
45038e03 33#define TMR_MSITE_ALL GENMASK(15, 0)
43528445 34
4316237b
AS
35#define REGS_TMTMIR 0x008 /* Temperature measurement interval Register */
36#define TMTMIR_DEFAULT 0x0000000f
9809797b 37
4316237b
AS
38#define REGS_V2_TMSR 0x008 /* monitor site register */
39
40#define REGS_V2_TMTMIR 0x00c /* Temperature measurement interval Register */
41
42#define REGS_TIER 0x020 /* Interrupt Enable Register */
43#define TIER_DISABLE 0x0
44
45
46#define REGS_TTCFGR 0x080 /* Temperature Configuration Register */
47#define REGS_TSCFGR 0x084 /* Sensor Configuration Register */
48
49#define REGS_TRITSR(n) (0x100 + 16 * (n)) /* Immediate Temperature
50 * Site Register
51 */
36564d7e 52#define TRITSR_V BIT(31)
4316237b
AS
53#define REGS_TTRnCR(n) (0xf10 + 4 * (n)) /* Temperature Range n
54 * Control Register
55 */
56#define REGS_IPBRR(n) (0xbf8 + 4 * (n)) /* IP Block Revision
57 * Register n
58 */
59#define REGS_V2_TEUMR(n) (0xf00 + 4 * (n))
43528445
JH
60
61/*
62 * Thermal zone data
63 */
7797ff42 64struct qoriq_sensor {
7797ff42
YT
65 int id;
66};
67
43528445 68struct qoriq_tmu_data {
9809797b 69 int ver;
4316237b 70 struct regmap *regmap;
51904045 71 struct clk *clk;
b319da1b 72 struct qoriq_sensor sensor[SITES_MAX];
43528445
JH
73};
74
b319da1b
AS
75static struct qoriq_tmu_data *qoriq_sensor_to_data(struct qoriq_sensor *s)
76{
77 return container_of(s, struct qoriq_tmu_data, sensor[s->id]);
78}
79
43528445
JH
80static int tmu_get_temp(void *p, int *temp)
81{
7797ff42 82 struct qoriq_sensor *qsensor = p;
b319da1b 83 struct qoriq_tmu_data *qdata = qoriq_sensor_to_data(qsensor);
43528445 84 u32 val;
36564d7e
AS
85 /*
86 * REGS_TRITSR(id) has the following layout:
87 *
88 * 31 ... 7 6 5 4 3 2 1 0
89 * V TEMP
90 *
91 * Where V bit signifies if the measurement is ready and is
92 * within sensor range. TEMP is an 8 bit value representing
93 * temperature in C.
94 */
95 if (regmap_read_poll_timeout(qdata->regmap,
96 REGS_TRITSR(qsensor->id),
97 val,
98 val & TRITSR_V,
99 USEC_PER_MSEC,
100 10 * USEC_PER_MSEC))
101 return -ENODATA;
43528445 102
43528445
JH
103 *temp = (val & 0xff) * 1000;
104
105 return 0;
106}
107
7797ff42
YT
108static const struct thermal_zone_of_device_ops tmu_tz_ops = {
109 .get_temp = tmu_get_temp,
110};
43528445 111
03036625
AS
112static int qoriq_tmu_register_tmu_zone(struct device *dev,
113 struct qoriq_tmu_data *qdata)
7797ff42 114{
45038e03
AS
115 int id;
116
117 if (qdata->ver == TMU_VER1) {
118 regmap_write(qdata->regmap, REGS_TMR,
119 TMR_MSITE_ALL | TMR_ME | TMR_ALPF);
120 } else {
121 regmap_write(qdata->regmap, REGS_V2_TMSR, TMR_MSITE_ALL);
122 regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
123 }
7797ff42
YT
124
125 for (id = 0; id < SITES_MAX; id++) {
11ef00f7 126 struct thermal_zone_device *tzd;
b319da1b 127 struct qoriq_sensor *sensor = &qdata->sensor[id];
11ef00f7
AS
128 int ret;
129
d6fb0564 130 sensor->id = id;
11ef00f7 131
03036625 132 tzd = devm_thermal_zone_of_sensor_register(dev, id,
d6fb0564 133 sensor,
11ef00f7
AS
134 &tmu_tz_ops);
135 ret = PTR_ERR_OR_ZERO(tzd);
136 if (ret) {
137 if (ret == -ENODEV)
7797ff42 138 continue;
43528445 139
45038e03
AS
140 regmap_write(qdata->regmap, REGS_TMR, TMR_DISABLE);
141 return ret;
9809797b
YT
142 }
143 }
43528445 144
7797ff42 145 return 0;
43528445
JH
146}
147
8e1cda35
AS
148static int qoriq_tmu_calibration(struct device *dev,
149 struct qoriq_tmu_data *data)
43528445
JH
150{
151 int i, val, len;
152 u32 range[4];
153 const u32 *calibration;
8e1cda35 154 struct device_node *np = dev->of_node;
43528445 155
9809797b
YT
156 len = of_property_count_u32_elems(np, "fsl,tmu-range");
157 if (len < 0 || len > 4) {
8e1cda35 158 dev_err(dev, "invalid range data.\n");
9809797b
YT
159 return len;
160 }
161
162 val = of_property_read_u32_array(np, "fsl,tmu-range", range, len);
163 if (val != 0) {
8e1cda35 164 dev_err(dev, "failed to read range data.\n");
9809797b 165 return val;
43528445
JH
166 }
167
168 /* Init temperature range registers */
9809797b 169 for (i = 0; i < len; i++)
4316237b 170 regmap_write(data->regmap, REGS_TTRnCR(i), range[i]);
43528445
JH
171
172 calibration = of_get_property(np, "fsl,tmu-calibration", &len);
173 if (calibration == NULL || len % 8) {
8e1cda35 174 dev_err(dev, "invalid calibration data.\n");
43528445
JH
175 return -ENODEV;
176 }
177
178 for (i = 0; i < len; i += 8, calibration += 2) {
179 val = of_read_number(calibration, 1);
4316237b 180 regmap_write(data->regmap, REGS_TTCFGR, val);
43528445 181 val = of_read_number(calibration + 1, 1);
4316237b 182 regmap_write(data->regmap, REGS_TSCFGR, val);
43528445
JH
183 }
184
185 return 0;
186}
187
188static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
189{
190 /* Disable interrupt, using polling instead */
4316237b 191 regmap_write(data->regmap, REGS_TIER, TIER_DISABLE);
43528445
JH
192
193 /* Set update_interval */
4316237b 194
9809797b 195 if (data->ver == TMU_VER1) {
4316237b 196 regmap_write(data->regmap, REGS_TMTMIR, TMTMIR_DEFAULT);
9809797b 197 } else {
4316237b
AS
198 regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT);
199 regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2);
9809797b 200 }
43528445
JH
201
202 /* Disable monitoring */
4316237b 203 regmap_write(data->regmap, REGS_TMR, TMR_DISABLE);
43528445
JH
204}
205
4316237b
AS
206static const struct regmap_range qoriq_yes_ranges[] = {
207 regmap_reg_range(REGS_TMR, REGS_TSCFGR),
208 regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)),
209 regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)),
210 regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)),
211 /* Read only registers below */
212 regmap_reg_range(REGS_TRITSR(0), REGS_TRITSR(15)),
213};
214
215static const struct regmap_access_table qoriq_wr_table = {
216 .yes_ranges = qoriq_yes_ranges,
217 .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges) - 1,
218};
219
220static const struct regmap_access_table qoriq_rd_table = {
221 .yes_ranges = qoriq_yes_ranges,
222 .n_yes_ranges = ARRAY_SIZE(qoriq_yes_ranges),
223};
224
43528445
JH
225static int qoriq_tmu_probe(struct platform_device *pdev)
226{
227 int ret;
9809797b 228 u32 ver;
43528445
JH
229 struct qoriq_tmu_data *data;
230 struct device_node *np = pdev->dev.of_node;
e167dc43 231 struct device *dev = &pdev->dev;
4316237b
AS
232 const bool little_endian = of_property_read_bool(np, "little-endian");
233 const enum regmap_endian format_endian =
234 little_endian ? REGMAP_ENDIAN_LITTLE : REGMAP_ENDIAN_BIG;
235 const struct regmap_config regmap_config = {
236 .reg_bits = 32,
237 .val_bits = 32,
238 .reg_stride = 4,
239 .rd_table = &qoriq_rd_table,
240 .wr_table = &qoriq_wr_table,
241 .val_format_endian = format_endian,
242 .max_register = SZ_4K,
243 };
244 void __iomem *base;
43528445 245
e167dc43 246 data = devm_kzalloc(dev, sizeof(struct qoriq_tmu_data),
43528445
JH
247 GFP_KERNEL);
248 if (!data)
249 return -ENOMEM;
250
4316237b
AS
251 base = devm_platform_ioremap_resource(pdev, 0);
252 ret = PTR_ERR_OR_ZERO(base);
253 if (ret) {
e167dc43 254 dev_err(dev, "Failed to get memory region\n");
4316237b
AS
255 return ret;
256 }
257
258 data->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
259 ret = PTR_ERR_OR_ZERO(data->regmap);
260 if (ret) {
261 dev_err(dev, "Failed to init regmap (%d)\n", ret);
262 return ret;
43528445
JH
263 }
264
e167dc43 265 data->clk = devm_clk_get_optional(dev, NULL);
51904045
AH
266 if (IS_ERR(data->clk))
267 return PTR_ERR(data->clk);
268
269 ret = clk_prepare_enable(data->clk);
270 if (ret) {
e167dc43 271 dev_err(dev, "Failed to enable clock\n");
51904045
AH
272 return ret;
273 }
274
9809797b 275 /* version register offset at: 0xbf8 on both v1 and v2 */
4316237b
AS
276 ret = regmap_read(data->regmap, REGS_IPBRR(0), &ver);
277 if (ret) {
278 dev_err(&pdev->dev, "Failed to read IP block version\n");
279 return ret;
280 }
9809797b 281 data->ver = (ver >> 8) & 0xff;
9809797b 282
43528445
JH
283 qoriq_tmu_init_device(data); /* TMU initialization */
284
8e1cda35 285 ret = qoriq_tmu_calibration(dev, data); /* TMU calibration */
43528445 286 if (ret < 0)
4d82000a 287 goto err;
43528445 288
03036625 289 ret = qoriq_tmu_register_tmu_zone(dev, data);
7797ff42 290 if (ret < 0) {
e167dc43 291 dev_err(dev, "Failed to register sensors\n");
7797ff42 292 ret = -ENODEV;
4d82000a 293 goto err;
43528445
JH
294 }
295
8e1cda35
AS
296 platform_set_drvdata(pdev, data);
297
43528445
JH
298 return 0;
299
4d82000a 300err:
51904045 301 clk_disable_unprepare(data->clk);
43528445
JH
302
303 return ret;
304}
305
306static int qoriq_tmu_remove(struct platform_device *pdev)
307{
308 struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
309
43528445 310 /* Disable monitoring */
4316237b 311 regmap_write(data->regmap, REGS_TMR, TMR_DISABLE);
43528445 312
51904045
AH
313 clk_disable_unprepare(data->clk);
314
43528445
JH
315 return 0;
316}
317
aea59197 318static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
43528445 319{
43528445 320 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
4316237b 321 int ret;
43528445 322
4316237b
AS
323 ret = regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, 0);
324 if (ret)
325 return ret;
43528445 326
51904045
AH
327 clk_disable_unprepare(data->clk);
328
43528445
JH
329 return 0;
330}
331
aea59197 332static int __maybe_unused qoriq_tmu_resume(struct device *dev)
43528445 333{
51904045 334 int ret;
43528445
JH
335 struct qoriq_tmu_data *data = dev_get_drvdata(dev);
336
51904045
AH
337 ret = clk_prepare_enable(data->clk);
338 if (ret)
339 return ret;
340
43528445 341 /* Enable monitoring */
4316237b 342 return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);
43528445 343}
43528445
JH
344
345static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
346 qoriq_tmu_suspend, qoriq_tmu_resume);
347
348static const struct of_device_id qoriq_tmu_match[] = {
349 { .compatible = "fsl,qoriq-tmu", },
6017e2a9 350 { .compatible = "fsl,imx8mq-tmu", },
43528445
JH
351 {},
352};
353MODULE_DEVICE_TABLE(of, qoriq_tmu_match);
354
355static struct platform_driver qoriq_tmu = {
356 .driver = {
357 .name = "qoriq_thermal",
358 .pm = &qoriq_tmu_pm_ops,
359 .of_match_table = qoriq_tmu_match,
360 },
361 .probe = qoriq_tmu_probe,
362 .remove = qoriq_tmu_remove,
363};
364module_platform_driver(qoriq_tmu);
365
366MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
367MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
368MODULE_LICENSE("GPL v2");