/*
 * Copyright (c) 2018, Cue Health Inc
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <nrfx_pwm.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/pm/device.h>
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>
#include <hal/nrf_gpio.h>
#include <stdbool.h>
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/cache.h>
#include <zephyr/mem_mgmt/mem_attr.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);

/* NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED can be undefined or defined
 * to 0 or 1, hence the use of #if IS_ENABLED().
 */
#if IS_ENABLED(NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
#define ANOMALY_109_EGU_IRQ_CONNECT(idx) _EGU_IRQ_CONNECT(idx)
#define _EGU_IRQ_CONNECT(idx) \
	extern void nrfx_egu_##idx##_irq_handler(void); \
	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(egu##idx)), \
		    DT_IRQ(DT_NODELABEL(egu##idx), priority), \
		    nrfx_isr, nrfx_egu_##idx##_irq_handler, 0)
#else
#define ANOMALY_109_EGU_IRQ_CONNECT(idx)
#endif

#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx)
#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop)
#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop)
#define PWM_NRFX_IS_FAST(idx) NRF_DT_IS_FAST(PWM(idx))

#if NRF_DT_INST_ANY_IS_FAST
#define PWM_NRFX_FAST_PRESENT 1
/* If fast instances are used then system managed device PM cannot be used because
 * it may call PM actions from locked context and fast PWM PM actions can only be
 * called in a thread context.
 */
BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED));
#endif

#if defined(PWM_NRFX_FAST_PRESENT) && CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL
#define PWM_NRFX_USE_CLOCK_CONTROL 1
#endif

#define PWM_NRFX_CH_POLARITY_MASK BIT(15)
#define PWM_NRFX_CH_COMPARE_MASK  BIT_MASK(15)
#define PWM_NRFX_CH_VALUE(compare_value, inverted) \
	(compare_value | (inverted ? 0 : PWM_NRFX_CH_POLARITY_MASK))

struct pwm_nrfx_config {
	nrfx_pwm_t pwm;
	nrfx_pwm_config_t initial_config;
	nrf_pwm_sequence_t seq;
	const struct pinctrl_dev_config *pcfg;
	uint32_t clock_freq;
#ifdef CONFIG_DCACHE
	uint32_t mem_attr;
#endif
#ifdef PWM_NRFX_USE_CLOCK_CONTROL
	const struct device *clk_dev;
	struct nrf_clock_spec clk_spec;
#endif
};

struct pwm_nrfx_data {
	uint32_t period_cycles;
	/* Bit mask indicating channels that need the PWM generation. */
	uint8_t  pwm_needed;
	uint8_t  prescaler;
	bool     stop_requested;
#ifdef PWM_NRFX_USE_CLOCK_CONTROL
	bool     clock_requested;
#endif
};
/* Ensure the pwm_needed bit mask can accommodate all available channels. */
#if (NRF_PWM_CHANNEL_COUNT > 8)
#error "Current implementation supports maximum 8 channels."
#endif

#ifdef PWM_NRFX_FAST_PRESENT
static bool pwm_is_fast(const struct pwm_nrfx_config *config)
{
	return config->clock_freq > MHZ(16);
}
#else
static bool pwm_is_fast(const struct pwm_nrfx_config *config)
{
	return false;
}
#endif

static uint16_t *seq_values_ptr_get(const struct device *dev)
{
	const struct pwm_nrfx_config *config = dev->config;

	return (uint16_t *)config->seq.values.p_raw;
}

static void pwm_handler(nrfx_pwm_evt_type_t event_type, void *p_context)
{
	ARG_UNUSED(event_type);
	ARG_UNUSED(p_context);
}

static bool pwm_period_check_and_set(const struct device *dev,
				     uint32_t channel, uint32_t period_cycles)
{
	const struct pwm_nrfx_config *config = dev->config;
	struct pwm_nrfx_data *data = dev->data;
	uint8_t prescaler;
	uint32_t countertop;

	/* If the currently configured period matches the requested one,
	 * nothing more needs to be done.
	 */
	if (period_cycles == data->period_cycles) {
		return true;
	}

	/* If any other channel is driven by the PWM peripheral, the period
	 * that is currently set cannot be changed, as this would influence
	 * the output for that channel.
	 */
	if ((data->pwm_needed & ~BIT(channel)) != 0) {
		LOG_ERR("Incompatible period.");
		return false;
	}

	/* Try to find a prescaler that will allow setting the requested period
	 * after prescaling as the countertop value for the PWM peripheral.
	 */
	prescaler = 0;
	countertop = period_cycles;
	do {
		if (countertop <= PWM_COUNTERTOP_COUNTERTOP_Msk) {
			data->period_cycles = period_cycles;
			data->prescaler     = prescaler;

			nrf_pwm_configure(config->pwm.p_reg,
					  data->prescaler,
					  config->initial_config.count_mode,
					  (uint16_t)countertop);
			return true;
		}

		countertop >>= 1;
		++prescaler;
	} while (prescaler <= PWM_PRESCALER_PRESCALER_Msk);

	LOG_ERR("Prescaler for period_cycles %u not found.", period_cycles);
	return false;
}

static bool channel_psel_get(uint32_t channel, uint32_t *psel,
			     const struct pwm_nrfx_config *config)
{
	*psel = nrf_pwm_pin_get(config->pwm.p_reg, (uint8_t)channel);

	return (((*psel & PWM_PSEL_OUT_CONNECT_Msk) >> PWM_PSEL_OUT_CONNECT_Pos)
		== PWM_PSEL_OUT_CONNECT_Connected);
}

static int stop_pwm(const struct device *dev)
{
	const struct pwm_nrfx_config *config = dev->config;

	/* Don't wait here for the peripheral to actually stop. Instead,
	 * ensure it is stopped before starting the next playback.
	 */
	nrfx_pwm_stop(&config->pwm, false);

#if PWM_NRFX_USE_CLOCK_CONTROL
	struct pwm_nrfx_data *data = dev->data;

	if (data->clock_requested) {
		int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec);

		if (ret < 0) {
			LOG_ERR("Global HSFLL release failed: %d", ret);
			return ret;
		}

		data->clock_requested = false;
	}
#endif

	return 0;
}

