• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Marvell EBU Armada SoCs thermal sensor driver
4  *
5  * Copyright (C) 2013 Marvell
6  */
7 #include <linux/device.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/kernel.h>
11 #include <linux/of.h>
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/platform_device.h>
15 #include <linux/of_device.h>
16 #include <linux/thermal.h>
17 #include <linux/iopoll.h>
18 #include <linux/mfd/syscon.h>
19 #include <linux/regmap.h>
20 #include <linux/interrupt.h>
21 
22 #include "thermal_core.h"
23 
24 #define TO_MCELSIUS(c)			((c) * 1000)
25 
26 /* Thermal Manager Control and Status Register */
27 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
28 #define PMU_TM_DISABLE_OFFS		0
29 #define PMU_TM_DISABLE_MASK		(0x1 << PMU_TM_DISABLE_OFFS)
30 #define PMU_TDC0_REF_CAL_CNT_OFFS	11
31 #define PMU_TDC0_REF_CAL_CNT_MASK	(0x1ff << PMU_TDC0_REF_CAL_CNT_OFFS)
32 #define PMU_TDC0_OTF_CAL_MASK		(0x1 << 30)
33 #define PMU_TDC0_START_CAL_MASK		(0x1 << 25)
34 
35 #define A375_UNIT_CONTROL_SHIFT		27
36 #define A375_UNIT_CONTROL_MASK		0x7
37 #define A375_READOUT_INVERT		BIT(15)
38 #define A375_HW_RESETn			BIT(8)
39 
40 /* Errata fields */
41 #define CONTROL0_TSEN_TC_TRIM_MASK	0x7
42 #define CONTROL0_TSEN_TC_TRIM_VAL	0x3
43 
44 #define CONTROL0_TSEN_START		BIT(0)
45 #define CONTROL0_TSEN_RESET		BIT(1)
46 #define CONTROL0_TSEN_ENABLE		BIT(2)
47 #define CONTROL0_TSEN_AVG_BYPASS	BIT(6)
48 #define CONTROL0_TSEN_CHAN_SHIFT	13
49 #define CONTROL0_TSEN_CHAN_MASK		0xF
50 #define CONTROL0_TSEN_OSR_SHIFT		24
51 #define CONTROL0_TSEN_OSR_MAX		0x3
52 #define CONTROL0_TSEN_MODE_SHIFT	30
53 #define CONTROL0_TSEN_MODE_EXTERNAL	0x2
54 #define CONTROL0_TSEN_MODE_MASK		0x3
55 
56 #define CONTROL1_TSEN_AVG_MASK		0x7
57 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
58 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
59 #define CONTROL1_TSEN_INT_EN		BIT(25)
60 #define CONTROL1_TSEN_SELECT_OFF	21
61 #define CONTROL1_TSEN_SELECT_MASK	0x3
62 
63 #define STATUS_POLL_PERIOD_US		1000
64 #define STATUS_POLL_TIMEOUT_US		100000
65 #define OVERHEAT_INT_POLL_DELAY_MS	1000
66 
67 struct armada_thermal_data;
68 
69 /* Marvell EBU Thermal Sensor Dev Structure */
70 struct armada_thermal_priv {
71 	struct device *dev;
72 	struct regmap *syscon;
73 	char zone_name[THERMAL_NAME_LENGTH];
74 	/* serialize temperature reads/updates */
75 	struct mutex update_lock;
76 	struct armada_thermal_data *data;
77 	struct thermal_zone_device *overheat_sensor;
78 	int interrupt_source;
79 	int current_channel;
80 	long current_threshold;
81 	long current_hysteresis;
82 };
83 
84 struct armada_thermal_data {
85 	/* Initialize the thermal IC */
86 	void (*init)(struct platform_device *pdev,
87 		     struct armada_thermal_priv *priv);
88 
89 	/* Formula coeficients: temp = (b - m * reg) / div */
90 	s64 coef_b;
91 	s64 coef_m;
92 	u32 coef_div;
93 	bool inverted;
94 	bool signed_sample;
95 
96 	/* Register shift and mask to access the sensor temperature */
97 	unsigned int temp_shift;
98 	unsigned int temp_mask;
99 	unsigned int thresh_shift;
100 	unsigned int hyst_shift;
101 	unsigned int hyst_mask;
102 	u32 is_valid_bit;
103 
104 	/* Syscon access */
105 	unsigned int syscon_control0_off;
106 	unsigned int syscon_control1_off;
107 	unsigned int syscon_status_off;
108 	unsigned int dfx_irq_cause_off;
109 	unsigned int dfx_irq_mask_off;
110 	unsigned int dfx_overheat_irq;
111 	unsigned int dfx_server_irq_mask_off;
112 	unsigned int dfx_server_irq_en;
113 
114 	/* One sensor is in the thermal IC, the others are in the CPUs if any */
115 	unsigned int cpu_nr;
116 };
117 
118 struct armada_drvdata {
119 	enum drvtype {
120 		LEGACY,
121 		SYSCON
122 	} type;
123 	union {
124 		struct armada_thermal_priv *priv;
125 		struct thermal_zone_device *tz;
126 	} data;
127 };
128 
129 /*
130  * struct armada_thermal_sensor - hold the information of one thermal sensor
131  * @thermal: pointer to the local private structure
132  * @tzd: pointer to the thermal zone device
133  * @id: identifier of the thermal sensor
134  */
135 struct armada_thermal_sensor {
136 	struct armada_thermal_priv *priv;
137 	int id;
138 };
139 
armadaxp_init(struct platform_device * pdev,struct armada_thermal_priv * priv)140 static void armadaxp_init(struct platform_device *pdev,
141 			  struct armada_thermal_priv *priv)
142 {
143 	struct armada_thermal_data *data = priv->data;
144 	u32 reg;
145 
146 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
147 	reg |= PMU_TDC0_OTF_CAL_MASK;
148 
149 	/* Reference calibration value */
150 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
151 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
152 
153 	/* Reset the sensor */
154 	reg |= PMU_TDC0_SW_RST_MASK;
155 
156 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
157 
158 	/* Enable the sensor */
159 	regmap_read(priv->syscon, data->syscon_status_off, &reg);
160 	reg &= ~PMU_TM_DISABLE_MASK;
161 	regmap_write(priv->syscon, data->syscon_status_off, reg);
162 }
163 
armada370_init(struct platform_device * pdev,struct armada_thermal_priv * priv)164 static void armada370_init(struct platform_device *pdev,
165 			   struct armada_thermal_priv *priv)
166 {
167 	struct armada_thermal_data *data = priv->data;
168 	u32 reg;
169 
170 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
171 	reg |= PMU_TDC0_OTF_CAL_MASK;
172 
173 	/* Reference calibration value */
174 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
175 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
176 
177 	/* Reset the sensor */
178 	reg &= ~PMU_TDC0_START_CAL_MASK;
179 
180 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
181 
182 	msleep(10);
183 }
184 
armada375_init(struct platform_device * pdev,struct armada_thermal_priv * priv)185 static void armada375_init(struct platform_device *pdev,
186 			   struct armada_thermal_priv *priv)
187 {
188 	struct armada_thermal_data *data = priv->data;
189 	u32 reg;
190 
191 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
192 	reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
193 	reg &= ~A375_READOUT_INVERT;
194 	reg &= ~A375_HW_RESETn;
195 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
196 
197 	msleep(20);
198 
199 	reg |= A375_HW_RESETn;
200 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
201 
202 	msleep(50);
203 }
204 
armada_wait_sensor_validity(struct armada_thermal_priv * priv)205 static int armada_wait_sensor_validity(struct armada_thermal_priv *priv)
206 {
207 	u32 reg;
208 
209 	return regmap_read_poll_timeout(priv->syscon,
210 					priv->data->syscon_status_off, reg,
211 					reg & priv->data->is_valid_bit,
212 					STATUS_POLL_PERIOD_US,
213 					STATUS_POLL_TIMEOUT_US);
214 }
215 
armada380_init(struct platform_device * pdev,struct armada_thermal_priv * priv)216 static void armada380_init(struct platform_device *pdev,
217 			   struct armada_thermal_priv *priv)
218 {
219 	struct armada_thermal_data *data = priv->data;
220 	u32 reg;
221 
222 	/* Disable the HW/SW reset */
223 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
224 	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
225 	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
226 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
227 
228 	/* Set Tsen Tc Trim to correct default value (errata #132698) */
229 	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
230 	reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
231 	reg |= CONTROL0_TSEN_TC_TRIM_VAL;
232 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
233 }
234 
armada_ap806_init(struct platform_device * pdev,struct armada_thermal_priv * priv)235 static void armada_ap806_init(struct platform_device *pdev,
236 			      struct armada_thermal_priv *priv)
237 {
238 	struct armada_thermal_data *data = priv->data;
239 	u32 reg;
240 
241 	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
242 	reg &= ~CONTROL0_TSEN_RESET;
243 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
244 
245 	/* Sample every ~2ms */
246 	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
247 
248 	/* Enable average (2 samples by default) */
249 	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
250 
251 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
252 }
253 
armada_cp110_init(struct platform_device * pdev,struct armada_thermal_priv * priv)254 static void armada_cp110_init(struct platform_device *pdev,
255 			      struct armada_thermal_priv *priv)
256 {
257 	struct armada_thermal_data *data = priv->data;
258 	u32 reg;
259 
260 	armada380_init(pdev, priv);
261 
262 	/* Sample every ~2ms */
263 	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
264 	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
265 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
266 
267 	/* Average the output value over 2^1 = 2 samples */
268 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
269 	reg &= ~CONTROL1_TSEN_AVG_MASK;
270 	reg |= 1;
271 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
272 }
273 
armada_is_valid(struct armada_thermal_priv * priv)274 static bool armada_is_valid(struct armada_thermal_priv *priv)
275 {
276 	u32 reg;
277 
278 	if (!priv->data->is_valid_bit)
279 		return true;
280 
281 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
282 
283 	return reg & priv->data->is_valid_bit;
284 }
285 
armada_enable_overheat_interrupt(struct armada_thermal_priv * priv)286 static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv)
287 {
288 	struct armada_thermal_data *data = priv->data;
289 	u32 reg;
290 
291 	/* Clear DFX temperature IRQ cause */
292 	regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
293 
294 	/* Enable DFX Temperature IRQ */
295 	regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
296 	reg |= data->dfx_overheat_irq;
297 	regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
298 
299 	/* Enable DFX server IRQ */
300 	regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg);
301 	reg |= data->dfx_server_irq_en;
302 	regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg);
303 
304 	/* Enable overheat interrupt */
305 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
306 	reg |= CONTROL1_TSEN_INT_EN;
307 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
308 }
309 
310 static void __maybe_unused
armada_disable_overheat_interrupt(struct armada_thermal_priv * priv)311 armada_disable_overheat_interrupt(struct armada_thermal_priv *priv)
312 {
313 	struct armada_thermal_data *data = priv->data;
314 	u32 reg;
315 
316 	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
317 	reg &= ~CONTROL1_TSEN_INT_EN;
318 	regmap_write(priv->syscon, data->syscon_control1_off, reg);
319 }
320 
321 /* There is currently no board with more than one sensor per channel */
armada_select_channel(struct armada_thermal_priv * priv,int channel)322 static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
323 {
324 	struct armada_thermal_data *data = priv->data;
325 	u32 ctrl0;
326 
327 	if (channel < 0 || channel > priv->data->cpu_nr)
328 		return -EINVAL;
329 
330 	if (priv->current_channel == channel)
331 		return 0;
332 
333 	/* Stop the measurements */
334 	regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
335 	ctrl0 &= ~CONTROL0_TSEN_START;
336 	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
337 
338 	/* Reset the mode, internal sensor will be automatically selected */
339 	ctrl0 &= ~(CONTROL0_TSEN_MODE_MASK << CONTROL0_TSEN_MODE_SHIFT);
340 
341 	/* Other channels are external and should be selected accordingly */
342 	if (channel) {
343 		/* Change the mode to external */
344 		ctrl0 |= CONTROL0_TSEN_MODE_EXTERNAL <<
345 			 CONTROL0_TSEN_MODE_SHIFT;
346 		/* Select the sensor */
347 		ctrl0 &= ~(CONTROL0_TSEN_CHAN_MASK << CONTROL0_TSEN_CHAN_SHIFT);
348 		ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT;
349 	}
350 
351 	/* Actually set the mode/channel */
352 	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
353 	priv->current_channel = channel;
354 
355 	/* Re-start the measurements */
356 	ctrl0 |= CONTROL0_TSEN_START;
357 	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
358 
359 	/*
360 	 * The IP has a latency of ~15ms, so after updating the selected source,
361 	 * we must absolutely wait for the sensor validity bit to ensure we read
362 	 * actual data.
363 	 */
364 	if (armada_wait_sensor_validity(priv)) {
365 		dev_err(priv->dev,
366 			"Temperature sensor reading not valid\n");
367 		return -EIO;
368 	}
369 
370 	return 0;
371 }
372 
armada_read_sensor(struct armada_thermal_priv * priv,int * temp)373 static int armada_read_sensor(struct armada_thermal_priv *priv, int *temp)
374 {
375 	u32 reg, div;
376 	s64 sample, b, m;
377 
378 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
379 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
380 	if (priv->data->signed_sample)
381 		/* The most significant bit is the sign bit */
382 		sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1);
383 	else
384 		sample = reg;
385 
386 	/* Get formula coeficients */
387 	b = priv->data->coef_b;
388 	m = priv->data->coef_m;
389 	div = priv->data->coef_div;
390 
391 	if (priv->data->inverted)
392 		*temp = div_s64((m * sample) - b, div);
393 	else
394 		*temp = div_s64(b - (m * sample), div);
395 
396 	return 0;
397 }
398 
armada_get_temp_legacy(struct thermal_zone_device * thermal,int * temp)399 static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
400 				  int *temp)
401 {
402 	struct armada_thermal_priv *priv = thermal->devdata;
403 	int ret;
404 
405 	/* Valid check */
406 	if (!armada_is_valid(priv)) {
407 		dev_err(priv->dev,
408 			"Temperature sensor reading not valid\n");
409 		return -EIO;
410 	}
411 
412 	/* Do the actual reading */
413 	ret = armada_read_sensor(priv, temp);
414 
415 	return ret;
416 }
417 
418 static struct thermal_zone_device_ops legacy_ops = {
419 	.get_temp = armada_get_temp_legacy,
420 };
421 
armada_get_temp(void * _sensor,int * temp)422 static int armada_get_temp(void *_sensor, int *temp)
423 {
424 	struct armada_thermal_sensor *sensor = _sensor;
425 	struct armada_thermal_priv *priv = sensor->priv;
426 	int ret;
427 
428 	mutex_lock(&priv->update_lock);
429 
430 	/* Select the desired channel */
431 	ret = armada_select_channel(priv, sensor->id);
432 	if (ret)
433 		goto unlock_mutex;
434 
435 	/* Do the actual reading */
436 	ret = armada_read_sensor(priv, temp);
437 	if (ret)
438 		goto unlock_mutex;
439 
440 	/*
441 	 * Select back the interrupt source channel from which a potential
442 	 * critical trip point has been set.
443 	 */
444 	ret = armada_select_channel(priv, priv->interrupt_source);
445 
446 unlock_mutex:
447 	mutex_unlock(&priv->update_lock);
448 
449 	return ret;
450 }
451 
452 static const struct thermal_zone_of_device_ops of_ops = {
453 	.get_temp = armada_get_temp,
454 };
455 
armada_mc_to_reg_temp(struct armada_thermal_data * data,unsigned int temp_mc)456 static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data,
457 					  unsigned int temp_mc)
458 {
459 	s64 b = data->coef_b;
460 	s64 m = data->coef_m;
461 	s64 div = data->coef_div;
462 	unsigned int sample;
463 
464 	if (data->inverted)
465 		sample = div_s64(((temp_mc * div) + b), m);
466 	else
467 		sample = div_s64((b - (temp_mc * div)), m);
468 
469 	return sample & data->temp_mask;
470 }
471 
472 /*
473  * The documentation states:
474  * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
475  * which is the mathematical derivation for:
476  * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C
477  */
478 static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200};
479 
armada_mc_to_reg_hyst(struct armada_thermal_data * data,unsigned int hyst_mc)480 static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data,
481 					  unsigned int hyst_mc)
482 {
483 	int i;
484 
485 	/*
486 	 * We will always take the smallest possible hysteresis to avoid risking
487 	 * the hardware integrity by enlarging the threshold by +8°C in the
488 	 * worst case.
489 	 */
490 	for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--)
491 		if (hyst_mc >= hyst_levels_mc[i])
492 			break;
493 
494 	return i & data->hyst_mask;
495 }
496 
armada_set_overheat_thresholds(struct armada_thermal_priv * priv,int thresh_mc,int hyst_mc)497 static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv,
498 					   int thresh_mc, int hyst_mc)
499 {
500 	struct armada_thermal_data *data = priv->data;
501 	unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc);
502 	unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc);
503 	u32 ctrl1;
504 
505 	regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1);
506 
507 	/* Set Threshold */
508 	if (thresh_mc >= 0) {
509 		ctrl1 &= ~(data->temp_mask << data->thresh_shift);
510 		ctrl1 |= threshold << data->thresh_shift;
511 		priv->current_threshold = thresh_mc;
512 	}
513 
514 	/* Set Hysteresis */
515 	if (hyst_mc >= 0) {
516 		ctrl1 &= ~(data->hyst_mask << data->hyst_shift);
517 		ctrl1 |= hysteresis << data->hyst_shift;
518 		priv->current_hysteresis = hyst_mc;
519 	}
520 
521 	regmap_write(priv->syscon, data->syscon_control1_off, ctrl1);
522 }
523 
armada_overheat_isr(int irq,void * blob)524 static irqreturn_t armada_overheat_isr(int irq, void *blob)
525 {
526 	/*
527 	 * Disable the IRQ and continue in thread context (thermal core
528 	 * notification and temperature monitoring).
529 	 */
530 	disable_irq_nosync(irq);
531 
532 	return IRQ_WAKE_THREAD;
533 }
534 
armada_overheat_isr_thread(int irq,void * blob)535 static irqreturn_t armada_overheat_isr_thread(int irq, void *blob)
536 {
537 	struct armada_thermal_priv *priv = blob;
538 	int low_threshold = priv->current_threshold - priv->current_hysteresis;
539 	int temperature;
540 	u32 dummy;
541 	int ret;
542 
543 	/* Notify the core in thread context */
544 	thermal_zone_device_update(priv->overheat_sensor,
545 				   THERMAL_EVENT_UNSPECIFIED);
546 
547 	/*
548 	 * The overheat interrupt must be cleared by reading the DFX interrupt
549 	 * cause _after_ the temperature has fallen down to the low threshold.
550 	 * Otherwise future interrupts might not be served.
551 	 */
552 	do {
553 		msleep(OVERHEAT_INT_POLL_DELAY_MS);
554 		mutex_lock(&priv->update_lock);
555 		ret = armada_read_sensor(priv, &temperature);
556 		mutex_unlock(&priv->update_lock);
557 		if (ret)
558 			goto enable_irq;
559 	} while (temperature >= low_threshold);
560 
561 	regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy);
562 
563 	/* Notify the thermal core that the temperature is acceptable again */
564 	thermal_zone_device_update(priv->overheat_sensor,
565 				   THERMAL_EVENT_UNSPECIFIED);
566 
567 enable_irq:
568 	enable_irq(irq);
569 
570 	return IRQ_HANDLED;
571 }
572 
573 static const struct armada_thermal_data armadaxp_data = {
574 	.init = armadaxp_init,
575 	.temp_shift = 10,
576 	.temp_mask = 0x1ff,
577 	.coef_b = 3153000000ULL,
578 	.coef_m = 10000000ULL,
579 	.coef_div = 13825,
580 	.syscon_status_off = 0xb0,
581 	.syscon_control1_off = 0xd0,
582 };
583 
584 static const struct armada_thermal_data armada370_data = {
585 	.init = armada370_init,
586 	.is_valid_bit = BIT(9),
587 	.temp_shift = 10,
588 	.temp_mask = 0x1ff,
589 	.coef_b = 3153000000ULL,
590 	.coef_m = 10000000ULL,
591 	.coef_div = 13825,
592 	.syscon_status_off = 0x0,
593 	.syscon_control1_off = 0x4,
594 };
595 
596 static const struct armada_thermal_data armada375_data = {
597 	.init = armada375_init,
598 	.is_valid_bit = BIT(10),
599 	.temp_shift = 0,
600 	.temp_mask = 0x1ff,
601 	.coef_b = 3171900000ULL,
602 	.coef_m = 10000000ULL,
603 	.coef_div = 13616,
604 	.syscon_status_off = 0x78,
605 	.syscon_control0_off = 0x7c,
606 	.syscon_control1_off = 0x80,
607 };
608 
609 static const struct armada_thermal_data armada380_data = {
610 	.init = armada380_init,
611 	.is_valid_bit = BIT(10),
612 	.temp_shift = 0,
613 	.temp_mask = 0x3ff,
614 	.coef_b = 1172499100ULL,
615 	.coef_m = 2000096ULL,
616 	.coef_div = 4201,
617 	.inverted = true,
618 	.syscon_control0_off = 0x70,
619 	.syscon_control1_off = 0x74,
620 	.syscon_status_off = 0x78,
621 };
622 
623 static const struct armada_thermal_data armada_ap806_data = {
624 	.init = armada_ap806_init,
625 	.is_valid_bit = BIT(16),
626 	.temp_shift = 0,
627 	.temp_mask = 0x3ff,
628 	.thresh_shift = 3,
629 	.hyst_shift = 19,
630 	.hyst_mask = 0x3,
631 	.coef_b = -150000LL,
632 	.coef_m = 423ULL,
633 	.coef_div = 1,
634 	.inverted = true,
635 	.signed_sample = true,
636 	.syscon_control0_off = 0x84,
637 	.syscon_control1_off = 0x88,
638 	.syscon_status_off = 0x8C,
639 	.dfx_irq_cause_off = 0x108,
640 	.dfx_irq_mask_off = 0x10C,
641 	.dfx_overheat_irq = BIT(22),
642 	.dfx_server_irq_mask_off = 0x104,
643 	.dfx_server_irq_en = BIT(1),
644 	.cpu_nr = 4,
645 };
646 
647 static const struct armada_thermal_data armada_cp110_data = {
648 	.init = armada_cp110_init,
649 	.is_valid_bit = BIT(10),
650 	.temp_shift = 0,
651 	.temp_mask = 0x3ff,
652 	.thresh_shift = 16,
653 	.hyst_shift = 26,
654 	.hyst_mask = 0x3,
655 	.coef_b = 1172499100ULL,
656 	.coef_m = 2000096ULL,
657 	.coef_div = 4201,
658 	.inverted = true,
659 	.syscon_control0_off = 0x70,
660 	.syscon_control1_off = 0x74,
661 	.syscon_status_off = 0x78,
662 	.dfx_irq_cause_off = 0x108,
663 	.dfx_irq_mask_off = 0x10C,
664 	.dfx_overheat_irq = BIT(20),
665 	.dfx_server_irq_mask_off = 0x104,
666 	.dfx_server_irq_en = BIT(1),
667 };
668 
669 static const struct of_device_id armada_thermal_id_table[] = {
670 	{
671 		.compatible = "marvell,armadaxp-thermal",
672 		.data       = &armadaxp_data,
673 	},
674 	{
675 		.compatible = "marvell,armada370-thermal",
676 		.data       = &armada370_data,
677 	},
678 	{
679 		.compatible = "marvell,armada375-thermal",
680 		.data       = &armada375_data,
681 	},
682 	{
683 		.compatible = "marvell,armada380-thermal",
684 		.data       = &armada380_data,
685 	},
686 	{
687 		.compatible = "marvell,armada-ap806-thermal",
688 		.data       = &armada_ap806_data,
689 	},
690 	{
691 		.compatible = "marvell,armada-cp110-thermal",
692 		.data       = &armada_cp110_data,
693 	},
694 	{
695 		/* sentinel */
696 	},
697 };
698 MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
699 
700 static const struct regmap_config armada_thermal_regmap_config = {
701 	.reg_bits = 32,
702 	.reg_stride = 4,
703 	.val_bits = 32,
704 	.fast_io = true,
705 };
706 
armada_thermal_probe_legacy(struct platform_device * pdev,struct armada_thermal_priv * priv)707 static int armada_thermal_probe_legacy(struct platform_device *pdev,
708 				       struct armada_thermal_priv *priv)
709 {
710 	struct armada_thermal_data *data = priv->data;
711 	struct resource *res;
712 	void __iomem *base;
713 
714 	/* First memory region points towards the status register */
715 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
716 	base = devm_ioremap_resource(&pdev->dev, res);
717 	if (IS_ERR(base))
718 		return PTR_ERR(base);
719 
720 	/*
721 	 * Fix up from the old individual DT register specification to
722 	 * cover all the registers.  We do this by adjusting the ioremap()
723 	 * result, which should be fine as ioremap() deals with pages.
724 	 * However, validate that we do not cross a page boundary while
725 	 * making this adjustment.
726 	 */
727 	if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off)
728 		return -EINVAL;
729 	base -= data->syscon_status_off;
730 
731 	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
732 					     &armada_thermal_regmap_config);
733 	return PTR_ERR_OR_ZERO(priv->syscon);
734 }
735 
armada_thermal_probe_syscon(struct platform_device * pdev,struct armada_thermal_priv * priv)736 static int armada_thermal_probe_syscon(struct platform_device *pdev,
737 				       struct armada_thermal_priv *priv)
738 {
739 	priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
740 	return PTR_ERR_OR_ZERO(priv->syscon);
741 }
742 
armada_set_sane_name(struct platform_device * pdev,struct armada_thermal_priv * priv)743 static void armada_set_sane_name(struct platform_device *pdev,
744 				 struct armada_thermal_priv *priv)
745 {
746 	const char *name = dev_name(&pdev->dev);
747 	char *insane_char;
748 
749 	if (strlen(name) > THERMAL_NAME_LENGTH) {
750 		/*
751 		 * When inside a system controller, the device name has the
752 		 * form: f06f8000.system-controller:ap-thermal so stripping
753 		 * after the ':' should give us a shorter but meaningful name.
754 		 */
755 		name = strrchr(name, ':');
756 		if (!name)
757 			name = "armada_thermal";
758 		else
759 			name++;
760 	}
761 
762 	/* Save the name locally */
763 	strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1);
764 	priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0';
765 
766 	/* Then check there are no '-' or hwmon core will complain */
767 	do {
768 		insane_char = strpbrk(priv->zone_name, "-");
769 		if (insane_char)
770 			*insane_char = '_';
771 	} while (insane_char);
772 }
773 
774 /*
775  * The IP can manage to trigger interrupts on overheat situation from all the
776  * sensors. However, the interrupt source changes along with the last selected
777  * source (ie. the last read sensor), which is an inconsistent behavior. Avoid
778  * possible glitches by always selecting back only one channel (arbitrarily: the
779  * first in the DT which has a critical trip point). We also disable sensor
780  * switch during overheat situations.
781  */
armada_configure_overheat_int(struct armada_thermal_priv * priv,struct thermal_zone_device * tz,int sensor_id)782 static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
783 					 struct thermal_zone_device *tz,
784 					 int sensor_id)
785 {
786 	/* Retrieve the critical trip point to enable the overheat interrupt */
787 	const struct thermal_trip *trips = of_thermal_get_trip_points(tz);
788 	int ret;
789 	int i;
790 
791 	if (!trips)
792 		return -EINVAL;
793 
794 	for (i = 0; i < of_thermal_get_ntrips(tz); i++)
795 		if (trips[i].type == THERMAL_TRIP_CRITICAL)
796 			break;
797 
798 	if (i == of_thermal_get_ntrips(tz))
799 		return -EINVAL;
800 
801 	ret = armada_select_channel(priv, sensor_id);
802 	if (ret)
803 		return ret;
804 
805 	armada_set_overheat_thresholds(priv,
806 				       trips[i].temperature,
807 				       trips[i].hysteresis);
808 	priv->overheat_sensor = tz;
809 	priv->interrupt_source = sensor_id;
810 
811 	armada_enable_overheat_interrupt(priv);
812 
813 	return 0;
814 }
815 
armada_thermal_probe(struct platform_device * pdev)816 static int armada_thermal_probe(struct platform_device *pdev)
817 {
818 	struct thermal_zone_device *tz;
819 	struct armada_thermal_sensor *sensor;
820 	struct armada_drvdata *drvdata;
821 	const struct of_device_id *match;
822 	struct armada_thermal_priv *priv;
823 	int sensor_id, irq;
824 	int ret;
825 
826 	match = of_match_device(armada_thermal_id_table, &pdev->dev);
827 	if (!match)
828 		return -ENODEV;
829 
830 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
831 	if (!priv)
832 		return -ENOMEM;
833 
834 	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
835 	if (!drvdata)
836 		return -ENOMEM;
837 
838 	priv->dev = &pdev->dev;
839 	priv->data = (struct armada_thermal_data *)match->data;
840 
841 	mutex_init(&priv->update_lock);
842 
843 	/*
844 	 * Legacy DT bindings only described "control1" register (also referred
845 	 * as "control MSB" on old documentation). Then, bindings moved to cover
846 	 * "control0/control LSB" and "control1/control MSB" registers within
847 	 * the same resource, which was then of size 8 instead of 4.
848 	 *
849 	 * The logic of defining sporadic registers is broken. For instance, it
850 	 * blocked the addition of the overheat interrupt feature that needed
851 	 * another resource somewhere else in the same memory area. One solution
852 	 * is to define an overall system controller and put the thermal node
853 	 * into it, which requires the use of regmaps across all the driver.
854 	 */
855 	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) {
856 		/* Ensure device name is correct for the thermal core */
857 		armada_set_sane_name(pdev, priv);
858 
859 		ret = armada_thermal_probe_legacy(pdev, priv);
860 		if (ret)
861 			return ret;
862 
863 		priv->data->init(pdev, priv);
864 
865 		/* Wait the sensors to be valid */
866 		armada_wait_sensor_validity(priv);
867 
868 		tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
869 						  &legacy_ops, NULL, 0, 0);
870 		if (IS_ERR(tz)) {
871 			dev_err(&pdev->dev,
872 				"Failed to register thermal zone device\n");
873 			return PTR_ERR(tz);
874 		}
875 
876 		drvdata->type = LEGACY;
877 		drvdata->data.tz = tz;
878 		platform_set_drvdata(pdev, drvdata);
879 
880 		return 0;
881 	}
882 
883 	ret = armada_thermal_probe_syscon(pdev, priv);
884 	if (ret)
885 		return ret;
886 
887 	priv->current_channel = -1;
888 	priv->data->init(pdev, priv);
889 	drvdata->type = SYSCON;
890 	drvdata->data.priv = priv;
891 	platform_set_drvdata(pdev, drvdata);
892 
893 	irq = platform_get_irq(pdev, 0);
894 	if (irq == -EPROBE_DEFER)
895 		return irq;
896 
897 	/* The overheat interrupt feature is not mandatory */
898 	if (irq > 0) {
899 		ret = devm_request_threaded_irq(&pdev->dev, irq,
900 						armada_overheat_isr,
901 						armada_overheat_isr_thread,
902 						0, NULL, priv);
903 		if (ret) {
904 			dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n",
905 				irq);
906 			return ret;
907 		}
908 	}
909 
910 	/*
911 	 * There is one channel for the IC and one per CPU (if any), each
912 	 * channel has one sensor.
913 	 */
914 	for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) {
915 		sensor = devm_kzalloc(&pdev->dev,
916 				      sizeof(struct armada_thermal_sensor),
917 				      GFP_KERNEL);
918 		if (!sensor)
919 			return -ENOMEM;
920 
921 		/* Register the sensor */
922 		sensor->priv = priv;
923 		sensor->id = sensor_id;
924 		tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
925 							  sensor->id, sensor,
926 							  &of_ops);
927 		if (IS_ERR(tz)) {
928 			dev_info(&pdev->dev, "Thermal sensor %d unavailable\n",
929 				 sensor_id);
930 			devm_kfree(&pdev->dev, sensor);
931 			continue;
932 		}
933 
934 		/*
935 		 * The first channel that has a critical trip point registered
936 		 * in the DT will serve as interrupt source. Others possible
937 		 * critical trip points will simply be ignored by the driver.
938 		 */
939 		if (irq > 0 && !priv->overheat_sensor)
940 			armada_configure_overheat_int(priv, tz, sensor->id);
941 	}
942 
943 	/* Just complain if no overheat interrupt was set up */
944 	if (!priv->overheat_sensor)
945 		dev_warn(&pdev->dev, "Overheat interrupt not available\n");
946 
947 	return 0;
948 }
949 
armada_thermal_exit(struct platform_device * pdev)950 static int armada_thermal_exit(struct platform_device *pdev)
951 {
952 	struct armada_drvdata *drvdata = platform_get_drvdata(pdev);
953 
954 	if (drvdata->type == LEGACY)
955 		thermal_zone_device_unregister(drvdata->data.tz);
956 
957 	return 0;
958 }
959 
960 static struct platform_driver armada_thermal_driver = {
961 	.probe = armada_thermal_probe,
962 	.remove = armada_thermal_exit,
963 	.driver = {
964 		.name = "armada_thermal",
965 		.of_match_table = armada_thermal_id_table,
966 	},
967 };
968 
969 module_platform_driver(armada_thermal_driver);
970 
971 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
972 MODULE_DESCRIPTION("Marvell EBU Armada SoCs thermal driver");
973 MODULE_LICENSE("GPL v2");
974