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