/*
 * Copyright (c) 2012 National Instruments
 *
 * Josh Cartwright <josh.cartwright@ni.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <linux/io.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/clk/zynq.h>

static void __iomem *slcr_base;

struct zynq_pll_clk {
	struct clk_hw	hw;
	void __iomem	*pll_ctrl;
	void __iomem	*pll_cfg;
};

#define to_zynq_pll_clk(hw)	container_of(hw, struct zynq_pll_clk, hw)

#define CTRL_PLL_FDIV(x)	((x) >> 12)

static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
					  unsigned long parent_rate)
{
	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
	return parent_rate * CTRL_PLL_FDIV(ioread32(pll->pll_ctrl));
}

static const struct clk_ops zynq_pll_clk_ops = {
	.recalc_rate	= zynq_pll_recalc_rate,
};

static void __init zynq_pll_clk_setup(struct device_node *np)
{
	struct clk_init_data init;
	struct zynq_pll_clk *pll;
	const char *parent_name;
	struct clk *clk;
	u32 regs[2];
	int ret;

	ret = of_property_read_u32_array(np, "reg", regs, ARRAY_SIZE(regs));
	if (WARN_ON(ret))
		return;

	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
	if (WARN_ON(!pll))
		return;

	pll->pll_ctrl = slcr_base + regs[0];
	pll->pll_cfg  = slcr_base + regs[1];

	of_property_read_string(np, "clock-output-names", &init.name);

	init.ops = &zynq_pll_clk_ops;
	parent_name = of_clk_get_parent_name(np, 0);
	init.parent_names = &parent_name;
	init.num_parents = 1;

	pll->hw.init = &init;

	clk = clk_register(NULL, &pll->hw);
	if (WARN_ON(IS_ERR(clk)))
		return;

	ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
	if (WARN_ON(ret))
		return;
}
CLK_OF_DECLARE(zynq_pll, "xlnx,zynq-pll", zynq_pll_clk_setup);

struct zynq_periph_clk {
	struct clk_hw		hw;
	struct clk_onecell_data	onecell_data;
	struct clk		*gates[2];
	void __iomem		*clk_ctrl;
	spinlock_t		clkact_lock;
};

#define to_zynq_periph_clk(hw)	container_of(hw, struct zynq_periph_clk, hw)

static const u8 periph_clk_parent_map[] = {
	0, 0, 1, 2
};
#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x) & 0x30) >> 4])
#define PERIPH_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)

static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw,
					     unsigned long parent_rate)
{
	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
	return parent_rate / PERIPH_CLK_CTRL_DIV(ioread32(periph->clk_ctrl));
}

static u8 zynq_periph_get_parent(struct clk_hw *hw)
{
	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
	return PERIPH_CLK_CTRL_SRC(ioread32(periph->clk_ctrl));
}

static const struct clk_ops zynq_periph_clk_ops = {
	.recalc_rate	= zynq_periph_recalc_rate,
	.get_parent	= zynq_periph_get_parent,
};

static void __init zynq_periph_clk_setup(struct device_node *np)
{
	struct zynq_periph_clk *periph;
	const char *parent_names[3];
	struct clk_init_data init;
	int clk_num = 0, err;
	const char *name;
	struct clk *clk;
	u32 reg;
	int i;

	err = of_property_read_u32(np, "reg", &reg);
	if (WARN_ON(err))
		return;

	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
	if (WARN_ON(!periph))
		return;

	periph->clk_ctrl = slcr_base + reg;
	spin_lock_init(&periph->clkact_lock);

	init.name = np->name;
	init.ops = &zynq_periph_clk_ops;
	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
		parent_names[i] = of_clk_get_parent_name(np, i);
	init.parent_names = parent_names;
	init.num_parents = ARRAY_SIZE(parent_names);

	periph->hw.init = &init;

	clk = clk_register(NULL, &periph->hw);
	if (WARN_ON(IS_ERR(clk)))
		return;

	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
	if (WARN_ON(err))
		return;

	err = of_property_read_string_index(np, "clock-output-names", 0,
					    &name);
	if (WARN_ON(err))
		return;

	periph->gates[0] = clk_register_gate(NULL, name, np->name, 0,
					     periph->clk_ctrl, 0, 0,
					     &periph->clkact_lock);
	if (WARN_ON(IS_ERR(periph->gates[0])))
		return;
	clk_num++;

	/* some periph clks have 2 downstream gates */
	err = of_property_read_string_index(np, "clock-output-names", 1,
					    &name);
	if (err != -ENODATA) {
		periph->gates[1] = clk_register_gate(NULL, name, np->name, 0,
						     periph->clk_ctrl, 1, 0,
						     &periph->clkact_lock);
		if (WARN_ON(IS_ERR(periph->gates[1])))
			return;
		clk_num++;
	}

	periph->onecell_data.clks = periph->gates;
	periph->onecell_data.clk_num = clk_num;

	err = of_clk_add_provider(np, of_clk_src_onecell_get,
				  &periph->onecell_data);
	if (WARN_ON(err))
		return;
}
CLK_OF_DECLARE(zynq_periph, "xlnx,zynq-periph-clock", zynq_periph_clk_setup);

/* CPU Clock domain is modelled as a mux with 4 children subclks, whose
 * derivative rates depend on CLK_621_TRUE
 */

