// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2024 Neil Armstrong <neil.armstrong@linaro.org>
 */

#include <linux/module.h>
#include "vclk.h"

/* The VCLK gate has a supplementary reset bit to pulse after ungating */

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

static int meson_vclk_gate_enable(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);

	meson_parm_write(clk->map, &vclk->enable, 1);

	/* Do a reset pulse */
	meson_parm_write(clk->map, &vclk->reset, 1);
	meson_parm_write(clk->map, &vclk->reset, 0);

	return 0;
}

static void meson_vclk_gate_disable(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);

	meson_parm_write(clk->map, &vclk->enable, 0);
}

static int meson_vclk_gate_is_enabled(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);

	return meson_parm_read(clk->map, &vclk->enable);
}

const struct clk_ops meson_vclk_gate_ops = {
	.init = clk_regmap_init,
	.enable = meson_vclk_gate_enable,
	.disable = meson_vclk_gate_disable,
	.is_enabled = meson_vclk_gate_is_enabled,
};
EXPORT_SYMBOL_NS_GPL(meson_vclk_gate_ops, "CLK_MESON");

/* The VCLK Divider has supplementary reset & enable bits */

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

static unsigned long meson_vclk_div_recalc_rate(struct clk_hw *hw,
						unsigned long prate)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);

	return divider_recalc_rate(hw, prate, meson_parm_read(clk->map, &vclk->div),
				   vclk->table, vclk->flags, vclk->div.width);
}

static int meson_vclk_div_determine_rate(struct clk_hw *hw,
					 struct clk_rate_request *req)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);

	return divider_determine_rate(hw, req, vclk->table, vclk->div.width,
				      vclk->flags);
}

static int meson_vclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
				   unsigned long parent_rate)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
	int ret;

	ret = divider_get_val(rate, parent_rate, vclk->table, vclk->div.width,
			      vclk->flags);
	if (ret < 0)
		return ret;

	meson_parm_write(clk->map, &vclk->div, ret);

	return 0;
};

static int meson_vclk_div_enable(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);

	/* Unreset the divider when ungating */
	meson_parm_write(clk->map, &vclk->reset, 0);
	meson_parm_write(clk->map, &vclk->enable, 1);

	return 0;
}

static void meson_vclk_div_disable(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);

	/* Reset the divider when gating */
	meson_parm_write(clk->map, &vclk->enable, 0);
	meson_parm_write(clk->map, &vclk->reset, 1);
}

static int meson_vclk_div_is_enabled(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);

	return meson_parm_read(clk->map, &vclk->enable);
}

const struct clk_ops meson_vclk_div_ops = {
	.init = clk_regmap_init,
	.recalc_rate = meson_vclk_div_recalc_rate,
	.determine_rate = meson_vclk_div_determine_rate,
	.set_rate = meson_vclk_div_set_rate,
	.enable = meson_vclk_div_enable,
	.disable = meson_vclk_div_disable,
	.is_enabled = meson_vclk_div_is_enabled,
};
EXPORT_SYMBOL_NS_GPL(meson_vclk_div_ops, "CLK_MESON");

MODULE_DESCRIPTION("Amlogic vclk clock driver");
MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("CLK_MESON");
