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