/* dma.c - DMA test source file */

/*
 * Copyright (c) 2016 Intel Corporation.
 * Copyright (c) 2021 Linaro Limited.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Verify zephyr dma memory to memory transfer loops
 * @details
 * - Test Steps
 *   -# Set dma channel configuration including source/dest addr, burstlen
 *   -# Set direction memory-to-memory
 *   -# Start transfer
 *   -# Move to next dest addr
 *   -# Back to first step
 * - Expected Results
 *   -# Data is transferred correctly from src to dest, for each loop
 */

#include <zephyr/kernel.h>

#include <zephyr/device.h>
#include <zephyr/drivers/dma.h>
#include <zephyr/pm/device.h>
#include <zephyr/ztest.h>

/* in millisecond */
#define SLEEPTIME 250

#define TRANSFER_LOOPS (4)

static __aligned(32) uint8_t tx_data[CONFIG_DMA_LOOP_TRANSFER_SIZE];
static __aligned(32) uint8_t rx_data[TRANSFER_LOOPS][CONFIG_DMA_LOOP_TRANSFER_SIZE] = { { 0 } };

volatile uint32_t transfer_count;
volatile uint32_t done;
static struct dma_config dma_cfg = {0};
static struct dma_block_config dma_block_cfg = {0};
static int test_case_id;

static void test_transfer(const struct device *dev, uint32_t id)
{
	transfer_count++;
	if (transfer_count < TRANSFER_LOOPS) {
		dma_block_cfg.block_size = sizeof(tx_data);
#ifdef CONFIG_DMA_64BIT
		dma_block_cfg.source_address = (uint64_t)tx_data;
		dma_block_cfg.dest_address = (uint64_t)rx_data[transfer_count];
#else
		dma_block_cfg.source_address = (uint32_t)tx_data;
		dma_block_cfg.dest_address = (uint32_t)rx_data[transfer_count];
#endif

		zassert_false(dma_config(dev, id, &dma_cfg),
					"Not able to config transfer %d",
					transfer_count + 1);
		zassert_false(dma_start(dev, id),
					"Not able to start next transfer %d",
					transfer_count + 1);
	}
}

static void dma_user_callback(const struct device *dma_dev, void *arg,
			      uint32_t id, int status)
{
	/* test case is done so ignore the interrupt */
	if (done) {
		return;
	}

	zassert_false(status < 0, "DMA could not proceed, an error occurred\n");

#ifdef CONFIG_DMAMUX_STM32
	/* the channel is the DMAMUX's one
	 * the device is the DMAMUX, given through
	 * the stream->user_data by the dma_stm32_irq_handler
	 */
	test_transfer((const struct device *)arg, id);
#else
	test_transfer(dma_dev, id);
#endif /* CONFIG_DMAMUX_STM32 */
}

