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;
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);
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 = thermal_zone_device_priv(tzd);
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(dts, 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 = thermal_zone_device_priv(tzd);
191 *type = dts->trip_types[trip];
196 static int sys_get_curr_temp(struct thermal_zone_device *tzd,
201 struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd);
202 struct intel_soc_dts_sensors *sensors;
205 sensors = dts->sensors;
206 status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
207 SOC_DTS_OFFSET_TEMP, &out);
212 out = bitmap_get_value8(&raw, dts->id * 8) - SOC_DTS_TJMAX_ENCODING;
213 *temp = sensors->tj_max - out * 1000;
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,
225 static int soc_dts_enable(int id)
230 ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
231 SOC_DTS_OFFSET_ENABLE, &out);
235 if (!(out & BIT(id))) {
237 ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
238 SOC_DTS_OFFSET_ENABLE, out);
246 static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *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);
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)
263 int writable_trip_cnt = 0;
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);
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);
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);
289 for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8)
290 trip_mask &= ~BIT(i / 8);
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,
300 if (IS_ERR(dts->tzone)) {
301 ret = PTR_ERR(dts->tzone);
304 ret = thermal_zone_device_enable(dts->tzone);
308 ret = soc_dts_enable(id);
314 thermal_zone_device_unregister(dts->tzone);
319 int intel_soc_dts_iosf_add_read_only_critical_trip(
320 struct intel_soc_dts_sensors *sensors, int critical_offset)
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;
330 j = find_first_zero_bit(&mask, count);
332 return update_trip_temp(entry, j, temp, THERMAL_TRIP_CRITICAL);
337 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_add_read_only_critical_trip);
339 void intel_soc_dts_iosf_interrupt_handler(struct intel_soc_dts_sensors *sensors)
346 spin_lock_irqsave(&sensors->intr_notify_lock, flags);
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);
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) {
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);
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);
370 spin_unlock_irqrestore(&sensors->intr_notify_lock, flags);
372 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler);
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)
378 struct intel_soc_dts_sensors *sensors;
384 if (!iosf_mbi_available())
385 return ERR_PTR(-ENODEV);
387 if (!trip_count || read_only_trip_count > trip_count)
388 return ERR_PTR(-EINVAL);
390 tj_max = intel_tcc_get_tjmax(-1);
392 return ERR_PTR(tj_max);
394 sensors = kzalloc(sizeof(*sensors), GFP_KERNEL);
396 return ERR_PTR(-ENOMEM);
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;
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);
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);
419 goto err_remove_zone;
421 ret = update_trip_temp(&sensors->soc_dts[i], 1, 0,
422 THERMAL_TRIP_PASSIVE);
424 goto err_remove_zone;
429 for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i)
430 remove_dts_thermal_zone(&sensors->soc_dts[i]);
436 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_init);
438 void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors)
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]);
449 EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit);
451 MODULE_IMPORT_NS(INTEL_TCC);
452 MODULE_LICENSE("GPL v2");