// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
 * All rights reserved.
 *
 * Authors:
 *	Yifeng Huang <huangyifeng@eswincomputing.com>
 *	Xuyang Dong <dongxuyang@eswincomputing.com>
 */

#include <linux/bitfield.h>
#include <linux/clk-provider.h>
#include <linux/iopoll.h>
#include <linux/math.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "common.h"

#define PLL_EN_MASK		GENMASK(1, 0)
#define PLL_REFDIV_MASK		GENMASK(17, 12)
#define PLL_FBDIV_MASK		GENMASK(31, 20)
#define PLL_FRAC_MASK		GENMASK(27, 4)
#define PLL_POSTDIV1_MASK	GENMASK(10, 8)
#define PLL_POSTDIV2_MASK	GENMASK(18, 16)

struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
					size_t nr_clks)
{
	struct eswin_clock_data *eclk_data;

	eclk_data = devm_kzalloc(&pdev->dev,
				 struct_size(eclk_data, clk_data.hws, nr_clks),
				 GFP_KERNEL);
	if (!eclk_data)
		return ERR_PTR(-ENOMEM);

	eclk_data->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(eclk_data->base))
		return ERR_PTR(-EINVAL);

	eclk_data->clk_data.num = nr_clks;
	spin_lock_init(&eclk_data->lock);

	return eclk_data;
}
EXPORT_SYMBOL_GPL(eswin_clk_init);

/**
 * eswin_calc_pll - calculate PLL values
 * @frac_val: fractional divider
 * @fbdiv_val: feedback divider
 * @rate: reference rate
 * @parent_rate: parent rate
 *
 *   Calculate PLL values for frac and fbdiv:
 *	fbdiv = rate * 4 / parent_rate
 *	frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate
 */
static void eswin_calc_pll(u32 *frac_val, u32 *fbdiv_val, unsigned long rate,
			   unsigned long parent_rate)
{
	u32 rem;
	u64 tmp;

	/* step 1: rate * 4 */
	tmp = rate * 4;
	/* step 2: use do_div() to get the quotient(tmp) and remainder(rem) */
	rem = do_div(tmp, (u32)parent_rate);
	/* fbdiv = rate * 4 / parent_rate */
	*fbdiv_val = (u32)tmp;
	/*
	 * step 3: rem << 24
	 * 24: 24-bit fractional accuracy
	 */
	tmp = (u64)rem << 24;
	/* step 4: use do_div() to get the quotient(tmp) */
	do_div(tmp, (u32)parent_rate);
	/* frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate */
	*frac_val = (u32)tmp;
}

static inline struct eswin_clk_pll *to_pll_clk(struct clk_hw *hw)
{
	return container_of(hw, struct eswin_clk_pll, hw);
}

static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{
	struct eswin_clk_pll *clk = to_pll_clk(hw);
	u32 frac_val, fbdiv_val, val, mask;
	int ret;

	eswin_calc_pll(&frac_val, &fbdiv_val, rate, parent_rate);

	/* First, disable pll */
	val = readl_relaxed(clk->ctrl_reg0);
	val &= ~PLL_EN_MASK;
	val |= FIELD_PREP(PLL_EN_MASK, 0);
	writel_relaxed(val, clk->ctrl_reg0);

	val = readl_relaxed(clk->ctrl_reg0);
	val &= ~(PLL_REFDIV_MASK | PLL_FBDIV_MASK);
	val |= FIELD_PREP(PLL_FBDIV_MASK, fbdiv_val);
	val |= FIELD_PREP(PLL_REFDIV_MASK, 1);
	writel_relaxed(val, clk->ctrl_reg0);

	val = readl_relaxed(clk->ctrl_reg1);
	val &= ~PLL_FRAC_MASK;
	val |= FIELD_PREP(PLL_FRAC_MASK, frac_val);
	writel_relaxed(val, clk->ctrl_reg1);

	val = readl_relaxed(clk->ctrl_reg2);
	val &= ~(PLL_POSTDIV1_MASK | PLL_POSTDIV2_MASK);
	val |= FIELD_PREP(PLL_POSTDIV1_MASK, 1);
	val |= FIELD_PREP(PLL_POSTDIV2_MASK, 1);
	writel_relaxed(val, clk->ctrl_reg2);

	/* Last, enable pll */
	val = readl_relaxed(clk->ctrl_reg0);
	val &= ~PLL_EN_MASK;
	val |= FIELD_PREP(PLL_EN_MASK, 1);
	writel_relaxed(val, clk->ctrl_reg0);

	/* Usually the pll will lock in 50us */
	mask = GENMASK(clk->lock_shift + clk->lock_width - 1, clk->lock_shift);
	ret = readl_poll_timeout(clk->status_reg, val, val & mask, 1, 50 * 2);
	if (ret)
		pr_err("failed to lock the pll!\n");

	return ret;
}

