// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 MediaTek Inc.
 * Author: Edward-JW Yang <edward-jw.yang@mediatek.com>
 */

#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/clkdev.h>
#include <linux/delay.h>

#include "clk-mtk.h"
#include "clk-pllfh.h"
#include "clk-fhctl.h"

static DEFINE_SPINLOCK(pllfh_lock);

inline struct mtk_fh *to_mtk_fh(struct clk_hw *hw)
{
	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);

	return container_of(pll, struct mtk_fh, clk_pll);
}

static int mtk_fhctl_set_rate(struct clk_hw *hw, unsigned long rate,
			      unsigned long parent_rate)
{
	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
	struct mtk_fh *fh = to_mtk_fh(hw);
	u32 pcw = 0;
	u32 postdiv;

	mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);

	return fh->ops->hopping(fh, pcw, postdiv);
}

static const struct clk_ops mtk_pllfh_ops = {
	.is_prepared	= mtk_pll_is_prepared,
	.prepare	= mtk_pll_prepare,
	.unprepare	= mtk_pll_unprepare,
	.recalc_rate	= mtk_pll_recalc_rate,
	.round_rate	= mtk_pll_round_rate,
	.set_rate	= mtk_fhctl_set_rate,
};

static struct mtk_pllfh_data *get_pllfh_by_id(struct mtk_pllfh_data *pllfhs,
					      int num_fhs, int pll_id)
{
	int i;

	for (i = 0; i < num_fhs; i++)
		if (pllfhs[i].data.pll_id == pll_id)
			return &pllfhs[i];

	return NULL;
}

void fhctl_parse_dt(const u8 *compatible_node, struct mtk_pllfh_data *pllfhs,
		    int num_fhs)
{
	void __iomem *base;
	struct device_node *node;
	u32 num_clocks, pll_id, ssc_rate;
	int offset, i;

	node = of_find_compatible_node(NULL, NULL, compatible_node);
	if (!node) {
		pr_warn("cannot find \"%s\"\n", compatible_node);
		return;
	}

	base = of_iomap(node, 0);
	if (!base) {
		pr_err("%s(): ioremap failed\n", __func__);
		goto out_node_put;
	}

	num_clocks = of_clk_get_parent_count(node);
	if (!num_clocks) {
		pr_err("%s(): failed to get clocks property\n", __func__);
		goto err;
	}

	for (i = 0; i < num_clocks; i++) {
		struct mtk_pllfh_data *pllfh;

		offset = i * 2;

		of_property_read_u32_index(node, "clocks", offset + 1, &pll_id);
		of_property_read_u32_index(node,
					   "mediatek,hopping-ssc-percent",
					   i, &ssc_rate);

		pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll_id);
		if (!pllfh)
			continue;

		pllfh->state.fh_enable = 1;
		pllfh->state.ssc_rate = ssc_rate;
		pllfh->state.base = base;
	}

out_node_put:
	of_node_put(node);
	return;
err:
	iounmap(base);
	goto out_node_put;
}
EXPORT_SYMBOL_GPL(fhctl_parse_dt);

static int pllfh_init(struct mtk_fh *fh, struct mtk_pllfh_data *pllfh_data)
{
	struct fh_pll_regs *regs = &fh->regs;
	const struct fhctl_offset *offset;
	void __iomem *base = pllfh_data->state.base;
	void __iomem *fhx_base = base + pllfh_data->data.fhx_offset;

	offset = fhctl_get_offset_table(pllfh_data->data.fh_ver);
	if (IS_ERR(offset))
		return PTR_ERR(offset);

	regs->reg_hp_en = base + offset->offset_hp_en;
	regs->reg_clk_con = base + offset->offset_clk_con;
	regs->reg_rst_con = base + offset->offset_rst_con;
	regs->reg_slope0 = base + offset->offset_slope0;
	regs->reg_slope1 = base + offset->offset_slope1;

	regs->reg_cfg = fhx_base + offset->offset_cfg;
	regs->reg_updnlmt = fhx_base + offset->offset_updnlmt;
	regs->reg_dds = fhx_base + offset->offset_dds;
	regs->reg_dvfs = fhx_base + offset->offset_dvfs;
	regs->reg_mon = fhx_base + offset->offset_mon;

	fh->pllfh_data = pllfh_data;
	fh->lock = &pllfh_lock;

	fh->ops = fhctl_get_ops();

	return 0;
}

