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