/*
 * Nomadik clock implementation
 * Copyright (C) 2013 ST-Ericsson AB
 * License terms: GNU General Public License (GPL) version 2
 * Author: Linus Walleij <linus.walleij@linaro.org>
 */

#define pr_fmt(fmt) "Nomadik SRC clocks: " fmt

#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/reboot.h>

/*
 * The Nomadik clock tree is described in the STN8815A12 DB V4.2
 * reference manual for the chip, page 94 ff.
 * Clock IDs are in the STn8815 Reference Manual table 3, page 27.
 */

#define SRC_CR			0x00U
#define SRC_CR_T0_ENSEL		BIT(15)
#define SRC_CR_T1_ENSEL		BIT(17)
#define SRC_CR_T2_ENSEL		BIT(19)
#define SRC_CR_T3_ENSEL		BIT(21)
#define SRC_CR_T4_ENSEL		BIT(23)
#define SRC_CR_T5_ENSEL		BIT(25)
#define SRC_CR_T6_ENSEL		BIT(27)
#define SRC_CR_T7_ENSEL		BIT(29)
#define SRC_XTALCR		0x0CU
#define SRC_XTALCR_XTALTIMEN	BIT(20)
#define SRC_XTALCR_SXTALDIS	BIT(19)
#define SRC_XTALCR_MXTALSTAT	BIT(2)
#define SRC_XTALCR_MXTALEN	BIT(1)
#define SRC_XTALCR_MXTALOVER	BIT(0)
#define SRC_PLLCR		0x10U
#define SRC_PLLCR_PLLTIMEN	BIT(29)
#define SRC_PLLCR_PLL2EN	BIT(28)
#define SRC_PLLCR_PLL1STAT	BIT(2)
#define SRC_PLLCR_PLL1EN	BIT(1)
#define SRC_PLLCR_PLL1OVER	BIT(0)
#define SRC_PLLFR		0x14U
#define SRC_PCKEN0		0x24U
#define SRC_PCKDIS0		0x28U
#define SRC_PCKENSR0		0x2CU
#define SRC_PCKSR0		0x30U
#define SRC_PCKEN1		0x34U
#define SRC_PCKDIS1		0x38U
#define SRC_PCKENSR1		0x3CU
#define SRC_PCKSR1		0x40U

/* Lock protecting the SRC_CR register */
static DEFINE_SPINLOCK(src_lock);
/* Base address of the SRC */
static void __iomem *src_base;

static int nomadik_clk_reboot_handler(struct notifier_block *this,
				unsigned long code,
				void *unused)
{
	u32 val;

	/* The main chrystal need to be enabled for reboot to work */
	val = readl(src_base + SRC_XTALCR);
	val &= ~SRC_XTALCR_MXTALOVER;
	val |= SRC_XTALCR_MXTALEN;
	pr_crit("force-enabling MXTALO\n");
	writel(val, src_base + SRC_XTALCR);
	return NOTIFY_OK;
}

static struct notifier_block nomadik_clk_reboot_notifier = {
	.notifier_call = nomadik_clk_reboot_handler,
};

static const struct of_device_id nomadik_src_match[] __initconst = {
	{ .compatible = "stericsson,nomadik-src" },
	{ /* sentinel */ }
};

