// SPDX-License-Identifier: GPL-2.0-only
/*
 * ARTPEC-6 clock initialization
 *
 * Copyright 2015-2016 Axis Communications AB.
 */

#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_DRIVER(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);
