// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
 * Copyright 2017 Linaro Ltd.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/slab.h>

#define ZX_PWM_MODE		0x0
#define ZX_PWM_CLKDIV_SHIFT	2
#define ZX_PWM_CLKDIV_MASK	GENMASK(11, 2)
#define ZX_PWM_CLKDIV(x)	(((x) << ZX_PWM_CLKDIV_SHIFT) & \
					 ZX_PWM_CLKDIV_MASK)
#define ZX_PWM_POLAR		BIT(1)
#define ZX_PWM_EN		BIT(0)
#define ZX_PWM_PERIOD		0x4
#define ZX_PWM_DUTY		0x8

#define ZX_PWM_CLKDIV_MAX	1023
#define ZX_PWM_PERIOD_MAX	65535

struct zx_pwm_chip {
	struct pwm_chip chip;
	struct clk *pclk;
	struct clk *wclk;
	void __iomem *base;
};

static inline struct zx_pwm_chip *to_zx_pwm_chip(struct pwm_chip *chip)
{
	return container_of(chip, struct zx_pwm_chip, chip);
}

static inline u32 zx_pwm_readl(struct zx_pwm_chip *zpc, unsigned int hwpwm,
			       unsigned int offset)
{
	return readl(zpc->base + (hwpwm + 1) * 0x10 + offset);
}

static inline void zx_pwm_writel(struct zx_pwm_chip *zpc, unsigned int hwpwm,
				 unsigned int offset, u32 value)
{
	writel(value, zpc->base + (hwpwm + 1) * 0x10 + offset);
}

static void zx_pwm_set_mask(struct zx_pwm_chip *zpc, unsigned int hwpwm,
			    unsigned int offset, u32 mask, u32 value)
{
	u32 data;

	data = zx_pwm_readl(zpc, hwpwm, offset);
	data &= ~mask;
	data |= value & mask;
	zx_pwm_writel(zpc, hwpwm, offset, data);
}

static void zx_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			     struct pwm_state *state)
{
	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
	unsigned long rate;
	unsigned int div;
	u32 value;
	u64 tmp;

	value = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_MODE);

	if (value & ZX_PWM_POLAR)
		state->polarity = PWM_POLARITY_NORMAL;
	else
		state->polarity = PWM_POLARITY_INVERSED;

	if (value & ZX_PWM_EN)
		state->enabled = true;
	else
		state->enabled = false;

	div = (value & ZX_PWM_CLKDIV_MASK) >> ZX_PWM_CLKDIV_SHIFT;
	rate = clk_get_rate(zpc->wclk);

	tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_PERIOD);
	tmp *= div * NSEC_PER_SEC;
	state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);

	tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_DUTY);
	tmp *= div * NSEC_PER_SEC;
	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
}

static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			 unsigned int duty_ns, unsigned int period_ns)
{
	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
	unsigned int period_cycles, duty_cycles;
	unsigned long long c;
	unsigned int div = 1;
	unsigned long rate;

	/* Find out the best divider */
	rate = clk_get_rate(zpc->wclk);

	while (1) {
		c = rate / div;
		c = c * period_ns;
		do_div(c, NSEC_PER_SEC);

		if (c < ZX_PWM_PERIOD_MAX)
			break;

		div++;

		if (div > ZX_PWM_CLKDIV_MAX)
			return -ERANGE;
	}

	/* Calculate duty cycles */
	period_cycles = c;
	c *= duty_ns;
	do_div(c, period_ns);
	duty_cycles = c;

	/*
	 * If the PWM is being enabled, we have to temporarily disable it
	 * before configuring the registers.
	 */
	if (pwm_is_enabled(pwm))
		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_EN, 0);

	/* Set up registers */
	zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_CLKDIV_MASK,
			ZX_PWM_CLKDIV(div));
	zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_PERIOD, period_cycles);
	zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_DUTY, duty_cycles);

	/* Re-enable the PWM if needed */
	if (pwm_is_enabled(pwm))
		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
				ZX_PWM_EN, ZX_PWM_EN);

	return 0;
}

static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			const struct pwm_state *state)
{
	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
	struct pwm_state cstate;
	int ret;

	pwm_get_state(pwm, &cstate);

	if (state->polarity != cstate.polarity)
		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_POLAR,
				(state->polarity == PWM_POLARITY_INVERSED) ?
				 0 : ZX_PWM_POLAR);

	if (state->period != cstate.period ||
	    state->duty_cycle != cstate.duty_cycle) {
		ret = zx_pwm_config(chip, pwm, state->duty_cycle,
				    state->period);
		if (ret)
			return ret;
	}

	if (state->enabled != cstate.enabled) {
		if (state->enabled) {
			ret = clk_prepare_enable(zpc->wclk);
			if (ret)
				return ret;

			zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
					ZX_PWM_EN, ZX_PWM_EN);
		} else {
			zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
					ZX_PWM_EN, 0);
			clk_disable_unprepare(zpc->wclk);
		}
	}

	return 0;
}

static const struct pwm_ops zx_pwm_ops = {
	.apply = zx_pwm_apply,
	.get_state = zx_pwm_get_state,
	.owner = THIS_MODULE,
};

static int zx_pwm_probe(struct platform_device *pdev)
{
	struct zx_pwm_chip *zpc;
	unsigned int i;
	int ret;

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

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

	zpc->pclk = devm_clk_get(&pdev->dev, "pclk");
	if (IS_ERR(zpc->pclk))
		return PTR_ERR(zpc->pclk);

	zpc->wclk = devm_clk_get(&pdev->dev, "wclk");
	if (IS_ERR(zpc->wclk))
		return PTR_ERR(zpc->wclk);

	ret = clk_prepare_enable(zpc->pclk);
	if (ret)
		return ret;

	zpc->chip.dev = &pdev->dev;
	zpc->chip.ops = &zx_pwm_ops;
	zpc->chip.base = -1;
	zpc->chip.npwm = 4;
	zpc->chip.of_xlate = of_pwm_xlate_with_flags;
	zpc->chip.of_pwm_n_cells = 3;

	/*
	 * PWM devices may be enabled by firmware, and let's disable all of
	 * them initially to save power.
	 */
	for (i = 0; i < zpc->chip.npwm; i++)
		zx_pwm_set_mask(zpc, i, ZX_PWM_MODE, ZX_PWM_EN, 0);

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

	platform_set_drvdata(pdev, zpc);

	return 0;
}

static int zx_pwm_remove(struct platform_device *pdev)
{
	struct zx_pwm_chip *zpc = platform_get_drvdata(pdev);
	int ret;

	ret = pwmchip_remove(&zpc->chip);
	clk_disable_unprepare(zpc->pclk);

	return ret;
}

static const struct of_device_id zx_pwm_dt_ids[] = {
	{ .compatible = "zte,zx296718-pwm", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, zx_pwm_dt_ids);

static struct platform_driver zx_pwm_driver = {
	.driver = {
		.name = "zx-pwm",
		.of_match_table = zx_pwm_dt_ids,
	},
	.probe = zx_pwm_probe,
	.remove = zx_pwm_remove,
};
module_platform_driver(zx_pwm_driver);

MODULE_ALIAS("platform:zx-pwm");
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
MODULE_DESCRIPTION("ZTE ZX PWM Driver");
MODULE_LICENSE("GPL v2");
