// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas RZ/V2H(P) Clock Pulse Generator
 *
 * Copyright (C) 2024 Renesas Electronics Corp.
 *
 * Based on rzg2l-cpg.c
 *
 * Copyright (C) 2015 Glider bvba
 * Copyright (C) 2013 Ideas On Board SPRL
 * Copyright (C) 2015 Renesas Electronics Corp.
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clk/renesas.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/limits.h>
#include <linux/math.h>
#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
#include <linux/refcount.h>
#include <linux/reset-controller.h>
#include <linux/string_choices.h>
#include <linux/units.h>

#include <dt-bindings/clock/renesas-cpg-mssr.h>

#include "rzv2h-cpg.h"

#ifdef DEBUG
#define WARN_DEBUG(x)		WARN_ON(x)
#else
#define WARN_DEBUG(x)		do { } while (0)
#endif

#define GET_CLK_ON_OFFSET(x)	(0x600 + ((x) * 4))
#define GET_CLK_MON_OFFSET(x)	(0x800 + ((x) * 4))
#define GET_RST_OFFSET(x)	(0x900 + ((x) * 4))
#define GET_RST_MON_OFFSET(x)	(0xA00 + ((x) * 4))

#define CPG_BUS_1_MSTOP		(0xd00)
#define CPG_BUS_MSTOP(m)	(CPG_BUS_1_MSTOP + ((m) - 1) * 4)

#define CPG_PLL_STBY(x)		((x))
#define CPG_PLL_STBY_RESETB	BIT(0)
#define CPG_PLL_STBY_SSC_EN	BIT(2)
#define CPG_PLL_STBY_RESETB_WEN	BIT(16)
#define CPG_PLL_STBY_SSC_EN_WEN BIT(18)
#define CPG_PLL_CLK1(x)		((x) + 0x004)
#define CPG_PLL_CLK1_KDIV	GENMASK(31, 16)
#define CPG_PLL_CLK1_MDIV	GENMASK(15, 6)
#define CPG_PLL_CLK1_PDIV	GENMASK(5, 0)
#define CPG_PLL_CLK2(x)		((x) + 0x008)
#define CPG_PLL_CLK2_SDIV	GENMASK(2, 0)
#define CPG_PLL_MON(x)		((x) + 0x010)
#define CPG_PLL_MON_RESETB	BIT(0)
#define CPG_PLL_MON_LOCK	BIT(4)

#define DDIV_DIVCTL_WEN(shift)		BIT((shift) + 16)

#define GET_MOD_CLK_ID(base, index, bit)		\
			((base) + ((((index) * (16))) + (bit)))

#define CPG_CLKSTATUS0		(0x700)

/* On RZ/G3E SoC we have two DSI PLLs */
#define MAX_CPG_DSI_PLL		2

/**
 * struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters
 *
 * @pll_dsi_limits: PLL DSI parameters limits
 * @pll_dsi_parameters: Calculated PLL DSI parameters
 * @req_pll_dsi_rate: Requested PLL DSI rate
 */
struct rzv2h_pll_dsi_info {
	const struct rzv2h_pll_limits *pll_dsi_limits;
	struct rzv2h_pll_div_pars pll_dsi_parameters;
	unsigned long req_pll_dsi_rate;
};

/**
 * struct rzv2h_cpg_priv - Clock Pulse Generator Private Data
 *
 * @dev: CPG device
 * @base: CPG register block base address
 * @rmw_lock: protects register accesses
 * @clks: Array containing all Core and Module Clocks
 * @num_core_clks: Number of Core Clocks in clks[]
 * @num_mod_clks: Number of Module Clocks in clks[]
 * @resets: Array of resets
 * @num_resets: Number of Module Resets in info->resets[]
 * @last_dt_core_clk: ID of the last Core Clock exported to DT
 * @ff_mod_status_ops: Fixed Factor Module Status Clock operations
 * @mstop_count: Array of mstop values
 * @rcdev: Reset controller entity
 * @pll_dsi_info: Array of PLL DSI information, holds the limits and parameters
 */
struct rzv2h_cpg_priv {
	struct device *dev;
	void __iomem *base;
	spinlock_t rmw_lock;

	struct clk **clks;
	unsigned int num_core_clks;
	unsigned int num_mod_clks;
	struct rzv2h_reset *resets;
	unsigned int num_resets;
	unsigned int last_dt_core_clk;

	struct clk_ops *ff_mod_status_ops;

	atomic_t *mstop_count;

	struct reset_controller_dev rcdev;

	struct rzv2h_pll_dsi_info pll_dsi_info[MAX_CPG_DSI_PLL];
};

#define rcdev_to_priv(x)	container_of(x, struct rzv2h_cpg_priv, rcdev)

struct pll_clk {
	struct rzv2h_cpg_priv *priv;
	struct clk_hw hw;
	struct pll pll;
};

#define to_pll(_hw)	container_of(_hw, struct pll_clk, hw)

/**
 * struct mod_clock - Module clock
 *
 * @priv: CPG private data
 * @mstop_data: mstop data relating to module clock
 * @hw: handle between common and hardware-specific interfaces
 * @no_pm: flag to indicate PM is not supported
 * @on_index: register offset
 * @on_bit: ON/MON bit
 * @mon_index: monitor register offset
 * @mon_bit: monitor bit
 * @ext_clk_mux_index: mux index for external clock source, or -1 if internal
 */
struct mod_clock {
	struct rzv2h_cpg_priv *priv;
	unsigned int mstop_data;
	struct clk_hw hw;
	bool no_pm;
	u8 on_index;
	u8 on_bit;
	s8 mon_index;
	u8 mon_bit;
	s8 ext_clk_mux_index;
};

#define to_mod_clock(_hw) container_of(_hw, struct mod_clock, hw)

/**
 * struct ddiv_clk - DDIV clock
 *
 * @priv: CPG private data
 * @div: divider clk
 * @mon: monitor bit in CPG_CLKSTATUS0 register
 */
struct ddiv_clk {
	struct rzv2h_cpg_priv *priv;
	struct clk_divider div;
	u8 mon;
};

#define to_ddiv_clock(_div) container_of(_div, struct ddiv_clk, div)

/**
 * struct rzv2h_ff_mod_status_clk - Fixed Factor Module Status Clock
 *
 * @priv: CPG private data
 * @conf: fixed mod configuration
 * @fix: fixed factor clock
 */
struct rzv2h_ff_mod_status_clk {
	struct rzv2h_cpg_priv *priv;
	struct fixed_mod_conf conf;
	struct clk_fixed_factor fix;
};

#define to_rzv2h_ff_mod_status_clk(_hw) \
	container_of(_hw, struct rzv2h_ff_mod_status_clk, fix.hw)

