// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved

#include <linux/hwmon.h>
#include <linux/bitmap.h>
#include <linux/mlx5/device.h>
#include <linux/mlx5/mlx5_ifc.h>
#include <linux/mlx5/port.h>
#include "mlx5_core.h"
#include "hwmon.h"

#define CHANNELS_TYPE_NUM 2 /* chip channel and temp channel */
#define CHIP_CONFIG_NUM 1

/* module 0 is mapped to sensor_index 64 in MTMP register */
#define to_mtmp_module_sensor_idx(idx) (64 + (idx))

/* All temperatures retrieved in units of 0.125C. hwmon framework expect
 * it in units of millidegrees C. Hence multiply values by 125.
 */
#define mtmp_temp_to_mdeg(temp) ((temp) * 125)

struct temp_channel_desc {
	u32 sensor_index;
	char sensor_name[32];
};

/* chip_channel_config and channel_info arrays must be 0-terminated, hence + 1 */
struct mlx5_hwmon {
	struct mlx5_core_dev *mdev;
	struct device *hwmon_dev;
	struct hwmon_channel_info chip_info;
	u32 chip_channel_config[CHIP_CONFIG_NUM + 1];
	struct hwmon_channel_info temp_info;
	u32 *temp_channel_config;
	const struct hwmon_channel_info *channel_info[CHANNELS_TYPE_NUM + 1];
	struct hwmon_chip_info chip;
	struct temp_channel_desc *temp_channel_desc;
	u32 asic_platform_scount;
	u32 module_scount;
};

static int mlx5_hwmon_query_mtmp(struct mlx5_core_dev *mdev, u32 sensor_index, u32 *mtmp_out)
{
	u32 mtmp_in[MLX5_ST_SZ_DW(mtmp_reg)] = {};

	MLX5_SET(mtmp_reg, mtmp_in, sensor_index, sensor_index);

	return mlx5_core_access_reg(mdev, mtmp_in,  sizeof(mtmp_in),
				    mtmp_out, MLX5_ST_SZ_BYTES(mtmp_reg),
				    MLX5_REG_MTMP, 0, 0);
}

static int mlx5_hwmon_reset_max_temp(struct mlx5_core_dev *mdev, int sensor_index)
{
	u32 mtmp_out[MLX5_ST_SZ_DW(mtmp_reg)] = {};
	u32 mtmp_in[MLX5_ST_SZ_DW(mtmp_reg)] = {};

	MLX5_SET(mtmp_reg, mtmp_in, sensor_index, sensor_index);
	MLX5_SET(mtmp_reg, mtmp_in, mtr, 1);

	return mlx5_core_access_reg(mdev, mtmp_in,  sizeof(mtmp_in),
				    mtmp_out, sizeof(mtmp_out),
				    MLX5_REG_MTMP, 0, 0);
}

static int mlx5_hwmon_enable_max_temp(struct mlx5_core_dev *mdev, int sensor_index)
{
	u32 mtmp_out[MLX5_ST_SZ_DW(mtmp_reg)] = {};
	u32 mtmp_in[MLX5_ST_SZ_DW(mtmp_reg)] = {};
	int err;

	err = mlx5_hwmon_query_mtmp(mdev, sensor_index, mtmp_in);
	if (err)
		return err;

	MLX5_SET(mtmp_reg, mtmp_in, mte, 1);
	return mlx5_core_access_reg(mdev, mtmp_in,  sizeof(mtmp_in),
				    mtmp_out, sizeof(mtmp_out),
				    MLX5_REG_MTMP, 0, 1);
}

static int mlx5_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
			   int channel, long *val)
{
	struct mlx5_hwmon *hwmon = dev_get_drvdata(dev);
	u32 mtmp_out[MLX5_ST_SZ_DW(mtmp_reg)] = {};
	int err;

	if (type != hwmon_temp)
		return -EOPNOTSUPP;

	err = mlx5_hwmon_query_mtmp(hwmon->mdev, hwmon->temp_channel_desc[channel].sensor_index,
				    mtmp_out);
	if (err)
		return err;

	switch (attr) {
	case hwmon_temp_input:
		*val = mtmp_temp_to_mdeg(MLX5_GET(mtmp_reg, mtmp_out, temperature));
		return 0;
	case hwmon_temp_highest:
		*val = mtmp_temp_to_mdeg(MLX5_GET(mtmp_reg, mtmp_out, max_temperature));
		return 0;
	case hwmon_temp_crit:
		*val = mtmp_temp_to_mdeg(MLX5_GET(mtmp_reg, mtmp_out, temp_threshold_hi));
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int mlx5_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
			    int channel, long val)
{
	struct mlx5_hwmon *hwmon = dev_get_drvdata(dev);

	if (type != hwmon_temp || attr != hwmon_temp_reset_history)
		return -EOPNOTSUPP;

	return mlx5_hwmon_reset_max_temp(hwmon->mdev,
				hwmon->temp_channel_desc[channel].sensor_index);
}

static umode_t mlx5_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
				     int channel)
{
	if (type != hwmon_temp)
		return 0;

	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_highest:
	case hwmon_temp_crit:
	case hwmon_temp_label:
		return 0444;
	case hwmon_temp_reset_history:
		return 0200;
	default:
		return 0;
	}
}

