// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2017-2018 Vasily Khoruzhick <anarsoul@gmail.com>
 */

#include <common.h>
#include <div64.h>
#include <dm.h>
#include <log.h>
#include <pwm.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/pwm.h>
#include <asm/arch/gpio.h>
#include <power/regulator.h>

DECLARE_GLOBAL_DATA_PTR;

#define OSC_24MHZ 24000000

struct sunxi_pwm_priv {
	struct sunxi_pwm *regs;
	bool invert;
	u32 prescaler;
};

static const u32 prescaler_table[] = {
	120,	/* 0000 */
	180,	/* 0001 */
	240,	/* 0010 */
	360,	/* 0011 */
	480,	/* 0100 */
	0,	/* 0101 */
	0,	/* 0110 */
	0,	/* 0111 */
	12000,	/* 1000 */
	24000,	/* 1001 */
	36000,	/* 1010 */
	48000,	/* 1011 */
	72000,	/* 1100 */
	0,	/* 1101 */
	0,	/* 1110 */
	1,	/* 1111 */
};

static int sunxi_pwm_config_pinmux(void)
{
#ifdef CONFIG_MACH_SUN50I
	sunxi_gpio_set_cfgpin(SUNXI_GPD(22), SUNXI_GPD_PWM);
#endif
	return 0;
}

static int sunxi_pwm_set_invert(struct udevice *dev, uint channel,
				bool polarity)
{
	struct sunxi_pwm_priv *priv = dev_get_priv(dev);

	debug("%s: polarity=%u\n", __func__, polarity);
	priv->invert = polarity;

	return 0;
}

static int sunxi_pwm_set_config(struct udevice *dev, uint channel,
				uint period_ns, uint duty_ns)
{
	struct sunxi_pwm_priv *priv = dev_get_priv(dev);
	struct sunxi_pwm *regs = priv->regs;
	int best_prescaler = 0;
	u32 v, best_period = 0, duty;
	u64 best_scaled_freq = 0;
	const u32 nsecs_per_sec = 1000000000U;

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

	for (int prescaler = 0; prescaler <= SUNXI_PWM_CTRL_PRESCALE0_MASK;
	     prescaler++) {
		u32 period = 0;
		u64 scaled_freq = 0;
		if (!prescaler_table[prescaler])
			continue;
		scaled_freq = lldiv(OSC_24MHZ, prescaler_table[prescaler]);
		period = lldiv(scaled_freq * period_ns, nsecs_per_sec);
		if ((period - 1 <= SUNXI_PWM_CH0_PERIOD_MAX) &&
		    best_period < period) {
			best_period = period;
			best_scaled_freq = scaled_freq;
			best_prescaler = prescaler;
		}
	}

	if (best_period - 1 > SUNXI_PWM_CH0_PERIOD_MAX) {
		debug("%s: failed to find prescaler value\n", __func__);
		return -EINVAL;
	}

	duty = lldiv(best_scaled_freq * duty_ns, nsecs_per_sec);

	if (priv->prescaler != best_prescaler) {
		/* Mask clock to update prescaler */
		v = readl(&regs->ctrl);
		v &= ~SUNXI_PWM_CTRL_CLK_GATE;
		writel(v, &regs->ctrl);
		v &= ~SUNXI_PWM_CTRL_PRESCALE0_MASK;
		v |= (best_prescaler & SUNXI_PWM_CTRL_PRESCALE0_MASK);
		writel(v, &regs->ctrl);
		v |= SUNXI_PWM_CTRL_CLK_GATE;
		writel(v, &regs->ctrl);
		priv->prescaler = best_prescaler;
	}

	writel(SUNXI_PWM_CH0_PERIOD_PRD(best_period) |
	       SUNXI_PWM_CH0_PERIOD_DUTY(duty), &regs->ch0_period);

	debug("%s: prescaler: %d, period: %d, duty: %d\n",
	      __func__, priv->prescaler,
	      best_period, duty);

	return 0;
}

static int sunxi_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
{
	struct sunxi_pwm_priv *priv = dev_get_priv(dev);
	struct sunxi_pwm *regs = priv->regs;
	u32 v;

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

	v = readl(&regs->ctrl);
	if (!enable) {
		v &= ~SUNXI_PWM_CTRL_ENABLE0;
		writel(v, &regs->ctrl);
		return 0;
	}

	sunxi_pwm_config_pinmux();

	if (priv->invert)
		v &= ~SUNXI_PWM_CTRL_CH0_ACT_STA;
	else
		v |= SUNXI_PWM_CTRL_CH0_ACT_STA;
	v |= SUNXI_PWM_CTRL_ENABLE0;
	writel(v, &regs->ctrl);

	return 0;
}

static int sunxi_pwm_ofdata_to_platdata(struct udevice *dev)
{
	struct sunxi_pwm_priv *priv = dev_get_priv(dev);

	priv->regs = dev_read_addr_ptr(dev);

	return 0;
}

static int sunxi_pwm_probe(struct udevice *dev)
{
	return 0;
}

static const struct pwm_ops sunxi_pwm_ops = {
	.set_invert	= sunxi_pwm_set_invert,
	.set_config	= sunxi_pwm_set_config,
	.set_enable	= sunxi_pwm_set_enable,
};

static const struct udevice_id sunxi_pwm_ids[] = {
	{ .compatible = "allwinner,sun5i-a13-pwm" },
	{ .compatible = "allwinner,sun50i-a64-pwm" },
	{ }
};

U_BOOT_DRIVER(sunxi_pwm) = {
	.name	= "sunxi_pwm",
	.id	= UCLASS_PWM,
	.of_match = sunxi_pwm_ids,
	.ops	= &sunxi_pwm_ops,
	.ofdata_to_platdata	= sunxi_pwm_ofdata_to_platdata,
	.probe		= sunxi_pwm_probe,
	.priv_auto_alloc_size	= sizeof(struct sunxi_pwm_priv),
};
