// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Freescale FlexTimer Module (FTM) PWM Driver
 *
 *  Copyright 2012-2013 Freescale Semiconductor, Inc.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/fsl/ftm.h>

#define FTM_SC_CLK(c)	(((c) + 1) << FTM_SC_CLK_MASK_SHIFT)

enum fsl_pwm_clk {
	FSL_PWM_CLK_SYS,
	FSL_PWM_CLK_FIX,
	FSL_PWM_CLK_EXT,
	FSL_PWM_CLK_CNTEN,
	FSL_PWM_CLK_MAX
};

struct fsl_ftm_soc {
	bool has_enable_bits;
};

struct fsl_pwm_periodcfg {
	enum fsl_pwm_clk clk_select;
	unsigned int clk_ps;
	unsigned int mod_period;
};

struct fsl_pwm_chip {
	struct pwm_chip chip;
	struct mutex lock;
	struct regmap *regmap;

	/* This value is valid iff a pwm is running */
	struct fsl_pwm_periodcfg period;

	struct clk *ipg_clk;
	struct clk *clk[FSL_PWM_CLK_MAX];

	const struct fsl_ftm_soc *soc;
};

static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct fsl_pwm_chip, chip);
}

static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc)
{
	u32 val;

	regmap_read(fpc->regmap, FTM_FMS, &val);
	if (val & FTM_FMS_WPEN)
		regmap_set_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS);
}

static void ftm_set_write_protection(struct fsl_pwm_chip *fpc)
{
	regmap_set_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN);
}

static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
					const struct fsl_pwm_periodcfg *b)
{
	if (a->clk_select != b->clk_select)
		return false;
	if (a->clk_ps != b->clk_ps)
		return false;
	if (a->mod_period != b->mod_period)
		return false;
	return true;
}

static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
	int ret;
	struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

	ret = clk_prepare_enable(fpc->ipg_clk);
	if (!ret && fpc->soc->has_enable_bits) {
		mutex_lock(&fpc->lock);
		regmap_set_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
		mutex_unlock(&fpc->lock);
	}

	return ret;
}

static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct fsl_pwm_chip *fpc = to_fsl_chip(chip);

	if (fpc->soc->has_enable_bits) {
		mutex_lock(&fpc->lock);
		regmap_clear_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
		mutex_unlock(&fpc->lock);
	}

	clk_disable_unprepare(fpc->ipg_clk);
}

static unsigned int fsl_pwm_ticks_to_ns(struct fsl_pwm_chip *fpc,
					  unsigned int ticks)
{
	unsigned long rate;
	unsigned long long exval;

	rate = clk_get_rate(fpc->clk[fpc->period.clk_select]);
	exval = ticks;
	exval *= 1000000000UL;
	do_div(exval, rate >> fpc->period.clk_ps);
	return exval;
}

static bool fsl_pwm_calculate_period_clk(struct fsl_pwm_chip *fpc,
					 unsigned int period_ns,
					 enum fsl_pwm_clk index,
					 struct fsl_pwm_periodcfg *periodcfg
					 )
{
	unsigned long long c;
	unsigned int ps;

	c = clk_get_rate(fpc->clk[index]);
	c = c * period_ns;
	do_div(c, 1000000000UL);

	if (c == 0)
		return false;

	for (ps = 0; ps < 8 ; ++ps, c >>= 1) {
		if (c <= 0x10000) {
			periodcfg->clk_select = index;
			periodcfg->clk_ps = ps;
			periodcfg->mod_period = c - 1;
			return true;
		}
	}
	return false;
}

static bool fsl_pwm_calculate_period(struct fsl_pwm_chip *fpc,
				     unsigned int period_ns,
				     struct fsl_pwm_periodcfg *periodcfg)
{
	enum fsl_pwm_clk m0, m1;
	unsigned long fix_rate, ext_rate;
	bool ret;

	ret = fsl_pwm_calculate_period_clk(fpc, period_ns, FSL_PWM_CLK_SYS,
					   periodcfg);
	if (ret)
		return true;

	fix_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_FIX]);
	ext_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_EXT]);

	if (fix_rate > ext_rate) {
		m0 = FSL_PWM_CLK_FIX;
		m1 = FSL_PWM_CLK_EXT;
	} else {
		m0 = FSL_PWM_CLK_EXT;
		m1 = FSL_PWM_CLK_FIX;
	}

	ret = fsl_pwm_calculate_period_clk(fpc, period_ns, m0, periodcfg);
	if (ret)
		return true;

	return fsl_pwm_calculate_period_clk(fpc, period_ns, m1, periodcfg);
}

