// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020 SiFive, Inc
 * For SiFive's PWM IP block documentation please refer Chapter 14 of
 * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf
 *
 * Limitations:
 * - When changing both duty cycle and period, we cannot prevent in
 *   software that the output might produce a period with mixed
 *   settings (new period length and old duty cycle).
 * - The hardware cannot generate a 100% duty cycle.
 * - The hardware generates only inverted output.
 */

#include <common.h>
#include <clk.h>
#include <div64.h>
#include <dm.h>
#include <pwm.h>
#include <regmap.h>
#include <linux/io.h>
#include <linux/log2.h>
#include <linux/bitfield.h>

/* PWMCFG fields */
#define PWM_SIFIVE_PWMCFG_SCALE         GENMASK(3, 0)
#define PWM_SIFIVE_PWMCFG_STICKY        BIT(8)
#define PWM_SIFIVE_PWMCFG_ZERO_CMP      BIT(9)
#define PWM_SIFIVE_PWMCFG_DEGLITCH      BIT(10)
#define PWM_SIFIVE_PWMCFG_EN_ALWAYS     BIT(12)
#define PWM_SIFIVE_PWMCFG_EN_ONCE       BIT(13)
#define PWM_SIFIVE_PWMCFG_CENTER        BIT(16)
#define PWM_SIFIVE_PWMCFG_GANG          BIT(24)
#define PWM_SIFIVE_PWMCFG_IP            BIT(28)

/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */
#define PWM_SIFIVE_SIZE_PWMCMP          4
#define PWM_SIFIVE_CMPWIDTH             16

DECLARE_GLOBAL_DATA_PTR;

struct pwm_sifive_regs {
	unsigned long cfg;
	unsigned long cnt;
	unsigned long pwms;
	unsigned long cmp0;
};

struct pwm_sifive_data {
	struct pwm_sifive_regs regs;
};

struct pwm_sifive_priv {
	void __iomem *base;
	ulong freq;
	const struct pwm_sifive_data *data;
};

static int pwm_sifive_set_config(struct udevice *dev, uint channel,
				 uint period_ns, uint duty_ns)
{
	struct pwm_sifive_priv *priv = dev_get_priv(dev);
	const struct pwm_sifive_regs *regs = &priv->data->regs;
	unsigned long scale_pow;
	unsigned long long num;
	u32 scale, val = 0, frac;

	debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns);

	/*
	 * The PWM unit is used with pwmzerocmp=0, so the only way to modify the
	 * period length is using pwmscale which provides the number of bits the
	 * counter is shifted before being feed to the comparators. A period
	 * lasts (1 << (PWM_SIFIVE_CMPWIDTH + pwmscale)) clock ticks.
	 * (1 << (PWM_SIFIVE_CMPWIDTH + scale)) * 10^9/rate = period
	 */
	scale_pow = lldiv((uint64_t)priv->freq * period_ns, 1000000000);
	scale = clamp(ilog2(scale_pow) - PWM_SIFIVE_CMPWIDTH, 0, 0xf);
	val |= FIELD_PREP(PWM_SIFIVE_PWMCFG_SCALE, scale);

	/*
	 * The problem of output producing mixed setting as mentioned at top,
	 * occurs here. To minimize the window for this problem, we are
	 * calculating the register values first and then writing them
	 * consecutively
	 */
	num = (u64)duty_ns * (1U << PWM_SIFIVE_CMPWIDTH);
	frac = DIV_ROUND_CLOSEST_ULL(num, period_ns);
	frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);

	writel(val, priv->base + regs->cfg);
	writel(frac, priv->base + regs->cmp0 + channel *
	       PWM_SIFIVE_SIZE_PWMCMP);

	return 0;
}

static int pwm_sifive_set_enable(struct udevice *dev, uint channel, bool enable)
{
	struct pwm_sifive_priv *priv = dev_get_priv(dev);
	const struct pwm_sifive_regs *regs = &priv->data->regs;
	u32 val;

	debug("%s: Enable '%s'\n", __func__, dev->name);

	if (enable) {
		val = readl(priv->base + regs->cfg);
		val |= PWM_SIFIVE_PWMCFG_EN_ALWAYS;
		writel(val, priv->base + regs->cfg);
	} else {
		writel(0, priv->base + regs->cmp0 + channel *
		       PWM_SIFIVE_SIZE_PWMCMP);
	}

	return 0;
}

static int pwm_sifive_of_to_plat(struct udevice *dev)
{
	struct pwm_sifive_priv *priv = dev_get_priv(dev);

	priv->base = dev_read_addr_ptr(dev);

	return 0;
}

static int pwm_sifive_probe(struct udevice *dev)
{
	struct pwm_sifive_priv *priv = dev_get_priv(dev);
	struct clk clk;
	int ret = 0;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		debug("%s get clock fail!\n", __func__);
		return -EINVAL;
	}

	priv->freq = clk_get_rate(&clk);
	priv->data = (struct pwm_sifive_data *)dev_get_driver_data(dev);

	return 0;
}

static const struct pwm_ops pwm_sifive_ops = {
	.set_config	= pwm_sifive_set_config,
	.set_enable	= pwm_sifive_set_enable,
};

static const struct pwm_sifive_data pwm_data = {
	.regs = {
		.cfg = 0x00,
		.cnt = 0x08,
		.pwms = 0x10,
		.cmp0 = 0x20,
	},
};

static const struct udevice_id pwm_sifive_ids[] = {
	{ .compatible = "sifive,pwm0", .data = (ulong)&pwm_data},
	{ }
};

U_BOOT_DRIVER(pwm_sifive) = {
	.name	= "pwm_sifive",
	.id	= UCLASS_PWM,
	.of_match = pwm_sifive_ids,
	.ops	= &pwm_sifive_ops,
	.of_to_plat     = pwm_sifive_of_to_plat,
	.probe		= pwm_sifive_probe,
	.priv_auto	= sizeof(struct pwm_sifive_priv),
};