static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{
	struct eswin_clk_pll *clk = to_pll_clk(hw);
	u64 fbdiv_val, frac_val, tmp;
	u32 rem, val;

	val = readl_relaxed(clk->ctrl_reg0);
	val &= PLL_FBDIV_MASK;
	fbdiv_val = (val >> clk->fbdiv_shift);

	val = readl_relaxed(clk->ctrl_reg1);
	val &= PLL_FRAC_MASK;
	frac_val = (val >> clk->frac_shift);

	/* rate = 24000000 * (fbdiv + frac / (2 ^ 24)) / 4 */
	tmp = parent_rate * frac_val;
	rem = do_div(tmp, BIT(24));
	if (rem)
		tmp = parent_rate * fbdiv_val + tmp + 1;
	else
		tmp = parent_rate * fbdiv_val + tmp;

	do_div(tmp, 4);

	return tmp;
}

static int clk_pll_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	struct eswin_clk_pll *clk = to_pll_clk(hw);

	req->rate = clamp(req->rate, clk->min_rate, clk->max_rate);
	req->min_rate = clk->min_rate;
	req->max_rate = clk->max_rate;

	return 0;
}

int eswin_clk_register_fixed_rate(struct device *dev,
				  struct eswin_fixed_rate_clock *clks,
				  int nums, struct eswin_clock_data *data)
{
	struct clk_hw *clk_hw;
	int i;

	for (i = 0; i < nums; i++) {
		clk_hw = devm_clk_hw_register_fixed_rate(dev, clks[i].name,
							 NULL, clks[i].flags,
							 clks[i].rate);
		if (IS_ERR(clk_hw))
			return PTR_ERR(clk_hw);

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_rate);

static const struct clk_ops eswin_clk_pll_ops = {
	.set_rate = clk_pll_set_rate,
	.recalc_rate = clk_pll_recalc_rate,
	.determine_rate = clk_pll_determine_rate,
};

int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
			   int nums, struct eswin_clock_data *data)
{
	struct eswin_clk_pll *p_clk = NULL;
	struct clk_init_data init;
	struct clk_hw *clk_hw;
	int i, ret;

	p_clk = devm_kzalloc(dev, sizeof(*p_clk) * nums, GFP_KERNEL);
	if (!p_clk)
		return -ENOMEM;

	for (i = 0; i < nums; i++) {
		p_clk->id = clks[i].id;
		p_clk->ctrl_reg0 = data->base + clks[i].ctrl_reg0;
		p_clk->fbdiv_shift = clks[i].fbdiv_shift;

		p_clk->ctrl_reg1 = data->base + clks[i].ctrl_reg1;
		p_clk->frac_shift = clks[i].frac_shift;

		p_clk->ctrl_reg2 = data->base + clks[i].ctrl_reg2;

		p_clk->status_reg = data->base + clks[i].status_reg;
		p_clk->lock_shift = clks[i].lock_shift;
		p_clk->lock_width = clks[i].lock_width;

		p_clk->max_rate = clks[i].max_rate;
		p_clk->min_rate = clks[i].min_rate;

		init.name = clks[i].name;
		init.flags = 0;
		init.parent_data = clks[i].parent_data;
		init.num_parents = 1;
		init.ops = &eswin_clk_pll_ops;
		p_clk->hw.init = &init;

		clk_hw = &p_clk->hw;

		ret = devm_clk_hw_register(dev, clk_hw);
		if (ret)
			return ret;

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
		p_clk++;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_pll);

int eswin_clk_register_fixed_factor(struct device *dev,
				    struct eswin_fixed_factor_clock *clks,
				    int nums, struct eswin_clock_data *data)
{
	struct clk_hw *clk_hw;
	int i;

	for (i = 0; i < nums; i++) {
		clk_hw = devm_clk_hw_register_fixed_factor_index(dev, clks[i].name,
								 clks[i].parent_data->index,
								 clks[i].flags, clks[i].mult,
								 clks[i].div);

		if (IS_ERR(clk_hw))
			return PTR_ERR(clk_hw);

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_factor);

int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
			   int nums, struct eswin_clock_data *data)
{
	struct clk_hw *clk_hw;
	int i;

	for (i = 0; i < nums; i++) {
		clk_hw = devm_clk_hw_register_mux_parent_data_table(dev, clks[i].name,
								    clks[i].parent_data,
								    clks[i].num_parents,
								    clks[i].flags,
								    data->base + clks[i].reg,
								    clks[i].shift, clks[i].width,
								    clks[i].mux_flags,
								    clks[i].table, &data->lock);

		if (IS_ERR(clk_hw))
			return PTR_ERR(clk_hw);

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_mux);

static unsigned int _eswin_get_val(unsigned int div, unsigned long flags,
				   u8 width)
{
	unsigned int maxdiv;

	maxdiv = clk_div_mask(width);
	div = div > maxdiv ? maxdiv : div;

	if (flags & ESWIN_PRIV_DIV_MIN_2)
		return (div < 2) ? 2 : div;

	return div;
}

static unsigned int eswin_div_get_val(unsigned long rate,
				      unsigned long parent_rate, u8 width,
				      unsigned long flags)
{
	unsigned int div;

	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);

	return _eswin_get_val(div, flags, width);
}

static inline struct eswin_divider_clock *to_div_clk(struct clk_hw *hw)
{
	return container_of(hw, struct eswin_divider_clock, hw);
}

static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{
	struct eswin_divider_clock *dclk = to_div_clk(hw);
	unsigned long flags;
	unsigned int value;
	u32 val;

	value = eswin_div_get_val(rate, parent_rate, dclk->width,
				  dclk->priv_flag);

	spin_lock_irqsave(dclk->lock, flags);

	val = readl_relaxed(dclk->ctrl_reg);
	val &= ~(clk_div_mask(dclk->width) << dclk->shift);
	val |= (u32)value << dclk->shift;
	writel_relaxed(val, dclk->ctrl_reg);

	spin_unlock_irqrestore(dclk->lock, flags);

	return 0;
}

static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{
	struct eswin_divider_clock *dclk = to_div_clk(hw);
	unsigned int div, val;

	val = readl_relaxed(dclk->ctrl_reg) >> dclk->shift;
	val &= clk_div_mask(dclk->width);
	div = _eswin_get_val(val, dclk->priv_flag, dclk->width);

	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
}

static int eswin_clk_bestdiv(unsigned long rate,
			     unsigned long best_parent_rate, u8 width,
			     unsigned long flags)
{
	unsigned long bestdiv, up_rate, down_rate;
	int up, down;

	if (!rate)
		rate = 1;

	/* closest round */
	up = DIV_ROUND_UP_ULL((u64)best_parent_rate, rate);
	down = best_parent_rate / rate;

	up_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, up);
	down_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, down);

	bestdiv = (rate - up_rate) <= (down_rate - rate) ? up : down;

	return bestdiv;
}

