// SPDX-License-Identifier: GPL-2.0+
/*
 * Texas Instruments K3 SoC PLL clock driver
 *
 * Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
 *	Tero Kristo <t-kristo@ti.com>
 */

#include <common.h>
#include <asm/io.h>
#include <dm.h>
#include <div64.h>
#include <errno.h>
#include <clk-uclass.h>
#include <linux/clk-provider.h>
#include "k3-clk.h"
#include <linux/rational.h>

/* 16FFT register offsets */
#define PLL_16FFT_CFG			0x08
#define PLL_KICK0			0x10
#define PLL_KICK1			0x14
#define PLL_16FFT_CTRL			0x20
#define PLL_16FFT_STAT			0x24
#define PLL_16FFT_FREQ_CTRL0		0x30
#define PLL_16FFT_FREQ_CTRL1		0x34
#define PLL_16FFT_DIV_CTRL		0x38

/* CTRL register bits */
#define PLL_16FFT_CTRL_BYPASS_EN	BIT(31)
#define PLL_16FFT_CTRL_PLL_EN		BIT(15)
#define PLL_16FFT_CTRL_DSM_EN		BIT(1)

/* STAT register bits */
#define PLL_16FFT_STAT_LOCK		BIT(0)

/* FREQ_CTRL0 bits */
#define PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK	0xfff

/* DIV CTRL register bits */
#define PLL_16FFT_DIV_CTRL_REF_DIV_MASK		0x3f

#define PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS	24
#define PLL_16FFT_HSDIV_CTRL_CLKOUT_EN          BIT(15)

/* KICK register magic values */
#define PLL_KICK0_VALUE				0x68ef3490
#define PLL_KICK1_VALUE				0xd172bc5a

/**
 * struct ti_pll_clk - TI PLL clock data info structure
 * @clk: core clock structure
 * @reg: memory address of the PLL controller
 */
struct ti_pll_clk {
	struct clk	clk;
	void __iomem	*reg;
};

#define to_clk_pll(_clk) container_of(_clk, struct ti_pll_clk, clk)

static int ti_pll_wait_for_lock(struct clk *clk)
{
	struct ti_pll_clk *pll = to_clk_pll(clk);
	u32 stat;
	int i;

	for (i = 0; i < 100000; i++) {
		stat = readl(pll->reg + PLL_16FFT_STAT);
		if (stat & PLL_16FFT_STAT_LOCK)
			return 0;
	}

	printf("%s: pll (%s) failed to lock\n", __func__,
	       clk->dev->name);

	return -EBUSY;
}

static ulong ti_pll_clk_get_rate(struct clk *clk)
{
	struct ti_pll_clk *pll = to_clk_pll(clk);
	u64 current_freq;
	u64 parent_freq = clk_get_parent_rate(clk);
	u32 pllm;
	u32 plld;
	u32 pllfm;
	u32 ctrl;

	/* Check if we are in bypass */
	ctrl = readl(pll->reg + PLL_16FFT_CTRL);
	if (ctrl & PLL_16FFT_CTRL_BYPASS_EN)
		return parent_freq;

	pllm = readl(pll->reg + PLL_16FFT_FREQ_CTRL0);
	pllfm = readl(pll->reg + PLL_16FFT_FREQ_CTRL1);

	plld = readl(pll->reg + PLL_16FFT_DIV_CTRL) &
		PLL_16FFT_DIV_CTRL_REF_DIV_MASK;

	current_freq = parent_freq * pllm / plld;

	if (pllfm) {
		u64 tmp;

		tmp = parent_freq * pllfm;
		do_div(tmp, plld);
		tmp >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
		current_freq += tmp;
	}

	return current_freq;
}

