// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 Intel Corporation.
 * Zhu YiXin <yixin.zhu@intel.com>
 * Rahul Tanwar <rahul.tanwar@intel.com>
 */

#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iopoll.h>
#include <linux/of.h>

#include "clk-cgu.h"

#define to_lgm_clk_pll(_hw)	container_of(_hw, struct lgm_clk_pll, hw)
#define PLL_REF_DIV(x)		((x) + 0x08)

/*
 * Calculate formula:
 * rate = (prate * mult + (prate * frac) / frac_div) / div
 */
static unsigned long
lgm_pll_calc_rate(unsigned long prate, unsigned int mult,
		  unsigned int div, unsigned int frac, unsigned int frac_div)
{
	u64 crate, frate, rate64;

	rate64 = prate;
	crate = rate64 * mult;
	frate = rate64 * frac;
	do_div(frate, frac_div);
	crate += frate;
	do_div(crate, div);

	return crate;
}

static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
{
	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
	unsigned int div, mult, frac;
	unsigned long flags;

	spin_lock_irqsave(&pll->lock, flags);
	mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
	div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
	frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
	spin_unlock_irqrestore(&pll->lock, flags);

	if (pll->type == TYPE_LJPLL)
		div *= 4;

	return lgm_pll_calc_rate(prate, mult, div, frac, BIT(24));
}

static int lgm_pll_is_enabled(struct clk_hw *hw)
{
	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
	unsigned long flags;
	unsigned int ret;

	spin_lock_irqsave(&pll->lock, flags);
	ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
	spin_unlock_irqrestore(&pll->lock, flags);

	return ret;
}

static int lgm_pll_enable(struct clk_hw *hw)
{
	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
	unsigned long flags;
	u32 val;
	int ret;

	spin_lock_irqsave(&pll->lock, flags);
	lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
	ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
					val, (val & 0x1), 1, 100);
	spin_unlock_irqrestore(&pll->lock, flags);

	return ret;
}

static void lgm_pll_disable(struct clk_hw *hw)
{
	struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
	unsigned long flags;

	spin_lock_irqsave(&pll->lock, flags);
	lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
	spin_unlock_irqrestore(&pll->lock, flags);
}

static const struct clk_ops lgm_pll_ops = {
	.recalc_rate = lgm_pll_recalc_rate,
	.is_enabled = lgm_pll_is_enabled,
	.enable = lgm_pll_enable,
	.disable = lgm_pll_disable,
};

static struct clk_hw *
lgm_clk_register_pll(struct lgm_clk_provider *ctx,
		     const struct lgm_pll_clk_data *list)
{
	struct clk_init_data init = {};
	struct lgm_clk_pll *pll;
	struct device *dev = ctx->dev;
	struct clk_hw *hw;
	int ret;

	init.ops = &lgm_pll_ops;
	init.name = list->name;
	init.flags = list->flags;
	init.parent_data = list->parent_data;
	init.num_parents = list->num_parents;

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

	pll->membase = ctx->membase;
	pll->lock = ctx->lock;
	pll->reg = list->reg;
	pll->flags = list->flags;
	pll->type = list->type;
	pll->hw.init = &init;

	hw = &pll->hw;
	ret = clk_hw_register(dev, hw);
	if (ret)
		return ERR_PTR(ret);

	return hw;
}

int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
			  const struct lgm_pll_clk_data *list,
			  unsigned int nr_clk)
{
	struct clk_hw *hw;
	int i;

	for (i = 0; i < nr_clk; i++, list++) {
		hw = lgm_clk_register_pll(ctx, list);
		if (IS_ERR(hw)) {
			dev_err(ctx->dev, "failed to register pll: %s\n",
				list->name);
			return PTR_ERR(hw);
		}
		ctx->clk_data.hws[list->id] = hw;
	}

	return 0;
}
