/*
 * ARTPEC-6 clock initialization
 *
 * Copyright 2015-2016 Axis Comunications AB.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/clock/axis,artpec6-clkctrl.h>

#define NUM_I2S_CLOCKS 2

struct artpec6_clkctrl_drvdata {
	struct clk *clk_table[ARTPEC6_CLK_NUMCLOCKS];
	void __iomem *syscon_base;
	struct clk_onecell_data clk_data;
	spinlock_t i2scfg_lock;
};

static struct artpec6_clkctrl_drvdata *clkdata;

static const char *const i2s_clk_names[NUM_I2S_CLOCKS] = {
	"i2s0",
	"i2s1",
};

static const int i2s_clk_indexes[NUM_I2S_CLOCKS] = {
	ARTPEC6_CLK_I2S0_CLK,
	ARTPEC6_CLK_I2S1_CLK,
};

static void of_artpec6_clkctrl_setup(struct device_node *np)
{
	int i;
	const char *sys_refclk_name;
	u32 pll_mode, pll_m, pll_n;
	struct clk **clks;

	/* Mandatory parent clock. */
	i = of_property_match_string(np, "clock-names", "sys_refclk");
	if (i < 0)
		return;

	sys_refclk_name = of_clk_get_parent_name(np, i);

	clkdata = kzalloc(sizeof(*clkdata), GFP_KERNEL);
	if (!clkdata)
		return;

	clks = clkdata->clk_table;

	for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i)
		clks[i] = ERR_PTR(-EPROBE_DEFER);

	clkdata->syscon_base = of_iomap(np, 0);
	BUG_ON(clkdata->syscon_base == NULL);

	/* Read PLL1 factors configured by boot strap pins. */
	pll_mode = (readl(clkdata->syscon_base) >> 6) & 3;
	switch (pll_mode) {
	case 0:		/* DDR3-2133 mode */
		pll_m = 4;
		pll_n = 85;
		break;
	case 1:		/* DDR3-1866 mode */
		pll_m = 6;
		pll_n = 112;
		break;
	case 2:		/* DDR3-1600 mode */
		pll_m = 4;
		pll_n = 64;
		break;
	case 3:		/* DDR3-1333 mode */
		pll_m = 8;
		pll_n = 106;
		break;
	}

	clks[ARTPEC6_CLK_CPU] =
	    clk_register_fixed_factor(NULL, "cpu", sys_refclk_name, 0, pll_n,
				      pll_m);
	clks[ARTPEC6_CLK_CPU_PERIPH] =
	    clk_register_fixed_factor(NULL, "cpu_periph", "cpu", 0, 1, 2);

	/* EPROBE_DEFER on the apb_clock is not handled in amba devices. */
	clks[ARTPEC6_CLK_UART_PCLK] =
	    clk_register_fixed_factor(NULL, "uart_pclk", "cpu", 0, 1, 8);
	clks[ARTPEC6_CLK_UART_REFCLK] =
	    clk_register_fixed_rate(NULL, "uart_ref", sys_refclk_name, 0,
				    50000000);

	clks[ARTPEC6_CLK_SPI_PCLK] =
	    clk_register_fixed_factor(NULL, "spi_pclk", "cpu", 0, 1, 8);
	clks[ARTPEC6_CLK_SPI_SSPCLK] =
	    clk_register_fixed_rate(NULL, "spi_sspclk", sys_refclk_name, 0,
				    50000000);

	clks[ARTPEC6_CLK_DBG_PCLK] =
	    clk_register_fixed_factor(NULL, "dbg_pclk", "cpu", 0, 1, 8);

	clkdata->clk_data.clks = clkdata->clk_table;
	clkdata->clk_data.clk_num = ARTPEC6_CLK_NUMCLOCKS;

	of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
}

CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl",
	       of_artpec6_clkctrl_setup);

