1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright 2016 Freescale Semiconductor, Inc.
6 #include <linux/module.h>
7 #include <linux/platform_device.h>
11 #include <linux/of_address.h>
12 #include <linux/thermal.h>
14 #include "thermal_core.h"
21 struct qoriq_tmu_site_regs
{
22 u32 tritsr
; /* Immediate Temperature Site Register */
23 u32 tratsr
; /* Average Temperature Site Register */
27 struct qoriq_tmu_regs
{
28 u32 tmr
; /* Mode Register */
29 #define TMR_DISABLE 0x0
30 #define TMR_ME 0x80000000
31 #define TMR_ALPF 0x0c000000
32 u32 tsr
; /* Status Register */
33 u32 tmtmir
; /* Temperature measurement interval Register */
34 #define TMTMIR_DEFAULT 0x0000000f
36 u32 tier
; /* Interrupt Enable Register */
37 #define TIER_DISABLE 0x0
38 u32 tidr
; /* Interrupt Detect Register */
39 u32 tiscr
; /* Interrupt Site Capture Register */
40 u32 ticscr
; /* Interrupt Critical Site Capture Register */
42 u32 tmhtcrh
; /* High Temperature Capture Register */
43 u32 tmhtcrl
; /* Low Temperature Capture Register */
45 u32 tmhtitr
; /* High Temperature Immediate Threshold */
46 u32 tmhtatr
; /* High Temperature Average Threshold */
47 u32 tmhtactr
; /* High Temperature Average Crit Threshold */
49 u32 ttcfgr
; /* Temperature Configuration Register */
50 u32 tscfgr
; /* Sensor Configuration Register */
52 struct qoriq_tmu_site_regs site
[SITES_MAX
];
54 u32 ipbrr0
; /* IP Block Revision Register 0 */
55 u32 ipbrr1
; /* IP Block Revision Register 1 */
57 u32 ttr0cr
; /* Temperature Range 0 Control Register */
58 u32 ttr1cr
; /* Temperature Range 1 Control Register */
59 u32 ttr2cr
; /* Temperature Range 2 Control Register */
60 u32 ttr3cr
; /* Temperature Range 3 Control Register */
63 struct qoriq_tmu_data
;
69 struct thermal_zone_device
*tzd
;
70 struct qoriq_tmu_data
*qdata
;
74 struct qoriq_tmu_data
{
75 struct qoriq_tmu_regs __iomem
*regs
;
78 struct qoriq_sensor
*sensor
[SITES_MAX
];
81 static void tmu_write(struct qoriq_tmu_data
*p
, u32 val
, void __iomem
*addr
)
86 iowrite32be(val
, addr
);
89 static u32
tmu_read(struct qoriq_tmu_data
*p
, void __iomem
*addr
)
92 return ioread32(addr
);
94 return ioread32be(addr
);
97 static int tmu_get_temp(void *p
, int *temp
)
99 struct qoriq_sensor
*qsensor
= p
;
100 struct qoriq_tmu_data
*qdata
= qsensor
->qdata
;
103 val
= tmu_read(qdata
, &qdata
->regs
->site
[qsensor
->id
].tritsr
);
104 *temp
= (val
& 0xff) * 1000;
109 static const struct thermal_zone_of_device_ops tmu_tz_ops
= {
110 .get_temp
= tmu_get_temp
,
113 static int qoriq_tmu_register_tmu_zone(struct platform_device
*pdev
)
115 struct qoriq_tmu_data
*qdata
= platform_get_drvdata(pdev
);
118 for (id
= 0; id
< SITES_MAX
; id
++) {
119 qdata
->sensor
[id
] = devm_kzalloc(&pdev
->dev
,
120 sizeof(struct qoriq_sensor
), GFP_KERNEL
);
121 if (!qdata
->sensor
[id
])
124 qdata
->sensor
[id
]->id
= id
;
125 qdata
->sensor
[id
]->qdata
= qdata
;
126 qdata
->sensor
[id
]->tzd
= devm_thermal_zone_of_sensor_register(
127 &pdev
->dev
, id
, qdata
->sensor
[id
], &tmu_tz_ops
);
128 if (IS_ERR(qdata
->sensor
[id
]->tzd
)) {
129 if (PTR_ERR(qdata
->sensor
[id
]->tzd
) == -ENODEV
)
132 return PTR_ERR(qdata
->sensor
[id
]->tzd
);
135 sites
|= 0x1 << (15 - id
);
138 /* Enable monitoring */
140 tmu_write(qdata
, sites
| TMR_ME
| TMR_ALPF
, &qdata
->regs
->tmr
);
145 static int qoriq_tmu_calibration(struct platform_device
*pdev
)
149 const u32
*calibration
;
150 struct device_node
*np
= pdev
->dev
.of_node
;
151 struct qoriq_tmu_data
*data
= platform_get_drvdata(pdev
);
153 if (of_property_read_u32_array(np
, "fsl,tmu-range", range
, 4)) {
154 dev_err(&pdev
->dev
, "missing calibration range.\n");
158 /* Init temperature range registers */
159 tmu_write(data
, range
[0], &data
->regs
->ttr0cr
);
160 tmu_write(data
, range
[1], &data
->regs
->ttr1cr
);
161 tmu_write(data
, range
[2], &data
->regs
->ttr2cr
);
162 tmu_write(data
, range
[3], &data
->regs
->ttr3cr
);
164 calibration
= of_get_property(np
, "fsl,tmu-calibration", &len
);
165 if (calibration
== NULL
|| len
% 8) {
166 dev_err(&pdev
->dev
, "invalid calibration data.\n");
170 for (i
= 0; i
< len
; i
+= 8, calibration
+= 2) {
171 val
= of_read_number(calibration
, 1);
172 tmu_write(data
, val
, &data
->regs
->ttcfgr
);
173 val
= of_read_number(calibration
+ 1, 1);
174 tmu_write(data
, val
, &data
->regs
->tscfgr
);
180 static void qoriq_tmu_init_device(struct qoriq_tmu_data
*data
)
182 /* Disable interrupt, using polling instead */
183 tmu_write(data
, TIER_DISABLE
, &data
->regs
->tier
);
185 /* Set update_interval */
186 tmu_write(data
, TMTMIR_DEFAULT
, &data
->regs
->tmtmir
);
188 /* Disable monitoring */
189 tmu_write(data
, TMR_DISABLE
, &data
->regs
->tmr
);
192 static int qoriq_tmu_probe(struct platform_device
*pdev
)
195 struct qoriq_tmu_data
*data
;
196 struct device_node
*np
= pdev
->dev
.of_node
;
198 data
= devm_kzalloc(&pdev
->dev
, sizeof(struct qoriq_tmu_data
),
203 platform_set_drvdata(pdev
, data
);
205 data
->little_endian
= of_property_read_bool(np
, "little-endian");
207 data
->regs
= devm_platform_ioremap_resource(pdev
, 0);
208 if (IS_ERR(data
->regs
)) {
209 dev_err(&pdev
->dev
, "Failed to get memory region\n");
210 return PTR_ERR(data
->regs
);
213 data
->clk
= devm_clk_get_optional(&pdev
->dev
, NULL
);
214 if (IS_ERR(data
->clk
))
215 return PTR_ERR(data
->clk
);
217 ret
= clk_prepare_enable(data
->clk
);
219 dev_err(&pdev
->dev
, "Failed to enable clock\n");
223 qoriq_tmu_init_device(data
); /* TMU initialization */
225 ret
= qoriq_tmu_calibration(pdev
); /* TMU calibration */
229 ret
= qoriq_tmu_register_tmu_zone(pdev
);
231 dev_err(&pdev
->dev
, "Failed to register sensors\n");
239 clk_disable_unprepare(data
->clk
);
240 platform_set_drvdata(pdev
, NULL
);
245 static int qoriq_tmu_remove(struct platform_device
*pdev
)
247 struct qoriq_tmu_data
*data
= platform_get_drvdata(pdev
);
249 /* Disable monitoring */
250 tmu_write(data
, TMR_DISABLE
, &data
->regs
->tmr
);
252 clk_disable_unprepare(data
->clk
);
254 platform_set_drvdata(pdev
, NULL
);
259 static int __maybe_unused
qoriq_tmu_suspend(struct device
*dev
)
262 struct qoriq_tmu_data
*data
= dev_get_drvdata(dev
);
264 /* Disable monitoring */
265 tmr
= tmu_read(data
, &data
->regs
->tmr
);
267 tmu_write(data
, tmr
, &data
->regs
->tmr
);
269 clk_disable_unprepare(data
->clk
);
274 static int __maybe_unused
qoriq_tmu_resume(struct device
*dev
)
278 struct qoriq_tmu_data
*data
= dev_get_drvdata(dev
);
280 ret
= clk_prepare_enable(data
->clk
);
284 /* Enable monitoring */
285 tmr
= tmu_read(data
, &data
->regs
->tmr
);
287 tmu_write(data
, tmr
, &data
->regs
->tmr
);
292 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops
,
293 qoriq_tmu_suspend
, qoriq_tmu_resume
);
295 static const struct of_device_id qoriq_tmu_match
[] = {
296 { .compatible
= "fsl,qoriq-tmu", },
297 { .compatible
= "fsl,imx8mq-tmu", },
300 MODULE_DEVICE_TABLE(of
, qoriq_tmu_match
);
302 static struct platform_driver qoriq_tmu
= {
304 .name
= "qoriq_thermal",
305 .pm
= &qoriq_tmu_pm_ops
,
306 .of_match_table
= qoriq_tmu_match
,
308 .probe
= qoriq_tmu_probe
,
309 .remove
= qoriq_tmu_remove
,
311 module_platform_driver(qoriq_tmu
);
313 MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
314 MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
315 MODULE_LICENSE("GPL v2");