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