// SPDX-License-Identifier: GPL-2.0
/*
 * Zynq UltraScale+ MPSoC clock controller
 *
 *  Copyright (C) 2016-2018 Xilinx
 *
 * Based on drivers/clk/zynq/clkc.c
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/string.h>

#include "clk-zynqmp.h"

#define MAX_PARENT			100
#define MAX_NODES			6
#define MAX_NAME_LEN			50

/* Flags for parents */
#define PARENT_CLK_SELF			0
#define PARENT_CLK_NODE1		1
#define PARENT_CLK_NODE2		2
#define PARENT_CLK_NODE3		3
#define PARENT_CLK_NODE4		4
#define PARENT_CLK_EXTERNAL		5

#define END_OF_CLK_NAME			"END_OF_CLK"
#define END_OF_TOPOLOGY_NODE		1
#define END_OF_PARENTS			1
#define RESERVED_CLK_NAME		""

#define CLK_GET_NAME_RESP_LEN		16
#define CLK_GET_TOPOLOGY_RESP_WORDS	3
#define CLK_GET_PARENTS_RESP_WORDS	3
#define CLK_GET_ATTR_RESP_WORDS		1

enum clk_type {
	CLK_TYPE_OUTPUT,
	CLK_TYPE_EXTERNAL,
};

/**
 * struct clock_parent - Clock parent
 * @name:	Parent name
 * @id:		Parent clock ID
 * @flag:	Parent flags
 */
struct clock_parent {
	char name[MAX_NAME_LEN];
	int id;
	u32 flag;
};

/**
 * struct zynqmp_clock - Clock
 * @clk_name:		Clock name
 * @valid:		Validity flag of clock
 * @type:		Clock type (Output/External)
 * @node:		Clock topology nodes
 * @num_nodes:		Number of nodes present in topology
 * @parent:		Parent of clock
 * @num_parents:	Number of parents of clock
 * @clk_id:		Clock id
 */
struct zynqmp_clock {
	char clk_name[MAX_NAME_LEN];
	u32 valid;
	enum clk_type type;
	struct clock_topology node[MAX_NODES];
	u32 num_nodes;
	struct clock_parent parent[MAX_PARENT];
	u32 num_parents;
	u32 clk_id;
};

struct name_resp {
	char name[CLK_GET_NAME_RESP_LEN];
};

struct topology_resp {
#define CLK_TOPOLOGY_TYPE		GENMASK(3, 0)
#define CLK_TOPOLOGY_FLAGS		GENMASK(23, 8)
#define CLK_TOPOLOGY_TYPE_FLAGS		GENMASK(31, 24)
	u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
};

struct parents_resp {
#define NA_PARENT			0xFFFFFFFF
#define DUMMY_PARENT			0xFFFFFFFE
#define CLK_PARENTS_ID			GENMASK(15, 0)
#define CLK_PARENTS_FLAGS		GENMASK(31, 16)
	u32 parents[CLK_GET_PARENTS_RESP_WORDS];
};

struct attr_resp {
#define CLK_ATTR_VALID			BIT(0)
#define CLK_ATTR_TYPE			BIT(2)
#define CLK_ATTR_NODE_INDEX		GENMASK(13, 0)
#define CLK_ATTR_NODE_TYPE		GENMASK(19, 14)
#define CLK_ATTR_NODE_SUBCLASS		GENMASK(25, 20)
#define CLK_ATTR_NODE_CLASS		GENMASK(31, 26)
	u32 attr[CLK_GET_ATTR_RESP_WORDS];
};

static const char clk_type_postfix[][10] = {
	[TYPE_INVALID] = "",
	[TYPE_MUX] = "_mux",
	[TYPE_GATE] = "",
	[TYPE_DIV1] = "_div1",
	[TYPE_DIV2] = "_div2",
	[TYPE_FIXEDFACTOR] = "_ff",
	[TYPE_PLL] = ""
};

