// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 NXP
 *
 * Clock driver for LS1028A Display output interfaces(LCD, DPHY).
 */

#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/bitfield.h>

/* PLLDIG register offsets and bit masks */
#define PLLDIG_REG_PLLSR            0x24
#define PLLDIG_LOCK_MASK            BIT(2)
#define PLLDIG_REG_PLLDV            0x28
#define PLLDIG_MFD_MASK             GENMASK(7, 0)
#define PLLDIG_RFDPHI1_MASK         GENMASK(30, 25)
#define PLLDIG_REG_PLLFM            0x2c
#define PLLDIG_SSCGBYP_ENABLE       BIT(30)
#define PLLDIG_REG_PLLFD            0x30
#define PLLDIG_FDEN                 BIT(30)
#define PLLDIG_FRAC_MASK            GENMASK(15, 0)
#define PLLDIG_REG_PLLCAL1          0x38
#define PLLDIG_REG_PLLCAL2          0x3c

/* Range of the VCO frequencies, in Hz */
#define PLLDIG_MIN_VCO_FREQ         650000000
#define PLLDIG_MAX_VCO_FREQ         1300000000

/* Range of the output frequencies, in Hz */
#define PHI1_MIN_FREQ               27000000UL
#define PHI1_MAX_FREQ               600000000UL

/* Maximum value of the reduced frequency divider */
#define MAX_RFDPHI1          63UL

/* Best value of multiplication factor divider */
#define PLLDIG_DEFAULT_MFD   44

/*
 * Denominator part of the fractional part of the
 * loop multiplication factor.
 */
#define MFDEN          20480

static const struct clk_parent_data parent_data[] = {
	{ .index = 0 },
};

struct clk_plldig {
	struct clk_hw hw;
	void __iomem *regs;
	unsigned int vco_freq;
};

#define to_clk_plldig(_hw)	container_of(_hw, struct clk_plldig, hw)

static int plldig_enable(struct clk_hw *hw)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	u32 val;

	val = readl(data->regs + PLLDIG_REG_PLLFM);
	/*
	 * Use Bypass mode with PLL off by default, the frequency overshoot
	 * detector output was disable. SSCG Bypass mode should be enable.
	 */
	val |= PLLDIG_SSCGBYP_ENABLE;
	writel(val, data->regs + PLLDIG_REG_PLLFM);

	return 0;
}

static void plldig_disable(struct clk_hw *hw)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	u32 val;

	val = readl(data->regs + PLLDIG_REG_PLLFM);

	val &= ~PLLDIG_SSCGBYP_ENABLE;
	val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0);

	writel(val, data->regs + PLLDIG_REG_PLLFM);
}

static int plldig_is_enabled(struct clk_hw *hw)
{
	struct clk_plldig *data = to_clk_plldig(hw);

	return readl(data->regs + PLLDIG_REG_PLLFM) &
			      PLLDIG_SSCGBYP_ENABLE;
}

static unsigned long plldig_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	u32 val, rfdphi1;

	val = readl(data->regs + PLLDIG_REG_PLLDV);

	/* Check if PLL is bypassed */
	if (val & PLLDIG_SSCGBYP_ENABLE)
		return parent_rate;

	rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val);

	/*
	 * If RFDPHI1 has a value of 1 the VCO frequency is also divided by
	 * one.
	 */
	if (!rfdphi1)
		rfdphi1 = 1;

	return DIV_ROUND_UP(data->vco_freq, rfdphi1);
}

static unsigned long plldig_calc_target_div(unsigned long vco_freq,
					    unsigned long target_rate)
{
	unsigned long div;

	div = DIV_ROUND_CLOSEST(vco_freq, target_rate);
	div = clamp(div, 1UL, MAX_RFDPHI1);

	return div;
}

