// SPDX-License-Identifier: GPL-2.0
/*
 * PWM device driver for SUNPLUS SP7021 SoC
 *
 * Links:
 *   Reference Manual:
 *   https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 *
 *   Reference Manual(PWM module):
 *   https://sunplus.atlassian.net/wiki/spaces/doc/pages/461144198/12.+Pulse+Width+Modulation+PWM
 *
 * Limitations:
 * - Only supports normal polarity.
 * - It output low when PWM channel disabled.
 * - When the parameters change, current running period will not be completed
 *     and run new settings immediately.
 * - In .apply() PWM output need to write register FREQ and DUTY. When first write FREQ
 *     done and not yet write DUTY, it has short timing gap use new FREQ and old DUTY.
 *
 * Author: Hammer Hsieh <hammerh0314@gmail.com>
 */
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>

#define SP7021_PWM_MODE0		0x000
#define SP7021_PWM_MODE0_PWMEN(ch)	BIT(ch)
#define SP7021_PWM_MODE0_BYPASS(ch)	BIT(8 + (ch))
#define SP7021_PWM_MODE1		0x004
#define SP7021_PWM_MODE1_CNT_EN(ch)	BIT(ch)
#define SP7021_PWM_FREQ(ch)		(0x008 + 4 * (ch))
#define SP7021_PWM_FREQ_MAX		GENMASK(15, 0)
#define SP7021_PWM_DUTY(ch)		(0x018 + 4 * (ch))
#define SP7021_PWM_DUTY_DD_SEL(ch)	FIELD_PREP(GENMASK(9, 8), ch)
#define SP7021_PWM_DUTY_MAX		GENMASK(7, 0)
#define SP7021_PWM_DUTY_MASK		SP7021_PWM_DUTY_MAX
#define SP7021_PWM_FREQ_SCALER		256
#define SP7021_PWM_NUM			4

struct sunplus_pwm {
	struct pwm_chip chip;
	void __iomem *base;
	struct clk *clk;
};

static inline struct sunplus_pwm *to_sunplus_pwm(struct pwm_chip *chip)
{
	return container_of(chip, struct sunplus_pwm, chip);
}

static int sunplus_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			     const struct pwm_state *state)
{
	struct sunplus_pwm *priv = to_sunplus_pwm(chip);
	u32 dd_freq, duty, mode0, mode1;
	u64 clk_rate;

	if (state->polarity != pwm->state.polarity)
		return -EINVAL;

	if (!state->enabled) {
		/* disable pwm channel output */
		mode0 = readl(priv->base + SP7021_PWM_MODE0);
		mode0 &= ~SP7021_PWM_MODE0_PWMEN(pwm->hwpwm);
		writel(mode0, priv->base + SP7021_PWM_MODE0);
		/* disable pwm channel clk source */
		mode1 = readl(priv->base + SP7021_PWM_MODE1);
		mode1 &= ~SP7021_PWM_MODE1_CNT_EN(pwm->hwpwm);
		writel(mode1, priv->base + SP7021_PWM_MODE1);
		return 0;
	}

	clk_rate = clk_get_rate(priv->clk);

	/*
	 * The following calculations might overflow if clk is bigger
	 * than 256 GHz. In practise it's 202.5MHz, so this limitation
	 * is only theoretic.
	 */
	if (clk_rate > (u64)SP7021_PWM_FREQ_SCALER * NSEC_PER_SEC)
		return -EINVAL;

	/*
	 * With clk_rate limited above we have dd_freq <= state->period,
	 * so this cannot overflow.
	 */
	dd_freq = mul_u64_u64_div_u64(clk_rate, state->period, (u64)SP7021_PWM_FREQ_SCALER
				* NSEC_PER_SEC);

	if (dd_freq == 0)
		return -EINVAL;

	if (dd_freq > SP7021_PWM_FREQ_MAX)
		dd_freq = SP7021_PWM_FREQ_MAX;

	writel(dd_freq, priv->base + SP7021_PWM_FREQ(pwm->hwpwm));

	/* cal and set pwm duty */
	mode0 = readl(priv->base + SP7021_PWM_MODE0);
	mode0 |= SP7021_PWM_MODE0_PWMEN(pwm->hwpwm);
	mode1 = readl(priv->base + SP7021_PWM_MODE1);
	mode1 |= SP7021_PWM_MODE1_CNT_EN(pwm->hwpwm);
	if (state->duty_cycle == state->period) {
		/* PWM channel output = high */
		mode0 |= SP7021_PWM_MODE0_BYPASS(pwm->hwpwm);
		duty = SP7021_PWM_DUTY_DD_SEL(pwm->hwpwm) | SP7021_PWM_DUTY_MAX;
	} else {
		mode0 &= ~SP7021_PWM_MODE0_BYPASS(pwm->hwpwm);
		/*
		 * duty_ns <= period_ns 27 bits, clk_rate 28 bits, won't overflow.
		 */
		duty = mul_u64_u64_div_u64(state->duty_cycle, clk_rate,
					   (u64)dd_freq * NSEC_PER_SEC);
		duty = SP7021_PWM_DUTY_DD_SEL(pwm->hwpwm) | duty;
	}
	writel(duty, priv->base + SP7021_PWM_DUTY(pwm->hwpwm));
	writel(mode1, priv->base + SP7021_PWM_MODE1);
	writel(mode0, priv->base + SP7021_PWM_MODE0);

	return 0;
}