/**
 * struct rzv2h_plldsi_div_clk - PLL DSI DDIV clock
 *
 * @dtable: divider table
 * @priv: CPG private data
 * @hw: divider clk
 * @ddiv: divider configuration
 */
struct rzv2h_plldsi_div_clk {
	const struct clk_div_table *dtable;
	struct rzv2h_cpg_priv *priv;
	struct clk_hw hw;
	struct ddiv ddiv;
};

#define to_plldsi_div_clk(_hw) \
	container_of(_hw, struct rzv2h_plldsi_div_clk, hw)

#define RZ_V2H_OSC_CLK_IN_MEGA		(24 * MEGA)
#define RZV2H_MAX_DIV_TABLES		(16)

/**
 * rzv2h_get_pll_pars - Finds the best combination of PLL parameters
 * for a given frequency.
 *
 * @limits: Pointer to the structure containing the limits for the PLL parameters
 * @pars: Pointer to the structure where the best calculated PLL parameters values
 * will be stored
 * @freq_millihz: Target output frequency in millihertz
 *
 * This function calculates the best set of PLL parameters (M, K, P, S) to achieve
 * the desired frequency.
 * There is no direct formula to calculate the PLL parameters, as it's an open
 * system of equations, therefore this function uses an iterative approach to
 * determine the best solution. The best solution is one that minimizes the error
 * (desired frequency - actual frequency).
 *
 * Return: true if a valid set of parameters values is found, false otherwise.
 */
bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
			struct rzv2h_pll_pars *pars, u64 freq_millihz)
{
	u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI);
	u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI);
	struct rzv2h_pll_pars p, best;

	if (freq_millihz > fout_max_millihz ||
	    freq_millihz < fout_min_millihz)
		return false;

	/* Initialize best error to maximum possible value */
	best.error_millihz = S64_MAX;

	for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) {
		u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p;
		u16 divider;

		for (divider = 1 << limits->s.min, p.s = limits->s.min;
			p.s <= limits->s.max; p.s++, divider <<= 1) {
			for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) {
				u64 output_m, output_k_range;
				s64 pll_k, output_k;
				u64 fvco, output;

				/*
				 * The frequency generated by the PLL + divider
				 * is calculated as follows:
				 *
				 * With:
				 * Freq = Ffout = Ffvco / 2^(pll_s)
				 * Ffvco = (pll_m + (pll_k / 65536)) * Ffref
				 * Ffref = 24MHz / pll_p
				 *
				 * Freq can also be rewritten as:
				 * Freq = Ffvco / 2^(pll_s)
				 *      = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s)
				 *      = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s)
				 *      = output_m + output_k
				 *
				 * Every parameter has been determined at this
				 * point, but pll_k.
				 *
				 * Considering that:
				 * limits->k.min <= pll_k <= limits->k.max
				 * Then:
				 * -0.5 <= (pll_k / 65536) < 0.5
				 * Therefore:
				 * -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s))
				 */

				/* Compute output M component (in mHz) */
				output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI,
								 divider);
				/* Compute range for output K (in mHz) */
				output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI),
								       2 * divider);
				/*
				 * No point in continuing if we can't achieve
				 * the desired frequency
				 */
				if (freq_millihz <  (output_m - output_k_range) ||
				    freq_millihz >= (output_m + output_k_range)) {
					continue;
				}

				/*
				 * Compute the K component
				 *
				 * Since:
				 * Freq = output_m + output_k
				 * Then:
				 * output_k = Freq - output_m
				 *          = ((pll_k / 65536) * Ffref) / 2^(pll_s)
				 * Therefore:
				 * pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref
				 */
				output_k = freq_millihz - output_m;
				pll_k = div_s64(output_k * 65536ULL * divider,
						fref);
				pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI);

				/* Validate K value within allowed limits */
				if (pll_k < limits->k.min ||
				    pll_k > limits->k.max)
					continue;

				p.k = pll_k;

				/* Compute (Ffvco * 65536) */
				fvco = mul_u32_u32(p.m * 65536 + p.k, fref);
				if (fvco < mul_u32_u32(limits->fvco.min, 65536) ||
				    fvco > mul_u32_u32(limits->fvco.max, 65536))
					continue;

				/* PLL_M component of (output * 65536 * PLL_P) */
				output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA);
				/* PLL_K component of (output * 65536 * PLL_P) */
				output += p.k * RZ_V2H_OSC_CLK_IN_MEGA;
				/* Make it in mHz */
				output *= MILLI;
				output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider);

				/* Check output frequency against limits */
				if (output < fout_min_millihz ||
				    output > fout_max_millihz)
					continue;

				p.error_millihz = freq_millihz - output;
				p.freq_millihz = output;

				/* If an exact match is found, return immediately */
				if (p.error_millihz == 0) {
					*pars = p;
					return true;
				}

				/* Update best match if error is smaller */
				if (abs(best.error_millihz) > abs(p.error_millihz))
					best = p;
			}
		}
	}

	/* If no valid parameters were found, return false */
	if (best.error_millihz == S64_MAX)
		return false;

	*pars = best;
	return true;
}
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG");

/*
 * rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters
 * and divider value for a given frequency.
 *
 * @limits: Pointer to the structure containing the limits for the PLL parameters
 * @pars: Pointer to the structure where the best calculated PLL parameters and
 * divider values will be stored
 * @table: Pointer to the array of valid divider values
 * @table_size: Size of the divider values array
 * @freq_millihz: Target output frequency in millihertz
 *
 * This function calculates the best set of PLL parameters (M, K, P, S) and divider
 * value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details
 * on how the PLL parameters are calculated.
 *
 * freq_millihz is the desired frequency generated by the PLL followed by a
 * a gear.
 */
bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
			     struct rzv2h_pll_div_pars *pars,
			     const u8 *table, u8 table_size, u64 freq_millihz)
{
	struct rzv2h_pll_div_pars p, best;

	best.div.error_millihz = S64_MAX;
	p.div.error_millihz = S64_MAX;
	for (unsigned int i = 0; i < table_size; i++) {
		if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i]))
			continue;

		p.div.divider_value = table[i];
		p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]);
		p.div.error_millihz = freq_millihz - p.div.freq_millihz;

		if (p.div.error_millihz == 0) {
			*pars = p;
			return true;
		}

		if (abs(best.div.error_millihz) > abs(p.div.error_millihz))
			best = p;
	}

	if (best.div.error_millihz == S64_MAX)
		return false;

	*pars = best;
	return true;
}
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG");

