/*
 * Copyright (c) 2016 Piotr Mienkowski
 * SPDX-License-Identifier: Apache-2.0
 */

/** @file
 * @brief Atmel SAM E70 MCU initialization code
 *
 * This file provides routines to initialize and support board-level hardware
 * for the Atmel SAM E70 MCU.
 */

#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <cortex_m/exc.h>

/* Power Manager Controller */

/*
 * PLL clock = Main * (MULA + 1) / DIVA
 *
 * By default, MULA == 24, DIVA == 1.
 * With main crystal running at 12 MHz,
 * PLL = 12 * (24 + 1) / 1 = 300 MHz
 *
 * With Processor Clock prescaler at 1
 * Processor Clock (HCLK)=300 MHz.
 */
#define PMC_CKGR_PLLAR_MULA	\
	(CKGR_PLLAR_MULA(CONFIG_SOC_ATMEL_SAME70_PLLA_MULA))
#define PMC_CKGR_PLLAR_DIVA	\
	(CKGR_PLLAR_DIVA(CONFIG_SOC_ATMEL_SAME70_PLLA_DIVA))

#if CONFIG_SOC_ATMEL_SAME70_MDIV == 1
#define SOC_ATMEL_SAME70_MDIV PMC_MCKR_MDIV_EQ_PCK
#elif CONFIG_SOC_ATMEL_SAME70_MDIV == 2
#define SOC_ATMEL_SAME70_MDIV PMC_MCKR_MDIV_PCK_DIV2
#elif CONFIG_SOC_ATMEL_SAME70_MDIV == 3
#define SOC_ATMEL_SAME70_MDIV PMC_MCKR_MDIV_PCK_DIV3
#elif CONFIG_SOC_ATMEL_SAME70_MDIV == 4
#define SOC_ATMEL_SAME70_MDIV PMC_MCKR_MDIV_PCK_DIV4
#else
#error "Invalid CONFIG_SOC_ATMEL_SAME70_MDIV define value"
#endif

/**
 * @brief Setup various clocks on SoC at boot time.
 *
 * Setup Slow, Main, PLLA, Processor and Master clocks during the device boot.
 * It is assumed that the relevant registers are at their reset value.
 */
static ALWAYS_INLINE void clock_init(void)
{
	u32_t reg_val;

#ifdef CONFIG_SOC_ATMEL_SAME70_EXT_SLCK
	/* Switch slow clock to the external 32 kHz crystal oscillator */
	SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL;

	/* Wait for oscillator to be stabilized */
	while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL)) {
		;
	}
#endif /* CONFIG_SOC_ATMEL_SAME70_EXT_SLCK */

#ifdef CONFIG_SOC_ATMEL_SAME70_EXT_MAINCK
	/*
	 * Setup main external crystal oscillator if not already done
	 * by a previous program i.e. bootloader
	 */

	if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL_Msk)) {
		/* Start the external crystal oscillator */
		PMC->CKGR_MOR =   CKGR_MOR_KEY_PASSWD
				/* We select maximum setup time.
				 * While start up time could be shortened
				 * this optimization is not deemed
				 * critical now.
				 */
				| CKGR_MOR_MOSCXTST(0xFFu)
				/* RC OSC must stay on */
				| CKGR_MOR_MOSCRCEN
				| CKGR_MOR_MOSCXTEN;

		/* Wait for oscillator to be stabilized */
		while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) {
			;
		}

		/* Select the external crystal oscillator as main clock */
		PMC->CKGR_MOR =   CKGR_MOR_KEY_PASSWD
				| CKGR_MOR_MOSCSEL
				| CKGR_MOR_MOSCXTST(0xFFu)
				| CKGR_MOR_MOSCRCEN
				| CKGR_MOR_MOSCXTEN;

		/* Wait for external oscillator to be selected */
		while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) {
			;
		}
	}

	/* Turn off RC OSC, not used any longer, to save power */
	PMC->CKGR_MOR =   CKGR_MOR_KEY_PASSWD
			| CKGR_MOR_MOSCSEL
			| CKGR_MOR_MOSCXTST(0xFFu)
			| CKGR_MOR_MOSCXTEN;

	/* Wait for RC OSC to be turned off */
	while (PMC->PMC_SR & PMC_SR_MOSCRCS) {
		;
	}