static int test_loop(const struct device *dma)
{
	static int chan_id;

	test_case_id = 0;
	TC_PRINT("DMA memory to memory transfer started\n");

	memset(tx_data, 0, sizeof(tx_data));

	for (int i = 0; i < CONFIG_DMA_LOOP_TRANSFER_SIZE; i++) {
		tx_data[i] = i;
	}

	memset(rx_data, 0, sizeof(rx_data));

	if (!device_is_ready(dma)) {
		TC_PRINT("dma controller device is not ready\n");
		return TC_FAIL;
	}

	TC_PRINT("Preparing DMA Controller: %s\n", dma->name);
	dma_cfg.channel_direction = MEMORY_TO_MEMORY;
	dma_cfg.source_data_size = 1U;
	dma_cfg.dest_data_size = 1U;
	dma_cfg.source_burst_length = 1U;
	dma_cfg.dest_burst_length = 1U;
#ifdef CONFIG_DMAMUX_STM32
	dma_cfg.user_data = (void *)dma;
#else
	dma_cfg.user_data = NULL;
#endif /* CONFIG_DMAMUX_STM32 */
	dma_cfg.dma_callback = dma_user_callback;
	dma_cfg.block_count = 1U;
	dma_cfg.head_block = &dma_block_cfg;

#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START
	dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START;
#endif

	chan_id = dma_request_channel(dma, NULL);
	if (chan_id < 0) {
		TC_PRINT("this platform do not support the dma channel\n");
		chan_id = CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR;
	}
	transfer_count = 0;
	done = 0;
	TC_PRINT("Starting the transfer on channel %d and waiting for 1 second\n", chan_id);
	dma_block_cfg.block_size = sizeof(tx_data);
#ifdef CONFIG_DMA_64BIT
	dma_block_cfg.source_address = (uint64_t)tx_data;
	dma_block_cfg.dest_address = (uint64_t)rx_data[transfer_count];
#else
	dma_block_cfg.source_address = (uint32_t)tx_data;
	dma_block_cfg.dest_address = (uint32_t)rx_data[transfer_count];
#endif

	if (dma_config(dma, chan_id, &dma_cfg)) {
		TC_PRINT("ERROR: transfer config (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (dma_start(dma, chan_id)) {
		TC_PRINT("ERROR: transfer start (%d)\n", chan_id);
		return TC_FAIL;
	}

	k_sleep(K_MSEC(SLEEPTIME));

	if (transfer_count < TRANSFER_LOOPS) {
		transfer_count = TRANSFER_LOOPS;
		TC_PRINT("ERROR: unfinished transfer\n");
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}

	TC_PRINT("Each RX buffer should contain the full TX buffer string.\n");

	for (int i = 0; i < TRANSFER_LOOPS; i++) {
		TC_PRINT("RX data Loop %d\n", i);
		if (memcmp(tx_data, rx_data[i], CONFIG_DMA_LOOP_TRANSFER_SIZE)) {
			return TC_FAIL;
		}
	}

	TC_PRINT("Finished DMA: %s\n", dma->name);
	return TC_PASS;
}

static int test_loop_suspend_resume(const struct device *dma)
{
	static int chan_id;
	int res = 0;

	test_case_id = 1;
	TC_PRINT("DMA memory to memory transfer started\n");

	memset(tx_data, 0, sizeof(tx_data));

	for (int i = 0; i < CONFIG_DMA_LOOP_TRANSFER_SIZE; i++) {
		tx_data[i] = i;
	}

	memset(rx_data, 0, sizeof(rx_data));

	if (!device_is_ready(dma)) {
		TC_PRINT("dma controller device is not ready\n");
		return TC_FAIL;
	}

	TC_PRINT("Preparing DMA Controller: %s\n", dma->name);
	dma_cfg.channel_direction = MEMORY_TO_MEMORY;
	dma_cfg.source_data_size = 1U;
	dma_cfg.dest_data_size = 1U;
	dma_cfg.source_burst_length = 1U;
	dma_cfg.dest_burst_length = 1U;
#ifdef CONFIG_DMAMUX_STM32
	dma_cfg.user_data = (struct device *)dma;
#else
	dma_cfg.user_data = NULL;
#endif /* CONFIG_DMAMUX_STM32 */
	dma_cfg.dma_callback = dma_user_callback;
	dma_cfg.block_count = 1U;
	dma_cfg.head_block = &dma_block_cfg;

#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START
	dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START;
#endif

	chan_id = dma_request_channel(dma, NULL);
	if (chan_id < 0) {
		TC_PRINT("this platform do not support the dma channel\n");
		chan_id = CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR;
	}
	transfer_count = 0;
	done = 0;
	TC_PRINT("Starting the transfer on channel %d and waiting for 1 second\n", chan_id);
	dma_block_cfg.block_size = sizeof(tx_data);
#ifdef CONFIG_DMA_64BIT
	dma_block_cfg.source_address = (uint64_t)tx_data;
	dma_block_cfg.dest_address = (uint64_t)rx_data[transfer_count];
#else
	dma_block_cfg.source_address = (uint32_t)tx_data;
	dma_block_cfg.dest_address = (uint32_t)rx_data[transfer_count];
#endif

	unsigned int irq_key;

	if (dma_config(dma, chan_id, &dma_cfg)) {
		TC_PRINT("ERROR: transfer config (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (dma_start(dma, chan_id)) {
		TC_PRINT("ERROR: transfer start (%d)\n", chan_id);
		return TC_FAIL;
	}

	/* Try multiple times to suspend the transfers */
	uint32_t tc = transfer_count;

	do {
		irq_key = irq_lock();
		res = dma_suspend(dma, chan_id);
		if (res == -ENOSYS) {
			done = 1;
			TC_PRINT("suspend not supported\n");
			dma_stop(dma, chan_id);
			return TC_PASS;
		}
		tc = transfer_count;
		irq_unlock(irq_key);
		k_busy_wait(100);
	} while (tc != transfer_count);

	/* If we failed to suspend we failed */
	if (transfer_count == TRANSFER_LOOPS) {
		TC_PRINT("ERROR: failed to suspend transfers\n");
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}
	TC_PRINT("suspended after %d transfers occurred\n", transfer_count);

	/* Now sleep */
	k_sleep(K_MSEC(SLEEPTIME));

	/* If we failed to suspend we failed */
	if (transfer_count == TRANSFER_LOOPS) {
		TC_PRINT("ERROR: failed to suspend transfers\n");
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}
	TC_PRINT("resuming after %d transfers occurred\n", transfer_count);

	res = dma_resume(dma, chan_id);
	TC_PRINT("Resumed transfers\n");
	if (res != 0) {
		TC_PRINT("ERROR: resume failed, channel %d, result %d", chan_id, res);
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}

	k_sleep(K_MSEC(SLEEPTIME));

	TC_PRINT("Transfer count %d\n", transfer_count);
	if (transfer_count < TRANSFER_LOOPS) {
		transfer_count = TRANSFER_LOOPS;
		TC_PRINT("ERROR: unfinished transfer\n");
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}

	TC_PRINT("Each RX buffer should contain the full TX buffer string.\n");

	for (int i = 0; i < TRANSFER_LOOPS; i++) {
		TC_PRINT("RX data Loop %d\n", i);
		if (memcmp(tx_data, rx_data[i], CONFIG_DMA_LOOP_TRANSFER_SIZE)) {
			return TC_FAIL;
		}
	}

	TC_PRINT("Finished DMA: %s\n", dma->name);
	return TC_PASS;
}

/**
 * @brief Check if the device is in valid power state.
 *
 * @param dev Device instance.
 * @param expected Device expected power state.
 *
 * @retval true If device is in correct power state.
 * @retval false If device is not in correct power state.
 */
static bool check_dev_power_state(const struct device *dev, enum pm_device_state expected)
{
#if CONFIG_PM_DEVICE_RUNTIME
	enum pm_device_state state;

	if (pm_device_state_get(dev, &state) == 0) {
		if (expected != state) {
			TC_PRINT("ERROR: device %s is incorrect power state"
				 " (current state = %s, expected = %s)\n",
				 dev->name, pm_device_state_str(state),
				 pm_device_state_str(expected));
			return false;
		}

		return true;
	}

	TC_PRINT("ERROR: unable to get power state of %s", dev->name);
	return false;
#else
	return true;
#endif /* CONFIG_PM_DEVICE_RUNTIME */
}

static int test_loop_repeated_start_stop(const struct device *dma)
{
	static int chan_id;
	enum pm_device_state init_state = pm_device_on_power_domain(dma) ?
					  PM_DEVICE_STATE_OFF : PM_DEVICE_STATE_SUSPENDED;

	test_case_id = 0;
	TC_PRINT("DMA memory to memory transfer started\n");
	TC_PRINT("Preparing DMA Controller\n");

	memset(tx_data, 0, sizeof(tx_data));

	memset(rx_data, 0, sizeof(rx_data));

	if (!device_is_ready(dma)) {
		TC_PRINT("dma controller device is not ready\n");
		return TC_FAIL;
	}

	dma_cfg.channel_direction = MEMORY_TO_MEMORY;
	dma_cfg.source_data_size = 1U;
	dma_cfg.dest_data_size = 1U;
	dma_cfg.source_burst_length = 1U;
	dma_cfg.dest_burst_length = 1U;
#ifdef CONFIG_DMAMUX_STM32
	dma_cfg.user_data = (void *)dma;
#else
	dma_cfg.user_data = NULL;
#endif /* CONFIG_DMAMUX_STM32 */
	dma_cfg.dma_callback = dma_user_callback;
	dma_cfg.block_count = 1U;
	dma_cfg.head_block = &dma_block_cfg;

#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START
	dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START;
#endif

	if (!check_dev_power_state(dma, PM_DEVICE_STATE_OFF)) {
		return TC_FAIL;
	}

	chan_id = dma_request_channel(dma, NULL);
	if (chan_id < 0) {
		TC_PRINT("this platform do not support the dma channel\n");
		chan_id = CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR;
	}
	transfer_count = 0;
	done = 0;
	TC_PRINT("Starting the transfer on channel %d and waiting for 1 second\n", chan_id);
	dma_block_cfg.block_size = sizeof(tx_data);
#ifdef CONFIG_DMA_64BIT
	dma_block_cfg.source_address = (uint64_t)tx_data;
	dma_block_cfg.dest_address = (uint64_t)rx_data[transfer_count];
#else
	dma_block_cfg.source_address = (uint32_t)tx_data;
	dma_block_cfg.dest_address = (uint32_t)rx_data[transfer_count];
#endif

	if (dma_config(dma, chan_id, &dma_cfg)) {
		TC_PRINT("ERROR: transfer config (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (dma_stop(dma, chan_id)) {
		TC_PRINT("ERROR: transfer stop on stopped channel (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (!check_dev_power_state(dma, init_state)) {
		return TC_FAIL;
	}

	if (dma_start(dma, chan_id)) {
		TC_PRINT("ERROR: transfer start (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (!check_dev_power_state(dma, PM_DEVICE_STATE_ACTIVE)) {
		return TC_FAIL;
	}

	k_sleep(K_MSEC(SLEEPTIME));

	if (transfer_count < TRANSFER_LOOPS) {
		transfer_count = TRANSFER_LOOPS;
		TC_PRINT("ERROR: unfinished transfer\n");
		if (dma_stop(dma, chan_id)) {
			TC_PRINT("ERROR: transfer stop\n");
		}
		return TC_FAIL;
	}

	TC_PRINT("Each RX buffer should contain the full TX buffer string.\n");

	for (int i = 0; i < TRANSFER_LOOPS; i++) {
		TC_PRINT("RX data Loop %d\n", i);
		if (memcmp(tx_data, rx_data[i], CONFIG_DMA_LOOP_TRANSFER_SIZE)) {
			return TC_FAIL;
		}
	}

	TC_PRINT("Finished: DMA\n");

	if (dma_stop(dma, chan_id)) {
		TC_PRINT("ERROR: transfer stop (%d)\n", chan_id);
		return TC_FAIL;
	}

	if (!check_dev_power_state(dma, init_state)) {
		return TC_FAIL;
	}

	if (dma_stop(dma, chan_id)) {
		TC_PRINT("ERROR: repeated transfer stop (%d)\n", chan_id);
		return TC_FAIL;
	}

	return TC_PASS;
}

#define DMA_NAME(i, _)	tst_dma ## i
#define DMA_LIST	LISTIFY(CONFIG_DMA_LOOP_TRANSFER_NUMBER_OF_DMAS, DMA_NAME, (,))

#define TEST_LOOP(dma_name)                                                                        \
	ZTEST(dma_m2m_loop, test_ ## dma_name ## _m2m_loop)                                        \
	{                                                                                          \
		const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name));                  \
		zassert_true((test_loop(dma) == TC_PASS));                                         \
	}

FOR_EACH(TEST_LOOP, (), DMA_LIST);

#define TEST_LOOP_SUSPEND_RESUME(dma_name)                                                         \
	ZTEST(dma_m2m_loop, test_ ## dma_name ## _m2m_loop_suspend_resume)                         \
	{                                                                                          \
		const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name));                  \
		zassert_true((test_loop_suspend_resume(dma) == TC_PASS));                          \
	}

FOR_EACH(TEST_LOOP_SUSPEND_RESUME, (), DMA_LIST);

#define TEST_LOOP_REPEATED_START_STOP(dma_name)                                                    \
	ZTEST(dma_m2m_loop, test_ ## dma_name ## _m2m_loop_repeated_start_stop)                    \
	{                                                                                          \
		const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma_name));                  \
		zassert_true((test_loop_repeated_start_stop(dma) == TC_PASS));                     \
	}

FOR_EACH(TEST_LOOP_REPEATED_START_STOP, (), DMA_LIST);
