mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-07-05 18:56:15 +09:00
arm, spl, at91: add at91sam9260 and at91sam9g45 spl support
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>
This commit is contained in:
parent
667af36905
commit
5abc00d020
|
@ -8,8 +8,10 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <asm/arch/at91sam9260_matrix.h>
|
||||||
#include <asm/arch/at91_common.h>
|
#include <asm/arch/at91_common.h>
|
||||||
#include <asm/arch/at91_pmc.h>
|
#include <asm/arch/at91_pmc.h>
|
||||||
|
#include <asm/arch/at91sam9_sdramc.h>
|
||||||
#include <asm/arch/gpio.h>
|
#include <asm/arch/gpio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -207,3 +209,23 @@ void at91_mci_hw_init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void at91_sdram_hw_init(void)
|
||||||
|
{
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 16, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 17, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 18, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 19, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 20, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 21, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 22, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 23, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 24, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 25, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 26, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 27, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 28, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 29, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 30, 0);
|
||||||
|
at91_set_a_periph(AT91_PIO_PORTC, 31, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -187,3 +187,63 @@ int at91_clock_init(unsigned long main_clock)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(AT91_PLL_LOCK_TIMEOUT)
|
||||||
|
#define AT91_PLL_LOCK_TIMEOUT 1000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void at91_plla_init(u32 pllar)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
int timeout = AT91_PLL_LOCK_TIMEOUT;
|
||||||
|
|
||||||
|
writel(pllar, &pmc->pllar);
|
||||||
|
while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) {
|
||||||
|
timeout--;
|
||||||
|
if (timeout == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void at91_pllb_init(u32 pllbr)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
int timeout = AT91_PLL_LOCK_TIMEOUT;
|
||||||
|
|
||||||
|
writel(pllbr, &pmc->pllbr);
|
||||||
|
while (!(readl(&pmc->sr) & (AT91_PMC_LOCKB | AT91_PMC_MCKRDY))) {
|
||||||
|
timeout--;
|
||||||
|
if (timeout == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void at91_mck_init(u32 mckr)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
int timeout = AT91_PLL_LOCK_TIMEOUT;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
tmp = readl(&pmc->mckr);
|
||||||
|
tmp &= ~(AT91_PMC_MCKR_PRES_MASK |
|
||||||
|
AT91_PMC_MCKR_MDIV_MASK |
|
||||||
|
AT91_PMC_MCKR_PLLADIV_MASK |
|
||||||
|
AT91_PMC_MCKR_CSS_MASK);
|
||||||
|
tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK |
|
||||||
|
AT91_PMC_MCKR_MDIV_MASK |
|
||||||
|
AT91_PMC_MCKR_PLLADIV_MASK |
|
||||||
|
AT91_PMC_MCKR_CSS_MASK);
|
||||||
|
writel(tmp, &pmc->mckr);
|
||||||
|
|
||||||
|
while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) {
|
||||||
|
timeout--;
|
||||||
|
if (timeout == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void at91_periph_clk_enable(int id)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
|
||||||
|
writel(1 << id, &pmc->pcer);
|
||||||
|
}
|
||||||
|
|
|
@ -111,6 +111,35 @@ int at91_clock_init(unsigned long main_clock)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void at91_plla_init(u32 pllar)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
|
||||||
|
writel(pllar, &pmc->pllar);
|
||||||
|
while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void at91_mck_init(u32 mckr)
|
||||||
|
{
|
||||||
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
tmp = readl(&pmc->mckr);
|
||||||
|
tmp &= ~(AT91_PMC_MCKR_CSS_MASK |
|
||||||
|
AT91_PMC_MCKR_PRES_MASK |
|
||||||
|
AT91_PMC_MCKR_MDIV_MASK |
|
||||||
|
AT91_PMC_MCKR_PLLADIV_2);
|
||||||
|
tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK |
|
||||||
|
AT91_PMC_MCKR_PRES_MASK |
|
||||||
|
AT91_PMC_MCKR_MDIV_MASK |
|
||||||
|
AT91_PMC_MCKR_PLLADIV_2);
|
||||||
|
writel(tmp, &pmc->mckr);
|
||||||
|
|
||||||
|
while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
void at91_periph_clk_enable(int id)
|
void at91_periph_clk_enable(int id)
|
||||||
{
|
{
|
||||||
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o
|
obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o
|
||||||
ifneq ($(CONFIG_SPL_BUILD),)
|
ifneq ($(CONFIG_SPL_BUILD),)
|
||||||
obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o
|
obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o
|
||||||
obj-$(CONFIG_SAMA5D3) += mpddrc.o
|
obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o
|
||||||
|
obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o
|
||||||
obj-y += spl.o
|
obj-y += spl.o
|
||||||
endif
|
endif
|
||||||
|
|
77
arch/arm/cpu/at91-common/sdram.c
Normal file
77
arch/arm/cpu/at91-common/sdram.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -8,89 +8,17 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/arch/at91_common.h>
|
#include <asm/arch/at91_common.h>
|
||||||
#include <asm/arch/at91_pmc.h>
|
|
||||||
#include <asm/arch/at91_wdt.h>
|
#include <asm/arch/at91_wdt.h>
|
||||||
#include <asm/arch/clk.h>
|
#include <asm/arch/clk.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
|
|
||||||
static void at91_disable_wdt(void)
|
void at91_disable_wdt(void)
|
||||||
{
|
{
|
||||||
struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
|
struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
|
||||||
|
|
||||||
writel(AT91_WDT_MR_WDDIS, &wdt->mr);
|
writel(AT91_WDT_MR_WDDIS, &wdt->mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 at91_plla_init(u32 pllar)
|
|
||||||
{
|
|
||||||
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
|
||||||
|
|
||||||
writel(pllar, &pmc->pllar);
|
|
||||||
while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void at91_mck_init(u32 mckr)
|
|
||||||
{
|
|
||||||
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
|
|
||||||
u32 tmp;
|
|
||||||
|
|
||||||
tmp = readl(&pmc->mckr);
|
|
||||||
tmp &= ~(AT91_PMC_MCKR_CSS_MASK |
|
|
||||||
AT91_PMC_MCKR_PRES_MASK |
|
|
||||||
AT91_PMC_MCKR_MDIV_MASK |
|
|
||||||
AT91_PMC_MCKR_PLLADIV_2);
|
|
||||||
tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK |
|
|
||||||
AT91_PMC_MCKR_PRES_MASK |
|
|
||||||
AT91_PMC_MCKR_MDIV_MASK |
|
|
||||||
AT91_PMC_MCKR_PLLADIV_2);
|
|
||||||
writel(tmp, &pmc->mckr);
|
|
||||||
|
|
||||||
while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
u32 spl_boot_device(void)
|
u32 spl_boot_device(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SYS_USE_MMC
|
#ifdef CONFIG_SYS_USE_MMC
|
||||||
|
@ -116,24 +44,3 @@ u32 spl_boot_mode(void)
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
124
arch/arm/cpu/at91-common/spl_at91.c
Normal file
124
arch/arm/cpu/at91-common/spl_at91.c
Normal file
|
@ -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();
|
||||||
|
}
|
80
arch/arm/cpu/at91-common/spl_atmel.c
Normal file
80
arch/arm/cpu/at91-common/spl_atmel.c
Normal file
|
@ -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();
|
||||||
|
}
|
|
@ -23,9 +23,15 @@ void at91_udp_hw_init(void);
|
||||||
void at91_uhp_hw_init(void);
|
void at91_uhp_hw_init(void);
|
||||||
void at91_lcd_hw_init(void);
|
void at91_lcd_hw_init(void);
|
||||||
void at91_plla_init(u32 pllar);
|
void at91_plla_init(u32 pllar);
|
||||||
|
void at91_pllb_init(u32 pllar);
|
||||||
void at91_mck_init(u32 mckr);
|
void at91_mck_init(u32 mckr);
|
||||||
void at91_pmc_init(void);
|
void at91_pmc_init(void);
|
||||||
void mem_init(void);
|
void mem_init(void);
|
||||||
void at91_phy_reset(void);
|
void at91_phy_reset(void);
|
||||||
|
void at91_sdram_hw_init(void);
|
||||||
|
void at91_mck_init(u32 mckr);
|
||||||
|
void at91_spl_board_init(void);
|
||||||
|
void at91_disable_wdt(void);
|
||||||
|
void matrix_init(void);
|
||||||
|
|
||||||
#endif /* AT91_COMMON_H */
|
#endif /* AT91_COMMON_H */
|
||||||
|
|
|
@ -133,6 +133,7 @@ typedef struct at91_pmc {
|
||||||
#define AT91_PMC_MCKR_MDIV_MASK 0x00000300
|
#define AT91_PMC_MCKR_MDIV_MASK 0x00000300
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define AT91_PMC_MCKR_PLLADIV_MASK 0x00003000
|
||||||
#define AT91_PMC_MCKR_PLLADIV_1 0x00000000
|
#define AT91_PMC_MCKR_PLLADIV_1 0x00000000
|
||||||
#define AT91_PMC_MCKR_PLLADIV_2 0x00001000
|
#define AT91_PMC_MCKR_PLLADIV_2 0x00001000
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
#define ATMEL_BASE_SDRAMC 0xffffea00
|
#define ATMEL_BASE_SDRAMC 0xffffea00
|
||||||
#define ATMEL_BASE_SMC 0xffffec00
|
#define ATMEL_BASE_SMC 0xffffec00
|
||||||
#define ATMEL_BASE_MATRIX 0xffffee00
|
#define ATMEL_BASE_MATRIX 0xffffee00
|
||||||
|
#define ATMEL_BASE_CCFG 0xffffef14
|
||||||
#define ATMEL_BASE_AIC 0xfffff000
|
#define ATMEL_BASE_AIC 0xfffff000
|
||||||
#define ATMEL_BASE_DBGU 0xfffff200
|
#define ATMEL_BASE_DBGU 0xfffff200
|
||||||
#define ATMEL_BASE_PIOA 0xfffff400
|
#define ATMEL_BASE_PIOA 0xfffff400
|
||||||
|
|
|
@ -61,5 +61,10 @@ struct at91_matrix {
|
||||||
#define AT91_MATRIX_DBPUC (1 << 8)
|
#define AT91_MATRIX_DBPUC (1 << 8)
|
||||||
#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
|
#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
|
||||||
#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
|
#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
|
||||||
|
#define AT91_MATRIX_EBI_IOSR_SEL (1 << 17)
|
||||||
|
|
||||||
|
/* Maximum Number of Allowed Cycles for a Burst */
|
||||||
|
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0)
|
||||||
|
#define AT91_MATRIX_SLOT_CYCLE_(x) (x << 0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,6 +25,21 @@
|
||||||
#define AT91_ASM_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08)
|
#define AT91_ASM_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08)
|
||||||
#define AT91_ASM_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24)
|
#define AT91_ASM_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24)
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct sdramc_reg {
|
||||||
|
u32 mr;
|
||||||
|
u32 tr;
|
||||||
|
u32 cr;
|
||||||
|
u32 lpr;
|
||||||
|
u32 ier;
|
||||||
|
u32 idr;
|
||||||
|
u32 imr;
|
||||||
|
u32 isr;
|
||||||
|
u32 mdr;
|
||||||
|
};
|
||||||
|
|
||||||
|
int sdramc_initialize(unsigned int sdram_address,
|
||||||
|
const struct sdramc_reg *p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SDRAM Controller (SDRAMC) registers */
|
/* SDRAM Controller (SDRAMC) registers */
|
||||||
|
@ -62,11 +77,17 @@
|
||||||
#define AT91_SDRAMC_DBW_32 (0 << 7)
|
#define AT91_SDRAMC_DBW_32 (0 << 7)
|
||||||
#define AT91_SDRAMC_DBW_16 (1 << 7)
|
#define AT91_SDRAMC_DBW_16 (1 << 7)
|
||||||
#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */
|
#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */
|
||||||
|
#define AT91_SDRAMC_TWR_VAL(x) (x << 8)
|
||||||
#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */
|
#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */
|
||||||
|
#define AT91_SDRAMC_TRC_VAL(x) (x << 12)
|
||||||
#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */
|
#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */
|
||||||
|
#define AT91_SDRAMC_TRP_VAL(x) (x << 16)
|
||||||
#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */
|
#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */
|
||||||
|
#define AT91_SDRAMC_TRCD_VAL(x) (x << 20)
|
||||||
#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */
|
#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */
|
||||||
|
#define AT91_SDRAMC_TRAS_VAL(x) (x << 24)
|
||||||
#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */
|
#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */
|
||||||
|
#define AT91_SDRAMC_TXSR_VAL(x) (x << 28)
|
||||||
|
|
||||||
#define AT91_SDRAMC_LPR (ATMEL_BASE_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */
|
#define AT91_SDRAMC_LPR (ATMEL_BASE_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */
|
||||||
#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */
|
#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */
|
||||||
|
@ -93,5 +114,4 @@
|
||||||
#define AT91_SDRAMC_MD_SDRAM 0
|
#define AT91_SDRAMC_MD_SDRAM 0
|
||||||
#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1
|
#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user