+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 Atmel Corporation
* Bo Shen <voice.shen@atmel.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <hang.h>
#include <asm/io.h>
#include <asm/arch/at91_common.h>
#include <asm/arch/at91_pit.h>
#include <asm/arch/clk.h>
#include <spl.h>
-DECLARE_GLOBAL_DATA_PTR;
-
static void switch_to_main_crystal_osc(void)
{
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
;
+#if defined(CONFIG_SAMA5D2)
+ /* Enable a measurement of the external oscillator */
+ tmp = readl(&pmc->mcfr);
+ tmp |= AT91_PMC_MCFR_CCSS_XTAL_OSC;
+ tmp |= AT91_PMC_MCFR_RCMEAS;
+ writel(tmp, &pmc->mcfr);
+
+ while (!(readl(&pmc->mcfr) & AT91_PMC_MCFR_MAINRDY))
+ ;
+
+ if (!(readl(&pmc->mcfr) & AT91_PMC_MCFR_MAINF_MASK))
+ hang();
+#endif
+
tmp = readl(&pmc->mor);
+/*
+ * some boards have an external oscillator with driving.
+ * in this case we need to disable the internal SoC driving (bypass mode)
+ */
+#if defined(CONFIG_SPL_AT91_MCK_BYPASS)
+ tmp |= AT91_PMC_MOR_OSCBYPASS;
+#else
tmp &= ~AT91_PMC_MOR_OSCBYPASS;
+#endif
tmp &= ~AT91_PMC_MOR_KEY(0xff);
tmp |= AT91_PMC_MOR_KEY(0x37);
writel(tmp, &pmc->mor);
while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS))
;
+#if !defined(CONFIG_SAMA5D2)
/* Wait until MAINRDY field is set to make sure main clock is stable */
while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY))
;
+#endif
-#ifndef CONFIG_SAMA5D4
+#if !defined(CONFIG_SAMA5D4) && !defined(CONFIG_SAMA5D2)
tmp = readl(&pmc->mor);
tmp &= ~AT91_PMC_MOR_MOSCRCEN;
tmp &= ~AT91_PMC_MOR_KEY(0xff);
configure_2nd_sram_as_l2_cache();
#endif
+#if !defined(CONFIG_WDT_AT91)
/* disable watchdog */
at91_disable_wdt();
+#endif
/* PMC configuration */
at91_pmc_init();