// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2018 NXP.
 *   Dong Aisheng <aisheng.dong@nxp.com>
 */

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

#include "clk.h"

struct clk_divider_gate {
	struct clk_divider divider;
	u32 cached_val;
};

static inline struct clk_divider_gate *to_clk_divider_gate(struct clk_hw *hw)
{
	struct clk_divider *div = to_clk_divider(hw);

	return container_of(div, struct clk_divider_gate, divider);
}

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

	val = readl(div->reg) >> div->shift;
	val &= clk_div_mask(div->width);
	if (!val)
		return 0;

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

static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
						  unsigned long parent_rate)
{
	struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
	struct clk_divider *div = to_clk_divider(hw);
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(div->lock, flags);

	if (!clk_hw_is_enabled(hw)) {
		val = div_gate->cached_val;
	} else {
		val = readl(div->reg) >> div->shift;
		val &= clk_div_mask(div->width);
	}

	spin_unlock_irqrestore(div->lock, flags);

	if (!val)
		return 0;

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

static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
				   unsigned long *prate)
{
	return clk_divider_ops.round_rate(hw, rate, prate);
}

static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent_rate)
{
	struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
	struct clk_divider *div = to_clk_divider(hw);
	unsigned long flags;
	int value;
	u32 val;

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

	spin_lock_irqsave(div->lock, flags);

	if (clk_hw_is_enabled(hw)) {
		val = readl(div->reg);
		val &= ~(clk_div_mask(div->width) << div->shift);
		val |= (u32)value << div->shift;
		writel(val, div->reg);
	} else {
		div_gate->cached_val = value;
	}

	spin_unlock_irqrestore(div->lock, flags);

	return 0;
}

static int clk_divider_enable(struct clk_hw *hw)
{
	struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
	struct clk_divider *div = to_clk_divider(hw);
	unsigned long flags;
	u32 val;

	if (!div_gate->cached_val) {
		pr_err("%s: no valid preset rate\n", clk_hw_get_name(hw));
		return -EINVAL;
	}

	spin_lock_irqsave(div->lock, flags);
	/* restore div val */
	val = readl(div->reg);
	val |= div_gate->cached_val << div->shift;
	writel(val, div->reg);

	spin_unlock_irqrestore(div->lock, flags);

	return 0;
}

static void clk_divider_disable(struct clk_hw *hw)
{
	struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
	struct clk_divider *div = to_clk_divider(hw);
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(div->lock, flags);

	/* store the current div val */
	val = readl(div->reg) >> div->shift;
	val &= clk_div_mask(div->width);
	div_gate->cached_val = val;
	writel(0, div->reg);

	spin_unlock_irqrestore(div->lock, flags);
}

static int clk_divider_is_enabled(struct clk_hw *hw)
{
	struct clk_divider *div = to_clk_divider(hw);
	u32 val;

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

	return val ? 1 : 0;
}

static const struct clk_ops clk_divider_gate_ro_ops = {
	.recalc_rate = clk_divider_gate_recalc_rate_ro,
	.round_rate = clk_divider_round_rate,
};

static const struct clk_ops clk_divider_gate_ops = {
	.recalc_rate = clk_divider_gate_recalc_rate,
	.round_rate = clk_divider_round_rate,
	.set_rate = clk_divider_gate_set_rate,
	.enable = clk_divider_enable,
	.disable = clk_divider_disable,
	.is_enabled = clk_divider_is_enabled,
};

/*
 * NOTE: In order to reuse the most code from the common divider,
 * we also design our divider following the way that provids an extra
 * clk_divider_flags, however it's fixed to CLK_DIVIDER_ONE_BASED by
 * default as our HW is. Besides that it supports only CLK_DIVIDER_READ_ONLY
 * flag which can be specified by user flexibly.
 */
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
				    unsigned long flags, void __iomem *reg,
				    u8 shift, u8 width, u8 clk_divider_flags,
				    const struct clk_div_table *table,
				    spinlock_t *lock)
{
	struct clk_init_data init;
	struct clk_divider_gate *div_gate;
	struct clk_hw *hw;
	u32 val;
	int ret;

	div_gate  = kzalloc(sizeof(*div_gate), GFP_KERNEL);
	if (!div_gate)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
		init.ops = &clk_divider_gate_ro_ops;
	else
		init.ops = &clk_divider_gate_ops;
	init.flags = flags;
	init.parent_names = parent_name ? &parent_name : NULL;
	init.num_parents = parent_name ? 1 : 0;

	div_gate->divider.reg = reg;
	div_gate->divider.shift = shift;
	div_gate->divider.width = width;
	div_gate->divider.lock = lock;
	div_gate->divider.table = table;
	div_gate->divider.hw.init = &init;
	div_gate->divider.flags = CLK_DIVIDER_ONE_BASED | clk_divider_flags;
	/* cache gate status */
	val = readl(reg) >> shift;
	val &= clk_div_mask(width);
	div_gate->cached_val = val;

	hw = &div_gate->divider.hw;
	ret = clk_hw_register(NULL, hw);
	if (ret) {
		kfree(div_gate);
		hw = ERR_PTR(ret);
	}

	return hw;
}
