// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Management Interface (SCMI) Voltage Protocol
 *
 * Copyright (C) 2020-2022 ARM Ltd.
 */

#include <linux/module.h>
#include <linux/scmi_protocol.h>

#include "protocols.h"

#define VOLTAGE_DOMS_NUM_MASK		GENMASK(15, 0)
#define REMAINING_LEVELS_MASK		GENMASK(31, 16)
#define RETURNED_LEVELS_MASK		GENMASK(11, 0)

enum scmi_voltage_protocol_cmd {
	VOLTAGE_DOMAIN_ATTRIBUTES = 0x3,
	VOLTAGE_DESCRIBE_LEVELS = 0x4,
	VOLTAGE_CONFIG_SET = 0x5,
	VOLTAGE_CONFIG_GET = 0x6,
	VOLTAGE_LEVEL_SET = 0x7,
	VOLTAGE_LEVEL_GET = 0x8,
	VOLTAGE_DOMAIN_NAME_GET = 0x09,
};

#define NUM_VOLTAGE_DOMAINS(x)	((u16)(FIELD_GET(VOLTAGE_DOMS_NUM_MASK, (x))))

struct scmi_msg_resp_domain_attributes {
	__le32 attr;
#define SUPPORTS_ASYNC_LEVEL_SET(x)	((x) & BIT(31))
#define SUPPORTS_EXTENDED_NAMES(x)	((x) & BIT(30))
	u8 name[SCMI_SHORT_NAME_MAX_SIZE];
};

struct scmi_msg_cmd_describe_levels {
	__le32 domain_id;
	__le32 level_index;
};

struct scmi_msg_resp_describe_levels {
	__le32 flags;
#define NUM_REMAINING_LEVELS(f)	((u16)(FIELD_GET(REMAINING_LEVELS_MASK, (f))))
#define NUM_RETURNED_LEVELS(f)	((u16)(FIELD_GET(RETURNED_LEVELS_MASK, (f))))
#define SUPPORTS_SEGMENTED_LEVELS(f)	((f) & BIT(12))
	__le32 voltage[];
};

struct scmi_msg_cmd_config_set {
	__le32 domain_id;
	__le32 config;
};

struct scmi_msg_cmd_level_set {
	__le32 domain_id;
	__le32 flags;
	__le32 voltage_level;
};

struct scmi_resp_voltage_level_set_complete {
	__le32 domain_id;
	__le32 voltage_level;
};

struct voltage_info {
	unsigned int version;
	unsigned int num_domains;
	struct scmi_voltage_info *domains;
};

static int scmi_protocol_attributes_get(const struct scmi_protocol_handle *ph,
					struct voltage_info *vinfo)
{
	int ret;
	struct scmi_xfer *t;

	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
				      sizeof(__le32), &t);
	if (ret)
		return ret;

	ret = ph->xops->do_xfer(ph, t);
	if (!ret)
		vinfo->num_domains =
			NUM_VOLTAGE_DOMAINS(get_unaligned_le32(t->rx.buf));

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int scmi_init_voltage_levels(struct device *dev,
				    struct scmi_voltage_info *v,
				    u32 num_returned, u32 num_remaining,
				    bool segmented)
{
	u32 num_levels;

	num_levels = num_returned + num_remaining;
	/*
	 * segmented levels entries are represented by a single triplet
	 * returned all in one go.
	 */
	if (!num_levels ||
	    (segmented && (num_remaining || num_returned != 3))) {
		dev_err(dev,
			"Invalid level descriptor(%d/%d/%d) for voltage dom %d\n",
			num_levels, num_returned, num_remaining, v->id);
		return -EINVAL;
	}

	v->levels_uv = devm_kcalloc(dev, num_levels, sizeof(u32), GFP_KERNEL);
	if (!v->levels_uv)
		return -ENOMEM;

	v->num_levels = num_levels;
	v->segmented = segmented;

	return 0;
}

struct scmi_volt_ipriv {
	struct device *dev;
	struct scmi_voltage_info *v;
};

static void iter_volt_levels_prepare_message(void *message,
					     unsigned int desc_index,
					     const void *priv)
{
	struct scmi_msg_cmd_describe_levels *msg = message;
	const struct scmi_volt_ipriv *p = priv;

	msg->domain_id = cpu_to_le32(p->v->id);
	msg->level_index = cpu_to_le32(desc_index);
}

static int iter_volt_levels_update_state(struct scmi_iterator_state *st,
					 const void *response, void *priv)
{
	int ret = 0;
	u32 flags;
	const struct scmi_msg_resp_describe_levels *r = response;
	struct scmi_volt_ipriv *p = priv;

	flags = le32_to_cpu(r->flags);
	st->num_returned = NUM_RETURNED_LEVELS(flags);
	st->num_remaining = NUM_REMAINING_LEVELS(flags);

	/* Allocate space for num_levels if not already done */
	if (!p->v->num_levels) {
		ret = scmi_init_voltage_levels(p->dev, p->v, st->num_returned,
					       st->num_remaining,
					      SUPPORTS_SEGMENTED_LEVELS(flags));
		if (!ret)
			st->max_resources = p->v->num_levels;
	}

	return ret;
}

