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

#define DT_DRV_COMPAT arm_cortex_m3

/**
 * @file
 * @brief Driver for Clock Control of Beetle MCUs.
 *
 * This file contains the Clock Control driver implementation for the
 * Beetle MCUs.
 */

#include <soc.h>
#include <drivers/clock_control.h>
#include <sys/util.h>
#include <drivers/clock_control/arm_clock_control.h>

#define MAINCLK_BASE_FREQ 24000000

struct beetle_clock_control_cfg_t {
	/* Clock Control ID */
	uint32_t clock_control_id;
	/* Clock control freq */
	uint32_t freq;
};

static inline void beetle_set_clock(volatile uint32_t *base,
				    uint8_t bit, enum arm_soc_state_t state)
{
	uint32_t key;

	key = irq_lock();

	switch (state) {
	case SOC_ACTIVE:
		base[0] |= (1 << bit);
		break;
	case SOC_SLEEP:
		base[2] |= (1 << bit);
		break;
	case SOC_DEEPSLEEP:
		base[4] |= (1 << bit);
		break;
	default:
		break;
	}

	irq_unlock(key);
}

static inline void beetle_ahb_set_clock_on(uint8_t bit,
					   enum arm_soc_state_t state)
{
	beetle_set_clock((volatile uint32_t *)&(__BEETLE_SYSCON->ahbclkcfg0set),
			 bit, state);
}

static inline void beetle_ahb_set_clock_off(uint8_t bit,
					    enum arm_soc_state_t state)
{
	beetle_set_clock((volatile uint32_t *)&(__BEETLE_SYSCON->ahbclkcfg0clr),
			 bit, state);
}

static inline void beetle_apb_set_clock_on(uint8_t bit,
					   enum arm_soc_state_t state)
{
	beetle_set_clock((volatile uint32_t *)&(__BEETLE_SYSCON->apbclkcfg0set),
			 bit, state);
}

static inline void beetle_apb_set_clock_off(uint8_t bit,
					    enum arm_soc_state_t state)
{
	beetle_set_clock((volatile uint32_t *)&(__BEETLE_SYSCON->apbclkcfg0clr),
			 bit, state);
}

static inline int beetle_clock_control_on(const struct device *dev,
					  clock_control_subsys_t sub_system)
{
	struct arm_clock_control_t *beetle_cc =
				(struct arm_clock_control_t *)(sub_system);

	uint8_t bit = 0U;

	switch (beetle_cc->bus) {
	case CMSDK_AHB:
		bit = (beetle_cc->device - _BEETLE_AHB_BASE) >> 12;
		beetle_ahb_set_clock_on(bit, beetle_cc->state);
		break;
	case CMSDK_APB:
		bit = (beetle_cc->device - _BEETLE_APB_BASE) >> 12;
		beetle_apb_set_clock_on(bit, beetle_cc->state);
		break;
	default:
		break;
	}

	return 0;
}

static inline int beetle_clock_control_off(const struct device *dev,
					   clock_control_subsys_t sub_system)
{
	struct arm_clock_control_t *beetle_cc =
				(struct arm_clock_control_t *)(sub_system);

	uint8_t bit = 0U;

	switch (beetle_cc->bus) {
	case CMSDK_AHB:
		bit = (beetle_cc->device - _BEETLE_AHB_BASE) >> 12;
		beetle_ahb_set_clock_off(bit, beetle_cc->state);
		break;
	case CMSDK_APB:
		bit = (beetle_cc->device - _BEETLE_APB_BASE) >> 12;
		beetle_apb_set_clock_off(bit, beetle_cc->state);
		break;
	default:
		break;
	}
	return 0;
}