static int artpec6_clkctrl_probe(struct platform_device *pdev)
{
	int propidx;
	struct device_node *np = pdev->dev.of_node;
	struct device *dev = &pdev->dev;
	struct clk **clks = clkdata->clk_table;
	const char *sys_refclk_name;
	const char *i2s_refclk_name = NULL;
	const char *frac_clk_name[2] = { NULL, NULL };
	const char *i2s_mux_parents[2];
	u32 muxreg;
	int i;
	int err = 0;

	/* Mandatory parent clock. */
	propidx = of_property_match_string(np, "clock-names", "sys_refclk");
	if (propidx < 0)
		return -EINVAL;

	sys_refclk_name = of_clk_get_parent_name(np, propidx);

	/* Find clock names of optional parent clocks. */
	propidx = of_property_match_string(np, "clock-names", "i2s_refclk");
	if (propidx >= 0)
		i2s_refclk_name = of_clk_get_parent_name(np, propidx);

	propidx = of_property_match_string(np, "clock-names", "frac_clk0");
	if (propidx >= 0)
		frac_clk_name[0] = of_clk_get_parent_name(np, propidx);
	propidx = of_property_match_string(np, "clock-names", "frac_clk1");
	if (propidx >= 0)
		frac_clk_name[1] = of_clk_get_parent_name(np, propidx);

	spin_lock_init(&clkdata->i2scfg_lock);

	clks[ARTPEC6_CLK_NAND_CLKA] =
	    clk_register_fixed_factor(dev, "nand_clka", "cpu", 0, 1, 8);
	clks[ARTPEC6_CLK_NAND_CLKB] =
	    clk_register_fixed_rate(dev, "nand_clkb", sys_refclk_name, 0,
				    100000000);
	clks[ARTPEC6_CLK_ETH_ACLK] =
	    clk_register_fixed_factor(dev, "eth_aclk", "cpu", 0, 1, 4);
	clks[ARTPEC6_CLK_DMA_ACLK] =
	    clk_register_fixed_factor(dev, "dma_aclk", "cpu", 0, 1, 4);
	clks[ARTPEC6_CLK_PTP_REF] =
	    clk_register_fixed_rate(dev, "ptp_ref", sys_refclk_name, 0,
				    100000000);
	clks[ARTPEC6_CLK_SD_PCLK] =
	    clk_register_fixed_rate(dev, "sd_pclk", sys_refclk_name, 0,
				    100000000);
	clks[ARTPEC6_CLK_SD_IMCLK] =
	    clk_register_fixed_rate(dev, "sd_imclk", sys_refclk_name, 0,
				    100000000);
	clks[ARTPEC6_CLK_I2S_HST] =
	    clk_register_fixed_factor(dev, "i2s_hst", "cpu", 0, 1, 8);

	for (i = 0; i < NUM_I2S_CLOCKS; ++i) {
		if (i2s_refclk_name && frac_clk_name[i]) {
			i2s_mux_parents[0] = frac_clk_name[i];
			i2s_mux_parents[1] = i2s_refclk_name;

			clks[i2s_clk_indexes[i]] =
			    clk_register_mux(dev, i2s_clk_names[i],
					     i2s_mux_parents, 2,
					     CLK_SET_RATE_NO_REPARENT |
					     CLK_SET_RATE_PARENT,
					     clkdata->syscon_base + 0x14, i, 1,
					     0, &clkdata->i2scfg_lock);
		} else if (frac_clk_name[i]) {
			/* Lock the mux for internal clock reference. */
			muxreg = readl(clkdata->syscon_base + 0x14);
			muxreg &= ~BIT(i);
			writel(muxreg, clkdata->syscon_base + 0x14);
			clks[i2s_clk_indexes[i]] =
			    clk_register_fixed_factor(dev, i2s_clk_names[i],
						      frac_clk_name[i], 0, 1,
						      1);
		} else if (i2s_refclk_name) {
			/* Lock the mux for external clock reference. */
			muxreg = readl(clkdata->syscon_base + 0x14);
			muxreg |= BIT(i);
			writel(muxreg, clkdata->syscon_base + 0x14);
			clks[i2s_clk_indexes[i]] =
			    clk_register_fixed_factor(dev, i2s_clk_names[i],
						      i2s_refclk_name, 0, 1, 1);
		}
	}

	clks[ARTPEC6_CLK_I2C] =
	    clk_register_fixed_rate(dev, "i2c", sys_refclk_name, 0, 100000000);

	clks[ARTPEC6_CLK_SYS_TIMER] =
	    clk_register_fixed_rate(dev, "timer", sys_refclk_name, 0,
				    100000000);
	clks[ARTPEC6_CLK_FRACDIV_IN] =
	    clk_register_fixed_rate(dev, "fracdiv_in", sys_refclk_name, 0,
				    600000000);

	for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i) {
		if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -EPROBE_DEFER) {
			dev_err(dev,
				"Failed to register clock at index %d err=%ld\n",
				i, PTR_ERR(clks[i]));
			err = PTR_ERR(clks[i]);
		}
	}

	return err;
}

static const struct of_device_id artpec_clkctrl_of_match[] = {
	{ .compatible = "axis,artpec6-clkctrl" },
	{}
};

static struct platform_driver artpec6_clkctrl_driver = {
	.probe = artpec6_clkctrl_probe,
	.driver = {
		   .name = "artpec6_clkctrl",
		   .of_match_table = artpec_clkctrl_of_match,
	},
};

builtin_platform_driver(artpec6_clkctrl_driver);
