add support for using spl code on at91sam9260 and at91sam9g45 based boards. Signed-off-by: Heiko Schocher <hs@denx.de> Reviewed-by: Bo Shen <voice.shen@atmel.com> Reviewed-by: Andreas Bießmann <andreas.devel@googlemail.com> [adopt Bo's change in spl.c] Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>master
parent
667af36905
commit
5abc00d020
@ -0,0 +1,77 @@ |
||||
/*
|
||||
* (C) Copyright 2014 |
||||
* Heiko Schocher, DENX Software Engineering, hs@denx.de. |
||||
* |
||||
* Based on: |
||||
* (C) Copyright 2007-2008 |
||||
* Stelian Pop <stelian@popies.net> |
||||
* Lead Tech Design <www.leadtechdesign.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/at91_common.h> |
||||
#include <asm/arch/at91_pmc.h> |
||||
#include <asm/arch/at91sam9_sdramc.h> |
||||
#include <asm/arch/gpio.h> |
||||
|
||||
int sdramc_initialize(unsigned int sdram_address, const struct sdramc_reg *p) |
||||
{ |
||||
struct sdramc_reg *reg = (struct sdramc_reg *)ATMEL_BASE_SDRAMC; |
||||
unsigned int i; |
||||
|
||||
/* SDRAM feature must be in the configuration register */ |
||||
writel(p->cr, ®->cr); |
||||
|
||||
/* The SDRAM memory type must be set in the Memory Device Register */ |
||||
writel(p->mdr, ®->mdr); |
||||
|
||||
/*
|
||||
* The minimum pause of 200 us is provided to precede any single |
||||
* toggle |
||||
*/ |
||||
for (i = 0; i < 1000; i++) |
||||
; |
||||
|
||||
/* A NOP command is issued to the SDRAM devices */ |
||||
writel(AT91_SDRAMC_MODE_NOP, ®->mr); |
||||
writel(0x00000000, sdram_address); |
||||
|
||||
/* An All Banks Precharge command is issued to the SDRAM devices */ |
||||
writel(AT91_SDRAMC_MODE_PRECHARGE, ®->mr); |
||||
writel(0x00000000, sdram_address); |
||||
|
||||
for (i = 0; i < 10000; i++) |
||||
; |
||||
|
||||
/* Eight auto-refresh cycles are provided */ |
||||
for (i = 0; i < 8; i++) { |
||||
writel(AT91_SDRAMC_MODE_REFRESH, ®->mr); |
||||
writel(0x00000001 + i, sdram_address + 4 + 4 * i); |
||||
} |
||||
|
||||
/*
|
||||
* A Mode Register set (MRS) cyscle is issued to program the |
||||
* SDRAM parameters(TCSR, PASR, DS) |
||||
*/ |
||||
writel(AT91_SDRAMC_MODE_LMR, ®->mr); |
||||
writel(0xcafedede, sdram_address + 0x24); |
||||
|
||||
/*
|
||||
* The application must go into Normal Mode, setting Mode |
||||
* to 0 in the Mode Register and perform a write access at |
||||
* any location in the SDRAM. |
||||
*/ |
||||
writel(AT91_SDRAMC_MODE_NORMAL, ®->mr); |
||||
writel(0x00000000, sdram_address); /* Perform Normal mode */ |
||||
|
||||
/*
|
||||
* Write the refresh rate into the count field in the SDRAMC |
||||
* Refresh Timer Rgister. |
||||
*/ |
||||
writel(p->tr, ®->tr); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,124 @@ |
||||
/*
|
||||
* (C) Copyright 2014 DENX Software Engineering |
||||
* Heiko Schocher <hs@denx.de> |
||||
* |
||||
* Based on: |
||||
* Copyright (C) 2013 Atmel Corporation |
||||
* Bo Shen <voice.shen@atmel.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/at91_common.h> |
||||
#include <asm/arch/at91sam9_matrix.h> |
||||
#include <asm/arch/at91_pit.h> |
||||
#include <asm/arch/at91_pmc.h> |
||||
#include <asm/arch/at91_rstc.h> |
||||
#include <asm/arch/at91_wdt.h> |
||||
#include <asm/arch/clk.h> |
||||
#include <spl.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static void enable_ext_reset(void) |
||||
{ |
||||
struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC; |
||||
|
||||
writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr); |
||||
} |
||||
|
||||
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 __weak matrix_init(void) |
||||
{ |
||||
} |
||||
|
||||
void __weak at91_spl_board_init(void) |
||||
{ |
||||
} |
||||
|
||||
void spl_board_init(void) |
||||
{ |
||||
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; |
||||
|
||||
lowlevel_clock_init(); |
||||
at91_disable_wdt(); |
||||
|
||||
/*
|
||||
* At this stage the main oscillator is supposed to be enabled |
||||
* PCK = MCK = MOSC |
||||
*/ |
||||
writel(0x00, &pmc->pllicpr); |
||||
|
||||
/* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ |
||||
at91_plla_init(CONFIG_SYS_AT91_PLLA); |
||||
|
||||
/* PCK = PLLA = 2 * MCK */ |
||||
at91_mck_init(CONFIG_SYS_MCKR); |
||||
|
||||
/* 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(); |
||||
|
||||
/* Initialize matrix */ |
||||
matrix_init(); |
||||
|
||||
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(); |
||||
} |
@ -0,0 +1,80 @@ |
||||
/*
|
||||
* Copyright (C) 2013 Atmel Corporation |
||||
* Bo Shen <voice.shen@atmel.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/at91_common.h> |
||||
#include <asm/arch/at91_pit.h> |
||||
#include <asm/arch/at91_pmc.h> |
||||
#include <asm/arch/at91_rstc.h> |
||||
#include <asm/arch/at91_wdt.h> |
||||
#include <asm/arch/clk.h> |
||||
#include <spl.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static void switch_to_main_crystal_osc(void) |
||||
{ |
||||
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&pmc->mor); |
||||
tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff); |
||||
tmp &= ~AT91_PMC_MOR_KEY(0xff); |
||||
tmp |= AT91_PMC_MOR_MOSCEN; |
||||
tmp |= AT91_PMC_MOR_OSCOUNT(8); |
||||
tmp |= AT91_PMC_MOR_KEY(0x37); |
||||
writel(tmp, &pmc->mor); |
||||
while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS)) |
||||
; |
||||
|
||||
tmp = readl(&pmc->mor); |
||||
tmp &= ~AT91_PMC_MOR_OSCBYPASS; |
||||
tmp &= ~AT91_PMC_MOR_KEY(0xff); |
||||
tmp |= AT91_PMC_MOR_KEY(0x37); |
||||
writel(tmp, &pmc->mor); |
||||
|
||||
tmp = readl(&pmc->mor); |
||||
tmp |= AT91_PMC_MOR_MOSCSEL; |
||||
tmp &= ~AT91_PMC_MOR_KEY(0xff); |
||||
tmp |= AT91_PMC_MOR_KEY(0x37); |
||||
writel(tmp, &pmc->mor); |
||||
|
||||
while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS)) |
||||
; |
||||
|
||||
/* Wait until MAINRDY field is set to make sure main clock is stable */ |
||||
while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY)) |
||||
; |
||||
|
||||
tmp = readl(&pmc->mor); |
||||
tmp &= ~AT91_PMC_MOR_MOSCRCEN; |
||||
tmp &= ~AT91_PMC_MOR_KEY(0xff); |
||||
tmp |= AT91_PMC_MOR_KEY(0x37); |
||||
writel(tmp, &pmc->mor); |
||||
} |
||||
|
||||
void s_init(void) |
||||
{ |
||||
switch_to_main_crystal_osc(); |
||||
|
||||
/* disable watchdog */ |
||||
at91_disable_wdt(); |
||||
|
||||
/* PMC configuration */ |
||||
at91_pmc_init(); |
||||
|
||||
at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); |
||||
|
||||
timer_init(); |
||||
|
||||
board_early_init_f(); |
||||
|
||||
preloader_console_init(); |
||||
|
||||
mem_init(); |
||||
} |
Loading…
Reference in new issue