/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/types.h>

#define REG_DIV_CTL1			0x43
#define DIV_CTL1_DIV_FACTOR_MASK	GENMASK(2, 0)

#define REG_EN_CTL			0x46
#define REG_EN_MASK			BIT(7)

struct clkdiv {
	struct regmap		*regmap;
	u16			base;
	spinlock_t		lock;

	struct clk_hw		hw;
	unsigned int		cxo_period_ns;
};

static inline struct clkdiv *to_clkdiv(struct clk_hw *hw)
{
	return container_of(hw, struct clkdiv, hw);
}

static inline unsigned int div_factor_to_div(unsigned int div_factor)
{
	if (!div_factor)
		div_factor = 1;

	return 1 << (div_factor - 1);
}

static inline unsigned int div_to_div_factor(unsigned int div)
{
	return min(ilog2(div) + 1, 7);
}

static bool is_spmi_pmic_clkdiv_enabled(struct clkdiv *clkdiv)
{
	unsigned int val = 0;

	regmap_read(clkdiv->regmap, clkdiv->base + REG_EN_CTL, &val);

	return val & REG_EN_MASK;
}

static int
__spmi_pmic_clkdiv_set_enable_state(struct clkdiv *clkdiv, bool enable,
				    unsigned int div_factor)
{
	int ret;
	unsigned int ns = clkdiv->cxo_period_ns;
	unsigned int div = div_factor_to_div(div_factor);

	ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_EN_CTL,
				 REG_EN_MASK, enable ? REG_EN_MASK : 0);
	if (ret)
		return ret;

	if (enable)
		ndelay((2 + 3 * div) * ns);
	else
		ndelay(3 * div * ns);

	return 0;
}

static int spmi_pmic_clkdiv_set_enable_state(struct clkdiv *clkdiv, bool enable)
{
	unsigned int div_factor;

	regmap_read(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, &div_factor);
	div_factor &= DIV_CTL1_DIV_FACTOR_MASK;

	return __spmi_pmic_clkdiv_set_enable_state(clkdiv, enable, div_factor);
}

static int clk_spmi_pmic_div_enable(struct clk_hw *hw)
{
	struct clkdiv *clkdiv = to_clkdiv(hw);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&clkdiv->lock, flags);
	ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, true);
	spin_unlock_irqrestore(&clkdiv->lock, flags);

	return ret;
}

static void clk_spmi_pmic_div_disable(struct clk_hw *hw)
{
	struct clkdiv *clkdiv = to_clkdiv(hw);
	unsigned long flags;

	spin_lock_irqsave(&clkdiv->lock, flags);
	spmi_pmic_clkdiv_set_enable_state(clkdiv, false);
	spin_unlock_irqrestore(&clkdiv->lock, flags);
}

static long clk_spmi_pmic_div_round_rate(struct clk_hw *hw, unsigned long rate,
					 unsigned long *parent_rate)
{
	unsigned int div, div_factor;

	div = DIV_ROUND_UP(*parent_rate, rate);
	div_factor = div_to_div_factor(div);
	div = div_factor_to_div(div_factor);

	return *parent_rate / div;
}

static unsigned long
clk_spmi_pmic_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
	struct clkdiv *clkdiv = to_clkdiv(hw);
	unsigned int div_factor;

	regmap_read(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, &div_factor);
	div_factor &= DIV_CTL1_DIV_FACTOR_MASK;

	return parent_rate / div_factor_to_div(div_factor);
}

static int clk_spmi_pmic_div_set_rate(struct clk_hw *hw, unsigned long rate,
				      unsigned long parent_rate)
{
	struct clkdiv *clkdiv = to_clkdiv(hw);
	unsigned int div_factor = div_to_div_factor(parent_rate / rate);
	unsigned long flags;
	bool enabled;
	int ret;

	spin_lock_irqsave(&clkdiv->lock, flags);
	enabled = is_spmi_pmic_clkdiv_enabled(clkdiv);
	if (enabled) {
		ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, false);
		if (ret)
			goto unlock;
	}

	ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1,
				 DIV_CTL1_DIV_FACTOR_MASK, div_factor);
	if (ret)
		goto unlock;

	if (enabled)
		ret = __spmi_pmic_clkdiv_set_enable_state(clkdiv, true,
							  div_factor);

