0001
0002
0003
0004
0005
0006
0007 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0008
0009 #include <linux/bitops.h>
0010 #include <linux/module.h>
0011 #include <linux/slab.h>
0012 #include <linux/interrupt.h>
0013 #include <asm/iosf_mbi.h>
0014 #include "intel_soc_dts_iosf.h"
0015
0016 #define SOC_DTS_OFFSET_ENABLE 0xB0
0017 #define SOC_DTS_OFFSET_TEMP 0xB1
0018
0019 #define SOC_DTS_OFFSET_PTPS 0xB2
0020 #define SOC_DTS_OFFSET_PTTS 0xB3
0021 #define SOC_DTS_OFFSET_PTTSS 0xB4
0022 #define SOC_DTS_OFFSET_PTMC 0x80
0023 #define SOC_DTS_TE_AUX0 0xB5
0024 #define SOC_DTS_TE_AUX1 0xB6
0025
0026 #define SOC_DTS_AUX0_ENABLE_BIT BIT(0)
0027 #define SOC_DTS_AUX1_ENABLE_BIT BIT(1)
0028 #define SOC_DTS_CPU_MODULE0_ENABLE_BIT BIT(16)
0029 #define SOC_DTS_CPU_MODULE1_ENABLE_BIT BIT(17)
0030 #define SOC_DTS_TE_SCI_ENABLE BIT(9)
0031 #define SOC_DTS_TE_SMI_ENABLE BIT(10)
0032 #define SOC_DTS_TE_MSI_ENABLE BIT(11)
0033 #define SOC_DTS_TE_APICA_ENABLE BIT(14)
0034 #define SOC_DTS_PTMC_APIC_DEASSERT_BIT BIT(4)
0035
0036
0037 #define SOC_DTS_TJMAX_ENCODING 0x7F
0038
0039
0040 #define SOC_MAX_DTS_TRIPS 2
0041
0042
0043 #define SOC_DTS_TRIP_MASK 0x03
0044
0045
0046 #define SOC_MAX_DTS_SENSORS 2
0047
0048 static int get_tj_max(u32 *tj_max)
0049 {
0050 u32 eax, edx;
0051 u32 val;
0052 int err;
0053
0054 err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
0055 if (err)
0056 goto err_ret;
0057 else {
0058 val = (eax >> 16) & 0xff;
0059 if (val)
0060 *tj_max = val * 1000;
0061 else {
0062 err = -EINVAL;
0063 goto err_ret;
0064 }
0065 }
0066
0067 return 0;
0068 err_ret:
0069 *tj_max = 0;
0070
0071 return err;
0072 }
0073
0074 static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip,
0075 int *temp)
0076 {
0077 int status;
0078 u32 out;
0079 struct intel_soc_dts_sensor_entry *dts;
0080 struct intel_soc_dts_sensors *sensors;
0081
0082 dts = tzd->devdata;
0083 sensors = dts->sensors;
0084 mutex_lock(&sensors->dts_update_lock);
0085 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0086 SOC_DTS_OFFSET_PTPS, &out);
0087 mutex_unlock(&sensors->dts_update_lock);
0088 if (status)
0089 return status;
0090
0091 out = (out >> (trip * 8)) & SOC_DTS_TJMAX_ENCODING;
0092 if (!out)
0093 *temp = 0;
0094 else
0095 *temp = sensors->tj_max - out * 1000;
0096
0097 return 0;
0098 }
0099
0100 static int update_trip_temp(struct intel_soc_dts_sensor_entry *dts,
0101 int thres_index, int temp,
0102 enum thermal_trip_type trip_type)
0103 {
0104 int status;
0105 u32 temp_out;
0106 u32 out;
0107 unsigned long update_ptps;
0108 u32 store_ptps;
0109 u32 store_ptmc;
0110 u32 store_te_out;
0111 u32 te_out;
0112 u32 int_enable_bit = SOC_DTS_TE_APICA_ENABLE;
0113 struct intel_soc_dts_sensors *sensors = dts->sensors;
0114
0115 if (sensors->intr_type == INTEL_SOC_DTS_INTERRUPT_MSI)
0116 int_enable_bit |= SOC_DTS_TE_MSI_ENABLE;
0117
0118 temp_out = (sensors->tj_max - temp) / 1000;
0119
0120 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0121 SOC_DTS_OFFSET_PTPS, &store_ptps);
0122 if (status)
0123 return status;
0124
0125 update_ptps = store_ptps;
0126 bitmap_set_value8(&update_ptps, temp_out & 0xFF, thres_index * 8);
0127 out = update_ptps;
0128
0129 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0130 SOC_DTS_OFFSET_PTPS, out);
0131 if (status)
0132 return status;
0133
0134 pr_debug("update_trip_temp PTPS = %x\n", out);
0135 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0136 SOC_DTS_OFFSET_PTMC, &out);
0137 if (status)
0138 goto err_restore_ptps;
0139
0140 store_ptmc = out;
0141
0142 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0143 SOC_DTS_TE_AUX0 + thres_index,
0144 &te_out);
0145 if (status)
0146 goto err_restore_ptmc;
0147
0148 store_te_out = te_out;
0149
0150 out |= (SOC_DTS_CPU_MODULE0_ENABLE_BIT |
0151 SOC_DTS_CPU_MODULE1_ENABLE_BIT);
0152 if (temp) {
0153 if (thres_index)
0154 out |= SOC_DTS_AUX1_ENABLE_BIT;
0155 else
0156 out |= SOC_DTS_AUX0_ENABLE_BIT;
0157 te_out |= int_enable_bit;
0158 } else {
0159 if (thres_index)
0160 out &= ~SOC_DTS_AUX1_ENABLE_BIT;
0161 else
0162 out &= ~SOC_DTS_AUX0_ENABLE_BIT;
0163 te_out &= ~int_enable_bit;
0164 }
0165 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0166 SOC_DTS_OFFSET_PTMC, out);
0167 if (status)
0168 goto err_restore_te_out;
0169
0170 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0171 SOC_DTS_TE_AUX0 + thres_index,
0172 te_out);
0173 if (status)
0174 goto err_restore_te_out;
0175
0176 dts->trip_types[thres_index] = trip_type;
0177
0178 return 0;
0179 err_restore_te_out:
0180 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0181 SOC_DTS_OFFSET_PTMC, store_te_out);
0182 err_restore_ptmc:
0183 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0184 SOC_DTS_OFFSET_PTMC, store_ptmc);
0185 err_restore_ptps:
0186 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0187 SOC_DTS_OFFSET_PTPS, store_ptps);
0188
0189
0190 return status;
0191 }
0192
0193 static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
0194 int temp)
0195 {
0196 struct intel_soc_dts_sensor_entry *dts = tzd->devdata;
0197 struct intel_soc_dts_sensors *sensors = dts->sensors;
0198 int status;
0199
0200 if (temp > sensors->tj_max)
0201 return -EINVAL;
0202
0203 mutex_lock(&sensors->dts_update_lock);
0204 status = update_trip_temp(tzd->devdata, trip, temp,
0205 dts->trip_types[trip]);
0206 mutex_unlock(&sensors->dts_update_lock);
0207
0208 return status;
0209 }
0210
0211 static int sys_get_trip_type(struct thermal_zone_device *tzd,
0212 int trip, enum thermal_trip_type *type)
0213 {
0214 struct intel_soc_dts_sensor_entry *dts;
0215
0216 dts = tzd->devdata;
0217
0218 *type = dts->trip_types[trip];
0219
0220 return 0;
0221 }
0222
0223 static int sys_get_curr_temp(struct thermal_zone_device *tzd,
0224 int *temp)
0225 {
0226 int status;
0227 u32 out;
0228 struct intel_soc_dts_sensor_entry *dts;
0229 struct intel_soc_dts_sensors *sensors;
0230 unsigned long raw;
0231
0232 dts = tzd->devdata;
0233 sensors = dts->sensors;
0234 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0235 SOC_DTS_OFFSET_TEMP, &out);
0236 if (status)
0237 return status;
0238
0239 raw = out;
0240 out = bitmap_get_value8(&raw, dts->id * 8) - SOC_DTS_TJMAX_ENCODING;
0241 *temp = sensors->tj_max - out * 1000;
0242
0243 return 0;
0244 }
0245
0246 static struct thermal_zone_device_ops tzone_ops = {
0247 .get_temp = sys_get_curr_temp,
0248 .get_trip_temp = sys_get_trip_temp,
0249 .get_trip_type = sys_get_trip_type,
0250 .set_trip_temp = sys_set_trip_temp,
0251 };
0252
0253 static int soc_dts_enable(int id)
0254 {
0255 u32 out;
0256 int ret;
0257
0258 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0259 SOC_DTS_OFFSET_ENABLE, &out);
0260 if (ret)
0261 return ret;
0262
0263 if (!(out & BIT(id))) {
0264 out |= BIT(id);
0265 ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0266 SOC_DTS_OFFSET_ENABLE, out);
0267 if (ret)
0268 return ret;
0269 }
0270
0271 return ret;
0272 }
0273
0274 static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *dts)
0275 {
0276 if (dts) {
0277 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0278 SOC_DTS_OFFSET_ENABLE, dts->store_status);
0279 thermal_zone_device_unregister(dts->tzone);
0280 }
0281 }
0282
0283 static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
0284 bool notification_support, int trip_cnt,
0285 int read_only_trip_cnt)
0286 {
0287 char name[10];
0288 unsigned long trip;
0289 int trip_count = 0;
0290 int trip_mask = 0;
0291 int writable_trip_cnt = 0;
0292 unsigned long ptps;
0293 u32 store_ptps;
0294 unsigned long i;
0295 int ret;
0296
0297
0298 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0299 SOC_DTS_OFFSET_ENABLE, &dts->store_status);
0300 if (ret)
0301 goto err_ret;
0302
0303 dts->id = id;
0304 if (notification_support) {
0305 trip_count = min(SOC_MAX_DTS_TRIPS, trip_cnt);
0306 writable_trip_cnt = trip_count - read_only_trip_cnt;
0307 trip_mask = GENMASK(writable_trip_cnt - 1, 0);
0308 }
0309
0310
0311 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0312 SOC_DTS_OFFSET_PTPS, &store_ptps);
0313 if (ret)
0314 trip_mask = 0;
0315 else {
0316 ptps = store_ptps;
0317 for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8)
0318 trip_mask &= ~BIT(i / 8);
0319 }
0320 dts->trip_mask = trip_mask;
0321 dts->trip_count = trip_count;
0322 snprintf(name, sizeof(name), "soc_dts%d", id);
0323 dts->tzone = thermal_zone_device_register(name,
0324 trip_count,
0325 trip_mask,
0326 dts, &tzone_ops,
0327 NULL, 0, 0);
0328 if (IS_ERR(dts->tzone)) {
0329 ret = PTR_ERR(dts->tzone);
0330 goto err_ret;
0331 }
0332 ret = thermal_zone_device_enable(dts->tzone);
0333 if (ret)
0334 goto err_enable;
0335
0336 ret = soc_dts_enable(id);
0337 if (ret)
0338 goto err_enable;
0339
0340 return 0;
0341 err_enable:
0342 thermal_zone_device_unregister(dts->tzone);
0343 err_ret:
0344 return ret;
0345 }
0346
0347 int intel_soc_dts_iosf_add_read_only_critical_trip(
0348 struct intel_soc_dts_sensors *sensors, int critical_offset)
0349 {
0350 int i, j;
0351
0352 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
0353 struct intel_soc_dts_sensor_entry *entry = &sensors->soc_dts[i];
0354 int temp = sensors->tj_max - critical_offset;
0355 unsigned long count = entry->trip_count;
0356 unsigned long mask = entry->trip_mask;
0357
0358 j = find_first_zero_bit(&mask, count);
0359 if (j < count)
0360 return update_trip_temp(entry, j, temp, THERMAL_TRIP_CRITICAL);
0361 }
0362
0363 return -EINVAL;
0364 }
0365 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_add_read_only_critical_trip);
0366
0367 void intel_soc_dts_iosf_interrupt_handler(struct intel_soc_dts_sensors *sensors)
0368 {
0369 u32 sticky_out;
0370 int status;
0371 u32 ptmc_out;
0372 unsigned long flags;
0373
0374 spin_lock_irqsave(&sensors->intr_notify_lock, flags);
0375
0376 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0377 SOC_DTS_OFFSET_PTMC, &ptmc_out);
0378 ptmc_out |= SOC_DTS_PTMC_APIC_DEASSERT_BIT;
0379 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0380 SOC_DTS_OFFSET_PTMC, ptmc_out);
0381
0382 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
0383 SOC_DTS_OFFSET_PTTSS, &sticky_out);
0384 pr_debug("status %d PTTSS %x\n", status, sticky_out);
0385 if (sticky_out & SOC_DTS_TRIP_MASK) {
0386 int i;
0387
0388 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
0389 SOC_DTS_OFFSET_PTTSS, sticky_out);
0390 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
0391
0392 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
0393 pr_debug("TZD update for zone %d\n", i);
0394 thermal_zone_device_update(sensors->soc_dts[i].tzone,
0395 THERMAL_EVENT_UNSPECIFIED);
0396 }
0397 } else
0398 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
0399 }
0400 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler);
0401
0402 struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
0403 enum intel_soc_dts_interrupt_type intr_type, int trip_count,
0404 int read_only_trip_count)
0405 {
0406 struct intel_soc_dts_sensors *sensors;
0407 bool notification;
0408 u32 tj_max;
0409 int ret;
0410 int i;
0411
0412 if (!iosf_mbi_available())
0413 return ERR_PTR(-ENODEV);
0414
0415 if (!trip_count || read_only_trip_count > trip_count)
0416 return ERR_PTR(-EINVAL);
0417
0418 if (get_tj_max(&tj_max))
0419 return ERR_PTR(-EINVAL);
0420
0421 sensors = kzalloc(sizeof(*sensors), GFP_KERNEL);
0422 if (!sensors)
0423 return ERR_PTR(-ENOMEM);
0424
0425 spin_lock_init(&sensors->intr_notify_lock);
0426 mutex_init(&sensors->dts_update_lock);
0427 sensors->intr_type = intr_type;
0428 sensors->tj_max = tj_max;
0429 if (intr_type == INTEL_SOC_DTS_INTERRUPT_NONE)
0430 notification = false;
0431 else
0432 notification = true;
0433 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
0434 sensors->soc_dts[i].sensors = sensors;
0435 ret = add_dts_thermal_zone(i, &sensors->soc_dts[i],
0436 notification, trip_count,
0437 read_only_trip_count);
0438 if (ret)
0439 goto err_free;
0440 }
0441
0442 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
0443 ret = update_trip_temp(&sensors->soc_dts[i], 0, 0,
0444 THERMAL_TRIP_PASSIVE);
0445 if (ret)
0446 goto err_remove_zone;
0447
0448 ret = update_trip_temp(&sensors->soc_dts[i], 1, 0,
0449 THERMAL_TRIP_PASSIVE);
0450 if (ret)
0451 goto err_remove_zone;
0452 }
0453
0454 return sensors;
0455 err_remove_zone:
0456 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i)
0457 remove_dts_thermal_zone(&sensors->soc_dts[i]);
0458
0459 err_free:
0460 kfree(sensors);
0461 return ERR_PTR(ret);
0462 }
0463 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_init);
0464
0465 void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors)
0466 {
0467 int i;
0468
0469 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
0470 update_trip_temp(&sensors->soc_dts[i], 0, 0, 0);
0471 update_trip_temp(&sensors->soc_dts[i], 1, 0, 0);
0472 remove_dts_thermal_zone(&sensors->soc_dts[i]);
0473 }
0474 kfree(sensors);
0475 }
0476 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit);
0477
0478 MODULE_LICENSE("GPL v2");