// SPDX-License-Identifier: GPL-2.0
//
// System Control and Management Interface (SCMI) based regulator driver
//
// Copyright (C) 2020-2021 ARM Ltd.
//
// Implements a regulator driver on top of the SCMI Voltage Protocol.
//
// The ARM SCMI Protocol aims in general to hide as much as possible all the
// underlying operational details while providing an abstracted interface for
// its users to operate upon: as a consequence the resulting operational
// capabilities and configurability of this regulator device are much more
// limited than the ones usually available on a standard physical regulator.
//
// The supported SCMI regulator ops are restricted to the bare minimum:
//
//  - 'status_ops': enable/disable/is_enabled
//  - 'voltage_ops': get_voltage_sel/set_voltage_sel
//		     list_voltage/map_voltage
//
// Each SCMI regulator instance is associated, through the means of a proper DT
// entry description, to a specific SCMI Voltage Domain.

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/linear_range.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/scmi_protocol.h>
#include <linux/slab.h>
#include <linux/types.h>

static const struct scmi_voltage_proto_ops *voltage_ops;

struct scmi_regulator {
	u32 id;
	struct scmi_device *sdev;
	struct scmi_protocol_handle *ph;
	struct regulator_dev *rdev;
	struct device_node *of_node;
	struct regulator_desc desc;
	struct regulator_config conf;
};

struct scmi_regulator_info {
	int num_doms;
	struct scmi_regulator **sregv;
};

static int scmi_reg_enable(struct regulator_dev *rdev)
{
	struct scmi_regulator *sreg = rdev_get_drvdata(rdev);

	return voltage_ops->config_set(sreg->ph, sreg->id,
				       SCMI_VOLTAGE_ARCH_STATE_ON);
}

static int scmi_reg_disable(struct regulator_dev *rdev)
{
	struct scmi_regulator *sreg = rdev_get_drvdata(rdev);

	return voltage_ops->config_set(sreg->ph, sreg->id,
				       SCMI_VOLTAGE_ARCH_STATE_OFF);
}

static int scmi_reg_is_enabled(struct regulator_dev *rdev)
{
	int ret;
	u32 config;
	struct scmi_regulator *sreg = rdev_get_drvdata(rdev);

	ret = voltage_ops->config_get(sreg->ph, sreg->id, &config);
	if (ret) {
		dev_err(&sreg->sdev->dev,
			"Error %d reading regulator %s status.\n",
			ret, sreg->desc.name);
		return ret;
	}

	return config & SCMI_VOLTAGE_ARCH_STATE_ON;
}

static int scmi_reg_get_voltage_sel(struct regulator_dev *rdev)
{
	int ret;
	s32 volt_uV;
	struct scmi_regulator *sreg = rdev_get_drvdata(rdev);

	ret = voltage_ops->level_get(sreg->ph, sreg->id, &volt_uV);
	if (ret)
		return ret;

	return sreg->desc.ops->map_voltage(rdev, volt_uV, volt_uV);
}

static int scmi_reg_set_voltage_sel(struct regulator_dev *rdev,
				    unsigned int selector)
{
	s32 volt_uV;
	struct scmi_regulator *sreg = rdev_get_drvdata(rdev);

	volt_uV = sreg->desc.ops->list_voltage(rdev, selector);
	if (volt_uV <= 0)
		return -EINVAL;

	return voltage_ops->level_set(sreg->ph, sreg->id, 0x0, volt_uV);
}

static const struct regulator_ops scmi_reg_fixed_ops = {
	.enable = scmi_reg_enable,
	.disable = scmi_reg_disable,
	.is_enabled = scmi_reg_is_enabled,
};

static const struct regulator_ops scmi_reg_linear_ops = {
	.enable = scmi_reg_enable,
	.disable = scmi_reg_disable,
	.is_enabled = scmi_reg_is_enabled,
	.get_voltage_sel = scmi_reg_get_voltage_sel,
	.set_voltage_sel = scmi_reg_set_voltage_sel,
	.list_voltage = regulator_list_voltage_linear,
	.map_voltage = regulator_map_voltage_linear,
};

static const struct regulator_ops scmi_reg_discrete_ops = {
	.enable = scmi_reg_enable,
	.disable = scmi_reg_disable,
	.is_enabled = scmi_reg_is_enabled,
	.get_voltage_sel = scmi_reg_get_voltage_sel,
	.set_voltage_sel = scmi_reg_set_voltage_sel,
	.list_voltage = regulator_list_voltage_table,
	.map_voltage = regulator_map_voltage_iterate,
};