static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw,
						      unsigned long parent_rate)
{
	struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
	struct rzv2h_cpg_priv *priv = dsi_div->priv;
	struct ddiv ddiv = dsi_div->ddiv;
	u32 div;

	div = readl(priv->base + ddiv.offset);
	div >>= ddiv.shift;
	div &= clk_div_mask(ddiv.width);
	div = dsi_div->dtable[div].div;

	return DIV_ROUND_CLOSEST_ULL(parent_rate, div);
}

static int rzv2h_cpg_plldsi_div_determine_rate(struct clk_hw *hw,
					       struct clk_rate_request *req)
{
	struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
	struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw));
	struct rzv2h_cpg_priv *priv = dsi_div->priv;
	u8 table[RZV2H_MAX_DIV_TABLES] = { 0 };
	struct rzv2h_pll_div_pars *dsi_params;
	struct rzv2h_pll_dsi_info *dsi_info;
	const struct clk_div_table *div;
	unsigned int i = 0;
	u64 rate_millihz;

	dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
	dsi_params = &dsi_info->pll_dsi_parameters;

	rate_millihz = mul_u32_u32(req->rate, MILLI);
	if (rate_millihz == dsi_params->div.error_millihz + dsi_params->div.freq_millihz)
		goto exit_determine_rate;

	for (div = dsi_div->dtable; div->div; div++) {
		if (i >= RZV2H_MAX_DIV_TABLES)
			return -EINVAL;
		table[i++] = div->div;
	}

	if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params, table, i,
				     rate_millihz)) {
		dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n",
			req->rate);
		return -EINVAL;
	}

exit_determine_rate:
	req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI);
	req->best_parent_rate = req->rate * dsi_params->div.divider_value;
	dsi_info->req_pll_dsi_rate = req->best_parent_rate;

	return 0;
}

static int rzv2h_cpg_plldsi_div_set_rate(struct clk_hw *hw,
					 unsigned long rate,
					 unsigned long parent_rate)
{
	struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
	struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw));
	struct rzv2h_cpg_priv *priv = dsi_div->priv;
	struct rzv2h_pll_div_pars *dsi_params;
	struct rzv2h_pll_dsi_info *dsi_info;
	struct ddiv ddiv = dsi_div->ddiv;
	const struct clk_div_table *clkt;
	bool divider_found = false;
	u32 val, shift;

	dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
	dsi_params = &dsi_info->pll_dsi_parameters;

	for (clkt = dsi_div->dtable; clkt->div; clkt++) {
		if (clkt->div == dsi_params->div.divider_value) {
			divider_found = true;
			break;
		}
	}

	if (!divider_found)
		return -EINVAL;

	shift = ddiv.shift;
	val = readl(priv->base + ddiv.offset) | DDIV_DIVCTL_WEN(shift);
	val &= ~(clk_div_mask(ddiv.width) << shift);
	val |= clkt->val << shift;
	writel(val, priv->base + ddiv.offset);

	return 0;
}

static const struct clk_ops rzv2h_cpg_plldsi_div_ops = {
	.recalc_rate = rzv2h_cpg_plldsi_div_recalc_rate,
	.determine_rate = rzv2h_cpg_plldsi_div_determine_rate,
	.set_rate = rzv2h_cpg_plldsi_div_set_rate,
};

static struct clk * __init
rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core,
				  struct rzv2h_cpg_priv *priv)
{
	struct rzv2h_plldsi_div_clk *clk_hw_data;
	struct clk **clks = priv->clks;
	struct clk_init_data init;
	const struct clk *parent;
	const char *parent_name;
	struct clk_hw *clk_hw;
	int ret;

	parent = clks[core->parent];
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
	if (!clk_hw_data)
		return ERR_PTR(-ENOMEM);

	clk_hw_data->priv = priv;
	clk_hw_data->ddiv = core->cfg.ddiv;
	clk_hw_data->dtable = core->dtable;

	parent_name = __clk_get_name(parent);
	init.name = core->name;
	init.ops = &rzv2h_cpg_plldsi_div_ops;
	init.flags = core->flag;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	clk_hw = &clk_hw_data->hw;
	clk_hw->init = &init;

	ret = devm_clk_hw_register(priv->dev, clk_hw);
	if (ret)
		return ERR_PTR(ret);

	return clk_hw->clk;
}

static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw,
					   struct clk_rate_request *req)
{
	struct pll_clk *pll_clk = to_pll(hw);
	struct rzv2h_cpg_priv *priv = pll_clk->priv;
	struct rzv2h_pll_dsi_info *dsi_info;
	u64 rate_millihz;

	dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
	/* check if the divider has already invoked the algorithm */
	if (req->rate == dsi_info->req_pll_dsi_rate)
		return 0;

	/* If the req->rate doesn't match we do the calculation assuming there is no divider */
	rate_millihz = mul_u32_u32(req->rate, MILLI);
	if (!rzv2h_get_pll_pars(dsi_info->pll_dsi_limits,
				&dsi_info->pll_dsi_parameters.pll, rate_millihz)) {
		dev_err(priv->dev,
			"failed to determine rate for req->rate: %lu\n",
			req->rate);
		return -EINVAL;
	}

	req->rate = DIV_ROUND_CLOSEST_ULL(dsi_info->pll_dsi_parameters.pll.freq_millihz, MILLI);
	dsi_info->req_pll_dsi_rate = req->rate;

	return 0;
}

static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk,
				  struct rzv2h_pll_pars *params,
				  bool ssc_disable)
{
	struct rzv2h_cpg_priv *priv = pll_clk->priv;
	u16 offset = pll_clk->pll.offset;
	u32 val;
	int ret;

	/* Put PLL into standby mode */
	writel(CPG_PLL_STBY_RESETB_WEN, priv->base + CPG_PLL_STBY(offset));
	ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset),
					val, !(val & CPG_PLL_MON_LOCK),
					100, 2000);
	if (ret) {
		dev_err(priv->dev, "Failed to put PLLDSI into standby mode\n");
		return ret;
	}

	/* Output clock setting 1 */
	writel(FIELD_PREP(CPG_PLL_CLK1_KDIV, (u16)params->k) |
	       FIELD_PREP(CPG_PLL_CLK1_MDIV, params->m) |
	       FIELD_PREP(CPG_PLL_CLK1_PDIV, params->p),
	       priv->base + CPG_PLL_CLK1(offset));

	/* Output clock setting 2 */
	val = readl(priv->base + CPG_PLL_CLK2(offset));
	writel((val & ~CPG_PLL_CLK2_SDIV) | FIELD_PREP(CPG_PLL_CLK2_SDIV, params->s),
	       priv->base + CPG_PLL_CLK2(offset));

	/* Put PLL to normal mode */
	if (ssc_disable)
		val = CPG_PLL_STBY_SSC_EN_WEN;
	else
		val = CPG_PLL_STBY_SSC_EN_WEN | CPG_PLL_STBY_SSC_EN;
	writel(val | CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB,
	       priv->base + CPG_PLL_STBY(offset));

	/* PLL normal mode transition, output clock stability check */
	ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset),
					val, (val & CPG_PLL_MON_LOCK),
					100, 2000);
	if (ret) {
		dev_err(priv->dev, "Failed to put PLLDSI into normal mode\n");
		return ret;
	}

	return 0;
}