static int clk_div_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	struct eswin_divider_clock *dclk = to_div_clk(hw);
	int div;

	div = eswin_clk_bestdiv(req->rate, req->best_parent_rate, dclk->width,
				dclk->priv_flag);
	div = _eswin_get_val(div, dclk->priv_flag, dclk->width);
	req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div);

	return 0;
}

static const struct clk_ops eswin_clk_div_ops = {
	.set_rate = clk_div_set_rate,
	.recalc_rate = clk_div_recalc_rate,
	.determine_rate = clk_div_determine_rate,
};

struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
				     const char *name,
				     const struct clk_hw *parent_hw,
				     unsigned long flags, void __iomem *reg,
				     u8 shift, u8 width,
				     unsigned long clk_divider_flags,
				     unsigned long priv_flag, spinlock_t *lock)
{
	struct eswin_divider_clock *dclk;
	struct clk_init_data init;
	struct clk_hw *clk_hw;
	int ret;

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

	init.name = name;
	init.ops = &eswin_clk_div_ops;
	init.flags = flags;
	init.parent_hws = &parent_hw;
	init.num_parents = 1;

	/* struct clk_divider assignments */
	dclk->id = id;
	dclk->ctrl_reg = reg;
	dclk->shift = shift;
	dclk->width = width;
	dclk->div_flags = clk_divider_flags;
	dclk->priv_flag = priv_flag;
	dclk->lock = lock;
	dclk->hw.init = &init;

	/* register the clock */
	clk_hw = &dclk->hw;
	ret = devm_clk_hw_register(dev, clk_hw);
	if (ret) {
		dev_err(dev, "failed to register divider clock!\n");
		return ERR_PTR(ret);
	}

	return clk_hw;
}
EXPORT_SYMBOL_GPL(eswin_register_clkdiv);

