/*
 * Copyright 2013 Emilio López
 *
 * Emilio López <emilio@elopez.com.ar>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "clk-factors.h"

/**
 * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
 * MOD0 rate is calculated as follows
 * rate = (parent_rate >> p) / (m + 1);
 */

static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate,
				       u8 *n, u8 *k, u8 *m, u8 *p)
{
	u8 div, calcm, calcp;

	/* These clocks can only divide, so we will never be able to achieve
	 * frequencies higher than the parent frequency */
	if (*freq > parent_rate)
		*freq = parent_rate;

	div = DIV_ROUND_UP(parent_rate, *freq);

	if (div < 16)
		calcp = 0;
	else if (div / 2 < 16)
		calcp = 1;
	else if (div / 4 < 16)
		calcp = 2;
	else
		calcp = 3;

	calcm = DIV_ROUND_UP(div, 1 << calcp);

	*freq = (parent_rate >> calcp) / calcm;

	/* we were called to round the frequency, we can now return */
	if (n == NULL)
		return;

	*m = calcm - 1;
	*p = calcp;
}

/* user manual says "n" but it's really "p" */
static struct clk_factors_config sun4i_a10_mod0_config = {
	.mshift = 0,
	.mwidth = 4,
	.pshift = 16,
	.pwidth = 2,
};

static const struct factors_data sun4i_a10_mod0_data = {
	.enable = 31,
	.mux = 24,
	.muxmask = BIT(1) | BIT(0),
	.table = &sun4i_a10_mod0_config,
	.getter = sun4i_a10_get_mod0_factors,
};

static DEFINE_SPINLOCK(sun4i_a10_mod0_lock);

static void __init sun4i_a10_mod0_setup(struct device_node *node)
{
	void __iomem *reg;

	reg = of_iomap(node, 0);
	if (!reg) {
		/*
		 * This happens with mod0 clk nodes instantiated through
		 * mfd, as those do not have their resources assigned at
		 * CLK_OF_DECLARE time yet, so do not print an error.
		 */
		return;
	}

	sunxi_factors_register(node, &sun4i_a10_mod0_data,
			       &sun4i_a10_mod0_lock, reg);
}
CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);

static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct resource *r;
	void __iomem *reg;

	if (!np)
		return -ENODEV;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(reg))
		return PTR_ERR(reg);

	sunxi_factors_register(np, &sun4i_a10_mod0_data,
			       &sun4i_a10_mod0_lock, reg);
	return 0;
}

static const struct of_device_id sun4i_a10_mod0_clk_dt_ids[] = {
	{ .compatible = "allwinner,sun4i-a10-mod0-clk" },
	{ /* sentinel */ }
};

static struct platform_driver sun4i_a10_mod0_clk_driver = {
	.driver = {
		.name = "sun4i-a10-mod0-clk",
		.of_match_table = sun4i_a10_mod0_clk_dt_ids,
	},
	.probe = sun4i_a10_mod0_clk_probe,
};
builtin_platform_driver(sun4i_a10_mod0_clk_driver);

static const struct factors_data sun9i_a80_mod0_data __initconst = {
	.enable = 31,
	.mux = 24,
	.muxmask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
	.table = &sun4i_a10_mod0_config,
	.getter = sun4i_a10_get_mod0_factors,
};

static void __init sun9i_a80_mod0_setup(struct device_node *node)
{
	void __iomem *reg;

	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(reg)) {
		pr_err("Could not get registers for mod0-clk: %s\n",
		       node->name);
		return;
	}

	sunxi_factors_register(node, &sun9i_a80_mod0_data,
			       &sun4i_a10_mod0_lock, reg);
}
CLK_OF_DECLARE(sun9i_a80_mod0, "allwinner,sun9i-a80-mod0-clk", sun9i_a80_mod0_setup);

static DEFINE_SPINLOCK(sun5i_a13_mbus_lock);

static void __init sun5i_a13_mbus_setup(struct device_node *node)
{
	struct clk *mbus;
	void __iomem *reg;

	reg = of_iomap(node, 0);
	if (!reg) {
		pr_err("Could not get registers for a13-mbus-clk\n");
		return;
	}

	mbus = sunxi_factors_register(node, &sun4i_a10_mod0_data,
				      &sun5i_a13_mbus_lock, reg);

	/* The MBUS clocks needs to be always enabled */
	__clk_get(mbus);
	clk_prepare_enable(mbus);
}
CLK_OF_DECLARE(sun5i_a13_mbus, "allwinner,sun5i-a13-mbus-clk", sun5i_a13_mbus_setup);

struct mmc_phase {
	struct clk_hw		hw;
	u8			offset;
	void __iomem		*reg;
	spinlock_t		*lock;
};

#define to_mmc_phase(_hw) container_of(_hw, struct mmc_phase, hw)

static int mmc_get_phase(struct clk_hw *hw)
{
	struct clk *mmc, *mmc_parent, *clk = hw->clk;
	struct mmc_phase *phase = to_mmc_phase(hw);
	unsigned int mmc_rate, mmc_parent_rate;
	u16 step, mmc_div;
	u32 value;
	u8 delay;

	value = readl(phase->reg);
	delay = (value >> phase->offset) & 0x3;

	if (!delay)
		return 180;

	/* Get the main MMC clock */
	mmc = clk_get_parent(clk);
	if (!mmc)
		return -EINVAL;

	/* And its rate */
	mmc_rate = clk_get_rate(mmc);
	if (!mmc_rate)
		return -EINVAL;

	/* Now, get the MMC parent (most likely some PLL) */
	mmc_parent = clk_get_parent(mmc);
	if (!mmc_parent)
		return -EINVAL;

	/* And its rate */
	mmc_parent_rate = clk_get_rate(mmc_parent);
	if (!mmc_parent_rate)
		return -EINVAL;

	/* Get MMC clock divider */
	mmc_div = mmc_parent_rate / mmc_rate;

	step = DIV_ROUND_CLOSEST(360, mmc_div);
	return delay * step;
}