static int
scmi_config_linear_regulator_mappings(struct scmi_regulator *sreg,
				      const struct scmi_voltage_info *vinfo)
{
	s32 delta_uV;

	/*
	 * Note that SCMI voltage domains describable by linear ranges
	 * (segments) {low, high, step} are guaranteed to come in one single
	 * triplet by the SCMI Voltage Domain protocol support itself.
	 */

	delta_uV = (vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH] -
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW]);

	/* Rule out buggy negative-intervals answers from fw */
	if (delta_uV < 0) {
		dev_err(&sreg->sdev->dev,
			"Invalid volt-range %d-%duV for domain %d\n",
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW],
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH],
			sreg->id);
		return -EINVAL;
	}

	if (!delta_uV) {
		/* Just one fixed voltage exposed by SCMI */
		sreg->desc.fixed_uV =
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW];
		sreg->desc.n_voltages = 1;
		sreg->desc.ops = &scmi_reg_fixed_ops;
	} else {
		/* One simple linear mapping. */
		sreg->desc.min_uV =
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW];
		sreg->desc.uV_step =
			vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_STEP];
		sreg->desc.linear_min_sel = 0;
		sreg->desc.n_voltages = (delta_uV / sreg->desc.uV_step) + 1;
		sreg->desc.ops = &scmi_reg_linear_ops;
	}

	return 0;
}

static int
scmi_config_discrete_regulator_mappings(struct scmi_regulator *sreg,
					const struct scmi_voltage_info *vinfo)
{
	/* Discrete non linear levels are mapped to volt_table */
	sreg->desc.n_voltages = vinfo->num_levels;

	if (sreg->desc.n_voltages > 1) {
		sreg->desc.volt_table = (const unsigned int *)vinfo->levels_uv;
		sreg->desc.ops = &scmi_reg_discrete_ops;
	} else {
		sreg->desc.fixed_uV = vinfo->levels_uv[0];
		sreg->desc.ops = &scmi_reg_fixed_ops;
	}

	return 0;
}

static int scmi_regulator_common_init(struct scmi_regulator *sreg)
{
	int ret;
	struct device *dev = &sreg->sdev->dev;
	const struct scmi_voltage_info *vinfo;

	vinfo = voltage_ops->info_get(sreg->ph, sreg->id);
	if (!vinfo) {
		dev_warn(dev, "Failure to get voltage domain %d\n",
			 sreg->id);
		return -ENODEV;
	}

	/*
	 * Regulator framework does not fully support negative voltages
	 * so we discard any voltage domain reported as supporting negative
	 * voltages: as a consequence each levels_uv entry is guaranteed to
	 * be non-negative from here on.
	 */
	if (vinfo->negative_volts_allowed) {
		dev_warn(dev, "Negative voltages NOT supported...skip %s\n",
			 sreg->of_node->full_name);
		return -EOPNOTSUPP;
	}

	sreg->desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s", vinfo->name);
	if (!sreg->desc.name)
		return -ENOMEM;

	sreg->desc.id = sreg->id;
	sreg->desc.type = REGULATOR_VOLTAGE;
	sreg->desc.owner = THIS_MODULE;
	sreg->desc.of_match_full_name = true;
	sreg->desc.of_match = sreg->of_node->full_name;
	sreg->desc.regulators_node = "regulators";
	if (vinfo->segmented)
		ret = scmi_config_linear_regulator_mappings(sreg, vinfo);
	else
		ret = scmi_config_discrete_regulator_mappings(sreg, vinfo);
	if (ret)
		return ret;

	/*
	 * Using the scmi device here to have DT searched from Voltage
	 * protocol node down.
	 */
	sreg->conf.dev = dev;

	/* Store for later retrieval via rdev_get_drvdata() */
	sreg->conf.driver_data = sreg;

	return 0;
}

static int process_scmi_regulator_of_node(struct scmi_device *sdev,
					  struct scmi_protocol_handle *ph,
					  struct device_node *np,
					  struct scmi_regulator_info *rinfo)
{
	u32 dom, ret;

	ret = of_property_read_u32(np, "reg", &dom);
	if (ret)
		return ret;

	if (dom >= rinfo->num_doms)
		return -ENODEV;

	if (rinfo->sregv[dom]) {
		dev_err(&sdev->dev,
			"SCMI Voltage Domain %d already in use. Skipping: %s\n",
			dom, np->full_name);
		return -EINVAL;
	}

