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

#include <logging/log.h>

LOG_MODULE_REGISTER(pwm_sifive, CONFIG_PWM_LOG_LEVEL);

#include <sys_io.h>
#include <device.h>
#include <pwm.h>

/* 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 {
	u32_t base;
	u32_t f_sys;
	u32_t cmpwidth;
};

/* Helper Functions */

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

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

	sys_write32(temp, addr);
}

/* API Functions */

static int pwm_sifive_init(struct device *dev)
{
	const struct pwm_sifive_cfg *config = dev->config->config_info;

	/* 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_pin_set(struct device *dev,
			      u32_t pwm,
			      u32_t period_cycles,
			      u32_t pulse_cycles)
{
	const struct pwm_sifive_cfg *config = NULL;
	u32_t count_max = 0U;
	u32_t max_cmp_val = 0U;
	u32_t pwmscale = 0U;

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

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

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

	/* Channel 0 sets the period, we can't output PWM with it */
	if ((pwm == 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;
	}

	if (pulse_cycles > period_cycles) {
		LOG_ERR("Requested pulse %d is longer than period %d\n",
			pulse_cycles, period_cycles);
		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(pwm)));

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

	return 0;
}

static int pwm_sifive_get_cycles_per_sec(struct device *dev,
					 u32_t pwm,
					 u64_t *cycles)
{
	const struct pwm_sifive_cfg *config;

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

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

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

	*cycles = config->f_sys;

	return 0;
}

/* Device Instantiation */

static const struct pwm_driver_api pwm_sifive_api = {
	.pin_set = pwm_sifive_pin_set,
	.get_cycles_per_sec = pwm_sifive_get_cycles_per_sec,
};

#define PWM_SIFIVE_INIT(n)	\
	static struct pwm_sifive_data pwm_sifive_data_##n;	\
	static const struct pwm_sifive_cfg pwm_sifive_cfg_##n = {	\
			.base = DT_SIFIVE_PWM0_##n##_BASE_ADDRESS,	\
			.f_sys = DT_SIFIVE_PWM0_##n##_CLOCK_FREQUENCY,  \
			.cmpwidth = DT_SIFIVE_PWM0_##n##_SIFIVE_COMPARE_WIDTH, \
		};	\
	DEVICE_AND_API_INIT(pwm_##n,	\
			    DT_SIFIVE_PWM0_##n##_LABEL,	\
			    pwm_sifive_init,	\
			    &pwm_sifive_data_##n,	\
			    &pwm_sifive_cfg_##n,	\
			    POST_KERNEL,	\
			    CONFIG_PWM_SIFIVE_INIT_PRIORITY,	\
			    &pwm_sifive_api)

#ifdef DT_SIFIVE_PWM0_0_LABEL
PWM_SIFIVE_INIT(0);
#endif /* DT_SIFIVE_PWM0_0_LABEL */

#ifdef DT_SIFIVE_PWM0_1_LABEL
PWM_SIFIVE_INIT(1);
#endif /* DT_SIFIVE_PWM0_1_LABEL */

#ifdef DT_SIFIVE_PWM0_2_LABEL
PWM_SIFIVE_INIT(2);
#endif /* DT_SIFIVE_PWM0_2_LABEL */

