1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2015, Intel Corporation.
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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"
17 #define SOC_DTS_OFFSET_ENABLE 0xB0
18 #define SOC_DTS_OFFSET_TEMP 0xB1
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
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)
37 /* DTS encoding for TJ MAX temperature */
38 #define SOC_DTS_TJMAX_ENCODING 0x7F
40 /* Only 2 out of 4 is allowed for OSPM */
41 #define SOC_MAX_DTS_TRIPS 2
43 /* Mask for two trips in status bits */
44 #define SOC_DTS_TRIP_MASK 0x03
47 #define SOC_MAX_DTS_SENSORS 2
49 static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip,
54 struct intel_soc_dts_sensor_entry *dts;
55 struct intel_soc_dts_sensors *sensors;
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);
66 out = (out >> (trip * 8)) & SOC_DTS_TJMAX_ENCODING;
70 *temp = sensors->tj_max - out * 1000;
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)
82 unsigned long update_ptps;
87 u32 int_enable_bit = SOC_DTS_TE_APICA_ENABLE;
88 struct intel_soc_dts_sensors *sensors = dts->sensors;
90 if (sensors->intr_type == INTEL_SOC_DTS_INTERRUPT_MSI)
91 int_enable_bit |= SOC_DTS_TE_MSI_ENABLE;
93 temp_out = (sensors->tj_max - temp) / 1000;
95 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
96 SOC_DTS_OFFSET_PTPS, &store_ptps);
100 update_ptps = store_ptps;
101 bitmap_set_value8(&update_ptps, temp_out & 0xFF, thres_index * 8);
104 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
105 SOC_DTS_OFFSET_PTPS, out);
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);
113 goto err_restore_ptps;
117 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
118 SOC_DTS_TE_AUX0 + thres_index,
121 goto err_restore_ptmc;
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);
129 out |= SOC_DTS_AUX1_ENABLE_BIT;
131 out |= SOC_DTS_AUX0_ENABLE_BIT;
132 te_out |= int_enable_bit;
135 out &= ~SOC_DTS_AUX1_ENABLE_BIT;
137 out &= ~SOC_DTS_AUX0_ENABLE_BIT;
138 te_out &= ~int_enable_bit;
140 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
141 SOC_DTS_OFFSET_PTMC, out);
143 goto err_restore_te_out;
145 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
146 SOC_DTS_TE_AUX0 + thres_index,
149 goto err_restore_te_out;
151 dts->trip_types[thres_index] = trip_type;
155 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
156 SOC_DTS_OFFSET_PTMC, store_te_out);
158 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
159 SOC_DTS_OFFSET_PTMC, store_ptmc);
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 */
168 static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
171 struct intel_soc_dts_sensor_entry *dts = tzd->devdata;
172 struct intel_soc_dts_sensors *sensors = dts->sensors;
175 if (temp > sensors->tj_max)
178 mutex_lock(&sensors->dts_update_lock);
179 status = update_trip_temp(tzd->devdata, trip, temp,
180 dts->trip_types[trip]);
181 mutex_unlock(&sensors->dts_update_lock);
186 static int sys_get_trip_type(struct thermal_zone_device *tzd,
187 int trip, enum thermal_trip_type *type)
189 struct intel_soc_dts_sensor_entry *dts;
193 *type = dts->trip_types[trip];
198 static int sys_get_curr_temp(struct thermal_zone_device *tzd,
203 struct intel_soc_dts_sensor_entry *dts;
204 struct intel_soc_dts_sensors *sensors;
208 sensors = dts->sensors;
209 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
210 SOC_DTS_OFFSET_TEMP, &out);
215 out = bitmap_get_value8(&raw, dts->id * 8) - SOC_DTS_TJMAX_ENCODING;
216 *temp = sensors->tj_max - out * 1000;
221 static struct thermal_zone_device_ops tzone_ops = {
222 .get_temp = sys_get_curr_temp,
223 .get_trip_temp = sys_get_trip_temp,
224 .get_trip_type = sys_get_trip_type,
225 .set_trip_temp = sys_set_trip_temp,
228 static int soc_dts_enable(int id)
233 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
234 SOC_DTS_OFFSET_ENABLE, &out);
238 if (!(out & BIT(id))) {
240 ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
241 SOC_DTS_OFFSET_ENABLE, out);
249 static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *dts)
252 iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
253 SOC_DTS_OFFSET_ENABLE, dts->store_status);
254 thermal_zone_device_unregister(dts->tzone);
258 static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
259 bool notification_support, int trip_cnt,
260 int read_only_trip_cnt)
266 int writable_trip_cnt = 0;
272 /* Store status to restor on exit */
273 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
274 SOC_DTS_OFFSET_ENABLE, &dts->store_status);
279 if (notification_support) {
280 trip_count = min(SOC_MAX_DTS_TRIPS, trip_cnt);
281 writable_trip_cnt = trip_count - read_only_trip_cnt;
282 trip_mask = GENMASK(writable_trip_cnt - 1, 0);
285 /* Check if the writable trip we provide is not used by BIOS */
286 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
287 SOC_DTS_OFFSET_PTPS, &store_ptps);
292 for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8)
293 trip_mask &= ~BIT(i / 8);
295 dts->trip_mask = trip_mask;
296 dts->trip_count = trip_count;
297 snprintf(name, sizeof(name), "soc_dts%d", id);
298 dts->tzone = thermal_zone_device_register(name,
303 if (IS_ERR(dts->tzone)) {
304 ret = PTR_ERR(dts->tzone);
307 ret = thermal_zone_device_enable(dts->tzone);
311 ret = soc_dts_enable(id);
317 thermal_zone_device_unregister(dts->tzone);
322 int intel_soc_dts_iosf_add_read_only_critical_trip(
323 struct intel_soc_dts_sensors *sensors, int critical_offset)
327 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
328 struct intel_soc_dts_sensor_entry *entry = &sensors->soc_dts[i];
329 int temp = sensors->tj_max - critical_offset;
330 unsigned long count = entry->trip_count;
331 unsigned long mask = entry->trip_mask;
333 j = find_first_zero_bit(&mask, count);
335 return update_trip_temp(entry, j, temp, THERMAL_TRIP_CRITICAL);
340 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_add_read_only_critical_trip);
342 void intel_soc_dts_iosf_interrupt_handler(struct intel_soc_dts_sensors *sensors)
349 spin_lock_irqsave(&sensors->intr_notify_lock, flags);
351 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
352 SOC_DTS_OFFSET_PTMC, &ptmc_out);
353 ptmc_out |= SOC_DTS_PTMC_APIC_DEASSERT_BIT;
354 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
355 SOC_DTS_OFFSET_PTMC, ptmc_out);
357 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
358 SOC_DTS_OFFSET_PTTSS, &sticky_out);
359 pr_debug("status %d PTTSS %x\n", status, sticky_out);
360 if (sticky_out & SOC_DTS_TRIP_MASK) {
362 /* reset sticky bit */
363 status = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
364 SOC_DTS_OFFSET_PTTSS, sticky_out);
365 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
367 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
368 pr_debug("TZD update for zone %d\n", i);
369 thermal_zone_device_update(sensors->soc_dts[i].tzone,
370 THERMAL_EVENT_UNSPECIFIED);
373 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
375 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler);
377 struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
378 enum intel_soc_dts_interrupt_type intr_type, int trip_count,
379 int read_only_trip_count)
381 struct intel_soc_dts_sensors *sensors;
387 if (!iosf_mbi_available())
388 return ERR_PTR(-ENODEV);
390 if (!trip_count || read_only_trip_count > trip_count)
391 return ERR_PTR(-EINVAL);
393 tj_max = intel_tcc_get_tjmax(-1);
395 return ERR_PTR(tj_max);
397 sensors = kzalloc(sizeof(*sensors), GFP_KERNEL);
399 return ERR_PTR(-ENOMEM);
401 spin_lock_init(&sensors->intr_notify_lock);
402 mutex_init(&sensors->dts_update_lock);
403 sensors->intr_type = intr_type;
404 sensors->tj_max = tj_max;
405 if (intr_type == INTEL_SOC_DTS_INTERRUPT_NONE)
406 notification = false;
409 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
410 sensors->soc_dts[i].sensors = sensors;
411 ret = add_dts_thermal_zone(i, &sensors->soc_dts[i],
412 notification, trip_count,
413 read_only_trip_count);
418 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
419 ret = update_trip_temp(&sensors->soc_dts[i], 0, 0,
420 THERMAL_TRIP_PASSIVE);
422 goto err_remove_zone;
424 ret = update_trip_temp(&sensors->soc_dts[i], 1, 0,
425 THERMAL_TRIP_PASSIVE);
427 goto err_remove_zone;
432 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i)
433 remove_dts_thermal_zone(&sensors->soc_dts[i]);
439 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_init);
441 void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors)
445 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
446 update_trip_temp(&sensors->soc_dts[i], 0, 0, 0);
447 update_trip_temp(&sensors->soc_dts[i], 1, 0, 0);
448 remove_dts_thermal_zone(&sensors->soc_dts[i]);
452 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit);
454 MODULE_IMPORT_NS(INTEL_TCC);
455 MODULE_LICENSE("GPL v2");