// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017~2018 NXP
 *
 */

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

#include "../clk-fractional-divider.h"
#include "clk.h"

#define PCG_PCS_SHIFT	24
#define PCG_PCS_MASK	0x7
#define PCG_CGC_SHIFT	30
#define PCG_FRAC_SHIFT	3
#define PCG_FRAC_WIDTH	1
#define PCG_PCD_SHIFT	0
#define PCG_PCD_WIDTH	3

#define SW_RST		BIT(28)

static int pcc_gate_enable(struct clk_hw *hw)
{
	struct clk_gate *gate = to_clk_gate(hw);
	unsigned long flags;
	u32 val;
	int ret;

	ret = clk_gate_ops.enable(hw);
	if (ret)
		return ret;

	spin_lock_irqsave(gate->lock, flags);
	/*
	 * release the sw reset for peripherals associated with
	 * with this pcc clock.
	 */
	val = readl(gate->reg);
	val |= SW_RST;
	writel(val, gate->reg);

	spin_unlock_irqrestore(gate->lock, flags);

	return 0;
}

static void pcc_gate_disable(struct clk_hw *hw)
{
	clk_gate_ops.disable(hw);
}

static int pcc_gate_is_enabled(struct clk_hw *hw)
{
	return clk_gate_ops.is_enabled(hw);
}

static const struct clk_ops pcc_gate_ops = {
	.enable = pcc_gate_enable,
	.disable = pcc_gate_disable,
	.is_enabled = pcc_gate_is_enabled,
};

static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,
				     const char * const *parent_names,
				     int num_parents, bool mux_present,
				     bool rate_present, bool gate_present,
				     void __iomem *reg, bool has_swrst)
{
	struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL;
	struct clk_fractional_divider *fd = NULL;
	struct clk_gate *gate = NULL;
	struct clk_mux *mux = NULL;
	struct clk_hw *hw;
	u32 val;

	if (mux_present) {
		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
		if (!mux)
			return ERR_PTR(-ENOMEM);
		mux_hw = &mux->hw;
		mux->reg = reg;
		mux->shift = PCG_PCS_SHIFT;
		mux->mask = PCG_PCS_MASK;
		if (has_swrst)
			mux->lock = &imx_ccm_lock;
	}

	if (rate_present) {
		fd = kzalloc(sizeof(*fd), GFP_KERNEL);
		if (!fd) {
			kfree(mux);
			return ERR_PTR(-ENOMEM);
		}
		fd_hw = &fd->hw;
		fd->reg = reg;
		fd->mshift = PCG_FRAC_SHIFT;
		fd->mwidth = PCG_FRAC_WIDTH;
		fd->nshift = PCG_PCD_SHIFT;
		fd->nwidth = PCG_PCD_WIDTH;
		fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
		if (has_swrst)
			fd->lock = &imx_ccm_lock;
	}

	if (gate_present) {
		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
		if (!gate) {
			kfree(mux);
			kfree(fd);
			return ERR_PTR(-ENOMEM);
		}
		gate_hw = &gate->hw;
		gate->reg = reg;
		gate->bit_idx = PCG_CGC_SHIFT;
		if (has_swrst)
			gate->lock = &imx_ccm_lock;
		/*
		 * make sure clock is gated during clock tree initialization,
		 * the HW ONLY allow clock parent/rate changed with clock gated,
		 * during clock tree initialization, clocks could be enabled
		 * by bootloader, so the HW status will mismatch with clock tree
		 * prepare count, then clock core driver will allow parent/rate
		 * change since the prepare count is zero, but HW actually
		 * prevent the parent/rate change due to the clock is enabled.
		 */
		val = readl_relaxed(reg);
		val &= ~(1 << PCG_CGC_SHIFT);
		writel_relaxed(val, reg);
	}

	hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
				       mux_hw, &clk_mux_ops, fd_hw,
				       &clk_fractional_divider_ops, gate_hw,
				       has_swrst ? &pcc_gate_ops : &clk_gate_ops, CLK_SET_RATE_GATE |
				       CLK_SET_PARENT_GATE | CLK_SET_RATE_NO_REPARENT);
	if (IS_ERR(hw)) {
		kfree(mux);
		kfree(fd);
		kfree(gate);
	}

	return hw;
}

struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names,
				int num_parents, bool mux_present, bool rate_present,
				bool gate_present, void __iomem *reg)
{
	return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present,
					gate_present, reg, false);
}

struct clk_hw *imx8ulp_clk_hw_composite(const char *name, const char * const *parent_names,
				int num_parents, bool mux_present, bool rate_present,
				bool gate_present, void __iomem *reg, bool has_swrst)
{
	return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present,
					gate_present, reg, has_swrst);
}
EXPORT_SYMBOL_GPL(imx8ulp_clk_hw_composite);
