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