// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * drivers/clk/at91/sckc.c
 *
 *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
 */

#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>

#include <dt-bindings/clock/at91.h>

#define SLOW_CLOCK_FREQ		32768
#define SLOWCK_SW_CYCLES	5
#define SLOWCK_SW_TIME_USEC	((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
				 SLOW_CLOCK_FREQ)

#define	AT91_SCKC_CR			0x00

struct clk_slow_bits {
	u32 cr_rcen;
	u32 cr_osc32en;
	u32 cr_osc32byp;
	u32 cr_oscsel;
};

struct clk_slow_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long startup_usec;
};

#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)

struct clk_sama5d4_slow_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long startup_usec;
	bool prepared;
};

#define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)

struct clk_slow_rc_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long frequency;
	unsigned long accuracy;
	unsigned long startup_usec;
};

#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)

struct clk_sam9x5_slow {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	u8 parent;
};

#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)

static int clk_slow_osc_prepare(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en))
		return 0;

	writel(tmp | osc->bits->cr_osc32en, sckcr);

	if (system_state < SYSTEM_RUNNING)
		udelay(osc->startup_usec);
	else
		usleep_range(osc->startup_usec, osc->startup_usec + 1);

	return 0;
}

static void clk_slow_osc_unprepare(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & osc->bits->cr_osc32byp)
		return;

	writel(tmp & ~osc->bits->cr_osc32en, sckcr);
}

static int clk_slow_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & osc->bits->cr_osc32byp)
		return 1;

	return !!(tmp & osc->bits->cr_osc32en);
}

static const struct clk_ops slow_osc_ops = {
	.prepare = clk_slow_osc_prepare,
	.unprepare = clk_slow_osc_unprepare,
	.is_prepared = clk_slow_osc_is_prepared,
};

static struct clk_hw * __init
at91_clk_register_slow_osc(void __iomem *sckcr,
			   const char *name,
			   const struct clk_parent_data *parent_data,
			   unsigned long startup,
			   bool bypass,
			   const struct clk_slow_bits *bits)
{
	struct clk_slow_osc *osc;
	struct clk_hw *hw;
	struct clk_init_data init = {};
	int ret;

	if (!sckcr || !name || !parent_data)
		return ERR_PTR(-EINVAL);

	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
	if (!osc)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &slow_osc_ops;
	init.parent_data = parent_data;
	init.num_parents = 1;
	init.flags = CLK_IGNORE_UNUSED;

	osc->hw.init = &init;
	osc->sckcr = sckcr;
	osc->startup_usec = startup;
	osc->bits = bits;

	if (bypass)
		writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
					osc->bits->cr_osc32byp, sckcr);

	hw = &osc->hw;
	ret = clk_hw_register(NULL, &osc->hw);
	if (ret) {
		kfree(osc);
		hw = ERR_PTR(ret);
	}

	return hw;
}

static void at91_clk_unregister_slow_osc(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);

	clk_hw_unregister(hw);
	kfree(osc);
}

static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
						 unsigned long parent_rate)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);

	return osc->frequency;
}

static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
						     unsigned long parent_acc)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);

	return osc->accuracy;
}

static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
	void __iomem *sckcr = osc->sckcr;

	writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);

	if (system_state < SYSTEM_RUNNING)
		udelay(osc->startup_usec);
	else
		usleep_range(osc->startup_usec, osc->startup_usec + 1);

	return 0;
}

static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
	void __iomem *sckcr = osc->sckcr;

	writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr);
}

static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);

	return !!(readl(osc->sckcr) & osc->bits->cr_rcen);
}

static const struct clk_ops slow_rc_osc_ops = {
	.prepare = clk_slow_rc_osc_prepare,
	.unprepare = clk_slow_rc_osc_unprepare,
	.is_prepared = clk_slow_rc_osc_is_prepared,
	.recalc_rate = clk_slow_rc_osc_recalc_rate,
	.recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
};

static struct clk_hw * __init
at91_clk_register_slow_rc_osc(void __iomem *sckcr,
			      const char *name,
			      unsigned long frequency,
			      unsigned long accuracy,
			      unsigned long startup,
			      const struct clk_slow_bits *bits)
{
	struct clk_slow_rc_osc *osc;
	struct clk_hw *hw;
	struct clk_init_data init;
	int ret;

	if (!sckcr || !name)
		return ERR_PTR(-EINVAL);

	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
	if (!osc)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &slow_rc_osc_ops;
	init.parent_names = NULL;
	init.num_parents = 0;
	init.flags = CLK_IGNORE_UNUSED;

	osc->hw.init = &init;
	osc->sckcr = sckcr;
	osc->bits = bits;
	osc->frequency = frequency;
	osc->accuracy = accuracy;
	osc->startup_usec = startup;

	hw = &osc->hw;
	ret = clk_hw_register(NULL, &osc->hw);
	if (ret) {
		kfree(osc);
		hw = ERR_PTR(ret);
	}

	return hw;
}

static void at91_clk_unregister_slow_rc_osc(struct clk_hw *hw)
{
	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);

	clk_hw_unregister(hw);
	kfree(osc);
}

