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 spl_board_init(void) 75 { 76 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; 77 78 lowlevel_clock_init(); 79 at91_disable_wdt(); 80 81 /* 82 * At this stage the main oscillator is supposed to be enabled 83 * PCK = MCK = MOSC 84 */ 85 writel(0x00, &pmc->pllicpr); 86 87 /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ 88 at91_plla_init(CONFIG_SYS_AT91_PLLA); 89 90 /* PCK = PLLA = 2 * MCK */ 91 at91_mck_init(CONFIG_SYS_MCKR); 92 93 /* Switch MCK on PLLA output */ 94 at91_mck_init(CONFIG_SYS_MCKR_CSS); 95 96 #if defined(CONFIG_SYS_AT91_PLLB) 97 /* Configure PLLB */ 98 at91_pllb_init(CONFIG_SYS_AT91_PLLB); 99 #endif 100 101 /* Enable External Reset */ 102 enable_ext_reset(); 103 104 /* Initialize matrix */ 105 matrix_init(); 106 107 gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK; 108 /* 109 * init timer long enough for using in spl. 110 */ 111 timer_init(); 112 113 /* enable clocks for all PIOs */ 114 at91_periph_clk_enable(ATMEL_ID_PIOA); 115 at91_periph_clk_enable(ATMEL_ID_PIOB); 116 at91_periph_clk_enable(ATMEL_ID_PIOC); 117 /* init console */ 118 at91_seriald_hw_init(); 119 preloader_console_init(); 120 121 mem_init(); 122 123 at91_spl_board_init(); 124 } 125