static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
			       uint32_t period_cycles, uint32_t pulse_cycles,
			       pwm_flags_t flags)
{
	/* We assume here that period_cycles will always be 16MHz
	 * peripheral clock. Since pwm_nrfx_get_cycles_per_sec() function might
	 * be removed, see ISSUE #6958.
	 * TODO: Remove this comment when issue has been resolved.
	 */
	const struct pwm_nrfx_config *config = dev->config;
	struct pwm_nrfx_data *data = dev->data;
	uint16_t compare_value;
	bool inverted = (flags & PWM_POLARITY_INVERTED);
	bool needs_pwm = false;

	if (channel >= NRF_PWM_CHANNEL_COUNT) {
		LOG_ERR("Invalid channel: %u.", channel);
		return -EINVAL;
	}

	/* If this PWM is in center-aligned mode, pulse and period lengths
	 * are effectively doubled by the up-down count, so halve them here
	 * to compensate.
	 */
	if (config->initial_config.count_mode == NRF_PWM_MODE_UP_AND_DOWN) {
		period_cycles /= 2;
		pulse_cycles /= 2;
	}

	if (pulse_cycles == 0) {
		/* Constantly inactive (duty 0%). */
		compare_value = 0;
	} else if (pulse_cycles >= period_cycles) {
		/* Constantly active (duty 100%). */
		/* This value is always greater than or equal to COUNTERTOP. */
		compare_value = PWM_NRFX_CH_COMPARE_MASK;
		needs_pwm = pwm_is_fast(config) ||
			(IS_ENABLED(NRF_PWM_HAS_IDLEOUT) &&
			 IS_ENABLED(CONFIG_PWM_NRFX_NO_GLITCH_DUTY_100));
	} else {
		/* PWM generation needed. Check if the requested period matches
		 * the one that is currently set, or the PWM peripheral can be
		 * reconfigured accordingly.
		 */
		if (!pwm_period_check_and_set(dev, channel, period_cycles)) {
			return -EINVAL;
		}

		compare_value = (uint16_t)(pulse_cycles >> data->prescaler);
		needs_pwm = true;
	}

	seq_values_ptr_get(dev)[channel] = PWM_NRFX_CH_VALUE(compare_value, inverted);

#ifdef CONFIG_DCACHE
	if (config->mem_attr & DT_MEM_CACHEABLE) {
		sys_cache_data_flush_range(seq_values_ptr_get(dev), config->seq.length);
	}
#endif

	LOG_DBG("channel %u, pulse %u, period %u, prescaler: %u.",
		channel, pulse_cycles, period_cycles, data->prescaler);

	/* If this channel does not need to be driven by the PWM peripheral
	 * because its state is to be constant (duty 0% or 100%), set properly
	 * the GPIO configuration for its output pin. This will provide
	 * the correct output state for this channel when the PWM peripheral
	 * is stopped.
	 */
	if (!needs_pwm) {
		uint32_t psel;

		if (channel_psel_get(channel, &psel, config)) {
			uint32_t out_level = (pulse_cycles == 0) ? 0 : 1;

			if (inverted) {
				out_level ^= 1;
			}

			nrf_gpio_pin_write(psel, out_level);
		}

		data->pwm_needed &= ~BIT(channel);
	} else {
		data->pwm_needed |= BIT(channel);
	}

	/* If the PWM generation is not needed for any channel (all are set
	 * to constant inactive or active state), stop the PWM peripheral.
	 * Otherwise, request a playback of the defined sequence so that
	 * the PWM peripheral loads `seq_values` into its internal compare
	 * registers and drives its outputs accordingly.
	 */
	if (data->pwm_needed == 0) {
		if (pwm_is_fast(config)) {
#if PWM_NRFX_USE_CLOCK_CONTROL
			if (data->clock_requested) {
				int ret = nrf_clock_control_release(config->clk_dev,
							    &config->clk_spec);

				if (ret < 0) {
					LOG_ERR("Global HSFLL release failed: %d", ret);
					return ret;
				}

				data->clock_requested = false;
			}
#endif
			return 0;
		}
		int ret = stop_pwm(dev);

		if (ret < 0) {
			LOG_ERR("PWM stop failed: %d", ret);
			return ret;
		}

		data->stop_requested = true;
	} else {
		if (data->stop_requested) {
			data->stop_requested = false;

			/* After a stop is requested, the PWM peripheral stops
			 * pulse generation at the end of the current period,
			 * and till that moment, it ignores any start requests,
			 * so ensure here that it is stopped.
			 */
			while (!nrfx_pwm_stopped_check(&config->pwm)) {
			}
		}

		/* It is sufficient to play the sequence once without looping.
		 * The PWM generation will continue with the loaded values
		 * until another playback is requested (new values will be
		 * loaded then) or the PWM peripheral is stopped.
		 */
#if PWM_NRFX_USE_CLOCK_CONTROL
		if (config->clk_dev && !data->clock_requested) {
			int ret = nrf_clock_control_request_sync(config->clk_dev,
								 &config->clk_spec,
								 K_FOREVER);

			if (ret < 0) {
				LOG_ERR("Global HSFLL request failed: %d", ret);
				return ret;
			}

			data->clock_requested = true;
		}
#endif
		nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1,
					 NRFX_PWM_FLAG_NO_EVT_FINISHED);
	}

	return 0;
}

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

	*cycles = config->clock_freq;

	return 0;
}

