1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Processor thermal device for newer processors
4  * Copyright (c) 2020, Intel Corporation.
5  */
6 
7 #include <linux/acpi.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/thermal.h>
12 
13 #include "int340x_thermal_zone.h"
14 #include "processor_thermal_device.h"
15 
16 #define DRV_NAME "proc_thermal_pci"
17 
18 static bool use_msi;
19 module_param(use_msi, bool, 0644);
20 MODULE_PARM_DESC(use_msi,
21 	"Use PCI MSI based interrupts for processor thermal device.");
22 
23 struct proc_thermal_pci {
24 	struct pci_dev *pdev;
25 	struct proc_thermal_device *proc_priv;
26 	struct thermal_zone_device *tzone;
27 	struct delayed_work work;
28 	int stored_thres;
29 	int no_legacy;
30 };
31 
32 enum proc_thermal_mmio_type {
33 	PROC_THERMAL_MMIO_TJMAX,
34 	PROC_THERMAL_MMIO_PP0_TEMP,
35 	PROC_THERMAL_MMIO_PP1_TEMP,
36 	PROC_THERMAL_MMIO_PKG_TEMP,
37 	PROC_THERMAL_MMIO_THRES_0,
38 	PROC_THERMAL_MMIO_THRES_1,
39 	PROC_THERMAL_MMIO_INT_ENABLE_0,
40 	PROC_THERMAL_MMIO_INT_ENABLE_1,
41 	PROC_THERMAL_MMIO_INT_STATUS_0,
42 	PROC_THERMAL_MMIO_INT_STATUS_1,
43 	PROC_THERMAL_MMIO_MAX
44 };
45 
46 struct proc_thermal_mmio_info {
47 	enum proc_thermal_mmio_type mmio_type;
48 	u64	mmio_addr;
49 	u64	shift;
50 	u64	mask;
51 };
52 
53 static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = {
54 	{ PROC_THERMAL_MMIO_TJMAX, 0x599c, 16, 0xff },
55 	{ PROC_THERMAL_MMIO_PP0_TEMP, 0x597c, 0, 0xff },
56 	{ PROC_THERMAL_MMIO_PP1_TEMP, 0x5980, 0, 0xff },
57 	{ PROC_THERMAL_MMIO_PKG_TEMP, 0x5978, 0, 0xff },
58 	{ PROC_THERMAL_MMIO_THRES_0, 0x5820, 8, 0x7F },
59 	{ PROC_THERMAL_MMIO_THRES_1, 0x5820, 16, 0x7F },
60 	{ PROC_THERMAL_MMIO_INT_ENABLE_0, 0x5820, 15, 0x01 },
61 	{ PROC_THERMAL_MMIO_INT_ENABLE_1, 0x5820, 23, 0x01 },
62 	{ PROC_THERMAL_MMIO_INT_STATUS_0, 0x7200, 6, 0x01 },
63 	{ PROC_THERMAL_MMIO_INT_STATUS_1, 0x7200, 8, 0x01 },
64 };
65 
66 #define B0D4_THERMAL_NOTIFY_DELAY	1000
67 static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY;
68 
proc_thermal_mmio_read(struct proc_thermal_pci * pci_info,enum proc_thermal_mmio_type type,u32 * value)69 static void proc_thermal_mmio_read(struct proc_thermal_pci *pci_info,
70 				    enum proc_thermal_mmio_type type,
71 				    u32 *value)
72 {
73 	*value = ioread32(((u8 __iomem *)pci_info->proc_priv->mmio_base +
74 				proc_thermal_mmio_info[type].mmio_addr));
75 	*value >>= proc_thermal_mmio_info[type].shift;
76 	*value &= proc_thermal_mmio_info[type].mask;
77 }
78 
proc_thermal_mmio_write(struct proc_thermal_pci * pci_info,enum proc_thermal_mmio_type type,u32 value)79 static void proc_thermal_mmio_write(struct proc_thermal_pci *pci_info,
80 				     enum proc_thermal_mmio_type type,
81 				     u32 value)
82 {
83 	u32 current_val;
84 	u32 mask;
85 
86 	current_val = ioread32(((u8 __iomem *)pci_info->proc_priv->mmio_base +
87 				proc_thermal_mmio_info[type].mmio_addr));
88 	mask = proc_thermal_mmio_info[type].mask << proc_thermal_mmio_info[type].shift;
89 	current_val &= ~mask;
90 
91 	value &= proc_thermal_mmio_info[type].mask;
92 	value <<= proc_thermal_mmio_info[type].shift;
93 
94 	current_val |= value;
95 	iowrite32(current_val, ((u8 __iomem *)pci_info->proc_priv->mmio_base +
96 				proc_thermal_mmio_info[type].mmio_addr));
97 }
98 
99 /*
100  * To avoid sending two many messages to user space, we have 1 second delay.
101  * On interrupt we are disabling interrupt and enabling after 1 second.
102  * This workload function is delayed by 1 second.
103  */
proc_thermal_threshold_work_fn(struct work_struct * work)104 static void proc_thermal_threshold_work_fn(struct work_struct *work)
105 {
106 	struct delayed_work *delayed_work = to_delayed_work(work);
107 	struct proc_thermal_pci *pci_info = container_of(delayed_work,
108 						struct proc_thermal_pci, work);
109 	struct thermal_zone_device *tzone = pci_info->tzone;
110 
111 	if (tzone)
112 		thermal_zone_device_update(tzone, THERMAL_TRIP_VIOLATED);
113 
114 	/* Enable interrupt flag */
115 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
116 }
117 
pkg_thermal_schedule_work(struct delayed_work * work)118 static void pkg_thermal_schedule_work(struct delayed_work *work)
119 {
120 	unsigned long ms = msecs_to_jiffies(notify_delay_ms);
121 
122 	schedule_delayed_work(work, ms);
123 }
124 
proc_thermal_clear_soc_int_status(struct proc_thermal_device * proc_priv)125 static void proc_thermal_clear_soc_int_status(struct proc_thermal_device *proc_priv)
126 {
127 	u64 status;
128 
129 	if (!(proc_priv->mmio_feature_mask &
130 	    (PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR)))
131 		return;
132 
133 	status = readq(proc_priv->mmio_base + SOC_WT_RES_INT_STATUS_OFFSET);
134 	writeq(status & ~SOC_WT_RES_INT_STATUS_MASK,
135 	       proc_priv->mmio_base + SOC_WT_RES_INT_STATUS_OFFSET);
136 }
137 
proc_thermal_irq_thread_handler(int irq,void * devid)138 static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
139 {
140 	struct proc_thermal_pci *pci_info = devid;
141 
142 	proc_thermal_wt_intr_callback(pci_info->pdev, pci_info->proc_priv);
143 	proc_thermal_power_floor_intr_callback(pci_info->pdev, pci_info->proc_priv);
144 	proc_thermal_clear_soc_int_status(pci_info->proc_priv);
145 
146 	return IRQ_HANDLED;
147 }
148 
proc_thermal_irq_handler(int irq,void * devid)149 static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
150 {
151 	struct proc_thermal_pci *pci_info = devid;
152 	struct proc_thermal_device *proc_priv;
153 	int ret = IRQ_HANDLED;
154 	u32 status;
155 
156 	proc_priv = pci_info->proc_priv;
157 
158 	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT) {
159 		if (proc_thermal_check_wt_intr(pci_info->proc_priv))
160 			ret = IRQ_WAKE_THREAD;
161 	}
162 
163 	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR) {
164 		if (proc_thermal_check_power_floor_intr(pci_info->proc_priv))
165 			ret = IRQ_WAKE_THREAD;
166 	}
167 
168 	/*
169 	 * Since now there are two sources of interrupts: one from thermal threshold
170 	 * and another from workload hint, add a check if there was really a threshold
171 	 * interrupt before scheduling work function for thermal threshold.
172 	 */
173 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status);
174 	if (status) {
175 		/* Disable enable interrupt flag */
176 		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
177 		pkg_thermal_schedule_work(&pci_info->work);
178 	}
179 
180 	pci_write_config_byte(pci_info->pdev, 0xdc, 0x01);
181 
182 	return ret;
183 }
184 
sys_get_curr_temp(struct thermal_zone_device * tzd,int * temp)185 static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
186 {
187 	struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd);
188 	u32 _temp;
189 
190 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_PKG_TEMP, &_temp);
191 	*temp = (unsigned long)_temp * 1000;
192 
193 	return 0;
194 }
195 
sys_set_trip_temp(struct thermal_zone_device * tzd,int trip,int temp)196 static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
197 {
198 	struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd);
199 	int tjmax, _temp;
200 
201 	if (temp <= 0) {
202 		cancel_delayed_work_sync(&pci_info->work);
203 		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
204 		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
205 		pci_info->stored_thres = 0;
206 		return 0;
207 	}
208 
209 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
210 	_temp = tjmax - (temp / 1000);
211 	if (_temp < 0)
212 		return -EINVAL;
213 
214 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, _temp);
215 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
216 
217 	pci_info->stored_thres = temp;
218 
219 	return 0;
220 }
221 
get_trip_temp(struct proc_thermal_pci * pci_info)222 static int get_trip_temp(struct proc_thermal_pci *pci_info)
223 {
224 	int temp, tjmax;
225 
226 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &temp);
227 	if (!temp)
228 		return THERMAL_TEMP_INVALID;
229 
230 	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
231 	temp = (tjmax - temp) * 1000;
232 
233 	return temp;
234 }
235 
236 static struct thermal_trip psv_trip = {
237 	.type = THERMAL_TRIP_PASSIVE,
238 };
239 
240 static struct thermal_zone_device_ops tzone_ops = {
241 	.get_temp = sys_get_curr_temp,
242 	.set_trip_temp	= sys_set_trip_temp,
243 };
244 
245 static struct thermal_zone_params tzone_params = {
246 	.governor_name = "user_space",
247 	.no_hwmon = true,
248 };
249 
proc_thermal_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)250 static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
251 {
252 	struct proc_thermal_device *proc_priv;
253 	struct proc_thermal_pci *pci_info;
254 	int irq_flag = 0, irq, ret;
255 	bool msi_irq = false;
256 
257 	proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
258 	if (!proc_priv)
259 		return -ENOMEM;
260 
261 	pci_info = devm_kzalloc(&pdev->dev, sizeof(*pci_info), GFP_KERNEL);
262 	if (!pci_info)
263 		return -ENOMEM;
264 
265 	pci_info->pdev = pdev;
266 	ret = pcim_enable_device(pdev);
267 	if (ret < 0) {
268 		dev_err(&pdev->dev, "error: could not enable device\n");
269 		return ret;
270 	}
271 
272 	pci_set_master(pdev);
273 
274 	INIT_DELAYED_WORK(&pci_info->work, proc_thermal_threshold_work_fn);
275 
276 	proc_priv->priv_data = pci_info;
277 	pci_info->proc_priv = proc_priv;
278 	pci_set_drvdata(pdev, proc_priv);
279 
280 	ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data);
281 	if (ret)
282 		return ret;
283 
284 	ret = proc_thermal_add(&pdev->dev, proc_priv);
285 	if (ret) {
286 		dev_err(&pdev->dev, "error: proc_thermal_add, will continue\n");
287 		pci_info->no_legacy = 1;
288 	}
289 
290 	psv_trip.temperature = get_trip_temp(pci_info);
291 
292 	pci_info->tzone = thermal_zone_device_register_with_trips("TCPU_PCI", &psv_trip,
293 							1, 1, pci_info,
294 							&tzone_ops,
295 							&tzone_params, 0, 0);
296 	if (IS_ERR(pci_info->tzone)) {
297 		ret = PTR_ERR(pci_info->tzone);
298 		goto err_del_legacy;
299 	}
300 
301 	if (use_msi && (pdev->msi_enabled || pdev->msix_enabled)) {
302 		/* request and enable interrupt */
303 		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
304 		if (ret < 0) {
305 			dev_err(&pdev->dev, "Failed to allocate vectors!\n");
306 			goto err_ret_tzone;
307 		}
308 
309 		irq =  pci_irq_vector(pdev, 0);
310 		msi_irq = true;
311 	} else {
312 		irq_flag = IRQF_SHARED;
313 		irq = pdev->irq;
314 	}
315 
316 	ret = devm_request_threaded_irq(&pdev->dev, irq,
317 					proc_thermal_irq_handler, proc_thermal_irq_thread_handler,
318 					irq_flag, KBUILD_MODNAME, pci_info);
319 	if (ret) {
320 		dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq);
321 		goto err_free_vectors;
322 	}
323 
324 	ret = thermal_zone_device_enable(pci_info->tzone);
325 	if (ret)
326 		goto err_free_vectors;
327 
328 	return 0;
329 
330 err_free_vectors:
331 	if (msi_irq)
332 		pci_free_irq_vectors(pdev);
333 err_ret_tzone:
334 	thermal_zone_device_unregister(pci_info->tzone);
335 err_del_legacy:
336 	if (!pci_info->no_legacy)
337 		proc_thermal_remove(proc_priv);
338 	proc_thermal_mmio_remove(pdev, proc_priv);
339 	pci_disable_device(pdev);
340 
341 	return ret;
342 }
343 
proc_thermal_pci_remove(struct pci_dev * pdev)344 static void proc_thermal_pci_remove(struct pci_dev *pdev)
345 {
346 	struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev);
347 	struct proc_thermal_pci *pci_info = proc_priv->priv_data;
348 
349 	cancel_delayed_work_sync(&pci_info->work);
350 
351 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
352 	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
353 
354 	devm_free_irq(&pdev->dev, pdev->irq, pci_info);
355 	pci_free_irq_vectors(pdev);
356 
357 	thermal_zone_device_unregister(pci_info->tzone);
358 	proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
359 	if (!pci_info->no_legacy)
360 		proc_thermal_remove(proc_priv);
361 	pci_disable_device(pdev);
362 }
363 
364 #ifdef CONFIG_PM_SLEEP
proc_thermal_pci_suspend(struct device * dev)365 static int proc_thermal_pci_suspend(struct device *dev)
366 {
367 	struct pci_dev *pdev = to_pci_dev(dev);
368 	struct proc_thermal_device *proc_priv;
369 	struct proc_thermal_pci *pci_info;
370 
371 	proc_priv = pci_get_drvdata(pdev);
372 	pci_info = proc_priv->priv_data;
373 
374 	if (!pci_info->no_legacy)
375 		return proc_thermal_suspend(dev);
376 
377 	return 0;
378 }
proc_thermal_pci_resume(struct device * dev)379 static int proc_thermal_pci_resume(struct device *dev)
380 {
381 	struct pci_dev *pdev = to_pci_dev(dev);
382 	struct proc_thermal_device *proc_priv;
383 	struct proc_thermal_pci *pci_info;
384 
385 	proc_priv = pci_get_drvdata(pdev);
386 	pci_info = proc_priv->priv_data;
387 
388 	if (pci_info->stored_thres) {
389 		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0,
390 					 pci_info->stored_thres / 1000);
391 		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1);
392 	}
393 
394 	if (!pci_info->no_legacy)
395 		return proc_thermal_resume(dev);
396 
397 	return 0;
398 }
399 #else
400 #define proc_thermal_pci_suspend NULL
401 #define proc_thermal_pci_resume NULL
402 #endif
403 
404 static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
405 			 proc_thermal_pci_resume);
406 
407 static const struct pci_device_id proc_thermal_pci_ids[] = {
408 	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
409 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) },
410 	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
411 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
412 	  PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) },
413 	{ PCI_DEVICE_DATA(INTEL, ARL_S_THERMAL, PROC_THERMAL_FEATURE_RAPL |
414 	  PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT) },
415 	{ PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
416 	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) },
417 	{ },
418 };
419 
420 MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids);
421 
422 static struct pci_driver proc_thermal_pci_driver = {
423 	.name		= DRV_NAME,
424 	.probe		= proc_thermal_pci_probe,
425 	.remove	= proc_thermal_pci_remove,
426 	.id_table	= proc_thermal_pci_ids,
427 	.driver.pm	= &proc_thermal_pci_pm,
428 };
429 
430 module_pci_driver(proc_thermal_pci_driver);
431 
432 MODULE_IMPORT_NS(INT340X_THERMAL);
433 
434 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
435 MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
436 MODULE_LICENSE("GPL v2");
437