struct zynq_cpu_clk {
	struct clk_hw		hw;
	struct clk_onecell_data	onecell_data;
	struct clk		*subclks[4];
	void __iomem		*clk_ctrl;
	spinlock_t		clkact_lock;
};

#define to_zynq_cpu_clk(hw)	container_of(hw, struct zynq_cpu_clk, hw)

static const u8 zynq_cpu_clk_parent_map[] = {
	1, 1, 2, 0
};
#define CPU_CLK_SRCSEL(x)	(zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
#define CPU_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)

static u8 zynq_cpu_clk_get_parent(struct clk_hw *hw)
{
	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
	return CPU_CLK_SRCSEL(ioread32(cpuclk->clk_ctrl));
}

static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw,
					      unsigned long parent_rate)
{
	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
	return parent_rate / CPU_CLK_CTRL_DIV(ioread32(cpuclk->clk_ctrl));
}

static const struct clk_ops zynq_cpu_clk_ops = {
	.get_parent	= zynq_cpu_clk_get_parent,
	.recalc_rate	= zynq_cpu_clk_recalc_rate,
};

struct zynq_cpu_subclk {
	struct clk_hw	hw;
	void __iomem	*clk_621;
	enum {
		CPU_SUBCLK_6X4X,
		CPU_SUBCLK_3X2X,
		CPU_SUBCLK_2X,
		CPU_SUBCLK_1X,
	} which;
};

#define CLK_621_TRUE(x)	((x) & 1)

#define to_zynq_cpu_subclk(hw)	container_of(hw, struct zynq_cpu_subclk, hw);

static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw,
						 unsigned long parent_rate)
{
	unsigned long uninitialized_var(rate);
	struct zynq_cpu_subclk *subclk;
	bool is_621;

	subclk = to_zynq_cpu_subclk(hw)
	is_621 = CLK_621_TRUE(ioread32(subclk->clk_621));

	switch (subclk->which) {
	case CPU_SUBCLK_6X4X:
		rate = parent_rate;
		break;
	case CPU_SUBCLK_3X2X:
		rate = parent_rate / 2;
		break;
	case CPU_SUBCLK_2X:
		rate = parent_rate / (is_621 ? 3 : 2);
		break;
	case CPU_SUBCLK_1X:
		rate = parent_rate / (is_621 ? 6 : 4);
		break;
	};

	return rate;
}

static const struct clk_ops zynq_cpu_subclk_ops = {
	.recalc_rate	= zynq_cpu_subclk_recalc_rate,
};

static struct clk *zynq_cpu_subclk_setup(struct device_node *np, u8 which,
					 void __iomem *clk_621)
{
	struct zynq_cpu_subclk *subclk;
	struct clk_init_data init;
	struct clk *clk;
	int err;

	err = of_property_read_string_index(np, "clock-output-names",
					    which, &init.name);
	if (WARN_ON(err))
		goto err_read_output_name;

	subclk = kzalloc(sizeof(*subclk), GFP_KERNEL);
	if (!subclk)
		goto err_subclk_alloc;

	subclk->clk_621 = clk_621;
	subclk->which = which;

	init.ops = &zynq_cpu_subclk_ops;
	init.parent_names = &np->name;
	init.num_parents = 1;

	subclk->hw.init = &init;

	clk = clk_register(NULL, &subclk->hw);
	if (WARN_ON(IS_ERR(clk)))
		goto err_clk_register;

	return clk;

err_clk_register:
	kfree(subclk);
err_subclk_alloc:
err_read_output_name:
	return ERR_PTR(-EINVAL);
}

static void __init zynq_cpu_clk_setup(struct device_node *np)
{
	struct zynq_cpu_clk *cpuclk;
	const char *parent_names[3];
	struct clk_init_data init;
	void __iomem *clk_621;
	struct clk *clk;
	u32 reg[2];
	int err;
	int i;

	err = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
	if (WARN_ON(err))
		return;

	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
	if (WARN_ON(!cpuclk))
		return;

	cpuclk->clk_ctrl = slcr_base + reg[0];
	clk_621 = slcr_base + reg[1];
	spin_lock_init(&cpuclk->clkact_lock);

	init.name = np->name;
	init.ops = &zynq_cpu_clk_ops;
	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
		parent_names[i] = of_clk_get_parent_name(np, i);
	init.parent_names = parent_names;
	init.num_parents = ARRAY_SIZE(parent_names);

	cpuclk->hw.init = &init;

	clk = clk_register(NULL, &cpuclk->hw);
	if (WARN_ON(IS_ERR(clk)))
		return;

	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
	if (WARN_ON(err))
		return;

	for (i = 0; i < 4; i++) {
		cpuclk->subclks[i] = zynq_cpu_subclk_setup(np, i, clk_621);
		if (WARN_ON(IS_ERR(cpuclk->subclks[i])))
			return;
	}

	cpuclk->onecell_data.clks = cpuclk->subclks;
	cpuclk->onecell_data.clk_num = i;

	err = of_clk_add_provider(np, of_clk_src_onecell_get,
				  &cpuclk->onecell_data);
	if (WARN_ON(err))
		return;
}
CLK_OF_DECLARE(zynq_cpu, "xlnx,zynq-cpu-clock", zynq_cpu_clk_setup);

void __init xilinx_zynq_clocks_init(void __iomem *slcr)
{
	slcr_base = slcr;
	of_clk_init(NULL);
}
