// SPDX-License-Identifier: GPL-2.0
/*
 * Xilinx 'Clocking Wizard' driver
 *
 * Copyright (c) 2021 Macronix Inc.
 *
 * Author: Zhengxun Li <zhengxunli@mxic.com.tw>
 */

#include <clk-uclass.h>
#include <dm.h>
#include <div64.h>
#include <dm/device_compat.h>
#include <linux/iopoll.h>

#include <linux/bitfield.h>

#define SRR			0x0

#define SR			0x4
#define SR_LOCKED		BIT(0)

#define CCR(x)			(0x200 + ((x) * 4))

#define FBOUT_CFG		CCR(0)
#define FBOUT_DIV(x)		(x)
#define FBOUT_DIV_MASK		GENMASK(7, 0)
#define FBOUT_GET_DIV(x)	FIELD_GET(FBOUT_DIV_MASK, x)
#define FBOUT_MUL(x)		((x) << 8)
#define FBOUT_MUL_MASK		GENMASK(15, 8)
#define FBOUT_GET_MUL(x)	FIELD_GET(FBOUT_MUL_MASK, x)
#define FBOUT_FRAC(x)		((x) << 16)
#define FBOUT_FRAC_MASK		GENMASK(25, 16)
#define FBOUT_GET_FRAC(x)	FIELD_GET(FBOUT_FRAC_MASK, x)
#define FBOUT_FRAC_EN		BIT(26)

#define FBOUT_PHASE		CCR(1)

#define OUT_CFG(x)		CCR(2 + ((x) * 3))
#define OUT_DIV(x)		(x)
#define OUT_DIV_MASK		GENMASK(7, 0)
#define OUT_GET_DIV(x)		FIELD_GET(OUT_DIV_MASK, x)
#define OUT_FRAC(x)		((x) << 8)
#define OUT_GET_MASK		GENMASK(17, 8)
#define OUT_GET_FRAC(x)		FIELD_GET(OUT_GET_MASK, x)
#define OUT_FRAC_EN		BIT(18)

#define OUT_PHASE(x)		CCR(3 + ((x) * 3))
#define OUT_DUTY(x)		CCR(4 + ((x) * 3))

#define CTRL			CCR(23)
#define CTRL_SEN		BIT(2)
#define CTRL_SADDR		BIT(1)
#define CTRL_LOAD		BIT(0)

/**
 * struct clkwzrd - Clock wizard private data structure
 *
 * @base:		memory base
 * @vco_clk:		voltage-controlled oscillator frequency
 *
 */
struct clkwzd {
	void *base;
	u64 vco_clk;
};

struct clkwzd_plat {
	fdt_addr_t addr;
};

static int clk_wzrd_enable(struct clk *clk)
{
	struct clkwzd *priv = dev_get_priv(clk->dev);
	int ret;
	u32 val;

	ret = readl_poll_sleep_timeout(priv->base + SR, val, val & SR_LOCKED,
				       1, 100);
	if (!ret) {
		writel(CTRL_SEN | CTRL_SADDR | CTRL_LOAD, priv->base + CTRL);
		writel(CTRL_SADDR, priv->base + CTRL);
		ret = readl_poll_sleep_timeout(priv->base + SR, val,
					       val & SR_LOCKED, 1, 100);
	}

	return ret;
}

static unsigned long clk_wzrd_set_rate(struct clk *clk, ulong rate)
{
	struct clkwzd *priv = dev_get_priv(clk->dev);
	u64 div;
	u32 cfg;

	/* Get output clock divide value */
	div = DIV_ROUND_DOWN_ULL(priv->vco_clk * 1000, rate);
	if (div < 1000 || div > 255999)
		return -EINVAL;

	cfg = OUT_DIV((u32)div / 1000);

	writel(cfg, priv->base + OUT_CFG(clk->id));

	return 0;
}

static struct clk_ops clk_wzrd_ops = {
	.enable = clk_wzrd_enable,
	.set_rate = clk_wzrd_set_rate,
};

static int clk_wzrd_probe(struct udevice *dev)
{
	struct clkwzd_plat *plat = dev_get_plat(dev);
	struct clkwzd *priv = dev_get_priv(dev);
	struct clk clk_in1;
	u64 clock, vco_clk;
	u32 cfg;
	int ret;

	priv->base = (void *)plat->addr;

	ret = clk_get_by_name(dev, "clk_in1", &clk_in1);
	if (ret < 0) {
		dev_err(dev, "failed to get clock\n");
		return ret;
	}

	clock = clk_get_rate(&clk_in1);
	if (IS_ERR_VALUE(clock)) {
		dev_err(dev, "failed to get rate\n");
		return clock;
	}

	ret = clk_enable(&clk_in1);
	if (ret) {
		dev_err(dev, "failed to enable clock\n");
		return ret;
	}

	/* Read clock configuration registers */
	cfg = readl(priv->base + FBOUT_CFG);

	/* Recalculate VCO rate */
	if (cfg & FBOUT_FRAC_EN)
		vco_clk = DIV_ROUND_DOWN_ULL(clock *
					     ((FBOUT_GET_MUL(cfg) * 1000) +
					      FBOUT_GET_FRAC(cfg)),
					     1000);
	else
		vco_clk = clock * FBOUT_GET_MUL(cfg);

	priv->vco_clk = DIV_ROUND_DOWN_ULL(vco_clk, FBOUT_GET_DIV(cfg));

	return 0;
}

static int clk_wzrd_of_to_plat(struct udevice *dev)
{
	struct clkwzd_plat *plat = dev_get_plat(dev);

	plat->addr = dev_read_addr(dev);
	if (plat->addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	return 0;
}

static const struct udevice_id clk_wzrd_ids[] = {
	{ .compatible = "xlnx,clocking-wizard" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(clk_wzrd) = {
	.name = "zynq-clk-wizard",
	.id = UCLASS_CLK,
	.of_match = clk_wzrd_ids,
	.ops = &clk_wzrd_ops,
	.probe = clk_wzrd_probe,
	.of_to_plat = clk_wzrd_of_to_plat,
	.priv_auto = sizeof(struct clkwzd),
	.plat_auto = sizeof(struct clkwzd_plat),
};
