/*
 * Copyright (C) 2016 NVIDIA Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/seq_buf.h>
#include <linux/slab.h>

#include <soc/tegra/bpmp.h>
#include <soc/tegra/bpmp-abi.h>

#define TEGRA_BPMP_DUMP_CLOCK_INFO	0

#define TEGRA_BPMP_CLK_HAS_MUX		BIT(0)
#define TEGRA_BPMP_CLK_HAS_SET_RATE	BIT(1)
#define TEGRA_BPMP_CLK_IS_ROOT		BIT(2)

struct tegra_bpmp_clk_info {
	unsigned int id;
	char name[MRQ_CLK_NAME_MAXLEN];
	unsigned int parents[MRQ_CLK_MAX_PARENTS];
	unsigned int num_parents;
	unsigned long flags;
};

struct tegra_bpmp_clk {
	struct clk_hw hw;

	struct tegra_bpmp *bpmp;
	unsigned int id;

	unsigned int num_parents;
	unsigned int *parents;
};

static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
{
	return container_of(hw, struct tegra_bpmp_clk, hw);
}

struct tegra_bpmp_clk_message {
	unsigned int cmd;
	unsigned int id;

	struct {
		const void *data;
		size_t size;
	} tx;

	struct {
		void *data;
		size_t size;
	} rx;
};

static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
				   const struct tegra_bpmp_clk_message *clk)
{
	struct mrq_clk_request request;
	struct tegra_bpmp_message msg;
	void *req = &request;

	memset(&request, 0, sizeof(request));
	request.cmd_and_id = (clk->cmd << 24) | clk->id;

	/*
	 * The mrq_clk_request structure has an anonymous union at offset 4
	 * that contains all possible sub-command structures. Copy the data
	 * to that union. Ideally we'd be able to refer to it by name, but
	 * doing so would require changing the ABI header and increase the
	 * maintenance burden.
	 */
	memcpy(req + 4, clk->tx.data, clk->tx.size);

	memset(&msg, 0, sizeof(msg));
	msg.mrq = MRQ_CLK;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = clk->rx.data;
	msg.rx.size = clk->rx.size;

	return tegra_bpmp_transfer(bpmp, &msg);
}

static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct tegra_bpmp_clk_message msg;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_ENABLE;
	msg.id = clk->id;

	return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
}

static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_DISABLE;
	msg.id = clk->id;

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0)
		dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
			clk_hw_get_name(hw), err);
}

static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_is_enabled_response response;
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_IS_ENABLED;
	msg.id = clk->id;
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0)
		return err;

	return response.state;
}

static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
						unsigned long parent_rate)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_get_rate_response response;
	struct cmd_clk_get_rate_request request;
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_GET_RATE;
	msg.id = clk->id;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0)
		return err;

	return response.rate;
}

static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
				      unsigned long *parent_rate)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_round_rate_response response;
	struct cmd_clk_round_rate_request request;
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&request, 0, sizeof(request));
	request.rate = rate;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_ROUND_RATE;
	msg.id = clk->id;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0)
		return err;

	return response.rate;
}

static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_set_parent_response response;
	struct cmd_clk_set_parent_request request;
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&request, 0, sizeof(request));
	request.parent_id = clk->parents[index];

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_SET_PARENT;
	msg.id = clk->id;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0)
		return err;

	/* XXX check parent ID in response */

	return 0;
}

static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_get_parent_response response;
	struct tegra_bpmp_clk_message msg;
	unsigned int i;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_GET_PARENT;
	msg.id = clk->id;
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
	if (err < 0) {
		dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n",
			clk_hw_get_name(hw), err);
		return U8_MAX;
	}

	for (i = 0; i < clk->num_parents; i++)
		if (clk->parents[i] == response.parent_id)
			return i;

	return U8_MAX;
}

static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
				   unsigned long parent_rate)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct cmd_clk_set_rate_response response;
	struct cmd_clk_set_rate_request request;
	struct tegra_bpmp_clk_message msg;

	memset(&request, 0, sizeof(request));
	request.rate = rate;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_SET_RATE;
	msg.id = clk->id;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
}

static const struct clk_ops tegra_bpmp_clk_gate_ops = {
	.prepare = tegra_bpmp_clk_prepare,
	.unprepare = tegra_bpmp_clk_unprepare,
	.is_prepared = tegra_bpmp_clk_is_prepared,
	.recalc_rate = tegra_bpmp_clk_recalc_rate,
};

