/*
 * Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT xlnx_xps_timer_1_00_a_pwm

#include <device.h>
#include <drivers/pwm.h>
#include <sys/sys_io.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(xlnx_axi_timer_pwm, CONFIG_PWM_LOG_LEVEL);

/* AXI Timer v2.0 registers offsets (See Xilinx PG079 for details) */
#define TCSR0_OFFSET 0x00
#define TLR0_OFFSET  0x04
#define TCR0_OFFSET  0x08
#define TCSR1_OFFSET 0x10
#define TLR1_OFFSET  0x14
#define TCR1_OFFSET  0x18

/* TCSRx bit definitions */
#define TCSR_MDT   BIT(0)
#define TCSR_UDT   BIT(1)
#define TCSR_GENT  BIT(2)
#define TCSR_CAPT  BIT(3)
#define TCSR_ARHT  BIT(4)
#define TCSR_LOAD  BIT(5)
#define TCSR_ENIT  BIT(6)
#define TCSR_ENT   BIT(7)
#define TCSR_TINT  BIT(8)
#define TCSR_PWMA  BIT(9)
#define TCSR_ENALL BIT(10)
#define TCSR_CASC  BIT(11)

/* Generate PWM mode, count-down, auto-reload */
#define TCSR_PWM (TCSR_UDT | TCSR_GENT | TCSR_ARHT | TCSR_PWMA)

struct xlnx_axi_timer_config {
	mm_reg_t base;
	uint32_t cycles_max;
	uint32_t freq;
};

static inline uint32_t xlnx_axi_timer_read32(const struct device *dev,
					     mm_reg_t offset)
{
	const struct xlnx_axi_timer_config *config = dev->config;

	return sys_read32(config->base + offset);
}

static inline void xlnx_axi_timer_write32(const struct device *dev,
					  uint32_t value,
					  mm_reg_t offset)
{
	const struct xlnx_axi_timer_config *config = dev->config;

	sys_write32(value, config->base + offset);
}

static int xlnx_axi_timer_set_cycles(const struct device *dev, uint32_t channel,
				     uint32_t period_cycles,
				     uint32_t pulse_cycles, pwm_flags_t flags)
{
	const struct xlnx_axi_timer_config *config = dev->config;
	uint32_t tcsr0 = TCSR_PWM;
	uint32_t tcsr1 = TCSR_PWM;
	uint32_t tlr0;
	uint32_t tlr1;

	if (channel != 0) {
		return -ENOTSUP;
	}

	LOG_DBG("period = 0x%08x, pulse = 0x%08x", period_cycles, pulse_cycles);

	if (pulse_cycles == 0) {
		LOG_DBG("setting constant inactive level");

		if (flags & PWM_POLARITY_INVERTED) {
			tcsr0 |= TCSR_ENT;
		} else {
			tcsr1 |= TCSR_ENT;
		}
	} else if (pulse_cycles == period_cycles) {
		LOG_DBG("setting constant active level");

		if (flags & PWM_POLARITY_INVERTED) {
			tcsr1 |= TCSR_ENT;
		} else {
			tcsr0 |= TCSR_ENT;
		}
	} else {
		LOG_DBG("setting normal pwm");

		if (period_cycles < 2) {
			LOG_ERR("period cycles too narrow");
			return -ENOTSUP;
		}

		/* PWM_PERIOD = (TLR0 + 2) * AXI_CLOCK_PERIOD */
		tlr0 = period_cycles - 2;

		if (tlr0 > config->cycles_max) {
			LOG_ERR("tlr0 out of range (0x%08x > 0x%08x)", tlr0,
				config->cycles_max);
			return -ENOTSUP;
		}

		if (flags & PWM_POLARITY_INVERTED) {
			/*
			 * Since this is a single-channel PWM controller (with
			 * no other channels to phase align with) inverse
			 * polarity can be achieved simply by inverting the
			 * pulse.
			 */

			if ((period_cycles - pulse_cycles) < 2) {
				LOG_ERR("pulse cycles too narrow");
				return -ENOTSUP;
			}

			/* PWM_HIGH_TIME = (TLR1 + 2) * AXI_CLOCK_PERIOD */
			tlr1 = period_cycles - pulse_cycles - 2;
		} else {
			if (pulse_cycles < 2) {
				LOG_ERR("pulse cycles too narrow");
				return -ENOTSUP;
			}

			/* PWM_HIGH_TIME = (TLR1 + 2) * AXI_CLOCK_PERIOD */
			tlr1 = pulse_cycles - 2;
		}

		LOG_DBG("tlr0 = 0x%08x, tlr1 = 0x%08x", tlr0, tlr1);

		/* Stop both timers */
		xlnx_axi_timer_write32(dev, TCSR_PWM, TCSR0_OFFSET);
		xlnx_axi_timer_write32(dev, TCSR_PWM, TCSR1_OFFSET);

		/* Load period cycles */
		xlnx_axi_timer_write32(dev, tlr0, TLR0_OFFSET);
		xlnx_axi_timer_write32(dev, TCSR_PWM | TCSR_LOAD, TCSR0_OFFSET);

		/* Load pulse cycles */
		xlnx_axi_timer_write32(dev, tlr1, TLR1_OFFSET);
		xlnx_axi_timer_write32(dev, TCSR_PWM | TCSR_LOAD, TCSR1_OFFSET);

		/* Start both timers */
		tcsr1 |= TCSR_ENALL;
	}

	xlnx_axi_timer_write32(dev, tcsr0, TCSR0_OFFSET);
	xlnx_axi_timer_write32(dev, tcsr1, TCSR1_OFFSET);

	return 0;
}