static DEVICE_API(pwm, pwm_nrfx_drv_api_funcs) = {
	.set_cycles = pwm_nrfx_set_cycles,
	.get_cycles_per_sec = pwm_nrfx_get_cycles_per_sec,
};

static int pwm_resume(const struct device *dev)
{
	const struct pwm_nrfx_config *config = dev->config;
	uint8_t initially_inverted = 0;

	(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

	for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
		uint32_t psel;

		if (channel_psel_get(i, &psel, config)) {
			/* Mark channels as inverted according to what initial
			 * state of their outputs has been set by pinctrl (high
			 * idle state means that the channel is inverted).
			 */
			initially_inverted |= nrf_gpio_pin_out_read(psel) ?
					      BIT(i) : 0;
		}
	}

	for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
		bool inverted = initially_inverted & BIT(i);

		seq_values_ptr_get(dev)[i] = PWM_NRFX_CH_VALUE(0, inverted);
	}

	return 0;
}

static int pwm_suspend(const struct device *dev)
{
	const struct pwm_nrfx_config *config = dev->config;

	int ret = stop_pwm(dev);

	if (ret < 0) {
		LOG_ERR("PWM stop failed: %d", ret);
		return ret;
	}

	while (!nrfx_pwm_stopped_check(&config->pwm)) {
	}

	memset(dev->data, 0, sizeof(struct pwm_nrfx_data));
	(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);

	return 0;
}

static int pwm_nrfx_pm_action(const struct device *dev,
			      enum pm_device_action action)
{
	if (action == PM_DEVICE_ACTION_RESUME) {
		return pwm_resume(dev);
	} else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) {
		return pwm_suspend(dev);
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static int pwm_nrfx_init(const struct device *dev)
{
	const struct pwm_nrfx_config *config = dev->config;
	nrfx_err_t err;

	ANOMALY_109_EGU_IRQ_CONNECT(NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
	}

	err = nrfx_pwm_init(&config->pwm, &config->initial_config, pwm_handler, dev->data);
	if (err != NRFX_SUCCESS) {
		LOG_ERR("Failed to initialize device: %s", dev->name);
		return -EBUSY;
	}

	return pm_device_driver_init(dev, pwm_nrfx_pm_action);
}

#define PWM_MEM_REGION(idx)     DT_PHANDLE(PWM(idx), memory_regions)

#define PWM_MEMORY_SECTION(idx)						      \
	COND_CODE_1(PWM_HAS_PROP(idx, memory_regions),			      \
		(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME(	      \
			PWM_MEM_REGION(idx)))))),			      \
		())

