/*
 * r8a7740 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 r8a7740_cpg {
	struct clk_onecell_data data;
	spinlock_t lock;
	void __iomem *reg;
};

#define CPG_FRQCRA	0x00
#define CPG_FRQCRB	0x04
#define CPG_PLLC2CR	0x2c
#define CPG_USBCKCR	0x8c
#define CPG_FRQCRC	0xe0

#define CLK_ENABLE_ON_INIT BIT(0)

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

static struct div4_clk div4_clks[] = {
	{ "i", CPG_FRQCRA, 20, CLK_ENABLE_ON_INIT },
	{ "zg", CPG_FRQCRA, 16, CLK_ENABLE_ON_INIT },
	{ "b", CPG_FRQCRA,  8, CLK_ENABLE_ON_INIT },
	{ "m1", CPG_FRQCRA,  4, CLK_ENABLE_ON_INIT },
	{ "hp", CPG_FRQCRB,  4, 0 },
	{ "hpp", CPG_FRQCRC, 20, 0 },
	{ "usbp", CPG_FRQCRC, 16, 0 },
	{ "s", CPG_FRQCRC, 12, 0 },
	{ "zb", CPG_FRQCRC,  8, 0 },
	{ "m3", CPG_FRQCRC,  4, 0 },
	{ "cp", CPG_FRQCRC,  0, 0 },
	{ NULL, 0, 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 }, { 9, 32 }, { 10, 36 }, { 11, 48 },
	{ 13, 72 }, { 14, 96 }, { 0, 0 }
};

static u32 cpg_mode __initdata;

static struct clk * __init
r8a7740_cpg_register_clock(struct device_node *np, struct r8a7740_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, "r")) {
		switch (cpg_mode & (BIT(2) | BIT(1))) {
		case BIT(1) | BIT(2):
			/* extal1 */
			parent_name = of_clk_get_parent_name(np, 0);
			div = 2048;
			break;
		case BIT(2):
			/* extal1 */
			parent_name = of_clk_get_parent_name(np, 0);
			div = 1024;
			break;
		default:
			/* extalr */
			parent_name = of_clk_get_parent_name(np, 2);
			break;
		}
	} else if (!strcmp(name, "system")) {
		parent_name = of_clk_get_parent_name(np, 0);
		if (cpg_mode & BIT(1))
			div = 2;
	} else if (!strcmp(name, "pllc0")) {
		/* PLLC0/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 = readl(cpg->reg + CPG_FRQCRC);
		parent_name = "system";
		mult = ((value >> 24) & 0x7f) + 1;
	} else if (!strcmp(name, "pllc1")) {
		u32 value = readl(cpg->reg + CPG_FRQCRA);
		parent_name = "system";
		mult = ((value >> 24) & 0x7f) + 1;
		div = 2;
	} else if (!strcmp(name, "pllc2")) {
		u32 value = readl(cpg->reg + CPG_PLLC2CR);
		parent_name = "system";
		mult = ((value >> 24) & 0x3f) + 1;
	} else if (!strcmp(name, "usb24s")) {
		u32 value = readl(cpg->reg + CPG_USBCKCR);
		if (value & BIT(7))
			/* extal2 */
			parent_name = of_clk_get_parent_name(np, 1);
		else
			parent_name = "system";
		if (!(value & BIT(6)))
			div = 2;
	} else {
		struct div4_clk *c;
		for (c = div4_clks; c->name; c++) {
			if (!strcmp(name, c->name)) {
				parent_name = "pllc1";
				table = div4_div_table;
				reg = c->reg;
				shift = c->shift;
				break;
			}
		}
		if (!c->name)
			return ERR_PTR(-EINVAL);
	}

	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 r8a7740_cpg_clocks_init(struct device_node *np)
{
	struct r8a7740_cpg *cpg;
	struct clk **clks;
	unsigned int i;
	int num_clks;

	if (of_property_read_u32(np, "renesas,mode", &cpg_mode))
		pr_warn("%s: missing renesas,mode property\n", __func__);

	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 = r8a7740_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(r8a7740_cpg_clks, "renesas,r8a7740-cpg-clocks",
	       r8a7740_cpg_clocks_init);
