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

/**
 * @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 <clock_control/arm_clock_control.h>

#define MAINCLK_BASE_FREQ 24000000

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

static inline void beetle_set_clock(volatile u32_t *base,
				    u8_t bit, enum arm_soc_state_t state)
{
	u32_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(u8_t bit,
					   enum arm_soc_state_t state)
{
	beetle_set_clock((volatile u32_t *)&(__BEETLE_SYSCON->ahbclkcfg0set),
			 bit, state);
}

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

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

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

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

	u8_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(struct device *dev,
					   clock_control_subsys_t sub_system)
{
	struct arm_clock_control_t *beetle_cc =
				(struct arm_clock_control_t *)(sub_system);

	u8_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(struct device *clock,
					      clock_control_subsys_t sub_system,
					      u32_t *rate)
{
#ifdef CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL
	const struct beetle_clock_control_cfg_t * const cfg =
						clock->config->config_info;
	u32_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 u32_t beetle_round_freq(u32_t mainclk)
{
	u32_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 u32_t beetle_get_prescaler(u32_t mainclk)
{
	u32_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(u32_t mainclk)
{

	u32_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(struct device *dev)
{
#ifdef CONFIG_CLOCK_CONTROL_BEETLE_ENABLE_PLL
	const struct beetle_clock_control_cfg_t * const cfg =
						dev->config->config_info;

	/*
	 * 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_ARM_CORTEX_M3_0_CLOCK_FREQUENCY,
};

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