#define PWM_GET_MEM_ATTR(idx)						      \
	COND_CODE_1(PWM_HAS_PROP(idx, memory_regions),			      \
		(DT_PROP_OR(PWM_MEM_REGION(idx), zephyr_memory_attr, 0)), (0))

/* Fast instances depend on the global HSFLL clock controller (as they need
 * to request the highest frequency from it to operate correctly), so they
 * must be initialized after that controller driver, hence the default PWM
 * initialization priority may be too early for them.
 */
#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY) && \
	CONFIG_PWM_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY
#define PWM_INIT_PRIORITY(idx)								\
	COND_CODE_1(PWM_NRFX_IS_FAST(idx),						\
		    (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)),	\
		    (CONFIG_PWM_INIT_PRIORITY))
#else
#define PWM_INIT_PRIORITY(idx) CONFIG_PWM_INIT_PRIORITY
#endif

#define PWM_NRFX_DEVICE(idx)						      \
	NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx));			      \
	NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(PWM(idx));	      \
	static struct pwm_nrfx_data pwm_nrfx_##idx##_data;		      \
	static uint16_t pwm_##idx##_seq_values[NRF_PWM_CHANNEL_COUNT]	      \
			PWM_MEMORY_SECTION(idx);			      \
	PINCTRL_DT_DEFINE(PWM(idx));					      \
	static const struct pwm_nrfx_config pwm_nrfx_##idx##_config = {	      \
		.pwm = NRFX_PWM_INSTANCE(idx),				      \
		.initial_config = {					      \
			.skip_gpio_cfg = true,				      \
			.skip_psel_cfg = true,				      \
			.base_clock = NRF_PWM_CLK_1MHz,			      \
			.count_mode = (PWM_PROP(idx, center_aligned)	      \
				       ? NRF_PWM_MODE_UP_AND_DOWN	      \
				       : NRF_PWM_MODE_UP),		      \
			.top_value = 1000,				      \
			.load_mode = NRF_PWM_LOAD_INDIVIDUAL,		      \
			.step_mode = NRF_PWM_STEP_TRIGGERED,		      \
		},							      \
		.seq.values.p_raw = pwm_##idx##_seq_values,		      \
		.seq.length = NRF_PWM_CHANNEL_COUNT,			      \
		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)),		      \
		.clock_freq = COND_CODE_1(DT_CLOCKS_HAS_IDX(PWM(idx), 0),     \
			(DT_PROP(DT_CLOCKS_CTLR(PWM(idx)), clock_frequency)), \
			(16ul * 1000ul * 1000ul)),			      \
		IF_ENABLED(CONFIG_DCACHE,				      \
			(.mem_attr = PWM_GET_MEM_ATTR(idx),))		      \
		IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL,			      \
			(.clk_dev = PWM_NRFX_IS_FAST(idx)		      \
				    ? DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))) \
				    : NULL,				      \
			 .clk_spec = {					      \
				.frequency =				      \
					NRF_PERIPH_GET_FREQUENCY(PWM(idx)),   \
			 },))						      \
	};								      \
	static int pwm_nrfx_init##idx(const struct device *dev)		      \
	{								      \
		IRQ_CONNECT(DT_IRQN(PWM(idx)), DT_IRQ(PWM(idx), priority),    \
			    nrfx_isr, nrfx_pwm_##idx##_irq_handler, 0);	      \
		return pwm_nrfx_init(dev);				      \
	};								      \
	PM_DEVICE_DT_DEFINE(PWM(idx), pwm_nrfx_pm_action);		      \
	DEVICE_DT_DEFINE(PWM(idx),					      \
			 pwm_nrfx_init##idx, PM_DEVICE_DT_GET(PWM(idx)),      \
			 &pwm_nrfx_##idx##_data,			      \
			 &pwm_nrfx_##idx##_config,			      \
			 POST_KERNEL, PWM_INIT_PRIORITY(idx),		      \
			 &pwm_nrfx_drv_api_funcs)

#define COND_PWM_NRFX_DEVICE(unused, prefix, i, _) \
	IF_ENABLED(CONFIG_HAS_HW_NRF_PWM##prefix##i, (PWM_NRFX_DEVICE(prefix##i);))

NRFX_FOREACH_PRESENT(PWM, COND_PWM_NRFX_DEVICE, (), (), _)
