/*
 * Copyright (c) 2024 GARDENA GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT silabs_si32_dma

#include <SI32_CLKCTRL_A_Type.h>
#include <SI32_DMACTRL_A_Type.h>
#include <SI32_DMADESC_A_Type.h>
#include <SI32_SCONFIG_A_Type.h>
#include <si32_device.h>

#include <soc.h>
#include <zephyr/device.h>
#include <zephyr/drivers/dma.h>
#include <zephyr/irq.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dma_si32, CONFIG_DMA_LOG_LEVEL);

#include <errno.h>
#include <inttypes.h>
#include <stdint.h>

/*
 * Having just one instance allows to avoid using the passed `struct device *` arguments, which in
 * turn (slightly) reduces verification code and flash space needed.
 */
BUILD_ASSERT((uintptr_t)SI32_DMACTRL_0 == (uintptr_t)DT_INST_REG_ADDR(0),
	     "There is just one DMA controller");

#define CHANNEL_COUNT DT_INST_PROP(0, dma_channels) /* number of used/enabled DMA channels */

struct dma_si32_channel_data {
	dma_callback_t callback;
	void *callback_user_data;
	unsigned int tmd: 3; /* transfer mode */
	unsigned int memory_to_memory: 1;
};

struct dma_si32_data {
	struct dma_context ctx; /* Must be first according to the API docs */
	struct dma_si32_channel_data channel_data[CHANNEL_COUNT];
};

ATOMIC_DEFINE(dma_si32_atomic, CHANNEL_COUNT);
static struct dma_si32_data dma_si32_data = {.ctx = {
						     .magic = DMA_MAGIC,
						     .atomic = dma_si32_atomic,
						     .dma_channels = CHANNEL_COUNT,
					     }};

__aligned(SI32_DMADESC_PRI_ALIGN) struct SI32_DMADESC_A_Struct channel_descriptors[CHANNEL_COUNT];

static void dma_si32_isr_handler(const uint8_t channel)
{
	const struct SI32_DMADESC_A_Struct *channel_descriptor = &channel_descriptors[channel];
	const dma_callback_t cb = dma_si32_data.channel_data[channel].callback;
	void *user_data = dma_si32_data.channel_data[channel].callback_user_data;
	int result;

	LOG_INF("Channel %" PRIu8 " ISR fired", channel);

	irq_disable(DMACH0_IRQn + channel);

	if (SI32_DMACTRL_A_is_bus_error_set(SI32_DMACTRL_0)) {
		LOG_ERR("Bus error on channel %" PRIu8, channel);
		result = -EIO;
	} else {
		result = DMA_STATUS_COMPLETE;
		__ASSERT(channel_descriptor->CONFIG.TMD == 0, "Result of success: TMD set to zero");
		__ASSERT(channel_descriptor->CONFIG.NCOUNT == 0,
			 "Result of success: All blocks processed");
		(void)channel_descriptor;
		__ASSERT((SI32_DMACTRL_0->CHENSET.U32 & BIT(channel)) == 0,
			 "Result of success: Channel disabled");
	}

	if (!cb) {
		return;
	}

	cb(DEVICE_DT_INST_GET(0), user_data, channel, result);
}

#define DMA_SI32_IRQ_CONNECT(channel)                                                              \
	do {                                                                                       \
		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, channel, irq),                                   \
			    DT_INST_IRQ_BY_IDX(0, channel, priority), dma_si32_isr_handler,        \
			    channel, 0);                                                           \
	} while (false)

#define DMA_SI32_IRQ_CONNECT_GEN(i, _) DMA_SI32_IRQ_CONNECT(i);

