1 /* 2 * Copyright (C) 2013 Atmel Corporation 3 * Bo Shen <voice.shen@atmel.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <asm/io.h> 10 #include <asm/arch/at91_common.h> 11 #include <asm/arch/at91_pit.h> 12 #include <asm/arch/at91_pmc.h> 13 #include <asm/arch/at91_rstc.h> 14 #include <asm/arch/at91_wdt.h> 15 #include <asm/arch/clk.h> 16 #include <spl.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 static void switch_to_main_crystal_osc(void) 21 { 22 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; 23 u32 tmp; 24 25 tmp = readl(&pmc->mor); 26 tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff); 27 tmp &= ~AT91_PMC_MOR_KEY(0xff); 28 tmp |= AT91_PMC_MOR_MOSCEN; 29 tmp |= AT91_PMC_MOR_OSCOUNT(8); 30 tmp |= AT91_PMC_MOR_KEY(0x37); 31 writel(tmp, &pmc->mor); 32 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS)) 33 ; 34 35 tmp = readl(&pmc->mor); 36 tmp &= ~AT91_PMC_MOR_OSCBYPASS; 37 tmp &= ~AT91_PMC_MOR_KEY(0xff); 38 tmp |= AT91_PMC_MOR_KEY(0x37); 39 writel(tmp, &pmc->mor); 40 41 tmp = readl(&pmc->mor); 42 tmp |= AT91_PMC_MOR_MOSCSEL; 43 tmp &= ~AT91_PMC_MOR_KEY(0xff); 44 tmp |= AT91_PMC_MOR_KEY(0x37); 45 writel(tmp, &pmc->mor); 46 47 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS)) 48 ; 49 50 /* Wait until MAINRDY field is set to make sure main clock is stable */ 51 while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY)) 52 ; 53 54 #ifndef CONFIG_SAMA5D4 55 tmp = readl(&pmc->mor); 56 tmp &= ~AT91_PMC_MOR_MOSCRCEN; 57 tmp &= ~AT91_PMC_MOR_KEY(0xff); 58 tmp |= AT91_PMC_MOR_KEY(0x37); 59 writel(tmp, &pmc->mor); 60 #endif 61 } 62 63 __weak void matrix_init(void) 64 { 65 /* This only be used for sama5d4 soc now */ 66 } 67 68 __weak void redirect_int_from_saic_to_aic(void) 69 { 70 /* This only be used for sama5d4 soc now */ 71 } 72 73 /* empty stub to satisfy current lowlevel_init, can be removed any time */ 74 void s_init(void) 75 { 76 } 77 78 void board_init_f(ulong dummy) 79 { 80 switch_to_main_crystal_osc(); 81 82 /* disable watchdog */ 83 at91_disable_wdt(); 84 85 /* PMC configuration */ 86 at91_pmc_init(); 87 88 at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); 89 90 matrix_init(); 91 92 redirect_int_from_saic_to_aic(); 93 94 timer_init(); 95 96 board_early_init_f(); 97 98 preloader_console_init(); 99 100 mem_init(); 101 102 /* Clear the BSS. */ 103 memset(__bss_start, 0, __bss_end - __bss_start); 104 105 board_init_r(NULL, 0); 106 } 107