static bool fhctl_is_supported_and_enabled(const struct mtk_pllfh_data *pllfh)
{
	return pllfh && (pllfh->state.fh_enable == 1);
}

static struct clk_hw *
mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data,
		       struct mtk_pllfh_data *pllfh_data, void __iomem *base)
{
	struct clk_hw *hw;
	struct mtk_fh *fh;
	int ret;

	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
	if (!fh)
		return ERR_PTR(-ENOMEM);

	ret = pllfh_init(fh, pllfh_data);
	if (ret) {
		hw = ERR_PTR(ret);
		goto out;
	}

	hw = mtk_clk_register_pll_ops(&fh->clk_pll, pll_data, base,
				      &mtk_pllfh_ops);

	if (IS_ERR(hw))
		goto out;

	fhctl_hw_init(fh);

out:
	if (IS_ERR(hw))
		kfree(fh);

	return hw;
}

static void mtk_clk_unregister_pllfh(struct clk_hw *hw)
{
	struct mtk_fh *fh;

	if (!hw)
		return;

	fh = to_mtk_fh(hw);

	clk_hw_unregister(hw);
	kfree(fh);
}

int mtk_clk_register_pllfhs(struct device_node *node,
			    const struct mtk_pll_data *plls, int num_plls,
			    struct mtk_pllfh_data *pllfhs, int num_fhs,
			    struct clk_hw_onecell_data *clk_data)
{
	void __iomem *base;
	int i;
	struct clk_hw *hw;

	base = of_iomap(node, 0);
	if (!base) {
		pr_err("%s(): ioremap failed\n", __func__);
		return -EINVAL;
	}

	for (i = 0; i < num_plls; i++) {
		const struct mtk_pll_data *pll = &plls[i];
		struct mtk_pllfh_data *pllfh;
		bool use_fhctl;

		pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id);
		use_fhctl = fhctl_is_supported_and_enabled(pllfh);

		if (use_fhctl)
			hw = mtk_clk_register_pllfh(pll, pllfh, base);
		else
			hw = mtk_clk_register_pll(pll, base);

		if (IS_ERR(hw)) {
			pr_err("Failed to register %s clk %s: %ld\n",
			       use_fhctl ? "fhpll" : "pll", pll->name,
			       PTR_ERR(hw));
			goto err;
		}

		clk_data->hws[pll->id] = hw;
	}

	return 0;

err:
	while (--i >= 0) {
		const struct mtk_pll_data *pll = &plls[i];
		struct mtk_pllfh_data *pllfh;
		bool use_fhctl;

		pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id);
		use_fhctl = fhctl_is_supported_and_enabled(pllfh);

		if (use_fhctl)
			mtk_clk_unregister_pllfh(clk_data->hws[pll->id]);
		else
			mtk_clk_unregister_pll(clk_data->hws[pll->id]);

		clk_data->hws[pll->id] = ERR_PTR(-ENOENT);
	}

	iounmap(base);

	return PTR_ERR(hw);
}
EXPORT_SYMBOL_GPL(mtk_clk_register_pllfhs);

void mtk_clk_unregister_pllfhs(const struct mtk_pll_data *plls, int num_plls,
			       struct mtk_pllfh_data *pllfhs, int num_fhs,
			       struct clk_hw_onecell_data *clk_data)
{
	void __iomem *base = NULL, *fhctl_base = NULL;
	int i;

	if (!clk_data)
		return;

	for (i = num_plls; i > 0; i--) {
		const struct mtk_pll_data *pll = &plls[i - 1];
		struct mtk_pllfh_data *pllfh;
		bool use_fhctl;

		if (IS_ERR_OR_NULL(clk_data->hws[pll->id]))
			continue;

		pllfh = get_pllfh_by_id(pllfhs, num_fhs, pll->id);
		use_fhctl = fhctl_is_supported_and_enabled(pllfh);

		if (use_fhctl) {
			fhctl_base = pllfh->state.base;
			mtk_clk_unregister_pllfh(clk_data->hws[pll->id]);
		} else {
			base = mtk_clk_pll_get_base(clk_data->hws[pll->id],
						    pll);
			mtk_clk_unregister_pll(clk_data->hws[pll->id]);
		}

		clk_data->hws[pll->id] = ERR_PTR(-ENOENT);
	}

	if (fhctl_base)
		iounmap(fhctl_base);

	iounmap(base);
}
EXPORT_SYMBOL_GPL(mtk_clk_unregister_pllfhs);