static int mlx5_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
				  int channel, const char **str)
{
	struct mlx5_hwmon *hwmon = dev_get_drvdata(dev);

	if (type != hwmon_temp || attr != hwmon_temp_label)
		return -EOPNOTSUPP;

	*str = (const char *)hwmon->temp_channel_desc[channel].sensor_name;
	return 0;
}

static const struct hwmon_ops mlx5_hwmon_ops = {
	.read = mlx5_hwmon_read,
	.read_string = mlx5_hwmon_read_string,
	.is_visible = mlx5_hwmon_is_visible,
	.write = mlx5_hwmon_write,
};

static int mlx5_hwmon_init_channels_names(struct mlx5_hwmon *hwmon)
{
	u32 i;

	for (i = 0; i < hwmon->asic_platform_scount + hwmon->module_scount; i++) {
		u32 mtmp_out[MLX5_ST_SZ_DW(mtmp_reg)] = {};
		char *sensor_name;
		int err;

		err = mlx5_hwmon_query_mtmp(hwmon->mdev, hwmon->temp_channel_desc[i].sensor_index,
					    mtmp_out);
		if (err)
			return err;

		sensor_name = MLX5_ADDR_OF(mtmp_reg, mtmp_out, sensor_name_hi);
		if (!*sensor_name) {
			snprintf(hwmon->temp_channel_desc[i].sensor_name,
				 sizeof(hwmon->temp_channel_desc[i].sensor_name), "sensor%u",
				 hwmon->temp_channel_desc[i].sensor_index);
			continue;
		}

		memcpy(&hwmon->temp_channel_desc[i].sensor_name, sensor_name,
		       MLX5_FLD_SZ_BYTES(mtmp_reg, sensor_name_hi) +
		       MLX5_FLD_SZ_BYTES(mtmp_reg, sensor_name_lo));
	}

	return 0;
}

static int mlx5_hwmon_get_module_sensor_index(struct mlx5_core_dev *mdev, u32 *module_index)
{
	int module_num;
	int err;

	err = mlx5_query_module_num(mdev, &module_num);
	if (err)
		return err;

	*module_index = to_mtmp_module_sensor_idx(module_num);

	return 0;
}

static int mlx5_hwmon_init_sensors_indexes(struct mlx5_hwmon *hwmon, u64 sensor_map)
{
	DECLARE_BITMAP(smap, BITS_PER_TYPE(sensor_map));
	unsigned long bit_pos;
	int err = 0;
	int i = 0;

	bitmap_from_u64(smap, sensor_map);

	for_each_set_bit(bit_pos, smap, BITS_PER_TYPE(sensor_map)) {
		hwmon->temp_channel_desc[i].sensor_index = bit_pos;
		i++;
	}

	if (hwmon->module_scount)
		err = mlx5_hwmon_get_module_sensor_index(hwmon->mdev,
							 &hwmon->temp_channel_desc[i].sensor_index);

	return err;
}

static void mlx5_hwmon_channel_info_init(struct mlx5_hwmon *hwmon)
{
	int i;

	hwmon->channel_info[0] = &hwmon->chip_info;
	hwmon->channel_info[1] = &hwmon->temp_info;

	hwmon->chip_channel_config[0] = HWMON_C_REGISTER_TZ;
	hwmon->chip_info.config = (const u32 *)hwmon->chip_channel_config;
	hwmon->chip_info.type = hwmon_chip;

	for (i = 0; i < hwmon->asic_platform_scount + hwmon->module_scount; i++)
		hwmon->temp_channel_config[i] = HWMON_T_INPUT | HWMON_T_HIGHEST | HWMON_T_CRIT |
					     HWMON_T_RESET_HISTORY | HWMON_T_LABEL;

	hwmon->temp_info.config = (const u32 *)hwmon->temp_channel_config;
	hwmon->temp_info.type = hwmon_temp;
}

static int mlx5_hwmon_is_module_mon_cap(struct mlx5_core_dev *mdev, bool *mon_cap)
{
	u32 mtmp_out[MLX5_ST_SZ_DW(mtmp_reg)];
	u32 module_index;
	int err;

	err = mlx5_hwmon_get_module_sensor_index(mdev, &module_index);
	if (err)
		return err;

	err = mlx5_hwmon_query_mtmp(mdev, module_index, mtmp_out);
	if (err)
		return err;

	if (MLX5_GET(mtmp_reg, mtmp_out, temperature))
		*mon_cap = true;

	return 0;
}

static int mlx5_hwmon_get_sensors_count(struct mlx5_core_dev *mdev, u32 *asic_platform_scount)
{
	u32 mtcap_out[MLX5_ST_SZ_DW(mtcap_reg)] = {};
	u32 mtcap_in[MLX5_ST_SZ_DW(mtcap_reg)] = {};
	int err;

	err = mlx5_core_access_reg(mdev, mtcap_in,  sizeof(mtcap_in),
				   mtcap_out, sizeof(mtcap_out),
				   MLX5_REG_MTCAP, 0, 0);
	if (err)
		return err;

	*asic_platform_scount = MLX5_GET(mtcap_reg, mtcap_out, sensor_count);

	return 0;
}