	rinfo->sregv[dom] = devm_kzalloc(&sdev->dev,
					 sizeof(struct scmi_regulator),
					 GFP_KERNEL);
	if (!rinfo->sregv[dom])
		return -ENOMEM;

	rinfo->sregv[dom]->id = dom;
	rinfo->sregv[dom]->sdev = sdev;
	rinfo->sregv[dom]->ph = ph;

	/* get hold of good nodes */
	of_node_get(np);
	rinfo->sregv[dom]->of_node = np;

	dev_dbg(&sdev->dev,
		"Found SCMI Regulator entry -- OF node [%d] -> %s\n",
		dom, np->full_name);

	return 0;
}

static int scmi_regulator_probe(struct scmi_device *sdev)
{
	int d, ret, num_doms;
	struct device_node *np;
	const struct scmi_handle *handle = sdev->handle;
	struct scmi_regulator_info *rinfo;
	struct scmi_protocol_handle *ph;

	if (!handle)
		return -ENODEV;

	voltage_ops = handle->devm_protocol_get(sdev,
						SCMI_PROTOCOL_VOLTAGE, &ph);
	if (IS_ERR(voltage_ops))
		return PTR_ERR(voltage_ops);

	num_doms = voltage_ops->num_domains_get(ph);
	if (!num_doms)
		return 0;

	if (num_doms < 0) {
		dev_err(&sdev->dev, "failed to get voltage domains - err:%d\n",
			num_doms);

		return num_doms;
	}

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

	/* Allocate pointers array for all possible domains */
	rinfo->sregv = devm_kcalloc(&sdev->dev, num_doms,
				    sizeof(void *), GFP_KERNEL);
	if (!rinfo->sregv)
		return -ENOMEM;

	rinfo->num_doms = num_doms;

	/*
	 * Start collecting into rinfo->sregv possibly good SCMI Regulators as
	 * described by a well-formed DT entry and associated with an existing
	 * plausible SCMI Voltage Domain number, all belonging to this SCMI
	 * platform instance node (handle->dev->of_node).
	 */
	of_node_get(handle->dev->of_node);
	np = of_find_node_by_name(handle->dev->of_node, "regulators");
	for_each_child_of_node_scoped(np, child) {
		ret = process_scmi_regulator_of_node(sdev, ph, child, rinfo);
		/* abort on any mem issue */
		if (ret == -ENOMEM)
			return ret;
	}
	of_node_put(np);
	/*
	 * Register a regulator for each valid regulator-DT-entry that we
	 * can successfully reach via SCMI and has a valid associated voltage
	 * domain.
	 */
	for (d = 0; d < num_doms; d++) {
		struct scmi_regulator *sreg = rinfo->sregv[d];

		/* Skip empty slots */
		if (!sreg)
			continue;

		ret = scmi_regulator_common_init(sreg);
		/* Skip invalid voltage domains */
		if (ret)
			continue;

		sreg->rdev = devm_regulator_register(&sdev->dev, &sreg->desc,
						     &sreg->conf);
		if (IS_ERR(sreg->rdev)) {
			sreg->rdev = NULL;
			continue;
		}

		dev_info(&sdev->dev,
			 "Regulator %s registered for domain [%d]\n",
			 sreg->desc.name, sreg->id);
	}

	dev_set_drvdata(&sdev->dev, rinfo);

	return 0;
}

static void scmi_regulator_remove(struct scmi_device *sdev)
{
	int d;
	struct scmi_regulator_info *rinfo;

	rinfo = dev_get_drvdata(&sdev->dev);
	if (!rinfo)
		return;

	for (d = 0; d < rinfo->num_doms; d++) {
		if (!rinfo->sregv[d])
			continue;
		of_node_put(rinfo->sregv[d]->of_node);
	}
}

static const struct scmi_device_id scmi_regulator_id_table[] = {
	{ SCMI_PROTOCOL_VOLTAGE,  "regulator" },
	{ },
};
MODULE_DEVICE_TABLE(scmi, scmi_regulator_id_table);

static struct scmi_driver scmi_drv = {
	.name		= "scmi-regulator",
	.probe		= scmi_regulator_probe,
	.remove		= scmi_regulator_remove,
	.id_table	= scmi_regulator_id_table,
};

module_scmi_driver(scmi_drv);

MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
MODULE_DESCRIPTION("ARM SCMI regulator driver");
MODULE_LICENSE("GPL v2");
