// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 Maxime Ripard
 * Maxime Ripard <maxime.ripard@free-electrons.com>
 */

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

#include "ccu_gate.h"
#include "ccu_nkm.h"

struct _ccu_nkm {
	unsigned long	n, min_n, max_n;
	unsigned long	k, min_k, max_k;
	unsigned long	m, min_m, max_m;
};

static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent,
				  unsigned long n, unsigned long m)
{
	struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);

	if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
		return false;

	if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
		return false;

	return true;
}

static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common,
						       struct clk_hw *parent_hw,
						       unsigned long *parent, unsigned long rate,
						       struct _ccu_nkm *nkm)
{
	unsigned long best_rate = 0, best_parent_rate = *parent;
	unsigned long best_n = 0, best_k = 0, best_m = 0;
	unsigned long _n, _k, _m;

	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
				unsigned long tmp_rate, tmp_parent;

				tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));

				if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m))
					continue;

				tmp_rate = tmp_parent * _n * _k / _m;

				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) ||
				    (tmp_parent == *parent && tmp_rate == best_rate)) {
					best_rate = tmp_rate;
					best_parent_rate = tmp_parent;
					best_n = _n;
					best_k = _k;
					best_m = _m;
				}
			}
		}
	}

	nkm->n = best_n;
	nkm->k = best_k;
	nkm->m = best_m;

	*parent = best_parent_rate;

	return best_rate;
}

static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate,
				       struct _ccu_nkm *nkm, struct ccu_common *common)
{
	unsigned long best_rate = 0;
	unsigned long best_n = 0, best_k = 0, best_m = 0;
	unsigned long _n, _k, _m;

	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
				if (!ccu_nkm_is_valid_rate(common, parent, _n, _m))
					continue;

				unsigned long tmp_rate;

				tmp_rate = parent * _n * _k / _m;

				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate)) {
					best_rate = tmp_rate;
					best_n = _n;
					best_k = _k;
					best_m = _m;
				}
			}
		}
	}

	nkm->n = best_n;
	nkm->k = best_k;
	nkm->m = best_m;

	return best_rate;
}

static void ccu_nkm_disable(struct clk_hw *hw)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_gate_helper_disable(&nkm->common, nkm->enable);
}

static int ccu_nkm_enable(struct clk_hw *hw)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_gate_helper_enable(&nkm->common, nkm->enable);
}

static int ccu_nkm_is_enabled(struct clk_hw *hw)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_gate_helper_is_enabled(&nkm->common, nkm->enable);
}

static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
	unsigned long n, m, k, rate;
	u32 reg;

	reg = readl(nkm->common.base + nkm->common.reg);

	n = reg >> nkm->n.shift;
	n &= (1 << nkm->n.width) - 1;
	n += nkm->n.offset;
	if (!n)
		n++;

	k = reg >> nkm->k.shift;
	k &= (1 << nkm->k.width) - 1;
	k += nkm->k.offset;
	if (!k)
		k++;

	m = reg >> nkm->m.shift;
	m &= (1 << nkm->m.width) - 1;
	m += nkm->m.offset;
	if (!m)
		m++;

	rate = parent_rate * n  * k / m;

	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
		rate /= nkm->fixed_post_div;

	return rate;
}

static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
					struct clk_hw *parent_hw,
					unsigned long *parent_rate,
					unsigned long rate,
					void *data)
{
	struct ccu_nkm *nkm = data;
	struct _ccu_nkm _nkm;

	_nkm.min_n = nkm->n.min ?: 1;
	_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
	_nkm.min_k = nkm->k.min ?: 1;
	_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
	_nkm.min_m = 1;
	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;

	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
		rate *= nkm->fixed_post_div;

	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
	else
		rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, parent_hw, parent_rate, rate,
							 &_nkm);

	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
		rate /= nkm->fixed_post_div;

	return rate;
}

static int ccu_nkm_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux,
					     req, ccu_nkm_round_rate, nkm);
}

static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
			   unsigned long parent_rate)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
	struct _ccu_nkm _nkm;
	unsigned long flags;
	u32 reg;

	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
		rate *= nkm->fixed_post_div;

	_nkm.min_n = nkm->n.min ?: 1;
	_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
	_nkm.min_k = nkm->k.min ?: 1;
	_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
	_nkm.min_m = 1;
	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;

	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);

	spin_lock_irqsave(nkm->common.lock, flags);

	reg = readl(nkm->common.base + nkm->common.reg);
	reg &= ~GENMASK(nkm->n.width + nkm->n.shift - 1, nkm->n.shift);
	reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
	reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);

	reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
	reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
	reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
	writel(reg, nkm->common.base + nkm->common.reg);

	spin_unlock_irqrestore(nkm->common.lock, flags);

	ccu_helper_wait_for_lock(&nkm->common, nkm->lock);

	return 0;
}

static u8 ccu_nkm_get_parent(struct clk_hw *hw)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_mux_helper_get_parent(&nkm->common, &nkm->mux);
}

static int ccu_nkm_set_parent(struct clk_hw *hw, u8 index)
{
	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);

	return ccu_mux_helper_set_parent(&nkm->common, &nkm->mux, index);
}

const struct clk_ops ccu_nkm_ops = {
	.disable	= ccu_nkm_disable,
	.enable		= ccu_nkm_enable,
	.is_enabled	= ccu_nkm_is_enabled,

	.get_parent	= ccu_nkm_get_parent,
	.set_parent	= ccu_nkm_set_parent,

	.determine_rate	= ccu_nkm_determine_rate,
	.recalc_rate	= ccu_nkm_recalc_rate,
	.set_rate	= ccu_nkm_set_rate,
};
EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, SUNXI_CCU);