static const struct clk_ops tegra_bpmp_clk_mux_ops = {
	.prepare = tegra_bpmp_clk_prepare,
	.unprepare = tegra_bpmp_clk_unprepare,
	.is_prepared = tegra_bpmp_clk_is_prepared,
	.recalc_rate = tegra_bpmp_clk_recalc_rate,
	.set_parent = tegra_bpmp_clk_set_parent,
	.get_parent = tegra_bpmp_clk_get_parent,
};

static const struct clk_ops tegra_bpmp_clk_rate_ops = {
	.prepare = tegra_bpmp_clk_prepare,
	.unprepare = tegra_bpmp_clk_unprepare,
	.is_prepared = tegra_bpmp_clk_is_prepared,
	.recalc_rate = tegra_bpmp_clk_recalc_rate,
	.round_rate = tegra_bpmp_clk_round_rate,
	.set_rate = tegra_bpmp_clk_set_rate,
};

static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
	.prepare = tegra_bpmp_clk_prepare,
	.unprepare = tegra_bpmp_clk_unprepare,
	.is_prepared = tegra_bpmp_clk_is_prepared,
	.recalc_rate = tegra_bpmp_clk_recalc_rate,
	.round_rate = tegra_bpmp_clk_round_rate,
	.set_parent = tegra_bpmp_clk_set_parent,
	.get_parent = tegra_bpmp_clk_get_parent,
	.set_rate = tegra_bpmp_clk_set_rate,
};

static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp)
{
	struct cmd_clk_get_max_clk_id_response response;
	struct tegra_bpmp_clk_message msg;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_GET_MAX_CLK_ID;
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(bpmp, &msg);
	if (err < 0)
		return err;

	if (response.max_id > INT_MAX)
		return -E2BIG;

	return response.max_id;
}

static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
				   struct tegra_bpmp_clk_info *info)
{
	struct cmd_clk_get_all_info_response response;
	struct tegra_bpmp_clk_message msg;
	unsigned int i;
	int err;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_GET_ALL_INFO;
	msg.id = id;
	msg.rx.data = &response;
	msg.rx.size = sizeof(response);

	err = tegra_bpmp_clk_transfer(bpmp, &msg);
	if (err < 0)
		return err;

	strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
	info->num_parents = response.num_parents;

	for (i = 0; i < info->num_parents; i++)
		info->parents[i] = response.parents[i];

	info->flags = response.flags;

	return 0;
}

static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp,
				     const char *level,
				     const struct tegra_bpmp_clk_info *info)
{
	const char *prefix = "";
	struct seq_buf buf;
	unsigned int i;
	char flags[64];

	seq_buf_init(&buf, flags, sizeof(flags));

	if (info->flags)
		seq_buf_printf(&buf, "(");

	if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
		seq_buf_printf(&buf, "%smux", prefix);
		prefix = ", ";
	}

	if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) {
		seq_buf_printf(&buf, "%sfixed", prefix);
		prefix = ", ";
	}

	if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) {
		seq_buf_printf(&buf, "%sroot", prefix);
		prefix = ", ";
	}

	if (info->flags)
		seq_buf_printf(&buf, ")");

	dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name);
	dev_printk(level, bpmp->dev, "  flags: %lx %s\n", info->flags, flags);
	dev_printk(level, bpmp->dev, "  parents: %u\n", info->num_parents);

	for (i = 0; i < info->num_parents; i++)
		dev_printk(level, bpmp->dev, "    %03u\n", info->parents[i]);
}

static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
				   struct tegra_bpmp_clk_info **clocksp)
{
	struct tegra_bpmp_clk_info *clocks;
	unsigned int max_id, id, count = 0;
	unsigned int holes = 0;
	int err;

	err = tegra_bpmp_clk_get_max_id(bpmp);
	if (err < 0)
		return err;

	max_id = err;

	dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id);

	clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL);
	if (!clocks)
		return -ENOMEM;

	for (id = 0; id <= max_id; id++) {
		struct tegra_bpmp_clk_info *info = &clocks[count];

		err = tegra_bpmp_clk_get_info(bpmp, id, info);
		if (err < 0) {
			dev_err(bpmp->dev, "failed to query clock %u: %d\n",
				id, err);
			continue;
		}

		if (info->num_parents >= U8_MAX) {
			dev_err(bpmp->dev,
				"clock %u has too many parents (%u, max: %u)\n",
				id, info->num_parents, U8_MAX);
			continue;
		}

		/* clock not exposed by BPMP */
		if (info->name[0] == '\0') {
			holes++;
			continue;
		}

		info->id = id;
		count++;

		if (TEGRA_BPMP_DUMP_CLOCK_INFO)
			tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info);
	}

	dev_dbg(bpmp->dev, "holes: %u\n", holes);
	*clocksp = clocks;

	return count;
}

