/*
 * Copyright (c) 2018 Aurelien Jarno
 * Copyright (c) 2023 Gerson Fernando Budke
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT atmel_sam_trng

#include <zephyr/device.h>
#include <zephyr/drivers/entropy.h>
#include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
#include <errno.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <string.h>

struct trng_sam_dev_cfg {
	Trng *regs;
};

static inline bool _ready(Trng * const trng)
{
#ifdef TRNG_ISR_DATRDY
	return trng->TRNG_ISR & TRNG_ISR_DATRDY;
#else
	return trng->INTFLAG.bit.DATARDY;
#endif
}

static inline uint32_t _data(Trng * const trng)
{
#ifdef REG_TRNG_DATA
	(void) trng;
	return TRNG->DATA.reg;
#else
	return trng->TRNG_ODATA;
#endif
}

static int entropy_sam_wait_ready(Trng * const trng, uint32_t flags)
{
	/* According to the reference manual, the generator provides
	 * one 32-bit random value every 84 peripheral clock cycles.
	 * MCK may not be smaller than HCLK/4, so it should not take
	 * more than 336 HCLK ticks. Assuming the CPU can do 1
	 * instruction per HCLK the number of times to loop before
	 * the TRNG is ready is less than 1000. And that is when
	 * assuming the loop only takes 1 instruction. So looping a
	 * million times should be more than enough.
	 */
	int timeout = 1000000;

	while (!_ready(trng)) {
		if (timeout-- == 0) {
			return -ETIMEDOUT;
		}

		if ((flags & ENTROPY_BUSYWAIT) == 0U) {
			/* This internal function is used by both get_entropy,
			 * and get_entropy_isr APIs. The later may call this
			 * function with the ENTROPY_BUSYWAIT flag set. In
			 * that case make no assumption that the kernel is
			 * initialized when the function is called; so, just
			 * do busy-wait for the random data to be ready.
			 */
			k_yield();
		}
	}

	return 0;
}

static int entropy_sam_get_entropy_internal(const struct device *dev,
					    uint8_t *buffer,
					    uint16_t length, uint32_t flags)
{
	const struct trng_sam_dev_cfg *config = dev->config;
	Trng *const trng = config->regs;

	while (length > 0) {
		size_t to_copy;
		uint32_t value;
		int res;

		res = entropy_sam_wait_ready(trng, flags);
		if (res < 0) {
			return res;
		}

		value = _data(trng);
		to_copy = MIN(length, sizeof(value));

		memcpy(buffer, &value, to_copy);
		buffer += to_copy;
		length -= to_copy;
	}

	return 0;
}

static int entropy_sam_get_entropy(const struct device *dev, uint8_t *buffer,
				   uint16_t length)
{
	return entropy_sam_get_entropy_internal(dev, buffer, length, 0);
}

static int entropy_sam_get_entropy_isr(const struct device *dev,
				       uint8_t *buffer,
				       uint16_t length, uint32_t flags)
{
	uint16_t cnt = length;


	if ((flags & ENTROPY_BUSYWAIT) == 0U) {
		const struct trng_sam_dev_cfg *config = dev->config;
		/* No busy wait; return whatever data is available. */

		Trng * const trng = config->regs;

		do {
			size_t to_copy;
			uint32_t value;

			if (!_ready(trng)) {

				/* Data not ready */
				break;
			}

			value = _data(trng);
			to_copy = MIN(length, sizeof(value));

			memcpy(buffer, &value, to_copy);
			buffer += to_copy;
			length -= to_copy;

		} while (length > 0);

		return cnt - length;

	} else {
		/* Allowed to busy-wait */
		int ret =
			entropy_sam_get_entropy_internal(dev,
				buffer, length, flags);

		if (ret == 0) {
			/* Data retrieved successfully. */
			return cnt;
		}

		return ret;
	}
}

static int entropy_sam_init(const struct device *dev)
{
	const struct trng_sam_dev_cfg *config = dev->config;
	Trng *const trng = config->regs;

#ifdef MCLK
	/* Enable the MCLK */
	MCLK->APBCMASK.bit.TRNG_ = 1;

	/* Enable the TRNG */
	trng->CTRLA.bit.ENABLE = 1;
#else
	/* Enable TRNG in PMC */
	const struct atmel_sam_pmc_config clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(0);
	(void)clock_control_on(SAM_DT_PMC_CONTROLLER,
			       (clock_control_subsys_t)&clock_cfg);

	/* Enable the TRNG */
	trng->TRNG_CR = TRNG_CR_KEY_PASSWD | TRNG_CR_ENABLE;
#endif
	return 0;
}

static const struct entropy_driver_api entropy_sam_api = {
	.get_entropy = entropy_sam_get_entropy,
	.get_entropy_isr = entropy_sam_get_entropy_isr
};

static const struct trng_sam_dev_cfg trng_sam_cfg = {
	.regs = (Trng *)DT_INST_REG_ADDR(0),
};

DEVICE_DT_INST_DEFINE(0,
		    entropy_sam_init, NULL,
		    NULL, &trng_sam_cfg,
		    PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY,
		    &entropy_sam_api);
