summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch405
1 files changed, 0 insertions, 405 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch
deleted file mode 100644
index 475e9611f..000000000
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch
+++ /dev/null
@@ -1,405 +0,0 @@
-From e40f7d10d5306c075e2fc7e538ce1efc70eeb448 Mon Sep 17 00:00:00 2001
-From: ZhikuiRen <zhikui.ren@intel.com>
-Date: Thu, 9 Jan 2020 10:48:00 -0800
-Subject: [PATCH] Add peci-cpupower driver
-
-peci-cpupower reads CPU energy counter through peci
-and computes average power in mW since last read.
-
-Signed-off-by: ZhikuiRen <zhikui.ren@intel.com>
----
- Documentation/hwmon/index.rst | 1 +
- Documentation/hwmon/peci-cpupower.rst | 52 ++++++++
- arch/arm/configs/aspeed_g5_defconfig | 1 +
- drivers/hwmon/Kconfig | 14 +++
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/peci-cpupower.c | 231 ++++++++++++++++++++++++++++++++++
- drivers/mfd/intel-peci-client.c | 1 +
- include/uapi/linux/peci-ioctl.h | 1 +
- 8 files changed, 302 insertions(+)
- create mode 100644 Documentation/hwmon/peci-cpupower.rst
- create mode 100644 drivers/hwmon/peci-cpupower.c
-
-diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
-index 7d894c9..0bde0ef 100644
---- a/Documentation/hwmon/index.rst
-+++ b/Documentation/hwmon/index.rst
-@@ -130,6 +130,7 @@ Hardware Monitoring Kernel Drivers
- pcf8591
- peci-cputemp
- peci-dimmtemp
-+ peci-cpupower
- pmbus
- powr1220
- pxe1610
-diff --git a/Documentation/hwmon/peci-cpupower.rst b/Documentation/hwmon/peci-cpupower.rst
-new file mode 100644
-index 0000000..4d7bd61
---- /dev/null
-+++ b/Documentation/hwmon/peci-cpupower.rst
-@@ -0,0 +1,52 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+Kernel driver peci-cpupower
-+==========================
-+
-+:Copyright: |copy| 2018-2020 Intel Corporation
-+
-+Supported chips:
-+ One of Intel server CPUs listed below which is connected to a PECI bus.
-+ * Intel Xeon E5/E7 v3 server processors
-+ Intel Xeon E5-14xx v3 family
-+ Intel Xeon E5-24xx v3 family
-+ Intel Xeon E5-16xx v3 family
-+ Intel Xeon E5-26xx v3 family
-+ Intel Xeon E5-46xx v3 family
-+ Intel Xeon E7-48xx v3 family
-+ Intel Xeon E7-88xx v3 family
-+ * Intel Xeon E5/E7 v4 server processors
-+ Intel Xeon E5-16xx v4 family
-+ Intel Xeon E5-26xx v4 family
-+ Intel Xeon E5-46xx v4 family
-+ Intel Xeon E7-48xx v4 family
-+ Intel Xeon E7-88xx v4 family
-+ * Intel Xeon Scalable server processors
-+ Intel Xeon D family
-+ Intel Xeon Bronze family
-+ Intel Xeon Silver family
-+ Intel Xeon Gold family
-+ Intel Xeon Platinum family
-+
-+ Addresses scanned: PECI client address 0x30 - 0x37
-+ Datasheet: Available from http://www.intel.com/design/literature.htm
-+
-+Author:
-+ Zhikui Ren <zhikui.ren@.intel.com>
-+
-+Description
-+-----------
-+
-+This driver implements a generic PECI hwmon feature which provides
-+average power consumption readings of the CPU package based on energy counter
-+accessible using the PECI Client Command Suite via the processor PECI client.
-+
-+Power values are average power since last measure given in milli Watt and
-+will be measurable only when the target CPU is powered on.
-+
-+``sysfs`` interface
-+-------------------
-+======================= =======================================================
-+power1_average Provides average power since last read in milli Watt.
-+power1_label Provides string "Average Power".
-+======================= =======================================================
-diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
-index 1e589a0..0e50040 100644
---- a/arch/arm/configs/aspeed_g5_defconfig
-+++ b/arch/arm/configs/aspeed_g5_defconfig
-@@ -177,6 +177,7 @@ CONFIG_SENSORS_OCC_P8_I2C=y
- CONFIG_SENSORS_OCC_P9_SBE=y
- CONFIG_SENSORS_PECI_CPUTEMP=y
- CONFIG_SENSORS_PECI_DIMMTEMP=y
-+CONFIG_SENSORS_PECI_CPUPOWER=y
- CONFIG_PMBUS=y
- CONFIG_SENSORS_ADM1275=y
- CONFIG_SENSORS_IBM_CFFPS=y
-diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index 8312b37..07d8826 100644
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -1361,6 +1361,20 @@ config SENSORS_PECI_DIMMTEMP
- This driver can also be built as a module. If so, the module
- will be called peci-dimmtemp.
-
-+config SENSORS_PECI_CPUPOWER
-+ tristate "PECI CPU power monitoring support"
-+ depends on PECI
-+ select MFD_INTEL_PECI_CLIENT
-+ help
-+ If you say yes here you get support for the generic Intel PECI
-+ cputemp driver which provides average engergy
-+ readings of the CPU package using
-+ the PECI Client Command Suite via the processor PECI client.
-+ Check Documentation/hwmon/peci-cpupower for details.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called peci-cpupower.
-+
- source "drivers/hwmon/pmbus/Kconfig"
-
- config SENSORS_PWM_FAN
-diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
-index e74ea92..fab43fd 100644
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -144,6 +144,7 @@ obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
- obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
- obj-$(CONFIG_SENSORS_PECI_CPUTEMP) += peci-cputemp.o
- obj-$(CONFIG_SENSORS_PECI_DIMMTEMP) += peci-dimmtemp.o
-+obj-$(CONFIG_SENSORS_PECI_CPUPOWER) += peci-cpupower.o
- obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o
- obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o
- obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o
-diff --git a/drivers/hwmon/peci-cpupower.c b/drivers/hwmon/peci-cpupower.c
-new file mode 100644
-index 0000000..6907696
---- /dev/null
-+++ b/drivers/hwmon/peci-cpupower.c
-@@ -0,0 +1,231 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2018-2020 Intel Corporation
-+
-+#include <linux/hwmon.h>
-+#include <linux/jiffies.h>
-+#include <linux/mfd/intel-peci-client.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "peci-hwmon.h"
-+
-+#define POWER_DEFAULT_CHANNEL_NUMS 1
-+
-+struct peci_cpupower {
-+ struct peci_client_manager *mgr;
-+ struct device *dev;
-+ char name[PECI_NAME_SIZE];
-+ const struct cpu_gen_info *gen_info;
-+ struct peci_sensor_data energy;
-+ long avg_power_val;
-+ u64 core_mask;
-+ u32 power_config[POWER_DEFAULT_CHANNEL_NUMS + 1];
-+ uint config_idx;
-+ struct hwmon_channel_info power_info;
-+ const struct hwmon_channel_info *info[2];
-+ struct hwmon_chip_info chip;
-+};
-+
-+enum cpupower_channels {
-+ average_power,
-+};
-+
-+static const u32 config_table[POWER_DEFAULT_CHANNEL_NUMS] = {
-+ /* average power */
-+ HWMON_P_LABEL | HWMON_P_AVERAGE,
-+};
-+
-+static const char *cpupower_label[POWER_DEFAULT_CHANNEL_NUMS] = {
-+ "Average Power",
-+};
-+
-+static int get_average_power(struct peci_cpupower *priv)
-+{
-+ u8 pkg_cfg[4];
-+ int ret;
-+
-+ if (!peci_sensor_need_update(&priv->energy))
-+ return 0;
-+
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_TDP_UNITS,
-+ PECI_PKG_ID_PKG_ENERGY_STATUS,
-+ pkg_cfg);
-+
-+ u32 power_unit = ((le32_to_cpup((__le32 *)pkg_cfg)) & 0x1f00) >> 8;
-+
-+ dev_dbg(priv->dev, "cpupower units %d (1J/pow(2, unit))\n",
-+ power_unit);
-+
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_ENERGY_COUNTER,
-+ PECI_PKG_ID_PKG_ENERGY_STATUS,
-+ pkg_cfg);
-+ if (!ret) {
-+ u32 energy_cnt = le32_to_cpup((__le32 *)pkg_cfg);
-+ ulong jif = jiffies;
-+ ulong elapsed = (jif - priv->energy.last_updated);
-+ long power_val = 0;
-+ /*
-+ * Don't calculate average power for first counter read or
-+ * counter wrapped around or last counter read was more than
-+ * 60 minutes ago (jiffies did not wrap and power calculation
-+ * does not overflow or underflow
-+ */
-+ if (priv->energy.last_updated > 0 &&
-+ energy_cnt > priv->energy.value &&
-+ (elapsed < (HZ * 3600))) {
-+ power_val = (long)(energy_cnt - priv->energy.value)
-+ / elapsed * HZ;
-+ dev_dbg(priv->dev, "countDiff %d, jiffes elapsed %d, raw powerValue %d scale to %d mW\n",
-+ (long)(energy_cnt - priv->energy.value),
-+ elapsed, power_val,
-+ power_val >> (power_unit - 10));
-+ } else {
-+ dev_dbg(priv->dev, "countDiff %d, jiffes elapsed %d, skipping calculate power, try agin\n",
-+ (long)(energy_cnt - priv->energy.value),
-+ elapsed);
-+ ret = -EAGAIN;
-+ }
-+
-+ priv->energy.value = energy_cnt;
-+ priv->avg_power_val = power_val >> ((power_unit - 10));
-+ peci_sensor_mark_updated(&priv->energy);
-+
-+ dev_dbg(priv->dev, "energy counter 0x%8x, average power %dmW, jif %u, HZ is %d jiffies\n",
-+ priv->energy.value, priv->avg_power_val,
-+ jif, HZ);
-+ }
-+ return ret;
-+}
-+
-+static int cpupower_read_string(struct device *dev,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel, const char **str)
-+{
-+ if (attr != hwmon_power_label)
-+ return -EOPNOTSUPP;
-+ if (channel >= POWER_DEFAULT_CHANNEL_NUMS)
-+ return -EOPNOTSUPP;
-+ *str = cpupower_label[channel];
-+
-+ return 0;
-+}
-+
-+static int cpupower_read(struct device *dev,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *val)
-+{
-+ struct peci_cpupower *priv = dev_get_drvdata(dev);
-+ int ret;
-+
-+ if (channel >= POWER_DEFAULT_CHANNEL_NUMS ||
-+ !(priv->power_config[channel] & BIT(attr)))
-+ return -EOPNOTSUPP;
-+
-+ switch (attr) {
-+ case hwmon_power_average:
-+ switch (channel) {
-+ case average_power:
-+ ret = get_average_power(priv);
-+ if (ret)
-+ break;
-+
-+ *val = priv->avg_power_val;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ ret = -EOPNOTSUPP;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static umode_t cpupower_is_visible(const void *data,
-+ enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ const struct peci_cpupower *priv = data;
-+
-+ if (channel < POWER_DEFAULT_CHANNEL_NUMS ||
-+ (priv->power_config[channel] & BIT(attr)))
-+ return 0444;
-+
-+ return 0;
-+}
-+
-+static const struct hwmon_ops cpupower_ops = {
-+ .is_visible = cpupower_is_visible,
-+ .read_string = cpupower_read_string,
-+ .read = cpupower_read,
-+};
-+
-+static int peci_cpupower_probe(struct platform_device *pdev)
-+{
-+ struct peci_client_manager *mgr = dev_get_drvdata(pdev->dev.parent);
-+ struct device *dev = &pdev->dev;
-+ struct peci_cpupower *priv;
-+ struct device *hwmon_dev;
-+
-+ if ((mgr->client->adapter->cmd_mask &
-+ (BIT(PECI_CMD_RD_PKG_CFG))) !=
-+ (BIT(PECI_CMD_RD_PKG_CFG))) {
-+ return -ENODEV;
-+ }
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ dev_set_drvdata(dev, priv);
-+ priv->mgr = mgr;
-+ priv->dev = dev;
-+ priv->gen_info = mgr->gen_info;
-+
-+ snprintf(priv->name, PECI_NAME_SIZE, "peci_cpupower.cpu%d",
-+ mgr->client->addr - PECI_BASE_ADDR);
-+
-+ priv->power_config[priv->config_idx++] = config_table[average_power];
-+
-+ priv->chip.ops = &cpupower_ops;
-+ priv->chip.info = priv->info;
-+
-+ priv->info[0] = &priv->power_info;
-+
-+ priv->power_info.type = hwmon_power;
-+ priv->power_info.config = priv->power_config;
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(priv->dev,
-+ priv->name,
-+ priv,
-+ &priv->chip,
-+ NULL);
-+
-+ if (IS_ERR(hwmon_dev))
-+ return PTR_ERR(hwmon_dev);
-+
-+ dev_dbg(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), priv->name);
-+
-+ return 0;
-+}
-+
-+static const struct platform_device_id peci_cpupower_ids[] = {
-+ { .name = "peci-cpupower", .driver_data = 0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(platform, peci_cpupower_ids);
-+
-+static struct platform_driver peci_cpupower_driver = {
-+ .probe = peci_cpupower_probe,
-+ .id_table = peci_cpupower_ids,
-+ .driver = { .name = KBUILD_MODNAME, },
-+};
-+module_platform_driver(peci_cpupower_driver);
-+
-+MODULE_AUTHOR("Zhikui Ren <zhikui.ren@intel.com>");
-+MODULE_DESCRIPTION("PECI cpupower driver");
-+MODULE_LICENSE("GPL v2");
-diff --git a/drivers/mfd/intel-peci-client.c b/drivers/mfd/intel-peci-client.c
-index 9751b04..0c62ad6 100644
---- a/drivers/mfd/intel-peci-client.c
-+++ b/drivers/mfd/intel-peci-client.c
-@@ -21,6 +21,7 @@
- static struct mfd_cell peci_functions[] = {
- { .name = "peci-cputemp", },
- { .name = "peci-dimmtemp", },
-+ { .name = "peci-cpupower", },
- };
-
- static const struct cpu_gen_info cpu_gen_info_table[] = {
-diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h
-index 843930f..d16f7c9 100644
---- a/include/uapi/linux/peci-ioctl.h
-+++ b/include/uapi/linux/peci-ioctl.h
-@@ -231,6 +231,7 @@ struct peci_rd_pkg_cfg_msg {
- #define PECI_PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */
- #define PECI_PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */
- #define PECI_PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */
-+#define PECI_PKG_ID_PKG_ENERGY_STATUS 0x00ff /* Average Energy */
-
- __u8 rx_len;
- __u8 cc;
---
-2.7.4
-