/*
 * r8a73a4 Core CPG Clocks
 *
 * Copyright (C) 2014  Ulrich Hecht
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 */

#include <linux/clk-provider.h>
#include <linux/clk/renesas.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/spinlock.h>

struct r8a73a4_cpg {
	struct clk_onecell_data data;
	spinlock_t lock;
	void __iomem *reg;
};

#define CPG_CKSCR	0xc0
#define CPG_FRQCRA	0x00
#define CPG_FRQCRB	0x04
#define CPG_FRQCRC	0xe0
#define CPG_PLL0CR	0xd8
#define CPG_PLL1CR	0x28
#define CPG_PLL2CR	0x2c
#define CPG_PLL2HCR	0xe4
#define CPG_PLL2SCR	0xf4

#define CLK_ENABLE_ON_INIT BIT(0)

struct div4_clk {
	const char *name;
	unsigned int reg;
	unsigned int shift;
};

static struct div4_clk div4_clks[] = {
	{ "i",	CPG_FRQCRA, 20 },
	{ "m3", CPG_FRQCRA, 12 },
	{ "b",	CPG_FRQCRA,  8 },
	{ "m1", CPG_FRQCRA,  4 },
	{ "m2", CPG_FRQCRA,  0 },
	{ "zx", CPG_FRQCRB, 12 },
	{ "zs", CPG_FRQCRB,  8 },
	{ "hp", CPG_FRQCRB,  4 },
	{ NULL, 0, 0 },
};

static const struct clk_div_table div4_div_table[] = {
	{ 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 },
	{ 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 },
	{ 12, 10 }, { 0, 0 }
};

static struct clk * __init
r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg,
			     const char *name)
{
	const struct clk_div_table *table = NULL;
	const char *parent_name;
	unsigned int shift, reg;
	unsigned int mult = 1;
	unsigned int div = 1;


	if (!strcmp(name, "main")) {
		u32 ckscr = clk_readl(cpg->reg + CPG_CKSCR);

		switch ((ckscr >> 28) & 3) {
		case 0:	/* extal1 */
			parent_name = of_clk_get_parent_name(np, 0);
			break;
		case 1:	/* extal1 / 2 */
			parent_name = of_clk_get_parent_name(np, 0);
			div = 2;
			break;
		case 2: /* extal2 */
			parent_name = of_clk_get_parent_name(np, 1);
			break;
		case 3: /* extal2 / 2 */
			parent_name = of_clk_get_parent_name(np, 1);
			div = 2;
			break;
		}
	} else if (!strcmp(name, "pll0")) {
		/* PLL0/1 are configurable multiplier clocks. Register them as
		 * fixed factor clocks for now as there's no generic multiplier
		 * clock implementation and we currently have no need to change
		 * the multiplier value.
		 */
		u32 value = clk_readl(cpg->reg + CPG_PLL0CR);

		parent_name = "main";
		mult = ((value >> 24) & 0x7f) + 1;
		if (value & BIT(20))
			div = 2;
	} else if (!strcmp(name, "pll1")) {
		u32 value = clk_readl(cpg->reg + CPG_PLL1CR);

		parent_name = "main";
		/* XXX: enable bit? */
		mult = ((value >> 24) & 0x7f) + 1;
		if (value & BIT(7))
			div = 2;
	} else if (!strncmp(name, "pll2", 4)) {
		u32 value, cr;

		switch (name[4]) {
		case 0:
			cr = CPG_PLL2CR;
			break;
		case 's':
			cr = CPG_PLL2SCR;
			break;
		case 'h':
			cr = CPG_PLL2HCR;
			break;
		default:
			return ERR_PTR(-EINVAL);
		}
		value = clk_readl(cpg->reg + cr);
		switch ((value >> 5) & 7) {
		case 0:
			parent_name = "main";
			div = 2;
			break;
		case 1:
			parent_name = "extal2";
			div = 2;
			break;
		case 3:
			parent_name = "extal2";
			div = 4;
			break;
		case 4:
			parent_name = "main";
			break;
		case 5:
			parent_name = "extal2";
			break;
		default:
			pr_warn("%s: unexpected parent of %s\n", __func__,
				name);
			return ERR_PTR(-EINVAL);
		}
		/* XXX: enable bit? */
		mult = ((value >> 24) & 0x7f) + 1;
	} else if (!strcmp(name, "z") || !strcmp(name, "z2")) {
		u32 shift = 8;

		parent_name = "pll0";
		if (name[1] == '2') {
			div = 2;
			shift = 0;
		}
		div *= 32;
		mult = 0x20 - ((clk_readl(cpg->reg + CPG_FRQCRC) >> shift)
		       & 0x1f);
	} else {
		struct div4_clk *c;

		for (c = div4_clks; c->name; c++) {
			if (!strcmp(name, c->name))
				break;
		}
		if (!c->name)
			return ERR_PTR(-EINVAL);

		parent_name = "pll1";
		table = div4_div_table;
		reg = c->reg;
		shift = c->shift;
	}

	if (!table) {
		return clk_register_fixed_factor(NULL, name, parent_name, 0,
						 mult, div);
	} else {
		return clk_register_divider_table(NULL, name, parent_name, 0,
						  cpg->reg + reg, shift, 4, 0,
						  table, &cpg->lock);
	}
}

static void __init r8a73a4_cpg_clocks_init(struct device_node *np)
{
	struct r8a73a4_cpg *cpg;
	struct clk **clks;
	unsigned int i;
	int num_clks;

	num_clks = of_property_count_strings(np, "clock-output-names");
	if (num_clks < 0) {
		pr_err("%s: failed to count clocks\n", __func__);
		return;
	}

	cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
	clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL);
	if (cpg == NULL || clks == NULL) {
		/* We're leaking memory on purpose, there's no point in cleaning
		 * up as the system won't boot anyway.
		 */
		return;
	}

	spin_lock_init(&cpg->lock);

	cpg->data.clks = clks;
	cpg->data.clk_num = num_clks;

	cpg->reg = of_iomap(np, 0);
	if (WARN_ON(cpg->reg == NULL))
		return;

	for (i = 0; i < num_clks; ++i) {
		const char *name;
		struct clk *clk;

		of_property_read_string_index(np, "clock-output-names", i,
					      &name);

		clk = r8a73a4_cpg_register_clock(np, cpg, name);
		if (IS_ERR(clk))
			pr_err("%s: failed to register %s %s clock (%ld)\n",
			       __func__, np->name, name, PTR_ERR(clk));
		else
			cpg->data.clks[i] = clk;
	}

	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
}
CLK_OF_DECLARE(r8a73a4_cpg_clks, "renesas,r8a73a4-cpg-clocks",
	       r8a73a4_cpg_clocks_init);
