1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright 2016 Freescale Semiconductor, Inc.
5 #include <linux/module.h>
6 #include <linux/platform_device.h>
10 #include <linux/of_address.h>
11 #include <linux/thermal.h>
13 #include "thermal_core.h"
20 struct qoriq_tmu_site_regs
{
21 u32 tritsr
; /* Immediate Temperature Site Register */
22 u32 tratsr
; /* Average Temperature Site Register */
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
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 */
41 u32 tmhtcrh
; /* High Temperature Capture Register */
42 u32 tmhtcrl
; /* Low Temperature Capture Register */
44 u32 tmhtitr
; /* High Temperature Immediate Threshold */
45 u32 tmhtatr
; /* High Temperature Average Threshold */
46 u32 tmhtactr
; /* High Temperature Average Crit Threshold */
48 u32 ttcfgr
; /* Temperature Configuration Register */
49 u32 tscfgr
; /* Sensor Configuration Register */
51 struct qoriq_tmu_site_regs site
[SITES_MAX
];
53 u32 ipbrr0
; /* IP Block Revision Register 0 */
54 u32 ipbrr1
; /* IP Block Revision Register 1 */
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 */
62 struct qoriq_tmu_data
;
68 struct thermal_zone_device
*tzd
;
69 struct qoriq_tmu_data
*qdata
;
73 struct qoriq_tmu_data
{
74 struct qoriq_tmu_regs __iomem
*regs
;
76 struct qoriq_sensor
*sensor
[SITES_MAX
];
79 static void tmu_write(struct qoriq_tmu_data
*p
, u32 val
, void __iomem
*addr
)
84 iowrite32be(val
, addr
);
87 static u32
tmu_read(struct qoriq_tmu_data
*p
, void __iomem
*addr
)
90 return ioread32(addr
);
92 return ioread32be(addr
);
95 static int tmu_get_temp(void *p
, int *temp
)
97 struct qoriq_sensor
*qsensor
= p
;
98 struct qoriq_tmu_data
*qdata
= qsensor
->qdata
;
101 val
= tmu_read(qdata
, &qdata
->regs
->site
[qsensor
->id
].tritsr
);
102 *temp
= (val
& 0xff) * 1000;
107 static const struct thermal_zone_of_device_ops tmu_tz_ops
= {
108 .get_temp
= tmu_get_temp
,
111 static int qoriq_tmu_register_tmu_zone(struct platform_device
*pdev
)
113 struct qoriq_tmu_data
*qdata
= platform_get_drvdata(pdev
);
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
])
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
)
130 return PTR_ERR(qdata
->sensor
[id
]->tzd
);
133 sites
|= 0x1 << (15 - id
);
136 /* Enable monitoring */
138 tmu_write(qdata
, sites
| TMR_ME
| TMR_ALPF
, &qdata
->regs
->tmr
);
143 static int qoriq_tmu_calibration(struct platform_device
*pdev
)
147 const u32
*calibration
;
148 struct device_node
*np
= pdev
->dev
.of_node
;
149 struct qoriq_tmu_data
*data
= platform_get_drvdata(pdev
);
151 if (of_property_read_u32_array(np
, "fsl,tmu-range", range
, 4)) {
152 dev_err(&pdev
->dev
, "missing calibration range.\n");
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
);
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");
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
);
178 static void qoriq_tmu_init_device(struct qoriq_tmu_data
*data
)
180 /* Disable interrupt, using polling instead */
181 tmu_write(data
, TIER_DISABLE
, &data
->regs
->tier
);
183 /* Set update_interval */
184 tmu_write(data
, TMTMIR_DEFAULT
, &data
->regs
->tmtmir
);
186 /* Disable monitoring */
187 tmu_write(data
, TMR_DISABLE
, &data
->regs
->tmr
);
190 static int qoriq_tmu_probe(struct platform_device
*pdev
)
193 struct qoriq_tmu_data
*data
;
194 struct device_node
*np
= pdev
->dev
.of_node
;
197 dev_err(&pdev
->dev
, "Device OF-Node is NULL");
201 data
= devm_kzalloc(&pdev
->dev
, sizeof(struct qoriq_tmu_data
),
206 platform_set_drvdata(pdev
, data
);
208 data
->little_endian
= of_property_read_bool(np
, "little-endian");
210 data
->regs
= of_iomap(np
, 0);
212 dev_err(&pdev
->dev
, "Failed to get memory region\n");
217 qoriq_tmu_init_device(data
); /* TMU initialization */
219 ret
= qoriq_tmu_calibration(pdev
); /* TMU calibration */
223 ret
= qoriq_tmu_register_tmu_zone(pdev
);
225 dev_err(&pdev
->dev
, "Failed to register sensors\n");
236 platform_set_drvdata(pdev
, NULL
);
241 static int qoriq_tmu_remove(struct platform_device
*pdev
)
243 struct qoriq_tmu_data
*data
= platform_get_drvdata(pdev
);
245 /* Disable monitoring */
246 tmu_write(data
, TMR_DISABLE
, &data
->regs
->tmr
);
249 platform_set_drvdata(pdev
, NULL
);
254 #ifdef CONFIG_PM_SLEEP
255 static int qoriq_tmu_suspend(struct device
*dev
)
258 struct qoriq_tmu_data
*data
= dev_get_drvdata(dev
);
260 /* Disable monitoring */
261 tmr
= tmu_read(data
, &data
->regs
->tmr
);
263 tmu_write(data
, tmr
, &data
->regs
->tmr
);
268 static int qoriq_tmu_resume(struct device
*dev
)
271 struct qoriq_tmu_data
*data
= dev_get_drvdata(dev
);
273 /* Enable monitoring */
274 tmr
= tmu_read(data
, &data
->regs
->tmr
);
276 tmu_write(data
, tmr
, &data
->regs
->tmr
);
282 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops
,
283 qoriq_tmu_suspend
, qoriq_tmu_resume
);
285 static const struct of_device_id qoriq_tmu_match
[] = {
286 { .compatible
= "fsl,qoriq-tmu", },
287 { .compatible
= "fsl,imx8mq-tmu", },
290 MODULE_DEVICE_TABLE(of
, qoriq_tmu_match
);
292 static struct platform_driver qoriq_tmu
= {
294 .name
= "qoriq_thermal",
295 .pm
= &qoriq_tmu_pm_ops
,
296 .of_match_table
= qoriq_tmu_match
,
298 .probe
= qoriq_tmu_probe
,
299 .remove
= qoriq_tmu_remove
,
301 module_platform_driver(qoriq_tmu
);
303 MODULE_AUTHOR("Jia Hongtao <hongtao.jia@nxp.com>");
304 MODULE_DESCRIPTION("QorIQ Thermal Monitoring Unit driver");
305 MODULE_LICENSE("GPL v2");