/*
 * Marvell Armada 37xx SoC Time Base Generator clocks
 *
 * Copyright (C) 2016 Marvell
 *
 * Gregory CLEMENT <gregory.clement@free-electrons.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2 or later. This program is licensed "as is"
 * without any warranty of any kind, whether express or implied.
 */

#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define NUM_TBG	    4

#define TBG_CTRL0		0x4
#define TBG_CTRL1		0x8
#define TBG_CTRL7		0x20
#define TBG_CTRL8		0x30

#define TBG_DIV_MASK		0x1FF

#define TBG_A_REFDIV		0
#define TBG_B_REFDIV		16

#define TBG_A_FBDIV		2
#define TBG_B_FBDIV		18

#define TBG_A_VCODIV_SE		0
#define TBG_B_VCODIV_SE		16

#define TBG_A_VCODIV_DIFF	1
#define TBG_B_VCODIV_DIFF	17

struct tbg_def {
	char *name;
	u32 refdiv_offset;
	u32 fbdiv_offset;
	u32 vcodiv_reg;
	u32 vcodiv_offset;
};

static const struct tbg_def tbg[NUM_TBG] = {
	{"TBG-A-P", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL8, TBG_A_VCODIV_DIFF},
	{"TBG-B-P", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL8, TBG_B_VCODIV_DIFF},
	{"TBG-A-S", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL1, TBG_A_VCODIV_SE},
	{"TBG-B-S", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL1, TBG_B_VCODIV_SE},
};

static unsigned int tbg_get_mult(void __iomem *reg, const struct tbg_def *ptbg)
{
	u32 val;

	val = readl(reg + TBG_CTRL0);

	return ((val >> ptbg->fbdiv_offset) & TBG_DIV_MASK) << 2;
}

static unsigned int tbg_get_div(void __iomem *reg, const struct tbg_def *ptbg)
{
	u32 val;
	unsigned int div;

	val = readl(reg + TBG_CTRL7);

	div = (val >> ptbg->refdiv_offset) & TBG_DIV_MASK;
	if (div == 0)
		div = 1;
	val = readl(reg + ptbg->vcodiv_reg);

	div *= 1 << ((val >>  ptbg->vcodiv_offset) & TBG_DIV_MASK);

	return div;
}


static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct clk_hw_onecell_data *hw_tbg_data;
	struct device *dev = &pdev->dev;
	const char *parent_name;
	struct resource *res;
	struct clk *parent;
	void __iomem *reg;
	int i, ret;

	hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data)
				   + sizeof(*hw_tbg_data->hws) * NUM_TBG,
				   GFP_KERNEL);
	if (!hw_tbg_data)
		return -ENOMEM;
	hw_tbg_data->num = NUM_TBG;
	platform_set_drvdata(pdev, hw_tbg_data);

	parent = devm_clk_get(dev, NULL);
	if (IS_ERR(parent)) {
		dev_err(dev, "Could get the clock parent\n");
		return -EINVAL;
	}
	parent_name = __clk_get_name(parent);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg = devm_ioremap_resource(dev, res);
	if (IS_ERR(reg))
		return PTR_ERR(reg);

	for (i = 0; i < NUM_TBG; i++) {
		const char *name;
		unsigned int mult, div;

		name = tbg[i].name;
		mult = tbg_get_mult(reg, &tbg[i]);
		div = tbg_get_div(reg, &tbg[i]);
		hw_tbg_data->hws[i] = clk_hw_register_fixed_factor(NULL, name,
						parent_name, 0, mult, div);
		if (IS_ERR(hw_tbg_data->hws[i]))
			dev_err(dev, "Can't register TBG clock %s\n", name);
	}

	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data);

	return ret;
}

static int armada_3700_tbg_clock_remove(struct platform_device *pdev)
{
	int i;
	struct clk_hw_onecell_data *hw_tbg_data = platform_get_drvdata(pdev);

	of_clk_del_provider(pdev->dev.of_node);
	for (i = 0; i < hw_tbg_data->num; i++)
		clk_hw_unregister_fixed_factor(hw_tbg_data->hws[i]);

	return 0;
}

static const struct of_device_id armada_3700_tbg_clock_of_match[] = {
	{ .compatible = "marvell,armada-3700-tbg-clock", },
	{ }
};

static struct platform_driver armada_3700_tbg_clock_driver = {
	.probe = armada_3700_tbg_clock_probe,
	.remove = armada_3700_tbg_clock_remove,
	.driver		= {
		.name	= "marvell-armada-3700-tbg-clock",
		.of_match_table = armada_3700_tbg_clock_of_match,
	},
};

builtin_platform_driver(armada_3700_tbg_clock_driver);