static int xlnx_axi_timer_get_cycles_per_sec(const struct device *dev,
					     uint32_t channel, uint64_t *cycles)
{
	const struct xlnx_axi_timer_config *config = dev->config;

	ARG_UNUSED(channel);

	*cycles = config->freq;

	return 0;
}

static int xlnx_axi_timer_init(const struct device *dev)
{
	return 0;
}

static const struct pwm_driver_api xlnx_axi_timer_driver_api = {
	.set_cycles = xlnx_axi_timer_set_cycles,
	.get_cycles_per_sec = xlnx_axi_timer_get_cycles_per_sec,
};

#define XLNX_AXI_TIMER_ASSERT_PROP_VAL(n, prop, val, str)	\
	BUILD_ASSERT(DT_INST_PROP(n, prop) == val, str)

#define XLNX_AXI_TIMER_INIT(n)						\
	XLNX_AXI_TIMER_ASSERT_PROP_VAL(n, xlnx_gen0_assert, 1,		\
				   "xlnx,gen0-assert must be 1 for pwm"); \
	XLNX_AXI_TIMER_ASSERT_PROP_VAL(n, xlnx_gen1_assert, 1,		\
				   "xlnx,gen1-assert must be 1 for pwm"); \
	XLNX_AXI_TIMER_ASSERT_PROP_VAL(n, xlnx_one_timer_only, 0,	\
				   "xlnx,one-timer-only must be 0 for pwm"); \
									\
	static struct xlnx_axi_timer_config xlnx_axi_timer_config_##n = { \
		.base = DT_INST_REG_ADDR(n),				\
		.freq = DT_INST_PROP(n, clock_frequency),		\
		.cycles_max =						\
			GENMASK(DT_INST_PROP(n, xlnx_count_width) - 1, 0), \
	};								\
									\
	DEVICE_DT_INST_DEFINE(n, &xlnx_axi_timer_init,			\
			    NULL, NULL,					\
			    &xlnx_axi_timer_config_##n,			\
			    POST_KERNEL,				\
			    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
			    &xlnx_axi_timer_driver_api)

DT_INST_FOREACH_STATUS_OKAY(XLNX_AXI_TIMER_INIT);
