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