static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,
					const char * const *parents,
					u8 num_parents,
					const struct clock_topology *nodes)
					= {
	[TYPE_INVALID] = NULL,
	[TYPE_MUX] = zynqmp_clk_register_mux,
	[TYPE_PLL] = zynqmp_clk_register_pll,
	[TYPE_FIXEDFACTOR] = zynqmp_clk_register_fixed_factor,
	[TYPE_DIV1] = zynqmp_clk_register_divider,
	[TYPE_DIV2] = zynqmp_clk_register_divider,
	[TYPE_GATE] = zynqmp_clk_register_gate
};

static struct zynqmp_clock *clock;
static struct clk_hw_onecell_data *zynqmp_data;
static unsigned int clock_max_idx;
static const struct zynqmp_eemi_ops *eemi_ops;

/**
 * zynqmp_is_valid_clock() - Check whether clock is valid or not
 * @clk_id:	Clock index
 *
 * Return: 1 if clock is valid, 0 if clock is invalid else error code
 */
static inline int zynqmp_is_valid_clock(u32 clk_id)
{
	if (clk_id >= clock_max_idx)
		return -ENODEV;

	return clock[clk_id].valid;
}

/**
 * zynqmp_get_clock_name() - Get name of clock from Clock index
 * @clk_id:	Clock index
 * @clk_name:	Name of clock
 *
 * Return: 0 on success else error code
 */
static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
{
	int ret;

	ret = zynqmp_is_valid_clock(clk_id);
	if (ret == 1) {
		strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
		return 0;
	}

	return ret == 0 ? -EINVAL : ret;
}

/**
 * zynqmp_get_clock_type() - Get type of clock
 * @clk_id:	Clock index
 * @type:	Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL
 *
 * Return: 0 on success else error code
 */
static int zynqmp_get_clock_type(u32 clk_id, u32 *type)
{
	int ret;

	ret = zynqmp_is_valid_clock(clk_id);
	if (ret == 1) {
		*type = clock[clk_id].type;
		return 0;
	}

	return ret == 0 ? -EINVAL : ret;
}

/**
 * zynqmp_pm_clock_get_num_clocks() - Get number of clocks in system
 * @nclocks:	Number of clocks in system/board.
 *
 * Call firmware API to get number of clocks.
 *
 * Return: 0 on success else error code.
 */
static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_NUM_CLOCKS;

	ret = eemi_ops->query_data(qdata, ret_payload);
	*nclocks = ret_payload[1];

	return ret;
}

/**
 * zynqmp_pm_clock_get_name() - Get the name of clock for given id
 * @clock_id:	ID of the clock to be queried
 * @response:	Name of the clock with the given id
 *
 * This function is used to get name of clock specified by given
 * clock ID.
 *
 * Return: Returns 0
 */
static int zynqmp_pm_clock_get_name(u32 clock_id,
				    struct name_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];

	qdata.qid = PM_QID_CLOCK_GET_NAME;
	qdata.arg1 = clock_id;

	eemi_ops->query_data(qdata, ret_payload);
	memcpy(response, ret_payload, sizeof(*response));

	return 0;
}

/**
 * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
 * @clock_id:	ID of the clock to be queried
 * @index:	Node index of clock topology
 * @response:	Buffer used for the topology response
 *
 * This function is used to get topology information for the clock
 * specified by given clock ID.
 *
 * This API will return 3 node of topology with a single response. To get
 * other nodes, master should call same API in loop with new
 * index till error is returned. E.g First call should have
 * index 0 which will return nodes 0,1 and 2. Next call, index
 * should be 3 which will return nodes 3,4 and 5 and so on.
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index,
					struct topology_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY;
	qdata.arg1 = clock_id;
	qdata.arg2 = index;

	ret = eemi_ops->query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

/**
 * zynqmp_clk_register_fixed_factor() - Register fixed factor with the
 *					clock framework
 * @name:		Name of this clock
 * @clk_id:		Clock ID
 * @parents:		Name of this clock's parents
 * @num_parents:	Number of parents
 * @nodes:		Clock topology node
 *
 * Return: clock hardware to the registered clock
 */
struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
					const char * const *parents,
					u8 num_parents,
					const struct clock_topology *nodes)
{
	u32 mult, div;
	struct clk_hw *hw;
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
	qdata.arg1 = clk_id;

	ret = eemi_ops->query_data(qdata, ret_payload);
	if (ret)
		return ERR_PTR(ret);

	mult = ret_payload[1];
	div = ret_payload[2];

	hw = clk_hw_register_fixed_factor(NULL, name,
					  parents[0],
					  nodes->flag, mult,
					  div);

	return hw;
}

