/*
 * Synopsys AXS10X SDP I2S PLL clock driver
 *
 * Copyright (C) 2016 Synopsys
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

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

/* PLL registers addresses */
#define PLL_IDIV_REG	0x0
#define PLL_FBDIV_REG	0x4
#define PLL_ODIV0_REG	0x8
#define PLL_ODIV1_REG	0xC

struct i2s_pll_cfg {
	unsigned int rate;
	unsigned int idiv;
	unsigned int fbdiv;
	unsigned int odiv0;
	unsigned int odiv1;
};

static const struct i2s_pll_cfg i2s_pll_cfg_27m[] = {
	/* 27 Mhz */
	{ 1024000, 0x104, 0x451, 0x10E38, 0x2000 },
	{ 1411200, 0x104, 0x596, 0x10D35, 0x2000 },
	{ 1536000, 0x208, 0xA28, 0x10B2C, 0x2000 },
	{ 2048000, 0x82, 0x451, 0x10E38, 0x2000 },
	{ 2822400, 0x82, 0x596, 0x10D35, 0x2000 },
	{ 3072000, 0x104, 0xA28, 0x10B2C, 0x2000 },
	{ 2116800, 0x82, 0x3CF, 0x10C30, 0x2000 },
	{ 2304000, 0x104, 0x79E, 0x10B2C, 0x2000 },
	{ 0, 0, 0, 0, 0 },
};

static const struct i2s_pll_cfg i2s_pll_cfg_28m[] = {
	/* 28.224 Mhz */
	{ 1024000, 0x82, 0x105, 0x107DF, 0x2000 },
	{ 1411200, 0x28A, 0x1, 0x10001, 0x2000 },
	{ 1536000, 0xA28, 0x187, 0x10042, 0x2000 },
	{ 2048000, 0x41, 0x105, 0x107DF, 0x2000 },
	{ 2822400, 0x145, 0x1, 0x10001, 0x2000 },
	{ 3072000, 0x514, 0x187, 0x10042, 0x2000 },
	{ 2116800, 0x514, 0x42, 0x10001, 0x2000 },
	{ 2304000, 0x619, 0x82, 0x10001, 0x2000 },
	{ 0, 0, 0, 0, 0 },
};

struct i2s_pll_clk {
	void __iomem *base;
	struct clk_hw hw;
	struct device *dev;
};

static inline void i2s_pll_write(struct i2s_pll_clk *clk, unsigned int reg,
		unsigned int val)
{
	writel_relaxed(val, clk->base + reg);
}

static inline unsigned int i2s_pll_read(struct i2s_pll_clk *clk,
		unsigned int reg)
{
	return readl_relaxed(clk->base + reg);
}

static inline struct i2s_pll_clk *to_i2s_pll_clk(struct clk_hw *hw)
{
	return container_of(hw, struct i2s_pll_clk, hw);
}

static inline unsigned int i2s_pll_get_value(unsigned int val)
{
	return (val & 0x3F) + ((val >> 6) & 0x3F);
}

static const struct i2s_pll_cfg *i2s_pll_get_cfg(unsigned long prate)
{
	switch (prate) {
	case 27000000:
		return i2s_pll_cfg_27m;
	case 28224000:
		return i2s_pll_cfg_28m;
	default:
		return NULL;
	}
}

static unsigned long i2s_pll_recalc_rate(struct clk_hw *hw,
			unsigned long parent_rate)
{
	struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
	unsigned int idiv, fbdiv, odiv;

	idiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_IDIV_REG));
	fbdiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_FBDIV_REG));
	odiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_ODIV0_REG));

	return ((parent_rate / idiv) * fbdiv) / odiv;
}

static long i2s_pll_round_rate(struct clk_hw *hw, unsigned long rate,
			unsigned long *prate)
{
	struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
	const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(*prate);
	int i;

	if (!pll_cfg) {
		dev_err(clk->dev, "invalid parent rate=%ld\n", *prate);
		return -EINVAL;
	}

	for (i = 0; pll_cfg[i].rate != 0; i++)
		if (pll_cfg[i].rate == rate)
			return rate;

	return -EINVAL;
}

static int i2s_pll_set_rate(struct clk_hw *hw, unsigned long rate,
			unsigned long parent_rate)
{
	struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
	const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(parent_rate);
	int i;

	if (!pll_cfg) {
		dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate);
		return -EINVAL;
	}

	for (i = 0; pll_cfg[i].rate != 0; i++) {
		if (pll_cfg[i].rate == rate) {
			i2s_pll_write(clk, PLL_IDIV_REG, pll_cfg[i].idiv);
			i2s_pll_write(clk, PLL_FBDIV_REG, pll_cfg[i].fbdiv);
			i2s_pll_write(clk, PLL_ODIV0_REG, pll_cfg[i].odiv0);
			i2s_pll_write(clk, PLL_ODIV1_REG, pll_cfg[i].odiv1);
			return 0;
		}
	}

	dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate,
			parent_rate);
	return -EINVAL;
}

static const struct clk_ops i2s_pll_ops = {
	.recalc_rate = i2s_pll_recalc_rate,
	.round_rate = i2s_pll_round_rate,
	.set_rate = i2s_pll_set_rate,
};

static int i2s_pll_clk_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	const char *clk_name;
	const char *parent_name;
	struct clk *clk;
	struct i2s_pll_clk *pll_clk;
	struct clk_init_data init;

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

	pll_clk->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(pll_clk->base))
		return PTR_ERR(pll_clk->base);

	memset(&init, 0, sizeof(init));
	clk_name = node->name;
	init.name = clk_name;
	init.ops = &i2s_pll_ops;
	parent_name = of_clk_get_parent_name(node, 0);
	init.parent_names = &parent_name;
	init.num_parents = 1;
	pll_clk->hw.init = &init;
	pll_clk->dev = dev;

	clk = devm_clk_register(dev, &pll_clk->hw);
	if (IS_ERR(clk)) {
		dev_err(dev, "failed to register %s clock (%ld)\n",
				clk_name, PTR_ERR(clk));
		return PTR_ERR(clk);
	}

	return of_clk_add_provider(node, of_clk_src_simple_get, clk);
}

static int i2s_pll_clk_remove(struct platform_device *pdev)
{
	of_clk_del_provider(pdev->dev.of_node);
	return 0;
}

static const struct of_device_id i2s_pll_clk_id[] = {
	{ .compatible = "snps,axs10x-i2s-pll-clock", },
	{ },
};
MODULE_DEVICE_TABLE(of, i2s_pll_clk_id);

static struct platform_driver i2s_pll_clk_driver = {
	.driver = {
		.name = "axs10x-i2s-pll-clock",
		.of_match_table = i2s_pll_clk_id,
	},
	.probe = i2s_pll_clk_probe,
	.remove = i2s_pll_clk_remove,
};
module_platform_driver(i2s_pll_clk_driver);

MODULE_AUTHOR("Jose Abreu <joabreu@synopsys.com>");
MODULE_DESCRIPTION("Synopsys AXS10X SDP I2S PLL Clock Driver");
MODULE_LICENSE("GPL v2");