static int mmc_set_phase(struct clk_hw *hw, int degrees)
{
	struct clk *mmc, *mmc_parent, *clk = hw->clk;
	struct mmc_phase *phase = to_mmc_phase(hw);
	unsigned int mmc_rate, mmc_parent_rate;
	unsigned long flags;
	u32 value;
	u8 delay;

	/* Get the main MMC clock */
	mmc = clk_get_parent(clk);
	if (!mmc)
		return -EINVAL;

	/* And its rate */
	mmc_rate = clk_get_rate(mmc);
	if (!mmc_rate)
		return -EINVAL;

	/* Now, get the MMC parent (most likely some PLL) */
	mmc_parent = clk_get_parent(mmc);
	if (!mmc_parent)
		return -EINVAL;

	/* And its rate */
	mmc_parent_rate = clk_get_rate(mmc_parent);
	if (!mmc_parent_rate)
		return -EINVAL;

	if (degrees != 180) {
		u16 step, mmc_div;

		/* Get MMC clock divider */
		mmc_div = mmc_parent_rate / mmc_rate;

		/*
		 * We can only outphase the clocks by multiple of the
		 * PLL's period.
		 *
		 * Since the MMC clock in only a divider, and the
		 * formula to get the outphasing in degrees is deg =
		 * 360 * delta / period
		 *
		 * If we simplify this formula, we can see that the
		 * only thing that we're concerned about is the number
		 * of period we want to outphase our clock from, and
		 * the divider set by the MMC clock.
		 */
		step = DIV_ROUND_CLOSEST(360, mmc_div);
		delay = DIV_ROUND_CLOSEST(degrees, step);
	} else {
		delay = 0;
	}

	spin_lock_irqsave(phase->lock, flags);
	value = readl(phase->reg);
	value &= ~GENMASK(phase->offset + 3, phase->offset);
	value |= delay << phase->offset;
	writel(value, phase->reg);
	spin_unlock_irqrestore(phase->lock, flags);

	return 0;
}

static const struct clk_ops mmc_clk_ops = {
	.get_phase	= mmc_get_phase,
	.set_phase	= mmc_set_phase,
};

/*
 * sunxi_mmc_setup - Common setup function for mmc module clocks
 *
 * The only difference between module clocks on different platforms is the
 * width of the mux register bits and the valid values, which are passed in
 * through struct factors_data. The phase clocks parts are identical.
 */
static void __init sunxi_mmc_setup(struct device_node *node,
				   const struct factors_data *data,
				   spinlock_t *lock)
{
	struct clk_onecell_data *clk_data;
	const char *parent;
	void __iomem *reg;
	int i;

	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(reg)) {
		pr_err("Couldn't map the %s clock registers\n", node->name);
		return;
	}

	clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL);
	if (!clk_data)
		return;

	clk_data->clks = kcalloc(3, sizeof(*clk_data->clks), GFP_KERNEL);
	if (!clk_data->clks)
		goto err_free_data;

	clk_data->clk_num = 3;
	clk_data->clks[0] = sunxi_factors_register(node, data, lock, reg);
	if (!clk_data->clks[0])
		goto err_free_clks;

	parent = __clk_get_name(clk_data->clks[0]);

	for (i = 1; i < 3; i++) {
		struct clk_init_data init = {
			.num_parents	= 1,
			.parent_names	= &parent,
			.ops		= &mmc_clk_ops,
		};
		struct mmc_phase *phase;

		phase = kmalloc(sizeof(*phase), GFP_KERNEL);
		if (!phase)
			continue;

		phase->hw.init = &init;
		phase->reg = reg;
		phase->lock = lock;

		if (i == 1)
			phase->offset = 8;
		else
			phase->offset = 20;

		if (of_property_read_string_index(node, "clock-output-names",
						  i, &init.name))
			init.name = node->name;

		clk_data->clks[i] = clk_register(NULL, &phase->hw);
		if (IS_ERR(clk_data->clks[i])) {
			kfree(phase);
			continue;
		}
	}

	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);

	return;

err_free_clks:
	kfree(clk_data->clks);
err_free_data:
	kfree(clk_data);
}

static DEFINE_SPINLOCK(sun4i_a10_mmc_lock);

static void __init sun4i_a10_mmc_setup(struct device_node *node)
{
	sunxi_mmc_setup(node, &sun4i_a10_mod0_data, &sun4i_a10_mmc_lock);
}
CLK_OF_DECLARE(sun4i_a10_mmc, "allwinner,sun4i-a10-mmc-clk", sun4i_a10_mmc_setup);

static DEFINE_SPINLOCK(sun9i_a80_mmc_lock);

static void __init sun9i_a80_mmc_setup(struct device_node *node)
{
	sunxi_mmc_setup(node, &sun9i_a80_mod0_data, &sun9i_a80_mmc_lock);
}
CLK_OF_DECLARE(sun9i_a80_mmc, "allwinner,sun9i-a80-mmc-clk", sun9i_a80_mmc_setup);
