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