static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
	void __iomem *sckcr = slowck->sckcr;
	u32 tmp;

	if (index > 1)
		return -EINVAL;

	tmp = readl(sckcr);

	if ((!index && !(tmp & slowck->bits->cr_oscsel)) ||
	    (index && (tmp & slowck->bits->cr_oscsel)))
		return 0;

	if (index)
		tmp |= slowck->bits->cr_oscsel;
	else
		tmp &= ~slowck->bits->cr_oscsel;

	writel(tmp, sckcr);

	if (system_state < SYSTEM_RUNNING)
		udelay(SLOWCK_SW_TIME_USEC);
	else
		usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);

	return 0;
}

static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
{
	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);

	return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel);
}

static const struct clk_ops sam9x5_slow_ops = {
	.determine_rate = clk_hw_determine_rate_no_reparent,
	.set_parent = clk_sam9x5_slow_set_parent,
	.get_parent = clk_sam9x5_slow_get_parent,
};

static struct clk_hw * __init
at91_clk_register_sam9x5_slow(void __iomem *sckcr,
			      const char *name,
			      const struct clk_hw **parent_hws,
			      int num_parents,
			      const struct clk_slow_bits *bits)
{
	struct clk_sam9x5_slow *slowck;
	struct clk_hw *hw;
	struct clk_init_data init = {};
	int ret;

	if (!sckcr || !name || !parent_hws || !num_parents)
		return ERR_PTR(-EINVAL);

	slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
	if (!slowck)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &sam9x5_slow_ops;
	init.parent_hws = parent_hws;
	init.num_parents = num_parents;
	init.flags = 0;

	slowck->hw.init = &init;
	slowck->sckcr = sckcr;
	slowck->bits = bits;
	slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);

	hw = &slowck->hw;
	ret = clk_hw_register(NULL, &slowck->hw);
	if (ret) {
		kfree(slowck);
		hw = ERR_PTR(ret);
	}

	return hw;
}

static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw)
{
	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);

	clk_hw_unregister(hw);
	kfree(slowck);
}

static void __init at91sam9x5_sckc_register(struct device_node *np,
					    unsigned int rc_osc_startup_us,
					    const struct clk_slow_bits *bits)
{
	void __iomem *regbase = of_iomap(np, 0);
	struct device_node *child = NULL;
	const char *xtal_name;
	struct clk_hw *slow_rc, *slow_osc, *slowck;
	static struct clk_parent_data parent_data = {
		.name = "slow_xtal",
	};
	const struct clk_hw *parent_hws[2];
	bool bypass;
	int ret;

	if (!regbase)
		return;

	slow_rc = at91_clk_register_slow_rc_osc(regbase, "slow_rc_osc",
						32768, 50000000,
						rc_osc_startup_us, bits);
	if (IS_ERR(slow_rc))
		return;

	xtal_name = of_clk_get_parent_name(np, 0);
	if (!xtal_name) {
		/* DT backward compatibility */
		child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
		if (!child)
			goto unregister_slow_rc;

		xtal_name = of_clk_get_parent_name(child, 0);
		bypass = of_property_read_bool(child, "atmel,osc-bypass");

		child =  of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
	} else {
		bypass = of_property_read_bool(np, "atmel,osc-bypass");
	}

	if (!xtal_name)
		goto unregister_slow_rc;

	parent_data.fw_name = xtal_name;

	slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
					      &parent_data, 1200000, bypass, bits);
	if (IS_ERR(slow_osc))
		goto unregister_slow_rc;

	parent_hws[0] = slow_rc;
	parent_hws[1] = slow_osc;
	slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_hws,
					       2, bits);
	if (IS_ERR(slowck))
		goto unregister_slow_osc;

	/* DT backward compatibility */
	if (child)
		ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get,
					     slowck);
	else
		ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);

	if (WARN_ON(ret))
		goto unregister_slowck;

	return;

unregister_slowck:
	at91_clk_unregister_sam9x5_slow(slowck);
unregister_slow_osc:
	at91_clk_unregister_slow_osc(slow_osc);
unregister_slow_rc:
	at91_clk_unregister_slow_rc_osc(slow_rc);
}

static const struct clk_slow_bits at91sam9x5_bits = {
	.cr_rcen = BIT(0),
	.cr_osc32en = BIT(1),
	.cr_osc32byp = BIT(2),
	.cr_oscsel = BIT(3),
};

static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
{
	at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits);
}
CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
	       of_at91sam9x5_sckc_setup);

static void __init of_sama5d3_sckc_setup(struct device_node *np)
{
	at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits);
}
CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
	       of_sama5d3_sckc_setup);

static const struct clk_slow_bits at91sam9x60_bits = {
	.cr_osc32en = BIT(1),
	.cr_osc32byp = BIT(2),
	.cr_oscsel = BIT(24),
};

