// SPDX-License-Identifier: GPL-2.0+
/*
 * Slow clock support for AT91 architectures.
 *
 * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
 *
 * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
 */

#include <clk-uclass.h>
#include <dm.h>
#include <dt-bindings/clk/at91.h>
#include <linux/clk-provider.h>

#include "pmc.h"

#define UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK	"at91-sam9x60-td-slck"
#define UBOOT_DM_CLK_AT91_SCKC			"at91-sckc"

#define AT91_OSC_SEL		BIT(24)
#define AT91_OSC_SEL_SHIFT	(24)

struct sam9x60_sckc {
	void __iomem *reg;
	const char **parent_names;
	unsigned int num_parents;
	struct clk clk;
};

#define to_sam9x60_sckc(c)	container_of(c, struct sam9x60_sckc, clk)

static int sam9x60_sckc_of_xlate(struct clk *clk,
				 struct ofnode_phandle_args *args)
{
	if (args->args_count != 1) {
		debug("AT91: SCKC: Invalid args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	clk->id = AT91_TO_CLK_ID(PMC_TYPE_SLOW, args->args[0]);

	return 0;
}

static const struct clk_ops sam9x60_sckc_ops = {
	.of_xlate = sam9x60_sckc_of_xlate,
	.get_rate = clk_generic_get_rate,
};

static int sam9x60_td_slck_set_parent(struct clk *clk, struct clk *parent)
{
	struct sam9x60_sckc *sckc = to_sam9x60_sckc(clk);
	u32 i;

	for (i = 0; i < sckc->num_parents; i++) {
		if (!strcmp(parent->dev->name, sckc->parent_names[i]))
			break;
	}
	if (i == sckc->num_parents)
		return -EINVAL;

	pmc_update_bits(sckc->reg, 0, AT91_OSC_SEL, (i << AT91_OSC_SEL_SHIFT));

	return 0;
}

static const struct clk_ops sam9x60_td_slck_ops = {
	.get_rate = clk_generic_get_rate,
	.set_parent = sam9x60_td_slck_set_parent,
};

static struct clk *at91_sam9x60_clk_register_td_slck(struct sam9x60_sckc *sckc,
		const char *name, const char * const *parent_names,
		int num_parents)
{
	struct clk *clk;
	int ret = -ENOMEM;
	u32 val, i;

	if (!sckc || !name || !parent_names || num_parents != 2)
		return ERR_PTR(-EINVAL);

	sckc->parent_names = kzalloc(sizeof(*sckc->parent_names) * num_parents,
				     GFP_KERNEL);
	if (!sckc->parent_names)
		return ERR_PTR(ret);

	for (i = 0; i < num_parents; i++) {
		sckc->parent_names[i] = kmemdup(parent_names[i],
				strlen(parent_names[i]) + 1, GFP_KERNEL);
		if (!sckc->parent_names[i])
			goto free;
	}
	sckc->num_parents = num_parents;

	pmc_read(sckc->reg, 0, &val);
	val = (val & AT91_OSC_SEL) >> AT91_OSC_SEL_SHIFT;

	clk = &sckc->clk;
	ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK, name,
			   parent_names[val]);
	if (ret)
		goto free;

	return clk;

free:
	for (; i >= 0; i--)
		kfree(sckc->parent_names[i]);
	kfree(sckc->parent_names);

	return ERR_PTR(ret);
}

U_BOOT_DRIVER(at91_sam9x60_td_slck) = {
	.name = UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK,
	.id = UCLASS_CLK,
	.ops = &sam9x60_td_slck_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

static int at91_sam9x60_sckc_probe(struct udevice *dev)
{
	struct sam9x60_sckc *sckc = dev_get_priv(dev);
	void __iomem *base = devfdt_get_addr_ptr(dev);
	const char *slow_rc_osc, *slow_osc;
	const char *parents[2];
	struct clk *clk, c;
	int ret;

	ret = clk_get_by_index(dev, 0, &c);
	if (ret)
		return ret;
	slow_rc_osc = clk_hw_get_name(&c);

	ret = clk_get_by_index(dev, 1, &c);
	if (ret)
		return ret;
	slow_osc = clk_hw_get_name(&c);

	clk = clk_register_fixed_factor(NULL, "md_slck", slow_rc_osc, 0, 1, 1);
	if (IS_ERR(clk))
		return PTR_ERR(clk);
	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SLOW, 0), clk);

	parents[0] = slow_rc_osc;
	parents[1] = slow_osc;
	sckc[1].reg = base;
	clk = at91_sam9x60_clk_register_td_slck(&sckc[1], "td_slck",
						parents, 2);
	if (IS_ERR(clk))
		return PTR_ERR(clk);
	clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SLOW, 1), clk);

	return 0;
}

static const struct udevice_id sam9x60_sckc_ids[] = {
	{ .compatible = "microchip,sam9x60-sckc" },
	{ /* Sentinel. */ },
};

U_BOOT_DRIVER(at91_sckc) = {
	.name = UBOOT_DM_CLK_AT91_SCKC,
	.id = UCLASS_CLK,
	.of_match = sam9x60_sckc_ids,
	.priv_auto	= sizeof(struct sam9x60_sckc) * 2,
	.ops = &sam9x60_sckc_ops,
	.probe = at91_sam9x60_sckc_probe,
	.flags = DM_FLAG_PRE_RELOC,
};