static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long parent_rate)
{
	struct pll_clk *pll_clk = to_pll(hw);
	struct rzv2h_pll_dsi_info *dsi_info;
	struct rzv2h_cpg_priv *priv = pll_clk->priv;

	dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];

	return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true);
}

static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw)
{
	struct pll_clk *pll_clk = to_pll(hw);
	struct rzv2h_cpg_priv *priv = pll_clk->priv;
	u32 val = readl(priv->base + CPG_PLL_MON(pll_clk->pll.offset));

	/* Ensure both RESETB and LOCK bits are set */
	return (val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) ==
	       (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK);
}

static int rzv2h_cpg_pll_clk_enable(struct clk_hw *hw)
{
	struct pll_clk *pll_clk = to_pll(hw);
	struct rzv2h_cpg_priv *priv = pll_clk->priv;
	struct pll pll = pll_clk->pll;
	u32 stby_offset;
	u32 mon_offset;
	u32 val;
	int ret;

	if (rzv2h_cpg_pll_clk_is_enabled(hw))
		return 0;

	stby_offset = CPG_PLL_STBY(pll.offset);
	mon_offset = CPG_PLL_MON(pll.offset);

	writel(CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB,
	       priv->base + stby_offset);

	/*
	 * Ensure PLL enters into normal mode
	 *
	 * Note: There is no HW information about the worst case latency.
	 *
	 * Since this latency might depend on external crystal or PLL rate,
	 * use a "super" safe timeout value.
	 */
	ret = readl_poll_timeout_atomic(priv->base + mon_offset, val,
			(val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) ==
			(CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK), 200, 2000);
	if (ret)
		dev_err(priv->dev, "Failed to enable PLL 0x%x/%pC\n",
			stby_offset, hw->clk);

	return ret;
}

static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
						   unsigned long parent_rate)
{
	struct pll_clk *pll_clk = to_pll(hw);
	struct rzv2h_cpg_priv *priv = pll_clk->priv;
	struct pll pll = pll_clk->pll;
	unsigned int clk1, clk2;
	u64 rate;

	if (!pll.has_clkn)
		return 0;

	clk1 = readl(priv->base + CPG_PLL_CLK1(pll.offset));
	clk2 = readl(priv->base + CPG_PLL_CLK2(pll.offset));

	rate = mul_u64_u32_shr(parent_rate, (FIELD_GET(CPG_PLL_CLK1_MDIV, clk1) << 16) +
			       (s16)FIELD_GET(CPG_PLL_CLK1_KDIV, clk1),
			       16 + FIELD_GET(CPG_PLL_CLK2_SDIV, clk2));

	return DIV_ROUND_CLOSEST_ULL(rate, FIELD_GET(CPG_PLL_CLK1_PDIV, clk1));
}

static const struct clk_ops rzv2h_cpg_plldsi_ops = {
	.recalc_rate = rzv2h_cpg_pll_clk_recalc_rate,
	.determine_rate = rzv2h_cpg_plldsi_determine_rate,
	.set_rate = rzv2h_cpg_plldsi_set_rate,
};

static const struct clk_ops rzv2h_cpg_pll_ops = {
	.is_enabled = rzv2h_cpg_pll_clk_is_enabled,
	.enable = rzv2h_cpg_pll_clk_enable,
	.recalc_rate = rzv2h_cpg_pll_clk_recalc_rate,
};

static struct clk * __init
rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core,
			   struct rzv2h_cpg_priv *priv,
			   const struct clk_ops *ops)
{
	struct device *dev = priv->dev;
	struct clk_init_data init;
	const struct clk *parent;
	const char *parent_name;
	struct pll_clk *pll_clk;
	int ret;

	parent = priv->clks[core->parent];
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
	if (!pll_clk)
		return ERR_PTR(-ENOMEM);

	if (core->type == CLK_TYPE_PLLDSI)
		priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits =
			core->cfg.pll.limits;

	parent_name = __clk_get_name(parent);
	init.name = core->name;
	init.ops = ops;
	init.flags = 0;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	pll_clk->hw.init = &init;
	pll_clk->pll = core->cfg.pll;
	pll_clk->priv = priv;

	ret = devm_clk_hw_register(dev, &pll_clk->hw);
	if (ret)
		return ERR_PTR(ret);

	return pll_clk->hw.clk;
}

static unsigned long rzv2h_ddiv_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct clk_divider *divider = to_clk_divider(hw);
	unsigned int val;

	val = readl(divider->reg) >> divider->shift;
	val &= clk_div_mask(divider->width);

	return divider_recalc_rate(hw, parent_rate, val, divider->table,
				   divider->flags, divider->width);
}

static int rzv2h_ddiv_determine_rate(struct clk_hw *hw,
				     struct clk_rate_request *req)
{
	struct clk_divider *divider = to_clk_divider(hw);

	return divider_determine_rate(hw, req, divider->table, divider->width,
				      divider->flags);
}

static inline int rzv2h_cpg_wait_ddiv_clk_update_done(void __iomem *base, u8 mon)
{
	u32 bitmask = BIT(mon);
	u32 val;

	if (mon == CSDIV_NO_MON)
		return 0;

	return readl_poll_timeout_atomic(base + CPG_CLKSTATUS0, val, !(val & bitmask), 10, 200);
}

static int rzv2h_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long parent_rate)
{
	struct clk_divider *divider = to_clk_divider(hw);
	struct ddiv_clk *ddiv = to_ddiv_clock(divider);
	struct rzv2h_cpg_priv *priv = ddiv->priv;
	unsigned long flags = 0;
	int value;
	u32 val;
	int ret;

	value = divider_get_val(rate, parent_rate, divider->table,
				divider->width, divider->flags);
	if (value < 0)
		return value;

	spin_lock_irqsave(divider->lock, flags);

	ret = rzv2h_cpg_wait_ddiv_clk_update_done(priv->base, ddiv->mon);
	if (ret)
		goto ddiv_timeout;

	val = readl(divider->reg) | DDIV_DIVCTL_WEN(divider->shift);
	val &= ~(clk_div_mask(divider->width) << divider->shift);
	val |= (u32)value << divider->shift;
	writel(val, divider->reg);

	ret = rzv2h_cpg_wait_ddiv_clk_update_done(priv->base, ddiv->mon);

ddiv_timeout:
	spin_unlock_irqrestore(divider->lock, flags);
	return ret;
}