static int plldig_determine_rate(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	unsigned int div;

	req->rate = clamp(req->rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
	div = plldig_calc_target_div(data->vco_freq, req->rate);
	req->rate = DIV_ROUND_UP(data->vco_freq, div);

	return 0;
}

static int plldig_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	unsigned int val, cond;
	unsigned int rfdphi1;

	rate = clamp(rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
	rfdphi1 = plldig_calc_target_div(data->vco_freq, rate);

	/* update the divider value */
	val = readl(data->regs + PLLDIG_REG_PLLDV);
	val &= ~PLLDIG_RFDPHI1_MASK;
	val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1);
	writel(val, data->regs + PLLDIG_REG_PLLDV);

	/* waiting for old lock state to clear */
	udelay(200);

	/* Wait until PLL is locked or timeout */
	return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond,
					 cond & PLLDIG_LOCK_MASK, 0,
					 USEC_PER_MSEC);
}

static const struct clk_ops plldig_clk_ops = {
	.enable = plldig_enable,
	.disable = plldig_disable,
	.is_enabled = plldig_is_enabled,
	.recalc_rate = plldig_recalc_rate,
	.determine_rate = plldig_determine_rate,
	.set_rate = plldig_set_rate,
};

static int plldig_init(struct clk_hw *hw)
{
	struct clk_plldig *data = to_clk_plldig(hw);
	struct clk_hw *parent = clk_hw_get_parent(hw);
	unsigned long parent_rate;
	unsigned long val;
	unsigned long long lltmp;
	unsigned int mfd, fracdiv = 0;

	if (!parent)
		return -EINVAL;

	parent_rate = clk_hw_get_rate(parent);

	if (data->vco_freq) {
		mfd = data->vco_freq / parent_rate;
		lltmp = data->vco_freq % parent_rate;
		lltmp *= MFDEN;
		do_div(lltmp, parent_rate);
		fracdiv = lltmp;
	} else {
		mfd = PLLDIG_DEFAULT_MFD;
		data->vco_freq = parent_rate * mfd;
	}

	val = FIELD_PREP(PLLDIG_MFD_MASK, mfd);
	writel(val, data->regs + PLLDIG_REG_PLLDV);

	/* Enable fractional divider */
	if (fracdiv) {
		val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv);
		val |= PLLDIG_FDEN;
		writel(val, data->regs + PLLDIG_REG_PLLFD);
	}

	return 0;
}

static int plldig_clk_probe(struct platform_device *pdev)
{
	struct clk_plldig *data;
	struct device *dev = &pdev->dev;
	int ret;

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

	data->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(data->regs))
		return PTR_ERR(data->regs);

	data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk",
						 parent_data,
						 &plldig_clk_ops,
						 0);

	ret = devm_clk_hw_register(dev, &data->hw);
	if (ret) {
		dev_err(dev, "failed to register %s clock\n",
						dev->of_node->name);
		return ret;
	}

	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
					  &data->hw);
	if (ret) {
		dev_err(dev, "unable to add clk provider\n");
		return ret;
	}

	/*
	 * The frequency of the VCO cannot be changed during runtime.
	 * Therefore, let the user specify a desired frequency.
	 */
	if (!of_property_read_u32(dev->of_node, "fsl,vco-hz",
				  &data->vco_freq)) {
		if (data->vco_freq < PLLDIG_MIN_VCO_FREQ ||
		    data->vco_freq > PLLDIG_MAX_VCO_FREQ)
			return -EINVAL;
	}

	return plldig_init(&data->hw);
}

static const struct of_device_id plldig_clk_id[] = {
	{ .compatible = "fsl,ls1028a-plldig" },
	{ }
};
MODULE_DEVICE_TABLE(of, plldig_clk_id);

static struct platform_driver plldig_clk_driver = {
	.driver = {
		.name = "plldig-clock",
		.of_match_table = plldig_clk_id,
	},
	.probe = plldig_clk_probe,
};
module_platform_driver(plldig_clk_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Wen He <wen.he_1@nxp.com>");
MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver");
