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 return -EIO; 365 366 return 0; 367 } 368 369 static int armada_read_sensor(struct armada_thermal_priv *priv, int *temp) 370 { 371 u32 reg, div; 372 s64 sample, b, m; 373 374 regmap_read(priv->syscon, priv->data->syscon_status_off, ®); 375 reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask; 376 if (priv->data->signed_sample) 377 /* The most significant bit is the sign bit */ 378 sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1); 379 else 380 sample = reg; 381 382 /* Get formula coeficients */ 383 b = priv->data->coef_b; 384 m = priv->data->coef_m; 385 div = priv->data->coef_div; 386 387 if (priv->data->inverted) 388 *temp = div_s64((m * sample) - b, div); 389 else 390 *temp = div_s64(b - (m * sample), div); 391 392 return 0; 393 } 394 395 static int armada_get_temp_legacy(struct thermal_zone_device *thermal, 396 int *temp) 397 { 398 struct armada_thermal_priv *priv = thermal_zone_device_priv(thermal); 399 int ret; 400 401 /* Valid check */ 402 if (!armada_is_valid(priv)) 403 return -EIO; 404 405 /* Do the actual reading */ 406 ret = armada_read_sensor(priv, temp); 407 408 return ret; 409 } 410 411 static struct thermal_zone_device_ops legacy_ops = { 412 .get_temp = armada_get_temp_legacy, 413 }; 414 415 static int armada_get_temp(struct thermal_zone_device *tz, int *temp) 416 { 417 struct armada_thermal_sensor *sensor = thermal_zone_device_priv(tz); 418 struct armada_thermal_priv *priv = sensor->priv; 419 int ret; 420 421 mutex_lock(&priv->update_lock); 422 423 /* Select the desired channel */ 424 ret = armada_select_channel(priv, sensor->id); 425 if (ret) 426 goto unlock_mutex; 427 428 /* Do the actual reading */ 429 ret = armada_read_sensor(priv, temp); 430 if (ret) 431 goto unlock_mutex; 432 433 /* 434 * Select back the interrupt source channel from which a potential 435 * critical trip point has been set. 436 */ 437 ret = armada_select_channel(priv, priv->interrupt_source); 438 439 unlock_mutex: 440 mutex_unlock(&priv->update_lock); 441 442 return ret; 443 } 444 445 static const struct thermal_zone_device_ops of_ops = { 446 .get_temp = armada_get_temp, 447 }; 448 449 static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data, 450 unsigned int temp_mc) 451 { 452 s64 b = data->coef_b; 453 s64 m = data->coef_m; 454 s64 div = data->coef_div; 455 unsigned int sample; 456 457 if (data->inverted) 458 sample = div_s64(((temp_mc * div) + b), m); 459 else 460 sample = div_s64((b - (temp_mc * div)), m); 461 462 return sample & data->temp_mask; 463 } 464 465 /* 466 * The documentation states: 467 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2) 468 * which is the mathematical derivation for: 469 * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2°C 470 */ 471 static unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200}; 472 473 static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data, 474 unsigned int hyst_mc) 475 { 476 int i; 477 478 /* 479 * We will always take the smallest possible hysteresis to avoid risking 480 * the hardware integrity by enlarging the threshold by +8°C in the 481 * worst case. 482 */ 483 for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--) 484 if (hyst_mc >= hyst_levels_mc[i]) 485 break; 486 487 return i & data->hyst_mask; 488 } 489 490 static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv, 491 int thresh_mc, int hyst_mc) 492 { 493 struct armada_thermal_data *data = priv->data; 494 unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc); 495 unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc); 496 u32 ctrl1; 497 498 regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1); 499 500 /* Set Threshold */ 501 if (thresh_mc >= 0) { 502 ctrl1 &= ~(data->temp_mask << data->thresh_shift); 503 ctrl1 |= threshold << data->thresh_shift; 504 priv->current_threshold = thresh_mc; 505 } 506 507 /* Set Hysteresis */ 508 if (hyst_mc >= 0) { 509 ctrl1 &= ~(data->hyst_mask << data->hyst_shift); 510 ctrl1 |= hysteresis << data->hyst_shift; 511 priv->current_hysteresis = hyst_mc; 512 } 513 514 regmap_write(priv->syscon, data->syscon_control1_off, ctrl1); 515 } 516 517 static irqreturn_t armada_overheat_isr(int irq, void *blob) 518 { 519 /* 520 * Disable the IRQ and continue in thread context (thermal core 521 * notification and temperature monitoring). 522 */ 523 disable_irq_nosync(irq); 524 525 return IRQ_WAKE_THREAD; 526 } 527 528 static irqreturn_t armada_overheat_isr_thread(int irq, void *blob) 529 { 530 struct armada_thermal_priv *priv = blob; 531 int low_threshold = priv->current_threshold - priv->current_hysteresis; 532 int temperature; 533 u32 dummy; 534 int ret; 535 536 /* Notify the core in thread context */ 537 thermal_zone_device_update(priv->overheat_sensor, 538 THERMAL_EVENT_UNSPECIFIED); 539 540 /* 541 * The overheat interrupt must be cleared by reading the DFX interrupt 542 * cause _after_ the temperature has fallen down to the low threshold. 543 * Otherwise future interrupts might not be served. 544 */ 545 do { 546 msleep(OVERHEAT_INT_POLL_DELAY_MS); 547 mutex_lock(&priv->update_lock); 548 ret = armada_read_sensor(priv, &temperature); 549 mutex_unlock(&priv->update_lock); 550 if (ret) 551 goto enable_irq; 552 } while (temperature >= low_threshold); 553 554 regmap_read(priv->syscon, priv->data->dfx_irq_cause_off, &dummy); 555 556 /* Notify the thermal core that the temperature is acceptable again */ 557 thermal_zone_device_update(priv->overheat_sensor, 558 THERMAL_EVENT_UNSPECIFIED); 559 560 enable_irq: 561 enable_irq(irq); 562 563 return IRQ_HANDLED; 564 } 565 566 static const struct armada_thermal_data armadaxp_data = { 567 .init = armadaxp_init, 568 .temp_shift = 10, 569 .temp_mask = 0x1ff, 570 .coef_b = 3153000000ULL, 571 .coef_m = 10000000ULL, 572 .coef_div = 13825, 573 .syscon_status_off = 0xb0, 574 .syscon_control1_off = 0x2d0, 575 }; 576 577 static const struct armada_thermal_data armada370_data = { 578 .init = armada370_init, 579 .is_valid_bit = BIT(9), 580 .temp_shift = 10, 581 .temp_mask = 0x1ff, 582 .coef_b = 3153000000ULL, 583 .coef_m = 10000000ULL, 584 .coef_div = 13825, 585 .syscon_status_off = 0x0, 586 .syscon_control1_off = 0x4, 587 }; 588 589 static const struct armada_thermal_data armada375_data = { 590 .init = armada375_init, 591 .is_valid_bit = BIT(10), 592 .temp_shift = 0, 593 .temp_mask = 0x1ff, 594 .coef_b = 3171900000ULL, 595 .coef_m = 10000000ULL, 596 .coef_div = 13616, 597 .syscon_status_off = 0x78, 598 .syscon_control0_off = 0x7c, 599 .syscon_control1_off = 0x80, 600 }; 601 602 static const struct armada_thermal_data armada380_data = { 603 .init = armada380_init, 604 .is_valid_bit = BIT(10), 605 .temp_shift = 0, 606 .temp_mask = 0x3ff, 607 .coef_b = 1172499100ULL, 608 .coef_m = 2000096ULL, 609 .coef_div = 4201, 610 .inverted = true, 611 .syscon_control0_off = 0x70, 612 .syscon_control1_off = 0x74, 613 .syscon_status_off = 0x78, 614 }; 615 616 static const struct armada_thermal_data armada_ap806_data = { 617 .init = armada_ap806_init, 618 .is_valid_bit = BIT(16), 619 .temp_shift = 0, 620 .temp_mask = 0x3ff, 621 .thresh_shift = 3, 622 .hyst_shift = 19, 623 .hyst_mask = 0x3, 624 .coef_b = -150000LL, 625 .coef_m = 423ULL, 626 .coef_div = 1, 627 .inverted = true, 628 .signed_sample = true, 629 .syscon_control0_off = 0x84, 630 .syscon_control1_off = 0x88, 631 .syscon_status_off = 0x8C, 632 .dfx_irq_cause_off = 0x108, 633 .dfx_irq_mask_off = 0x10C, 634 .dfx_overheat_irq = BIT(22), 635 .dfx_server_irq_mask_off = 0x104, 636 .dfx_server_irq_en = BIT(1), 637 .cpu_nr = 4, 638 }; 639 640 static const struct armada_thermal_data armada_cp110_data = { 641 .init = armada_cp110_init, 642 .is_valid_bit = BIT(10), 643 .temp_shift = 0, 644 .temp_mask = 0x3ff, 645 .thresh_shift = 16, 646 .hyst_shift = 26, 647 .hyst_mask = 0x3, 648 .coef_b = 1172499100ULL, 649 .coef_m = 2000096ULL, 650 .coef_div = 4201, 651 .inverted = true, 652 .syscon_control0_off = 0x70, 653 .syscon_control1_off = 0x74, 654 .syscon_status_off = 0x78, 655 .dfx_irq_cause_off = 0x108, 656 .dfx_irq_mask_off = 0x10C, 657 .dfx_overheat_irq = BIT(20), 658 .dfx_server_irq_mask_off = 0x104, 659 .dfx_server_irq_en = BIT(1), 660 }; 661 662 static const struct of_device_id armada_thermal_id_table[] = { 663 { 664 .compatible = "marvell,armadaxp-thermal", 665 .data = &armadaxp_data, 666 }, 667 { 668 .compatible = "marvell,armada370-thermal", 669 .data = &armada370_data, 670 }, 671 { 672 .compatible = "marvell,armada375-thermal", 673 .data = &armada375_data, 674 }, 675 { 676 .compatible = "marvell,armada380-thermal", 677 .data = &armada380_data, 678 }, 679 { 680 .compatible = "marvell,armada-ap806-thermal", 681 .data = &armada_ap806_data, 682 }, 683 { 684 .compatible = "marvell,armada-cp110-thermal", 685 .data = &armada_cp110_data, 686 }, 687 { 688 /* sentinel */ 689 }, 690 }; 691 MODULE_DEVICE_TABLE(of, armada_thermal_id_table); 692 693 static const struct regmap_config armada_thermal_regmap_config = { 694 .reg_bits = 32, 695 .reg_stride = 4, 696 .val_bits = 32, 697 .fast_io = true, 698 }; 699 700 static int armada_thermal_probe_legacy(struct platform_device *pdev, 701 struct armada_thermal_priv *priv) 702 { 703 struct armada_thermal_data *data = priv->data; 704 void __iomem *base; 705 706 /* First memory region points towards the status register */ 707 base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 708 if (IS_ERR(base)) 709 return PTR_ERR(base); 710 711 /* 712 * Fix up from the old individual DT register specification to 713 * cover all the registers. We do this by adjusting the ioremap() 714 * result, which should be fine as ioremap() deals with pages. 715 * However, validate that we do not cross a page boundary while 716 * making this adjustment. 717 */ 718 if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off) 719 return -EINVAL; 720 base -= data->syscon_status_off; 721 722 priv->syscon = devm_regmap_init_mmio(&pdev->dev, base, 723 &armada_thermal_regmap_config); 724 return PTR_ERR_OR_ZERO(priv->syscon); 725 } 726 727 static int armada_thermal_probe_syscon(struct platform_device *pdev, 728 struct armada_thermal_priv *priv) 729 { 730 priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node); 731 return PTR_ERR_OR_ZERO(priv->syscon); 732 } 733 734 static void armada_set_sane_name(struct platform_device *pdev, 735 struct armada_thermal_priv *priv) 736 { 737 const char *name = dev_name(&pdev->dev); 738 char *insane_char; 739 740 if (strlen(name) > THERMAL_NAME_LENGTH) { 741 /* 742 * When inside a system controller, the device name has the 743 * form: f06f8000.system-controller:ap-thermal so stripping 744 * after the ':' should give us a shorter but meaningful name. 745 */ 746 name = strrchr(name, ':'); 747 if (!name) 748 name = "armada_thermal"; 749 else 750 name++; 751 } 752 753 /* Save the name locally */ 754 strscpy(priv->zone_name, name, THERMAL_NAME_LENGTH); 755 756 /* Then check there are no '-' or hwmon core will complain */ 757 do { 758 insane_char = strpbrk(priv->zone_name, "-"); 759 if (insane_char) 760 *insane_char = '_'; 761 } while (insane_char); 762 } 763 764 /* 765 * The IP can manage to trigger interrupts on overheat situation from all the 766 * sensors. However, the interrupt source changes along with the last selected 767 * source (ie. the last read sensor), which is an inconsistent behavior. Avoid 768 * possible glitches by always selecting back only one channel (arbitrarily: the 769 * first in the DT which has a critical trip point). We also disable sensor 770 * switch during overheat situations. 771 */ 772 static int armada_configure_overheat_int(struct armada_thermal_priv *priv, 773 struct thermal_zone_device *tz, 774 int sensor_id) 775 { 776 /* Retrieve the critical trip point to enable the overheat interrupt */ 777 int temperature; 778 int ret; 779 780 ret = thermal_zone_get_crit_temp(tz, &temperature); 781 if (ret) 782 return ret; 783 784 ret = armada_select_channel(priv, sensor_id); 785 if (ret) 786 return ret; 787 788 /* 789 * A critical temperature does not have a hysteresis 790 */ 791 armada_set_overheat_thresholds(priv, temperature, 0); 792 priv->overheat_sensor = tz; 793 priv->interrupt_source = sensor_id; 794 armada_enable_overheat_interrupt(priv); 795 796 return 0; 797 } 798 799 static int armada_thermal_probe(struct platform_device *pdev) 800 { 801 struct thermal_zone_device *tz; 802 struct armada_thermal_sensor *sensor; 803 struct armada_drvdata *drvdata; 804 const struct of_device_id *match; 805 struct armada_thermal_priv *priv; 806 int sensor_id, irq; 807 int ret; 808 809 match = of_match_device(armada_thermal_id_table, &pdev->dev); 810 if (!match) 811 return -ENODEV; 812 813 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 814 if (!priv) 815 return -ENOMEM; 816 817 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 818 if (!drvdata) 819 return -ENOMEM; 820 821 priv->dev = &pdev->dev; 822 priv->data = (struct armada_thermal_data *)match->data; 823 824 mutex_init(&priv->update_lock); 825 826 /* 827 * Legacy DT bindings only described "control1" register (also referred 828 * as "control MSB" on old documentation). Then, bindings moved to cover 829 * "control0/control LSB" and "control1/control MSB" registers within 830 * the same resource, which was then of size 8 instead of 4. 831 * 832 * The logic of defining sporadic registers is broken. For instance, it 833 * blocked the addition of the overheat interrupt feature that needed 834 * another resource somewhere else in the same memory area. One solution 835 * is to define an overall system controller and put the thermal node 836 * into it, which requires the use of regmaps across all the driver. 837 */ 838 if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) { 839 /* Ensure device name is correct for the thermal core */ 840 armada_set_sane_name(pdev, priv); 841 842 ret = armada_thermal_probe_legacy(pdev, priv); 843 if (ret) 844 return ret; 845 846 priv->data->init(pdev, priv); 847 848 /* Wait the sensors to be valid */ 849 armada_wait_sensor_validity(priv); 850 851 tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv, 852 &legacy_ops, NULL, 0, 0); 853 if (IS_ERR(tz)) { 854 dev_err(&pdev->dev, 855 "Failed to register thermal zone device\n"); 856 return PTR_ERR(tz); 857 } 858 859 ret = thermal_zone_device_enable(tz); 860 if (ret) { 861 thermal_zone_device_unregister(tz); 862 return ret; 863 } 864 865 drvdata->type = LEGACY; 866 drvdata->data.tz = tz; 867 platform_set_drvdata(pdev, drvdata); 868 869 return 0; 870 } 871 872 ret = armada_thermal_probe_syscon(pdev, priv); 873 if (ret) 874 return ret; 875 876 priv->current_channel = -1; 877 priv->data->init(pdev, priv); 878 drvdata->type = SYSCON; 879 drvdata->data.priv = priv; 880 platform_set_drvdata(pdev, drvdata); 881 882 irq = platform_get_irq(pdev, 0); 883 if (irq == -EPROBE_DEFER) 884 return irq; 885 886 /* The overheat interrupt feature is not mandatory */ 887 if (irq > 0) { 888 ret = devm_request_threaded_irq(&pdev->dev, irq, 889 armada_overheat_isr, 890 armada_overheat_isr_thread, 891 0, NULL, priv); 892 if (ret) { 893 dev_err(&pdev->dev, "Cannot request threaded IRQ %d\n", 894 irq); 895 return ret; 896 } 897 } 898 899 /* 900 * There is one channel for the IC and one per CPU (if any), each 901 * channel has one sensor. 902 */ 903 for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) { 904 sensor = devm_kzalloc(&pdev->dev, 905 sizeof(struct armada_thermal_sensor), 906 GFP_KERNEL); 907 if (!sensor) 908 return -ENOMEM; 909 910 /* Register the sensor */ 911 sensor->priv = priv; 912 sensor->id = sensor_id; 913 tz = devm_thermal_of_zone_register(&pdev->dev, 914 sensor->id, sensor, 915 &of_ops); 916 if (IS_ERR(tz)) { 917 dev_info(&pdev->dev, "Thermal sensor %d unavailable\n", 918 sensor_id); 919 devm_kfree(&pdev->dev, sensor); 920 continue; 921 } 922 923 /* 924 * The first channel that has a critical trip point registered 925 * in the DT will serve as interrupt source. Others possible 926 * critical trip points will simply be ignored by the driver. 927 */ 928 if (irq > 0 && !priv->overheat_sensor) 929 armada_configure_overheat_int(priv, tz, sensor->id); 930 } 931 932 /* Just complain if no overheat interrupt was set up */ 933 if (!priv->overheat_sensor) 934 dev_warn(&pdev->dev, "Overheat interrupt not available\n"); 935 936 return 0; 937 } 938 939 static int armada_thermal_exit(struct platform_device *pdev) 940 { 941 struct armada_drvdata *drvdata = platform_get_drvdata(pdev); 942 943 if (drvdata->type == LEGACY) 944 thermal_zone_device_unregister(drvdata->data.tz); 945 946 return 0; 947 } 948 949 static struct platform_driver armada_thermal_driver = { 950 .probe = armada_thermal_probe, 951 .remove = armada_thermal_exit, 952 .driver = { 953 .name = "armada_thermal", 954 .of_match_table = armada_thermal_id_table, 955 }, 956 }; 957 958 module_platform_driver(armada_thermal_driver); 959 960 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>"); 961 MODULE_DESCRIPTION("Marvell EBU Armada SoCs thermal driver"); 962 MODULE_LICENSE("GPL v2"); 963