1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2014 DENX Software Engineering 4 * Heiko Schocher <hs@denx.de> 5 * 6 * Based on: 7 * Copyright (C) 2013 Atmel Corporation 8 * Bo Shen <voice.shen@atmel.com> 9 */ 10 11 #include <common.h> 12 #include <hang.h> 13 #include <init.h> 14 #include <log.h> 15 #include <asm/global_data.h> 16 #include <asm/io.h> 17 #include <asm/arch/at91_common.h> 18 #include <asm/arch/at91sam9_matrix.h> 19 #include <asm/arch/at91_pit.h> 20 #include <asm/arch/at91_rstc.h> 21 #include <asm/arch/at91_wdt.h> 22 #include <asm/arch/clk.h> 23 #include <spl.h> 24 25 DECLARE_GLOBAL_DATA_PTR; 26 enable_ext_reset(void)27static void enable_ext_reset(void) 28 { 29 struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC; 30 31 writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr); 32 } 33 lowlevel_clock_init(void)34void lowlevel_clock_init(void) 35 { 36 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; 37 38 if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) { 39 /* Enable Main Oscillator */ 40 writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor); 41 42 /* Wait until Main Oscillator is stable */ 43 while (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) 44 ; 45 } 46 47 /* After stabilization, switch to Main Oscillator */ 48 if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) { 49 unsigned long tmp; 50 51 tmp = readl(&pmc->mckr); 52 tmp &= ~AT91_PMC_CSS; 53 tmp |= AT91_PMC_CSS_MAIN; 54 writel(tmp, &pmc->mckr); 55 while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) 56 ; 57 58 tmp &= ~AT91_PMC_PRES; 59 tmp |= AT91_PMC_PRES_1; 60 writel(tmp, &pmc->mckr); 61 while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) 62 ; 63 } 64 65 return; 66 } 67 matrix_init(void)68void __weak matrix_init(void) 69 { 70 } 71 at91_spl_board_init(void)72void __weak at91_spl_board_init(void) 73 { 74 } 75 spl_board_init(void)76void __weak spl_board_init(void) 77 { 78 } 79 board_init_f(ulong dummy)80void board_init_f(ulong dummy) 81 { 82 #if CONFIG_IS_ENABLED(OF_CONTROL) 83 int ret; 84 85 ret = spl_early_init(); 86 if (ret) { 87 debug("spl_early_init() failed: %d\n", ret); 88 hang(); 89 } 90 #endif 91 92 lowlevel_clock_init(); 93 #if !defined(CONFIG_WDT_AT91) 94 at91_disable_wdt(); 95 #endif 96 97 /* 98 * At this stage the main oscillator is supposed to be enabled 99 * PCK = MCK = MOSC 100 */ 101 at91_pllicpr_init(0x00); 102 103 /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ 104 at91_plla_init(CONFIG_SYS_AT91_PLLA); 105 106 /* PCK = PLLA = 2 * MCK */ 107 at91_mck_init(CONFIG_SYS_MCKR); 108 109 /* Switch MCK on PLLA output */ 110 at91_mck_init(CONFIG_SYS_MCKR_CSS); 111 112 #if defined(CONFIG_SYS_AT91_PLLB) 113 /* Configure PLLB */ 114 at91_pllb_init(CONFIG_SYS_AT91_PLLB); 115 #endif 116 117 /* Enable External Reset */ 118 enable_ext_reset(); 119 120 /* Initialize matrix */ 121 matrix_init(); 122 123 gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK; 124 /* 125 * init timer long enough for using in spl. 126 */ 127 timer_init(); 128 129 /* enable clocks for all PIOs */ 130 #if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12) 131 at91_periph_clk_enable(ATMEL_ID_PIOAB); 132 at91_periph_clk_enable(ATMEL_ID_PIOCD); 133 #else 134 at91_periph_clk_enable(ATMEL_ID_PIOA); 135 at91_periph_clk_enable(ATMEL_ID_PIOB); 136 at91_periph_clk_enable(ATMEL_ID_PIOC); 137 #endif 138 139 #if defined(CONFIG_SPL_SERIAL_SUPPORT) 140 /* init console */ 141 at91_seriald_hw_init(); 142 preloader_console_init(); 143 #endif 144 145 mem_init(); 146 147 at91_spl_board_init(); 148 } 149