// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Programmable clock support for AT91 architectures.
 *
 * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
 *
 * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
 *
 * Based on drivers/clk/at91/clk-programmable.c from Linux.
 */
#include <clk-uclass.h>
#include <dm.h>
#include <linux/clk-provider.h>
#include <linux/clk/at91_pmc.h>

#include "pmc.h"

#define UBOOT_DM_CLK_AT91_PROG		"at91-prog-clk"

#define PROG_ID_MAX		7

#define PROG_STATUS_MASK(id)	(1 << ((id) + 8))
#define PROG_PRES(_l, _p)	(((_p) >> (_l)->pres_shift) & (_l)->pres_mask)
#define PROG_MAX_RM9200_CSS	3

struct clk_programmable {
	void __iomem *base;
	const u32 *clk_mux_table;
	const u32 *mux_table;
	const struct clk_programmable_layout *layout;
	u32 num_parents;
	struct clk clk;
	u8 id;
};

#define to_clk_programmable(_c) container_of(_c, struct clk_programmable, clk)

static ulong clk_programmable_get_rate(struct clk *clk)
{
	struct clk_programmable *prog = to_clk_programmable(clk);
	const struct clk_programmable_layout *layout = prog->layout;
	ulong rate, parent_rate = clk_get_parent_rate(clk);
	unsigned int pckr;

	pmc_read(prog->base, AT91_PMC_PCKR(prog->id), &pckr);

	if (layout->is_pres_direct)
		rate = parent_rate / (PROG_PRES(layout, pckr) + 1);
	else
		rate = parent_rate >> PROG_PRES(layout, pckr);

	return rate;
}

static int clk_programmable_set_parent(struct clk *clk, struct clk *parent)
{
	struct clk_programmable *prog = to_clk_programmable(clk);
	const struct clk_programmable_layout *layout = prog->layout;
	unsigned int mask = layout->css_mask;
	int index;

	index = at91_clk_mux_val_to_index(prog->clk_mux_table,
					  prog->num_parents, parent->id);
	if (index < 0)
		return index;

	index = at91_clk_mux_index_to_val(prog->mux_table, prog->num_parents,
					  index);
	if (index < 0)
		return index;

	if (layout->have_slck_mck)
		mask |= AT91_PMC_CSSMCK_MCK;

	if (index > layout->css_mask) {
		if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck)
			return -EINVAL;

		index |= AT91_PMC_CSSMCK_MCK;
	}

	pmc_update_bits(prog->base, AT91_PMC_PCKR(prog->id), mask, index);

	return 0;
}

static ulong clk_programmable_set_rate(struct clk *clk, ulong rate)
{
	struct clk_programmable *prog = to_clk_programmable(clk);
	const struct clk_programmable_layout *layout = prog->layout;
	ulong parent_rate = clk_get_parent_rate(clk);
	ulong div = parent_rate / rate;
	int shift = 0;

	if (!parent_rate || !div)
		return -EINVAL;

	if (layout->is_pres_direct) {
		shift = div - 1;

		if (shift > layout->pres_mask)
			return -EINVAL;
	} else {
		shift = fls(div) - 1;

		if (div != (1 << shift))
			return -EINVAL;

		if (shift >= layout->pres_mask)
			return -EINVAL;
	}

	pmc_update_bits(prog->base, AT91_PMC_PCKR(prog->id),
			layout->pres_mask << layout->pres_shift,
			shift << layout->pres_shift);

	if (layout->is_pres_direct)
		return (parent_rate / shift + 1);

	return parent_rate >> shift;
}

static const struct clk_ops programmable_ops = {
	.get_rate = clk_programmable_get_rate,
	.set_parent = clk_programmable_set_parent,
	.set_rate = clk_programmable_set_rate,
};

struct clk *at91_clk_register_programmable(void __iomem *base, const char *name,
			const char *const *parent_names, u8 num_parents, u8 id,
			const struct clk_programmable_layout *layout,
			const u32 *clk_mux_table, const u32 *mux_table)
{
	struct clk_programmable *prog;
	struct clk *clk;
	u32 val, tmp;
	int ret;

	if (!base || !name || !parent_names || !num_parents ||
	    !layout || !clk_mux_table || !mux_table || id > PROG_ID_MAX)
		return ERR_PTR(-EINVAL);

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

	prog->id = id;
	prog->layout = layout;
	prog->base = base;
	prog->clk_mux_table = clk_mux_table;
	prog->mux_table = mux_table;
	prog->num_parents = num_parents;

	pmc_read(prog->base, AT91_PMC_PCKR(prog->id), &tmp);
	val = tmp & prog->layout->css_mask;
	if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !val)
		ret = PROG_MAX_RM9200_CSS + 1;
	else
		ret = at91_clk_mux_val_to_index(prog->mux_table,
						prog->num_parents, val);
	if (ret < 0) {
		kfree(prog);
		return ERR_PTR(ret);
	}

	clk = &prog->clk;
	clk->flags = CLK_GET_RATE_NOCACHE;
	ret = clk_register(clk, UBOOT_DM_CLK_AT91_PROG, name,
			   parent_names[ret]);
	if (ret) {
		kfree(prog);
		clk = ERR_PTR(ret);
	}

	return clk;
}

U_BOOT_DRIVER(at91_prog_clk) = {
	.name = UBOOT_DM_CLK_AT91_PROG,
	.id = UCLASS_CLK,
	.ops = &programmable_ops,
	.flags = DM_FLAG_PRE_RELOC,
};

const struct clk_programmable_layout at91rm9200_programmable_layout = {
	.pres_mask = 0x7,
	.pres_shift = 2,
	.css_mask = 0x3,
	.have_slck_mck = 0,
	.is_pres_direct = 0,
};

const struct clk_programmable_layout at91sam9g45_programmable_layout = {
	.pres_mask = 0x7,
	.pres_shift = 2,
	.css_mask = 0x3,
	.have_slck_mck = 1,
	.is_pres_direct = 0,
};

const struct clk_programmable_layout at91sam9x5_programmable_layout = {
	.pres_mask = 0x7,
	.pres_shift = 4,
	.css_mask = 0x7,
	.have_slck_mck = 0,
	.is_pres_direct = 0,
};