static int
iter_volt_levels_process_response(const struct scmi_protocol_handle *ph,
				  const void *response,
				  struct scmi_iterator_state *st, void *priv)
{
	s32 val;
	const struct scmi_msg_resp_describe_levels *r = response;
	struct scmi_volt_ipriv *p = priv;

	val = (s32)le32_to_cpu(r->voltage[st->loop_idx]);
	p->v->levels_uv[st->desc_index + st->loop_idx] = val;
	if (val < 0)
		p->v->negative_volts_allowed = true;

	return 0;
}

static int scmi_voltage_levels_get(const struct scmi_protocol_handle *ph,
				   struct scmi_voltage_info *v)
{
	int ret;
	void *iter;
	struct scmi_iterator_ops ops = {
		.prepare_message = iter_volt_levels_prepare_message,
		.update_state = iter_volt_levels_update_state,
		.process_response = iter_volt_levels_process_response,
	};
	struct scmi_volt_ipriv vpriv = {
		.dev = ph->dev,
		.v = v,
	};

	iter = ph->hops->iter_response_init(ph, &ops, v->num_levels,
					    VOLTAGE_DESCRIBE_LEVELS,
					    sizeof(struct scmi_msg_cmd_describe_levels),
					    &vpriv);
	if (IS_ERR(iter))
		return PTR_ERR(iter);

	ret = ph->hops->iter_response_run(iter);
	if (ret) {
		v->num_levels = 0;
		devm_kfree(ph->dev, v->levels_uv);
	}

	return ret;
}

static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph,
					struct voltage_info *vinfo)
{
	int ret, dom;
	struct scmi_xfer *td;
	struct scmi_msg_resp_domain_attributes *resp_dom;

	ret = ph->xops->xfer_get_init(ph, VOLTAGE_DOMAIN_ATTRIBUTES,
				      sizeof(__le32), sizeof(*resp_dom), &td);
	if (ret)
		return ret;
	resp_dom = td->rx.buf;

	for (dom = 0; dom < vinfo->num_domains; dom++) {
		u32 attributes;
		struct scmi_voltage_info *v;

		/* Retrieve domain attributes at first ... */
		put_unaligned_le32(dom, td->tx.buf);
		/* Skip domain on comms error */
		if (ph->xops->do_xfer(ph, td))
			continue;

		v = vinfo->domains + dom;
		v->id = dom;
		attributes = le32_to_cpu(resp_dom->attr);
		strscpy(v->name, resp_dom->name, SCMI_SHORT_NAME_MAX_SIZE);

		/*
		 * If supported overwrite short name with the extended one;
		 * on error just carry on and use already provided short name.
		 */
		if (PROTOCOL_REV_MAJOR(vinfo->version) >= 0x2) {
			if (SUPPORTS_EXTENDED_NAMES(attributes))
				ph->hops->extended_name_get(ph,
							VOLTAGE_DOMAIN_NAME_GET,
							v->id, v->name,
							SCMI_MAX_STR_SIZE);
			if (SUPPORTS_ASYNC_LEVEL_SET(attributes))
				v->async_level_set = true;
		}

		/* Skip invalid voltage descriptors */
		scmi_voltage_levels_get(ph, v);
	}

	ph->xops->xfer_put(ph, td);

	return ret;
}

