/*
 * r8a7778 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/of_address.h>
#include <linux/slab.h>

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

/* PLL multipliers per bits 11, 12, and 18 of MODEMR */
static const struct {
	unsigned long plla_mult;
	unsigned long pllb_mult;
} r8a7778_rates[] __initconst = {
	[0] = { 21, 21 },
	[1] = { 24, 24 },
	[2] = { 28, 28 },
	[3] = { 32, 32 },
	[5] = { 24, 21 },
	[6] = { 28, 21 },
	[7] = { 32, 24 },
};

/* Clock dividers per bits 1 and 2 of MODEMR */
static const struct {
	const char *name;
	unsigned int div[4];
} r8a7778_divs[6] __initconst = {
	{ "b",   { 12, 12, 16, 18 } },
	{ "out", { 12, 12, 16, 18 } },
	{ "p",   { 16, 12, 16, 12 } },
	{ "s",   { 4,  3,  4,  3  } },
	{ "s1",  { 8,  6,  8,  6  } },
};

static u32 cpg_mode_rates __initdata;
static u32 cpg_mode_divs __initdata;

static struct clk * __init
r8a7778_cpg_register_clock(struct device_node *np, struct r8a7778_cpg *cpg,
			     const char *name)
{
	if (!strcmp(name, "plla")) {
		return clk_register_fixed_factor(NULL, "plla",
			of_clk_get_parent_name(np, 0), 0,
			r8a7778_rates[cpg_mode_rates].plla_mult, 1);
	} else if (!strcmp(name, "pllb")) {
		return clk_register_fixed_factor(NULL, "pllb",
			of_clk_get_parent_name(np, 0), 0,
			r8a7778_rates[cpg_mode_rates].pllb_mult, 1);
	} else {
		unsigned int i;

		for (i = 0; i < ARRAY_SIZE(r8a7778_divs); i++) {
			if (!strcmp(name, r8a7778_divs[i].name)) {
				return clk_register_fixed_factor(NULL,
					r8a7778_divs[i].name,
					"plla", 0, 1,
					r8a7778_divs[i].div[cpg_mode_divs]);
			}
		}
	}

	return ERR_PTR(-EINVAL);
}


static void __init r8a7778_cpg_clocks_init(struct device_node *np)
{
	struct r8a7778_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 = r8a7778_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);

	cpg_mstp_add_clk_domain(np);
}

CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks",
	       r8a7778_cpg_clocks_init);

void __init r8a7778_clocks_init(u32 mode)
{
	BUG_ON(!(mode & BIT(19)));

	cpg_mode_rates = (!!(mode & BIT(18)) << 2) |
			 (!!(mode & BIT(12)) << 1) |
			 (!!(mode & BIT(11)));
	cpg_mode_divs = (!!(mode & BIT(2)) << 1) |
			(!!(mode & BIT(1)));

	of_clk_init(NULL);
}