#ifdef CONFIG_SOC_ATMEL_SAME70_WAIT_MODE
	/*
	 * Instruct CPU to enter Wait mode instead of Sleep mode to
	 * keep Processor Clock (HCLK) and thus be able to debug
	 * CPU using JTAG
	 */
	PMC->PMC_FSMR |= PMC_FSMR_LPM;
#endif
#else
	/* Attempt to change main fast RC oscillator frequency */

	/*
	 * NOTE: MOSCRCF must be changed only if MOSCRCS is set in the PMC_SR
	 * register, should normally be the case here
	 */
	while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) {
		;
	}

	/* Set main fast RC oscillator to 12 MHz */
	PMC->CKGR_MOR =   CKGR_MOR_KEY_PASSWD
			| CKGR_MOR_MOSCRCF_12_MHz
			| CKGR_MOR_MOSCRCEN;

	/* Wait for oscillator to be stabilized */
	while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) {
		;
	}
#endif /* CONFIG_SOC_ATMEL_SAME70_EXT_MAINCK */

	/*
	 * Setup PLLA
	 */

	/* Switch MCK (Master Clock) to the main clock first */
	reg_val = PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk;
	PMC->PMC_MCKR = reg_val | PMC_MCKR_CSS_MAIN_CLK;

	/* Wait for clock selection to complete */
	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
		;
	}

	/* Setup PLLA */
	PMC->CKGR_PLLAR =   CKGR_PLLAR_ONE
			  | PMC_CKGR_PLLAR_MULA
			  | CKGR_PLLAR_PLLACOUNT(0x3Fu)
			  | PMC_CKGR_PLLAR_DIVA;

	/*
	 * NOTE: Both MULA and DIVA must be set to a value greater than 0 or
	 * otherwise PLL will be disabled. In this case we would get stuck in
	 * the following loop.
	 */

	/* Wait for PLL lock */
	while (!(PMC->PMC_SR & PMC_SR_LOCKA)) {
		;
	}

	/*
	 * Final setup of the Master Clock
	 */

	/*
	 * NOTE: PMC_MCKR must not be programmed in a single write operation.
	 * If CSS, MDIV or PRES are modified we must wait for MCKRDY bit to be
	 * set again.
	 */

	/* Setup prescaler - PLLA Clock / Processor Clock (HCLK) */
	reg_val = PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk;
	PMC->PMC_MCKR = reg_val | PMC_MCKR_PRES_CLK_1;

	/* Wait for Master Clock setup to complete */
	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
		;
	}

	/* Setup divider - Processor Clock (HCLK) / Master Clock (MCK) */
	reg_val = PMC->PMC_MCKR & ~PMC_MCKR_MDIV_Msk;
	PMC->PMC_MCKR = reg_val | SOC_ATMEL_SAME70_MDIV;

	/* Wait for Master Clock setup to complete */
	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
		;
	}

	/* Finally select PLL as Master Clock source */
	reg_val = PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk;
	PMC->PMC_MCKR = reg_val | PMC_MCKR_CSS_PLLA_CLK;

	/* Wait for Master Clock setup to complete */
	while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
		;
	}
}

/**
 * @brief Perform basic hardware initialization at boot.
 *
 * This needs to be run at the very beginning.
 * So the init priority has to be 0 (zero).
 *
 * @return 0
 */
static int atmel_same70_init(struct device *arg)
{
	u32_t key;

	ARG_UNUSED(arg);

	key = irq_lock();

	SCB_EnableICache();

	if (!(SCB->CCR & SCB_CCR_DC_Msk)) {
		SCB_EnableDCache();
	}

	/* Clear all faults */
	z_clearfaults();

	/*
	 * Set FWS (Flash Wait State) value before increasing Master Clock
	 * (MCK) frequency.
	 * TODO: set FWS based on the actual MCK frequency and VDDIO value
	 * rather than maximum supported 150 MHz at standard VDDIO=2.7V
	 */
	EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE;

	/* Setup system clocks */
	clock_init();

	/* Install default handler that simply resets the CPU
	 * if configured in the kernel, NOP otherwise
	 */
	NMI_INIT();

	irq_unlock(key);

	return 0;
}

SYS_INIT(atmel_same70_init, PRE_KERNEL_1, 0);