/**
 * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
 * @clock_id:	Clock ID
 * @index:	Parent index
 * @response:	Parents of the given clock
 *
 * This function is used to get 3 parents for the clock specified by
 * given clock ID.
 *
 * This API will return 3 parents with a single response. To get
 * other parents, master should call same API in loop with new
 * parent index till error is returned. E.g First call should have
 * index 0 which will return parents 0,1 and 2. Next call, index
 * should be 3 which will return parent 3,4 and 5 and so on.
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index,
				       struct parents_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_PARENTS;
	qdata.arg1 = clock_id;
	qdata.arg2 = index;

	ret = eemi_ops->query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

/**
 * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
 * @clock_id:	Clock ID
 * @response:	Clock attributes response
 *
 * This function is used to get clock's attributes(e.g. valid, clock type, etc).
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_attributes(u32 clock_id,
					  struct attr_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES;
	qdata.arg1 = clock_id;

	ret = eemi_ops->query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

/**
 * __zynqmp_clock_get_topology() - Get topology data of clock from firmware
 *				   response data
 * @topology:		Clock topology
 * @response:		Clock topology data received from firmware
 * @nnodes:		Number of nodes
 *
 * Return: 0 on success else error+reason
 */
static int __zynqmp_clock_get_topology(struct clock_topology *topology,
				       struct topology_resp *response,
				       u32 *nnodes)
{
	int i;
	u32 type;

	for (i = 0; i < ARRAY_SIZE(response->topology); i++) {
		type = FIELD_GET(CLK_TOPOLOGY_TYPE, response->topology[i]);
		if (type == TYPE_INVALID)
			return END_OF_TOPOLOGY_NODE;
		topology[*nnodes].type = type;
		topology[*nnodes].flag = FIELD_GET(CLK_TOPOLOGY_FLAGS,
						   response->topology[i]);
		topology[*nnodes].type_flag =
				FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
					  response->topology[i]);
		(*nnodes)++;
	}

	return 0;
}

/**
 * zynqmp_clock_get_topology() - Get topology of clock from firmware using
 *				 PM_API
 * @clk_id:		Clock index
 * @topology:		Clock topology
 * @num_nodes:		Number of nodes
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_clock_get_topology(u32 clk_id,
				     struct clock_topology *topology,
				     u32 *num_nodes)
{
	int j, ret;
	struct topology_resp response = { };

	*num_nodes = 0;
	for (j = 0; j <= MAX_NODES; j += ARRAY_SIZE(response.topology)) {
		ret = zynqmp_pm_clock_get_topology(clock[clk_id].clk_id, j,
						   &response);
		if (ret)
			return ret;
		ret = __zynqmp_clock_get_topology(topology, &response,
						  num_nodes);
		if (ret == END_OF_TOPOLOGY_NODE)
			return 0;
	}

	return 0;
}

/**
 * __zynqmp_clock_get_parents() - Get parents info of clock from firmware
 *				   response data
 * @parents:		Clock parents
 * @response:		Clock parents data received from firmware
 * @nparent:		Number of parent
 *
 * Return: 0 on success else error+reason
 */
static int __zynqmp_clock_get_parents(struct clock_parent *parents,
				      struct parents_resp *response,
				      u32 *nparent)
{
	int i;
	struct clock_parent *parent;

	for (i = 0; i < ARRAY_SIZE(response->parents); i++) {
		if (response->parents[i] == NA_PARENT)
			return END_OF_PARENTS;

		parent = &parents[i];
		parent->id = FIELD_GET(CLK_PARENTS_ID, response->parents[i]);
		if (response->parents[i] == DUMMY_PARENT) {
			strcpy(parent->name, "dummy_name");
			parent->flag = 0;
		} else {
			parent->flag = FIELD_GET(CLK_PARENTS_FLAGS,
						 response->parents[i]);
			if (zynqmp_get_clock_name(parent->id, parent->name))
				continue;
		}
		*nparent += 1;
	}

	return 0;
}

