brintos

brintos / linux-shallow public Read only

0
0
Text · 2.9 KiB · bde2cc3 Raw
115 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * processor thermal device RFIM control4 * Copyright (c) 2020, Intel Corporation.5 */6 7#include <linux/kernel.h>8#include <linux/module.h>9#include <linux/pci.h>10#include "processor_thermal_device.h"11 12static struct rapl_if_priv rapl_mmio_priv;13 14static const struct rapl_mmio_regs rapl_mmio_default = {15	.reg_unit = 0x5938,16	.regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930, 0x59b0},17	.regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0},18	.limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2) | BIT(POWER_LIMIT4),19	.limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2),20};21 22static int rapl_mmio_read_raw(int cpu, struct reg_action *ra)23{24	if (!ra->reg.mmio)25		return -EINVAL;26 27	ra->value = readq(ra->reg.mmio);28	ra->value &= ra->mask;29	return 0;30}31 32static int rapl_mmio_write_raw(int cpu, struct reg_action *ra)33{34	u64 val;35 36	if (!ra->reg.mmio)37		return -EINVAL;38 39	val = readq(ra->reg.mmio);40	val &= ~ra->mask;41	val |= ra->value;42	writeq(val, ra->reg.mmio);43	return 0;44}45 46int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)47{48	const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default;49	struct rapl_package *rp;50	enum rapl_domain_reg_id reg;51	enum rapl_domain_type domain;52	int ret;53 54	if (!rapl_regs)55		return 0;56 57	for (domain = RAPL_DOMAIN_PACKAGE; domain < RAPL_DOMAIN_MAX; domain++) {58		for (reg = RAPL_DOMAIN_REG_LIMIT; reg < RAPL_DOMAIN_REG_MAX; reg++)59			if (rapl_regs->regs[domain][reg])60				rapl_mmio_priv.regs[domain][reg].mmio =61						proc_priv->mmio_base +62						rapl_regs->regs[domain][reg];63		rapl_mmio_priv.limits[domain] = rapl_regs->limits[domain];64	}65	rapl_mmio_priv.type = RAPL_IF_MMIO;66	rapl_mmio_priv.reg_unit.mmio = proc_priv->mmio_base + rapl_regs->reg_unit;67 68	rapl_mmio_priv.read_raw = rapl_mmio_read_raw;69	rapl_mmio_priv.write_raw = rapl_mmio_write_raw;70 71	rapl_mmio_priv.control_type = powercap_register_control_type(NULL, "intel-rapl-mmio", NULL);72	if (IS_ERR(rapl_mmio_priv.control_type)) {73		pr_debug("failed to register powercap control_type.\n");74		return PTR_ERR(rapl_mmio_priv.control_type);75	}76 77	/* Register a RAPL package device for package 0 which is always online */78	rp = rapl_find_package_domain(0, &rapl_mmio_priv, false);79	if (rp) {80		ret = -EEXIST;81		goto err;82	}83 84	rp = rapl_add_package(0, &rapl_mmio_priv, false);85	if (IS_ERR(rp)) {86		ret = PTR_ERR(rp);87		goto err;88	}89 90	return 0;91 92err:93	powercap_unregister_control_type(rapl_mmio_priv.control_type);94	rapl_mmio_priv.control_type = NULL;95	return ret;96}97EXPORT_SYMBOL_GPL(proc_thermal_rapl_add);98 99void proc_thermal_rapl_remove(void)100{101	struct rapl_package *rp;102 103	if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type))104		return;105 106	rp = rapl_find_package_domain(0, &rapl_mmio_priv, false);107	if (rp)108		rapl_remove_package(rp);109	powercap_unregister_control_type(rapl_mmio_priv.control_type);110}111EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove);112 113MODULE_LICENSE("GPL v2");114MODULE_DESCRIPTION("RAPL interface using MMIO");115