// 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/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;
	}
}

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(sizeof(*emc), GFP_KERNEL);
	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;
}
