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

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

struct sh73a0_cpg {
	struct clk_onecell_data data;
	spinlock_t lock;
};

#define CPG_FRQCRA	0x00
#define CPG_FRQCRB	0x04
#define CPG_SD0CKCR	0x74
#define CPG_SD1CKCR	0x78
#define CPG_SD2CKCR	0x7c
#define CPG_PLLECR	0xd0
#define CPG_PLL0CR	0xd8
#define CPG_PLL1CR	0x28
#define CPG_PLL2CR	0x2c
#define CPG_PLL3CR	0xdc
#define CPG_CKSCR	0xc0
#define CPG_DSI0PHYCR	0x6c
#define CPG_DSI1PHYCR	0x70

#define CLK_ENABLE_ON_INIT BIT(0)

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

static const struct div4_clk div4_clks[] = {
	{ "zg", "pll0", CPG_FRQCRA, 16 },
	{ "m3", "pll1", CPG_FRQCRA, 12 },
	{ "b",  "pll1", CPG_FRQCRA,  8 },
	{ "m1", "pll1", CPG_FRQCRA,  4 },
	{ "m2", "pll1", CPG_FRQCRA,  0 },
	{ "zx", "pll1", CPG_FRQCRB, 12 },
	{ "hp", "pll1", CPG_FRQCRB,  4 },
	{ NULL, 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, 7 }, { 0, 0 }
};

static const struct clk_div_table z_div_table[] = {
	/* ZSEL == 0 */
	{ 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 },
	{ 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 },
	{ 12, 1 }, { 13, 1 }, { 14, 1 }, { 15, 1 },
	/* ZSEL == 1 */
	{ 16, 2 }, { 17, 3 }, { 18, 4 }, { 19, 6 }, { 20, 8 }, { 21, 12 },
	{ 22, 16 }, { 24, 24 }, { 27, 48 }, { 0, 0 }
};

static struct clk * __init
sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg,
			  void __iomem *base, const char *name)
{
	const struct clk_div_table *table = NULL;
	unsigned int shift, reg, width;
	const char *parent_name = NULL;
	unsigned int mult = 1;
	unsigned int div = 1;

	if (!strcmp(name, "main")) {
		/* extal1, extal1_div2, extal2, extal2_div2 */
		u32 parent_idx = (readl(base + CPG_CKSCR) >> 28) & 3;

		parent_name = of_clk_get_parent_name(np, parent_idx >> 1);
		div = (parent_idx & 1) + 1;
	} else if (!strncmp(name, "pll", 3)) {
		void __iomem *enable_reg = base;
		u32 enable_bit = name[3] - '0';

		parent_name = "main";
		switch (enable_bit) {
		case 0:
			enable_reg += CPG_PLL0CR;
			break;
		case 1:
			enable_reg += CPG_PLL1CR;
			break;
		case 2:
			enable_reg += CPG_PLL2CR;
			break;
		case 3:
			enable_reg += CPG_PLL3CR;
			break;
		default:
			return ERR_PTR(-EINVAL);
		}
		if (readl(base + CPG_PLLECR) & BIT(enable_bit)) {
			mult = ((readl(enable_reg) >> 24) & 0x3f) + 1;
			/* handle CFG bit for PLL1 and PLL2 */
			if (enable_bit == 1 || enable_bit == 2)
				if (readl(enable_reg) & BIT(20))
					mult *= 2;
		}
	} else if (!strcmp(name, "dsi0phy") || !strcmp(name, "dsi1phy")) {
		u32 phy_no = name[3] - '0';
		void __iomem *dsi_reg = base +
			(phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR);

		parent_name = phy_no ? "dsi1pck" : "dsi0pck";
		mult = readl(dsi_reg);
		if (!(mult & 0x8000))
			mult = 1;
		else
			mult = (mult & 0x3f) + 1;
	} else if (!strcmp(name, "z")) {
		parent_name = "pll0";
		table = z_div_table;
		reg = CPG_FRQCRB;
		shift = 24;
		width = 5;
	} else {
		const struct div4_clk *c;

		for (c = div4_clks; c->name; c++) {
			if (!strcmp(name, c->name)) {
				parent_name = c->parent;
				table = div4_div_table;
				reg = c->reg;
				shift = c->shift;
				width = 4;
				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,
						  base + reg, shift, width, 0,
						  table, &cpg->lock);
	}
}

static void __init sh73a0_cpg_clocks_init(struct device_node *np)
{
	struct sh73a0_cpg *cpg;
	void __iomem *base;
	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;

	base = of_iomap(np, 0);
	if (WARN_ON(base == NULL))
		return;

	/* Set SDHI clocks to a known state */
	writel(0x108, base + CPG_SD0CKCR);
	writel(0x108, base + CPG_SD1CKCR);
	writel(0x108, base + CPG_SD2CKCR);

	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 = sh73a0_cpg_register_clock(np, cpg, base, name);
		if (IS_ERR(clk))
			pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
			       __func__, np, 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(sh73a0_cpg_clks, "renesas,sh73a0-cpg-clocks",
	       sh73a0_cpg_clocks_init);