static void mlx5_hwmon_free(struct mlx5_hwmon *hwmon)
{
	if (!hwmon)
		return;

	kfree(hwmon->temp_channel_config);
	kfree(hwmon->temp_channel_desc);
	kfree(hwmon);
}

static struct mlx5_hwmon *mlx5_hwmon_alloc(struct mlx5_core_dev *mdev)
{
	struct mlx5_hwmon *hwmon;
	bool mon_cap = false;
	u32 sensors_count;
	int err;

	hwmon = kzalloc(sizeof(*mdev->hwmon), GFP_KERNEL);
	if (!hwmon)
		return ERR_PTR(-ENOMEM);

	err = mlx5_hwmon_get_sensors_count(mdev, &hwmon->asic_platform_scount);
	if (err)
		goto err_free_hwmon;

	/* check if module sensor has thermal mon cap. if yes, allocate channel desc for it */
	err = mlx5_hwmon_is_module_mon_cap(mdev, &mon_cap);
	if (err)
		goto err_free_hwmon;

	hwmon->module_scount = mon_cap ? 1 : 0;
	sensors_count = hwmon->asic_platform_scount + hwmon->module_scount;
	hwmon->temp_channel_desc = kcalloc(sensors_count, sizeof(*hwmon->temp_channel_desc),
					   GFP_KERNEL);
	if (!hwmon->temp_channel_desc) {
		err = -ENOMEM;
		goto err_free_hwmon;
	}

	/* sensors configuration values array, must be 0-terminated hence, + 1 */
	hwmon->temp_channel_config = kcalloc(sensors_count + 1, sizeof(*hwmon->temp_channel_config),
					     GFP_KERNEL);
	if (!hwmon->temp_channel_config) {
		err = -ENOMEM;
		goto err_free_temp_channel_desc;
	}

	hwmon->mdev = mdev;

	return hwmon;

err_free_temp_channel_desc:
	kfree(hwmon->temp_channel_desc);
err_free_hwmon:
	kfree(hwmon);
	return ERR_PTR(err);
}

static int mlx5_hwmon_dev_init(struct mlx5_hwmon *hwmon)
{
	u32 mtcap_out[MLX5_ST_SZ_DW(mtcap_reg)] = {};
	u32 mtcap_in[MLX5_ST_SZ_DW(mtcap_reg)] = {};
	int err;
	int i;

	err =  mlx5_core_access_reg(hwmon->mdev, mtcap_in,  sizeof(mtcap_in),
				    mtcap_out, sizeof(mtcap_out),
				    MLX5_REG_MTCAP, 0, 0);
	if (err)
		return err;

	mlx5_hwmon_channel_info_init(hwmon);
	mlx5_hwmon_init_sensors_indexes(hwmon, MLX5_GET64(mtcap_reg, mtcap_out, sensor_map));
	err = mlx5_hwmon_init_channels_names(hwmon);
	if (err)
		return err;

	for (i = 0; i < hwmon->asic_platform_scount + hwmon->module_scount; i++) {
		err = mlx5_hwmon_enable_max_temp(hwmon->mdev,
						 hwmon->temp_channel_desc[i].sensor_index);
		if (err)
			return err;
	}

	hwmon->chip.ops = &mlx5_hwmon_ops;
	hwmon->chip.info = (const struct hwmon_channel_info **)hwmon->channel_info;

	return 0;
}

int mlx5_hwmon_dev_register(struct mlx5_core_dev *mdev)
{
	struct device *dev = mdev->device;
	struct mlx5_hwmon *hwmon;
	int err;

	if (!MLX5_CAP_MCAM_REG(mdev, mtmp))
		return 0;

	hwmon = mlx5_hwmon_alloc(mdev);
	if (IS_ERR(hwmon))
		return PTR_ERR(hwmon);

	err = mlx5_hwmon_dev_init(hwmon);
	if (err)
		goto err_free_hwmon;

	hwmon->hwmon_dev = hwmon_device_register_with_info(dev, "mlx5",
							   hwmon,
							   &hwmon->chip,
							   NULL);
	if (IS_ERR(hwmon->hwmon_dev)) {
		err = PTR_ERR(hwmon->hwmon_dev);
		goto err_free_hwmon;
	}

	mdev->hwmon = hwmon;
	return 0;

err_free_hwmon:
	mlx5_hwmon_free(hwmon);
	return err;
}

void mlx5_hwmon_dev_unregister(struct mlx5_core_dev *mdev)
{
	struct mlx5_hwmon *hwmon = mdev->hwmon;

	if (!hwmon)
		return;

	hwmon_device_unregister(hwmon->hwmon_dev);
	mlx5_hwmon_free(hwmon);
	mdev->hwmon = NULL;
}
