From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bo Shen Date: Fri, 31 Oct 2014 09:50:12 +0800 Subject: [U-Boot] [v2 PATCH 10/12] arm, spl, at91: add at91sam9260 and at91sam9g45 spl support In-Reply-To: <1414656906-16632-11-git-send-email-hs@denx.de> References: <1414656906-16632-1-git-send-email-hs@denx.de> <1414656906-16632-11-git-send-email-hs@denx.de> Message-ID: <5452EAD4.7080903@atmel.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Heiko, On 10/30/2014 04:15 PM, Heiko Schocher wrote: > diff --git a/arch/arm/cpu/at91-common/spl.c b/arch/arm/cpu/at91-common/spl.c > index 674a470..5c9a3ad 100644 > --- a/arch/arm/cpu/at91-common/spl.c > +++ b/arch/arm/cpu/at91-common/spl.c I am thinking, whether it be better to keep this file as two copy? This will remove #ifdef, although a little code duplication. If this solution acceptable, some suggestion as following: - for armv5 (arm926ejs, now at91 series), named it spl_at91.c, - for armv7 (cortex-a5, now, sama5d3), named it spl_atmel.c? (As for arm9 series, we have at91 prefix for SoC name, and for armv7 SoC, we don't have at91 prefix, and it now changed to Atmel Smart) > @@ -8,11 +8,18 @@ > #include > #include > #include > +#if !defined(CONFIG_SAMA5D3) > +#include > +#endif > +#include > #include > +#include > #include > #include > #include > > +DECLARE_GLOBAL_DATA_PTR; > + > static void at91_disable_wdt(void) > { > struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; > @@ -20,6 +27,33 @@ static void at91_disable_wdt(void) > writel(AT91_WDT_MR_WDDIS, &wdt->mr); > } > > +u32 spl_boot_device(void) > +{ > +#ifdef CONFIG_SYS_USE_MMC > + return BOOT_DEVICE_MMC1; > +#elif CONFIG_SYS_USE_NANDFLASH > + return BOOT_DEVICE_NAND; > +#elif CONFIG_SYS_USE_SERIALFLASH > + return BOOT_DEVICE_SPI; > +#endif > + return BOOT_DEVICE_NONE; > +} > + > +u32 spl_boot_mode(void) > +{ > + switch (spl_boot_device()) { > +#ifdef CONFIG_SYS_USE_MMC > + case BOOT_DEVICE_MMC1: > + return MMCSD_MODE_FS; > + break; > +#endif > + case BOOT_DEVICE_NONE: > + default: > + hang(); > + } > +} > + > +#if defined(CONFIG_SAMA5D3) > static void switch_to_main_crystal_osc(void) > { > struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; > @@ -57,77 +91,134 @@ static void switch_to_main_crystal_osc(void) > writel(tmp, &pmc->mor); > } > > -void at91_plla_init(u32 pllar) > +void s_init(void) > { > - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; > + switch_to_main_crystal_osc(); > > - writel(pllar, &pmc->pllar); > - while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) > - ; > -} > + /* disable watchdog */ > + at91_disable_wdt(); > > -void at91_mck_init(u32 mckr) > -{ > - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; > - u32 tmp; > + /* PMC configuration */ > + at91_pmc_init(); > > - tmp = readl(&pmc->mckr); > - tmp &= ~(AT91_PMC_MCKR_PRES_MASK | > - AT91_PMC_MCKR_MDIV_MASK | > - AT91_PMC_MCKR_PLLADIV_2); > - tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK | > - AT91_PMC_MCKR_MDIV_MASK | > - AT91_PMC_MCKR_PLLADIV_2); > - writel(tmp, &pmc->mckr); > + at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); > > - while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) > - ; > -} > + timer_init(); > > + board_early_init_f(); > > -u32 spl_boot_device(void) > + preloader_console_init(); > + > + mem_init(); > +} > +#else > +static void enable_ext_reset(void) > { > -#ifdef CONFIG_SYS_USE_MMC > - return BOOT_DEVICE_MMC1; > -#elif CONFIG_SYS_USE_NANDFLASH > - return BOOT_DEVICE_NAND; > -#elif CONFIG_SYS_USE_SERIALFLASH > - return BOOT_DEVICE_SPI; > -#endif > - return BOOT_DEVICE_NONE; > + struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC; > + > + writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr); > } > > -u32 spl_boot_mode(void) > +#if defined(CONFIG_ATMEL_MATRIX_INIT) > +static void matrix_init(void) > { > - switch (spl_boot_device()) { > -#ifdef CONFIG_SYS_USE_MMC > - case BOOT_DEVICE_MMC1: > - return MMCSD_MODE_FS; > - break; > + struct at91_matrix *mat = (struct at91_matrix *)ATMEL_BASE_MATRIX; > + > + writel((readl(&mat->scfg[3]) & (~AT91_MATRIX_SLOT_CYCLE)) > + | AT91_MATRIX_SLOT_CYCLE_(0x40), > + &mat->scfg[3]); > +} > #endif > - case BOOT_DEVICE_NONE: > - default: > - hang(); > + > +void lowlevel_clock_init(void) > +{ > + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; > + > + if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) { > + /* Enable Main Oscillator */ > + writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor); > + > + /* Wait until Main Oscillator is stable */ > + while (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) > + ; > } > + > + /* After stabilization, switch to Main Oscillator */ > + if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) { > + unsigned long tmp; > + > + tmp = readl(&pmc->mckr); > + tmp &= ~AT91_PMC_CSS; > + tmp |= AT91_PMC_CSS_MAIN; > + writel(tmp, &pmc->mckr); > + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) > + ; > + > + tmp &= ~AT91_PMC_PRES; > + tmp |= AT91_PMC_PRES_1; > + writel(tmp, &pmc->mckr); > + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) > + ; > + } > + > + return; > } > > -void s_init(void) > +void __weak at91_spl_board_init(void) > { > - switch_to_main_crystal_osc(); > +} > > - /* disable watchdog */ > +void spl_board_init(void) > +{ > + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; > + > + lowlevel_clock_init(); > at91_disable_wdt(); > > - /* PMC configuration */ > - at91_pmc_init(); > + /* > + * At this stage the main oscillator is supposed to be enabled > + * PCK = MCK = MOSC > + */ > + writel(0x00, &pmc->pllicpr); > > - at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); > + /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ > + at91_plla_init(CONFIG_SYS_AT91_PLLA); > > - timer_init(); > + /* PCK = PLLA = 2 * MCK */ > + at91_mck_init(CONFIG_SYS_MCKR); > > - board_early_init_f(); > + /* Switch MCK on PLLA output */ > + at91_mck_init(CONFIG_SYS_MCKR_CSS); > + > +#if defined(CONFIG_SYS_AT91_PLLB) > + /* Configure PLLB */ > + at91_pllb_init(CONFIG_SYS_AT91_PLLB); > +#endif > + > + /* Enable External Reset */ > + enable_ext_reset(); > > +#if defined(CONFIG_ATMEL_MATRIX_INIT) > + /* Initialize matrix */ > + matrix_init(); > +#endif Can this also be weak function? And put matrix_init() code to SoC/board related file. > + gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK; > + /* > + * init timer long enough for using in spl. > + */ > + timer_init(); > + > + /* enable clocks for all PIOs */ > + at91_periph_clk_enable(ATMEL_ID_PIOA); > + at91_periph_clk_enable(ATMEL_ID_PIOB); > + at91_periph_clk_enable(ATMEL_ID_PIOC); > + /* init console */ > + at91_seriald_hw_init(); > preloader_console_init(); > > mem_init(); > + > + at91_spl_board_init(); > } > +#endif Best Regards, Bo Shen