static void __init of_sam9x60_sckc_setup(struct device_node *np)
{
	void __iomem *regbase = of_iomap(np, 0);
	struct clk_hw_onecell_data *clk_data;
	struct clk_hw *slow_rc, *slow_osc, *hw;
	const char *xtal_name;
	const struct clk_hw *parent_hws[2];
	static struct clk_parent_data parent_data = {
		.name = "slow_xtal",
	};
	bool bypass;
	int ret;

	if (!regbase)
		return;

	slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, "slow_rc_osc",
							   NULL, 0, 32768,
							   93750000);
	if (IS_ERR(slow_rc))
		return;

	xtal_name = of_clk_get_parent_name(np, 0);
	if (!xtal_name)
		goto unregister_slow_rc;

	parent_data.fw_name = xtal_name;
	bypass = of_property_read_bool(np, "atmel,osc-bypass");
	slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc",
					      &parent_data, 5000000, bypass,
					      &at91sam9x60_bits);
	if (IS_ERR(slow_osc))
		goto unregister_slow_rc;

	clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
	if (!clk_data)
		goto unregister_slow_osc;

	/* MD_SLCK and TD_SLCK. */
	clk_data->num = 2;
	hw = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", slow_rc,
						  0, 32768);
	if (IS_ERR(hw))
		goto clk_data_free;
	clk_data->hws[SCKC_MD_SLCK] = hw;

	parent_hws[0] = slow_rc;
	parent_hws[1] = slow_osc;
	hw = at91_clk_register_sam9x5_slow(regbase, "td_slck", parent_hws,
					   2, &at91sam9x60_bits);
	if (IS_ERR(hw))
		goto unregister_md_slck;
	clk_data->hws[SCKC_TD_SLCK] = hw;

	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
	if (WARN_ON(ret))
		goto unregister_td_slck;

	return;

unregister_td_slck:
	at91_clk_unregister_sam9x5_slow(clk_data->hws[SCKC_TD_SLCK]);
unregister_md_slck:
	clk_hw_unregister(clk_data->hws[SCKC_MD_SLCK]);
clk_data_free:
	kfree(clk_data);
unregister_slow_osc:
	at91_clk_unregister_slow_osc(slow_osc);
unregister_slow_rc:
	clk_hw_unregister(slow_rc);
}
CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
	       of_sam9x60_sckc_setup);

static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
{
	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);

	if (osc->prepared)
		return 0;

	/*
	 * Assume that if it has already been selected (for example by the
	 * bootloader), enough time has already passed.
	 */
	if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) {
		osc->prepared = true;
		return 0;
	}

	if (system_state < SYSTEM_RUNNING)
		udelay(osc->startup_usec);
	else
		usleep_range(osc->startup_usec, osc->startup_usec + 1);
	osc->prepared = true;

	return 0;
}

static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);

	return osc->prepared;
}

static const struct clk_ops sama5d4_slow_osc_ops = {
	.prepare = clk_sama5d4_slow_osc_prepare,
	.is_prepared = clk_sama5d4_slow_osc_is_prepared,
};

static const struct clk_slow_bits at91sama5d4_bits = {
	.cr_oscsel = BIT(3),
};

static void __init of_sama5d4_sckc_setup(struct device_node *np)
{
	void __iomem *regbase = of_iomap(np, 0);
	struct clk_hw *slow_rc, *slowck;
	struct clk_sama5d4_slow_osc *osc;
	struct clk_init_data init = {};
	const char *xtal_name;
	const struct clk_hw *parent_hws[2];
	static struct clk_parent_data parent_data = {
		.name = "slow_xtal",
	};
	int ret;

	if (!regbase)
		return;

	slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL,
							   "slow_rc_osc",
							   NULL, 0, 32768,
							   250000000);
	if (IS_ERR(slow_rc))
		return;

	xtal_name = of_clk_get_parent_name(np, 0);
	if (!xtal_name)
		goto unregister_slow_rc;
	parent_data.fw_name = xtal_name;

	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
	if (!osc)
		goto unregister_slow_rc;

	init.name = "slow_osc";
	init.ops = &sama5d4_slow_osc_ops;
	init.parent_data = &parent_data;
	init.num_parents = 1;
	init.flags = CLK_IGNORE_UNUSED;

	osc->hw.init = &init;
	osc->sckcr = regbase;
	osc->startup_usec = 1200000;
	osc->bits = &at91sama5d4_bits;

	ret = clk_hw_register(NULL, &osc->hw);
	if (ret)
		goto free_slow_osc_data;

	parent_hws[0] = slow_rc;
	parent_hws[1] = &osc->hw;
	slowck = at91_clk_register_sam9x5_slow(regbase, "slowck",
					       parent_hws, 2,
					       &at91sama5d4_bits);
	if (IS_ERR(slowck))
		goto unregister_slow_osc;

	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck);
	if (WARN_ON(ret))
		goto unregister_slowck;

	return;

unregister_slowck:
	at91_clk_unregister_sam9x5_slow(slowck);
unregister_slow_osc:
	clk_hw_unregister(&osc->hw);
free_slow_osc_data:
	kfree(osc);
unregister_slow_rc:
	clk_hw_unregister(slow_rc);
}
CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
	       of_sama5d4_sckc_setup);
