hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/thermal/rcar_gen3_thermal.c
....@@ -18,6 +18,7 @@
1818 #include <linux/thermal.h>
1919
2020 #include "thermal_core.h"
21
+#include "thermal_hwmon.h"
2122
2223 /* Register offsets */
2324 #define REG_GEN3_IRQSTR 0x04
....@@ -61,6 +62,13 @@
6162
6263 #define TSC_MAX_NUM 3
6364
65
+/* default THCODE values if FUSEs are missing */
66
+static const int thcodes[TSC_MAX_NUM][3] = {
67
+ { 3397, 2800, 2221 },
68
+ { 3393, 2795, 2216 },
69
+ { 3389, 2805, 2237 },
70
+};
71
+
6472 /* Structure for thermal temperature calculation */
6573 struct equation_coefs {
6674 int a1;
....@@ -73,8 +81,8 @@
7381 void __iomem *base;
7482 struct thermal_zone_device *zone;
7583 struct equation_coefs coef;
76
- int low;
77
- int high;
84
+ int tj_t;
85
+ int id; /* thermal channel id */
7886 };
7987
8088 struct rcar_gen3_thermal_priv {
....@@ -121,30 +129,28 @@
121129 #define RCAR3_THERMAL_GRAN 500 /* mili Celsius */
122130
123131 /* no idea where these constants come from */
124
-#define TJ_1 116
125132 #define TJ_3 -41
126133
127
-static void rcar_gen3_thermal_calc_coefs(struct equation_coefs *coef,
128
- int *ptat, int *thcode)
134
+static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_tsc *tsc,
135
+ int *ptat, const int *thcode,
136
+ int ths_tj_1)
129137 {
130
- int tj_2;
131
-
132138 /* TODO: Find documentation and document constant calculation formula */
133139
134140 /*
135141 * Division is not scaled in BSP and if scaled it might overflow
136142 * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
137143 */
138
- tj_2 = (FIXPT_INT((ptat[1] - ptat[2]) * 157)
139
- / (ptat[0] - ptat[2])) - FIXPT_INT(41);
144
+ tsc->tj_t = (FIXPT_INT((ptat[1] - ptat[2]) * (ths_tj_1 - TJ_3))
145
+ / (ptat[0] - ptat[2])) + FIXPT_INT(TJ_3);
140146
141
- coef->a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]),
142
- tj_2 - FIXPT_INT(TJ_3));
143
- coef->b1 = FIXPT_INT(thcode[2]) - coef->a1 * TJ_3;
147
+ tsc->coef.a1 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[2]),
148
+ tsc->tj_t - FIXPT_INT(TJ_3));
149
+ tsc->coef.b1 = FIXPT_INT(thcode[2]) - tsc->coef.a1 * TJ_3;
144150
145
- coef->a2 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[0]),
146
- tj_2 - FIXPT_INT(TJ_1));
147
- coef->b2 = FIXPT_INT(thcode[0]) - coef->a2 * TJ_1;
151
+ tsc->coef.a2 = FIXPT_DIV(FIXPT_INT(thcode[1] - thcode[0]),
152
+ tsc->tj_t - FIXPT_INT(ths_tj_1));
153
+ tsc->coef.b2 = FIXPT_INT(thcode[0]) - tsc->coef.a2 * ths_tj_1;
148154 }
149155
150156 static int rcar_gen3_thermal_round(int temp)
....@@ -160,19 +166,21 @@
160166 static int rcar_gen3_thermal_get_temp(void *devdata, int *temp)
161167 {
162168 struct rcar_gen3_thermal_tsc *tsc = devdata;
163
- int mcelsius, val1, val2;
164
- u32 reg;
169
+ int mcelsius, val;
170
+ int reg;
165171
166172 /* Read register and convert to mili Celsius */
167173 reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
168174
169
- val1 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1, tsc->coef.a1);
170
- val2 = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2, tsc->coef.a2);
171
- mcelsius = FIXPT_TO_MCELSIUS((val1 + val2) / 2);
175
+ if (reg <= thcodes[tsc->id][1])
176
+ val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
177
+ tsc->coef.a1);
178
+ else
179
+ val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2,
180
+ tsc->coef.a2);
181
+ mcelsius = FIXPT_TO_MCELSIUS(val);
172182
173
- /* Make sure we are inside specifications */
174
- if ((mcelsius < MCELSIUS(-40)) || (mcelsius > MCELSIUS(125)))
175
- return -EIO;
183
+ /* Guaranteed operating range is -40C to 125C. */
176184
177185 /* Round value to device granularity setting */
178186 *temp = rcar_gen3_thermal_round(mcelsius);
....@@ -183,21 +191,25 @@
183191 static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc,
184192 int mcelsius)
185193 {
186
- int celsius, val1, val2;
194
+ int celsius, val;
187195
188196 celsius = DIV_ROUND_CLOSEST(mcelsius, 1000);
189
- val1 = celsius * tsc->coef.a1 + tsc->coef.b1;
190
- val2 = celsius * tsc->coef.a2 + tsc->coef.b2;
197
+ if (celsius <= INT_FIXPT(tsc->tj_t))
198
+ val = celsius * tsc->coef.a1 + tsc->coef.b1;
199
+ else
200
+ val = celsius * tsc->coef.a2 + tsc->coef.b2;
191201
192
- return INT_FIXPT((val1 + val2) / 2);
202
+ return INT_FIXPT(val);
193203 }
194204
195
-static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high)
205
+static int rcar_gen3_thermal_update_range(struct rcar_gen3_thermal_tsc *tsc)
196206 {
197
- struct rcar_gen3_thermal_tsc *tsc = devdata;
207
+ int temperature, low, high;
198208
199
- low = clamp_val(low, -40000, 120000);
200
- high = clamp_val(high, -40000, 120000);
209
+ rcar_gen3_thermal_get_temp(tsc, &temperature);
210
+
211
+ low = temperature - MCELSIUS(1);
212
+ high = temperature + MCELSIUS(1);
201213
202214 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1,
203215 rcar_gen3_thermal_mcelsius_to_temp(tsc, low));
....@@ -205,15 +217,11 @@
205217 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2,
206218 rcar_gen3_thermal_mcelsius_to_temp(tsc, high));
207219
208
- tsc->low = low;
209
- tsc->high = high;
210
-
211220 return 0;
212221 }
213222
214223 static const struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = {
215224 .get_temp = rcar_gen3_thermal_get_temp,
216
- .set_trips = rcar_gen3_thermal_set_trips,
217225 };
218226
219227 static void rcar_thermal_irq_set(struct rcar_gen3_thermal_priv *priv, bool on)
....@@ -234,9 +242,11 @@
234242 for (i = 0; i < priv->num_tscs; i++) {
235243 status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
236244 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
237
- if (status)
245
+ if (status) {
246
+ rcar_gen3_thermal_update_range(priv->tscs[i]);
238247 thermal_zone_device_update(priv->tscs[i]->zone,
239248 THERMAL_EVENT_UNSPECIFIED);
249
+ }
240250 }
241251
242252 return IRQ_HANDLED;
....@@ -282,7 +292,7 @@
282292
283293 usleep_range(1000, 2000);
284294
285
- rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F);
295
+ rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0);
286296 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
287297 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, IRQ_TEMPD1 | IRQ_TEMP2);
288298
....@@ -293,10 +303,41 @@
293303 usleep_range(1000, 2000);
294304 }
295305
306
+static const int rcar_gen3_ths_tj_1 = 126;
307
+static const int rcar_gen3_ths_tj_1_m3_w = 116;
296308 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
297
- { .compatible = "renesas,r8a7795-thermal", },
298
- { .compatible = "renesas,r8a7796-thermal", },
299
- { .compatible = "renesas,r8a77965-thermal", },
309
+ {
310
+ .compatible = "renesas,r8a774a1-thermal",
311
+ .data = &rcar_gen3_ths_tj_1_m3_w,
312
+ },
313
+ {
314
+ .compatible = "renesas,r8a774b1-thermal",
315
+ .data = &rcar_gen3_ths_tj_1,
316
+ },
317
+ {
318
+ .compatible = "renesas,r8a774e1-thermal",
319
+ .data = &rcar_gen3_ths_tj_1,
320
+ },
321
+ {
322
+ .compatible = "renesas,r8a7795-thermal",
323
+ .data = &rcar_gen3_ths_tj_1,
324
+ },
325
+ {
326
+ .compatible = "renesas,r8a7796-thermal",
327
+ .data = &rcar_gen3_ths_tj_1_m3_w,
328
+ },
329
+ {
330
+ .compatible = "renesas,r8a77961-thermal",
331
+ .data = &rcar_gen3_ths_tj_1_m3_w,
332
+ },
333
+ {
334
+ .compatible = "renesas,r8a77965-thermal",
335
+ .data = &rcar_gen3_ths_tj_1,
336
+ },
337
+ {
338
+ .compatible = "renesas,r8a77980-thermal",
339
+ .data = &rcar_gen3_ths_tj_1,
340
+ },
300341 {},
301342 };
302343 MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
....@@ -314,10 +355,18 @@
314355 return 0;
315356 }
316357
358
+static void rcar_gen3_hwmon_action(void *data)
359
+{
360
+ struct thermal_zone_device *zone = data;
361
+
362
+ thermal_remove_hwmon_sysfs(zone);
363
+}
364
+
317365 static int rcar_gen3_thermal_probe(struct platform_device *pdev)
318366 {
319367 struct rcar_gen3_thermal_priv *priv;
320368 struct device *dev = &pdev->dev;
369
+ const int *ths_tj_1 = of_device_get_match_data(dev);
321370 struct resource *res;
322371 struct thermal_zone_device *zone;
323372 int ret, irq, i;
....@@ -326,11 +375,6 @@
326375 /* default values if FUSEs are missing */
327376 /* TODO: Read values from hardware on supported platforms */
328377 int ptat[3] = { 2631, 1509, 435 };
329
- int thcode[TSC_MAX_NUM][3] = {
330
- { 3397, 2800, 2221 },
331
- { 3393, 2795, 2216 },
332
- { 3389, 2805, 2237 },
333
- };
334378
335379 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
336380 if (!priv)
....@@ -385,11 +429,12 @@
385429 ret = PTR_ERR(tsc->base);
386430 goto error_unregister;
387431 }
432
+ tsc->id = i;
388433
389434 priv->tscs[i] = tsc;
390435
391436 priv->thermal_init(tsc);
392
- rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]);
437
+ rcar_gen3_thermal_calc_coefs(tsc, ptat, thcodes[i], *ths_tj_1);
393438
394439 zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
395440 &rcar_gen3_tz_of_ops);
....@@ -400,9 +445,20 @@
400445 }
401446 tsc->zone = zone;
402447
448
+ tsc->zone->tzp->no_hwmon = false;
449
+ ret = thermal_add_hwmon_sysfs(tsc->zone);
450
+ if (ret)
451
+ goto error_unregister;
452
+
453
+ ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
454
+ if (ret)
455
+ goto error_unregister;
456
+
403457 ret = of_thermal_get_ntrips(tsc->zone);
404458 if (ret < 0)
405459 goto error_unregister;
460
+
461
+ rcar_gen3_thermal_update_range(tsc);
406462
407463 dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret);
408464 }
....@@ -442,7 +498,7 @@
442498 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
443499
444500 priv->thermal_init(tsc);
445
- rcar_gen3_thermal_set_trips(tsc, tsc->low, tsc->high);
501
+ rcar_gen3_thermal_update_range(tsc);
446502 }
447503
448504 rcar_thermal_irq_set(priv, true);