static int beetle_clock_control_get_subsys_rate(const struct device *clock,
						clock_control_subsys_t sub_system,
						uint32_t *rate)
{
#ifdef CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL
	const struct beetle_clock_control_cfg_t * const cfg =
						clock->config;
	uint32_t nc_mainclk = beetle_round_freq(cfg->freq);

	*rate = nc_mainclk;
#else
	ARG_UNUSED(clock);
	ARG_UNUSED(sub_system);

	*rate = MAINCLK_BASE_FREQ;
#endif /* CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL */

	return 0;
}

static const struct clock_control_driver_api beetle_clock_control_api = {
	.on = beetle_clock_control_on,
	.off = beetle_clock_control_off,
	.get_rate = beetle_clock_control_get_subsys_rate,
};

#ifdef CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL
static uint32_t beetle_round_freq(uint32_t mainclk)
{
	uint32_t nc_mainclk = 0U;

	/*
	 * Verify that the frequency is in the supported range otherwise
	 * round it to the next closer one.
	 */
	if (mainclk <= BEETLE_PLL_FREQUENCY_12MHZ) {
		nc_mainclk = BEETLE_PLL_FREQUENCY_12MHZ;
	} else if (mainclk <= BEETLE_PLL_FREQUENCY_24MHZ) {
		nc_mainclk = BEETLE_PLL_FREQUENCY_24MHZ;
	} else if (mainclk <= BEETLE_PLL_FREQUENCY_36MHZ) {
		nc_mainclk = BEETLE_PLL_FREQUENCY_36MHZ;
	} else {
		nc_mainclk = BEETLE_PLL_FREQUENCY_48MHZ;
	}

	return nc_mainclk;
}

static uint32_t beetle_get_prescaler(uint32_t mainclk)
{
	uint32_t pre_mainclk = 0U;

	/*
	 * Verify that the frequency is in the supported range otherwise
	 * round it to the next closer one.
	 */
	if (mainclk <= BEETLE_PLL_FREQUENCY_12MHZ) {
		pre_mainclk = BEETLE_PLL_PRESCALER_12MHZ;
	} else if (mainclk <= BEETLE_PLL_FREQUENCY_24MHZ) {
		pre_mainclk = BEETLE_PLL_PRESCALER_24MHZ;
	} else if (mainclk <= BEETLE_PLL_FREQUENCY_36MHZ) {
		pre_mainclk = BEETLE_PLL_PRESCALER_36MHZ;
	} else {
		pre_mainclk = BEETLE_PLL_PRESCALER_48MHZ;
	}

	return pre_mainclk;
}

static int beetle_pll_enable(uint32_t mainclk)
{

	uint32_t pre_mainclk = beetle_get_prescaler(mainclk);

	/* Set PLLCTRL Register */
	__BEETLE_SYSCON->pllctrl = BEETLE_PLL_CONFIGURATION;

	/* Switch the the Main clock to PLL and set prescaler */
	__BEETLE_SYSCON->mainclk = pre_mainclk;

	while (!__BEETLE_SYSCON->pllstatus) {
		/* Wait for PLL to lock */
	}

	return 0;
}
#endif /* CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL */

static int beetle_clock_control_init(const struct device *dev)
{
#ifdef CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL
	const struct beetle_clock_control_cfg_t * const cfg =
						dev->config;

	/*
	 * Enable PLL if Beetle is configured to run at a different
	 * frequency than 24Mhz.
	 */
	if (cfg->freq != MAINCLK_BASE_FREQ) {
		beetle_pll_enable(cfg->freq);
	}
#endif /* CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL */

	return 0;
}

static const struct beetle_clock_control_cfg_t beetle_cc_cfg = {
	.clock_control_id = 0,
	.freq = DT_INST_PROP(0, clock_frequency),
};

/**
 * @brief Clock Control device init
 *
 */
DEVICE_DEFINE(clock_control_beetle, CONFIG_ARM_CLOCK_CONTROL_DEV_NAME,
		    &beetle_clock_control_init,
		    NULL,
		    NULL, &beetle_cc_cfg,
		    PRE_KERNEL_1,
		    CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
		    &beetle_clock_control_api);
