1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * intel_soc_dts_iosf.c 4 * Copyright (c) 2015, Intel Corporation. 5 */ 6 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 9 #include <linux/bitops.h> 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 #include <linux/interrupt.h> 13 #include <asm/iosf_mbi.h> 14 #include "intel_soc_dts_iosf.h" 15 16 #define SOC_DTS_OFFSET_ENABLE 0xB0 17 #define SOC_DTS_OFFSET_TEMP 0xB1 18 19 #define SOC_DTS_OFFSET_PTPS 0xB2 20 #define SOC_DTS_OFFSET_PTTS 0xB3 21 #define SOC_DTS_OFFSET_PTTSS 0xB4 22 #define SOC_DTS_OFFSET_PTMC 0x80 23 #define SOC_DTS_TE_AUX0 0xB5 24 #define SOC_DTS_TE_AUX1 0xB6 25 26 #define SOC_DTS_AUX0_ENABLE_BIT BIT(0) 27 #define SOC_DTS_AUX1_ENABLE_BIT BIT(1) 28 #define SOC_DTS_CPU_MODULE0_ENABLE_BIT BIT(16) 29 #define SOC_DTS_CPU_MODULE1_ENABLE_BIT BIT(17) 30 #define SOC_DTS_TE_SCI_ENABLE BIT(9) 31 #define SOC_DTS_TE_SMI_ENABLE BIT(10) 32 #define SOC_DTS_TE_MSI_ENABLE BIT(11) 33 #define SOC_DTS_TE_APICA_ENABLE BIT(14) 34 #define SOC_DTS_PTMC_APIC_DEASSERT_BIT BIT(4) 35 36 /* DTS encoding for TJ MAX temperature */ 37 #define SOC_DTS_TJMAX_ENCODING 0x7F 38 39 /* Only 2 out of 4 is allowed for OSPM */ 40 #define SOC_MAX_DTS_TRIPS 2 41 42 /* Mask for two trips in status bits */ 43 #define SOC_DTS_TRIP_MASK 0x03 44 45 /* DTS0 and DTS 1 */ 46 #define SOC_MAX_DTS_SENSORS 2 47 48 static int get_tj_max(u32 *tj_max) 49 { 50 u32 eax, edx; 51 u32 val; 52 int err; 53 54 err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); 55 if (err) 56 goto err_ret; 57 else { 58 val = (eax >> 16) & 0xff; 59 if (val) 60 *tj_max = val * 1000; 61 else { 62 err = -EINVAL; 63 goto err_ret; 64 } 65 } 66 67 return 0; 68 err_ret: 69 *tj_max = 0; 70 71 return err; 72 } 73 74 static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip, 75 int *temp) 76 { 77 int status; 78 u32 out; 79 struct intel_soc_dts_sensor_entry *dts; 80 struct intel_soc_dts_sensors *sensors; 81 82 dts = tzd->devdata; 83 sensors = dts->sensors; 84 mutex_lock(&sensors->dts_update_lock); 85 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 86 SOC_DTS_OFFSET_PTPS, &out); 87 mutex_unlock(&sensors->dts_update_lock); 88 if (status) 89 return status; 90 91 out = (out >> (trip * 8)) & SOC_DTS_TJMAX_ENCODING; 92 if (!out) 93 *temp = 0; 94 else 95 *temp = sensors->tj_max - out * 1000; 96 97 return 0; 98 } 99 100 static int update_trip_temp(struct intel_soc_dts_sensor_entry *dts, 101 int thres_index, int temp, 102 enum thermal_trip_type trip_type) 103 { 104 int status; 105 u32 temp_out; 106 u32 out; 107 unsigned long update_ptps; 108 u32 store_ptps; 109 u32 store_ptmc; 110 u32 store_te_out; 111 u32 te_out; 112 u32 int_enable_bit = SOC_DTS_TE_APICA_ENABLE; 113 struct intel_soc_dts_sensors *sensors = dts->sensors; 114 115 if (sensors->intr_type == INTEL_SOC_DTS_INTERRUPT_MSI) 116 int_enable_bit |= SOC_DTS_TE_MSI_ENABLE; 117 118 temp_out = (sensors->tj_max - temp) / 1000; 119 120 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 121 SOC_DTS_OFFSET_PTPS, &store_ptps); 122 if (status) 123 return status; 124 125 update_ptps = store_ptps; 126 bitmap_set_value8(&update_ptps, temp_out & 0xFF, thres_index * 8); 127 out = update_ptps; 128 129 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 130 SOC_DTS_OFFSET_PTPS, out); 131 if (status) 132 return status; 133 134 pr_debug("update_trip_temp PTPS = %x\n", out); 135 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 136 SOC_DTS_OFFSET_PTMC, &out); 137 if (status) 138 goto err_restore_ptps; 139 140 store_ptmc = out; 141 142 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 143 SOC_DTS_TE_AUX0 + thres_index, 144 &te_out); 145 if (status) 146 goto err_restore_ptmc; 147 148 store_te_out = te_out; 149 /* Enable for CPU module 0 and module 1 */ 150 out |= (SOC_DTS_CPU_MODULE0_ENABLE_BIT | 151 SOC_DTS_CPU_MODULE1_ENABLE_BIT); 152 if (temp) { 153 if (thres_index) 154 out |= SOC_DTS_AUX1_ENABLE_BIT; 155 else 156 out |= SOC_DTS_AUX0_ENABLE_BIT; 157 te_out |= int_enable_bit; 158 } else { 159 if (thres_index) 160 out &= ~SOC_DTS_AUX1_ENABLE_BIT; 161 else 162 out &= ~SOC_DTS_AUX0_ENABLE_BIT; 163 te_out &= ~int_enable_bit; 164 } 165 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 166 SOC_DTS_OFFSET_PTMC, out); 167 if (status) 168 goto err_restore_te_out; 169 170 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 171 SOC_DTS_TE_AUX0 + thres_index, 172 te_out); 173 if (status) 174 goto err_restore_te_out; 175 176 dts->trip_types[thres_index] = trip_type; 177 178 return 0; 179 err_restore_te_out: 180 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 181 SOC_DTS_OFFSET_PTMC, store_te_out); 182 err_restore_ptmc: 183 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 184 SOC_DTS_OFFSET_PTMC, store_ptmc); 185 err_restore_ptps: 186 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 187 SOC_DTS_OFFSET_PTPS, store_ptps); 188 /* Nothing we can do if restore fails */ 189 190 return status; 191 } 192 193 static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, 194 int temp) 195 { 196 struct intel_soc_dts_sensor_entry *dts = tzd->devdata; 197 struct intel_soc_dts_sensors *sensors = dts->sensors; 198 int status; 199 200 if (temp > sensors->tj_max) 201 return -EINVAL; 202 203 mutex_lock(&sensors->dts_update_lock); 204 status = update_trip_temp(tzd->devdata, trip, temp, 205 dts->trip_types[trip]); 206 mutex_unlock(&sensors->dts_update_lock); 207 208 return status; 209 } 210 211 static int sys_get_trip_type(struct thermal_zone_device *tzd, 212 int trip, enum thermal_trip_type *type) 213 { 214 struct intel_soc_dts_sensor_entry *dts; 215 216 dts = tzd->devdata; 217 218 *type = dts->trip_types[trip]; 219 220 return 0; 221 } 222 223 static int sys_get_curr_temp(struct thermal_zone_device *tzd, 224 int *temp) 225 { 226 int status; 227 u32 out; 228 struct intel_soc_dts_sensor_entry *dts; 229 struct intel_soc_dts_sensors *sensors; 230 unsigned long raw; 231 232 dts = tzd->devdata; 233 sensors = dts->sensors; 234 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 235 SOC_DTS_OFFSET_TEMP, &out); 236 if (status) 237 return status; 238 239 raw = out; 240 out = bitmap_get_value8(&raw, dts->id * 8) - SOC_DTS_TJMAX_ENCODING; 241 *temp = sensors->tj_max - out * 1000; 242 243 return 0; 244 } 245 246 static struct thermal_zone_device_ops tzone_ops = { 247 .get_temp = sys_get_curr_temp, 248 .get_trip_temp = sys_get_trip_temp, 249 .get_trip_type = sys_get_trip_type, 250 .set_trip_temp = sys_set_trip_temp, 251 }; 252 253 static int soc_dts_enable(int id) 254 { 255 u32 out; 256 int ret; 257 258 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 259 SOC_DTS_OFFSET_ENABLE, &out); 260 if (ret) 261 return ret; 262 263 if (!(out & BIT(id))) { 264 out |= BIT(id); 265 ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 266 SOC_DTS_OFFSET_ENABLE, out); 267 if (ret) 268 return ret; 269 } 270 271 return ret; 272 } 273 274 static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *dts) 275 { 276 if (dts) { 277 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 278 SOC_DTS_OFFSET_ENABLE, dts->store_status); 279 thermal_zone_device_unregister(dts->tzone); 280 } 281 } 282 283 static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts, 284 bool notification_support, int trip_cnt, 285 int read_only_trip_cnt) 286 { 287 char name[10]; 288 unsigned long trip; 289 int trip_count = 0; 290 int trip_mask = 0; 291 int writable_trip_cnt = 0; 292 unsigned long ptps; 293 u32 store_ptps; 294 unsigned long i; 295 int ret; 296 297 /* Store status to restor on exit */ 298 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 299 SOC_DTS_OFFSET_ENABLE, &dts->store_status); 300 if (ret) 301 goto err_ret; 302 303 dts->id = id; 304 if (notification_support) { 305 trip_count = min(SOC_MAX_DTS_TRIPS, trip_cnt); 306 writable_trip_cnt = trip_count - read_only_trip_cnt; 307 trip_mask = GENMASK(writable_trip_cnt - 1, 0); 308 } 309 310 /* Check if the writable trip we provide is not used by BIOS */ 311 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 312 SOC_DTS_OFFSET_PTPS, &store_ptps); 313 if (ret) 314 trip_mask = 0; 315 else { 316 ptps = store_ptps; 317 for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8) 318 trip_mask &= ~BIT(i / 8); 319 } 320 dts->trip_mask = trip_mask; 321 dts->trip_count = trip_count; 322 snprintf(name, sizeof(name), "soc_dts%d", id); 323 dts->tzone = thermal_zone_device_register(name, 324 trip_count, 325 trip_mask, 326 dts, &tzone_ops, 327 NULL, 0, 0); 328 if (IS_ERR(dts->tzone)) { 329 ret = PTR_ERR(dts->tzone); 330 goto err_ret; 331 } 332 ret = thermal_zone_device_enable(dts->tzone); 333 if (ret) 334 goto err_enable; 335 336 ret = soc_dts_enable(id); 337 if (ret) 338 goto err_enable; 339 340 return 0; 341 err_enable: 342 thermal_zone_device_unregister(dts->tzone); 343 err_ret: 344 return ret; 345 } 346 347 int intel_soc_dts_iosf_add_read_only_critical_trip( 348 struct intel_soc_dts_sensors *sensors, int critical_offset) 349 { 350 int i, j; 351 352 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { 353 for (j = 0; j < sensors->soc_dts[i].trip_count; ++j) { 354 if (!(sensors->soc_dts[i].trip_mask & BIT(j))) { 355 return update_trip_temp(&sensors->soc_dts[i], j, 356 sensors->tj_max - critical_offset, 357 THERMAL_TRIP_CRITICAL); 358 } 359 } 360 } 361 362 return -EINVAL; 363 } 364 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_add_read_only_critical_trip); 365 366 void intel_soc_dts_iosf_interrupt_handler(struct intel_soc_dts_sensors *sensors) 367 { 368 u32 sticky_out; 369 int status; 370 u32 ptmc_out; 371 unsigned long flags; 372 373 spin_lock_irqsave(&sensors->intr_notify_lock, flags); 374 375 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 376 SOC_DTS_OFFSET_PTMC, &ptmc_out); 377 ptmc_out |= SOC_DTS_PTMC_APIC_DEASSERT_BIT; 378 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 379 SOC_DTS_OFFSET_PTMC, ptmc_out); 380 381 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, 382 SOC_DTS_OFFSET_PTTSS, &sticky_out); 383 pr_debug("status %d PTTSS %x\n", status, sticky_out); 384 if (sticky_out & SOC_DTS_TRIP_MASK) { 385 int i; 386 /* reset sticky bit */ 387 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, 388 SOC_DTS_OFFSET_PTTSS, sticky_out); 389 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags); 390 391 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { 392 pr_debug("TZD update for zone %d\n", i); 393 thermal_zone_device_update(sensors->soc_dts[i].tzone, 394 THERMAL_EVENT_UNSPECIFIED); 395 } 396 } else 397 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags); 398 } 399 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler); 400 401 struct intel_soc_dts_sensors *intel_soc_dts_iosf_init( 402 enum intel_soc_dts_interrupt_type intr_type, int trip_count, 403 int read_only_trip_count) 404 { 405 struct intel_soc_dts_sensors *sensors; 406 bool notification; 407 u32 tj_max; 408 int ret; 409 int i; 410 411 if (!iosf_mbi_available()) 412 return ERR_PTR(-ENODEV); 413 414 if (!trip_count || read_only_trip_count > trip_count) 415 return ERR_PTR(-EINVAL); 416 417 if (get_tj_max(&tj_max)) 418 return ERR_PTR(-EINVAL); 419 420 sensors = kzalloc(sizeof(*sensors), GFP_KERNEL); 421 if (!sensors) 422 return ERR_PTR(-ENOMEM); 423 424 spin_lock_init(&sensors->intr_notify_lock); 425 mutex_init(&sensors->dts_update_lock); 426 sensors->intr_type = intr_type; 427 sensors->tj_max = tj_max; 428 if (intr_type == INTEL_SOC_DTS_INTERRUPT_NONE) 429 notification = false; 430 else 431 notification = true; 432 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { 433 sensors->soc_dts[i].sensors = sensors; 434 ret = add_dts_thermal_zone(i, &sensors->soc_dts[i], 435 notification, trip_count, 436 read_only_trip_count); 437 if (ret) 438 goto err_free; 439 } 440 441 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { 442 ret = update_trip_temp(&sensors->soc_dts[i], 0, 0, 443 THERMAL_TRIP_PASSIVE); 444 if (ret) 445 goto err_remove_zone; 446 447 ret = update_trip_temp(&sensors->soc_dts[i], 1, 0, 448 THERMAL_TRIP_PASSIVE); 449 if (ret) 450 goto err_remove_zone; 451 } 452 453 return sensors; 454 err_remove_zone: 455 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) 456 remove_dts_thermal_zone(&sensors->soc_dts[i]); 457 458 err_free: 459 kfree(sensors); 460 return ERR_PTR(ret); 461 } 462 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_init); 463 464 void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors) 465 { 466 int i; 467 468 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { 469 update_trip_temp(&sensors->soc_dts[i], 0, 0, 0); 470 update_trip_temp(&sensors->soc_dts[i], 1, 0, 0); 471 remove_dts_thermal_zone(&sensors->soc_dts[i]); 472 } 473 kfree(sensors); 474 } 475 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit); 476 477 MODULE_LICENSE("GPL v2"); 478