// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019 DENX Software Engineering
 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
 */

#include <common.h>
#include <asm/io.h>
#include <div64.h>
#include <malloc.h>
#include <clk-uclass.h>
#include <dm/device.h>
#include <dm/uclass.h>
#include <clk.h>
#include "clk.h"

#define UBOOT_DM_CLK_IMX_PLLV3_GENERIC	"imx_clk_pllv3_generic"
#define UBOOT_DM_CLK_IMX_PLLV3_SYS	"imx_clk_pllv3_sys"
#define UBOOT_DM_CLK_IMX_PLLV3_USB	"imx_clk_pllv3_usb"
#define UBOOT_DM_CLK_IMX_PLLV3_AV	"imx_clk_pllv3_av"

#define PLL_NUM_OFFSET		0x10
#define PLL_DENOM_OFFSET	0x20

#define BM_PLL_POWER		(0x1 << 12)
#define BM_PLL_LOCK		(0x1 << 31)

struct clk_pllv3 {
	struct clk	clk;
	void __iomem	*base;
	u32		power_bit;
	bool		powerup_set;
	u32		div_mask;
	u32		div_shift;
};

#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)

static ulong clk_pllv3_generic_get_rate(struct clk *clk)
{
	struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
	unsigned long parent_rate = clk_get_parent_rate(clk);

	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;

	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
}

static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	unsigned long parent_rate = clk_get_parent_rate(clk);
	u32 val, div;

	if (rate == parent_rate * 22)
		div = 1;
	else if (rate == parent_rate * 20)
		div = 0;
	else
		return -EINVAL;

	val = readl(pll->base);
	val &= ~(pll->div_mask << pll->div_shift);
	val |= (div << pll->div_shift);
	writel(val, pll->base);

	/* Wait for PLL to lock */
	while (!(readl(pll->base) & BM_PLL_LOCK))
		;

	return 0;
}

static int clk_pllv3_generic_enable(struct clk *clk)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	u32 val;

	val = readl(pll->base);
	if (pll->powerup_set)
		val |= pll->power_bit;
	else
		val &= ~pll->power_bit;
	writel(val, pll->base);

	return 0;
}

static int clk_pllv3_generic_disable(struct clk *clk)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	u32 val;

	val = readl(pll->base);
	if (pll->powerup_set)
		val &= ~pll->power_bit;
	else
		val |= pll->power_bit;
	writel(val, pll->base);

	return 0;
}

static const struct clk_ops clk_pllv3_generic_ops = {
	.get_rate	= clk_pllv3_generic_get_rate,
	.enable		= clk_pllv3_generic_enable,
	.disable	= clk_pllv3_generic_disable,
	.set_rate	= clk_pllv3_generic_set_rate,
};

static ulong clk_pllv3_sys_get_rate(struct clk *clk)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	unsigned long parent_rate = clk_get_parent_rate(clk);
	u32 div = readl(pll->base) & pll->div_mask;

	return parent_rate * div / 2;
}

static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	unsigned long parent_rate = clk_get_parent_rate(clk);
	unsigned long min_rate = parent_rate * 54 / 2;
	unsigned long max_rate = parent_rate * 108 / 2;
	u32 val, div;

	if (rate < min_rate || rate > max_rate)
		return -EINVAL;

	div = rate * 2 / parent_rate;
	val = readl(pll->base);
	val &= ~pll->div_mask;
	val |= div;
	writel(val, pll->base);

	/* Wait for PLL to lock */
	while (!(readl(pll->base) & BM_PLL_LOCK))
		;

	return 0;
}

static const struct clk_ops clk_pllv3_sys_ops = {
	.enable 	= clk_pllv3_generic_enable,
	.disable	= clk_pllv3_generic_disable,
	.get_rate	= clk_pllv3_sys_get_rate,
	.set_rate	= clk_pllv3_sys_set_rate,
};