static const struct clk_ops rzv2h_ddiv_clk_divider_ops = {
	.recalc_rate = rzv2h_ddiv_recalc_rate,
	.determine_rate = rzv2h_ddiv_determine_rate,
	.set_rate = rzv2h_ddiv_set_rate,
};

static struct clk * __init
rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core,
			    struct rzv2h_cpg_priv *priv)
{
	struct ddiv cfg_ddiv = core->cfg.ddiv;
	struct clk_init_data init = {};
	struct device *dev = priv->dev;
	u8 shift = cfg_ddiv.shift;
	u8 width = cfg_ddiv.width;
	const struct clk *parent;
	const char *parent_name;
	struct clk_divider *div;
	struct ddiv_clk *ddiv;
	int ret;

	parent = priv->clks[core->parent];
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	parent_name = __clk_get_name(parent);

	if ((shift + width) > 16)
		return ERR_PTR(-EINVAL);

	ddiv = devm_kzalloc(priv->dev, sizeof(*ddiv), GFP_KERNEL);
	if (!ddiv)
		return ERR_PTR(-ENOMEM);

	init.name = core->name;
	if (cfg_ddiv.no_rmw)
		init.ops = &clk_divider_ops;
	else
		init.ops = &rzv2h_ddiv_clk_divider_ops;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	init.flags = CLK_SET_RATE_PARENT;

	ddiv->priv = priv;
	ddiv->mon = cfg_ddiv.monbit;
	div = &ddiv->div;
	div->reg = priv->base + cfg_ddiv.offset;
	div->shift = shift;
	div->width = width;
	div->flags = core->flag;
	div->lock = &priv->rmw_lock;
	div->hw.init = &init;
	div->table = core->dtable;

	ret = devm_clk_hw_register(dev, &div->hw);
	if (ret)
		return ERR_PTR(ret);

	return div->hw.clk;
}

static struct clk * __init
rzv2h_cpg_mux_clk_register(const struct cpg_core_clk *core,
			   struct rzv2h_cpg_priv *priv)
{
	struct smuxed mux = core->cfg.smux;
	const struct clk_hw *clk_hw;

	clk_hw = devm_clk_hw_register_mux(priv->dev, core->name,
					  core->parent_names, core->num_parents,
					  core->flag, priv->base + mux.offset,
					  mux.shift, mux.width,
					  core->mux_flags, &priv->rmw_lock);
	if (IS_ERR(clk_hw))
		return ERR_CAST(clk_hw);

	return clk_hw->clk;
}

static int
rzv2h_clk_ff_mod_status_is_enabled(struct clk_hw *hw)
{
	struct rzv2h_ff_mod_status_clk *fix = to_rzv2h_ff_mod_status_clk(hw);
	struct rzv2h_cpg_priv *priv = fix->priv;
	u32 offset = GET_CLK_MON_OFFSET(fix->conf.mon_index);
	u32 bitmask = BIT(fix->conf.mon_bit);
	u32 val;

	val = readl(priv->base + offset);
	return !!(val & bitmask);
}

static struct clk * __init
rzv2h_cpg_fixed_mod_status_clk_register(const struct cpg_core_clk *core,
					struct rzv2h_cpg_priv *priv)
{
	struct rzv2h_ff_mod_status_clk *clk_hw_data;
	struct clk_init_data init = { };
	struct clk_fixed_factor *fix;
	const struct clk *parent;
	const char *parent_name;
	int ret;

	WARN_DEBUG(core->parent >= priv->num_core_clks);
	parent = priv->clks[core->parent];
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	parent_name = __clk_get_name(parent);
	parent = priv->clks[core->parent];
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
	if (!clk_hw_data)
		return ERR_PTR(-ENOMEM);

	clk_hw_data->priv = priv;
	clk_hw_data->conf = core->cfg.fixed_mod;

	init.name = core->name;
	init.ops = priv->ff_mod_status_ops;
	init.flags = CLK_SET_RATE_PARENT;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	fix = &clk_hw_data->fix;
	fix->hw.init = &init;
	fix->mult = core->mult;
	fix->div = core->div;

	ret = devm_clk_hw_register(priv->dev, &clk_hw_data->fix.hw);
	if (ret)
		return ERR_PTR(ret);

	return clk_hw_data->fix.hw.clk;
}

static struct clk
*rzv2h_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
			       void *data)
{
	unsigned int clkidx = clkspec->args[1];
	struct rzv2h_cpg_priv *priv = data;
	struct device *dev = priv->dev;
	const char *type;
	struct clk *clk;

	switch (clkspec->args[0]) {
	case CPG_CORE:
		type = "core";
		if (clkidx > priv->last_dt_core_clk) {
			dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
			return ERR_PTR(-EINVAL);
		}
		clk = priv->clks[clkidx];
		break;

	case CPG_MOD:
		type = "module";
		if (clkidx >= priv->num_mod_clks) {
			dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
			return ERR_PTR(-EINVAL);
		}
		clk = priv->clks[priv->num_core_clks + clkidx];
		break;

	default:
		dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
		return ERR_PTR(-EINVAL);
	}

	if (IS_ERR(clk))
		dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx,
			PTR_ERR(clk));
	else
		dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
			clkspec->args[0], clkspec->args[1], clk,
			clk_get_rate(clk));
	return clk;
}

static void __init
rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
			    struct rzv2h_cpg_priv *priv)
{
	struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;
	unsigned int id = core->id, div = core->div;
	struct device *dev = priv->dev;
	const char *parent_name;
	struct clk_hw *clk_hw;