static const struct tegra_bpmp_clk_info *
tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
		    unsigned int num_clocks, unsigned int id)
{
	unsigned int i;

	for (i = 0; i < num_clocks; i++)
		if (clocks[i].id == id)
			return &clocks[i];

	return NULL;
}

static struct tegra_bpmp_clk *
tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
			const struct tegra_bpmp_clk_info *info,
			const struct tegra_bpmp_clk_info *clocks,
			unsigned int num_clocks)
{
	struct tegra_bpmp_clk *clk;
	struct clk_init_data init;
	const char **parents;
	unsigned int i;
	int err;

	clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL);
	if (!clk)
		return ERR_PTR(-ENOMEM);

	clk->id = info->id;
	clk->bpmp = bpmp;

	clk->parents = devm_kcalloc(bpmp->dev, info->num_parents,
				    sizeof(*clk->parents), GFP_KERNEL);
	if (!clk->parents)
		return ERR_PTR(-ENOMEM);

	clk->num_parents = info->num_parents;

	/* hardware clock initialization */
	memset(&init, 0, sizeof(init));
	init.name = info->name;
	clk->hw.init = &init;

	if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
		if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
			init.ops = &tegra_bpmp_clk_mux_rate_ops;
		else
			init.ops = &tegra_bpmp_clk_mux_ops;
	} else {
		if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
			init.ops = &tegra_bpmp_clk_rate_ops;
		else
			init.ops = &tegra_bpmp_clk_gate_ops;
	}

	init.num_parents = info->num_parents;

	parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL);
	if (!parents)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < info->num_parents; i++) {
		const struct tegra_bpmp_clk_info *parent;

		/* keep a private copy of the ID to parent index map */
		clk->parents[i] = info->parents[i];

		parent = tegra_bpmp_clk_find(clocks, num_clocks,
					     info->parents[i]);
		if (!parent) {
			dev_err(bpmp->dev, "no parent %u found for %u\n",
				info->parents[i], info->id);
			continue;
		}

		parents[i] = parent->name;
	}

	init.parent_names = parents;

	err = devm_clk_hw_register(bpmp->dev, &clk->hw);

	kfree(parents);

	if (err < 0)
		return ERR_PTR(err);

	return clk;
}

static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
				      struct tegra_bpmp_clk_info *infos,
				      unsigned int count)
{
	struct tegra_bpmp_clk *clk;
	unsigned int i;

	bpmp->num_clocks = count;

	bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL);
	if (!bpmp->clocks)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		struct tegra_bpmp_clk_info *info = &infos[i];

		clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
		if (IS_ERR(clk)) {
			dev_err(bpmp->dev,
				"failed to register clock %u (%s): %ld\n",
				info->id, info->name, PTR_ERR(clk));
			continue;
		}

		bpmp->clocks[i] = clk;
	}

	return 0;
}

static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
{
	unsigned int i;

	for (i = 0; i < bpmp->num_clocks; i++)
		clk_hw_unregister(&bpmp->clocks[i]->hw);
}

static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
					      void *data)
{
	unsigned int id = clkspec->args[0], i;
	struct tegra_bpmp *bpmp = data;

	for (i = 0; i < bpmp->num_clocks; i++)
		if (bpmp->clocks[i]->id == id)
			return &bpmp->clocks[i]->hw;

	return NULL;
}

int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
{
	struct tegra_bpmp_clk_info *clocks;
	unsigned int count;
	int err;

	err = tegra_bpmp_probe_clocks(bpmp, &clocks);
	if (err < 0)
		return err;

	count = err;

	dev_dbg(bpmp->dev, "%u clocks probed\n", count);

	err = tegra_bpmp_register_clocks(bpmp, clocks, count);
	if (err < 0)
		goto free;

	err = of_clk_add_hw_provider(bpmp->dev->of_node,
				     tegra_bpmp_clk_of_xlate,
				     bpmp);
	if (err < 0) {
		tegra_bpmp_unregister_clocks(bpmp);
		goto free;
	}

free:
	kfree(clocks);
	return err;
}
