diff --git a/patch/0060-hwmon-pmbus-core-Add-support-for-vid-mode-detecti.patch b/patch/0060-hwmon-pmbus-core-Add-support-for-vid-mode-detecti.patch new file mode 100644 index 000000000..2ce567aff --- /dev/null +++ b/patch/0060-hwmon-pmbus-core-Add-support-for-vid-mode-detecti.patch @@ -0,0 +1,386 @@ +From 482c5a7b46fd39c2df42c47f96a817c2d50b9c75 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Tue, 3 Mar 2020 14:33:59 +0200 +Subject: [hwmon v1] hwmon: (pmbus/core) Add support for vid mode detection per + page bases + +Add support for VID protocol detection per page bases, instead of +detecting it based on PMBU_VOUT readout from page 0. +The reason that some devices allows to configure different VID modes +per page within the same device. + +Extend "vrm_version" with the type for Intel IMVP9 and AMD 6.25mV VID +modes. +Add calculation for those types. + +Add support for devices XDPE12254, XDPE12284. +All these device support two pages. +The below lists of VOUT_MODE command readout with their related VID +protocols, Digital to Analog Converter steps, supported by these +devices: +VR12.0 mode, 5-mV DAC - 0x01; +VR12.5 mode, 10-mV DAC - 0x02; +IMVP9 mode, 5-mV DAC - 0x03; +AMD mode 6.25mV - 0x10. + +Signed-off-by: Vadim Pasternak +--- + drivers/hwmon/pmbus/Kconfig | 9 +++ + drivers/hwmon/pmbus/Makefile | 1 + + drivers/hwmon/pmbus/max20751.c | 2 +- + drivers/hwmon/pmbus/pmbus.c | 5 +- + drivers/hwmon/pmbus/pmbus.h | 4 +- + drivers/hwmon/pmbus/pmbus_core.c | 10 ++- + drivers/hwmon/pmbus/tps53679.c | 44 +++++----- + drivers/hwmon/pmbus/xdpe12284.c | 171 +++++++++++++++++++++++++++++++++++++++ + 8 files changed, 219 insertions(+), 27 deletions(-) + create mode 100644 drivers/hwmon/pmbus/xdpe12284.c + +diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig +index 61938ea22208..79fd67e0c940 100644 +--- a/drivers/hwmon/pmbus/Kconfig ++++ b/drivers/hwmon/pmbus/Kconfig +@@ -156,6 +156,15 @@ config SENSORS_UCD9200 + This driver can also be built as a module. If so, the module will + be called ucd9200. + ++config SENSORS_XDPE122 ++ tristate "Infineon XDPE122 family" ++ help ++ If you say yes here you get hardware monitoring support for Infineon ++ XDPE12254, XDPE12284, device. ++ ++ This driver can also be built as a module. If so, the module will ++ be called xdpe12284. ++ + config SENSORS_ZL6100 + tristate "Intersil ZL6100 and compatibles" + default n +diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile +index b912fec9876d..e0fe17121afb 100644 +--- a/drivers/hwmon/pmbus/Makefile ++++ b/drivers/hwmon/pmbus/Makefile +@@ -16,4 +16,5 @@ obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o + obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o + obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o + obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o ++obj-$(CONFIG_SENSORS_XDPE122) += xdpe12284.o + obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o +diff --git a/drivers/hwmon/pmbus/max20751.c b/drivers/hwmon/pmbus/max20751.c +index ab74aeae8cf2..394c662c811b 100644 +--- a/drivers/hwmon/pmbus/max20751.c ++++ b/drivers/hwmon/pmbus/max20751.c +@@ -25,7 +25,7 @@ static struct pmbus_driver_info max20751_info = { + .pages = 1, + .format[PSC_VOLTAGE_IN] = linear, + .format[PSC_VOLTAGE_OUT] = vid, +- .vrm_version = vr12, ++ .vrm_version[0] = vr12, + .format[PSC_TEMPERATURE] = linear, + .format[PSC_CURRENT_OUT] = linear, + .format[PSC_POWER] = linear, +diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c +index 44ca8a94873d..ad360a88a53a 100644 +--- a/drivers/hwmon/pmbus/pmbus.c ++++ b/drivers/hwmon/pmbus/pmbus.c +@@ -121,7 +121,7 @@ static int pmbus_identify(struct i2c_client *client, + } + + if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { +- int vout_mode; ++ int vout_mode, i; + + vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); + if (vout_mode >= 0 && vout_mode != 0xff) { +@@ -130,7 +130,8 @@ static int pmbus_identify(struct i2c_client *client, + break; + case 1: + info->format[PSC_VOLTAGE_OUT] = vid; +- info->vrm_version = vr11; ++ for (i = 0; i < info->pages; i++) ++ info->vrm_version[i] = vr11; + break; + case 2: + info->format[PSC_VOLTAGE_OUT] = direct; +diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h +index 4efa2bd4f6d8..881156491581 100644 +--- a/drivers/hwmon/pmbus/pmbus.h ++++ b/drivers/hwmon/pmbus/pmbus.h +@@ -341,12 +341,12 @@ enum pmbus_sensor_classes { + #define PMBUS_HAVE_STATUS_VMON BIT(19) + + enum pmbus_data_format { linear = 0, direct, vid }; +-enum vrm_version { vr11 = 0, vr12, vr13 }; ++enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv }; + + struct pmbus_driver_info { + int pages; /* Total number of pages */ + enum pmbus_data_format format[PSC_NUM_CLASSES]; +- enum vrm_version vrm_version; ++ enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */ + /* + * Support one set of coefficients for each sensor type + * Used for chips providing data in direct mode. +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c +index 682b01624908..764a28105831 100644 +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -522,7 +522,7 @@ static long pmbus_reg2data_vid(struct pmbus_data *data, + long val = sensor->data; + long rv = 0; + +- switch (data->info->vrm_version) { ++ switch (data->info->vrm_version[sensor->page]) { + case vr11: + if (val >= 0x02 && val <= 0xb2) + rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); +@@ -535,6 +535,14 @@ static long pmbus_reg2data_vid(struct pmbus_data *data, + if (val >= 0x01) + rv = 500 + (val - 1) * 10; + break; ++ case imvp9: ++ if (val >= 0x01) ++ rv = 200 + (val - 1) * 10; ++ break; ++ case amd625mv: ++ if (val >= 0x0 && val <= 0xd8) ++ rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100); ++ break; + } + return rv; + } +diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c +index 45eacc504e2f..28d3de029b91 100644 +--- a/drivers/hwmon/pmbus/tps53679.c ++++ b/drivers/hwmon/pmbus/tps53679.c +@@ -33,27 +33,29 @@ static int tps53679_identify(struct i2c_client *client, + struct pmbus_driver_info *info) + { + u8 vout_params; +- int ret; +- +- /* Read the register with VOUT scaling value.*/ +- ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); +- if (ret < 0) +- return ret; +- +- vout_params = ret & GENMASK(4, 0); +- +- switch (vout_params) { +- case TPS53679_PROT_VR13_10MV: +- case TPS53679_PROT_VR12_5_10MV: +- info->vrm_version = vr13; +- break; +- case TPS53679_PROT_VR13_5MV: +- case TPS53679_PROT_VR12_5MV: +- case TPS53679_PROT_IMVP8_5MV: +- info->vrm_version = vr12; +- break; +- default: +- return -EINVAL; ++ int i, ret; ++ ++ for (i = 0; i < TPS53679_PAGE_NUM; i++) { ++ /* Read the register with VOUT scaling value.*/ ++ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); ++ if (ret < 0) ++ return ret; ++ ++ vout_params = ret & GENMASK(4, 0); ++ ++ switch (vout_params) { ++ case TPS53679_PROT_VR13_10MV: ++ case TPS53679_PROT_VR12_5_10MV: ++ info->vrm_version[i] = vr13; ++ break; ++ case TPS53679_PROT_VR13_5MV: ++ case TPS53679_PROT_VR12_5MV: ++ case TPS53679_PROT_IMVP8_5MV: ++ info->vrm_version[i] = vr12; ++ break; ++ default: ++ return -EINVAL; ++ } + } + + return 0; +diff --git a/drivers/hwmon/pmbus/xdpe12284.c b/drivers/hwmon/pmbus/xdpe12284.c +new file mode 100644 +index 000000000000..660556b89e9f +--- /dev/null ++++ b/drivers/hwmon/pmbus/xdpe12284.c +@@ -0,0 +1,171 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Hardware monitoring driver for Infineon Multi-phase Digital VR Controllers ++ * ++ * Copyright (c) 2020 Mellanox Technologies. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "pmbus.h" ++ ++#define XDPE122_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ ++#define XDPE122_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ ++#define XDPE122_PROT_IMVP9_10MV 0x03 /* IMVP9 mode, 10-mV DAC */ ++#define XDPE122_AMD_625MV 0x10 /* AMD mode 6.25mV */ ++#define XDPE122_PAGE_NUM 2 ++ ++static int xdpe122_read_word_data(struct i2c_client *client, int page, int reg) ++{ ++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client); ++ long val; ++ s16 exponent; ++ s32 mantissa; ++ int ret; ++ ++ switch (reg) { ++ case PMBUS_VOUT_OV_FAULT_LIMIT: ++ case PMBUS_VOUT_UV_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, reg); ++ if (ret < 0) ++ return ret; ++ ++ /* Convert register value to LINEAR11 data. */ ++ exponent = ((s16)ret) >> 11; ++ mantissa = ((s16)((ret & GENMASK(10, 0)) << 5)) >> 5; ++ val = mantissa * 1000L; ++ if (exponent >= 0) ++ val <<= exponent; ++ else ++ val >>= -exponent; ++ ++ /* Convert data to VID register. */ ++ switch (info->vrm_version[page]) { ++ case vr13: ++ if (val >= 500) ++ return 1 + DIV_ROUND_CLOSEST(val - 500, 10); ++ return 0; ++ case vr12: ++ if (val >= 250) ++ return 1 + DIV_ROUND_CLOSEST(val - 250, 5); ++ return 0; ++ case imvp9: ++ if (val >= 200) ++ return 1 + DIV_ROUND_CLOSEST(val - 200, 10); ++ return 0; ++ case amd625mv: ++ if (val >= 200 && val <= 1550) ++ return DIV_ROUND_CLOSEST((1550 - val) * 100, ++ 625); ++ return 0; ++ default: ++ return -EINVAL; ++ } ++ default: ++ return -ENODATA; ++ } ++ ++ return 0; ++} ++ ++static int xdpe122_identify(struct i2c_client *client, ++ struct pmbus_driver_info *info) ++{ ++ u8 vout_params; ++ int i, ret; ++ ++ for (i = 0; i < XDPE122_PAGE_NUM; i++) { ++ /* Read the register with VOUT scaling value.*/ ++ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); ++ if (ret < 0) ++ return ret; ++ ++ vout_params = ret & GENMASK(4, 0); ++ ++ switch (vout_params) { ++ case XDPE122_PROT_VR12_5_10MV: ++ info->vrm_version[i] = vr13; ++ break; ++ case XDPE122_PROT_VR12_5MV: ++ info->vrm_version[i] = vr12; ++ break; ++ case XDPE122_PROT_IMVP9_10MV: ++ info->vrm_version[i] = imvp9; ++ break; ++ case XDPE122_AMD_625MV: ++ info->vrm_version[i] = amd625mv; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static struct pmbus_driver_info xdpe122_info = { ++ .pages = XDPE122_PAGE_NUM, ++ .format[PSC_VOLTAGE_IN] = linear, ++ .format[PSC_VOLTAGE_OUT] = vid, ++ .format[PSC_TEMPERATURE] = linear, ++ .format[PSC_CURRENT_IN] = linear, ++ .format[PSC_CURRENT_OUT] = linear, ++ .format[PSC_POWER] = linear, ++ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ++ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ++ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | ++ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, ++ .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ++ PMBUS_HAVE_IIN | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ++ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | ++ PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, ++ .identify = xdpe122_identify, ++ .read_word_data = xdpe122_read_word_data, ++}; ++ ++static int xdpe122_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ struct pmbus_driver_info *info; ++ ++ info = devm_kmemdup(&client->dev, &xdpe122_info, sizeof(*info), ++ GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ ++ return pmbus_do_probe(client, id, info); ++} ++ ++static const struct i2c_device_id xdpe122_id[] = { ++ {"xdpe12254", 0}, ++ {"xdpe12284", 0}, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(i2c, xdpe122_id); ++ ++static const struct of_device_id __maybe_unused xdpe122_of_match[] = { ++ {.compatible = "infineon,xdpe12254"}, ++ {.compatible = "infineon,xdpe12284"}, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, xdpe122_of_match); ++ ++static struct i2c_driver xdpe122_driver = { ++ .driver = { ++ .name = "xdpe12284", ++ .of_match_table = of_match_ptr(xdpe122_of_match), ++ }, ++ .probe = xdpe122_probe, ++ .remove = pmbus_do_remove, ++ .id_table = xdpe122_id, ++}; ++ ++module_i2c_driver(xdpe122_driver); ++ ++MODULE_AUTHOR("Vadim Pasternak "); ++MODULE_DESCRIPTION("PMBus driver for Infineon XDPE122 family"); ++MODULE_LICENSE("GPL"); +-- +2.11.0 + diff --git a/patch/0061-i2c-busses-i2c-mlxcpld-Increase-transaction-pooli.patch b/patch/0061-i2c-busses-i2c-mlxcpld-Increase-transaction-pooli.patch new file mode 100644 index 000000000..62cf8e834 --- /dev/null +++ b/patch/0061-i2c-busses-i2c-mlxcpld-Increase-transaction-pooli.patch @@ -0,0 +1,31 @@ +From 10301ce5d3375b4a088710e3ce8ecc6f4acc6ed7 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Thu, 5 Mar 2020 13:09:06 +0200 +Subject: [hwmon v1] i2c: busses: i2c-mlxcpld: Increase transaction pooling + time + +i2c-mlxcpld polling time from 200 to 600 usec due to some +problematic power supply units, which cannot work with +such frequency. + +Signed-off-by: Vadim Pasternak +--- + drivers/i2c/busses/i2c-mlxcpld.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c +index 41b57027e348..6da4b58eee4f 100644 +--- a/drivers/i2c/busses/i2c-mlxcpld.c ++++ b/drivers/i2c/busses/i2c-mlxcpld.c +@@ -51,7 +51,7 @@ + #define MLXCPLD_I2C_MAX_ADDR_LEN 4 + #define MLXCPLD_I2C_RETR_NUM 2 + #define MLXCPLD_I2C_XFER_TO 500000 /* usec */ +-#define MLXCPLD_I2C_POLL_TIME 200 /* usec */ ++#define MLXCPLD_I2C_POLL_TIME 400 /* usec */ + + /* LPC I2C registers */ + #define MLXCPLD_LPCI2C_CPBLTY_REG 0x0 +-- +2.11.0 + diff --git a/patch/0062-platform-mellanox-mlxreg-hotplug-Use-capability-r.patch b/patch/0062-platform-mellanox-mlxreg-hotplug-Use-capability-r.patch new file mode 100644 index 000000000..3de055dbb --- /dev/null +++ b/patch/0062-platform-mellanox-mlxreg-hotplug-Use-capability-r.patch @@ -0,0 +1,73 @@ +From af50fedeeaa767a0c7c3a9cf399fe23314adc609 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Thu, 12 Mar 2020 23:51:41 +0200 +Subject: [platform-next v1 1/2] platform/mellanox: mlxreg-hotplug: Use + capability register for attribute creation + +Create the 'sysfs' attributes according to configuration provided +through the capability register, which purpose is to indicate the +actual number of the components within the particular group. +Such components could be, for example the FAN or power supply units. +The motivation is to avoid adding a new code in the future in order to +distinct between the systems types supported different number of the +components like power supplies, FANs, ASICs, line cards. + +Signed-off-by: Vadim Pasternak +--- + drivers/platform/mellanox/mlxreg-hotplug.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c +index 77be37a1fbcf..c21754821789 100644 +--- a/drivers/platform/mellanox/mlxreg-hotplug.c ++++ b/drivers/platform/mellanox/mlxreg-hotplug.c +@@ -196,17 +196,29 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv) + struct mlxreg_core_hotplug_platform_data *pdata; + struct mlxreg_core_item *item; + struct mlxreg_core_data *data; +- int num_attrs = 0, id = 0, i, j; ++ u32 regval; ++ int num_attrs = 0, id = 0, i, j, k, ret; + + pdata = dev_get_platdata(&priv->pdev->dev); + item = pdata->items; + + /* Go over all kinds of items - psu, pwr, fan. */ + for (i = 0; i < pdata->counter; i++, item++) { +- num_attrs += item->count; + data = item->data; + /* Go over all units within the item. */ +- for (j = 0; j < item->count; j++, data++, id++) { ++ for (j = 0, k = 0; j < item->count; j++, data++) { ++ if (data->capability) { ++ /* ++ * Read capability register and skip non ++ * relevant attributes. ++ */ ++ ret = regmap_read(priv->regmap, ++ data->capability, ®val); ++ if (ret) ++ return ret; ++ if (!(regval & data->bit)) ++ continue; ++ } + PRIV_ATTR(id) = &PRIV_DEV_ATTR(id).dev_attr.attr; + PRIV_ATTR(id)->name = devm_kasprintf(&priv->pdev->dev, + GFP_KERNEL, +@@ -224,9 +236,12 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv) + PRIV_DEV_ATTR(id).dev_attr.show = + mlxreg_hotplug_attr_show; + PRIV_DEV_ATTR(id).nr = i; +- PRIV_DEV_ATTR(id).index = j; ++ PRIV_DEV_ATTR(id).index = k; + sysfs_attr_init(&PRIV_DEV_ATTR(id).dev_attr.attr); ++ id++; ++ k++; + } ++ num_attrs += k; + } + + priv->group.attrs = devm_kcalloc(&priv->pdev->dev, +-- +2.11.0 + diff --git a/patch/0063-platform-mellanox-mlxreg-io-Add-support-for-compl.patch b/patch/0063-platform-mellanox-mlxreg-io-Add-support-for-compl.patch new file mode 100644 index 000000000..35101092d --- /dev/null +++ b/patch/0063-platform-mellanox-mlxreg-io-Add-support-for-compl.patch @@ -0,0 +1,256 @@ +From e74853715ed50660960ee7891e1979c685ab2fde Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Fri, 13 Mar 2020 00:15:54 +0200 +Subject: [platform-next v1 2/2] platform/mellanox: mlxreg-io: Add support for + complex attributes + +Add support for attributes composed from few registers. +Such attributes could occupy from 2 to 4 sequential registers. +This is not the case for double word size register space, for word size +register space complex attribute can occupy up to two register, for +byte size - up to four. These attributes can carry, for example, CPLD +or FPGA versioning, power consuming info, etcetera. + +Signed-off-by: Vadim Pasternak +--- + drivers/platform/mellanox/mlxreg-io.c | 79 ++++++++++++++++++++++++++++++----- + drivers/platform/x86/mlx-platform.c | 72 +++++++++++++++++++++++++++++++ + 2 files changed, 141 insertions(+), 10 deletions(-) + +diff --git a/drivers/platform/mellanox/mlxreg-io.c b/drivers/platform/mellanox/mlxreg-io.c +index acfaf64ffde6..b8b8300928dd 100644 +--- a/drivers/platform/mellanox/mlxreg-io.c ++++ b/drivers/platform/mellanox/mlxreg-io.c +@@ -19,6 +19,13 @@ + /* Attribute parameters. */ + #define MLXREG_IO_ATT_SIZE 10 + #define MLXREG_IO_ATT_NUM 48 ++#define MLXREG_IO_REGVAL_ARR 4 ++#define MLXREG_IO_REG_8BIT GENMASK(7, 0) ++#define MLXREG_IO_REG_16BIT GENMASK(15, 0) ++#define MLXREG_IO_REG_24BIT GENMASK(23, 0) ++#define MLXREG_IO_REG_32BIT GENMASK(31, 0) ++#define MLXREG_IO_REG_BYTE 8 ++#define MLXREG_IO_REG_WORD 16 + + /** + * struct mlxreg_io_priv_data - driver's private data: +@@ -45,21 +52,23 @@ static int + mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val, + bool rw_flag, u32 *regval) + { +- int ret; ++ u32 val; ++ int regnum, len, mask, i, ret; + + ret = regmap_read(regmap, data->reg, regval); + if (ret) + goto access_error; +- + /* +- * There are three kinds of attributes: single bit, full register's +- * bits and bit sequence. For the first kind field mask indicates which +- * bits are not related and field bit is set zero. For the second kind +- * field mask is set to zero and field bit is set with all bits one. +- * No special handling for such kind of attributes - pass value as is. +- * For the third kind, field mask indicates which bits are related and +- * field bit is set to the first bit number (from 1 to 32) is the bit +- * sequence. ++ * There are four kinds of attributes: single bit, full register's ++ * bits, bit sequence, bits in few registers For the first kind field ++ * mask indicates which bits are not related and field bit is set zero. ++ * For the second kind field mask is set to zero and field bit is set ++ * with all bits one. No special handling for such kind of attributes - ++ * pass value as is. For the third kind, field mask indicates which ++ * bits are related and field bit is set to the first bit number (from ++ * 1 to 32) is the bit sequence. For the fourth mask - the number of ++ * registers which should be written for attribute are set according ++ * to 'data->bit' field. + */ + if (!data->bit) { + /* Single bit. */ +@@ -83,6 +92,56 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val, + /* Clear relevant bits and set them to new value. */ + *regval = (*regval & ~data->mask) | in_val; + } ++ } else { ++ /* ++ * Some attributes could occupied few registers in case regmap ++ * bit size is 8 or 16. Maximum register for such case is ++ * respectively 0xff or 0xffff. Not relevant for the case, when ++ * regmap bit size is 32 and maximum registers 0xffffffff. ++ */ ++ mask = regmap_get_max_register(regmap); ++ if (mask < 0) ++ goto access_error; ++ ++ /* ++ * Get register bit length and the number of registers from ++ * wich this attribute is composed. Attribute can be located ++ * in 1, 2, 3 or 4 registers. ++ */ ++ switch (mask) { ++ case MLXREG_IO_REG_8BIT: ++ if (data->bit > MLXREG_IO_REG_24BIT) ++ regnum = 4; ++ else if (data->bit > MLXREG_IO_REG_16BIT) ++ regnum = 3; ++ else if (data->bit > MLXREG_IO_REG_8BIT) ++ regnum = 2; ++ else ++ return ret; ++ len = MLXREG_IO_REG_BYTE; ++ break; ++ case MLXREG_IO_REG_16BIT: ++ if (data->bit > MLXREG_IO_REG_16BIT) ++ regnum = 2; ++ else ++ return ret; ++ len = MLXREG_IO_REG_WORD; ++ break; ++ case MLXREG_IO_REG_32BIT: ++ return ret; ++ default: ++ return -EINVAL; ++ } ++ ++ /* Compose attribute from 'regnum' registers. */ ++ for (i = 1; i < regnum; i++) { ++ ret = regmap_read(regmap, data->reg + i, &val); ++ if (ret) ++ goto access_error; ++ ++ *regval |= rol32(val, len * i); ++ } ++ *regval = le32_to_cpu(*regval & mask); + } + + access_error: +diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c +index c27548fd386a..a916a1d7ce2d 100644 +--- a/drivers/platform/x86/mlx-platform.c ++++ b/drivers/platform/x86/mlx-platform.c +@@ -26,6 +26,10 @@ + #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01 + #define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02 + #define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03 ++#define MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET 0x04 ++#define MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET 0x06 ++#define MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET 0x08 ++#define MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET 0x0a + #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d + #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e + #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f +@@ -72,6 +76,10 @@ + #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1 + #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET 0xd2 + #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd3 ++#define MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET 0xde ++#define MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET 0xdf ++#define MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET 0xe0 ++#define MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET 0xe1 + #define MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET 0xe2 + #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3 + #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4 +@@ -1528,6 +1536,54 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .mode = 0444, + }, + { ++ .label = "cpld1_pn", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET, ++ .bit = GENMASK(15, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld2_pn", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET, ++ .bit = GENMASK(15, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld3_pn", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET, ++ .bit = GENMASK(15, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld4_pn", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET, ++ .bit = GENMASK(15, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld1_version_min", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld2_version_min", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld3_version_min", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, ++ { ++ .label = "cpld4_version_min", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, ++ { + .label = "reset_long_pb", + .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, + .mask = GENMASK(7, 0) & ~BIT(0), +@@ -2006,6 +2062,10 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: +@@ -2051,6 +2111,10 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET: + case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET: +@@ -2085,6 +2149,10 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: +@@ -2122,6 +2190,10 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET: + case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET: +-- +2.11.0 + diff --git a/patch/0064-Add-config-for-sensor-xdpe122-and-modify-mlx_wdt-.patch b/patch/0064-Add-config-for-sensor-xdpe122-and-modify-mlx_wdt-.patch new file mode 100644 index 000000000..8e057a3b9 --- /dev/null +++ b/patch/0064-Add-config-for-sensor-xdpe122-and-modify-mlx_wdt-.patch @@ -0,0 +1,89 @@ +From 90ddafe594f825e72fcdf4294f60e73ba7a689f9 Mon Sep 17 00:00:00 2001 +From: Stephen Sun +Date: Wed, 25 Mar 2020 15:07:34 +0000 +Subject: [PATCH] Add config for sensor xdpe122 and modify mlx_wdt to m +Add the following options to kernel config file: +CONFIG_SENSORS_XDPE122=m Modify the following +options to kernel config file: +CONFIG_MLX_WDT=y => CONFIG_MLX_WDT=m + +Signed-off-by: Stephen Sun +--- + debian/build/build_amd64_none_amd64/.config | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/debian/build/build_amd64_none_amd64/.config b/debian/build/build_amd64_none_amd64/.config +index 6c4c6443..6ae593b6 100644 +--- a/debian/build/build_amd64_none_amd64/.config ++++ b/debian/build/build_amd64_none_amd64/.config +@@ -707,7 +707,6 @@ CONFIG_ACPI_EXTLOG=y + # CONFIG_PMIC_OPREGION is not set + # CONFIG_ACPI_CONFIGFS is not set + CONFIG_SFI=y +-CONFIG_SENSORS_MLXREG_FAN=m + + # + # CPU Frequency scaling +@@ -1453,6 +1452,7 @@ CONFIG_NET_ACT_POLICE=m + CONFIG_NET_ACT_GACT=m + CONFIG_GACT_PROB=y + CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_SAMPLE=m + CONFIG_NET_ACT_IPT=m + CONFIG_NET_ACT_NAT=m + CONFIG_NET_ACT_PEDIT=m +@@ -1761,6 +1761,7 @@ CONFIG_NFC_PN533_USB=m + # CONFIG_NFC_PN533_I2C is not set + # CONFIG_NFC_MICROREAD_MEI is not set + # CONFIG_NFC_ST95HF is not set ++CONFIG_PSAMPLE=m + CONFIG_LWTUNNEL=y + CONFIG_DST_CACHE=y + CONFIG_NET_DEVLINK=m +@@ -3925,6 +3926,7 @@ CONFIG_SENSORS_MAX6620=m + CONFIG_SENSORS_MAX6697=m + CONFIG_SENSORS_MAX31790=m + # CONFIG_SENSORS_MCP3021 is not set ++CONFIG_SENSORS_MLXREG_FAN=m + CONFIG_SENSORS_MENF21BMC_HWMON=m + CONFIG_SENSORS_ADCXX=m + CONFIG_SENSORS_LM63=m +@@ -3966,8 +3968,9 @@ CONFIG_SENSORS_DNI_DPS460=m + CONFIG_SENSORS_TPS53679=m + CONFIG_SENSORS_UCD9000=m + CONFIG_SENSORS_UCD9200=m +-CONFIG_SENSORS_DPS1900=m ++CONFIG_SENSORS_XDPE122=m + # CONFIG_SENSORS_ZL6100 is not set ++CONFIG_SENSORS_DPS1900=m + # CONFIG_SENSORS_SHT15 is not set + CONFIG_SENSORS_SHT21=m + # CONFIG_SENSORS_SHT3x is not set +@@ -4057,6 +4060,7 @@ CONFIG_MENF21BMC_WATCHDOG=m + # CONFIG_WDAT_WDT is not set + # CONFIG_XILINX_WATCHDOG is not set + # CONFIG_ZIIRAVE_WATCHDOG is not set ++CONFIG_MLX_WDT=m + # CONFIG_CADENCE_WATCHDOG is not set + # CONFIG_DW_WATCHDOG is not set + # CONFIG_MAX63XX_WATCHDOG is not set +@@ -4097,7 +4101,6 @@ CONFIG_SBC_EPX_C3_WATCHDOG=m + # CONFIG_NI903X_WDT is not set + # CONFIG_MEN_A21_WDT is not set + CONFIG_XEN_WDT=m +-CONFIG_MLX_WDT=y + + # + # PCI-based Watchdog Cards +@@ -6139,7 +6142,7 @@ CONFIG_INTEL_MIC_X100_DMA=m + # CONFIG_QCOM_HIDMA is not set + CONFIG_DW_DMAC_CORE=m + CONFIG_DW_DMAC=m +-# CONFIG_DW_DMAC_PCI is not set ++CONFIG_DW_DMAC_PCI=m + CONFIG_HSU_DMA=y + + # +-- +2.11.0 + diff --git a/patch/series b/patch/series index 075a64f01..b13162b0a 100755 --- a/patch/series +++ b/patch/series @@ -97,6 +97,11 @@ linux-4.13-thermal-intel_pch_thermal-Fix-enable-check-on.patch 0057-mlxsw-minimal-Fix-validation-for-FW-minor-version.patch 0058-mlxsw-core-thermal-Set-default-thermal-trips-at-init.patch 0059-mlxsw-core-Add-the-hottest-thermal-zone-detection.patch +0060-hwmon-pmbus-core-Add-support-for-vid-mode-detecti.patch +0061-i2c-busses-i2c-mlxcpld-Increase-transaction-pooli.patch +0062-platform-mellanox-mlxreg-hotplug-Use-capability-r.patch +0063-platform-mellanox-mlxreg-io-Add-support-for-compl.patch +0064-Add-config-for-sensor-xdpe122-and-modify-mlx_wdt-.patch linux-4.16-firmware-dmi-handle-missing-DMI-data-gracefully.patch mellanox-backport-introduce-psample-a-new-genetlink-channel.patch mellanox-backport-introduce-tc-sample-action.patch