static int dma_si32_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	__ASSERT(SI32_DMACTRL_0 == SI32_DMACTRL_0, "There is only one DMA controller");
	__ASSERT(SI32_DMACTRL_A_get_number_of_channels(SI32_DMACTRL_0) >= CHANNEL_COUNT,
		 "Invalid channel count");

	/* Route clock to the DMA controller */
	SI32_CLKCTRL_A_enable_ahb_to_dma_controller(SI32_CLKCTRL_0);

	/* Configure base address of the DMA channel descriptors */
	SI32_DMACTRL_A_write_baseptr(SI32_DMACTRL_0, (uintptr_t)channel_descriptors);

	/* Enable the DMA interface */
	SI32_DMACTRL_A_enable_module(SI32_DMACTRL_0);

	/* Primary descriptors only. This driver does do not support the more complex cases yet. */
	SI32_DMACTRL_A_write_chalt(SI32_DMACTRL_0, 0);

	/* AN666.pdf: The SCONFIG module contains a bit (FDMAEN) that enables faster DMA transfers
	 * when set to 1. It is recommended that all applications using the DMA set this bit to 1.
	 */
	SI32_SCONFIG_A_enter_fast_dma_mode(SI32_SCONFIG_0);

	/* Install handlers for all channels */
	LISTIFY(DT_NUM_IRQS(DT_DRV_INST(0)), DMA_SI32_IRQ_CONNECT_GEN, (;));

	return 0;
}