static int sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
				 struct pwm_state *state)
{
	struct sunplus_pwm *priv = to_sunplus_pwm(chip);
	u32 mode0, dd_freq, duty;
	u64 clk_rate;

	mode0 = readl(priv->base + SP7021_PWM_MODE0);

	if (mode0 & BIT(pwm->hwpwm)) {
		clk_rate = clk_get_rate(priv->clk);
		dd_freq = readl(priv->base + SP7021_PWM_FREQ(pwm->hwpwm));
		duty = readl(priv->base + SP7021_PWM_DUTY(pwm->hwpwm));
		duty = FIELD_GET(SP7021_PWM_DUTY_MASK, duty);
		/*
		 * dd_freq 16 bits, SP7021_PWM_FREQ_SCALER 8 bits
		 * NSEC_PER_SEC 30 bits, won't overflow.
		 */
		state->period = DIV64_U64_ROUND_UP((u64)dd_freq * (u64)SP7021_PWM_FREQ_SCALER
						* NSEC_PER_SEC, clk_rate);
		/*
		 * dd_freq 16 bits, duty 8 bits, NSEC_PER_SEC 30 bits, won't overflow.
		 */
		state->duty_cycle = DIV64_U64_ROUND_UP((u64)dd_freq * (u64)duty * NSEC_PER_SEC,
						       clk_rate);
		state->enabled = true;
	} else {
		state->enabled = false;
	}

	state->polarity = PWM_POLARITY_NORMAL;

	return 0;
}

static const struct pwm_ops sunplus_pwm_ops = {
	.apply = sunplus_pwm_apply,
	.get_state = sunplus_pwm_get_state,
	.owner = THIS_MODULE,
};

static void sunplus_pwm_clk_release(void *data)
{
	struct clk *clk = data;

	clk_disable_unprepare(clk);
}

static int sunplus_pwm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sunplus_pwm *priv;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

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

	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk))
		return dev_err_probe(dev, PTR_ERR(priv->clk),
				     "get pwm clock failed\n");

	ret = clk_prepare_enable(priv->clk);
	if (ret < 0) {
		dev_err(dev, "failed to enable clock: %d\n", ret);
		return ret;
	}

	ret = devm_add_action_or_reset(dev, sunplus_pwm_clk_release, priv->clk);
	if (ret < 0) {
		dev_err(dev, "failed to release clock: %d\n", ret);
		return ret;
	}

	priv->chip.dev = dev;
	priv->chip.ops = &sunplus_pwm_ops;
	priv->chip.npwm = SP7021_PWM_NUM;

	ret = devm_pwmchip_add(dev, &priv->chip);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Cannot register sunplus PWM\n");

	return 0;
}

static const struct of_device_id sunplus_pwm_of_match[] = {
	{ .compatible = "sunplus,sp7021-pwm", },
	{}
};
MODULE_DEVICE_TABLE(of, sunplus_pwm_of_match);

static struct platform_driver sunplus_pwm_driver = {
	.probe		= sunplus_pwm_probe,
	.driver		= {
		.name	= "sunplus-pwm",
		.of_match_table = sunplus_pwm_of_match,
	},
};
module_platform_driver(sunplus_pwm_driver);

MODULE_DESCRIPTION("Sunplus SoC PWM Driver");
MODULE_AUTHOR("Hammer Hsieh <hammerh0314@gmail.com>");
MODULE_LICENSE("GPL");