	WARN_DEBUG(id >= priv->num_core_clks);
	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);

	switch (core->type) {
	case CLK_TYPE_IN:
		clk = of_clk_get_by_name(priv->dev->of_node, core->name);
		break;
	case CLK_TYPE_FF:
		WARN_DEBUG(core->parent >= priv->num_core_clks);
		parent = priv->clks[core->parent];
		if (IS_ERR(parent)) {
			clk = parent;
			goto fail;
		}

		parent_name = __clk_get_name(parent);
		clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name,
							   parent_name, CLK_SET_RATE_PARENT,
							   core->mult, div);
		if (IS_ERR(clk_hw))
			clk = ERR_CAST(clk_hw);
		else
			clk = clk_hw->clk;
		break;
	case CLK_TYPE_FF_MOD_STATUS:
		if (!priv->ff_mod_status_ops) {
			priv->ff_mod_status_ops =
				devm_kzalloc(dev, sizeof(*priv->ff_mod_status_ops), GFP_KERNEL);
			if (!priv->ff_mod_status_ops) {
				clk = ERR_PTR(-ENOMEM);
				goto fail;
			}
			memcpy(priv->ff_mod_status_ops, &clk_fixed_factor_ops,
			       sizeof(const struct clk_ops));
			priv->ff_mod_status_ops->is_enabled = rzv2h_clk_ff_mod_status_is_enabled;
		}
		clk = rzv2h_cpg_fixed_mod_status_clk_register(core, priv);
		break;
	case CLK_TYPE_PLL:
		clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_pll_ops);
		break;
	case CLK_TYPE_DDIV:
		clk = rzv2h_cpg_ddiv_clk_register(core, priv);
		break;
	case CLK_TYPE_SMUX:
		clk = rzv2h_cpg_mux_clk_register(core, priv);
		break;
	case CLK_TYPE_PLLDSI:
		clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops);
		break;
	case CLK_TYPE_PLLDSI_DIV:
		clk = rzv2h_cpg_plldsi_div_clk_register(core, priv);
		break;
	default:
		goto fail;
	}

	if (IS_ERR(clk))
		goto fail;

	dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
	priv->clks[id] = clk;
	return;

fail:
	dev_err(dev, "Failed to register core clock %s: %ld\n",
		core->name, PTR_ERR(clk));
}

static void rzv2h_mod_clock_mstop_enable(struct rzv2h_cpg_priv *priv,
					 u32 mstop_data)
{
	unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, mstop_data);
	u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, mstop_data);
	atomic_t *mstop = &priv->mstop_count[mstop_index * 16];
	unsigned long flags;
	unsigned int i;
	u32 val = 0;

	spin_lock_irqsave(&priv->rmw_lock, flags);
	for_each_set_bit(i, &mstop_mask, 16) {
		if (!atomic_read(&mstop[i]))
			val |= BIT(i) << 16;
		atomic_inc(&mstop[i]);
	}
	if (val)
		writel(val, priv->base + CPG_BUS_MSTOP(mstop_index));
	spin_unlock_irqrestore(&priv->rmw_lock, flags);
}

static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv,
					  u32 mstop_data)
{
	unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, mstop_data);
	u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, mstop_data);
	atomic_t *mstop = &priv->mstop_count[mstop_index * 16];
	unsigned long flags;
	unsigned int i;
	u32 val = 0;

	spin_lock_irqsave(&priv->rmw_lock, flags);
	for_each_set_bit(i, &mstop_mask, 16) {
		if (!atomic_read(&mstop[i]) ||
		    atomic_dec_and_test(&mstop[i]))
			val |= BIT(i) << 16 | BIT(i);
	}
	if (val)
		writel(val, priv->base + CPG_BUS_MSTOP(mstop_index));
	spin_unlock_irqrestore(&priv->rmw_lock, flags);
}

static int rzv2h_parent_clk_mux_to_index(struct clk_hw *hw)
{
	struct clk_hw *parent_hw;
	struct clk *parent_clk;
	struct clk_mux *mux;
	u32 val;

	/* This will always succeed, so no need to check for IS_ERR() */
	parent_clk = clk_get_parent(hw->clk);

	parent_hw = __clk_get_hw(parent_clk);
	mux = to_clk_mux(parent_hw);

	val = readl(mux->reg) >> mux->shift;
	val &= mux->mask;
	return clk_mux_val_to_index(parent_hw, mux->table, 0, val);
}

static int rzv2h_mod_clock_is_enabled(struct clk_hw *hw)
{
	struct mod_clock *clock = to_mod_clock(hw);
	struct rzv2h_cpg_priv *priv = clock->priv;
	int mon_index = clock->mon_index;
	u32 bitmask;
	u32 offset;

	if (clock->ext_clk_mux_index >= 0 &&
	    rzv2h_parent_clk_mux_to_index(hw) == clock->ext_clk_mux_index)
		mon_index = -1;

	if (mon_index >= 0) {
		offset = GET_CLK_MON_OFFSET(mon_index);
		bitmask = BIT(clock->mon_bit);

		if (!(readl(priv->base + offset) & bitmask))
			return 0;
	}

	offset = GET_CLK_ON_OFFSET(clock->on_index);
	bitmask = BIT(clock->on_bit);

	return readl(priv->base + offset) & bitmask;
}

static int rzv2h_mod_clock_endisable(struct clk_hw *hw, bool enable)
{
	bool enabled = rzv2h_mod_clock_is_enabled(hw);
	struct mod_clock *clock = to_mod_clock(hw);
	unsigned int reg = GET_CLK_ON_OFFSET(clock->on_index);
	struct rzv2h_cpg_priv *priv = clock->priv;
	u32 bitmask = BIT(clock->on_bit);
	struct device *dev = priv->dev;
	u32 value;
	int error;

	dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", reg, hw->clk,
		str_on_off(enable));

	if (enabled == enable)
		return 0;

	value = bitmask << 16;
	if (enable) {
		value |= bitmask;
		writel(value, priv->base + reg);
		if (clock->mstop_data != BUS_MSTOP_NONE)
			rzv2h_mod_clock_mstop_enable(priv, clock->mstop_data);
	} else {
		if (clock->mstop_data != BUS_MSTOP_NONE)
			rzv2h_mod_clock_mstop_disable(priv, clock->mstop_data);
		writel(value, priv->base + reg);
	}

	if (!enable || clock->mon_index < 0)
		return 0;

	reg = GET_CLK_MON_OFFSET(clock->mon_index);
	bitmask = BIT(clock->mon_bit);
	error = readl_poll_timeout_atomic(priv->base + reg, value,
					  value & bitmask, 0, 10);
	if (error)
		dev_err(dev, "Failed to enable CLK_ON 0x%x/%pC\n",
			GET_CLK_ON_OFFSET(clock->on_index), hw->clk);

	return error;
}

static int rzv2h_mod_clock_enable(struct clk_hw *hw)
{
	return rzv2h_mod_clock_endisable(hw, true);
}

static void rzv2h_mod_clock_disable(struct clk_hw *hw)
{
	rzv2h_mod_clock_endisable(hw, false);
}

static const struct clk_ops rzv2h_mod_clock_ops = {
	.enable = rzv2h_mod_clock_enable,
	.disable = rzv2h_mod_clock_disable,
	.is_enabled = rzv2h_mod_clock_is_enabled,
};

static void __init
rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
			   struct rzv2h_cpg_priv *priv)
{
	struct mod_clock *clock = NULL;
	struct device *dev = priv->dev;
	struct clk_init_data init;
	struct clk *parent, *clk;
	const char *parent_name;
	unsigned int id;
	int ret;

