// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017~2018 NXP
 *
 * Author: Dong Aisheng <aisheng.dong@nxp.com>
 *
 */

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

#include "clk.h"

/**
 * struct clk_pfdv2 - IMX PFD clock
 * @hw:		clock source
 * @reg:	PFD register address
 * @gate_bit:	Gate bit offset
 * @vld_bit:	Valid bit offset
 * @frac_off:	PLL Fractional Divider offset
 */

struct clk_pfdv2 {
	struct clk_hw	hw;
	void __iomem	*reg;
	u8		gate_bit;
	u8		vld_bit;
	u8		frac_off;
};

#define to_clk_pfdv2(_hw) container_of(_hw, struct clk_pfdv2, hw)

#define CLK_PFDV2_FRAC_MASK 0x3f

#define LOCK_TIMEOUT_US		USEC_PER_MSEC

static DEFINE_SPINLOCK(pfd_lock);

static int clk_pfdv2_wait(struct clk_pfdv2 *pfd)
{
	u32 val;

	return readl_poll_timeout(pfd->reg, val, val & (1 << pfd->vld_bit),
				  0, LOCK_TIMEOUT_US);
}

static int clk_pfdv2_enable(struct clk_hw *hw)
{
	struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&pfd_lock, flags);
	val = readl_relaxed(pfd->reg);
	val &= ~(1 << pfd->gate_bit);
	writel_relaxed(val, pfd->reg);
	spin_unlock_irqrestore(&pfd_lock, flags);

	return clk_pfdv2_wait(pfd);
}

static void clk_pfdv2_disable(struct clk_hw *hw)
{
	struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&pfd_lock, flags);
	val = readl_relaxed(pfd->reg);
	val |= (1 << pfd->gate_bit);
	writel_relaxed(val, pfd->reg);
	spin_unlock_irqrestore(&pfd_lock, flags);
}

static unsigned long clk_pfdv2_recalc_rate(struct clk_hw *hw,
					   unsigned long parent_rate)
{
	struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
	u64 tmp = parent_rate;
	u8 frac;

	frac = (readl_relaxed(pfd->reg) >> pfd->frac_off)
		& CLK_PFDV2_FRAC_MASK;

	if (!frac) {
		pr_debug("clk_pfdv2: %s invalid pfd frac value 0\n",
			 clk_hw_get_name(hw));
		return 0;
	}

	tmp *= 18;
	do_div(tmp, frac);

	return tmp;
}

static int clk_pfdv2_determine_rate(struct clk_hw *hw,
				    struct clk_rate_request *req)
{
	unsigned long parent_rates[] = {
					480000000,
					528000000,
					req->best_parent_rate
				       };
	unsigned long best_rate = -1UL, rate = req->rate;
	unsigned long best_parent_rate = req->best_parent_rate;
	u64 tmp;
	u8 frac;
	int i;

	for (i = 0; i < ARRAY_SIZE(parent_rates); i++) {
		tmp = parent_rates[i];
		tmp = tmp * 18 + rate / 2;
		do_div(tmp, rate);
		frac = tmp;

		if (frac < 12)
			frac = 12;
		else if (frac > 35)
			frac = 35;

		tmp = parent_rates[i];
		tmp *= 18;
		do_div(tmp, frac);

		if (abs(tmp - req->rate) < abs(best_rate - req->rate)) {
			best_rate = tmp;
			best_parent_rate = parent_rates[i];
		}
	}

	req->best_parent_rate = best_parent_rate;
	req->rate = best_rate;

	return 0;
}

static int clk_pfdv2_is_enabled(struct clk_hw *hw)
{
	struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);

	if (readl_relaxed(pfd->reg) & (1 << pfd->gate_bit))
		return 0;

	return 1;
}

static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate,
			      unsigned long parent_rate)
{
	struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
	unsigned long flags;
	u64 tmp = parent_rate;
	u32 val;
	u8 frac;

	if (!rate)
		return -EINVAL;

	/*
	 * PFD can NOT change rate without gating.
	 * as the PFDs may enabled in HW by default but no
	 * consumer used it, the enable count is '0', so the
	 * 'SET_RATE_GATE' can NOT help on blocking the set_rate
	 * ops especially for 'assigned-clock-xxx'. In order
	 * to simplify the case, just disable the PFD if it is
	 * enabled in HW but not in SW.
	 */
	if (clk_pfdv2_is_enabled(hw))
		clk_pfdv2_disable(hw);

	tmp = tmp * 18 + rate / 2;
	do_div(tmp, rate);
	frac = tmp;
	if (frac < 12)
		frac = 12;
	else if (frac > 35)
		frac = 35;

	spin_lock_irqsave(&pfd_lock, flags);
	val = readl_relaxed(pfd->reg);
	val &= ~(CLK_PFDV2_FRAC_MASK << pfd->frac_off);
	val |= frac << pfd->frac_off;
	writel_relaxed(val, pfd->reg);
	spin_unlock_irqrestore(&pfd_lock, flags);

	return 0;
}

static const struct clk_ops clk_pfdv2_ops = {
	.enable		= clk_pfdv2_enable,
	.disable	= clk_pfdv2_disable,
	.recalc_rate	= clk_pfdv2_recalc_rate,
	.determine_rate	= clk_pfdv2_determine_rate,
	.set_rate	= clk_pfdv2_set_rate,
	.is_enabled     = clk_pfdv2_is_enabled,
};

struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name,
			     const char *parent_name, void __iomem *reg, u8 idx)
{
	struct clk_init_data init;
	struct clk_pfdv2 *pfd;
	struct clk_hw *hw;
	int ret;

	WARN_ON(idx > 3);

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

	pfd->reg = reg;
	pfd->gate_bit = (idx + 1) * 8 - 1;
	pfd->vld_bit = pfd->gate_bit - 1;
	pfd->frac_off = idx * 8;

	init.name = name;
	init.ops = &clk_pfdv2_ops;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	if (type == IMX_PFDV2_IMX7ULP)
		init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
	else
		init.flags = CLK_SET_RATE_GATE;

	pfd->hw.init = &init;

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

	return hw;
}
EXPORT_SYMBOL_GPL(imx_clk_hw_pfdv2);
