// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PWM Controller Driver for HiSilicon BVT SoCs
 *
 * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/reset.h>

#define PWM_CFG0_ADDR(x)    (((x) * 0x20) + 0x0)
#define PWM_CFG1_ADDR(x)    (((x) * 0x20) + 0x4)
#define PWM_CFG2_ADDR(x)    (((x) * 0x20) + 0x8)
#define PWM_CTRL_ADDR(x)    (((x) * 0x20) + 0xC)

#define PWM_ENABLE_SHIFT    0
#define PWM_ENABLE_MASK     BIT(0)

#define PWM_POLARITY_SHIFT  1
#define PWM_POLARITY_MASK   BIT(1)

#define PWM_KEEP_SHIFT      2
#define PWM_KEEP_MASK       BIT(2)

#define PWM_PERIOD_MASK     GENMASK(31, 0)
#define PWM_DUTY_MASK       GENMASK(31, 0)

struct hibvt_pwm_chip {
	struct clk *clk;
	void __iomem *base;
	struct reset_control *rstc;
	const struct hibvt_pwm_soc *soc;
};

struct hibvt_pwm_soc {
	u32 num_pwms;
	bool quirk_force_enable;
};

static const struct hibvt_pwm_soc hi3516cv300_soc_info = {
	.num_pwms = 4,
};

static const struct hibvt_pwm_soc hi3519v100_soc_info = {
	.num_pwms = 8,
};

static const struct hibvt_pwm_soc hi3559v100_shub_soc_info = {
	.num_pwms = 8,
	.quirk_force_enable = true,
};

static const struct hibvt_pwm_soc hi3559v100_soc_info = {
	.num_pwms = 2,
	.quirk_force_enable = true,
};

static inline struct hibvt_pwm_chip *to_hibvt_pwm_chip(struct pwm_chip *chip)
{
	return pwmchip_get_drvdata(chip);
}

static void hibvt_pwm_set_bits(void __iomem *base, u32 offset,
					u32 mask, u32 data)
{
	void __iomem *address = base + offset;
	u32 value;

	value = readl(address);
	value &= ~mask;
	value |= (data & mask);
	writel(value, address);
}

static void hibvt_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);

	hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
			PWM_ENABLE_MASK, 0x1);
}

static void hibvt_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);

	hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
			PWM_ENABLE_MASK, 0x0);
}

static void hibvt_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
					int duty_cycle_ns, int period_ns)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
	u32 freq, period, duty;

	freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000);

	period = div_u64(freq * period_ns, 1000);
	duty = div_u64(period * duty_cycle_ns, period_ns);

	hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm),
			PWM_PERIOD_MASK, period);

	hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm),
			PWM_DUTY_MASK, duty);
}

static void hibvt_pwm_set_polarity(struct pwm_chip *chip,
					struct pwm_device *pwm,
					enum pwm_polarity polarity)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);

	if (polarity == PWM_POLARITY_INVERSED)
		hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
				PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT));
	else
		hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm),
				PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT));
}

static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			       struct pwm_state *state)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
	void __iomem *base;
	u32 freq, value;

	freq = div_u64(clk_get_rate(hi_pwm_chip->clk), 1000000);
	base = hi_pwm_chip->base;

	value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm));
	state->period = div_u64(value * 1000, freq);

	value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm));
	state->duty_cycle = div_u64(value * 1000, freq);

	value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
	state->enabled = (PWM_ENABLE_MASK & value);
	state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;

	return 0;
}

static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			   const struct pwm_state *state)
{
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);

	if (state->polarity != pwm->state.polarity)
		hibvt_pwm_set_polarity(chip, pwm, state->polarity);

	if (state->period != pwm->state.period ||
	    state->duty_cycle != pwm->state.duty_cycle) {
		hibvt_pwm_config(chip, pwm, state->duty_cycle, state->period);

		/*
		 * Some implementations require the PWM to be enabled twice
		 * each time the duty cycle is refreshed.
		 */
		if (hi_pwm_chip->soc->quirk_force_enable && state->enabled)
			hibvt_pwm_enable(chip, pwm);
	}

	if (state->enabled != pwm->state.enabled) {
		if (state->enabled)
			hibvt_pwm_enable(chip, pwm);
		else
			hibvt_pwm_disable(chip, pwm);
	}

	return 0;
}

static const struct pwm_ops hibvt_pwm_ops = {
	.get_state = hibvt_pwm_get_state,
	.apply = hibvt_pwm_apply,

};

static int hibvt_pwm_probe(struct platform_device *pdev)
{
	const struct hibvt_pwm_soc *soc =
				of_device_get_match_data(&pdev->dev);
	struct pwm_chip *chip;
	struct hibvt_pwm_chip *hi_pwm_chip;
	int ret, i;

	chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*hi_pwm_chip));
	if (IS_ERR(chip))
		return PTR_ERR(chip);
	hi_pwm_chip = to_hibvt_pwm_chip(chip);

	hi_pwm_chip->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(hi_pwm_chip->clk)) {
		dev_err(&pdev->dev, "getting clock failed with %ld\n",
				PTR_ERR(hi_pwm_chip->clk));
		return PTR_ERR(hi_pwm_chip->clk);
	}

	chip->ops = &hibvt_pwm_ops;
	hi_pwm_chip->soc = soc;

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

	ret = clk_prepare_enable(hi_pwm_chip->clk);
	if (ret < 0)
		return ret;

	hi_pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
	if (IS_ERR(hi_pwm_chip->rstc)) {
		clk_disable_unprepare(hi_pwm_chip->clk);
		return PTR_ERR(hi_pwm_chip->rstc);
	}

	reset_control_assert(hi_pwm_chip->rstc);
	msleep(30);
	reset_control_deassert(hi_pwm_chip->rstc);

	ret = pwmchip_add(chip);
	if (ret < 0) {
		clk_disable_unprepare(hi_pwm_chip->clk);
		return ret;
	}

	for (i = 0; i < chip->npwm; i++) {
		hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(i),
				PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT));
	}

	platform_set_drvdata(pdev, chip);

	return 0;
}

static void hibvt_pwm_remove(struct platform_device *pdev)
{
	struct pwm_chip *chip = platform_get_drvdata(pdev);
	struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);

	pwmchip_remove(chip);

	reset_control_assert(hi_pwm_chip->rstc);
	msleep(30);
	reset_control_deassert(hi_pwm_chip->rstc);

	clk_disable_unprepare(hi_pwm_chip->clk);
}

static const struct of_device_id hibvt_pwm_of_match[] = {
	{ .compatible = "hisilicon,hi3516cv300-pwm",
	  .data = &hi3516cv300_soc_info },
	{ .compatible = "hisilicon,hi3519v100-pwm",
	  .data = &hi3519v100_soc_info },
	{ .compatible = "hisilicon,hi3559v100-shub-pwm",
	  .data = &hi3559v100_shub_soc_info },
	{ .compatible = "hisilicon,hi3559v100-pwm",
	  .data = &hi3559v100_soc_info },
	{  }
};
MODULE_DEVICE_TABLE(of, hibvt_pwm_of_match);

static struct platform_driver hibvt_pwm_driver = {
	.driver = {
		.name = "hibvt-pwm",
		.of_match_table = hibvt_pwm_of_match,
	},
	.probe = hibvt_pwm_probe,
	.remove_new = hibvt_pwm_remove,
};
module_platform_driver(hibvt_pwm_driver);

MODULE_AUTHOR("Jian Yuan");
MODULE_DESCRIPTION("HiSilicon BVT SoCs PWM driver");
MODULE_LICENSE("GPL");