	id = GET_MOD_CLK_ID(priv->num_core_clks, mod->on_index, mod->on_bit);
	WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
	WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
	WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);

	parent = priv->clks[mod->parent];
	if (IS_ERR(parent)) {
		clk = parent;
		goto fail;
	}

	clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
	if (!clock) {
		clk = ERR_PTR(-ENOMEM);
		goto fail;
	}

	init.name = mod->name;
	init.ops = &rzv2h_mod_clock_ops;
	init.flags = CLK_SET_RATE_PARENT;
	if (mod->critical)
		init.flags |= CLK_IS_CRITICAL;

	parent_name = __clk_get_name(parent);
	init.parent_names = &parent_name;
	init.num_parents = 1;

	clock->on_index = mod->on_index;
	clock->on_bit = mod->on_bit;
	clock->mon_index = mod->mon_index;
	clock->mon_bit = mod->mon_bit;
	clock->no_pm = mod->no_pm;
	clock->ext_clk_mux_index = mod->ext_clk_mux_index;
	clock->priv = priv;
	clock->hw.init = &init;
	clock->mstop_data = mod->mstop_data;

	ret = devm_clk_hw_register(dev, &clock->hw);
	if (ret) {
		clk = ERR_PTR(ret);
		goto fail;
	}

	priv->clks[id] = clock->hw.clk;

	/*
	 * Ensure the module clocks and MSTOP bits are synchronized when they are
	 * turned ON by the bootloader. Enable MSTOP bits for module clocks that were
	 * turned ON in an earlier boot stage.
	 */
	if (clock->mstop_data != BUS_MSTOP_NONE &&
	    !mod->critical && rzv2h_mod_clock_is_enabled(&clock->hw)) {
		rzv2h_mod_clock_mstop_enable(priv, clock->mstop_data);
	} else if (clock->mstop_data != BUS_MSTOP_NONE && mod->critical) {
		unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, clock->mstop_data);
		u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, clock->mstop_data);
		atomic_t *mstop = &priv->mstop_count[mstop_index * 16];
		unsigned long flags;
		unsigned int i;
		u32 val = 0;

		/*
		 * Critical clocks are turned ON immediately upon registration, and the
		 * MSTOP counter is updated through the rzv2h_mod_clock_enable() path.
		 * However, if the critical clocks were already turned ON by the initial
		 * bootloader, synchronize the atomic counter here and clear the MSTOP bit.
		 */
		spin_lock_irqsave(&priv->rmw_lock, flags);
		for_each_set_bit(i, &mstop_mask, 16) {
			if (atomic_read(&mstop[i]))
				continue;
			val |= BIT(i) << 16;
			atomic_inc(&mstop[i]);
		}
		if (val)
			writel(val, priv->base + CPG_BUS_MSTOP(mstop_index));
		spin_unlock_irqrestore(&priv->rmw_lock, flags);
	}

	return;

fail:
	dev_err(dev, "Failed to register module clock %s: %ld\n",
		mod->name, PTR_ERR(clk));
}

static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev,
			      unsigned long id, bool assert)
{
	struct rzv2h_cpg_priv *priv = rcdev_to_priv(rcdev);
	unsigned int reg = GET_RST_OFFSET(priv->resets[id].reset_index);
	u32 mask = BIT(priv->resets[id].reset_bit);
	u8 monbit = priv->resets[id].mon_bit;
	u32 value = mask << 16;
	u32 mon;
	int ret;

	dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n",
		assert ? "assert" : "deassert", id, reg);

	if (!assert)
		value |= mask;
	writel(value, priv->base + reg);

	reg = GET_RST_MON_OFFSET(priv->resets[id].mon_index);
	mask = BIT(monbit);

	ret = readl_poll_timeout_atomic(priv->base + reg, mon,
					assert == !!(mon & mask), 10, 200);
	if (ret) {
		value ^= mask;
		writel(value, priv->base + GET_RST_OFFSET(priv->resets[id].reset_index));
	}

	return ret;
}

static int rzv2h_cpg_assert(struct reset_controller_dev *rcdev,
			    unsigned long id)
{
	return __rzv2h_cpg_assert(rcdev, id, true);
}

static int rzv2h_cpg_deassert(struct reset_controller_dev *rcdev,
			      unsigned long id)
{
	return __rzv2h_cpg_assert(rcdev, id, false);
}

static int rzv2h_cpg_reset(struct reset_controller_dev *rcdev,
			   unsigned long id)
{
	int ret;

	ret = rzv2h_cpg_assert(rcdev, id);
	if (ret)
		return ret;

	return rzv2h_cpg_deassert(rcdev, id);
}

static int rzv2h_cpg_status(struct reset_controller_dev *rcdev,
			    unsigned long id)
{
	struct rzv2h_cpg_priv *priv = rcdev_to_priv(rcdev);
	unsigned int reg = GET_RST_MON_OFFSET(priv->resets[id].mon_index);
	u8 monbit = priv->resets[id].mon_bit;

	return !!(readl(priv->base + reg) & BIT(monbit));
}

static const struct reset_control_ops rzv2h_cpg_reset_ops = {
	.reset = rzv2h_cpg_reset,
	.assert = rzv2h_cpg_assert,
	.deassert = rzv2h_cpg_deassert,
	.status = rzv2h_cpg_status,
};

static int rzv2h_cpg_reset_xlate(struct reset_controller_dev *rcdev,
				 const struct of_phandle_args *reset_spec)
{
	struct rzv2h_cpg_priv *priv = rcdev_to_priv(rcdev);
	unsigned int id = reset_spec->args[0];
	u8 rst_index = id / 16;
	u8 rst_bit = id % 16;
	unsigned int i;

	for (i = 0; i < rcdev->nr_resets; i++) {
		if (rst_index == priv->resets[i].reset_index &&
		    rst_bit == priv->resets[i].reset_bit)
			return i;
	}

	return -EINVAL;
}

static int rzv2h_cpg_reset_controller_register(struct rzv2h_cpg_priv *priv)
{
	priv->rcdev.ops = &rzv2h_cpg_reset_ops;
	priv->rcdev.of_node = priv->dev->of_node;
	priv->rcdev.dev = priv->dev;
	priv->rcdev.of_reset_n_cells = 1;
	priv->rcdev.of_xlate = rzv2h_cpg_reset_xlate;
	priv->rcdev.nr_resets = priv->num_resets;

	return devm_reset_controller_register(priv->dev, &priv->rcdev);
}

/**
 * struct rzv2h_cpg_pd - RZ/V2H power domain data structure
 * @priv: pointer to CPG private data structure
 * @genpd: generic PM domain
 */