static void __init nomadik_src_init(void)
{
	struct device_node *np;
	u32 val;

	np = of_find_matching_node(NULL, nomadik_src_match);
	if (!np) {
		pr_crit("no matching node for SRC, aborting clock init\n");
		return;
	}
	src_base = of_iomap(np, 0);
	if (!src_base) {
		pr_err("%s: must have src parent node with REGS (%s)\n",
		       __func__, np->name);
		return;
	}

	/* Set all timers to use the 2.4 MHz TIMCLK */
	val = readl(src_base + SRC_CR);
	val |= SRC_CR_T0_ENSEL;
	val |= SRC_CR_T1_ENSEL;
	val |= SRC_CR_T2_ENSEL;
	val |= SRC_CR_T3_ENSEL;
	val |= SRC_CR_T4_ENSEL;
	val |= SRC_CR_T5_ENSEL;
	val |= SRC_CR_T6_ENSEL;
	val |= SRC_CR_T7_ENSEL;
	writel(val, src_base + SRC_CR);

	val = readl(src_base + SRC_XTALCR);
	pr_info("SXTALO is %s\n",
		(val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
	pr_info("MXTAL is %s\n",
		(val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
	if (of_property_read_bool(np, "disable-sxtalo")) {
		/* The machine uses an external oscillator circuit */
		val |= SRC_XTALCR_SXTALDIS;
		pr_info("disabling SXTALO\n");
	}
	if (of_property_read_bool(np, "disable-mxtalo")) {
		/* Disable this too: also run by external oscillator */
		val |= SRC_XTALCR_MXTALOVER;
		val &= ~SRC_XTALCR_MXTALEN;
		pr_info("disabling MXTALO\n");
	}
	writel(val, src_base + SRC_XTALCR);
	register_reboot_notifier(&nomadik_clk_reboot_notifier);
}

/**
 * struct clk_pll1 - Nomadik PLL1 clock
 * @hw: corresponding clock hardware entry
 * @id: PLL instance: 1 or 2
 */
struct clk_pll {
	struct clk_hw hw;
	int id;
};

/**
 * struct clk_src - Nomadik src clock
 * @hw: corresponding clock hardware entry
 * @id: the clock ID
 * @group1: true if the clock is in group1, else it is in group0
 * @clkbit: bit 0...31 corresponding to the clock in each clock register
 */
struct clk_src {
	struct clk_hw hw;
	int id;
	bool group1;
	u32 clkbit;
};

#define to_pll(_hw) container_of(_hw, struct clk_pll, hw)
#define to_src(_hw) container_of(_hw, struct clk_src, hw)

static int pll_clk_enable(struct clk_hw *hw)
{
	struct clk_pll *pll = to_pll(hw);
	u32 val;

	spin_lock(&src_lock);
	val = readl(src_base + SRC_PLLCR);
	if (pll->id == 1) {
		if (val & SRC_PLLCR_PLL1OVER) {
			val |= SRC_PLLCR_PLL1EN;
			writel(val, src_base + SRC_PLLCR);
		}
	} else if (pll->id == 2) {
		val |= SRC_PLLCR_PLL2EN;
		writel(val, src_base + SRC_PLLCR);
	}
	spin_unlock(&src_lock);
	return 0;
}

static void pll_clk_disable(struct clk_hw *hw)
{
	struct clk_pll *pll = to_pll(hw);
	u32 val;

	spin_lock(&src_lock);
	val = readl(src_base + SRC_PLLCR);
	if (pll->id == 1) {
		if (val & SRC_PLLCR_PLL1OVER) {
			val &= ~SRC_PLLCR_PLL1EN;
			writel(val, src_base + SRC_PLLCR);
		}
	} else if (pll->id == 2) {
		val &= ~SRC_PLLCR_PLL2EN;
		writel(val, src_base + SRC_PLLCR);
	}
	spin_unlock(&src_lock);
}

static int pll_clk_is_enabled(struct clk_hw *hw)
{
	struct clk_pll *pll = to_pll(hw);
	u32 val;

	val = readl(src_base + SRC_PLLCR);
	if (pll->id == 1) {
		if (val & SRC_PLLCR_PLL1OVER)
			return !!(val & SRC_PLLCR_PLL1EN);
	} else if (pll->id == 2) {
		return !!(val & SRC_PLLCR_PLL2EN);
	}
	return 1;
}

static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
					  unsigned long parent_rate)
{
	struct clk_pll *pll = to_pll(hw);
	u32 val;

	val = readl(src_base + SRC_PLLFR);

	if (pll->id == 1) {
		u8 mul;
		u8 div;

		mul = (val >> 8) & 0x3FU;
		mul += 2;
		div = val & 0x07U;
		return (parent_rate * mul) >> div;
	}

	if (pll->id == 2) {
		u8 mul;

		mul = (val >> 24) & 0x3FU;
		mul += 2;
		return (parent_rate * mul);
	}

	/* Unknown PLL */
	return 0;
}


static const struct clk_ops pll_clk_ops = {
	.enable = pll_clk_enable,
	.disable = pll_clk_disable,
	.is_enabled = pll_clk_is_enabled,
	.recalc_rate = pll_clk_recalc_rate,
};

static struct clk_hw * __init
pll_clk_register(struct device *dev, const char *name,
		 const char *parent_name, u32 id)
{
	int ret;
	struct clk_pll *pll;
	struct clk_init_data init;

	if (id != 1 && id != 2) {
		pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
	if (!pll) {
		pr_err("%s: could not allocate PLL clk\n", __func__);
		return ERR_PTR(-ENOMEM);
	}

	init.name = name;
	init.ops = &pll_clk_ops;
	init.parent_names = (parent_name ? &parent_name : NULL);
	init.num_parents = (parent_name ? 1 : 0);
	pll->hw.init = &init;
	pll->id = id;

	pr_debug("register PLL1 clock \"%s\"\n", name);

	ret = clk_hw_register(dev, &pll->hw);
	if (ret) {
		kfree(pll);
		return ERR_PTR(ret);
	}

	return &pll->hw;
}

/*
 * The Nomadik SRC clocks are gated, but not in the sense that
 * you read-modify-write a register. Instead there are separate
 * clock enable and clock disable registers. Writing a '1' bit in
 * the enable register for a certain clock ungates that clock without
 * affecting the other clocks. The disable register works the opposite
 * way.
 */

static int src_clk_enable(struct clk_hw *hw)
{
	struct clk_src *sclk = to_src(hw);
	u32 enreg = sclk->group1 ? SRC_PCKEN1 : SRC_PCKEN0;
	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;

	writel(sclk->clkbit, src_base + enreg);
	/* spin until enabled */
	while (!(readl(src_base + sreg) & sclk->clkbit))
		cpu_relax();
	return 0;
}

static void src_clk_disable(struct clk_hw *hw)
{
	struct clk_src *sclk = to_src(hw);
	u32 disreg = sclk->group1 ? SRC_PCKDIS1 : SRC_PCKDIS0;
	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;

	writel(sclk->clkbit, src_base + disreg);
	/* spin until disabled */
	while (readl(src_base + sreg) & sclk->clkbit)
		cpu_relax();
}

static int src_clk_is_enabled(struct clk_hw *hw)
{
	struct clk_src *sclk = to_src(hw);
	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
	u32 val = readl(src_base + sreg);

	return !!(val & sclk->clkbit);
}

static unsigned long
src_clk_recalc_rate(struct clk_hw *hw,
		    unsigned long parent_rate)
{
	return parent_rate;
}

static const struct clk_ops src_clk_ops = {
	.enable = src_clk_enable,
	.disable = src_clk_disable,
	.is_enabled = src_clk_is_enabled,
	.recalc_rate = src_clk_recalc_rate,
};

static struct clk_hw * __init
src_clk_register(struct device *dev, const char *name,
		 const char *parent_name, u8 id)
{
	int ret;
	struct clk_src *sclk;
	struct clk_init_data init;

	sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
	if (!sclk) {
		pr_err("could not allocate SRC clock %s\n",
			name);
		return ERR_PTR(-ENOMEM);
	}
	init.name = name;
	init.ops = &src_clk_ops;
	/* Do not force-disable the static SDRAM controller */
	if (id == 2)
		init.flags = CLK_IGNORE_UNUSED;
	else
		init.flags = 0;
	init.parent_names = (parent_name ? &parent_name : NULL);
	init.num_parents = (parent_name ? 1 : 0);
	sclk->hw.init = &init;
	sclk->id = id;
	sclk->group1 = (id > 31);
	sclk->clkbit = BIT(id & 0x1f);

	pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
		 name, id, sclk->group1, sclk->clkbit);

	ret = clk_hw_register(dev, &sclk->hw);
	if (ret) {
		kfree(sclk);
		return ERR_PTR(ret);
	}

	return &sclk->hw;
}

#ifdef CONFIG_DEBUG_FS

static u32 src_pcksr0_boot;
static u32 src_pcksr1_boot;

static const char * const src_clk_names[] = {
	"HCLKDMA0  ",
	"HCLKSMC   ",
	"HCLKSDRAM ",
	"HCLKDMA1  ",
	"HCLKCLCD  ",
	"PCLKIRDA  ",
	"PCLKSSP   ",
	"PCLKUART0 ",
	"PCLKSDI   ",
	"PCLKI2C0  ",
	"PCLKI2C1  ",
	"PCLKUART1 ",
	"PCLMSP0   ",
	"HCLKUSB   ",
	"HCLKDIF   ",
	"HCLKSAA   ",
	"HCLKSVA   ",
	"PCLKHSI   ",
	"PCLKXTI   ",
	"PCLKUART2 ",
	"PCLKMSP1  ",
	"PCLKMSP2  ",
	"PCLKOWM   ",
	"HCLKHPI   ",
	"PCLKSKE   ",
	"PCLKHSEM  ",
	"HCLK3D    ",
	"HCLKHASH  ",
	"HCLKCRYP  ",
	"PCLKMSHC  ",
	"HCLKUSBM  ",
	"HCLKRNG   ",
	"RESERVED  ",
	"RESERVED  ",
	"RESERVED  ",
	"RESERVED  ",
	"CLDCLK    ",
	"IRDACLK   ",
	"SSPICLK   ",
	"UART0CLK  ",
	"SDICLK    ",
	"I2C0CLK   ",
	"I2C1CLK   ",
	"UART1CLK  ",
	"MSPCLK0   ",
	"USBCLK    ",
	"DIFCLK    ",
	"IPI2CCLK  ",
	"IPBMCCLK  ",
	"HSICLKRX  ",
	"HSICLKTX  ",
	"UART2CLK  ",
	"MSPCLK1   ",
	"MSPCLK2   ",
	"OWMCLK    ",
	"RESERVED  ",
	"SKECLK    ",
	"RESERVED  ",
	"3DCLK     ",
	"PCLKMSP3  ",
	"MSPCLK3   ",
	"MSHCCLK   ",
	"USBMCLK   ",
	"RNGCCLK   ",
};

static int nomadik_src_clk_show(struct seq_file *s, void *what)
{
	int i;
	u32 src_pcksr0 = readl(src_base + SRC_PCKSR0);
	u32 src_pcksr1 = readl(src_base + SRC_PCKSR1);
	u32 src_pckensr0 = readl(src_base + SRC_PCKENSR0);
	u32 src_pckensr1 = readl(src_base + SRC_PCKENSR1);

	seq_printf(s, "Clock:      Boot:   Now:    Request: ASKED:\n");
	for (i = 0; i < ARRAY_SIZE(src_clk_names); i++) {
		u32 pcksrb = (i < 0x20) ? src_pcksr0_boot : src_pcksr1_boot;
		u32 pcksr = (i < 0x20) ? src_pcksr0 : src_pcksr1;
		u32 pckreq = (i < 0x20) ? src_pckensr0 : src_pckensr1;
		u32 mask = BIT(i & 0x1f);

		seq_printf(s, "%s  %s     %s     %s\n",
			   src_clk_names[i],
			   (pcksrb & mask) ? "on " : "off",
			   (pcksr & mask) ? "on " : "off",
			   (pckreq & mask) ? "on " : "off");
	}
	return 0;
}

static int nomadik_src_clk_open(struct inode *inode, struct file *file)
{
	return single_open(file, nomadik_src_clk_show, NULL);
}

static const struct file_operations nomadik_src_clk_debugfs_ops = {
	.open           = nomadik_src_clk_open,
	.read           = seq_read,
        .llseek         = seq_lseek,
	.release        = single_release,
};

static int __init nomadik_src_clk_init_debugfs(void)
{
	/* Vital for multiplatform */
	if (!src_base)
		return -ENODEV;
	src_pcksr0_boot = readl(src_base + SRC_PCKSR0);
	src_pcksr1_boot = readl(src_base + SRC_PCKSR1);
	debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO,
			    NULL, NULL, &nomadik_src_clk_debugfs_ops);
	return 0;
}
device_initcall(nomadik_src_clk_init_debugfs);

#endif

static void __init of_nomadik_pll_setup(struct device_node *np)
{
	struct clk_hw *hw;
	const char *clk_name = np->name;
	const char *parent_name;
	u32 pll_id;

	if (!src_base)
		nomadik_src_init();

	if (of_property_read_u32(np, "pll-id", &pll_id)) {
		pr_err("%s: PLL \"%s\" missing pll-id property\n",
			__func__, clk_name);
		return;
	}
	parent_name = of_clk_get_parent_name(np, 0);
	hw = pll_clk_register(NULL, clk_name, parent_name, pll_id);
	if (!IS_ERR(hw))
		of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(nomadik_pll_clk,
	"st,nomadik-pll-clock", of_nomadik_pll_setup);

static void __init of_nomadik_hclk_setup(struct device_node *np)
{
	struct clk_hw *hw;
	const char *clk_name = np->name;
	const char *parent_name;

	if (!src_base)
		nomadik_src_init();

	parent_name = of_clk_get_parent_name(np, 0);
	/*
	 * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
	 */
	hw = clk_hw_register_divider(NULL, clk_name, parent_name,
			   0, src_base + SRC_CR,
			   13, 2,
			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
			   &src_lock);
	if (!IS_ERR(hw))
		of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(nomadik_hclk_clk,
	"st,nomadik-hclk-clock", of_nomadik_hclk_setup);

static void __init of_nomadik_src_clk_setup(struct device_node *np)
{
	struct clk_hw *hw;
	const char *clk_name = np->name;
	const char *parent_name;
	u32 clk_id;

	if (!src_base)
		nomadik_src_init();

	if (of_property_read_u32(np, "clock-id", &clk_id)) {
		pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
			__func__, clk_name);
		return;
	}
	parent_name = of_clk_get_parent_name(np, 0);
	hw = src_clk_register(NULL, clk_name, parent_name, clk_id);
	if (!IS_ERR(hw))
		of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(nomadik_src_clk,
	"st,nomadik-src-clock", of_nomadik_src_clk_setup);
