// 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_ofdata_to_platdata(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,
	.ofdata_to_platdata     = pwm_sifive_ofdata_to_platdata,
	.probe		= pwm_sifive_probe,
	.priv_auto_alloc_size	= sizeof(struct pwm_sifive_priv),
};