static ulong ti_pll_clk_set_rate(struct clk *clk, ulong rate)
{
	struct ti_pll_clk *pll = to_clk_pll(clk);
	u64 current_freq;
	u64 parent_freq = clk_get_parent_rate(clk);
	int ret;
	u32 ctrl;
	unsigned long pllm;
	u32 pllfm = 0;
	unsigned long plld;
	u32 div_ctrl;
	u32 rem;
	int shift;

	debug("%s(clk=%p, rate=%u)\n", __func__, clk, (u32)rate);

	if (ti_pll_clk_get_rate(clk) == rate)
		return rate;

	if (rate != parent_freq)
		/*
		 * Attempt with higher max multiplier value first to give
		 * some space for fractional divider to kick in.
		 */
		for (shift = 8; shift >= 0; shift -= 8) {
			rational_best_approximation(rate, parent_freq,
				((PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK + 1) << shift) - 1,
				PLL_16FFT_DIV_CTRL_REF_DIV_MASK, &pllm, &plld);
			if (pllm / plld <= PLL_16FFT_FREQ_CTRL0_FB_DIV_INT_MASK)
				break;
		}

	/* Put PLL to bypass mode */
	ctrl = readl(pll->reg + PLL_16FFT_CTRL);
	ctrl |= PLL_16FFT_CTRL_BYPASS_EN;
	writel(ctrl, pll->reg + PLL_16FFT_CTRL);

	if (rate == parent_freq) {
		debug("%s: put %s to bypass\n", __func__, clk->dev->name);
		return rate;
	}

	debug("%s: pre-frac-calc: rate=%u, parent_freq=%u, plld=%u, pllm=%u\n",
	      __func__, (u32)rate, (u32)parent_freq, (u32)plld, (u32)pllm);

	/* Check if we need fractional config */
	if (plld > 1) {
		pllfm = pllm % plld;
		pllfm <<= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
		rem = pllfm % plld;
		pllfm /= plld;
		if (rem)
			pllfm++;
		pllm /= plld;
		plld = 1;
	}

	if (pllfm)
		ctrl |= PLL_16FFT_CTRL_DSM_EN;
	else
		ctrl &= ~PLL_16FFT_CTRL_DSM_EN;

	writel(pllm, pll->reg + PLL_16FFT_FREQ_CTRL0);
	writel(pllfm, pll->reg + PLL_16FFT_FREQ_CTRL1);

	/*
	 * div_ctrl register contains other divider values, so rmw
	 * only plld and leave existing values alone
	 */
	div_ctrl = readl(pll->reg + PLL_16FFT_DIV_CTRL);
	div_ctrl &= ~PLL_16FFT_DIV_CTRL_REF_DIV_MASK;
	div_ctrl |= plld;
	writel(div_ctrl, pll->reg + PLL_16FFT_DIV_CTRL);

	ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN;
	ctrl |= PLL_16FFT_CTRL_PLL_EN;
	writel(ctrl, pll->reg + PLL_16FFT_CTRL);

	ret = ti_pll_wait_for_lock(clk);
	if (ret)
		return ret;

	debug("%s: pllm=%u, plld=%u, pllfm=%u, parent_freq=%u\n",
	      __func__, (u32)pllm, (u32)plld, (u32)pllfm, (u32)parent_freq);

	current_freq = parent_freq * pllm / plld;

	if (pllfm) {
		u64 tmp;

		tmp = parent_freq * pllfm;
		do_div(tmp, plld);
		tmp >>= PLL_16FFT_FREQ_CTRL1_FB_DIV_FRAC_BITS;
		current_freq += tmp;
	}

	return current_freq;
}

static int ti_pll_clk_enable(struct clk *clk)
{
	struct ti_pll_clk *pll = to_clk_pll(clk);
	u32 ctrl;

	ctrl = readl(pll->reg + PLL_16FFT_CTRL);
	ctrl &= ~PLL_16FFT_CTRL_BYPASS_EN;
	ctrl |= PLL_16FFT_CTRL_PLL_EN;
	writel(ctrl, pll->reg + PLL_16FFT_CTRL);

	return ti_pll_wait_for_lock(clk);
}

static int ti_pll_clk_disable(struct clk *clk)
{
	struct ti_pll_clk *pll = to_clk_pll(clk);
	u32 ctrl;

	ctrl = readl(pll->reg + PLL_16FFT_CTRL);
	ctrl |= PLL_16FFT_CTRL_BYPASS_EN;
	writel(ctrl, pll->reg + PLL_16FFT_CTRL);

	return 0;
}

static const struct clk_ops ti_pll_clk_ops = {
	.get_rate = ti_pll_clk_get_rate,
	.set_rate = ti_pll_clk_set_rate,
	.enable = ti_pll_clk_enable,
	.disable = ti_pll_clk_disable,
};

struct clk *clk_register_ti_pll(const char *name, const char *parent_name,
				void __iomem *reg)
{
	struct ti_pll_clk *pll;
	int ret;
	int i;
	u32 cfg, ctrl, hsdiv_presence_bit, hsdiv_ctrl_offs;

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

	pll->reg = reg;

	ret = clk_register(&pll->clk, "ti-pll-clk", name, parent_name);
	if (ret) {
		printf("%s: failed to register: %d\n", __func__, ret);
		kfree(pll);
		return ERR_PTR(ret);
	}

	/* Unlock the PLL registers */
	writel(PLL_KICK0_VALUE, pll->reg + PLL_KICK0);
	writel(PLL_KICK1_VALUE, pll->reg + PLL_KICK1);

	/* Enable all HSDIV outputs */
	cfg = readl(pll->reg + PLL_16FFT_CFG);
	for (i = 0; i < 16; i++) {
		hsdiv_presence_bit = BIT(16 + i);
		hsdiv_ctrl_offs = 0x80 + (i * 4);
		/* Enable HSDIV output if present */
		if ((hsdiv_presence_bit & cfg) != 0UL) {
			ctrl = readl(pll->reg + hsdiv_ctrl_offs);
			ctrl |= PLL_16FFT_HSDIV_CTRL_CLKOUT_EN;
			writel(ctrl, pll->reg + hsdiv_ctrl_offs);
		}
	}

	return &pll->clk;
}

U_BOOT_DRIVER(ti_pll_clk) = {
	.name = "ti-pll-clk",
	.id = UCLASS_CLK,
	.ops = &ti_pll_clk_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