static unsigned int fsl_pwm_calculate_duty(struct fsl_pwm_chip *fpc,
					   unsigned int duty_ns)
{
	unsigned long long duty;

	unsigned int period = fpc->period.mod_period + 1;
	unsigned int period_ns = fsl_pwm_ticks_to_ns(fpc, period);

	duty = (unsigned long long)duty_ns * period;
	do_div(duty, period_ns);

	return (unsigned int)duty;
}

static bool fsl_pwm_is_any_pwm_enabled(struct fsl_pwm_chip *fpc,
				       struct pwm_device *pwm)
{
	u32 val;

	regmap_read(fpc->regmap, FTM_OUTMASK, &val);
	if (~val & 0xFF)
		return true;
	else
		return false;
}

static bool fsl_pwm_is_other_pwm_enabled(struct fsl_pwm_chip *fpc,
					 struct pwm_device *pwm)
{
	u32 val;

	regmap_read(fpc->regmap, FTM_OUTMASK, &val);
	if (~(val | BIT(pwm->hwpwm)) & 0xFF)
		return true;
	else
		return false;
}

static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc,
				struct pwm_device *pwm,
				const struct pwm_state *newstate)
{
	unsigned int duty;
	u32 reg_polarity;

	struct fsl_pwm_periodcfg periodcfg;
	bool do_write_period = false;

	if (!fsl_pwm_calculate_period(fpc, newstate->period, &periodcfg)) {
		dev_err(fpc->chip.dev, "failed to calculate new period\n");
		return -EINVAL;
	}

	if (!fsl_pwm_is_any_pwm_enabled(fpc, pwm))
		do_write_period = true;
	/*
	 * The Freescale FTM controller supports only a single period for
	 * all PWM channels, therefore verify if the newly computed period
	 * is different than the current period being used. In such case
	 * we allow to change the period only if no other pwm is running.
	 */
	else if (!fsl_pwm_periodcfg_are_equal(&fpc->period, &periodcfg)) {
		if (fsl_pwm_is_other_pwm_enabled(fpc, pwm)) {
			dev_err(fpc->chip.dev,
				"Cannot change period for PWM %u, disable other PWMs first\n",
				pwm->hwpwm);
			return -EBUSY;
		}
		if (fpc->period.clk_select != periodcfg.clk_select) {
			int ret;
			enum fsl_pwm_clk oldclk = fpc->period.clk_select;
			enum fsl_pwm_clk newclk = periodcfg.clk_select;

			ret = clk_prepare_enable(fpc->clk[newclk]);
			if (ret)
				return ret;
			clk_disable_unprepare(fpc->clk[oldclk]);
		}
		do_write_period = true;
	}

	ftm_clear_write_protection(fpc);

	if (do_write_period) {
		regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
				   FTM_SC_CLK(periodcfg.clk_select));
		regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_PS_MASK,
				   periodcfg.clk_ps);
		regmap_write(fpc->regmap, FTM_MOD, periodcfg.mod_period);

		fpc->period = periodcfg;
	}

	duty = fsl_pwm_calculate_duty(fpc, newstate->duty_cycle);

	regmap_write(fpc->regmap, FTM_CSC(pwm->hwpwm),
		     FTM_CSC_MSB | FTM_CSC_ELSB);
	regmap_write(fpc->regmap, FTM_CV(pwm->hwpwm), duty);

	reg_polarity = 0;
	if (newstate->polarity == PWM_POLARITY_INVERSED)
		reg_polarity = BIT(pwm->hwpwm);

	regmap_update_bits(fpc->regmap, FTM_POL, BIT(pwm->hwpwm), reg_polarity);

	ftm_set_write_protection(fpc);

	return 0;
}

static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			 const struct pwm_state *newstate)
{
	struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
	struct pwm_state *oldstate = &pwm->state;
	int ret = 0;

	/*
	 * oldstate to newstate : action
	 *
	 * disabled to disabled : ignore
	 * enabled to disabled : disable
	 * enabled to enabled : update settings
	 * disabled to enabled : update settings + enable
	 */

	mutex_lock(&fpc->lock);

	if (!newstate->enabled) {
		if (oldstate->enabled) {
			regmap_set_bits(fpc->regmap, FTM_OUTMASK,
					BIT(pwm->hwpwm));
			clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
			clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
		}

		goto end_mutex;
	}

	ret = fsl_pwm_apply_config(fpc, pwm, newstate);
	if (ret)
		goto end_mutex;

	/* check if need to enable */
	if (!oldstate->enabled) {
		ret = clk_prepare_enable(fpc->clk[fpc->period.clk_select]);
		if (ret)
			goto end_mutex;

		ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
		if (ret) {
			clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
			goto end_mutex;
		}

		regmap_clear_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm));
	}

end_mutex:
	mutex_unlock(&fpc->lock);
	return ret;
}

