File Index
Files and directories
Sign in
FILE

intel_tcc_cooling.c

File preview with syntax highlighting.

linux-6.19.14/drivers/thermal/intel/intel_tcc_cooling.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * cooling device driver that activates the processor throttling by
  4 * programming the TCC Offset register.
  5 * Copyright (c) 2021, Intel Corporation.
  6 */
  7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  8
  9#include <linux/device.h>
 10#include <linux/intel_tcc.h>
 11#include <linux/module.h>
 12#include <linux/thermal.h>
 13#include <asm/cpu_device_id.h>
 14#include <asm/msr.h>
 15
 16#define TCC_PROGRAMMABLE	BIT(30)
 17#define TCC_LOCKED		BIT(31)
 18
 19static struct thermal_cooling_device *tcc_cdev;
 20
 21static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long
 22			     *state)
 23{
 24	*state = intel_tcc_get_offset_mask();
 25	return 0;
 26}
 27
 28static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
 29			     *state)
 30{
 31	int offset = intel_tcc_get_offset(-1);
 32
 33	if (offset < 0)
 34		return offset;
 35
 36	*state = offset;
 37	return 0;
 38}
 39
 40static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long
 41			     state)
 42{
 43	return intel_tcc_set_offset(-1, (int)state);
 44}
 45
 46static const struct thermal_cooling_device_ops tcc_cooling_ops = {
 47	.get_max_state = tcc_get_max_state,
 48	.get_cur_state = tcc_get_cur_state,
 49	.set_cur_state = tcc_set_cur_state,
 50};
 51
 52static const struct x86_cpu_id tcc_ids[] __initconst = {
 53	X86_MATCH_VFM(INTEL_SKYLAKE, NULL),
 54	X86_MATCH_VFM(INTEL_SKYLAKE_L, NULL),
 55	X86_MATCH_VFM(INTEL_KABYLAKE, NULL),
 56	X86_MATCH_VFM(INTEL_KABYLAKE_L, NULL),
 57	X86_MATCH_VFM(INTEL_ICELAKE, NULL),
 58	X86_MATCH_VFM(INTEL_ICELAKE_L, NULL),
 59	X86_MATCH_VFM(INTEL_TIGERLAKE, NULL),
 60	X86_MATCH_VFM(INTEL_TIGERLAKE_L, NULL),
 61	X86_MATCH_VFM(INTEL_COMETLAKE, NULL),
 62	X86_MATCH_VFM(INTEL_ALDERLAKE, NULL),
 63	X86_MATCH_VFM(INTEL_ALDERLAKE_L, NULL),
 64	X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, NULL),
 65	X86_MATCH_VFM(INTEL_RAPTORLAKE, NULL),
 66	X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL),
 67	X86_MATCH_VFM(INTEL_RAPTORLAKE_S, NULL),
 68	{}
 69};
 70
 71MODULE_DEVICE_TABLE(x86cpu, tcc_ids);
 72
 73static int __init tcc_cooling_init(void)
 74{
 75	int ret;
 76	u64 val;
 77	const struct x86_cpu_id *id;
 78
 79	int err;
 80
 81	id = x86_match_cpu(tcc_ids);
 82	if (!id)
 83		return -ENODEV;
 84
 85	err = rdmsrq_safe(MSR_PLATFORM_INFO, &val);
 86	if (err)
 87		return err;
 88
 89	if (!(val & TCC_PROGRAMMABLE))
 90		return -ENODEV;
 91
 92	err = rdmsrq_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
 93	if (err)
 94		return err;
 95
 96	if (val & TCC_LOCKED) {
 97		pr_info("TCC Offset locked\n");
 98		return -ENODEV;
 99	}
100
101	pr_info("Programmable TCC Offset detected\n");
102
103	tcc_cdev =
104	    thermal_cooling_device_register("TCC Offset", NULL,
105					    &tcc_cooling_ops);
106	if (IS_ERR(tcc_cdev)) {
107		ret = PTR_ERR(tcc_cdev);
108		return ret;
109	}
110	return 0;
111}
112
113module_init(tcc_cooling_init)
114
115static void __exit tcc_cooling_exit(void)
116{
117	thermal_cooling_device_unregister(tcc_cdev);
118}
119
120module_exit(tcc_cooling_exit)
121
122MODULE_IMPORT_NS("INTEL_TCC");
123MODULE_DESCRIPTION("TCC offset cooling device Driver");
124MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
125MODULE_LICENSE("GPL v2");
~/ Read-only file preview.