unlock:
	spin_unlock_irqrestore(&clkdiv->lock, flags);

	return ret;
}

static const struct clk_ops clk_spmi_pmic_div_ops = {
	.enable = clk_spmi_pmic_div_enable,
	.disable = clk_spmi_pmic_div_disable,
	.set_rate = clk_spmi_pmic_div_set_rate,
	.recalc_rate = clk_spmi_pmic_div_recalc_rate,
	.round_rate = clk_spmi_pmic_div_round_rate,
};

struct spmi_pmic_div_clk_cc {
	int		nclks;
	struct clkdiv	clks[];
};

static struct clk_hw *
spmi_pmic_div_clk_hw_get(struct of_phandle_args *clkspec, void *data)
{
	struct spmi_pmic_div_clk_cc *cc = data;
	int idx = clkspec->args[0] - 1; /* Start at 1 instead of 0 */

	if (idx < 0 || idx >= cc->nclks) {
		pr_err("%s: index value %u is invalid; allowed range [1, %d]\n",
		       __func__, clkspec->args[0], cc->nclks);
		return ERR_PTR(-EINVAL);
	}

	return &cc->clks[idx].hw;
}

static int spmi_pmic_clkdiv_probe(struct platform_device *pdev)
{
	struct spmi_pmic_div_clk_cc *cc;
	struct clk_init_data init = {};
	struct clkdiv *clkdiv;
	struct clk *cxo;
	struct regmap *regmap;
	struct device *dev = &pdev->dev;
	struct device_node *of_node = dev->of_node;
	const char *parent_name;
	int nclks, i, ret, cxo_hz;
	char name[20];
	u32 start;

	ret = of_property_read_u32(of_node, "reg", &start);
	if (ret < 0) {
		dev_err(dev, "reg property reading failed\n");
		return ret;
	}

	regmap = dev_get_regmap(dev->parent, NULL);
	if (!regmap) {
		dev_err(dev, "Couldn't get parent's regmap\n");
		return -EINVAL;
	}

	ret = of_property_read_u32(of_node, "qcom,num-clkdivs", &nclks);
	if (ret < 0) {
		dev_err(dev, "qcom,num-clkdivs property reading failed, ret=%d\n",
			ret);
		return ret;
	}

	if (!nclks)
		return -EINVAL;

	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*cc->clks) * nclks,
			  GFP_KERNEL);
	if (!cc)
		return -ENOMEM;
	cc->nclks = nclks;

	cxo = clk_get(dev, "xo");
	if (IS_ERR(cxo)) {
		ret = PTR_ERR(cxo);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to get xo clock\n");
		return ret;
	}
	cxo_hz = clk_get_rate(cxo);
	clk_put(cxo);

	parent_name = of_clk_get_parent_name(of_node, 0);
	if (!parent_name) {
		dev_err(dev, "missing parent clock\n");
		return -ENODEV;
	}

	init.name = name;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	init.ops = &clk_spmi_pmic_div_ops;

	for (i = 0, clkdiv = cc->clks; i < nclks; i++) {
		snprintf(name, sizeof(name), "div_clk%d", i + 1);

		spin_lock_init(&clkdiv[i].lock);
		clkdiv[i].base = start + i * 0x100;
		clkdiv[i].regmap = regmap;
		clkdiv[i].cxo_period_ns = NSEC_PER_SEC / cxo_hz;
		clkdiv[i].hw.init = &init;

		ret = devm_clk_hw_register(dev, &clkdiv[i].hw);
		if (ret)
			return ret;
	}

	return devm_of_clk_add_hw_provider(dev, spmi_pmic_div_clk_hw_get, cc);
}

static const struct of_device_id spmi_pmic_clkdiv_match_table[] = {
	{ .compatible = "qcom,spmi-clkdiv" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, spmi_pmic_clkdiv_match_table);

static struct platform_driver spmi_pmic_clkdiv_driver = {
	.driver		= {
		.name	= "qcom,spmi-pmic-clkdiv",
		.of_match_table = spmi_pmic_clkdiv_match_table,
	},
	.probe		= spmi_pmic_clkdiv_probe,
};
module_platform_driver(spmi_pmic_clkdiv_driver);

MODULE_DESCRIPTION("QCOM SPMI PMIC clkdiv driver");
MODULE_LICENSE("GPL v2");