/**
 * zynqmp_clock_get_parents() - Get parents info from firmware using PM_API
 * @clk_id:		Clock index
 * @parents:		Clock parents
 * @num_parents:	Total number of parents
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
				    u32 *num_parents)
{
	int j = 0, ret;
	struct parents_resp response = { };

	*num_parents = 0;
	do {
		/* Get parents from firmware */
		ret = zynqmp_pm_clock_get_parents(clock[clk_id].clk_id, j,
						  &response);
		if (ret)
			return ret;

		ret = __zynqmp_clock_get_parents(&parents[j], &response,
						 num_parents);
		if (ret == END_OF_PARENTS)
			return 0;
		j += ARRAY_SIZE(response.parents);
	} while (*num_parents <= MAX_PARENT);

	return 0;
}

/**
 * zynqmp_get_parent_list() - Create list of parents name
 * @np:			Device node
 * @clk_id:		Clock index
 * @parent_list:	List of parent's name
 * @num_parents:	Total number of parents
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
				  const char **parent_list, u32 *num_parents)
{
	int i = 0, ret;
	u32 total_parents = clock[clk_id].num_parents;
	struct clock_topology *clk_nodes;
	struct clock_parent *parents;

	clk_nodes = clock[clk_id].node;
	parents = clock[clk_id].parent;

	for (i = 0; i < total_parents; i++) {
		if (!parents[i].flag) {
			parent_list[i] = parents[i].name;
		} else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
			ret = of_property_match_string(np, "clock-names",
						       parents[i].name);
			if (ret < 0)
				strcpy(parents[i].name, "dummy_name");
			parent_list[i] = parents[i].name;
		} else {
			strcat(parents[i].name,
			       clk_type_postfix[clk_nodes[parents[i].flag - 1].
			       type]);
			parent_list[i] = parents[i].name;
		}
	}

	*num_parents = total_parents;
	return 0;
}

/**
 * zynqmp_register_clk_topology() - Register clock topology
 * @clk_id:		Clock index
 * @clk_name:		Clock Name
 * @num_parents:	Total number of parents
 * @parent_names:	List of parents name
 *
 * Return: Returns either clock hardware or error+reason
 */
static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
						   int num_parents,
						   const char **parent_names)
{
	int j;
	u32 num_nodes, clk_dev_id;
	char *clk_out = NULL;
	struct clock_topology *nodes;
	struct clk_hw *hw = NULL;

	nodes = clock[clk_id].node;
	num_nodes = clock[clk_id].num_nodes;
	clk_dev_id = clock[clk_id].clk_id;

	for (j = 0; j < num_nodes; j++) {
		/*
		 * Clock name received from firmware is output clock name.
		 * Intermediate clock names are postfixed with type of clock.
		 */
		if (j != (num_nodes - 1)) {
			clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
					    clk_type_postfix[nodes[j].type]);
		} else {
			clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
		}

		if (!clk_topology[nodes[j].type])
			continue;

		hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
						    parent_names,
						    num_parents,
						    &nodes[j]);
		if (IS_ERR(hw))
			pr_warn_once("%s() 0x%x: %s register fail with %ld\n",
				     __func__,  clk_dev_id, clk_name,
				     PTR_ERR(hw));

		parent_names[0] = clk_out;
	}
	kfree(clk_out);
	return hw;
}

/**
 * zynqmp_register_clocks() - Register clocks
 * @np:		Device node
 *
 * Return: 0 on success else error code
 */
static int zynqmp_register_clocks(struct device_node *np)
{
	int ret;
	u32 i, total_parents = 0, type = 0;
	const char *parent_names[MAX_PARENT];

	for (i = 0; i < clock_max_idx; i++) {
		char clk_name[MAX_NAME_LEN];

		/* get clock name, continue to next clock if name not found */
		if (zynqmp_get_clock_name(i, clk_name))
			continue;

		/* Check if clock is valid and output clock.
		 * Do not register invalid or external clock.
		 */
		ret = zynqmp_get_clock_type(i, &type);
		if (ret || type != CLK_TYPE_OUTPUT)
			continue;

		/* Get parents of clock*/
		if (zynqmp_get_parent_list(np, i, parent_names,
					   &total_parents)) {
			WARN_ONCE(1, "No parents found for %s\n",
				  clock[i].clk_name);
			continue;
		}

		zynqmp_data->hws[i] =
			zynqmp_register_clk_topology(i, clk_name,
						     total_parents,
						     parent_names);
	}

	for (i = 0; i < clock_max_idx; i++) {
		if (IS_ERR(zynqmp_data->hws[i])) {
			pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n",
			       clock[i].clk_name, PTR_ERR(zynqmp_data->hws[i]));
			WARN_ON(1);
		}
	}
	return 0;
}

