From fae04902baf5c421b32cbe5e223d1a1ac69b5fe4 Mon Sep 17 00:00:00 2001 From: Vivek Date: Mon, 3 Jun 2024 22:48:11 +0000 Subject: [PATCH 1/2] Integrate HW-MGMT 7.0030.4002 Changes ## Patch List * 0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch : https://github.com/torvalds/linux/commit/e7210563432a * 0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch : * 0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch : * 0089-platform-mellanox-mlx-platform-Change-register-name.patch : * 0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch : * 0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch : --- ...-Add-support-for-new-flavour-of-capa.patch | 43 +- ...-fan-Extend-number-of-supporetd-fans.patch | 10 +- ...support-for-new-flavour-of-capabilit.patch | 10 +- ...reg-Remove-code-for-amber-LED-colour.patch | 7 +- ...support-for-MPS-Multi-phase-mp2891-c.patch | 259 +-- ...-setting-LED-color-during-initializa.patch | 8 +- ...I-Add-new-attribute-for-mlxreg-io-sy.patch | 74 + ...-Separate-methods-of-fan-setting-com.patch | 18 +- ...xreg-Add-capability-bit-and-mask-fie.patch | 60 + ...x-mlxreg-hotplug-Add-support-for-new.patch | 87 + ...ox-mlx-platform-Change-register-name.patch | 57 + ...x-mlx-platform-Add-support-for-new-X.patch | 1402 +++++++++++++++++ ...support-for-MPS-Multi-phase-mp2855-c.patch | 457 ++++++ ...-Downstream-Send-udev-event-from-led.patch | 8 +- ...-Downstream-Allow-fan-speed-setting-.patch | 13 +- patch/kconfig-inclusions | 14 + patch/series | 6 + 17 files changed, 2391 insertions(+), 142 deletions(-) create mode 100644 patch/0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch create mode 100644 patch/0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch create mode 100644 patch/0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch create mode 100644 patch/0089-platform-mellanox-mlx-platform-Change-register-name.patch create mode 100644 patch/0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch create mode 100644 patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch diff --git a/patch/0042-hwmon-mlxreg-fan-Add-support-for-new-flavour-of-capa.patch b/patch/0042-hwmon-mlxreg-fan-Add-support-for-new-flavour-of-capa.patch index df8454321..cced17761 100644 --- a/patch/0042-hwmon-mlxreg-fan-Add-support-for-new-flavour-of-capa.patch +++ b/patch/0042-hwmon-mlxreg-fan-Add-support-for-new-flavour-of-capa.patch @@ -1,8 +1,8 @@ -From bb46d45ce13c8faf9c2ab57b945c3a3adc587918 Mon Sep 17 00:00:00 2001 +From c729c7228762db53a6219d3ef126226b50b54dfc Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Sun, 23 Jul 2023 06:26:09 +0000 -Subject: [PATCH backport 6.1.42 42/85] hwmon: (mlxreg-fan) Add support for new - flavour of capability register +Subject: [PATCH v6.1 23/80] hwmon: (mlxreg-fan) Add support for new flavour of + capability register FAN platform data is common across the various systems, while fan driver should be able to apply only the fan instances relevant @@ -27,14 +27,41 @@ bitmask or counter. Signed-off-by: Vadim Pasternak --- - drivers/hwmon/mlxreg-fan.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) + drivers/hwmon/mlxreg-fan.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c -index 96017cc8da7e..dad94d2892b2 100644 +index 96017cc8da7e..342ff355e925 100644 --- a/drivers/hwmon/mlxreg-fan.c +++ b/drivers/hwmon/mlxreg-fan.c -@@ -390,7 +390,7 @@ static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan, +@@ -63,12 +63,14 @@ struct mlxreg_fan; + * @reg: register offset; + * @mask: fault mask; + * @prsnt: present register offset; ++ * @shift: tacho presence bit shift; + */ + struct mlxreg_fan_tacho { + bool connected; + u32 reg; + u32 mask; + u32 prsnt; ++ u32 shift; + }; + + /* +@@ -143,8 +145,10 @@ mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, + /* + * Map channel to presence bit - drawer can be equipped with + * one or few FANs, while presence is indicated per drawer. ++ * Shift channle value if necessary to align with register value. + */ +- if (BIT(channel / fan->tachos_per_drwr) & regval) { ++ if (BIT(rol32(channel, tacho->shift) / fan->tachos_per_drwr) & ++ regval) { + /* FAN is not connected - return zero for FAN speed. */ + *val = 0; + return 0; +@@ -390,7 +394,7 @@ static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan, return err; } @@ -43,7 +70,7 @@ index 96017cc8da7e..dad94d2892b2 100644 } static int mlxreg_pwm_connect_verify(struct mlxreg_fan *fan, -@@ -527,7 +527,15 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan, +@@ -527,7 +531,15 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan, return err; } diff --git a/patch/0043-hwmon-mlxreg-fan-Extend-number-of-supporetd-fans.patch b/patch/0043-hwmon-mlxreg-fan-Extend-number-of-supporetd-fans.patch index 08e93d5d6..115e5f406 100644 --- a/patch/0043-hwmon-mlxreg-fan-Extend-number-of-supporetd-fans.patch +++ b/patch/0043-hwmon-mlxreg-fan-Extend-number-of-supporetd-fans.patch @@ -1,8 +1,8 @@ -From fa70f126d07b6fe84c1c110fb3a3923570b72f2e Mon Sep 17 00:00:00 2001 +From 8769d44cd9dab3e8e6f539956a40eb041f479fef Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Sun, 23 Jul 2023 06:49:01 +0000 -Subject: [PATCH backport 6.1.42 43/85] hwmon: (mlxreg-fan) Extend number of - supporetd fans +Subject: [PATCH v6.1 24/80] hwmon: (mlxreg-fan) Extend number of supporetd + fans Some new big modular systems can be equipped with up to 24 fans. Extend maximum number of fans accordingly. @@ -13,7 +13,7 @@ Signed-off-by: Vadim Pasternak 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c -index dad94d2892b2..c515e1d2fe4e 100644 +index 342ff355e925..bddc927b207c 100644 --- a/drivers/hwmon/mlxreg-fan.c +++ b/drivers/hwmon/mlxreg-fan.c @@ -12,7 +12,7 @@ @@ -25,7 +25,7 @@ index dad94d2892b2..c515e1d2fe4e 100644 #define MLXREG_FAN_MAX_PWM 4 #define MLXREG_FAN_PWM_NOT_CONNECTED 0xff #define MLXREG_FAN_MAX_STATE 10 -@@ -300,6 +300,16 @@ static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = { +@@ -304,6 +304,16 @@ static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = { HWMON_F_INPUT | HWMON_F_FAULT, HWMON_F_INPUT | HWMON_F_FAULT, HWMON_F_INPUT | HWMON_F_FAULT, diff --git a/patch/0044-leds-mlxreg-Add-support-for-new-flavour-of-capabilit.patch b/patch/0044-leds-mlxreg-Add-support-for-new-flavour-of-capabilit.patch index 225ef9b30..bb7a89978 100644 --- a/patch/0044-leds-mlxreg-Add-support-for-new-flavour-of-capabilit.patch +++ b/patch/0044-leds-mlxreg-Add-support-for-new-flavour-of-capabilit.patch @@ -1,8 +1,8 @@ -From 46c4b0cdf2a3abe321e137bcb87e5639c39fd655 Mon Sep 17 00:00:00 2001 +From 242233be3adcd06398d728b2e793d9e40e6fbc3d Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 20 Jul 2023 11:01:56 +0000 -Subject: [PATCH backport 6.1.42 44/85] leds: mlxreg: Add support for new - flavour of capability register +Subject: [PATCH v6.1 25/81] leds: mlxreg: Add support for new flavour of + capability register LED platform data is common across the various systems, while LED driver should be able to apply only the LED instances relevant @@ -28,7 +28,7 @@ Signed-off-by: Vadim Pasternak 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c -index b7855c93bd72..063a9cb50a2b 100644 +index b7855c93bd72..161195de78ba 100644 --- a/drivers/leds/leds-mlxreg.c +++ b/drivers/leds/leds-mlxreg.c @@ -206,16 +206,22 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv) @@ -43,7 +43,7 @@ index b7855c93bd72..063a9cb50a2b 100644 + */ + if (data->slot && data->slot > regval) + continue; -+ else if (!(regval & data->bit)) ++ else if (!(regval & data->bit) && !data->slot) continue; /* * Field "bit" can contain one capability bit in 0 byte diff --git a/patch/0045-leds-mlxreg-Remove-code-for-amber-LED-colour.patch b/patch/0045-leds-mlxreg-Remove-code-for-amber-LED-colour.patch index a20c6183b..b418d5dfa 100644 --- a/patch/0045-leds-mlxreg-Remove-code-for-amber-LED-colour.patch +++ b/patch/0045-leds-mlxreg-Remove-code-for-amber-LED-colour.patch @@ -1,8 +1,7 @@ -From af93d2527b5af3f2e53507c7e35bcd9c9bd521cb Mon Sep 17 00:00:00 2001 +From 9fc276007cac2ab2efc9f55f66c11816f4e2da6b Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 20 Jul 2023 11:17:31 +0000 -Subject: [PATCH backport 6.1.42 45/85] leds: mlxreg: Remove code for amber LED - colour +Subject: [PATCH v6.1 26/81] leds: mlxreg: Remove code for amber LED colour Remove unused code for amber LED colour. @@ -15,7 +14,7 @@ Signed-off-by: Vadim Pasternak 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c -index 063a9cb50a2b..215132f67c07 100644 +index 161195de78ba..23de154ade61 100644 --- a/drivers/leds/leds-mlxreg.c +++ b/drivers/leds/leds-mlxreg.c @@ -19,7 +19,6 @@ diff --git a/patch/0048-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2891-c.patch b/patch/0048-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2891-c.patch index 860a7d220..d94e43e2f 100644 --- a/patch/0048-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2891-c.patch +++ b/patch/0048-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2891-c.patch @@ -1,8 +1,8 @@ -From c8a04a4c79a9fb99215e93884ff76b89e9947275 Mon Sep 17 00:00:00 2001 +From b45f52995f0108302bd25a143b82161d5053b74e Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 13 Jul 2023 06:16:53 +0000 -Subject: [PATCH backport 6.1.42 48/85] hwmon: (pmbus) Add support for MPS - Multi-phase mp2891 controller +Subject: [PATCH v6.1 20/70] hwmon: (pmbus) Add support for MPS Multi-phase + mp2891 controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -21,11 +21,11 @@ This device supports: Signed-off-by: Vadim Pasternak --- - Documentation/hwmon/mp2891.rst | 128 ++++++++++++ + Documentation/hwmon/mp2891.rst | 128 ++++++++++ drivers/hwmon/pmbus/Kconfig | 9 + drivers/hwmon/pmbus/Makefile | 1 + - drivers/hwmon/pmbus/mp2891.c | 357 +++++++++++++++++++++++++++++++++ - 4 files changed, 495 insertions(+) + drivers/hwmon/pmbus/mp2891.c | 424 +++++++++++++++++++++++++++++++++ + 4 files changed, 562 insertions(+) create mode 100644 Documentation/hwmon/mp2891.rst create mode 100644 drivers/hwmon/pmbus/mp2891.c @@ -197,10 +197,10 @@ index 0002dbe22d52..8e767d7b8c5b 100644 obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o diff --git a/drivers/hwmon/pmbus/mp2891.c b/drivers/hwmon/pmbus/mp2891.c new file mode 100644 -index 000000000000..e9e82844ee2a +index 000000000000..1547625fea7e --- /dev/null +++ b/drivers/hwmon/pmbus/mp2891.c -@@ -0,0 +1,357 @@ +@@ -0,0 +1,424 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2891) @@ -213,81 +213,63 @@ index 000000000000..e9e82844ee2a +#include +#include +#include ++#include +#include "pmbus.h" + -+/* Vendor specific registers. */ +/* -+ * MP2891_MFR_SVI3_IOUT_PRT: -+ * bits 15:5 - reserved zeros; -+ * bits 4:3 - set SVI3 Vout digital filter -+ * b00: 5kHz -+ * b01: 2kHz -+ * b10: 1kHz -+ * b11: no filter -+ * bits 2:0 - define output current scaling selection of rail1. -+ * b000: 1 A/LSB -+ * b001: (1/32) A/LSB -+ * b010: (1/16) A/LSB -+ * b011: (1/8) A/LSB -+ * b100: (1/4) A/LSB -+ * b101: (1/2) A/LSB -+ * b110: 1 A/LSB -+ * b111: 2 A/LSB ++ * Vendor specific registers. ++ * Note: command PMBUS_READ_DUTY_CYCLE (0x94) is re-purposed for reading input power. ++ * command PMBUS_READ_FREQUENCY (0x95) is re-purposed for reading input current. + */ ++#define MP2891_VOUT_OV_FAULT_LIMIT_R1 0x40 ++#define MP2891_VOUT_UV_FAULT_LIMIT_R1 0x44 ++#define MP2891_MFR_IIN_RPT_EST 0x53 ++#define MP2891_MFR_IIN_TUNE_GAIN_EST 0x54 +#define MP2891_MFR_SVI3_IOUT_PRT 0x65 -+/* -+ * MP2891_MFR_VOUT_LOOP_CTRL: -+ * bits 15:14 define the VID step. -+ * b00: 6.25mV -+ * b01: 5mV -+ * b10: 2mV -+ * b11: 1mV -+ * bit 13 enable bit of 2.5mV resolution. -+ * b0: disable -+ * b1: enable -+ * bits 12:11 reserved zeros -+ * bit 10 defines rail remote sense amplifier gain: -+ * b0: 1 -+ * b1: 0.5 -+ * bit 9 DC reference_select -+ * b0: Comp EA uses Vfb and Vref -+ * b1: Comp EA uses Vdiff and Vref -+ * bit 8 enables DC loop calibration at DCM. -+ * b0: disable -+ * b1: enable -+ * bit 7 enables DC loop calibration both at DCM and CCM operation. -+ * b0: disable -+ * b1: enable -+ * bit 6 - holds DC loop when the PWM time interval meets PWM switching period condition -+ * set with PMBus command MFR_VR_CONFIG1 (B7h), bit [3:2]. -+ * b0: disable hold DC loop when PWM switching period condition meets -+ * b1: hold DC loop when PWM switching period condition meets -+ * bit 5 hold DC loop when phase count is changed. -+ * b0: disable hold DC loop when phase number change -+ * b1: hold the DC loop when phase number change. -+ * bit 4 hold DC loop regulation when a load transient event is detected. -+ * b0: disable hold DC loop when meets VFB+/- window condition -+ * b1: hold DC loop when meets VFB+/- window condition -+ * bits 3:0 set the DC loop minimal holding time in direct format. -+ */ ++#define MP2891_MFR_READ_PIN_EST 0x94 ++#define MP2891_MFR_READ_IIN_EST 0x95 +#define MP2891_MFR_VOUT_LOOP_CTRL 0xbd + ++#define MP2891_MFR_OVUV_DIV2_R1 BIT(13) ++#define MP2891_MFR_OVP_REF_SEL_R1 BIT(12) ++#define MP2891_MFR_OVP_DELTA_R1 GENAMSK(11, 8) ++#define MP2891_MFR_OVP_ABS_LIMIT_R1 GENMASK(8, 0) ++#define MP2891_MFR_OVP_DELTA_DEFAULT 500 ++#define MP2891_MFR_UVP_REF_SEL_R1 BIT(12) ++#define MP2891_MFR_UVP_DELTA_R1 GENAMSK(11, 8) ++#define MP2891_MFR_UVP_ABS_LIMIT_R1 GENMASK(8, 0) ++#define MP2891_MFR_UVP_OFFSET_DEFAULT (-5000) ++#define MP2891_MFR_OVP_OFFSET_DEFAULT 5000 ++ ++#define MP2891_MFR_OVP_UVP_OFFSET_GET(ret, off) \ ++ (((((ret) & GENMASK(11, 8)) >> 8) + 1) * (off)) ++ +#define MP2891_VID_STEP_POS 14 +#define MP2891_VID_STEP_MASK GENMASK(MP2891_VID_STEP_POS + 1, MP2891_VID_STEP_POS) +#define MP2891_DAC_2P5MV_MASK BIT(13) +#define MP2891_IOUT_SCALE_MASK GENMASK(2, 0) + ++#define MP2975_IIN_OC_WARN_LIMIT_UNIT 2 ++#define MP2975_IOUT_OC_LIMIT_UNIT 4 ++#define MP2975_PIN_LIMIT_UNIT 2 ++#define MP2975_VIN_UNIT 32 ++#define MP2975_IOUT_UC_LIMIT_SCALE 124 ++#define MP2975_IOUT_UC_LIMIT_UNIT 25600 ++#define MP2975_TEMP_LIMIT_OFFSET 40 ++ +#define MP2891_PAGE_NUM 2 ++ +#define MP2891_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \ -+ PMBUS_HAVE_TEMP | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | \ -+ PMBUS_PHASE_VIRTUAL) ++ PMBUS_HAVE_IIN | PMBUS_HAVE_TEMP | PMBUS_HAVE_POUT | \ ++ PMBUS_HAVE_PIN) + -+#define MP2891_RAIL2_FUNC (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP | \ -+ PMBUS_HAVE_POUT | PMBUS_PHASE_VIRTUAL) ++#define MP2891_RAIL2_FUNC (PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_IIN | \ ++ PMBUS_HAVE_TEMP | PMBUS_HAVE_POUT) + +struct mp2891_data { + struct pmbus_driver_info info; + int vid_step[MP2891_PAGE_NUM]; ++ int vid_ref[MP2891_PAGE_NUM]; + int iout_scale[MP2891_PAGE_NUM]; +}; + @@ -295,26 +277,13 @@ index 000000000000..e9e82844ee2a + +static int mp2891_read_vout(struct i2c_client *client, int page, int phase, int reg) +{ -+ int ret; -+ + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + struct mp2891_data *data = to_mp2891_data(info); -+ -+ ret = pmbus_read_word_data(client, page, phase, reg); -+ -+ return ret < 0 ? ret : ret * data->vid_step[page] / 100; -+} -+ -+static int mp2891_read_iout(struct i2c_client *client, int page, int phase, int reg) -+{ + int ret; + -+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client); -+ struct mp2891_data *data = to_mp2891_data(info); -+ + ret = pmbus_read_word_data(client, page, phase, reg); + -+ return ret < 0 ? ret : ret * data->iout_scale[page]; ++ return ret < 0 ? ret : ret * data->vid_step[page] / 100; +} + +static int mp2891_read_byte_data(struct i2c_client *client, int page, int reg) @@ -341,17 +310,82 @@ index 000000000000..e9e82844ee2a + +static int mp2891_read_word_data(struct i2c_client *client, int page, int phase, int reg) +{ ++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client); ++ struct mp2891_data *data = to_mp2891_data(info); ++ int off, ret; ++ + switch (reg) { + case PMBUS_READ_VOUT: + return mp2891_read_vout(client, page, phase, reg); -+ case PMBUS_READ_IOUT: -+ return mp2891_read_iout(client, page, phase, reg); ++ case PMBUS_READ_VIN: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ if (ret <= 0) ++ return ret; ++ ++ /* ++ * READ_VIN register contains bits 15:11 set with the fixed value 11011b, bit 10 ++ * is set with 0. Bits 9:0 provides input voltage in linear11 format, scaled as ++ * 1/32V/LSB. ++ */ ++ return DIV_ROUND_CLOSEST(((ret & GENMASK(9, 0)) * 1000), MP2975_VIN_UNIT); + case PMBUS_OT_WARN_LIMIT: + case PMBUS_OT_FAULT_LIMIT: ++ return (pmbus_read_word_data(client, page, phase, reg) & GENMASK(7, 0)) - ++ MP2975_TEMP_LIMIT_OFFSET; ++ case PMBUS_VIN_OV_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ if (ret <= 0) ++ return ret; ++ return DIV_ROUND_CLOSEST(ret & GENMASK(7, 0), 8) * 1000; ++ case PMBUS_VOUT_UV_FAULT_LIMIT: ++ case PMBUS_VOUT_OV_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ if (ret <= 0) ++ return ret; ++ off = (reg == PMBUS_VOUT_UV_FAULT_LIMIT) ? MP2891_MFR_UVP_OFFSET_DEFAULT : ++ MP2891_MFR_OVP_OFFSET_DEFAULT; ++ off = MP2891_MFR_OVP_UVP_OFFSET_GET(ret, off); ++ return DIV_ROUND_CLOSEST(data->vid_ref[page] + off, 100); ++ case PMBUS_IOUT_UC_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return ret <= 0 ? ret : DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * ++ MP2975_IOUT_UC_LIMIT_SCALE, ++ MP2975_IOUT_UC_LIMIT_UNIT); ++ return ret; ++ case PMBUS_READ_PIN: ++ /* ++ * From some unknown reason the vendor decide to re-purpose command ++ * PMBUS_READ_DUTY_CYCLE (0x94) for reading input and output power. ++ */ ++ return pmbus_read_word_data(client, page, phase, MP2891_MFR_READ_PIN_EST); ++ case PMBUS_READ_POUT: ++ return pmbus_read_word_data(client, page, phase, reg); ++ case PMBUS_READ_IIN: ++ /* ++ * From some unknown reason the vendor decide to re-purpose command ++ * PMBUS_READ_FREQUENCY (0x95) for reading input current. ++ */ ++ return pmbus_read_word_data(client, page, phase, MP2891_MFR_READ_IIN_EST); ++ case PMBUS_IIN_OC_WARN_LIMIT: ++ /* Read only from page 0. */ ++ ret = pmbus_read_word_data(client, 0, phase, reg); ++ return ret <= 0 ? ret : DIV_ROUND_CLOSEST(ret, MP2975_IIN_OC_WARN_LIMIT_UNIT); ++ case PMBUS_PIN_OP_WARN_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return ret <= 0 ? ret : ret * MP2975_PIN_LIMIT_UNIT; ++ case PMBUS_IOUT_OC_WARN_LIMIT: ++ case PMBUS_IOUT_OC_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return ret <= 0 ? ret : DIV_ROUND_CLOSEST(ret * data->iout_scale[page], ++ MP2975_IOUT_OC_LIMIT_UNIT); + case PMBUS_UT_WARN_LIMIT: + case PMBUS_UT_FAULT_LIMIT: -+ case PMBUS_VOUT_OV_WARN_LIMIT: + case PMBUS_VIN_OV_WARN_LIMIT: ++ case PMBUS_VIN_UV_WARN_LIMIT: ++ case PMBUS_VOUT_OV_WARN_LIMIT: ++ case PMBUS_VOUT_UV_WARN_LIMIT: ++ case PMBUS_POUT_OP_WARN_LIMIT: ++ case PMBUS_IIN_OC_FAULT_LIMIT: + case PMBUS_POUT_MAX: + case PMBUS_POUT_OP_FAULT_LIMIT: + case PMBUS_MFR_VIN_MIN: @@ -365,10 +399,44 @@ index 000000000000..e9e82844ee2a + case PMBUS_MFR_MAX_TEMP_1: + return -ENXIO; + default: -+ return -EINVAL; ++ return -ENODATA; + } +} + ++static int mp2891_write_word_data(struct i2c_client *client, int page, int reg, u16 word) ++{ ++ switch (reg) { ++ case PMBUS_OT_FAULT_LIMIT: ++ case PMBUS_OT_WARN_LIMIT: ++ /* Drop unused bits 15:8. */ ++ word = clamp_val(word, 0, GENMASK(7, 0)); ++ break; ++ case PMBUS_IOUT_OC_WARN_LIMIT: ++ case PMBUS_POUT_OP_WARN_LIMIT: ++ case PMBUS_IIN_OC_WARN_LIMIT: ++ /* Drop unused bits 15:10. */ ++ word = clamp_val(word, 0, GENMASK(9, 0)); ++ break; ++ default: ++ return -ENODATA; ++ } ++ return pmbus_write_word_data(client, page, reg, word); ++} ++ ++static int ++mp2891_git_vid_volt_ref(struct i2c_client *client, struct mp2891_data *data, int page) ++{ ++ int ret; ++ ++ ret = i2c_smbus_read_word_data(client, PMBUS_VOUT_COMMAND); ++ if (ret < 0) ++ return ret; ++ ++ data->vid_ref[page] = (ret & GENMASK(10, 0)) * data->vid_step[page]; ++ ++ return 0; ++} ++ +static int mp2891_identify_vid(struct i2c_client *client, struct mp2891_data *data, u32 reg, + int page) +{ @@ -390,13 +458,10 @@ index 000000000000..e9e82844ee2a + */ + if ((ret & MP2891_DAC_2P5MV_MASK) >> MP2891_VID_STEP_POS) { + data->vid_step[page] = 250; -+ return 0; ++ return mp2891_git_vid_volt_ref(client, data, page); + } + + switch ((ret & MP2891_VID_STEP_MASK) >> MP2891_VID_STEP_POS) { -+ case 0: -+ data->vid_step[page] = 625; -+ break; + case 1: + data->vid_step[page] = 500; + break; @@ -404,11 +469,11 @@ index 000000000000..e9e82844ee2a + data->vid_step[page] = 200; + break; + default: -+ data->vid_step[page] = 100; ++ data->vid_step[page] = 250; + break; + } + -+ return 0; ++ return mp2891_git_vid_volt_ref(client, data, page); +} + +static int mp2891_identify_rails_vid(struct i2c_client *client, struct mp2891_data *data) @@ -484,25 +549,26 @@ index 000000000000..e9e82844ee2a + .pages = MP2891_PAGE_NUM, + .format[PSC_VOLTAGE_IN] = direct, + .format[PSC_VOLTAGE_OUT] = direct, -+ .format[PSC_CURRENT_OUT] = direct, ++ .format[PSC_CURRENT_OUT] = linear, + .format[PSC_TEMPERATURE] = direct, + .format[PSC_POWER] = linear, + .m[PSC_VOLTAGE_IN] = 1, + .m[PSC_VOLTAGE_OUT] = 1, -+ .m[PSC_CURRENT_OUT] = 32, ++ .m[PSC_CURRENT_OUT] = 1, + .m[PSC_TEMPERATURE] = 1, + .R[PSC_VOLTAGE_IN] = 3, + .R[PSC_VOLTAGE_OUT] = 3, -+ .R[PSC_CURRENT_OUT] = 0, ++ .R[PSC_CURRENT_OUT] = 1, + .R[PSC_TEMPERATURE] = 0, -+ .b[PSC_VOLTAGE_IN] = 0, -+ .b[PSC_VOLTAGE_OUT] = 0, -+ .b[PSC_CURRENT_OUT] = 0, -+ .b[PSC_TEMPERATURE] = 0, + .func[0] = MP2891_RAIL1_FUNC, + .func[1] = MP2891_RAIL2_FUNC, -+ .read_word_data = mp2891_read_word_data, + .read_byte_data = mp2891_read_byte_data, ++ .read_word_data = mp2891_read_word_data, ++ .write_word_data = mp2891_write_word_data, ++}; ++ ++static struct pmbus_platform_data mp2891_pdata = { ++ .flags = PMBUS_SKIP_STATUS_CHECK, +}; + +static int mp2891_probe(struct i2c_client *client) @@ -516,6 +582,7 @@ index 000000000000..e9e82844ee2a + if (!data) + return -ENOMEM; + ++ client->dev.platform_data = &mp2891_pdata; + memcpy(&data->info, &mp2891_info, sizeof(*info)); + info = &data->info; + diff --git a/patch/0050-leds-mlxreg-Skip-setting-LED-color-during-initializa.patch b/patch/0050-leds-mlxreg-Skip-setting-LED-color-during-initializa.patch index 3118617ea..aa3ac65e4 100644 --- a/patch/0050-leds-mlxreg-Skip-setting-LED-color-during-initializa.patch +++ b/patch/0050-leds-mlxreg-Skip-setting-LED-color-during-initializa.patch @@ -1,8 +1,8 @@ -From 519742b99a6a2d6b8d5797d70608fdc954d2871a Mon Sep 17 00:00:00 2001 +From 7d6423a976efbdc18b6df9b38169837a68ef46aa Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Wed, 7 Jul 2021 10:18:14 +0000 -Subject: [PATCH backport 6.1.42 55/85] leds: mlxreg: Skip setting LED color - during initialization +Subject: [PATCH v6.1 31/81] leds: mlxreg: Skip setting LED color during + initialization Hardware controls LED through CPLD device and LED control ownership passes to the software after it performs the first write operation for @@ -21,7 +21,7 @@ Reviewed-by: Michael Shych 1 file changed, 3 deletions(-) diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c -index 215132f67c07..c0caf810b6d0 100644 +index 23de154ade61..6ddbfceaceec 100644 --- a/drivers/leds/leds-mlxreg.c +++ b/drivers/leds/leds-mlxreg.c @@ -246,9 +246,6 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv) diff --git a/patch/0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch b/patch/0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch new file mode 100644 index 000000000..943780109 --- /dev/null +++ b/patch/0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch @@ -0,0 +1,74 @@ +From fe6caa3afd2525ee83f1b2ee13a1650c596f9e1c Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Sun, 13 Aug 2023 17:51:39 +0000 +Subject: [PATH backport v6.1 32/32] Documentation/ABI: Add new attribute for + mlxreg-io sysfs interfaces + +Link: https://www.spinics.net/lists/platform-driver-x86/msg39648.html + +Add documentation for the new attributes: +- CPLD versioning: "cpld5_pn", "cpld5_version", "cpld5_version_min". +- JTAG capability: "jtag_cap", indicating the available method of + CPLD/FPGA devices field update. +- System lid status: "lid_open". +- Reset caused by long press of power button: "reset_long_pwr_pb". + +Signed-off-by: Vadim Pasternak +Reviewed-by: Michael Shych +--- + .../ABI/stable/sysfs-driver-mlxreg-io | 42 +++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io +index 60953903d007..633be2bf2cd0 100644 +--- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io ++++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io +@@ -662,3 +662,45 @@ Description: This file shows the system reset cause due to AC power failure. + Value 1 in file means this is reset cause, 0 - otherwise. + + The file is read only. ++ ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld5_pn ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld5_version ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld5_version_min ++Date: August 2023 ++KernelVersion: 6.6 ++Contact: Vadim Pasternak ++Description: These files show with which CPLD part numbers, version and minor ++ versions have been burned the 5-th CPLD device equipped on a ++ system. ++ ++ The files are read only. ++ ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_cap ++Date: August 2023 ++KernelVersion: 6.6 ++Contact: Vadim Pasternak ++Description: This file indicates the available method of CPLD/FPGA devices ++ field update through the JTAG chain: ++ b00 - field update through LPC bus register memory space. ++ b01 - Reserved. ++ b10 - Reserved. ++ b11 - field update through CPU GPIOs bit-banging. ++ ++ The file is read only. ++ ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/lid_open ++Date: August 2023 ++KernelVersion: 6.6 ++Contact: Vadim Pasternak ++Description: 1 - indicates that system lid is opened, otherwise 0. ++ ++ The file is read only. ++ ++What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_long_pwr_pb ++Date: August 2023 ++KernelVersion: 6.6 ++Contact: Vadim Pasternak ++Description: This file if set 1 indicates that system has been reset by ++ long press of power button. ++ ++ The file is read only. +-- +2.20.1 + diff --git a/patch/0085-hwmon-mlxreg-fan-Separate-methods-of-fan-setting-com.patch b/patch/0085-hwmon-mlxreg-fan-Separate-methods-of-fan-setting-com.patch index dad93b6cf..88853ea87 100644 --- a/patch/0085-hwmon-mlxreg-fan-Separate-methods-of-fan-setting-com.patch +++ b/patch/0085-hwmon-mlxreg-fan-Separate-methods-of-fan-setting-com.patch @@ -1,8 +1,8 @@ -From 2ed90978c8b91ffe717c3e2164921a79dd757c1c Mon Sep 17 00:00:00 2001 +From 66c36c502d56010fa726af98ff63c9e895791c4d Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Fri, 1 Sep 2023 07:16:20 +0000 -Subject: [PATCH hwmon 1/1] hwmon: (mlxreg-fan) Separate methods of fan setting - coming from different subsystems +Subject: [PATCH v6.1 68/80] hwmon: (mlxreg-fan) Separate methods of fan + setting coming from different subsystems Distinct between fan speed setting request coming for hwmon and thermal subsystems. @@ -28,10 +28,10 @@ Signed-off-by: Vadim Pasternak 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c -index c515e1d2fe4e..01c1baa3d06d 100644 +index bddc927b207c..102a517940f3 100644 --- a/drivers/hwmon/mlxreg-fan.c +++ b/drivers/hwmon/mlxreg-fan.c -@@ -113,8 +113,8 @@ struct mlxreg_fan { +@@ -115,8 +115,8 @@ struct mlxreg_fan { int divider; }; @@ -42,7 +42,7 @@ index c515e1d2fe4e..01c1baa3d06d 100644 static int mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, -@@ -224,8 +224,9 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, +@@ -228,8 +228,9 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, * last thermal state. */ if (pwm->last_hwmon_state >= pwm->last_thermal_state) @@ -54,7 +54,7 @@ index c515e1d2fe4e..01c1baa3d06d 100644 return 0; } return regmap_write(fan->regmap, pwm->reg, val); -@@ -357,9 +358,8 @@ static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev, +@@ -361,9 +362,8 @@ static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev, return 0; } @@ -66,7 +66,7 @@ index c515e1d2fe4e..01c1baa3d06d 100644 { struct mlxreg_fan_pwm *pwm = cdev->devdata; struct mlxreg_fan *fan = pwm->fan; -@@ -369,7 +369,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, +@@ -373,7 +373,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, return -EINVAL; /* Save thermal state. */ @@ -76,7 +76,7 @@ index c515e1d2fe4e..01c1baa3d06d 100644 state = max_t(unsigned long, state, pwm->last_hwmon_state); err = regmap_write(fan->regmap, pwm->reg, -@@ -381,6 +382,13 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, +@@ -385,6 +386,13 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev, return 0; } diff --git a/patch/0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch b/patch/0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch new file mode 100644 index 000000000..0b5d4a713 --- /dev/null +++ b/patch/0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch @@ -0,0 +1,60 @@ +From 923c91d57aa35fc063001fea28ba884a1b6ba224 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Thu, 24 Aug 2023 13:20:54 +0000 +Subject: [PATCH v6.1 31/50] platform_data/mlxreg: Add capability bit and mask + fields + +Some 'capability' registers can be shared between different resources. +Add new fields 'capability_bit' and 'capability_mask' to structs +'mlxreg_core_data' and and 'mlxreg_core_item' for getting only relevant +capability bits. + +Signed-off-by: Vadim Pasternak +Reviewed-by: Felix Radensky +--- + include/linux/platform_data/mlxreg.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h +index 0b9f81a6f753..d9f679752226 100644 +--- a/include/linux/platform_data/mlxreg.h ++++ b/include/linux/platform_data/mlxreg.h +@@ -118,6 +118,8 @@ struct mlxreg_hotplug_device { + * @mask: attribute access mask; + * @bit: attribute effective bit; + * @capability: attribute capability register; ++ * @capability_bit: started bit in attribute capability register; ++ * @capability_mask: mask in attribute capability register; + * @reg_prsnt: attribute presence register; + * @reg_sync: attribute synch register; + * @reg_pwr: attribute power register; +@@ -138,6 +140,8 @@ struct mlxreg_core_data { + u32 mask; + u32 bit; + u32 capability; ++ u32 capability_bit; ++ u32 capability_mask; + u32 reg_prsnt; + u32 reg_sync; + u32 reg_pwr; +@@ -162,6 +166,8 @@ struct mlxreg_core_data { + * @reg: group interrupt status register; + * @mask: group interrupt mask; + * @capability: group capability register; ++ * @capability_bit: started bit in attribute capability register; ++ * @capability_mask: mask in attribute capability register; + * @cache: last status value for elements fro the same group; + * @count: number of available elements in the group; + * @ind: element's index inside the group; +@@ -175,6 +181,8 @@ struct mlxreg_core_item { + u32 reg; + u32 mask; + u32 capability; ++ u32 capability_bit; ++ u32 capability_mask; + u32 cache; + u8 count; + u8 ind; +-- +2.20.1 + diff --git a/patch/0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch b/patch/0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch new file mode 100644 index 000000000..33dbe7426 --- /dev/null +++ b/patch/0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch @@ -0,0 +1,87 @@ +From 8ef21e6d6273636a4bb6f9c4f704c3aaa5d4f736 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Thu, 24 Aug 2023 11:47:54 +0000 +Subject: [PATCH v6.1 2/9] platform/mellanox: mlxreg-hotplug: Add support for + new flavor of capability registers + +Hotplug platform data is common across the various systems, while +hotplug driver should be able to configure only the instances relevant +to specific system. + +For example, platform hoptplug data might contain descriptions for fan1, +fan2, ..., fan{n}, while some systems equipped with all 'n' fans, +others with less. +Same for power units, power controllers, ASICs and so on. + +For detection of the real number of equipped devices capability +registers are used. +These registers used to indicate presence of hotplug devices through +the bitmap. + +For some new big modular systems, these registers will provide presence +by counters. + +Use slot parameter to determine whether capability register contains +bitmask or counter. + +Some 'capability' registers can be shared between different resources. +Use fields 'capability_bit' and 'capability_mask' for getting only +relevant capability bits. + +Signed-off-by: Vadim Pasternak +Reviewed-by: Felix Radensky +--- + drivers/platform/mellanox/mlxreg-hotplug.c | 23 ++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c +index c5abedd3514d..3737af0d3e43 100644 +--- a/drivers/platform/mellanox/mlxreg-hotplug.c ++++ b/drivers/platform/mellanox/mlxreg-hotplug.c +@@ -275,6 +275,13 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv) + if (ret) + return ret; + ++ if (!regval) ++ continue; ++ ++ /* Remove non-relevant bits. */ ++ if (item->capability_mask) ++ regval = rol32(regval & item->capability_mask, ++ item->capability_bit); + item->mask = GENMASK((regval & item->mask) - 1, 0); + } + +@@ -295,7 +302,19 @@ static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv) + if (ret) + return ret; + +- if (!(regval & data->bit)) { ++ /* ++ * In case slot field is provided, capability ++ * register contains counter, otherwise bitmask. ++ * Skip non-relevant entries if slot set and ++ * exceeds counter. Othewise validate entry by ++ * matching bitmask. ++ */ ++ if (data->capability_mask) ++ regval = rol32(regval & data->capability_mask, ++ data->capability_bit); ++ if (data->slot > regval) { ++ break; ++ } else if (!(regval & data->bit) && !data->slot) { + data++; + continue; + } +@@ -626,7 +645,7 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv) + if (ret) + goto out; + +- if (!(regval & data->bit)) ++ if (!(regval & data->bit) && !data->slot) + item->mask &= ~BIT(j); + } + } +-- +2.20.1 + diff --git a/patch/0089-platform-mellanox-mlx-platform-Change-register-name.patch b/patch/0089-platform-mellanox-mlx-platform-Change-register-name.patch new file mode 100644 index 000000000..77ae17d7f --- /dev/null +++ b/patch/0089-platform-mellanox-mlx-platform-Change-register-name.patch @@ -0,0 +1,57 @@ +From deff38f0bc8aa9518a78474b2b1ab28f85f75f58 Mon Sep 17 00:00:00 2001 +From: Felix Radensky +Date: Thu, 21 Sep 2023 05:53:11 +0000 +Subject: [PATCH v6.1 1/8] platform: mellanox: mlx-platform: Change register + name + +Register 0xd9 was repurposed on new systems. Change its name +to correctly reflect the new functionality. + +Signed-off-by: Felix Radensky +Reviewed-by: Vadim Pasternak +--- + drivers/platform/mellanox/mlx-platform.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c +index 46958810e972..c1ebd4f85158 100644 +--- a/drivers/platform/mellanox/mlx-platform.c ++++ b/drivers/platform/mellanox/mlx-platform.c +@@ -146,7 +146,7 @@ + #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_DBG_CTRL_OFFSET 0xd9 ++#define MLXPLAT_CPLD_LPC_REG_CPLD6_MVER_OFFSET 0xd9 + #define MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET 0xdb + #define MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET 0xda + #define MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET 0xdc +@@ -5102,7 +5102,6 @@ static bool mlxplat_mlxcpld_writeable_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_DBG_CTRL_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET: +@@ -5239,7 +5238,7 @@ 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_DBG_CTRL_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_MVER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET: +@@ -5397,7 +5396,7 @@ 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_DBG_CTRL_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_MVER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET: + case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET: +-- +2.20.1 + diff --git a/patch/0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch b/patch/0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch new file mode 100644 index 000000000..36e74128d --- /dev/null +++ b/patch/0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch @@ -0,0 +1,1402 @@ +From 75f034c8cfba7ce9f79e72e06f328aa39103fcff Mon Sep 17 00:00:00 2001 +From: Felix Radensky +Date: Mon, 4 Sep 2023 18:28:37 +0000 +Subject: [PATCH v6.1 2/8] platform: mellanox: mlx-platform: Add support for + new XDR systems + +Add support for QM3400 and QM3000, Nvidia XDR switches. + +QM3400 is a 57.6Tbps switch based on Nvidia Quantum-3 ASIC. +It provides up-to 800Gbps full bidirectional bandwidth per port. +The system supports 36 OSFP cages and fits into standard 2U racks. + +QM3400 Features: + - 36 OSFP ports supporting 2.5Gbps - 800Gbps speeds. + - Air-cooled with 4 + 1 redundant fan units. + - 2 + 2 redundant 2000W PSUs. + - System management board based on Intel Coffee Lake CPU + with secure-boot support. + +QM3000 is a 115.2Tbps switch based on Nvidia Quantum-3 ASIC. +It provides up-to 800Gbps full bidirectional bandwidth per port. +The system supports 72 OSFP cages and fits into standard 4U racks. + +QM3000 Features: + - 72 OSFP ports or 144 aggregated XDR ports supporting 800Gbps speeds. + - Air-cooled with 9 + 1 redundant fan units. + - 4 + 4 redundant 2000W PSUs. + - System management board based on Intel Coffee Lake CPU + with secure-boot support. + +Signed-off-by: Felix Radensky +Reviewed-by: Vadim Pasternak +--- + drivers/platform/mellanox/mlx-platform.c | 1068 +++++++++++++++++++++- + 1 file changed, 1049 insertions(+), 19 deletions(-) + +diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c +index c1ebd4f85158..cafa4f762672 100644 +--- a/drivers/platform/mellanox/mlx-platform.c ++++ b/drivers/platform/mellanox/mlx-platform.c +@@ -50,6 +50,7 @@ + #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24 + #define MLXPLAT_CPLD_LPC_REG_LED6_OFFSET 0x25 + #define MLXPLAT_CPLD_LPC_REG_LED7_OFFSET 0x26 ++#define MLXPLAT_CPLD_LPC_REG_LED8_OFFSET 0x27 + #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION 0x2a + #define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET 0x2b + #define MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET 0x2d +@@ -95,9 +96,21 @@ + #define MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET 0x70 + #define MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET 0x71 + #define MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET 0x72 ++#define MLXPLAT_CPLD_LPC_REG_CPLD6_VER_OFFSET 0x7c ++#define MLXPLAT_CPLD_LPC_REG_CPLD6_PN_OFFSET 0x7d ++#define MLXPLAT_CPLD_LPC_REG_CPLD6_PN1_OFFSET 0x7e ++#define MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET 0x82 ++#define MLXPLAT_CPLD_LPC_REG_ASIC3_EVENT_OFFSET 0x83 ++#define MLXPLAT_CPLD_LPC_REG_ASIC3_MASK_OFFSET 0x84 ++#define MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET 0x85 ++#define MLXPLAT_CPLD_LPC_REG_ASIC4_EVENT_OFFSET 0x86 ++#define MLXPLAT_CPLD_LPC_REG_ASIC4_MASK_OFFSET 0x87 + #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88 + #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89 + #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a ++#define MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET 0x8b ++#define MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET 0x8c ++#define MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET 0x8d + #define MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET 0x8e + #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET 0x8f + #define MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET 0x90 +@@ -129,10 +142,15 @@ + #define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET 0xaa + #define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET 0xab + #define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON 0xb2 ++#define MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET 0xb4 ++#define MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET 0xb5 + #define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0xb6 + #define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0xb7 + #define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0xb8 + #define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0xb9 ++#define MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET 0xba ++#define MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET 0xbb ++#define MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET 0xc1 + #define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET 0xc2 + #define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT 0xc3 + #define MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET 0xc4 +@@ -183,6 +201,8 @@ + #define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET 0xfb + #define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET 0xfc + #define MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET 0xfd ++#define MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET 0xfe ++#define MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET 0xff + #define MLXPLAT_CPLD_LPC_REG_EXT_MIN_OFFSET 0x100 + #define MLXPLAT_CPLD_LPC_REG_EXT_MID_OFFSET 0x195 + #define MLXPLAT_CPLD_LPC_REG_EXT_MAX_OFFSET 0x1ff +@@ -235,19 +255,30 @@ + #define MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2 BIT(2) + #define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT GENMASK(5, 4) + #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C BIT(6) ++#define MLXPLAT_CPLD_LOW_AGGR_MASK_MULTI_ASICS GENMASK(3, 0) ++#define MLXPLAT_CPLD_LOW_AGGR_MASK_FRU BIT(7) + #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0) + #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0) + #define MLXPLAT_CPLD_PSU_EXT_MASK GENMASK(3, 0) + #define MLXPLAT_CPLD_PWR_EXT_MASK GENMASK(3, 0) ++#define MLXPLAT_CPLD_PSU_XDR_MASK GENMASK(7, 0) ++#define MLXPLAT_CPLD_PWR_XDR_MASK GENMASK(7, 0) + #define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0) + #define MLXPLAT_CPLD_ASIC_MASK GENMASK(1, 0) ++#define MLXPLAT_CPLD_ASIC_XDR_MASK GENMASK(3, 0) + #define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(6, 0) ++#define MLXPLAT_CPLD_FAN_QMB8700_MASK GENMASK(5, 0) ++#define MLXPLAT_CPLD_FAN_XDR_MASK GENMASK(7, 0) ++#define MLXPLAT_CPLD_FAN_XDR_EXT_MASK GENMASK(1, 0) + #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4) + #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0) + #define MLXPLAT_CPLD_VOLTREG_UPD_MASK GENMASK(5, 4) + #define MLXPLAT_CPLD_GWP_MASK GENMASK(0, 0) + #define MLXPLAT_CPLD_EROT_MASK GENMASK(1, 0) + #define MLXPLAT_CPLD_FU_CAP_MASK GENMASK(1, 0) ++#define MLXPLAT_CPLD_PSU_CAP_MASK GENMASK(3, 0) ++#define MLXPLAT_CPLD_FAN_CAP_MASK GENMASK(7, 0) ++#define MLXPLAT_CPLD_ASIC_CAP_MASK GENMASK(7, 0) + #define MLXPLAT_CPLD_PWR_BUTTON_MASK BIT(0) + #define MLXPLAT_CPLD_LATCH_RST_MASK BIT(6) + #define MLXPLAT_CPLD_THERMAL1_PDB_MASK BIT(3) +@@ -294,6 +325,7 @@ + #define MLXPLAT_CPLD_CH4_ETH_MODULAR 51 + #define MLXPLAT_CPLD_CH2_RACK_SWITCH 18 + #define MLXPLAT_CPLD_CH2_NG800 34 ++#define MLXPLAT_CPLD_CH2_XDR 66 + + /* Number of LPC attached MUX platform devices */ + #define MLXPLAT_CPLD_LPC_MUX_DEVS 4 +@@ -302,6 +334,7 @@ + #define MLXPLAT_CPLD_NR_NONE -1 + #define MLXPLAT_CPLD_PSU_DEFAULT_NR 10 + #define MLXPLAT_CPLD_PSU_MSNXXXX_NR 4 ++#define MLXPLAT_CPLD_PSU_XDR_NR 3 + #define MLXPLAT_CPLD_FAN1_DEFAULT_NR 11 + #define MLXPLAT_CPLD_FAN2_DEFAULT_NR 12 + #define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13 +@@ -644,6 +677,38 @@ static struct i2c_mux_reg_platform_data mlxplat_ng800_mux_data[] = { + + }; + ++/* Platform channels for XDR system family */ ++static const int mlxplat_xdr_channels[] = { ++ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ++ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, ++ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 ++}; ++ ++/* Platform XDR mux data */ ++static struct i2c_mux_reg_platform_data mlxplat_xdr_mux_data[] = { ++ { ++ .parent = 1, ++ .base_nr = MLXPLAT_CPLD_CH1, ++ .write_only = 1, ++ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1, ++ .reg_size = 1, ++ .idle_in_use = 1, ++ .values = mlxplat_xdr_channels, ++ .n_values = ARRAY_SIZE(mlxplat_xdr_channels), ++ }, ++ { ++ .parent = 1, ++ .base_nr = MLXPLAT_CPLD_CH2_XDR, ++ .write_only = 1, ++ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2, ++ .reg_size = 1, ++ .idle_in_use = 1, ++ .values = mlxplat_msn21xx_channels, ++ .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels), ++ }, ++}; ++ + /* Platform hotplug devices */ + static struct i2c_board_info mlxplat_mlxcpld_pwr[] = { + { +@@ -663,6 +728,21 @@ static struct i2c_board_info mlxplat_mlxcpld_ext_pwr[] = { + }, + }; + ++static struct i2c_board_info mlxplat_mlxcpld_xdr_pwr[] = { ++ { ++ I2C_BOARD_INFO("dps460", 0x5d), ++ }, ++ { ++ I2C_BOARD_INFO("dps460", 0x5c), ++ }, ++ { ++ I2C_BOARD_INFO("dps460", 0x5e), ++ }, ++ { ++ I2C_BOARD_INFO("dps460", 0x5f), ++ }, ++}; ++ + static struct i2c_board_info mlxplat_mlxcpld_pwr_ng800[] = { + { + I2C_BOARD_INFO("dps460", 0x59), +@@ -1432,6 +1512,441 @@ static struct mlxreg_core_item mlxplat_mlxcpld_ng800_items[] = { + }, + }; + ++/* Platform hotplug XDR system family data */ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_psu_items_data[] = { ++ { ++ .label = "psu1", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(0), ++ .slot = 1, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu2", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(1), ++ .slot = 2, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu3", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(2), ++ .slot = 3, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu4", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(3), ++ .slot = 4, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu5", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(4), ++ .slot = 5, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu6", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(5), ++ .slot = 6, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu7", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(6), ++ .slot = 7, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "psu8", ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = BIT(7), ++ .slot = 8, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_pwr_items_data[] = { ++ { ++ .label = "pwr1", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(0), ++ .slot = 1, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ }, ++ { ++ .label = "pwr2", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(1), ++ .slot = 2, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ }, ++ { ++ .label = "pwr3", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(2), ++ .slot = 3, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[0], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ }, ++ { ++ .label = "pwr4", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(3), ++ .slot = 4, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[1], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ }, ++ { ++ .label = "pwr5", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(4), ++ .slot = 5, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[0], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR, ++ }, ++ { ++ .label = "pwr6", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(5), ++ .slot = 6, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[1], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR, ++ }, ++ { ++ .label = "pwr7", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(6), ++ .slot = 7, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[2], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR, ++ }, ++ { ++ .label = "pwr8", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = BIT(7), ++ .slot = 8, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .hpdev.brdinfo = &mlxplat_mlxcpld_xdr_pwr[3], ++ .hpdev.nr = MLXPLAT_CPLD_PSU_XDR_NR, ++ }, ++}; ++ ++static int mlxplat_mlxcpld_xdr_pwr_nr_fixup[] = { ++ MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ MLXPLAT_CPLD_PSU_XDR_NR, ++ MLXPLAT_CPLD_PSU_XDR_NR, ++ MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ MLXPLAT_CPLD_PSU_MSNXXXX_NR, ++ MLXPLAT_CPLD_PSU_XDR_NR, ++ MLXPLAT_CPLD_PSU_XDR_NR, ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_items_data[] = { ++ { ++ .label = "fan1", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(0), ++ .slot = 1, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(0), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan2", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(1), ++ .slot = 2, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(1), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan3", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(2), ++ .slot = 3, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(2), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan4", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(3), ++ .slot = 4, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(3), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan5", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(4), ++ .slot = 5, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(4), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan6", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(5), ++ .slot = 6, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(5), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan7", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(6), ++ .slot = 7, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(6), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan8", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = BIT(7), ++ .slot = 8, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(7), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_ext_fan_items_data[] = { ++ { ++ .label = "fan9", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ .mask = BIT(0), ++ .slot = 9, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(0), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan10", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ .mask = BIT(1), ++ .slot = 10, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(1), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan11", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ .mask = BIT(2), ++ .slot = 11, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(2), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++ { ++ .label = "fan12", ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ .mask = BIT(3), ++ .slot = 12, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .bit = BIT(3), ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ }, ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic1_items_data[] = { ++ { ++ .label = "asic1", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .slot = 1, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ } ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic2_items_data[] = { ++ { ++ .label = "asic2", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .slot = 2, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ } ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic3_items_data[] = { ++ { ++ .label = "asic3", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .slot = 3, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ } ++}; ++ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_asic4_items_data[] = { ++ { ++ .label = "asic4", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .slot = 4, ++ .hpdev.nr = MLXPLAT_CPLD_NR_NONE, ++ } ++}; ++ ++static struct mlxreg_core_item mlxplat_mlxcpld_xdr_items[] = { ++ { ++ .data = mlxplat_mlxcpld_xdr_psu_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, ++ .mask = MLXPLAT_CPLD_PSU_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_psu_items_data), ++ .inversed = 1, ++ .health = false, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_pwr_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, ++ .mask = MLXPLAT_CPLD_PWR_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_PSU_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_pwr_items_data), ++ .inversed = 0, ++ .health = false, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_fan_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ .mask = MLXPLAT_CPLD_FAN_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_items_data), ++ .inversed = 1, ++ .health = false, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_ext_fan_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ .mask = MLXPLAT_CPLD_FAN_XDR_EXT_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_FAN_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_ext_fan_items_data), ++ .inversed = 1, ++ .health = false, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_asic1_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic1_items_data), ++ .inversed = 0, ++ .health = true, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_asic2_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic2_items_data), ++ .inversed = 0, ++ .health = true, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_asic3_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic3_items_data), ++ .inversed = 0, ++ .health = true, ++ }, ++ { ++ .data = mlxplat_mlxcpld_xdr_asic4_items_data, ++ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_XDR_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET, ++ .capability_mask = MLXPLAT_CPLD_ASIC_CAP_MASK, ++ .count = ARRAY_SIZE(mlxplat_mlxcpld_xdr_asic4_items_data), ++ .inversed = 0, ++ .health = true, ++ }, ++}; ++ + static + struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = { + .items = mlxplat_mlxcpld_ext_items, +@@ -1452,6 +1967,16 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_data = { + .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2, + }; + ++static ++struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_xdr_data = { ++ .items = mlxplat_mlxcpld_xdr_items, ++ .counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_items), ++ .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, ++ .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX, ++ .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, ++ .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_FRU | MLXPLAT_CPLD_LOW_AGGR_MASK_MULTI_ASICS, ++}; ++ + static struct mlxreg_core_data mlxplat_mlxcpld_modular_pwr_items_data[] = { + { + .label = "pwr1", +@@ -3159,42 +3684,216 @@ static struct mlxreg_core_data mlxplat_mlxcpld_l1_switch_led_data[] = { + .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, + .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(3), ++ .bit = BIT(3), ++ }, ++ { ++ .label = "fan4:orange", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .bit = BIT(3), ++ }, ++ { ++ .label = "fan5:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .bit = BIT(4), ++ }, ++ { ++ .label = "fan5:orange", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .bit = BIT(4), ++ }, ++ { ++ .label = "fan6:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .bit = BIT(5), ++ }, ++ { ++ .label = "fan6:orange", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .bit = BIT(5), ++ }, ++ { ++ .label = "uid:blue", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ }, ++}; ++ ++static struct mlxreg_core_platform_data mlxplat_l1_switch_led_data = { ++ .data = mlxplat_mlxcpld_l1_switch_led_data, ++ .counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_led_data), ++}; ++ ++/* Platform led data for XDR systems */ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_led_data[] = { ++ { ++ .label = "status:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ }, ++ { ++ .label = "status:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK ++ }, ++ { ++ .label = "psu:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ }, ++ { ++ .label = "psu:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ }, ++ { ++ .label = "fan1:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 1, ++ }, ++ { ++ .label = "fan1:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 1, ++ }, ++ { ++ .label = "fan2:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 2, ++ }, ++ { ++ .label = "fan2:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 2, ++ }, ++ { ++ .label = "fan3:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 3, ++ }, ++ { ++ .label = "fan3:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 3, ++ }, ++ { ++ .label = "fan4:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 4, ++ }, ++ { ++ .label = "fan4:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 4, ++ }, ++ { ++ .label = "fan5:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 5, ++ }, ++ { ++ .label = "fan5:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 5, ++ }, ++ { ++ .label = "fan6:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 6, ++ }, ++ { ++ .label = "fan6:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 6, ++ }, ++ { ++ .label = "fan7:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 7, + }, + { +- .label = "fan4:orange", +- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, ++ .label = "fan7:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET, + .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(3), ++ .slot = 7, + }, + { +- .label = "fan5:green", +- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .label = "fan8:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET, + .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(4), ++ .slot = 8, + }, + { +- .label = "fan5:orange", +- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .label = "fan8:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET, + .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(4), ++ .slot = 8, + }, + { +- .label = "fan6:green", +- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .label = "fan9:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET, + .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(5), ++ .slot = 9, + }, + { +- .label = "fan6:orange", +- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, ++ .label = "fan9:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET, + .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, +- .bit = BIT(5), ++ .slot = 9, ++ }, ++ { ++ .label = "fan10:green", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 10, ++ }, ++ { ++ .label = "fan10:amber", ++ .reg = MLXPLAT_CPLD_LPC_REG_LED8_OFFSET, ++ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .slot = 10, + }, + { + .label = "uid:blue", +@@ -3203,9 +3902,9 @@ static struct mlxreg_core_data mlxplat_mlxcpld_l1_switch_led_data[] = { + }, + }; + +-static struct mlxreg_core_platform_data mlxplat_l1_switch_led_data = { +- .data = mlxplat_mlxcpld_l1_switch_led_data, +- .counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_led_data), ++static struct mlxreg_core_platform_data mlxplat_xdr_led_data = { ++ .data = mlxplat_mlxcpld_xdr_led_data, ++ .counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_led_data), + }; + + /* Platform register access default */ +@@ -3504,6 +4203,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .bit = GENMASK(7, 0), + .mode = 0444, + }, ++ { ++ .label = "cpld6_version", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD6_VER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, + { + .label = "cpld1_pn", + .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET, +@@ -3539,6 +4244,13 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .mode = 0444, + .regnum = 2, + }, ++ { ++ .label = "cpld6_pn", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD6_PN_OFFSET, ++ .bit = GENMASK(15, 0), ++ .mode = 0444, ++ .regnum = 2, ++ }, + { + .label = "cpld1_version_min", + .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET, +@@ -3569,6 +4281,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .bit = GENMASK(7, 0), + .mode = 0444, + }, ++ { ++ .label = "cpld6_version_min", ++ .reg = MLXPLAT_CPLD_LPC_REG_CPLD6_MVER_OFFSET, ++ .bit = GENMASK(7, 0), ++ .mode = 0444, ++ }, + { + .label = "asic_reset", + .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET, +@@ -3758,6 +4476,43 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .mask = GENMASK(7, 0) & ~BIT(1), + .mode = 0200, + }, ++ { ++ .label = "psu3_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(4), ++ .mode = 0200, ++ }, ++ { ++ .label = "psu4_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(7), ++ .mode = 0200, ++ }, ++ { ++ .label = "psu5_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(0), ++ .mode = 0200, ++ }, ++ ++ { ++ .label = "psu6_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(1), ++ .mode = 0200, ++ }, ++ { ++ .label = "psu7_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(2), ++ .mode = 0200, ++ }, ++ { ++ .label = "psu8_on", ++ .reg = MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, ++ .mask = GENMASK(7, 0) & ~BIT(3), ++ .mode = 0200, ++ }, + { + .label = "pwr_cycle", + .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, +@@ -3833,6 +4588,20 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { + .bit = 1, + .mode = 0444, + }, ++ { ++ .label = "asic3_health", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .bit = 1, ++ .mode = 0444, ++ }, ++ { ++ .label = "asic4_health", ++ .reg = MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET, ++ .mask = MLXPLAT_CPLD_ASIC_MASK, ++ .bit = 1, ++ .mode = 0444, ++ }, + { + .label = "fan_dir", + .reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION, +@@ -4803,6 +5572,185 @@ static struct mlxreg_core_platform_data mlxplat_default_fan_data = { + .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, + }; + ++/* XDR platform fan data */ ++static struct mlxreg_core_data mlxplat_mlxcpld_xdr_fan_data[] = { ++ { ++ .label = "pwm1", ++ .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET, ++ }, ++ { ++ .label = "tacho1", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 1, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho2", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 2, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho3", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 3, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho4", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 4, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho5", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 5, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho6", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 6, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho7", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 7, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho8", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 8, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho9", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 9, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho10", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 10, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho11", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 11, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho12", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 12, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho13", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 13, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho14", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 14, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho15", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 15, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho16", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 16, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, ++ }, ++ { ++ .label = "tacho17", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 17, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ }, ++ { ++ .label = "tacho18", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 18, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ }, ++ { ++ .label = "tacho19", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 19, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ }, ++ { ++ .label = "tacho20", ++ .reg = MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET, ++ .mask = GENMASK(7, 0), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, ++ .slot = 20, ++ .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET, ++ }, ++ { ++ .label = "conf", ++ .capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET, ++ }, ++}; ++ ++static struct mlxreg_core_platform_data mlxplat_xdr_fan_data = { ++ .data = mlxplat_mlxcpld_xdr_fan_data, ++ .counter = ARRAY_SIZE(mlxplat_mlxcpld_xdr_fan_data), ++ .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, ++ .version = 1, ++}; ++ + /* Watchdog type1: hardware implementation version1 + * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems). + */ +@@ -5035,6 +5983,7 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET: + case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET: + case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET: + case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: +@@ -5062,12 +6011,18 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET: +@@ -5125,6 +6080,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD1_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET: +@@ -5135,6 +6091,8 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: +@@ -5147,6 +6105,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION: + case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET: + case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET: +@@ -5184,6 +6143,12 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: +@@ -5193,6 +6158,9 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET: +@@ -5266,6 +6234,13 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET: +@@ -5291,6 +6266,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_VER_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD1_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET: +@@ -5301,6 +6277,8 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_PN_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_CPLD6_PN1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET: + case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: +@@ -5313,6 +6291,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET: + case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_LED8_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION: + case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET: + case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET: +@@ -5348,6 +6327,12 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_HEALTH_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC3_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_HEALTH_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC4_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: +@@ -5357,6 +6342,9 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_EVENT_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_FAN2_MASK_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET: + case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET: +@@ -5424,6 +6412,13 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) + case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET: + case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO15_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO16_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO17_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO18_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO19_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_TACHO20_OFFSET: ++ case MLXPLAT_CPLD_LPC_REG_ASIC_CAP_OFFSET: + case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET: + case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET: +@@ -6116,6 +7111,35 @@ static int __init mlxplat_dmi_bf3_comex_default_matched(const struct dmi_system_ + return 1; + } + ++static int __init mlxplat_dmi_xdr_matched(const struct dmi_system_id *dmi) ++{ ++ int i; ++ const char *sku; ++ ++ sku = dmi_get_system_info(DMI_PRODUCT_SKU); ++ if (!strcmp(sku, "HI158")) { ++ for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_xdr_pwr_items_data); i++) ++ mlxplat_mlxcpld_xdr_pwr_items_data[i].hpdev.nr = ++ mlxplat_mlxcpld_xdr_pwr_nr_fixup[i]; ++ } ++ ++ mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; ++ mlxplat_mux_num = ARRAY_SIZE(mlxplat_xdr_mux_data); ++ mlxplat_mux_data = mlxplat_xdr_mux_data; ++ mlxplat_hotplug = &mlxplat_mlxcpld_xdr_data; ++ mlxplat_hotplug->deferred_nr = ++ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; ++ mlxplat_led = &mlxplat_xdr_led_data; ++ mlxplat_regs_io = &mlxplat_default_ng_regs_io_data; ++ mlxplat_fan = &mlxplat_xdr_fan_data; ++ for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++) ++ mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i]; ++ mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data; ++ mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400; ++ ++ return mlxplat_register_platform_device(); ++} ++ + static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { + { + .callback = mlxplat_dmi_default_wc_matched, +@@ -6216,6 +7240,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { + DMI_MATCH(DMI_BOARD_NAME, "VMOD0017"), + }, + }, ++ { ++ .callback = mlxplat_dmi_xdr_matched, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "VMOD0018"), ++ }, ++ }, + { + .callback = mlxplat_dmi_msn274x_matched, + .matches = { +-- +2.20.1 + diff --git a/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch b/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch new file mode 100644 index 000000000..8f08753bb --- /dev/null +++ b/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch @@ -0,0 +1,457 @@ +From ad3bc878f59106091171e2870b7613b74e021691 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Thu, 4 Jan 2024 09:12:29 +0000 +Subject: [PATCH v6.1 9/9] hwmon: (pmbus) Add support for MPS Multi-phase + mp2855 controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add support for MP2855 device, which is a dual-loop, digital, +multi-phase controller that provides power for the core of the +AMD SVI2 2.0 platform. + +Device configurations and fault parameters can be configured or +monitored via the PMBus interface. + +The device: +- Can work with MPS’s Intelli-PhaseTM products +- Can be configured with up to 9-phase operation for rail 1 and up + to 4-phase operation for rail 2. +- Provides an on-chip non-volatile memory (NVM) to store and restore + device configurations. +- Can monitor and report the output current (IOUT) through the CS + output from Intelli-PhaseTM products. + +The device is available in a TQFN-40 (5mmx5mm) package. + +Signed-off-by: Vadim Pasternak +--- + drivers/hwmon/pmbus/Kconfig | 10 + + drivers/hwmon/pmbus/Makefile | 1 + + drivers/hwmon/pmbus/mp2855.c | 380 +++++++++++++++++++++++++++++++++++ + 3 files changed, 391 insertions(+) + create mode 100644 drivers/hwmon/pmbus/mp2855.c + +diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig +index 77d67344cee4..f173c4195d86 100644 +--- a/drivers/hwmon/pmbus/Kconfig ++++ b/drivers/hwmon/pmbus/Kconfig +@@ -290,6 +290,16 @@ config SENSORS_MAX8688 + This driver can also be built as a module. If so, the module will + be called max8688. + ++config SENSORS_MP2855 ++ tristate "MPS MP2855" ++ help ++ If you say yes here you get hardware monitoring support for MPS ++ MP2855 Daula-Loop, Digital, Multi-Phase Controller with PMBus ++ interface for AMD SVI2 2.0 platform. ++ ++ This driver can also be built as a module. If so, the module will ++ be called mp2855. ++ + config SENSORS_MP2888 + tristate "MPS MP2888" + help +diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile +index 8e767d7b8c5b..24b38e451bc7 100644 +--- a/drivers/hwmon/pmbus/Makefile ++++ b/drivers/hwmon/pmbus/Makefile +@@ -31,6 +31,7 @@ obj-$(CONFIG_SENSORS_MAX20751) += max20751.o + obj-$(CONFIG_SENSORS_MAX31785) += max31785.o + obj-$(CONFIG_SENSORS_MAX34440) += max34440.o + obj-$(CONFIG_SENSORS_MAX8688) += max8688.o ++obj-$(CONFIG_SENSORS_MP2855) += mp2855.o + obj-$(CONFIG_SENSORS_MP2888) += mp2888.o + obj-$(CONFIG_SENSORS_MP2891) += mp2891.o + obj-$(CONFIG_SENSORS_MP2975) += mp2975.o +diff --git a/drivers/hwmon/pmbus/mp2855.c b/drivers/hwmon/pmbus/mp2855.c +new file mode 100644 +index 000000000000..3cffd0973706 +--- /dev/null ++++ b/drivers/hwmon/pmbus/mp2855.c +@@ -0,0 +1,380 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2855) ++ * ++ * Copyright (C) 2023 MPS ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "pmbus.h" ++ ++#define MP2855_MFR_VR_CONFIG1 0xc1 ++ ++#define MP2855_VOUT_CONFIG_OFF 14 ++#define MP2891_OV_TH_MASK GENMASK(9, 8) ++#define MP2891_OV_TH_POS 8 ++#define MP2891_UV_TH_MASK GENMASK(10, 8) ++#define MP2891_UV_TH_POS 8 ++ ++#define MP2855_PAGE_NUM 2 ++#define MP2855_IOUT_SCALE_MASK GENMASK (31, 27) ++ ++#define MP2855_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP | \ ++ PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_VOUT | \ ++ PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | \ ++ PMBUS_HAVE_STATUS_TEMP) ++ ++#define MP2855_RAIL2_FUNC (PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_IOUT | \ ++ PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT | \ ++ PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP) ++ ++ ++#define MP2891_TMP_TH_GET(ret) DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(((ret) & GENMASK(7, 0)) * \ ++ 3125, 1000) - 275, 3); ++ ++struct mp2855_data { ++ struct pmbus_driver_info info; ++ struct i2c_client client; ++ int iout_scale[MP2855_PAGE_NUM]; ++ int vout_scale[MP2855_PAGE_NUM]; ++ int vout_shift[MP2855_PAGE_NUM]; ++ int uv_off[MP2855_PAGE_NUM]; ++ int ov_off[MP2855_PAGE_NUM]; ++}; ++ ++struct mp2855_data data; ++ ++#define to_mp2855_data(x) container_of(x, struct mp2855_data, info) ++ ++static int mp2855_read_byte_data(struct i2c_client *client, int page, int reg) ++{ ++ switch (reg) { ++ case PMBUS_VOUT_MODE: ++ /* ++ * Enforce VOUT direct format, since device allows to set the ++ * different formats for the different rails. Conversion from ++ * VID to direct provided by driver internally, in case it is ++ * necessary. ++ */ ++ return PB_VOUT_MODE_DIRECT; ++ default: ++ return -ENODATA; ++ } ++} ++ ++static int mp2855_read_word_data(struct i2c_client *client, int page, int phase, int reg) ++{ ++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client); ++ struct mp2855_data *data = to_mp2855_data(info); ++ int ret; ++ ++ switch (reg) { ++ case PMBUS_READ_VIN: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return (ret < 0) ? ret : (ret & 0x3ff) * 3125 / 100; ++ case PMBUS_READ_VOUT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ if (ret < 0) ++ return ret; ++ ++ if (data->vout_shift[page] > 0) ++ return ret & GENMASK(10, 0) >> -data->vout_shift[page]; ++ else if (data->vout_shift[page] < 0) ++ return ret & GENMASK(10, 0) << data->vout_shift[page]; ++ return (ret & GENMASK(10, 0)) * data->vout_scale[page] / 100; ++ case PMBUS_READ_TEMPERATURE_1: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return (ret < 0) ? ret : ret & GENMASK(7, 0); ++ case PMBUS_READ_IOUT: ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ return (ret < 0) ? ret : (ret & GENMASK(7, 0)) * data->iout_scale[page]; ++ case PMBUS_VOUT_OV_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, PMBUS_READ_VOUT); ++ if (ret <= 0) ++ return ret; ++ ++ return (ret & GENMASK(10, 0)) * data->vout_scale[page] / 100 + data->ov_off[page]; ++ case PMBUS_VOUT_UV_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, page, phase, PMBUS_READ_VOUT); ++ if (ret <= 0) ++ return ret; ++ ++ return (ret & GENMASK(10, 0)) * data->vout_scale[page] / 100 - data->uv_off[page]; ++ case PMBUS_OT_FAULT_LIMIT: ++ ret = pmbus_read_word_data(client, 1, phase, reg); ++ return (ret <= 0) ? ret : MP2891_TMP_TH_GET(ret); ++ case PMBUS_UT_WARN_LIMIT: ++ case PMBUS_UT_FAULT_LIMIT: ++ case PMBUS_OT_WARN_LIMIT: ++ case PMBUS_VIN_OV_WARN_LIMIT: ++ case PMBUS_VIN_OV_FAULT_LIMIT: ++ case PMBUS_VIN_UV_WARN_LIMIT: ++ case PMBUS_VIN_UV_FAULT_LIMIT: ++ case PMBUS_VOUT_OV_WARN_LIMIT: ++ case PMBUS_VOUT_UV_WARN_LIMIT: ++ case PMBUS_POUT_OP_WARN_LIMIT: ++ case PMBUS_IIN_OC_FAULT_LIMIT: ++ case PMBUS_POUT_MAX: ++ case PMBUS_POUT_OP_FAULT_LIMIT: ++ case PMBUS_IOUT_OC_WARN_LIMIT: ++ case PMBUS_IOUT_OC_FAULT_LIMIT: ++ case PMBUS_IOUT_UC_FAULT_LIMIT: ++ case PMBUS_MFR_VIN_MIN: ++ case PMBUS_MFR_VOUT_MIN: ++ case PMBUS_MFR_VIN_MAX: ++ case PMBUS_MFR_VOUT_MAX: ++ case PMBUS_MFR_IIN_MAX: ++ case PMBUS_MFR_IOUT_MAX: ++ case PMBUS_MFR_PIN_MAX: ++ case PMBUS_MFR_POUT_MAX: ++ case PMBUS_MFR_MAX_TEMP_1: ++ return -ENXIO; ++ default: ++ return -ENODATA; ++ } ++ ++ return ret; ++} ++ ++static struct pmbus_driver_info mp2855_info = { ++ .pages = MP2855_PAGE_NUM, ++ .phases[0] = 1, ++ .phases[1] = 1, ++ .format[PSC_VOLTAGE_IN] = direct, ++ .format[PSC_VOLTAGE_OUT] = direct, ++ .format[PSC_TEMPERATURE] = direct, ++ .format[PSC_CURRENT_OUT] = direct, ++ .m[PSC_VOLTAGE_IN] = 1, ++ .R[PSC_VOLTAGE_IN] = 3, ++ .b[PSC_VOLTAGE_IN] = 0, ++ .m[PSC_VOLTAGE_OUT] = 1, ++ .R[PSC_VOLTAGE_OUT] = 3, ++ .b[PSC_VOLTAGE_OUT] = 0, ++ .m[PSC_TEMPERATURE] = 1, ++ .R[PSC_TEMPERATURE] = 0, ++ .b[PSC_TEMPERATURE] = 0, ++ .m[PSC_CURRENT_OUT] = 1, ++ .R[PSC_CURRENT_OUT] = 3, ++ .b[PSC_CURRENT_OUT] = 0, ++ .func[0] = MP2855_RAIL1_FUNC, ++ .func[1] = MP2855_RAIL2_FUNC, ++ .read_byte_data = mp2855_read_byte_data, ++ .read_word_data = mp2855_read_word_data, ++}; ++ ++static int mp2855_vout_scale_get(struct i2c_client *client, struct mp2855_data *data, ++ int vout_mode, int page) ++{ ++ int ret; ++ ++ if (vout_mode & GENMASK(7, 5)) { ++ /* Direct mode. */ ++ ret = i2c_smbus_read_word_data(client, MP2855_MFR_VR_CONFIG1); ++ if (ret < 0) ++ return ret; ++ ++ switch (ret >> MP2855_VOUT_CONFIG_OFF) { ++ case 0 : ++ data->vout_scale[page] = 625; ++ break; ++ case 1: ++ data->vout_scale[page] = 500; ++ break; ++ default: ++ data->vout_scale[page] = 500; ++ break; ++ } ++ return 0; ++ } ++ ++ /* Linear mode. */ ++ vout_mode &= GENMASK(4, 0); ++ vout_mode = vout_mode >= 16 ? vout_mode - 32 : vout_mode; ++ if (vout_mode == -9) ++ data->vout_scale[page] = 200; ++ else if (vout_mode < 0) ++ data->vout_shift[page] = -vout_mode; ++ else ++ data->vout_shift[page] = vout_mode; ++ ++ return 0; ++} ++ ++static int mp2855_rails_vout_scale_get(struct i2c_client *client, struct mp2855_data *data) ++{ ++ int vout_mode, ret; ++ ++ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); ++ if (ret < 0) ++ return ret; ++ ++ vout_mode = i2c_smbus_read_word_data(client, PMBUS_VOUT_MODE); ++ if (vout_mode < 0) ++ return vout_mode; ++ ++ /* Get iout_scale for rail 1. */ ++ ret = mp2855_vout_scale_get(client, data, vout_mode, 0); ++ /* Get iout_scale for rail 2. */ ++ return ret < 0 ? ret : mp2855_vout_scale_get(client, data, vout_mode, 1); ++} ++ ++static int ++mp2855_iout_scale_get(struct i2c_client *client, struct mp2855_data *data, u32 reg, int page) ++{ ++ int ret; ++ ++ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); ++ if (ret < 0) ++ return ret; ++ ++ ret = i2c_smbus_read_word_data(client, reg); ++ if (ret < 0) ++ return ret; ++ ++ data->iout_scale[page] = (ret & MP2855_IOUT_SCALE_MASK) == MP2855_IOUT_SCALE_MASK ? ++ 500 : 250; ++ ++ return 0; ++} ++ ++static int mp2855_rails_iout_scale_get(struct i2c_client *client, struct mp2855_data *data) ++{ ++ int ret; ++ ++ /* Get iout_scale for rail 1. */ ++ ret = mp2855_iout_scale_get(client, data, PMBUS_READ_IOUT, 0); ++ /* Get iout_scale for rail 2. */ ++ return ret < 0 ? ret : mp2855_iout_scale_get(client, data, PMBUS_READ_IOUT, 1); ++} ++ ++static int ++mp2855_vout_thresholds_get(struct i2c_client *client, struct mp2855_data *data, int page) ++{ ++ int ret; ++ ++ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); ++ if (ret < 0) ++ return ret; ++ ++ ret = i2c_smbus_read_word_data(client, PMBUS_VOUT_OV_FAULT_LIMIT); ++ if (ret < 0) ++ return ret; ++ ++ switch ((ret & MP2891_OV_TH_MASK) >> MP2891_OV_TH_POS) { ++ case 0: ++ data->ov_off[page] = 200; ++ break; ++ case 1: ++ data->ov_off[page] = 325; ++ break; ++ case 2: ++ data->ov_off[page] = 450; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ ret = i2c_smbus_read_word_data(client, PMBUS_VOUT_UV_FAULT_LIMIT); ++ if (ret < 0) ++ return ret; ++ ++ switch ((ret & MP2891_UV_TH_MASK) >> MP2891_UV_TH_POS) { ++ case 0: ++ data->uv_off[page] = 425; ++ break; ++ case 1: ++ data->uv_off[page] = 375; ++ break; ++ case 2: ++ data->uv_off[page] = 325; ++ break; ++ case 3: ++ data->uv_off[page] = 275; ++ break; ++ case 4: ++ data->uv_off[page] = 225; ++ break; ++ case 5: ++ data->uv_off[page] = 175; ++ break; ++ case 6: ++ data->uv_off[page] = 125; ++ break; ++ case 7: ++ data->uv_off[page] = 75; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int mp2855_rails_vout_thresholds_get(struct i2c_client *client, struct mp2855_data *data) ++{ ++ int ret; ++ ++ /* Get vout thresholds for rail 1. */ ++ ret = mp2855_vout_thresholds_get(client, data, 0); ++ /* Get vout thresholds for rail 2. */ ++ return ret < 0 ? ret : mp2855_vout_thresholds_get(client, data, 1); ++} ++ ++static int mp2855_probe(struct i2c_client *client) ++{ ++ struct pmbus_driver_info *info; ++ struct mp2855_data *data; ++ int ret; ++ ++ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ memcpy(&data->info, &mp2855_info, sizeof(*info)); ++ info = &data->info; ++ ++ ret = mp2855_rails_iout_scale_get(client, data); ++ if (ret < 0) ++ return ret; ++ ret = mp2855_rails_vout_scale_get(client, data); ++ if (ret < 0) ++ return ret; ++ ++ mp2855_rails_vout_thresholds_get(client, data); ++ if (ret < 0) ++ return ret; ++ ++ return pmbus_do_probe(client, info); ++} ++ ++static const struct i2c_device_id mp2855_id[] = { ++ {"mp2855", 0}, ++ {} ++}; ++MODULE_DEVICE_TABLE(i2c, mp2855_id); ++ ++static const struct of_device_id mp2855_of_match[] = { ++ {.compatible = "mps,mp2855"}, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, mp2855_of_match); ++ ++static struct i2c_driver mp2855_driver = { ++ .driver = { ++ .name = "mp2855", ++ .of_match_table = mp2855_of_match, ++ }, ++ .probe_new = mp2855_probe, ++ .id_table = mp2855_id, ++}; ++ ++module_i2c_driver(mp2855_driver); ++ ++MODULE_DESCRIPTION("PMBus driver for MPS MP2855 device"); ++MODULE_LICENSE("GPL"); ++MODULE_IMPORT_NS(PMBUS); +-- +2.20.1 + diff --git a/patch/8005-leds-leds-mlxreg-Downstream-Send-udev-event-from-led.patch b/patch/8005-leds-leds-mlxreg-Downstream-Send-udev-event-from-led.patch index 07ac5bb76..932b77fde 100644 --- a/patch/8005-leds-leds-mlxreg-Downstream-Send-udev-event-from-led.patch +++ b/patch/8005-leds-leds-mlxreg-Downstream-Send-udev-event-from-led.patch @@ -1,8 +1,8 @@ -From f43af239d01b6a8b62667a3b06ee87d2dc3d405d Mon Sep 17 00:00:00 2001 +From c8e0a4b95379b40e2fe768f00caee4c8b9fec42f Mon Sep 17 00:00:00 2001 From: Michael Shych Date: Mon, 11 Jul 2022 12:51:27 +0300 -Subject: [PATH backport v6.1 3/3] leds: leds-mlxreg: Downstream: Send udev - event from leds-mlxreg driver. +Subject: [PATCH v6.1 64/81] leds: leds-mlxreg: Downstream: Send udev event + from leds-mlxreg driver. Add sending udev event from leds-mlxreg driver in case of color change. This patch will not be accepted in upstream as it provides no regular flow. @@ -16,7 +16,7 @@ Signed-off-by: Michael Shych 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c -index c0caf810b6d0..aadf90abce2e 100644 +index 6ddbfceaceec..236f116567ac 100644 --- a/drivers/leds/leds-mlxreg.c +++ b/drivers/leds/leds-mlxreg.c @@ -11,6 +11,7 @@ diff --git a/patch/8007-hwmon-mlxreg-fan-Downstream-Allow-fan-speed-setting-.patch b/patch/8007-hwmon-mlxreg-fan-Downstream-Allow-fan-speed-setting-.patch index 556230981..69aaa50a7 100644 --- a/patch/8007-hwmon-mlxreg-fan-Downstream-Allow-fan-speed-setting-.patch +++ b/patch/8007-hwmon-mlxreg-fan-Downstream-Allow-fan-speed-setting-.patch @@ -1,8 +1,8 @@ -From f897ae50422b9fbff200051419ebb3f5fa280bd8 Mon Sep 17 00:00:00 2001 +From 34758fcde60b934272415849940ee11da6328385 Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Thu, 2 Nov 2023 11:42:47 +0000 -Subject: [PATCH v6.1.42 downstream 1/2] hwmon: (mlxreg-fan): Downstream: Allow - fan speed setting granularity of 1 PWM +Subject: [PATCH v6.1 81/81] hwmon: (mlxreg-fan): Downstream: Allow fan speed + setting granularity of 1 PWM Currently PWM setting is allowed with 10 percent stepping. Such configuration is aligned with thermal drivers, which are used to be @@ -26,11 +26,11 @@ submitted to up-stream. Signed-off-by: Vadim Pasternak --- - drivers/hwmon/mlxreg-fan.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) + drivers/hwmon/mlxreg-fan.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c -index b48bd7c961d6..ca9b1b27e5d2 100644 +index 102a517940f3..1c4adcfd4498 100644 --- a/drivers/hwmon/mlxreg-fan.c +++ b/drivers/hwmon/mlxreg-fan.c @@ -15,10 +15,15 @@ @@ -52,6 +52,5 @@ index b48bd7c961d6..ca9b1b27e5d2 100644 #define MLXREG_FAN_TACHO_DIV_MIN 283 #define MLXREG_FAN_TACHO_DIV_DEF (MLXREG_FAN_TACHO_DIV_MIN * 4) -- --- 2.20.1 diff --git a/patch/kconfig-inclusions b/patch/kconfig-inclusions index e4a16d081..6b408daca 100644 --- a/patch/kconfig-inclusions +++ b/patch/kconfig-inclusions @@ -34,12 +34,17 @@ CONFIG_SENSORS_MAX31790=m # For optoe CONFIG_EEPROM_OPTOE=m ###-> mellanox_amd64-start +CONFIG_X86_AMD_PLATFORM_DEVICE=y CONFIG_DMI_SYSFS=y CONFIG_OF=y CONFIG_EEPROM_AT24=m +CONFIG_AMD_XGBE=m CONFIG_IGB=m CONFIG_MLXSW_CORE=m +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_USBNET=m CONFIG_SERIAL_8250_DW=y +CONFIG_HW_RANDOM_AMD=m CONFIG_I2C_CHARDEV=m CONFIG_I2C_MUX=m CONFIG_I2C_SMBUS=m @@ -48,6 +53,7 @@ CONFIG_I2C_DESIGNWARE_PCI=m CONFIG_I2C_MLXCPLD=m CONFIG_PINCTRL=y CONFIG_GPIOLIB=y +CONFIG_SENSORS_K10TEMP=m CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_CORETEMP=m CONFIG_SENSORS_JC42=m @@ -70,6 +76,7 @@ CONFIG_MLX_PLATFORM=m CONFIG_NET_DEVLINK=y CONFIG_I2C_MUX_REG=m CONFIG_I2C_MUX_MLXCPLD=m +CONFIG_REGMAP_I2C=m CONFIG_IIO_SYSFS_TRIGGER=m CONFIG_NVME_HWMON=y CONFIG_MLXSW_CORE_HWMON=y @@ -86,6 +93,7 @@ CONFIG_MAX1363=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_XDPE122=m CONFIG_SENSORS_MP2975=m +CONFIG_SENSORS_MP2855=m CONFIG_SENSORS_MP2888=m CONFIG_SENSORS_MP2891=m CONFIG_CPU_THERMAL=y @@ -107,6 +115,12 @@ CONFIG_SENSORS_LM25066=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m CONFIG_THERMAL_OF=y +CONFIG_SPI_AMD=m +CONFIG_PINCTRL_AMD=y +CONFIG_EDAC_AMD64=m +CONFIG_AMD_XGBE_DCB=y +CONFIG_AMD_XGBE_HAVE_ECC=y +CONFIG_USB_NET_CDCETHER=m ###-> mellanox_amd64-end # For Cisco 8000 CONFIG_PHYLIB=m diff --git a/patch/series b/patch/series index d9bfe14d7..443b5d316 100755 --- a/patch/series +++ b/patch/series @@ -129,8 +129,14 @@ Support-for-fullcone-nat.patch 0054-platform-mellanox-Introduce-support-for-switches-equ.patch 0055-mellanox-Relocate-mlx-platform-driver.patch 0056-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch +0057-Documentation-ABI-Add-new-attribute-for-mlxreg-io-sy.patch 0085-hwmon-mlxreg-fan-Separate-methods-of-fan-setting-com.patch 0087-platform-mellanox-indicate-deferred-I2C-bus-creation.patch +0087-platform_data-mlxreg-Add-capability-bit-and-mask-fie.patch +0088-platform-mellanox-mlxreg-hotplug-Add-support-for-new.patch +0089-platform-mellanox-mlx-platform-Change-register-name.patch +0090-platform-mellanox-mlx-platform-Add-support-for-new-X.patch +0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch 8000-mlxsw-Use-weak-reverse-dependencies-for-firmware-fla.patch 8003-mlxsw-i2c-SONIC-ISSU-Prevent-transaction-execution-f.patch 8004-mlxsw-minimal-Downstream-Ignore-error-reading-SPAD-r.patch From 03d0237c96a4dc28ccb24f2434c3f893addc6070 Mon Sep 17 00:00:00 2001 From: Vivek Reddy Date: Thu, 6 Jun 2024 16:59:53 +0000 Subject: [PATCH 2/2] Integrate HW-MGMT 7.0030.4003 Changes --- ...hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch | 2 +- patch/kconfig-inclusions | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch b/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch index 8f08753bb..211c3dce4 100644 --- a/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch +++ b/patch/0093-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch @@ -45,7 +45,7 @@ index 77d67344cee4..f173c4195d86 100644 + tristate "MPS MP2855" + help + If you say yes here you get hardware monitoring support for MPS -+ MP2855 Daula-Loop, Digital, Multi-Phase Controller with PMBus ++ MP2855 Dual-Loop, Digital, Multi-Phase Controller with PMBus + interface for AMD SVI2 2.0 platform. + + This driver can also be built as a module. If so, the module will diff --git a/patch/kconfig-inclusions b/patch/kconfig-inclusions index 6b408daca..d0f19f0be 100644 --- a/patch/kconfig-inclusions +++ b/patch/kconfig-inclusions @@ -41,8 +41,6 @@ CONFIG_EEPROM_AT24=m CONFIG_AMD_XGBE=m CONFIG_IGB=m CONFIG_MLXSW_CORE=m -CONFIG_USB_NET_DRIVERS=m -CONFIG_USB_USBNET=m CONFIG_SERIAL_8250_DW=y CONFIG_HW_RANDOM_AMD=m CONFIG_I2C_CHARDEV=m @@ -119,8 +117,6 @@ CONFIG_SPI_AMD=m CONFIG_PINCTRL_AMD=y CONFIG_EDAC_AMD64=m CONFIG_AMD_XGBE_DCB=y -CONFIG_AMD_XGBE_HAVE_ECC=y -CONFIG_USB_NET_CDCETHER=m ###-> mellanox_amd64-end # For Cisco 8000 CONFIG_PHYLIB=m