diff options
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.patch | 405 |
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 - |