static const struct pwm_ops fsl_pwm_ops = {
	.request = fsl_pwm_request,
	.free = fsl_pwm_free,
	.apply = fsl_pwm_apply,
	.owner = THIS_MODULE,
};

static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
{
	int ret;

	ret = clk_prepare_enable(fpc->ipg_clk);
	if (ret)
		return ret;

	regmap_write(fpc->regmap, FTM_CNTIN, 0x00);
	regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
	regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);

	clk_disable_unprepare(fpc->ipg_clk);

	return 0;
}

static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case FTM_FMS:
	case FTM_MODE:
	case FTM_CNT:
		return true;
	}
	return false;
}

static const struct regmap_config fsl_pwm_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,

	.max_register = FTM_PWMLOAD,
	.volatile_reg = fsl_pwm_volatile_reg,
	.cache_type = REGCACHE_FLAT,
};

static int fsl_pwm_probe(struct platform_device *pdev)
{
	struct fsl_pwm_chip *fpc;
	void __iomem *base;
	int ret;

	fpc = devm_kzalloc(&pdev->dev, sizeof(*fpc), GFP_KERNEL);
	if (!fpc)
		return -ENOMEM;

	mutex_init(&fpc->lock);

	fpc->soc = of_device_get_match_data(&pdev->dev);
	fpc->chip.dev = &pdev->dev;

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

	fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ftm_sys", base,
						&fsl_pwm_regmap_config);
	if (IS_ERR(fpc->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(fpc->regmap);
	}

	fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
	if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
		dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
		return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
	}

	fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(fpc->chip.dev, "ftm_fix");
	if (IS_ERR(fpc->clk[FSL_PWM_CLK_FIX]))
		return PTR_ERR(fpc->clk[FSL_PWM_CLK_FIX]);

	fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(fpc->chip.dev, "ftm_ext");
	if (IS_ERR(fpc->clk[FSL_PWM_CLK_EXT]))
		return PTR_ERR(fpc->clk[FSL_PWM_CLK_EXT]);

	fpc->clk[FSL_PWM_CLK_CNTEN] =
				devm_clk_get(fpc->chip.dev, "ftm_cnt_clk_en");
	if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
		return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);

	/*
	 * ipg_clk is the interface clock for the IP. If not provided, use the
	 * ftm_sys clock as the default.
	 */
	fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(fpc->ipg_clk))
		fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];


	fpc->chip.ops = &fsl_pwm_ops;
	fpc->chip.npwm = 8;

	ret = devm_pwmchip_add(&pdev->dev, &fpc->chip);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, fpc);

	return fsl_pwm_init(fpc);
}

#ifdef CONFIG_PM_SLEEP
static int fsl_pwm_suspend(struct device *dev)
{
	struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
	int i;

	regcache_cache_only(fpc->regmap, true);
	regcache_mark_dirty(fpc->regmap);

	for (i = 0; i < fpc->chip.npwm; i++) {
		struct pwm_device *pwm = &fpc->chip.pwms[i];

		if (!test_bit(PWMF_REQUESTED, &pwm->flags))
			continue;

		clk_disable_unprepare(fpc->ipg_clk);

		if (!pwm_is_enabled(pwm))
			continue;

		clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
		clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
	}

	return 0;
}

static int fsl_pwm_resume(struct device *dev)
{
	struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < fpc->chip.npwm; i++) {
		struct pwm_device *pwm = &fpc->chip.pwms[i];

		if (!test_bit(PWMF_REQUESTED, &pwm->flags))
			continue;

		clk_prepare_enable(fpc->ipg_clk);

		if (!pwm_is_enabled(pwm))
			continue;

		clk_prepare_enable(fpc->clk[fpc->period.clk_select]);
		clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
	}

	/* restore all registers from cache */
	regcache_cache_only(fpc->regmap, false);
	regcache_sync(fpc->regmap);

	return 0;
}
#endif

static const struct dev_pm_ops fsl_pwm_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
};

static const struct fsl_ftm_soc vf610_ftm_pwm = {
	.has_enable_bits = false,
};

static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
	.has_enable_bits = true,
};

static const struct of_device_id fsl_pwm_dt_ids[] = {
	{ .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
	{ .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);

static struct platform_driver fsl_pwm_driver = {
	.driver = {
		.name = "fsl-ftm-pwm",
		.of_match_table = fsl_pwm_dt_ids,
		.pm = &fsl_pwm_pm_ops,
	},
	.probe = fsl_pwm_probe,
};
module_platform_driver(fsl_pwm_driver);

MODULE_DESCRIPTION("Freescale FlexTimer Module PWM Driver");
MODULE_AUTHOR("Xiubo Li <Li.Xiubo@freescale.com>");
MODULE_ALIAS("platform:fsl-ftm-pwm");
MODULE_LICENSE("GPL");
