// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2025, STMicroelectronics - All Rights Reserved
 * Author: Cheick Traore <cheick.traore@foss.st.com>
 *
 * Originally based on the Linux kernel v6.10 drivers/pwm/pwm-stm32.c.
 */

#include <div64.h>
#include <dm.h>
#include <pwm.h>
#include <asm/io.h>
#include <asm/arch/timers.h>
#include <dm/device_compat.h>
#include <linux/time.h>

#define CCMR_CHANNEL_SHIFT	8
#define CCMR_CHANNEL_MASK	0xFF

struct stm32_pwm_priv {
	bool have_complementary_output;
	bool invert_polarity;
};

static u32 active_channels(struct stm32_timers_plat *plat)
{
	return readl(plat->base + TIM_CCER) & TIM_CCER_CCXE;
}

static int stm32_pwm_set_config(struct udevice *dev, uint channel,
				uint period_ns, uint duty_ns)
{
	struct stm32_timers_plat *plat = dev_get_plat(dev_get_parent(dev));
	struct stm32_timers_priv *priv = dev_get_priv(dev_get_parent(dev));
	unsigned long long prd, div, dty;
	unsigned int prescaler = 0;
	u32 ccmr, mask, shift;

	if (duty_ns > period_ns)
		return -EINVAL;

	/*
	 * Period and prescaler values depends on clock rate
	 * First we need to find the minimal value for prescaler such that
	 *
	 *        period_ns * clkrate
	 *   ------------------------------ < max_arr + 1
	 *   NSEC_PER_SEC * (prescaler + 1)
	 *
	 * This equation is equivalent to
	 *
	 *        period_ns * clkrate
	 *   ---------------------------- < prescaler + 1
	 *   NSEC_PER_SEC * (max_arr + 1)
	 *
	 * Using integer division and knowing that the right hand side is
	 * integer, this is further equivalent to
	 *
	 *   (period_ns * clkrate) // (NSEC_PER_SEC * (max_arr + 1)) ≤ prescaler
	 */

	div = (unsigned long long)priv->rate * period_ns;
	do_div(div, NSEC_PER_SEC);
	prd = div;

	do_div(div, priv->max_arr + 1);
	prescaler = div;
	if (prescaler > MAX_TIM_PSC)
		return -EINVAL;

	do_div(prd, prescaler + 1);
	if (!prd)
		return -EINVAL;

	/*
	 * All channels share the same prescaler and counter so when two
	 * channels are active at the same time we can't change them
	 */
	if (active_channels(plat) & ~(1 << channel * 4)) {
		u32 psc, arr;

		psc = readl(plat->base + TIM_PSC);
		arr = readl(plat->base + TIM_ARR);
		if (psc != prescaler || arr != prd - 1)
			return -EBUSY;
	}

	writel(prescaler, plat->base + TIM_PSC);
	writel(prd - 1, plat->base + TIM_ARR);
	setbits_le32(plat->base + TIM_CR1, TIM_CR1_ARPE);

	/* Calculate the duty cycles */
	dty = prd * duty_ns;
	do_div(dty, period_ns);

	writel(dty, plat->base + TIM_CCRx(channel + 1));

	/* Configure output mode */
	shift = (channel & 0x1) * CCMR_CHANNEL_SHIFT;
	ccmr = (TIM_CCMR_PE | TIM_CCMR_M1) << shift;
	mask = CCMR_CHANNEL_MASK << shift;
	if (channel < 2)
		clrsetbits_le32(plat->base + TIM_CCMR1, mask, ccmr);
	else
		clrsetbits_le32(plat->base + TIM_CCMR2, mask, ccmr);

	setbits_le32(plat->base + TIM_BDTR, TIM_BDTR_MOE);

	return 0;
}

static int stm32_pwm_set_enable(struct udevice *dev, uint channel,
				bool enable)
{
	struct stm32_timers_plat *plat = dev_get_plat(dev_get_parent(dev));
	struct stm32_pwm_priv *priv = dev_get_priv(dev);
	u32 mask;

	/* Enable channel */
	mask = TIM_CCER_CC1E << (channel * 4);
	if (priv->have_complementary_output)
		mask |= TIM_CCER_CC1NE << (channel * 4);

	if (enable) {
		setbits_le32(plat->base + TIM_CCER, mask);
		/* Make sure that registers are updated */
		setbits_le32(plat->base + TIM_EGR, TIM_EGR_UG);
		/* Enable controller */
		setbits_le32(plat->base + TIM_CR1, TIM_CR1_CEN);
	} else {
		clrbits_le32(plat->base + TIM_CCER, mask);
		/* When all channels are disabled, we can disable the controller */
		if (!active_channels(plat))
			clrbits_le32(plat->base + TIM_CR1, TIM_CR1_CEN);
	}

	return 0;
}

static int stm32_pwm_set_invert(struct udevice *dev, uint channel,
				bool polarity)
{
	struct stm32_timers_plat *plat = dev_get_plat(dev_get_parent(dev));
	struct stm32_pwm_priv *priv = dev_get_priv(dev);
	u32 mask;

	mask = TIM_CCER_CC1P << (channel * 4);
	if (priv->have_complementary_output)
		mask |= TIM_CCER_CC1NP << (channel * 4);

	clrsetbits_le32(plat->base + TIM_CCER, mask, polarity ? mask : 0);

	return 0;
}

static void stm32_pwm_detect_complementary(struct udevice *dev)
{
	struct stm32_timers_plat *plat = dev_get_plat(dev_get_parent(dev));
	struct stm32_pwm_priv *priv = dev_get_priv(dev);
	u32 ccer;

	/*
	 * If complementary bit doesn't exist writing 1 will have no
	 * effect so we can detect it.
	 */
	setbits_le32(plat->base + TIM_CCER, TIM_CCER_CC1NE);
	ccer = readl(plat->base + TIM_CCER);
	clrbits_le32(plat->base + TIM_CCER, TIM_CCER_CC1NE);

	priv->have_complementary_output = (ccer != 0);
}

static int stm32_pwm_probe(struct udevice *dev)
{
	struct stm32_timers_priv *timer = dev_get_priv(dev_get_parent(dev));

	if (timer->rate > 1000000000) {
		dev_err(dev, "Clock freq too high (%lu)\n", timer->rate);
		return -EINVAL;
	}

	stm32_pwm_detect_complementary(dev);

	return 0;
}

static const struct pwm_ops stm32_pwm_ops = {
	.set_config	= stm32_pwm_set_config,
	.set_enable	= stm32_pwm_set_enable,
	.set_invert	= stm32_pwm_set_invert,
};

static const struct udevice_id stm32_pwm_ids[] = {
	{ .compatible = "st,stm32-pwm" },
	{ }
};

U_BOOT_DRIVER(stm32_pwm) = {
	.name		= "stm32_pwm",
	.id		= UCLASS_PWM,
	.of_match	= stm32_pwm_ids,
	.ops		= &stm32_pwm_ops,
	.probe          = stm32_pwm_probe,
	.priv_auto	= sizeof(struct stm32_pwm_priv),
};