int eswin_clk_register_divider(struct device *dev,
			       struct eswin_divider_clock *clks,
			       int nums, struct eswin_clock_data *data)
{
	struct clk_hw *clk_hw;
	int i;

	for (i = 0; i < nums; i++) {
		clk_hw = devm_clk_hw_register_divider_parent_data(dev, clks[i].name,
								  clks[i].parent_data,
								  clks[i].flags,
								  data->base + clks[i].reg,
								  clks[i].shift, clks[i].width,
								  clks[i].div_flags, &data->lock);

		if (IS_ERR(clk_hw))
			return PTR_ERR(clk_hw);

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_divider);

int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
			    int nums, struct eswin_clock_data *data)
{
	struct clk_hw *clk_hw;
	int i;

	for (i = 0; i < nums; i++) {
		clk_hw = devm_clk_hw_register_gate_parent_data(dev, clks[i].name,
							       clks[i].parent_data,
							       clks[i].flags,
							       data->base + clks[i].reg,
							       clks[i].bit_idx, clks[i].gate_flags,
							       &data->lock);

		if (IS_ERR(clk_hw))
			return PTR_ERR(clk_hw);

		clks[i].hw = *clk_hw;
		data->clk_data.hws[clks[i].id] = clk_hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_gate);

int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
			    int nums, struct eswin_clock_data *data)
{
	struct eswin_clk_info *info;
	const struct clk_hw *phw = NULL;
	struct clk_hw *hw;
	int i;

	for (i = 0; i < nums; i++) {
		info = &clks[i];
		switch (info->type) {
		case CLK_FIXED_FACTOR: {
			const struct eswin_fixed_factor_clock *factor;

			factor = &info->data.factor;
			phw = data->clk_data.hws[info->pid];
			hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, factor->name, phw,
									 factor->flags,
									 factor->mult,
									 factor->div);
			break;
		}
		case CLK_MUX: {
			const struct eswin_mux_clock *mux = &info->data.mux;

			hw = devm_clk_hw_register_mux_parent_data_table(dev, mux->name,
									mux->parent_data,
									mux->num_parents,
									mux->flags,
									data->base + mux->reg,
									mux->shift, mux->width,
									mux->mux_flags,
									mux->table, &data->lock);
			break;
		}
		case CLK_DIVIDER: {
			const struct eswin_divider_clock *div = &info->data.div;

			phw = data->clk_data.hws[info->pid];
			if (div->priv_flag)
				hw = eswin_register_clkdiv(dev, div->id, div->name, phw,
							   div->flags, data->base + div->reg,
							   div->shift, div->width, div->div_flags,
							   div->priv_flag, &data->lock);
			else
				hw = devm_clk_hw_register_divider_parent_hw(dev, div->name, phw,
									    div->flags,
									    data->base + div->reg,
									    div->shift, div->width,
									    div->div_flags,
									    &data->lock);
			break;
		}
		case CLK_GATE: {
			const struct eswin_gate_clock *gate = &info->data.gate;

			phw = data->clk_data.hws[info->pid];
			hw = devm_clk_hw_register_gate_parent_hw(dev, gate->name, phw,
								 gate->flags,
								 data->base + gate->reg,
								 gate->bit_idx, gate->gate_flags,
								 &data->lock);
			break;
		}
		default:
			dev_err(dev, "Unidentifiable clock type!\n");
			return -EINVAL;
		}
		if (IS_ERR(hw))
			return PTR_ERR(hw);

		info->hw = *hw;
		data->clk_data.hws[info->id] = hw;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(eswin_clk_register_clks);
