/*
 * 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;
	struct resource *mem;

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

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	pll_clk->base = devm_ioremap_resource(dev, mem);
	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");
