// SPDX-License-Identifier: GPL-2.0+
/*
 * Based on drivers/clk/tegra/clk-emc.c
 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
 *
 * Author: Dmitry Osipenko <digetx@gmail.com>
 * Copyright (C) 2019 GRATE-DRIVER project
 */

#define pr_fmt(fmt)	"tegra-emc-clk: " fmt

#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/clk/tegra.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/slab.h>

#include "clk.h"

#define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK	GENMASK(7, 0)
#define CLK_SOURCE_EMC_2X_CLK_SRC_MASK		GENMASK(31, 30)
#define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT		30

#define MC_EMC_SAME_FREQ	BIT(16)
#define USE_PLLM_UD		BIT(29)

#define EMC_SRC_PLL_M		0
#define EMC_SRC_PLL_C		1
#define EMC_SRC_PLL_P		2
#define EMC_SRC_CLK_M		3

static const char * const emc_parent_clk_names[] = {
	"pll_m", "pll_c", "pll_p", "clk_m",
};

struct tegra_clk_emc {
	struct clk_hw hw;
	void __iomem *reg;
	bool mc_same_freq;
	bool want_low_jitter;

	tegra20_clk_emc_round_cb *round_cb;
	void *cb_arg;
};

static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw)
{
	return container_of(hw, struct tegra_clk_emc, hw);
}

static unsigned long emc_recalc_rate(struct clk_hw *hw,
				     unsigned long parent_rate)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
	u32 val, div;

	val = readl_relaxed(emc->reg);
	div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;

	return DIV_ROUND_UP(parent_rate * 2, div + 2);
}

static u8 emc_get_parent(struct clk_hw *hw)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);

	return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;
}

static int emc_set_parent(struct clk_hw *hw, u8 index)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
	u32 val, div;

	val = readl_relaxed(emc->reg);
	val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK;
	val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;

	div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;

	if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
		val |= USE_PLLM_UD;
	else
		val &= ~USE_PLLM_UD;

	if (emc->mc_same_freq)
		val |= MC_EMC_SAME_FREQ;
	else
		val &= ~MC_EMC_SAME_FREQ;

	writel_relaxed(val, emc->reg);

	fence_udelay(1, emc->reg);

	return 0;
}

static int emc_set_rate(struct clk_hw *hw, unsigned long rate,
			unsigned long parent_rate)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
	unsigned int index;
	u32 val, div;

	div = div_frac_get(rate, parent_rate, 8, 1, 0);

	val = readl_relaxed(emc->reg);
	val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
	val |= div;

	index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;

	if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
		val |= USE_PLLM_UD;
	else
		val &= ~USE_PLLM_UD;

	if (emc->mc_same_freq)
		val |= MC_EMC_SAME_FREQ;
	else
		val &= ~MC_EMC_SAME_FREQ;

	writel_relaxed(val, emc->reg);

	fence_udelay(1, emc->reg);

	return 0;
}

static int emc_set_rate_and_parent(struct clk_hw *hw,
				   unsigned long rate,
				   unsigned long parent_rate,
				   u8 index)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
	u32 val, div;

	div = div_frac_get(rate, parent_rate, 8, 1, 0);

	val = readl_relaxed(emc->reg);

	val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK;
	val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT;

	val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK;
	val |= div;

	if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter)
		val |= USE_PLLM_UD;
	else
		val &= ~USE_PLLM_UD;

	if (emc->mc_same_freq)
		val |= MC_EMC_SAME_FREQ;
	else
		val &= ~MC_EMC_SAME_FREQ;

	writel_relaxed(val, emc->reg);

	fence_udelay(1, emc->reg);

	return 0;
}

static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
	struct tegra_clk_emc *emc = to_tegra_clk_emc(hw);
	struct clk_hw *parent_hw;
	unsigned long divided_rate;
	unsigned long parent_rate;
	unsigned int i;
	long emc_rate;
	int div;

	emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate,
				 emc->cb_arg);
	if (emc_rate < 0)
		return emc_rate;

	for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) {
		parent_hw = clk_hw_get_parent_by_index(hw, i);

		if (req->best_parent_hw == parent_hw)
			parent_rate = req->best_parent_rate;
		else
			parent_rate = clk_hw_get_rate(parent_hw);

		if (emc_rate > parent_rate)
			continue;

		div = div_frac_get(emc_rate, parent_rate, 8, 1, 0);
		divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2);

		if (divided_rate != emc_rate)
			continue;

		req->best_parent_rate = parent_rate;
		req->best_parent_hw = parent_hw;
		req->rate = emc_rate;
		break;
	}

	if (i == ARRAY_SIZE(emc_parent_clk_names)) {
		pr_err_once("can't find parent for rate %lu emc_rate %lu\n",
			    req->rate, emc_rate);
		return -EINVAL;
	}

	return 0;
}

static const struct clk_ops tegra_clk_emc_ops = {
	.recalc_rate = emc_recalc_rate,
	.get_parent = emc_get_parent,
	.set_parent = emc_set_parent,
	.set_rate = emc_set_rate,
	.set_rate_and_parent = emc_set_rate_and_parent,
	.determine_rate = emc_determine_rate,
};

void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
					void *cb_arg)
{
	struct clk *clk = __clk_lookup("emc");
	struct tegra_clk_emc *emc;
	struct clk_hw *hw;

	if (clk) {
		hw = __clk_get_hw(clk);
		emc = to_tegra_clk_emc(hw);

		emc->round_cb = round_cb;
		emc->cb_arg = cb_arg;
	}
}
EXPORT_SYMBOL_GPL(tegra20_clk_set_emc_round_callback);

bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw)
{
	return to_tegra_clk_emc(emc_hw)->round_cb != NULL;
}

struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter)
{
	struct tegra_clk_emc *emc;
	struct clk_init_data init;
	struct clk *clk;

	emc = kzalloc_obj(*emc);
	if (!emc)
		return NULL;

	/*
	 * EMC stands for External Memory Controller.
	 *
	 * We don't want EMC clock to be disabled ever by gating its
	 * parent and whatnot because system is busted immediately in that
	 * case, hence the clock is marked as critical.
	 */
	init.name = "emc";
	init.ops = &tegra_clk_emc_ops;
	init.flags = CLK_IS_CRITICAL;
	init.parent_names = emc_parent_clk_names;
	init.num_parents = ARRAY_SIZE(emc_parent_clk_names);

	emc->reg = ioaddr;
	emc->hw.init = &init;
	emc->want_low_jitter = low_jitter;

	clk = clk_register(NULL, &emc->hw);
	if (IS_ERR(clk)) {
		kfree(emc);
		return NULL;
	}

	return clk;
}

int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
{
	struct tegra_clk_emc *emc;
	struct clk_hw *hw;

	if (!emc_clk)
		return -EINVAL;

	hw = __clk_get_hw(emc_clk);
	emc = to_tegra_clk_emc(hw);
	emc->mc_same_freq = same;

	return 0;
}
EXPORT_SYMBOL_GPL(tegra20_clk_prepare_emc_mc_same_freq);