struct rzv2h_cpg_pd {
	struct rzv2h_cpg_priv *priv;
	struct generic_pm_domain genpd;
};

static bool rzv2h_cpg_is_pm_clk(struct rzv2h_cpg_pd *pd,
				const struct of_phandle_args *clkspec)
{
	if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2)
		return false;

	switch (clkspec->args[0]) {
	case CPG_MOD: {
		struct rzv2h_cpg_priv *priv = pd->priv;
		unsigned int id = clkspec->args[1];
		struct mod_clock *clock;

		if (id >= priv->num_mod_clks)
			return false;

		if (priv->clks[priv->num_core_clks + id] == ERR_PTR(-ENOENT))
			return false;

		clock = to_mod_clock(__clk_get_hw(priv->clks[priv->num_core_clks + id]));

		return !clock->no_pm;
	}

	case CPG_CORE:
	default:
		return false;
	}
}

static int rzv2h_cpg_attach_dev(struct generic_pm_domain *domain, struct device *dev)
{
	struct rzv2h_cpg_pd *pd = container_of(domain, struct rzv2h_cpg_pd, genpd);
	struct device_node *np = dev->of_node;
	struct of_phandle_args clkspec;
	bool once = true;
	struct clk *clk;
	unsigned int i;
	int error;

	for (i = 0; !of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec); i++) {
		if (!rzv2h_cpg_is_pm_clk(pd, &clkspec)) {
			of_node_put(clkspec.np);
			continue;
		}

		if (once) {
			once = false;
			error = pm_clk_create(dev);
			if (error) {
				of_node_put(clkspec.np);
				goto err;
			}
		}
		clk = of_clk_get_from_provider(&clkspec);
		of_node_put(clkspec.np);
		if (IS_ERR(clk)) {
			error = PTR_ERR(clk);
			goto fail_destroy;
		}

		error = pm_clk_add_clk(dev, clk);
		if (error) {
			dev_err(dev, "pm_clk_add_clk failed %d\n",
				error);
			goto fail_put;
		}
	}

	return 0;

fail_put:
	clk_put(clk);

fail_destroy:
	pm_clk_destroy(dev);
err:
	return error;
}

static void rzv2h_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev)
{
	if (!pm_clk_no_clocks(dev))
		pm_clk_destroy(dev);
}

static void rzv2h_cpg_genpd_remove_simple(void *data)
{
	pm_genpd_remove(data);
}

static int __init rzv2h_cpg_add_pm_domains(struct rzv2h_cpg_priv *priv)
{
	struct device *dev = priv->dev;
	struct device_node *np = dev->of_node;
	struct rzv2h_cpg_pd *pd;
	int ret;

	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
	if (!pd)
		return -ENOMEM;

	pd->genpd.name = np->name;
	pd->priv = priv;
	pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
	pd->genpd.attach_dev = rzv2h_cpg_attach_dev;
	pd->genpd.detach_dev = rzv2h_cpg_detach_dev;
	ret = pm_genpd_init(&pd->genpd, &pm_domain_always_on_gov, false);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, rzv2h_cpg_genpd_remove_simple, &pd->genpd);
	if (ret)
		return ret;

	return of_genpd_add_provider_simple(np, &pd->genpd);
}

static void rzv2h_cpg_del_clk_provider(void *data)
{
	of_clk_del_provider(data);
}

static int __init rzv2h_cpg_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	const struct rzv2h_cpg_info *info;
	struct rzv2h_cpg_priv *priv;
	unsigned int nclks, i;
	struct clk **clks;
	int error;

	info = of_device_get_match_data(dev);

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	spin_lock_init(&priv->rmw_lock);

	priv->dev = dev;

	priv->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	nclks = info->num_total_core_clks + info->num_hw_mod_clks;
	clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
	if (!clks)
		return -ENOMEM;

	priv->mstop_count = devm_kcalloc(dev, info->num_mstop_bits,
					 sizeof(*priv->mstop_count), GFP_KERNEL);
	if (!priv->mstop_count)
		return -ENOMEM;

	/* Adjust for CPG_BUS_m_MSTOP starting from m = 1 */
	priv->mstop_count -= 16;

	priv->resets = devm_kmemdup_array(dev, info->resets, info->num_resets,
					  sizeof(*info->resets), GFP_KERNEL);
	if (!priv->resets)
		return -ENOMEM;

	dev_set_drvdata(dev, priv);
	priv->clks = clks;
	priv->num_core_clks = info->num_total_core_clks;
	priv->num_mod_clks = info->num_hw_mod_clks;
	priv->last_dt_core_clk = info->last_dt_core_clk;
	priv->num_resets = info->num_resets;

	for (i = 0; i < nclks; i++)
		clks[i] = ERR_PTR(-ENOENT);

	for (i = 0; i < info->num_core_clks; i++)
		rzv2h_cpg_register_core_clk(&info->core_clks[i], priv);

	for (i = 0; i < info->num_mod_clks; i++)
		rzv2h_cpg_register_mod_clk(&info->mod_clks[i], priv);

	error = of_clk_add_provider(np, rzv2h_cpg_clk_src_twocell_get, priv);
	if (error)
		return error;

	error = devm_add_action_or_reset(dev, rzv2h_cpg_del_clk_provider, np);
	if (error)
		return error;

	error = rzv2h_cpg_add_pm_domains(priv);
	if (error)
		return error;

	error = rzv2h_cpg_reset_controller_register(priv);
	if (error)
		return error;

	return 0;
}

static const struct of_device_id rzv2h_cpg_match[] = {
#ifdef CONFIG_CLK_R9A09G047
	{
		.compatible = "renesas,r9a09g047-cpg",
		.data = &r9a09g047_cpg_info,
	},
#endif
#ifdef CONFIG_CLK_R9A09G056
	{
		.compatible = "renesas,r9a09g056-cpg",
		.data = &r9a09g056_cpg_info,
	},
#endif
#ifdef CONFIG_CLK_R9A09G057
	{
		.compatible = "renesas,r9a09g057-cpg",
		.data = &r9a09g057_cpg_info,
	},
#endif
	{ /* sentinel */ }
};

static struct platform_driver rzv2h_cpg_driver = {
	.driver		= {
		.name	= "rzv2h-cpg",
		.of_match_table = rzv2h_cpg_match,
	},
};

static int __init rzv2h_cpg_init(void)
{
	return platform_driver_probe(&rzv2h_cpg_driver, rzv2h_cpg_probe);
}

subsys_initcall(rzv2h_cpg_init);

MODULE_DESCRIPTION("Renesas RZ/V2H CPG Driver");
