// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2017 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 * Author: Jerome Brunet <jbrunet@baylibre.com>
 */

/*
 * The AO Domain embeds a dual/divider to generate a more precise
 * 32,768KHz clock for low-power suspend mode and CEC.
 *     ______   ______
 *    |      | |      |
 *    | Div1 |-| Cnt1 |
 *   /|______| |______|\
 * -|  ______   ______  X--> Out
 *   \|      | |      |/
 *    | Div2 |-| Cnt2 |
 *    |______| |______|
 *
 * The dividing can be switched to single or dual, with a counter
 * for each divider to set when the switching is done.
 */

#include <linux/clk-provider.h>
#include <linux/module.h>

#include "clk-regmap.h"
#include "clk-dualdiv.h"

static inline struct meson_clk_dualdiv_data *
meson_clk_dualdiv_data(struct clk_regmap *clk)
{
	return (struct meson_clk_dualdiv_data *)clk->data;
}

static unsigned long
__dualdiv_param_to_rate(unsigned long parent_rate,
			const struct meson_clk_dualdiv_param *p)
{
	if (!p->dual)
		return DIV_ROUND_CLOSEST(parent_rate, p->n1);

	return DIV_ROUND_CLOSEST(parent_rate * (p->m1 + p->m2),
				 p->n1 * p->m1 + p->n2 * p->m2);
}

static unsigned long meson_clk_dualdiv_recalc_rate(struct clk_hw *hw,
						   unsigned long parent_rate)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
	struct meson_clk_dualdiv_param setting;

	setting.dual = meson_parm_read(clk->map, &dualdiv->dual);
	setting.n1 = meson_parm_read(clk->map, &dualdiv->n1) + 1;
	setting.m1 = meson_parm_read(clk->map, &dualdiv->m1) + 1;
	setting.n2 = meson_parm_read(clk->map, &dualdiv->n2) + 1;
	setting.m2 = meson_parm_read(clk->map, &dualdiv->m2) + 1;

	return __dualdiv_param_to_rate(parent_rate, &setting);
}

static const struct meson_clk_dualdiv_param *
__dualdiv_get_setting(unsigned long rate, unsigned long parent_rate,
		      struct meson_clk_dualdiv_data *dualdiv)
{
	const struct meson_clk_dualdiv_param *table = dualdiv->table;
	unsigned long best = 0, now = 0;
	unsigned int i, best_i = 0;

	if (!table)
		return NULL;

	for (i = 0; table[i].n1; i++) {
		now = __dualdiv_param_to_rate(parent_rate, &table[i]);

		/* If we get an exact match, don't bother any further */
		if (now == rate) {
			return &table[i];
		} else if (abs(now - rate) < abs(best - rate)) {
			best = now;
			best_i = i;
		}
	}

	return (struct meson_clk_dualdiv_param *)&table[best_i];
}

static long meson_clk_dualdiv_round_rate(struct clk_hw *hw, unsigned long rate,
					 unsigned long *parent_rate)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
	const struct meson_clk_dualdiv_param *setting =
		__dualdiv_get_setting(rate, *parent_rate, dualdiv);

	if (!setting)
		return meson_clk_dualdiv_recalc_rate(hw, *parent_rate);

	return __dualdiv_param_to_rate(*parent_rate, setting);
}

static int meson_clk_dualdiv_set_rate(struct clk_hw *hw, unsigned long rate,
				      unsigned long parent_rate)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
	const struct meson_clk_dualdiv_param *setting =
		__dualdiv_get_setting(rate, parent_rate, dualdiv);

	if (!setting)
		return -EINVAL;

	meson_parm_write(clk->map, &dualdiv->dual, setting->dual);
	meson_parm_write(clk->map, &dualdiv->n1, setting->n1 - 1);
	meson_parm_write(clk->map, &dualdiv->m1, setting->m1 - 1);
	meson_parm_write(clk->map, &dualdiv->n2, setting->n2 - 1);
	meson_parm_write(clk->map, &dualdiv->m2, setting->m2 - 1);

	return 0;
}

const struct clk_ops meson_clk_dualdiv_ops = {
	.recalc_rate	= meson_clk_dualdiv_recalc_rate,
	.round_rate	= meson_clk_dualdiv_round_rate,
	.set_rate	= meson_clk_dualdiv_set_rate,
};
EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ops);

const struct clk_ops meson_clk_dualdiv_ro_ops = {
	.recalc_rate	= meson_clk_dualdiv_recalc_rate,
};
EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ro_ops);

MODULE_DESCRIPTION("Amlogic dual divider driver");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL v2");