static ulong clk_pllv3_av_get_rate(struct clk *clk)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	unsigned long parent_rate = clk_get_parent_rate(clk);
	u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
	u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
	u32 div = readl(pll->base) & pll->div_mask;
	u64 temp64 = (u64)parent_rate;

	temp64 *= mfn;
	do_div(temp64, mfd);

	return parent_rate * div + (unsigned long)temp64;
}

static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
{
	struct clk_pllv3 *pll = to_clk_pllv3(clk);
	unsigned long parent_rate = clk_get_parent_rate(clk);
	unsigned long min_rate = parent_rate * 27;
	unsigned long max_rate = parent_rate * 54;
	u32 val, div;
	u32 mfn, mfd = 1000000;
	u32 max_mfd = 0x3FFFFFFF;
	u64 temp64;

	if (rate < min_rate || rate > max_rate)
		return -EINVAL;

	if (parent_rate <= max_mfd)
		mfd = parent_rate;

	div = rate / parent_rate;
	temp64 = (u64)(rate - div * parent_rate);
	temp64 *= mfd;
	do_div(temp64, parent_rate);
	mfn = temp64;

	val = readl(pll->base);
	val &= ~pll->div_mask;
	val |= div;
	writel(val, pll->base);
	writel(mfn, pll->base + PLL_NUM_OFFSET);
	writel(mfd, pll->base + PLL_DENOM_OFFSET);

	/* Wait for PLL to lock */
	while (!(readl(pll->base) & BM_PLL_LOCK))
		;

	return 0;
}

static const struct clk_ops clk_pllv3_av_ops = {
	.enable		= clk_pllv3_generic_enable,
	.disable	= clk_pllv3_generic_disable,
	.get_rate	= clk_pllv3_av_get_rate,
	.set_rate	= clk_pllv3_av_set_rate,
};

struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
			  const char *parent_name, void __iomem *base,
			  u32 div_mask)
{
	struct clk_pllv3 *pll;
	struct clk *clk;
	char *drv_name;
	int ret;

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

	pll->power_bit = BM_PLL_POWER;

	switch (type) {
	case IMX_PLLV3_GENERIC:
		drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENERIC;
		pll->div_shift = 0;
		pll->powerup_set = false;
		break;
	case IMX_PLLV3_SYS:
		drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
		pll->div_shift = 0;
		pll->powerup_set = false;
		break;
	case IMX_PLLV3_USB:
		drv_name = UBOOT_DM_CLK_IMX_PLLV3_USB;
		pll->div_shift = 1;
		pll->powerup_set = true;
		break;
	case IMX_PLLV3_AV:
		drv_name = UBOOT_DM_CLK_IMX_PLLV3_AV;
		pll->div_shift = 0;
		pll->powerup_set = false;
		break;
	default:
		kfree(pll);
		return ERR_PTR(-ENOTSUPP);
	}

	pll->base = base;
	pll->div_mask = div_mask;
	clk = &pll->clk;

	ret = clk_register(clk, drv_name, name, parent_name);
	if (ret) {
		kfree(pll);
		return ERR_PTR(ret);
	}

	return clk;
}

U_BOOT_DRIVER(clk_pllv3_generic) = {
	.name	= UBOOT_DM_CLK_IMX_PLLV3_GENERIC,
	.id	= UCLASS_CLK,
	.ops	= &clk_pllv3_generic_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

U_BOOT_DRIVER(clk_pllv3_sys) = {
	.name	= UBOOT_DM_CLK_IMX_PLLV3_SYS,
	.id	= UCLASS_CLK,
	.ops	= &clk_pllv3_sys_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

U_BOOT_DRIVER(clk_pllv3_usb) = {
	.name	= UBOOT_DM_CLK_IMX_PLLV3_USB,
	.id	= UCLASS_CLK,
	.ops	= &clk_pllv3_generic_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

U_BOOT_DRIVER(clk_pllv3_av) = {
	.name	= UBOOT_DM_CLK_IMX_PLLV3_AV,
	.id	= UCLASS_CLK,
	.ops	= &clk_pllv3_av_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