static int __scmi_voltage_get_u32(const struct scmi_protocol_handle *ph,
				  u8 cmd_id, u32 domain_id, u32 *value)
{
	int ret;
	struct scmi_xfer *t;
	struct voltage_info *vinfo = ph->get_priv(ph);

	if (domain_id >= vinfo->num_domains)
		return -EINVAL;

	ret = ph->xops->xfer_get_init(ph, cmd_id, sizeof(__le32), 0, &t);
	if (ret)
		return ret;

	put_unaligned_le32(domain_id, t->tx.buf);
	ret = ph->xops->do_xfer(ph, t);
	if (!ret)
		*value = get_unaligned_le32(t->rx.buf);

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int scmi_voltage_config_set(const struct scmi_protocol_handle *ph,
				   u32 domain_id, u32 config)
{
	int ret;
	struct scmi_xfer *t;
	struct voltage_info *vinfo = ph->get_priv(ph);
	struct scmi_msg_cmd_config_set *cmd;

	if (domain_id >= vinfo->num_domains)
		return -EINVAL;

	ret = ph->xops->xfer_get_init(ph, VOLTAGE_CONFIG_SET,
				     sizeof(*cmd), 0, &t);
	if (ret)
		return ret;

	cmd = t->tx.buf;
	cmd->domain_id = cpu_to_le32(domain_id);
	cmd->config = cpu_to_le32(config & GENMASK(3, 0));

	ret = ph->xops->do_xfer(ph, t);

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int scmi_voltage_config_get(const struct scmi_protocol_handle *ph,
				   u32 domain_id, u32 *config)
{
	return __scmi_voltage_get_u32(ph, VOLTAGE_CONFIG_GET,
				      domain_id, config);
}

static int scmi_voltage_level_set(const struct scmi_protocol_handle *ph,
				  u32 domain_id,
				  enum scmi_voltage_level_mode mode,
				  s32 volt_uV)
{
	int ret;
	struct scmi_xfer *t;
	struct voltage_info *vinfo = ph->get_priv(ph);
	struct scmi_msg_cmd_level_set *cmd;
	struct scmi_voltage_info *v;

	if (domain_id >= vinfo->num_domains)
		return -EINVAL;

	ret = ph->xops->xfer_get_init(ph, VOLTAGE_LEVEL_SET,
				      sizeof(*cmd), 0, &t);
	if (ret)
		return ret;

	v = vinfo->domains + domain_id;

	cmd = t->tx.buf;
	cmd->domain_id = cpu_to_le32(domain_id);
	cmd->voltage_level = cpu_to_le32(volt_uV);

	if (!v->async_level_set || mode != SCMI_VOLTAGE_LEVEL_SET_AUTO) {
		cmd->flags = cpu_to_le32(0x0);
		ret = ph->xops->do_xfer(ph, t);
	} else {
		cmd->flags = cpu_to_le32(0x1);
		ret = ph->xops->do_xfer_with_response(ph, t);
		if (!ret) {
			struct scmi_resp_voltage_level_set_complete *resp;

			resp = t->rx.buf;
			if (le32_to_cpu(resp->domain_id) == domain_id)
				dev_dbg(ph->dev,
					"Voltage domain %d set async to %d\n",
					v->id,
					le32_to_cpu(resp->voltage_level));
			else
				ret = -EPROTO;
		}
	}

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int scmi_voltage_level_get(const struct scmi_protocol_handle *ph,
				  u32 domain_id, s32 *volt_uV)
{
	return __scmi_voltage_get_u32(ph, VOLTAGE_LEVEL_GET,
				      domain_id, (u32 *)volt_uV);
}

static const struct scmi_voltage_info * __must_check
scmi_voltage_info_get(const struct scmi_protocol_handle *ph, u32 domain_id)
{
	struct voltage_info *vinfo = ph->get_priv(ph);

	if (domain_id >= vinfo->num_domains ||
	    !vinfo->domains[domain_id].num_levels)
		return NULL;

	return vinfo->domains + domain_id;
}

static int scmi_voltage_domains_num_get(const struct scmi_protocol_handle *ph)
{
	struct voltage_info *vinfo = ph->get_priv(ph);

	return vinfo->num_domains;
}

static struct scmi_voltage_proto_ops voltage_proto_ops = {
	.num_domains_get = scmi_voltage_domains_num_get,
	.info_get = scmi_voltage_info_get,
	.config_set = scmi_voltage_config_set,
	.config_get = scmi_voltage_config_get,
	.level_set = scmi_voltage_level_set,
	.level_get = scmi_voltage_level_get,
};

static int scmi_voltage_protocol_init(const struct scmi_protocol_handle *ph)
{
	int ret;
	u32 version;
	struct voltage_info *vinfo;

	ret = ph->xops->version_get(ph, &version);
	if (ret)
		return ret;

	dev_dbg(ph->dev, "Voltage Version %d.%d\n",
		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));

	vinfo = devm_kzalloc(ph->dev, sizeof(*vinfo), GFP_KERNEL);
	if (!vinfo)
		return -ENOMEM;
	vinfo->version = version;

	ret = scmi_protocol_attributes_get(ph, vinfo);
	if (ret)
		return ret;

	if (vinfo->num_domains) {
		vinfo->domains = devm_kcalloc(ph->dev, vinfo->num_domains,
					      sizeof(*vinfo->domains),
					      GFP_KERNEL);
		if (!vinfo->domains)
			return -ENOMEM;
		ret = scmi_voltage_descriptors_get(ph, vinfo);
		if (ret)
			return ret;
	} else {
		dev_warn(ph->dev, "No Voltage domains found.\n");
	}

	return ph->set_priv(ph, vinfo);
}

static const struct scmi_protocol scmi_voltage = {
	.id = SCMI_PROTOCOL_VOLTAGE,
	.owner = THIS_MODULE,
	.instance_init = &scmi_voltage_protocol_init,
	.ops = &voltage_proto_ops,
};

DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(voltage, scmi_voltage)