static int dma_si32_config(const struct device *dev, uint32_t channel, struct dma_config *cfg)
{
	ARG_UNUSED(dev);

	const struct dma_block_config *block;
	struct SI32_DMADESC_A_Struct *channel_descriptor;
	struct dma_si32_channel_data *channel_data;
	uint32_t ncount;

	LOG_INF("Configuring channel %" PRIu8, channel);

	if (channel >= CHANNEL_COUNT) {
		LOG_ERR("Invalid channel (id %" PRIu32 ", have %d)", channel, CHANNEL_COUNT);
		return -EINVAL;
	}

	/* Prevent messing up (potentially) ongoing DMA operations and their settings. This behavior
	 * is required by the Zephyr DMA API.
	 */
	if (SI32_DMACTRL_A_is_channel_enabled(SI32_DMACTRL_0, channel)) {
		LOG_ERR("DMA channel is currently in use");
		return -EBUSY;
	}

	channel_descriptor = &channel_descriptors[channel];

	if (cfg == NULL) {
		LOG_ERR("Missing config");
		return -EINVAL;
	}

	if (cfg->complete_callback_en > 1) {
		LOG_ERR("Callback on each block not implemented");
		return -ENOTSUP;
	}

	if (cfg->error_callback_dis > 1) {
		LOG_ERR("Error callback disabling not implemented");
		return -ENOTSUP;
	}

	if (cfg->source_handshake > 1 || cfg->dest_handshake > 1) {
		LOG_ERR("Handshake not implemented");
		return -ENOTSUP;
	}

	if (cfg->channel_priority > 1) {
		LOG_ERR("Channel priority not implemented");
		return -ENOTSUP;
	}

	if (cfg->source_chaining_en > 1 || cfg->dest_chaining_en > 1) {
		LOG_ERR("Chaining not implemented");
		return -ENOTSUP;
	}

	if (cfg->linked_channel > 1) {
		LOG_ERR("Linked channel not implemented");
		return -ENOTSUP;
	}

	if (cfg->cyclic > 1) {
		LOG_ERR("Cyclic transfer not implemented");
		return -ENOTSUP;
	}

	if (cfg->source_data_size != 1 && cfg->source_data_size != 2 &&
	    cfg->source_data_size != 4) {
		LOG_ERR("source_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->source_data_size);
		return -ENOTSUP;
	}

	if (cfg->dest_data_size != 1 && cfg->dest_data_size != 2 && cfg->dest_data_size != 4) {
		LOG_ERR("dest_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->dest_data_size);
		return -ENOTSUP;
	}

	__ASSERT(cfg->source_data_size == cfg->dest_data_size,
		 "The destination size (DSTSIZE) must equal the source size (SRCSIZE).");

	if (cfg->source_burst_length != cfg->dest_burst_length) {
		LOG_ERR("Individual burst modes not supported");
		return -ENOTSUP;
	}

	if (POPCOUNT(cfg->source_burst_length) > 1) {
		LOG_ERR("Burst lengths must be power of two");
		return -ENOTSUP;
	}

	if (cfg->block_count > 1) {
		LOG_ERR("Scatter-Gather not implemented");
		return -ENOTSUP;
	}

	/* Config is sane, start using it */
	channel_data = &dma_si32_data.channel_data[channel];
	channel_data->callback = cfg->dma_callback;
	channel_data->callback_user_data = cfg->user_data;

	switch (cfg->source_data_size) {
	case 4:
		channel_descriptor->CONFIG.SRCSIZE = 0b10;
		channel_descriptor->CONFIG.DSTSIZE = 0b10;
		channel_descriptor->CONFIG.RPOWER =
			cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 3 : 0;
		break;
	case 2:
		channel_descriptor->CONFIG.SRCSIZE = 0b01;
		channel_descriptor->CONFIG.DSTSIZE = 0b01;
		channel_descriptor->CONFIG.RPOWER =
			cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 2 : 0;
		break;
	case 1:
		channel_descriptor->CONFIG.SRCSIZE = 0b00;
		channel_descriptor->CONFIG.DSTSIZE = 0b00;
		channel_descriptor->CONFIG.RPOWER =
			cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 1 : 0;
		break;
	default:
		LOG_ERR("source_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->source_data_size);
		return -EINVAL;
	}

	/* Configuration evaluated and extracted, except for its (first) block. Do this now. */
	if (!cfg->head_block || cfg->block_count == 0) {
		LOG_ERR("Missing head block");
		return -EINVAL;
	}

	block = cfg->head_block;

	if (block->block_size % cfg->source_data_size != 0) {
		LOG_ERR("Block size not a multiple of data size");
		return -EINVAL;
	}

	if (block->source_address % cfg->source_data_size != 0) {
		LOG_ERR("Block source address not aligned with source data size");
		return -EINVAL;
	}

	if (block->dest_address % cfg->dest_data_size != 0) {
		LOG_ERR("Block dest address not aligned with dest data size");
		return -EINVAL;
	}

	ncount = block->block_size / cfg->source_data_size - 1;

	/* NCOUNT (10 bits wide) works only for values up to 1023 (1024 transfers) */
	if (ncount >= 1024) {
		LOG_ERR("Transfer size exceeded");
		return -EINVAL;
	}

	channel_descriptor->CONFIG.NCOUNT = ncount;

	/* Copy data to own location so that cfg must not exist during all of the channels usage */
	switch (cfg->channel_direction) {
	case 0b000: /* memory to memory */
		/* SiM3U1xx-SiM3C1xx-RM.pdf, 16.6.2. Auto-Request Transfers: This transfer type is
		 * recommended for memory to memory transfers.
		 */
		channel_data->tmd = SI32_DMADESC_A_CONFIG_TMD_AUTO_REQUEST_VALUE;
		channel_data->memory_to_memory = 1;
		SI32_DMACTRL_A_disable_data_request(SI32_DMACTRL_0, channel);
		break;
	case 0b001: /* memory to peripheral */
	case 0b010: /* peripheral to memory */
		/* SiM3U1xx-SiM3C1xx-RM.pdf, 4.3.1. Basic Transfers: This transfer type is
		 * recommended for peripheral-to-memory or memory-to-peripheral transfers.
		 */
		channel_data->tmd = SI32_DMADESC_A_CONFIG_TMD_BASIC_VALUE;
		channel_data->memory_to_memory = 0;
		SI32_DMACTRL_A_enable_data_request(SI32_DMACTRL_0, channel);
		break;
	default: /* everything else is not (yet) supported */
		LOG_ERR("Channel direction not implemented: %d", cfg->channel_direction);
		return -ENOTSUP;
	}

	switch (block->source_addr_adj) {
	case 0b00: /* increment */
		channel_descriptor->SRCEND.U32 =
			block->source_address + ncount * cfg->source_data_size;
		channel_descriptor->CONFIG.SRCAIMD = channel_descriptor->CONFIG.SRCSIZE;
		break;
	case 0b01: /* decrement */
		LOG_ERR("source_addr_adj value not supported by HW");
		return -ENOTSUP;
	case 0b10: /* no change */
		channel_descriptor->SRCEND.U32 = block->source_address;
		channel_descriptor->CONFIG.SRCAIMD = 0b11;
		break;
	default:
		LOG_ERR("Unknown source_addr_adj value");
		return -EINVAL;
	}

	switch (block->dest_addr_adj) {
	case 0b00: /* increment */
		channel_descriptor->DSTEND.U32 = block->dest_address + ncount * cfg->dest_data_size;
		channel_descriptor->CONFIG.DSTAIMD = channel_descriptor->CONFIG.DSTSIZE;
		break;
	case 0b01: /* decrement */
		LOG_ERR("dest_addr_adj value not supported by HW");
		return -ENOTSUP;
	case 0b10: /* no change */
		channel_descriptor->DSTEND.U32 = block->dest_address;
		channel_descriptor->CONFIG.DSTAIMD = 0b11;
		break;
	default:
		LOG_ERR("Unknown dest_addr_adj value");
		return -EINVAL;
	}

	return 0;
}

static int dma_si32_start(const struct device *dev, const uint32_t channel)
{
	ARG_UNUSED(dev);

	struct SI32_DMADESC_A_Struct *channel_desc = &channel_descriptors[channel];
	struct dma_si32_channel_data *channel_data;

	LOG_INF("Starting channel %" PRIu8, channel);

	if (channel >= CHANNEL_COUNT) {
		LOG_ERR("Invalid channel (id %" PRIu32 ", have %d)", channel, CHANNEL_COUNT);
		return -EINVAL;
	}

	channel_data = &dma_si32_data.channel_data[channel];

	/* All of this should be set by our own, previously running code. During development
	 * however, it is still useful to double check here.
	 */
	__ASSERT(SI32_CLKCTRL_0->AHBCLKG.DMACEN,
		 "AHB clock to the DMA controller must be enabled.");
	__ASSERT(SI32_DMACTRL_A_is_enabled(SI32_DMACTRL_0), "DMA controller must be enabled.");
	__ASSERT(SI32_DMACTRL_0->BASEPTR.U32 == (uintptr_t)channel_descriptors,
		 "Address location of the channel transfer descriptors (BASEPTR) must be set.");
	__ASSERT(SI32_DMACTRL_A_is_primary_selected(SI32_DMACTRL_0, channel),
		 "Primary descriptors must be used for basic and auto-request operations.");
	__ASSERT(SI32_SCONFIG_0->CONFIG.FDMAEN, "Fast mode is recommened to be enabled.");
	__ASSERT(SI32_DMACTRL_0->CHSTATUS.U32 & BIT(channel),
		 "Channel must be waiting for request");

	channel_desc->CONFIG.TMD = channel_data->tmd;

	/* Get rid of potentially lingering bus errors. */
	SI32_DMACTRL_A_clear_bus_error(SI32_DMACTRL_0);

	/* Enable interrupt for this DMA channels. */
	irq_enable(DMACH0_IRQn + channel);

	SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, channel);

	/* memory-to-memory transfers have to be started by this driver. When peripherals are
	 * involved, the caller has to enable the peripheral to start the transfer.
	 */
	if (dma_si32_data.channel_data[channel].memory_to_memory) {
		__ASSERT((SI32_DMACTRL_0->CHREQMSET.U32 & BIT(channel)),
			 "Peripheral data requests for the channel must be disabled");
		SI32_DMACTRL_A_generate_software_request(SI32_DMACTRL_0, channel);
	} else {
		__ASSERT(!(SI32_DMACTRL_0->CHREQMSET.U32 & BIT(channel)),
			 "Data requests for the channel must be enabled");
	}

	return 0;
}

static int dma_si32_stop(const struct device *dev, const uint32_t channel)
{
	ARG_UNUSED(dev);

	if (channel >= CHANNEL_COUNT) {
		LOG_ERR("Invalid channel (id %" PRIu32 ", have %d)", channel, CHANNEL_COUNT);
		return -EINVAL;
	}

	irq_disable(DMACH0_IRQn + channel);

	channel_descriptors[channel].CONFIG.TMD = 0; /* Stop the DMA channel. */

	SI32_DMACTRL_A_disable_channel(SI32_DMACTRL_0, channel);

	return 0;
}

static const struct dma_driver_api dma_si32_driver_api = {
	.config = dma_si32_config,
	.start = dma_si32_start,
	.stop = dma_si32_stop,
};

DEVICE_DT_INST_DEFINE(0, &dma_si32_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY,
		      &dma_si32_driver_api);
