// SPDX-License-Identifier: GPL-2.0
/*
 * r8a7778 Core CPG Clocks
 *
 * Copyright (C) 2014  Ulrich Hecht
 */

#include <linux/clk-provider.h>
#include <linux/clk/renesas.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/soc/renesas/rcar-rst.h>

/* 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, 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 clk_onecell_data *data;
	struct clk **clks;
	unsigned int i;
	int num_clks;
	u32 mode;

	if (rcar_rst_read_mode_pins(&mode))
		return;

	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)));

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

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

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

	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, name);
		if (IS_ERR(clk))
			pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
			       __func__, np, name, PTR_ERR(clk));
		else
			data->clks[i] = clk;
	}

	of_clk_add_provider(np, of_clk_src_onecell_get, data);

	cpg_mstp_add_clk_domain(np);
}

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