sonic-buildimage/platform/mellanox/non-upstream-patches/patches/0198-platform-mellanox-Introduce-support-for-switches-bas.patch
Kebo Liu e286869b24
[Mellanox] Update HW-MGMT package to new version V.7.0030.1011 (#16239)
- Why I did it
1. Update Mellanox HW-MGMT package to newer version V.7.0030.1011
2. Replace the SONiC PMON Thermal control algorithm with the one inside the HW-MGMT package on all Nvidia platforms
3. Support Spectrum-4 systems

- How I did it
1. Update the HW-MGMT package version number and submodule pointer
2. Remove the thermal control algorithm implementation from Mellanox platform API
3. Revise the patch to HW-MGMT package which will disable HW-MGMT from running on SIMX
4. Update the downstream kernel patch list

Signed-off-by: Kebo Liu <kebol@nvidia.com>
2023-09-06 11:32:08 +03:00

254 lines
8.8 KiB
Diff

From bcdfc7d1d106889fa9af3404f252fb1260f5a0fd Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@nvidia.com>
Date: Tue, 15 Nov 2022 11:51:47 +0200
Subject: [PATCH backport 5.10 086/150] platform: mellanox: Introduce support
for switches based on BlueField-3/ARM64 COMe
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add support for Nvidia MQM97xx family switches providing a
high-performance solution by delivering high bandwidth with low latency
to Enterprise Data Centers.
These switches are based on previous generation of MQM97xx switches,
excepting CFL based COMe module is replaced by new BlueField®-3 COMe
module.
Switches of this class are equipped with:
- Nvidia Quantum™-2 ASIC, providing up to 64x400GB/s (IB) full
bidirectional bandwidth per port using PAM-4 modulation.
- Com-Express type 7 module, based on Nvidia NVIDIA® BlueField®-3
processing unit and equipped with LATTICE LFD2NX40 Certus™-NX FPGA
secured device with fail safe
mechanism, connected by PCIe bus.
- Switch board with two Lattice LCMXO3D-9400HC secured with fail safe
mechanism, connected by PCEi-to-LPC bridge.
- Fan board to supporting 7 fans.
- 2x power extender boards.
- 7x FRU fans.
- 2x 2000W AC/DC PSU (FRU).
New switches platform configuration is based on the new VMOD0016
class. Configuration is extended to support new register map with
callbacks supporting indirect addressing for PCIe-to-LPC bridge.
This bridge provides interface between FPAG at COMe board (directly
connected to CPU PCIe root complex) to CPLDs on switch board (which
cannot be connected directly to PCIe root complex).
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
drivers/platform/mellanox/mlx-platform.c | 147 ++++++++++++++++++++++-
1 file changed, 146 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/mellanox/mlx-platform.c b/drivers/platform/mellanox/mlx-platform.c
index f3df56c41..b1c8632d6 100644
--- a/drivers/platform/mellanox/mlx-platform.c
+++ b/drivers/platform/mellanox/mlx-platform.c
@@ -270,6 +270,7 @@
/* Maximum number of possible physical buses equipped on system */
#define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
#define MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM 24
+#define MLXPLAT_CPLD_DEFAULT_MUX_HOTPLUG_VECTOR 0
/* Number of channels in group */
#define MLXPLAT_CPLD_GRP_CHNL_NUM 8
@@ -331,6 +332,17 @@
#define PCI_VENDOR_ID_LATTICE 0x1204
#define PCI_DEVICE_ID_LATTICE_LFD2NX40 0x9c1d
#define MLXPLAT_FPGA_PCI_BAR0_SIZE 0x4000
+#define MLXPLAT_FPGA_PCI_BASE_OFFSET 0x00000000
+#define MLXPLAT_FPGA_PCI_ADDR_OFFSET MLXPLAT_FPGA_PCI_BASE_OFFSET
+#define MLXPLAT_FPGA_PCI_DATA_OFFSET (MLXPLAT_FPGA_PCI_BASE_OFFSET + 0x02)
+#define MLXPLAT_FPGA_PCI_CTRL_OFFSET (MLXPLAT_FPGA_PCI_BASE_OFFSET + 0x04)
+#define MLXPLAT_FPGA_PCI_STAT_OFFSET (MLXPLAT_FPGA_PCI_BASE_OFFSET + 0x06)
+#define MLXPLAT_FPGA_PCI_I2C_LPC_OFFSET (MLXPLAT_FPGA_PCI_BASE_OFFSET + 0x400)
+
+#define MLXPLAT_FPGA_PCI_CTRL_READ BIT(0)
+#define MLXPLAT_FPGA_PCI_CTRL_WRITE BIT(1)
+#define MLXPLAT_FPGA_PCI_COMPLETED BIT(0)
+#define MLXPLAT_FPGA_PCI_TO 50 /* usec */
/* mlxplat_priv - platform private data
* @pdev_i2c - i2c controller platform device
@@ -443,6 +455,28 @@ static struct i2c_mux_reg_platform_data mlxplat_default_mux_data[] = {
};
+/* Default channels vector for regmap mux. */
+static int mlxplat_default_regmap_mux_chan[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+/* Platform regmap mux data */
+static struct i2c_mux_regmap_platform_data mlxplat_default_regmap_mux_data[] = {
+ {
+ .parent = 1,
+ .chan_ids = mlxplat_default_regmap_mux_chan,
+ .num_adaps = ARRAY_SIZE(mlxplat_default_regmap_mux_chan),
+ .sel_reg_addr = MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET,
+ .reg_size = 1,
+ },
+ {
+ .parent = 1,
+ .chan_ids = mlxplat_default_regmap_mux_chan,
+ .num_adaps = ARRAY_SIZE(mlxplat_default_regmap_mux_chan),
+ .sel_reg_addr = MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET,
+ .reg_size = 1,
+ },
+
+};
+
/* Platform mux configuration variables */
static int mlxplat_max_adap_num;
static int mlxplat_mux_num;
@@ -5796,6 +5830,84 @@ static const struct regmap_config mlxplat_mlxcpld_regmap_config_eth_modular = {
.reg_write = mlxplat_mlxcpld_reg_write,
};
+/* Wait completion routine for indirect access for register map */
+static int mlxplat_fpga_completion_wait(struct mlxplat_mlxcpld_regmap_context *ctx)
+{
+ unsigned long end;
+ u16 status;
+
+ end = jiffies + msecs_to_jiffies(MLXPLAT_FPGA_PCI_TO);
+ do {
+ status = ioread16(ctx->base + MLXPLAT_FPGA_PCI_STAT_OFFSET);
+ if (status & MLXPLAT_FPGA_PCI_COMPLETED)
+ return 0;
+ cond_resched();
+ } while (time_before(jiffies, end));
+
+ return -EIO;
+}
+
+/* Read callback for indirect register map access */
+static int mlxplat_fpga_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct mlxplat_mlxcpld_regmap_context *ctx = context;
+ int err;
+
+ /* Verify there is no pending transactions */
+ err = mlxplat_fpga_completion_wait(ctx);
+ if (err)
+ return err;
+
+ /* Set address in register space */
+ iowrite16(reg, ctx->base + MLXPLAT_FPGA_PCI_ADDR_OFFSET);
+ /* Activate read operation */
+ iowrite16(MLXPLAT_FPGA_PCI_CTRL_READ, ctx->base + MLXPLAT_FPGA_PCI_CTRL_OFFSET);
+ /* Verify transaction completion */
+ err = mlxplat_fpga_completion_wait(ctx);
+ if (err)
+ return err;
+
+ /* Read data */
+ *val = ioread16(ctx->base + MLXPLAT_FPGA_PCI_DATA_OFFSET);
+
+ return 0;
+}
+
+/* Write callback for indirect register map access */
+static int mlxplat_fpga_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct mlxplat_mlxcpld_regmap_context *ctx = context;
+ int err;
+
+ /* Verify there is no pending transactions */
+ err = mlxplat_fpga_completion_wait(ctx);
+ if (err)
+ return err;
+
+ /* Set address in register space */
+ iowrite16(reg, ctx->base + MLXPLAT_FPGA_PCI_ADDR_OFFSET);
+ /* Set data to be written */
+ iowrite16(val, ctx->base + MLXPLAT_FPGA_PCI_DATA_OFFSET);
+ /* Activate write operation */
+ iowrite16(MLXPLAT_FPGA_PCI_CTRL_WRITE, ctx->base + MLXPLAT_FPGA_PCI_CTRL_OFFSET);
+
+ return 0;
+}
+
+static const struct regmap_config mlxplat_fpga_regmap_config_bf3_comex_default = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 512,
+ .cache_type = REGCACHE_FLAT,
+ .writeable_reg = mlxplat_mlxcpld_writeable_reg,
+ .readable_reg = mlxplat_mlxcpld_readable_reg,
+ .volatile_reg = mlxplat_mlxcpld_volatile_reg,
+ .reg_defaults = mlxplat_mlxcpld_regmap_ng400,
+ .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng400),
+ .reg_read = mlxplat_fpga_reg_read,
+ .reg_write = mlxplat_fpga_reg_write,
+};
+
static struct resource mlxplat_mlxcpld_resources[] = {
[0] = DEFINE_RES_IRQ_NAMED(MLXPLAT_CPLD_LPC_SYSIRQ, "mlxreg-hotplug"),
};
@@ -6175,6 +6287,29 @@ static int __init mlxplat_dmi_l1_switch_matched(const struct dmi_system_id *dmi)
return 1;
}
+static int __init mlxplat_dmi_bf3_comex_default_matched(const struct dmi_system_id *dmi)
+{
+ int i;
+
+ mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
+ mlxplat_mux_hotplug_num = MLXPLAT_CPLD_DEFAULT_MUX_HOTPLUG_VECTOR;
+ mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_regmap_mux_data);
+ mlxplat_mux_regmap_data = mlxplat_default_regmap_mux_data;
+ mlxplat_hotplug = &mlxplat_mlxcpld_ext_data;
+ mlxplat_hotplug->deferred_nr =
+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
+ mlxplat_led = &mlxplat_default_ng_led_data;
+ mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
+ mlxplat_fan = &mlxplat_default_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_fpga_regmap_config_bf3_comex_default;
+ pm_power_off = mlxplat_poweroff;
+
+ return 1;
+}
+
static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
{
.callback = mlxplat_dmi_default_wc_matched,
@@ -6270,6 +6405,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
DMI_MATCH(DMI_BOARD_NAME, "VMOD0015"),
},
},
+ {
+ .callback = mlxplat_dmi_bf3_comex_default_matched,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "VMOD0016"),
+ },
+ },
{
.callback = mlxplat_dmi_l1_switch_matched,
.matches = {
@@ -6502,6 +6643,11 @@ mlxplat_pci_fpga_device_init(struct resource **hotplug_resources,
err = -EIO;
goto fail_ioremap;
}
+
+ /* Set mapped base address of I2C-LPC bridge over PCIe */
+ mlxplat_i2c->addr = mlxplat_mlxcpld_regmap_ctx.base +
+ MLXPLAT_FPGA_PCI_I2C_LPC_OFFSET;
+
pci_set_master(pci_dev);
mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, PLATFORM_DEVID_NONE,
@@ -6782,7 +6928,6 @@ static int mlxplat_i2c_main_init(struct mlxplat_priv *priv)
nr = (nr == mlxplat_max_adap_num) ? -1 : nr;
mlxplat_i2c->regmap = priv->regmap;
mlxplat_i2c->handle = priv;
-
priv->pdev_i2c = platform_device_register_resndata(&mlxplat_dev->dev, "i2c_mlxcpld",
nr, priv->hotplug_resources,
priv->hotplug_resources_size,
--
2.20.1