/*
 * Copyright (c) 2018 SiFive Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT sifive_pwm0

#include <zephyr/arch/cpu.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/device.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/pwm.h>
#include <soc.h>

LOG_MODULE_REGISTER(pwm_sifive, CONFIG_PWM_LOG_LEVEL);

/* Macros */

#define PWM_REG(z_config, _offset) ((mem_addr_t) ((z_config)->base + _offset))

/* Register Offsets */
#define REG_PWMCFG		0x00
#define REG_PWMCOUNT		0x08
#define REG_PWMS		0x10
#define REG_PWMCMP0		0x20
#define REG_PWMCMP(_channel)	(REG_PWMCMP0 + ((_channel) * 0x4))

/* Number of PWM Channels */
#define SF_NUMCHANNELS		4

/* pwmcfg Bit Offsets */
#define SF_PWMSTICKY			8
#define SF_PWMZEROCMP			9
#define SF_PWMDEGLITCH			10
#define SF_PWMENALWAYS			12
#define SF_PWMENONESHOT			13
#define SF_PWMCMPCENTER(_channel)	(16 + (_channel))
#define SF_PWMCMPGANG(_channel)		(24 + (_channel))
#define SF_PWMCMPIP(_channel)		(28 + (_channel))

/* pwmcount scale factor */
#define SF_PWMSCALEMASK		0xF
#define SF_PWMSCALE(_val)	(SF_PWMSCALEMASK & (_val))

#define SF_PWMCOUNT_MIN_WIDTH	15

/* Structure Declarations */

struct pwm_sifive_data {};

struct pwm_sifive_cfg {
	uint32_t base;
	uint32_t f_sys;
	uint32_t cmpwidth;
	const struct pinctrl_dev_config *pcfg;
};

/* Helper Functions */

static inline void sys_set_mask(mem_addr_t addr, uint32_t mask, uint32_t value)
{
	uint32_t temp = sys_read32(addr);

	temp &= ~(mask);
	temp |= value;

	sys_write32(temp, addr);
}

/* API Functions */

static int pwm_sifive_init(const struct device *dev)
{
	const struct pwm_sifive_cfg *config = dev->config;
#ifdef CONFIG_PINCTRL
	int ret;

	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		return ret;
	}
#endif

	/* When pwms == pwmcmp0, reset the counter */
	sys_set_bit(PWM_REG(config, REG_PWMCFG), SF_PWMZEROCMP);

	/* Enable continuous operation */
	sys_set_bit(PWM_REG(config, REG_PWMCFG), SF_PWMENALWAYS);

	/* Clear IP config bits */
	sys_clear_bit(PWM_REG(config, REG_PWMCFG), SF_PWMSTICKY);
	sys_clear_bit(PWM_REG(config, REG_PWMCFG), SF_PWMDEGLITCH);

	/* Clear all channels */
	for (int i = 0; i < SF_NUMCHANNELS; i++) {
		/* Clear the channel comparator */
		sys_write32(0, PWM_REG(config, REG_PWMCMP(i)));

		/* Clear the compare center and compare gang bits */
		sys_clear_bit(PWM_REG(config, REG_PWMCFG), SF_PWMCMPCENTER(i));
		sys_clear_bit(PWM_REG(config, REG_PWMCFG), SF_PWMCMPGANG(i));
	}

	return 0;
}

static int pwm_sifive_set_cycles(const struct device *dev, uint32_t channel,
				 uint32_t period_cycles, uint32_t pulse_cycles,
				 pwm_flags_t flags)
{
	const struct pwm_sifive_cfg *config = dev->config;
	uint32_t count_max = 0U;
	uint32_t max_cmp_val = 0U;
	uint32_t pwmscale = 0U;

	if (flags) {
		/* PWM polarity not supported (yet?) */
		return -ENOTSUP;
	}

	if (channel >= SF_NUMCHANNELS) {
		LOG_ERR("The requested PWM channel %d is invalid\n", channel);
		return -EINVAL;
	}

	/* Channel 0 sets the period, we can't output PWM with it */
	if (channel == 0U) {
		LOG_ERR("PWM channel 0 cannot be configured\n");
		return -ENOTSUP;
	}

	/* We can't support periods greater than we can store in pwmcount */
	count_max = (1 << (config->cmpwidth + SF_PWMCOUNT_MIN_WIDTH)) - 1;

	if (period_cycles > count_max) {
		LOG_ERR("Requested period is %d but maximum is %d\n",
			period_cycles, count_max);
		return -EIO;
	}

	/* Calculate the maximum value that pwmcmpX can be set to */
	max_cmp_val = ((1 << config->cmpwidth) - 1);

	/*
	 * Find the minimum value of pwmscale that will allow us to set the
	 * requested period
	 */
	while ((period_cycles >> pwmscale) > max_cmp_val) {
		pwmscale++;
	}

	/* Make sure that we can scale that much */
	if (pwmscale > SF_PWMSCALEMASK) {
		LOG_ERR("Requested period is %d but maximum is %d\n",
			period_cycles, max_cmp_val << pwmscale);
		return -EIO;
	}

	/* Set the pwmscale field */
	sys_set_mask(PWM_REG(config, REG_PWMCFG),
		     SF_PWMSCALEMASK,
		     SF_PWMSCALE(pwmscale));

	/* Set the period by setting pwmcmp0 */
	sys_write32((period_cycles >> pwmscale), PWM_REG(config, REG_PWMCMP0));

	/* Set the duty cycle by setting pwmcmpX */
	sys_write32((pulse_cycles >> pwmscale),
		    PWM_REG(config, REG_PWMCMP(channel)));

	LOG_DBG("channel: %d, pwmscale: %d, pwmcmp0: %d, pwmcmp%d: %d",
		channel,
		pwmscale,
		(period_cycles >> pwmscale),
		channel,
		(pulse_cycles >> pwmscale));

	return 0;
}

static int pwm_sifive_get_cycles_per_sec(const struct device *dev,
					 uint32_t channel, uint64_t *cycles)
{
	const struct pwm_sifive_cfg *config;

	if (dev == NULL) {
		LOG_ERR("The device instance pointer was NULL\n");
		return -EFAULT;
	}

	config = dev->config;
	if (config == NULL) {
		LOG_ERR("The device configuration is NULL\n");
		return -EFAULT;
	}

	/* Fail if we don't have that channel */
	if (channel >= SF_NUMCHANNELS) {
		return -EINVAL;
	}

	*cycles = config->f_sys;

	return 0;
}

/* Device Instantiation */

static const struct pwm_driver_api pwm_sifive_api = {
	.set_cycles = pwm_sifive_set_cycles,
	.get_cycles_per_sec = pwm_sifive_get_cycles_per_sec,
};

#define PWM_SIFIVE_INIT(n)	\
	PINCTRL_DT_INST_DEFINE(n);	\
	static struct pwm_sifive_data pwm_sifive_data_##n;	\
	static const struct pwm_sifive_cfg pwm_sifive_cfg_##n = {	\
			.base = DT_INST_REG_ADDR(n),	\
			.f_sys = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY,  \
			.cmpwidth = DT_INST_PROP(n, sifive_compare_width), \
			.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),	\
		};	\
	DEVICE_DT_INST_DEFINE(n,	\
			    pwm_sifive_init,	\
			    NULL,	\
			    &pwm_sifive_data_##n,	\
			    &pwm_sifive_cfg_##n,	\
			    POST_KERNEL,	\
			    CONFIG_PWM_INIT_PRIORITY,	\
			    &pwm_sifive_api);

DT_INST_FOREACH_STATUS_OKAY(PWM_SIFIVE_INIT)