/**
 * zynqmp_get_clock_info() - Get clock information from firmware using PM_API
 */
static void zynqmp_get_clock_info(void)
{
	int i, ret;
	u32 type = 0;
	u32 nodetype, subclass, class;
	struct attr_resp attr;
	struct name_resp name;

	for (i = 0; i < clock_max_idx; i++) {
		ret = zynqmp_pm_clock_get_attributes(i, &attr);
		if (ret)
			continue;

		clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
		clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
			CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;

		nodetype = FIELD_GET(CLK_ATTR_NODE_TYPE, attr.attr[0]);
		subclass = FIELD_GET(CLK_ATTR_NODE_SUBCLASS, attr.attr[0]);
		class = FIELD_GET(CLK_ATTR_NODE_CLASS, attr.attr[0]);

		clock[i].clk_id = FIELD_PREP(CLK_ATTR_NODE_CLASS, class) |
				  FIELD_PREP(CLK_ATTR_NODE_SUBCLASS, subclass) |
				  FIELD_PREP(CLK_ATTR_NODE_TYPE, nodetype) |
				  FIELD_PREP(CLK_ATTR_NODE_INDEX, i);

		zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
		if (!strcmp(name.name, RESERVED_CLK_NAME))
			continue;
		strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
	}

	/* Get topology of all clock */
	for (i = 0; i < clock_max_idx; i++) {
		ret = zynqmp_get_clock_type(i, &type);
		if (ret || type != CLK_TYPE_OUTPUT)
			continue;

		ret = zynqmp_clock_get_topology(i, clock[i].node,
						&clock[i].num_nodes);
		if (ret)
			continue;

		ret = zynqmp_clock_get_parents(i, clock[i].parent,
					       &clock[i].num_parents);
		if (ret)
			continue;
	}
}

/**
 * zynqmp_clk_setup() - Setup the clock framework and register clocks
 * @np:		Device node
 *
 * Return: 0 on success else error code
 */
static int zynqmp_clk_setup(struct device_node *np)
{
	int ret;

	ret = zynqmp_pm_clock_get_num_clocks(&clock_max_idx);
	if (ret)
		return ret;

	zynqmp_data = kzalloc(struct_size(zynqmp_data, hws, clock_max_idx),
			      GFP_KERNEL);
	if (!zynqmp_data)
		return -ENOMEM;

	clock = kcalloc(clock_max_idx, sizeof(*clock), GFP_KERNEL);
	if (!clock) {
		kfree(zynqmp_data);
		return -ENOMEM;
	}

	zynqmp_get_clock_info();
	zynqmp_register_clocks(np);

	zynqmp_data->num = clock_max_idx;
	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, zynqmp_data);

	return 0;
}

static int zynqmp_clock_probe(struct platform_device *pdev)
{
	int ret;
	struct device *dev = &pdev->dev;

	eemi_ops = zynqmp_pm_get_eemi_ops();
	if (IS_ERR(eemi_ops))
		return PTR_ERR(eemi_ops);

	ret = zynqmp_clk_setup(dev->of_node);

	return ret;
}

static const struct of_device_id zynqmp_clock_of_match[] = {
	{.compatible = "xlnx,zynqmp-clk"},
	{},
};
MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match);

static struct platform_driver zynqmp_clock_driver = {
	.driver = {
		.name = "zynqmp_clock",
		.of_match_table = zynqmp_clock_of_match,
	},
	.probe = zynqmp_clock_probe,
};
module_platform_driver(zynqmp_clock_driver);
