Unverified Commit 56b0bb7f authored by Vadim Pasternak's avatar Vadim Pasternak Committed by Ilpo Järvinen
Browse files

platform: mellanox: nvsw-sn2200: Add support for new system flavour



Add support for SN2201 system flavour, which is fitting OCP rack
form-factor and feeded from external power source through the rack
standard busbar interface.

Validate system type through DMI decode.
For new system flavour:
- Skip internal power supply configuration.
- Attach power hotswap device.

Reviewed-by: default avatarMichael Shych <michaelsh@nvidia.com>
Signed-off-by: default avatarVadim Pasternak <vadimp@nvidia.com>
Link: https://lore.kernel.org/r/20250504165507.9003-2-vadimp@nvidia.com


Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
parent c5925f43
Loading
Loading
Loading
Loading
+107 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */

#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -104,6 +105,9 @@
	| NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \
	| NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \
	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
#define NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF \
	(NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \
	| NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)

#define NVSW_SN2201_CPLD_ASIC_MASK		GENMASK(3, 1)
#define NVSW_SN2201_CPLD_PSU_MASK		GENMASK(1, 0)
@@ -132,6 +136,7 @@
 * @cpld_devs: I2C devices for cpld;
 * @cpld_devs_num: number of I2C devices for cpld;
 * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution;
 * @ext_pwr_source: true if system powered by external power supply; false - by internal;
 */
struct nvsw_sn2201 {
	struct device *dev;
@@ -152,6 +157,7 @@ struct nvsw_sn2201 {
	struct mlxreg_hotplug_device *cpld_devs;
	int cpld_devs_num;
	int main_mux_deferred_nr;
	bool ext_pwr_source;
};

static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg)
@@ -522,6 +528,35 @@ struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = {
	.mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF,
};

static struct mlxreg_core_item nvsw_sn2201_busbar_items[] = {
	{
		.data = nvsw_sn2201_fan_items_data,
		.aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF,
		.reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
		.mask = NVSW_SN2201_CPLD_FAN_MASK,
		.count = ARRAY_SIZE(nvsw_sn2201_fan_items_data),
		.inversed = 1,
		.health = false,
	},
	{
		.data = nvsw_sn2201_sys_items_data,
		.aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF,
		.reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
		.mask = NVSW_SN2201_CPLD_ASIC_MASK,
		.count = ARRAY_SIZE(nvsw_sn2201_sys_items_data),
		.inversed = 1,
		.health = false,
	},
};

static
struct mlxreg_core_hotplug_platform_data nvsw_sn2201_busbar_hotplug = {
	.items = nvsw_sn2201_items,
	.count = ARRAY_SIZE(nvsw_sn2201_busbar_items),
	.cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET,
	.mask = NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF,
};

/* SN2201 static devices. */
static struct i2c_board_info nvsw_sn2201_static_devices[] = {
	{
@@ -557,6 +592,9 @@ static struct i2c_board_info nvsw_sn2201_static_devices[] = {
	{
		I2C_BOARD_INFO("pmbus", 0x40),
	},
	{
		I2C_BOARD_INFO("lm5066i", 0x15),
	},
};

/* SN2201 default static board info. */
@@ -607,6 +645,58 @@ static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = {
	},
};

/* SN2201 default busbar static board info. */
static struct mlxreg_hotplug_device nvsw_sn2201_busbar_static_brdinfo[] = {
	{
		.brdinfo = &nvsw_sn2201_static_devices[0],
		.nr = NVSW_SN2201_MAIN_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[1],
		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[2],
		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[3],
		.nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[4],
		.nr = NVSW_SN2201_MAIN_MUX_CH3_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[5],
		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[6],
		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[7],
		.nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[8],
		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[9],
		.nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[10],
		.nr = NVSW_SN2201_MAIN_MUX_CH7_NR,
	},
	{
		.brdinfo = &nvsw_sn2201_static_devices[11],
		.nr = NVSW_SN2201_MAIN_MUX_CH1_NR,
	},
};

/* LED default data. */
static struct mlxreg_core_data nvsw_sn2201_led_data[] = {
	{
@@ -981,6 +1071,9 @@ static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap
	nvsw_sn2201->io_data = &nvsw_sn2201_regs_io;
	nvsw_sn2201->led_data = &nvsw_sn2201_led;
	nvsw_sn2201->wd_data = &nvsw_sn2201_wd;
	if (nvsw_sn2201->ext_pwr_source)
		nvsw_sn2201->hotplug_data = &nvsw_sn2201_busbar_hotplug;
	else
		nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;

	/* Register IO access driver. */
@@ -1198,12 +1291,18 @@ static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201)
static int nvsw_sn2201_probe(struct platform_device *pdev)
{
	struct nvsw_sn2201 *nvsw_sn2201;
	const char *sku;
	int ret;

	nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL);
	if (!nvsw_sn2201)
		return -ENOMEM;

	/* Validate system powering type - only HI168 SKU supports external power. */
	sku = dmi_get_system_info(DMI_PRODUCT_SKU);
	if (sku && !strcmp(sku, "HI168"))
		nvsw_sn2201->ext_pwr_source = true;

	nvsw_sn2201->dev = &pdev->dev;
	platform_set_drvdata(pdev, nvsw_sn2201);
	ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources,
@@ -1214,8 +1313,13 @@ static int nvsw_sn2201_probe(struct platform_device *pdev)
	nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR;
	nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo;
	nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo;
	if (nvsw_sn2201->ext_pwr_source) {
		nvsw_sn2201->sn2201_devs = nvsw_sn2201_busbar_static_brdinfo;
		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_busbar_static_brdinfo);
	} else {
		nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
		nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
	}

	return nvsw_sn2201_config_pre_init(nvsw_sn2201);
}