[U-Boot] [RFC PATCH 0/7] arm: atmel: sama5d3: enable spl boot from SD card

This patch series enable spl boot from SD card, it only can boot u-boot itself.
Bo Shen (7): arm: atmel: sama5d3: early enable PIO peripherals arm: atmel: sama5d3: correct the ID for DBGU and PIT arm: atmel: the offset of MULA is 18 in sama5d3 arm: atmel: sama5: correct the error define of DIV arm: atmel: add plla and mck initialize function arm: atmel: add ddr2 initialization function spl: mmc: FAT support boot u-boot
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/Makefile | 1 + arch/arm/cpu/armv7/at91/clock.c | 27 ++++++ arch/arm/cpu/armv7/at91/mpddrc.c | 123 ++++++++++++++++++++++++ arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- arch/arm/cpu/armv7/at91/u-boot-spl.lds | 50 ++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 2 + arch/arm/include/asm/arch-at91/at91_pmc.h | 8 +- arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 111 ++++++++++++++++++++++ arch/arm/include/asm/arch-at91/spl.h | 17 ++++ board/atmel/sama5d3xek/sama5d3xek.c | 126 +++++++++++++++++++++++++ include/configs/sama5d3xek.h | 37 ++++++++ 13 files changed, 503 insertions(+), 5 deletions(-) create mode 100644 arch/arm/cpu/armv7/at91/mpddrc.c create mode 100644 arch/arm/cpu/armv7/at91/u-boot-spl.lds create mode 100644 arch/arm/include/asm/arch-at91/atmel_mpddrc.h create mode 100644 arch/arm/include/asm/arch-at91/spl.h

Enable the PIO peripherals early that other peripherals.
Signed-off-by: Bo Shen voice.shen@atmel.com --- board/atmel/sama5d3xek/sama5d3xek.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef..7fa3ae7 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -158,6 +158,9 @@ void lcd_show_board_info(void)
int board_early_init_f(void) { + at91_periph_clk_enable(ATMEL_ID_PIOA | ATMEL_ID_PIOB | ATMEL_ID_PIOC | + ATMEL_ID_PIOD | ATMEL_ID_PIOE); + at91_seriald_hw_init();
return 0;

Hello bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
Enable the PIO peripherals early that other peripherals.
Signed-off-by: Bo Shenvoice.shen@atmel.com
board/atmel/sama5d3xek/sama5d3xek.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef..7fa3ae7 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -158,6 +158,9 @@ void lcd_show_board_info(void)
int board_early_init_f(void) {
at91_periph_clk_enable(ATMEL_ID_PIOA | ATMEL_ID_PIOB | ATMEL_ID_PIOC |
ATMEL_ID_PIOD | ATMEL_ID_PIOE);
at91_seriald_hw_init();
return 0;
Hmm.. you do this board specific. I think, we should make there a more generic approach.
Could we create here a
arch/arm/cpu/arm926ejs/at91/spl.c
and collect such common code?
This comment aplly also for your patch: http://patchwork.ozlabs.org/patch/287165/
bye, Heiko

Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
Enable the PIO peripherals early that other peripherals.
Signed-off-by: Bo Shen voice.shen@atmel.com
board/atmel/sama5d3xek/sama5d3xek.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef..7fa3ae7 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -158,6 +158,9 @@ void lcd_show_board_info(void)
int board_early_init_f(void) {
- at91_periph_clk_enable(ATMEL_ID_PIOA | ATMEL_ID_PIOB | ATMEL_ID_PIOC |
ATMEL_ID_PIOD | ATMEL_ID_PIOE);
that should be done in some SPL specific 'main()'. I dunno which is the entry point for SPL, but we should provide such a function and there should we do such stuff.
Best regards
Andreas Bießmann

Hi Andreas,
On 10/30/2013 19:11, Andreas Bießmann wrote:
Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
Enable the PIO peripherals early that other peripherals.
Signed-off-by: Bo Shen voice.shen@atmel.com
board/atmel/sama5d3xek/sama5d3xek.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef..7fa3ae7 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -158,6 +158,9 @@ void lcd_show_board_info(void)
int board_early_init_f(void) {
- at91_periph_clk_enable(ATMEL_ID_PIOA | ATMEL_ID_PIOB | ATMEL_ID_PIOC |
ATMEL_ID_PIOD | ATMEL_ID_PIOE);
that should be done in some SPL specific 'main()'. I dunno which is the entry point for SPL, but we should provide such a function and there should we do such stuff.
As before, we depends on the at91bootstrap to enable the PIO clock. Now, I think we need to enable PIO clock in u-boot by itself. So, we need this.
Best regards
Andreas Bießmann
Best Regards, Bo Shen

As the DBGU and PIT has its own ID on sama5d3 SoC, while not share with SYS ID. So, correct them.
Signed-off-by: Bo Shen voice.shen@atmel.com --- arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c index 51f0a6d..ebe99d2 100644 --- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c +++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c @@ -82,7 +82,7 @@ void at91_seriald_hw_init(void) at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */
/* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_SYS); + at91_periph_clk_enable(ATMEL_ID_DBGU); }
#if defined(CONFIG_ATMEL_SPI) diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c index 3808aed..e3ebfe0 100644 --- a/arch/arm/cpu/armv7/at91/timer.c +++ b/arch/arm/cpu/armv7/at91/timer.c @@ -60,7 +60,7 @@ int timer_init(void) at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
/* Enable PITC Clock */ - at91_periph_clk_enable(ATMEL_ID_SYS); + at91_periph_clk_enable(ATMEL_ID_PIT);
/* Enable PITC */ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);

Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
As the DBGU and PIT has its own ID on sama5d3 SoC, while not share with SYS ID. So, correct them.
Signed-off-by: Bo Shen voice.shen@atmel.com
arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c index 51f0a6d..ebe99d2 100644 --- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c +++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c @@ -82,7 +82,7 @@ void at91_seriald_hw_init(void) at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */
/* Enable clock */
- at91_periph_clk_enable(ATMEL_ID_SYS);
- at91_periph_clk_enable(ATMEL_ID_DBGU);
}
#if defined(CONFIG_ATMEL_SPI) diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c index 3808aed..e3ebfe0 100644 --- a/arch/arm/cpu/armv7/at91/timer.c +++ b/arch/arm/cpu/armv7/at91/timer.c @@ -60,7 +60,7 @@ int timer_init(void) at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
/* Enable PITC Clock */
- at91_periph_clk_enable(ATMEL_ID_SYS);
at91_periph_clk_enable(ATMEL_ID_PIT);
/* Enable PITC */ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
I think these two are generic bug fixes, could you please send them as not RFC for inclusion?
Best regards
Andreas Bießmann

Hi Andreas,
On 10/30/2013 19:12, Andreas Bießmann wrote:
Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
As the DBGU and PIT has its own ID on sama5d3 SoC, while not share with SYS ID. So, correct them.
Signed-off-by: Bo Shen voice.shen@atmel.com
arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c index 51f0a6d..ebe99d2 100644 --- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c +++ b/arch/arm/cpu/armv7/at91/sama5d3_devices.c @@ -82,7 +82,7 @@ void at91_seriald_hw_init(void) at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */
/* Enable clock */
- at91_periph_clk_enable(ATMEL_ID_SYS);
at91_periph_clk_enable(ATMEL_ID_DBGU); }
#if defined(CONFIG_ATMEL_SPI)
diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c index 3808aed..e3ebfe0 100644 --- a/arch/arm/cpu/armv7/at91/timer.c +++ b/arch/arm/cpu/armv7/at91/timer.c @@ -60,7 +60,7 @@ int timer_init(void) at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT;
/* Enable PITC Clock */
- at91_periph_clk_enable(ATMEL_ID_SYS);
at91_periph_clk_enable(ATMEL_ID_PIT);
/* Enable PITC */ writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
I think these two are generic bug fixes, could you please send them as not RFC for inclusion?
OK, I will remove RFC for inclusion in v2.
Best regards
Andreas Bießmann
Best Regards, Bo Shen

The offset of MULA field in PLLA register in sama5d3 is 18, and the length only 7 bits.
Signed-off-by: Bo Shen voice.shen@atmel.com --- arch/arm/include/asm/arch-at91/at91_pmc.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h index 003920c..0d82960 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -73,7 +73,11 @@ typedef struct at91_pmc { #define AT91_PMC_PLLXR_DIV(x) (x & 0xFF) #define AT91_PMC_PLLXR_PLLCOUNT(x) ((x & 0x3F) << 8) #define AT91_PMC_PLLXR_OUT(x) ((x & 0x03) << 14) +#ifdef CONFIG_SAMA5D3 +#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7F) << 18) +#else #define AT91_PMC_PLLXR_MUL(x) ((x & 0x7FF) << 16) +#endif #define AT91_PMC_PLLAR_29 0x20000000 #define AT91_PMC_PLLBR_USBDIV_1 0x00000000 #define AT91_PMC_PLLBR_USBDIV_2 0x10000000

Correct the error define of DIV.
Signed-off-by: Bo Shen voice.shen@atmel.com --- arch/arm/include/asm/arch-at91/at91_pmc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h index 0d82960..c063213 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -128,8 +128,8 @@ typedef struct at91_pmc { #define AT91_PMC_MCKR_MDIV_MASK 0x00000300 #endif
-#define AT91_PMC_MCKR_PLLADIV_1 0x00001000 -#define AT91_PMC_MCKR_PLLADIV_2 0x00002000 +#define AT91_PMC_MCKR_PLLADIV_1 0x00000000 +#define AT91_PMC_MCKR_PLLADIV_2 0x00001000
#define AT91_PMC_IXR_MOSCS 0x00000001 #define AT91_PMC_IXR_LOCKA 0x00000002

Add plla and mck initialize function.
Signed-off-by: Bo Shen voice.shen@atmel.com --- arch/arm/cpu/armv7/at91/clock.c | 27 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 2 ++ 2 files changed, 29 insertions(+)
diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c index 1588e0c..ec92950 100644 --- a/arch/arm/cpu/armv7/at91/clock.c +++ b/arch/arm/cpu/armv7/at91/clock.c @@ -120,3 +120,30 @@ void at91_periph_clk_enable(int id) else writel(1 << id, &pmc->pcer); } + +void at91_plla_init(u32 pllar, int timeout) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + writel(pllar, &pmc->pllar); + while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) + timeout--; +} + +void at91_mck_init(u32 mckr, int timeout) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + 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); + + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + timeout--; +} diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index abcb97d..a692275 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -22,5 +22,7 @@ void at91_spi1_hw_init(unsigned long cs_mask); void at91_udp_hw_init(void); void at91_uhp_hw_init(void); void at91_lcd_hw_init(void); +void at91_plla_init(u32 pllar, int timeout); +void at91_mck_init(u32 mckr, int timeout);
#endif /* AT91_COMMON_H */

Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
Add plla and mck initialize function.
Signed-off-by: Bo Shen voice.shen@atmel.com
arch/arm/cpu/armv7/at91/clock.c | 27 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 2 ++ 2 files changed, 29 insertions(+)
diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c index 1588e0c..ec92950 100644 --- a/arch/arm/cpu/armv7/at91/clock.c +++ b/arch/arm/cpu/armv7/at91/clock.c @@ -120,3 +120,30 @@ void at91_periph_clk_enable(int id) else writel(1 << id, &pmc->pcer); }
+void at91_plla_init(u32 pllar, int timeout) +{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- writel(pllar, &pmc->pllar);
- while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
timeout--;
I do not understand use of this timeout here ... You do not check it nor return something ... It would make sense to add an check into the wile() and return upon the state of timeout true/false. This however is not needed here cause we either succeed to setup the PLL or not. If not we could not proceed anyways, so why check it here?
In connection with a watchdog it could make sense to kick it while waiting for PLL initialisation.
+}
+void at91_mck_init(u32 mckr, int timeout)
I wonder if it would make sense to abstract the functionality of mckr to the function parameters. Something like 'I want to set 400MHz, do it for me'. Maybe this doesn't make any sense, lets discuss.
+{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- u32 tmp;
- 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);
- while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
timeout--;
+} diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index abcb97d..a692275 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -22,5 +22,7 @@ void at91_spi1_hw_init(unsigned long cs_mask); void at91_udp_hw_init(void); void at91_uhp_hw_init(void); void at91_lcd_hw_init(void); +void at91_plla_init(u32 pllar, int timeout); +void at91_mck_init(u32 mckr, int timeout);
#endif /* AT91_COMMON_H */

Hi Andreas,
On 10/30/2013 19:21, Andreas Bießmann wrote:
Hi Bo,
On 10/30/2013 10:15 AM, Bo Shen wrote:
Add plla and mck initialize function.
Signed-off-by: Bo Shen voice.shen@atmel.com
arch/arm/cpu/armv7/at91/clock.c | 27 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 2 ++ 2 files changed, 29 insertions(+)
diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c index 1588e0c..ec92950 100644 --- a/arch/arm/cpu/armv7/at91/clock.c +++ b/arch/arm/cpu/armv7/at91/clock.c @@ -120,3 +120,30 @@ void at91_periph_clk_enable(int id) else writel(1 << id, &pmc->pcer); }
+void at91_plla_init(u32 pllar, int timeout) +{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- writel(pllar, &pmc->pllar);
- while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
timeout--;
I do not understand use of this timeout here ... You do not check it nor return something ... It would make sense to add an check into the wile() and return upon the state of timeout true/false. This however is not needed here cause we either succeed to setup the PLL or not. If not we could not proceed anyways, so why check it here?
OK, I will remove this timeout here.
In connection with a watchdog it could make sense to kick it while waiting for PLL initialisation.
As watchdog is disabled, so can not use it.
+}
+void at91_mck_init(u32 mckr, int timeout)
I wonder if it would make sense to abstract the functionality of mckr to the function parameters. Something like 'I want to set 400MHz, do it for me'. Maybe this doesn't make any sense, lets discuss.
As the SoC can run in 132MHz * (2, 3, 4), if it runs in different frequency, the mckr configuration is different, so we need this function,
+{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- u32 tmp;
- 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);
- while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
timeout--;
+} diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index abcb97d..a692275 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -22,5 +22,7 @@ void at91_spi1_hw_init(unsigned long cs_mask); void at91_udp_hw_init(void); void at91_uhp_hw_init(void); void at91_lcd_hw_init(void); +void at91_plla_init(u32 pllar, int timeout); +void at91_mck_init(u32 mckr, int timeout);
#endif /* AT91_COMMON_H */
Best Regards, Bo Shen

The MPDDRC supports different type of SDRAM This patch add ddr2 initialization function
Signed-off-by: Bo Shen voice.shen@atmel.com --- arch/arm/cpu/armv7/at91/Makefile | 1 + arch/arm/cpu/armv7/at91/mpddrc.c | 123 +++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 111 ++++++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 arch/arm/cpu/armv7/at91/mpddrc.c create mode 100644 arch/arm/include/asm/arch-at91/atmel_mpddrc.h
diff --git a/arch/arm/cpu/armv7/at91/Makefile b/arch/arm/cpu/armv7/at91/Makefile index 90b9bd6..4a02d06 100644 --- a/arch/arm/cpu/armv7/at91/Makefile +++ b/arch/arm/cpu/armv7/at91/Makefile @@ -17,6 +17,7 @@ COBJS-y += clock.o COBJS-y += cpu.o COBJS-y += reset.o COBJS-y += timer.o +COBJS-$(CONFIG_SPL_BUILD) += mpddrc.o
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/arm/cpu/armv7/at91/mpddrc.c b/arch/arm/cpu/armv7/at91/mpddrc.c new file mode 100644 index 0000000..1abde1e --- /dev/null +++ b/arch/arm/cpu/armv7/at91/mpddrc.c @@ -0,0 +1,123 @@ +/* + * 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/atmel_mpddrc.h> + +static void atmel_mpddr_op(int mode, u32 ram_address) +{ + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; + + writel(mode, &mpddr->mr); + writel(0, ram_address); +} + +int ddr2_init(u32 ram_address, struct atmel_mpddr *mpddr_value) +{ + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; + u32 ba_off, cr; + + /* Compute bank offset according to NC in configuration register */ + ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; + if (!(mpddr_value->cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED)) + ba_off += ((mpddr->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; + + ba_off += (mpddr_value->mdr & ATMEL_MPDDRC_MDR_DBW_MASK) ? 1 : 2; + + /* Program the memory device type into the memory device register */ + writel(mpddr_value->mdr, &mpddr->mdr); + + /* Program the configuration register */ + writel(mpddr_value->cr, &mpddr->cr); + + /* Program the timing register */ + writel(mpddr_value->tp0r, &mpddr->tp0r); + writel(mpddr_value->tp1r, &mpddr->tp1r); + writel(mpddr_value->tp2r, &mpddr->tp2r); + + /* Issue a NOP command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_NOP_CMD, ram_address); + + /* A 200 us is provided to precede any signal toggle */ + udelay(200); + + /* Issue a NOP command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_NOP_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_PRCGALL_CMD, ram_address); + + /* Issue an extended mode register set(EMRS2) to choose operation */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_EXT_LMR_CMD, + ram_address + (0x2 << ba_off)); + + /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_EXT_LMR_CMD, + ram_address + (0x3 << ba_off)); + + /* + * Issue an extended mode register set(EMRS1) to enable DLL and + * program D.I.C (output driver impedance control) + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* Enable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr | ATMEL_MPDDRC_CR_EN_RESET_DLL, &mpddr->cr); + + /* A mode register set(MRS) cycle is issued to reset DLL */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_LMR_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_PRCGALL_CMD, ram_address); + + /* Two auto-refresh (CBR) cycles are provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_RFSH_CMD, ram_address); + atmel_mpddr_op(ATMEL_MPDDRC_MR_RFSH_CMD, ram_address); + + /* Disable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr & (~ATMEL_MPDDRC_CR_EN_RESET_DLL), &mpddr->cr); + + /* A mode register set (MRS) cycle is issued to disable DLL reset */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_LMR_CMD, ram_address); + + /* Set OCD calibration in defautl state */ + cr = readl(&mpddr->cr); + writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr); + + /* + * An extended mode register set (EMRS1) cycle is issued + * to OCD default value + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* OCD calibration mode exit */ + cr = readl(&mpddr->cr); + writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr); + + /* + * An extended mode register set (EMRS1) cycle is issued + * to enable OCD exit + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* A nornal mode command is provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_NORMAL_CMD, ram_address); + + /* Perform a write access to any DDR2-SDRAM address */ + writel(0, ram_address); + + /* Write the refresh rate */ + writel(mpddr_value->rtr, &mpddr->rtr); + + return 0; +} diff --git a/arch/arm/include/asm/arch-at91/atmel_mpddrc.h b/arch/arm/include/asm/arch-at91/atmel_mpddrc.h new file mode 100644 index 0000000..abd8b68 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/atmel_mpddrc.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen voice.shen@atmel.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ATMEL_MPDDRC_H__ +#define __ATMEL_MPDDRC_H__ + +struct atmel_mpddr { + u32 mr; + u32 rtr; + u32 cr; + u32 tp0r; + u32 tp1r; + u32 tp2r; + u32 reserved[2]; + u32 mdr; +}; + +int ddr2_init(unsigned int ram_address, + struct atmel_mpddr *mpddr); + +/* bit field in mode register */ +#define ATMEL_MPDDRC_MR_NORMAL_CMD 0x0 +#define ATMEL_MPDDRC_MR_NOP_CMD 0x1 +#define ATMEL_MPDDRC_MR_PRCGALL_CMD 0x2 +#define ATMEL_MPDDRC_MR_LMR_CMD 0x3 +#define ATMEL_MPDDRC_MR_RFSH_CMD 0x4 +#define ATMEL_MPDDRC_MR_EXT_LMR_CMD 0x5 +#define ATMEL_MPDDRC_MR_DEEP_CMD 0x6 +#define ATMEL_MPDDRC_MR_LPDDR2_CMD 0x7 + +/* bit field in configuration register */ +#define ATMEL_MPDDRC_CR_NC_MASK 0x3 +#define ATMEL_MPDDRC_CR_NC_COL_9 0x0 +#define ATMEL_MPDDRC_CR_NC_COL_10 0x1 +#define ATMEL_MPDDRC_CR_NC_COL_11 0x2 +#define ATMEL_MPDDRC_CR_NC_COL_12 0x3 +#define ATMEL_MPDDRC_CR_NR_MASK (0x3 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_11 (0x0 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_12 (0x1 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_13 (0x2 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_14 (0x3 << 2) +#define ATMEL_MPDDRC_CR_CAS (0x7 << 4) +#define ATMEL_MPDDRC_CR_CAS_2 (0x2 << 4) +#define ATMEL_MPDDRC_CR_CAS_3 (0x3 << 4) +#define ATMEL_MPDDRC_CR_CAS_4 (0x4 << 4) +#define ATMEL_MPDDRC_CR_CAS_5 (0x5 << 4) +#define ATMEL_MPDDRC_CR_CAS_6 (0x6 << 4) +#define ATMEL_MPDDRC_CR_EN_RESET_DLL (0x1 << 7) +#define ATMEL_MPDDRC_CR_DIC_DS (0x1 << 8) +#define ATMEL_MPDDRC_CR_DIS_DLL (0x1 << 9) +#define ATMEL_MPDDRC_CR_OCD_DEFAULT (0x7 << 12) +#define ATMEL_MPDDRC_CR_EN_ENRDM (0x1 << 17) +#define ATMEL_MPDDRC_CR_NB_8BANKS (0x1 << 20) +#define ATMEL_MPDDRC_CR_DIS_NDQS (0x1 << 21) +#define ATMEL_MPDDRC_CR_DECOD_INTERLEAVED (0x1 << 22) +#define ATMEL_MPDDRC_CR_UNAL_SUPPORTED (0x1 << 23) + +/* bit field in timing parameter 0 register */ +#define ATMEL_MPDDRC_TP0R_TRAS_OFFSET 0 +#define ATMEL_MPDDRC_TP0R_TRAS_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TRCD_OFFSET 4 +#define ATMEL_MPDDRC_TP0R_TRCD_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TWR_OFFSET 8 +#define ATMEL_MPDDRC_TP0R_TWR_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TRC_OFFSET 12 +#define ATMEL_MPDDRC_TP0R_TRC_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TRP_OFFSET 16 +#define ATMEL_MPDDRC_TP0R_TRP_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TRRD_OFFSET 20 +#define ATMEL_MPDDRC_TP0R_TRRD_MASK 0xf +#define ATMEL_MPDDRC_TP0R_TWTR_OFFSET 24 +#define ATMEL_MPDDRC_TP0R_TWTR_MASK 0x7 +#define ATMEL_MPDDRC_TP0R_RDC_WRRD_OFFSET 27 +#define ATMEL_MPDDRC_TP0R_RDC_WRRD_MASK 0x1 +#define ATMEL_MPDDRC_TP0R_TMRD_OFFSET 28 +#define ATMEL_MPDDRC_TP0R_TMRD_MASK 0xf + +/* bit field in timing parameter 1 register */ +#define ATMEL_MPDDRC_TP1R_TRFC_OFFSET 0 +#define ATMEL_MPDDRC_TP1R_TRFC_MASK 0x7f +#define ATMEL_MPDDRC_TP1R_TXSNR_OFFSET 8 +#define ATMEL_MPDDRC_TP1R_TXSNR_MASK 0xff +#define ATMEL_MPDDRC_TP1R_TXSRD_OFFSET 16 +#define ATMEL_MPDDRC_TP1R_TXSRD_MASK 0xff +#define ATMEL_MPDDRC_TP1R_TXP_OFFSET 24 +#define ATMEL_MPDDRC_TP1R_TXP_MASK 0xf + +/* bit field in timing parameter 2 register */ +#define ATMEL_MPDDRC_TP2R_TXARD_OFFSET 0 +#define ATMEL_MPDDRC_TP2R_TXARD_MASK 0xf +#define ATMEL_MPDDRC_TP2R_TXARDS_OFFSET 4 +#define ATMEL_MPDDRC_TP2R_TXARDS_MASK 0xf +#define ATMEL_MPDDRC_TP2R_TRPA_OFFSET 8 +#define ATMEL_MPDDRC_TP2R_TRPA_MASK 0xf +#define ATMEL_MPDDRC_TP2R_TRTP_OFFSET 12 +#define ATMEL_MPDDRC_TP2R_TRTP_MASK 0x7 +#define ATMEL_MPDDRC_TP2R_TFAW_OFFSET 16 +#define ATMEL_MPDDRC_TP2R_TFAW_MASK 0xf + +/* bit field in Memory Device Register */ +#define ATMEL_MPDDRC_MDR_LPDDR_SDRAM 0x3 +#define ATMEL_MPDDRC_MDR_DDR2_SDRAM 0x6 +#define ATMEL_MPDDRC_MDR_DBW_MASK (0x1 << 4) +#define ATMEL_MPDDRC_MDR_DBW_32BITS (0x0 << 4) +#define ATMEL_MPDDRC_MDR_DBW_16BITS (0x1 << 4) + +#endif

Enable SPL support which can load u-boot from SD card in FAT format.
Signed-off-by: Bo Shen voice.shen@atmel.com
--- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/u-boot-spl.lds | 50 +++++++++++++ arch/arm/include/asm/arch-at91/spl.h | 17 +++++ board/atmel/sama5d3xek/sama5d3xek.c | 123 ++++++++++++++++++++++++++++++++ include/configs/sama5d3xek.h | 37 ++++++++++ 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/at91/u-boot-spl.lds create mode 100644 arch/arm/include/asm/arch-at91/spl.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index ee4b021..4246f1f 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -16,7 +16,7 @@ COBJS += cache_v7.o COBJS += cpu.o COBJS += syslib.o
-ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX),) +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_SAMA5D3),) SOBJS += lowlevel_init.o endif
diff --git a/arch/arm/cpu/armv7/at91/u-boot-spl.lds b/arch/arm/cpu/armv7/at91/u-boot-spl.lds new file mode 100644 index 0000000..038335d --- /dev/null +++ b/arch/arm/cpu/armv7/at91/u-boot-spl.lds @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V aneesh@ti.com + * + * (C) 2013 Atmel Corporation + * Bo Shen voice.shen@atmel.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + __image_copy_end = .; + _end = .; + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +} diff --git a/arch/arm/include/asm/arch-at91/spl.h b/arch/arm/include/asm/arch-at91/spl.h new file mode 100644 index 0000000..5bbd4fc --- /dev/null +++ b/arch/arm/include/asm/arch-at91/spl.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen voice.shen@atmel.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_ARCH_SPL_H_ + +enum { + BOOT_DEVICE_MMC1, + BOOT_DEVICE_MMC2, + BOOT_DEVICE_MMC2_2, +}; + +#endif diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index 7fa3ae7..4a5aea3 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -20,6 +20,9 @@ #include <micrel.h> #include <net.h> #include <netdev.h> +#include <spl.h> +#include <asm/arch/atmel_mpddrc.h> +#include <asm/arch/at91_wdt.h>
#ifdef CONFIG_USB_GADGET_ATMEL_USBA #include <asm/arch/atmel_usba_udc.h> @@ -293,3 +296,123 @@ void spi_cs_deactivate(struct spi_slave *slave) } } #endif /* CONFIG_ATMEL_SPI */ + +/* NAND SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ + sama5d3xek_mci_hw_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_MMC1; +} + +u32 spl_boot_mode(void) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_FAT; + break; + default: + hang(); + } +} + +void ddr2_conf(struct atmel_mpddr *ddr2) +{ + ddr2->mdr = (ATMEL_MPDDRC_MDR_DBW_32BITS | ATMEL_MPDDRC_MDR_DDR2_SDRAM); + + ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_3 | + ATMEL_MPDDRC_CR_EN_ENRDM | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_DIS_NDQS | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + + ddr2->rtr = 0x411; + + ddr2->tp0r = (6 << ATMEL_MPDDRC_TP0R_TRAS_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TRCD_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TWR_OFFSET | + 8 << ATMEL_MPDDRC_TP0R_TRC_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TRP_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TRRD_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TWTR_OFFSET | + 2 << ATMEL_MPDDRC_TP0R_TMRD_OFFSET); + + ddr2->tp1r = (2 << ATMEL_MPDDRC_TP1R_TXP_OFFSET | + 200 << ATMEL_MPDDRC_TP1R_TXSRD_OFFSET | + 28 << ATMEL_MPDDRC_TP1R_TXSNR_OFFSET | + 26 << ATMEL_MPDDRC_TP1R_TRFC_OFFSET); + + ddr2->tp2r = (7 << ATMEL_MPDDRC_TP2R_TFAW_OFFSET | + 2 << ATMEL_MPDDRC_TP2R_TRTP_OFFSET | + 2 << ATMEL_MPDDRC_TP2R_TRPA_OFFSET | + 7 << ATMEL_MPDDRC_TP2R_TXARDS_OFFSET | + 8 << ATMEL_MPDDRC_TP2R_TXARD_OFFSET); +} + +void mem_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + struct atmel_mpddr ddr2; + + ddr2_conf(&ddr2); + + /* enable MPDDR clock */ + at91_periph_clk_enable(ATMEL_ID_MPDDRC); + writel(0x4, &pmc->scer); + + /* DDRAM2 Controller initialize */ + ddr2_init(ATMEL_BASE_DDRCS, &ddr2); +} + +static void at91_disable_wdt(void) +{ + struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; + + writel(AT91_WDT_MR_WDDIS, &wdt->mr); +} + +static void sama5d3xek_plla_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = AT91_PMC_PLLAR_29 | + AT91_PMC_PLLXR_PLLCOUNT(0x3f) | + AT91_PMC_PLLXR_MUL(43) | + AT91_PMC_PLLXR_DIV(1); + at91_plla_init(tmp, 10000); + + writel(0x3 << 8, &pmc->pllicpr); +} + +void s_init(void) +{ + u32 tmp; + + /* disable watchdog */ + at91_disable_wdt(); + + /* PMC configuration */ + sama5d3xek_plla_init(); + tmp = AT91_PMC_MCKR_MDIV_4 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp, 10000); + + at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); + + timer_init(); + + board_early_init_f(); + + preloader_console_init(); + + mem_init(); +} +#endif diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h index 79c0068..53ec27e 100644 --- a/include/configs/sama5d3xek.h +++ b/include/configs/sama5d3xek.h @@ -25,7 +25,10 @@ #define CONFIG_AT91FAMILY #define CONFIG_ARCH_CPU_INIT
+#ifndef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT +#endif + #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_DISPLAY_CPUINFO
@@ -94,8 +97,12 @@ #define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS #define CONFIG_SYS_SDRAM_SIZE 0x20000000
+#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_INIT_SP_ADDR 0x310000 +#else #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) +#endif
/* SerialFlash */ #define CONFIG_CMD_SF @@ -235,4 +242,34 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (1024 * 1024)
+/* SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK + +#define CONFIG_SPL_TEXT_BASE 0x300000 +#define CONFIG_SPL_MAX_SIZE 0x10000 + +#define CONFIG_SPL_BSS_START_ADDR 0x20000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 + +#define CONFIG_SYS_SPL_MALLOC_START 0x20080000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 + +#define CONFIG_SPL_LDSCRIPT $(CPUDIR)/at91/u-boot-spl.lds + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT + +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 +#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1 +#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img" + +#define CONFIG_SPL_FAT_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT + #endif

Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
Enable SPL support which can load u-boot from SD card in FAT format.
Signed-off-by: Bo Shenvoice.shen@atmel.com
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/u-boot-spl.lds | 50 +++++++++++++ arch/arm/include/asm/arch-at91/spl.h | 17 +++++ board/atmel/sama5d3xek/sama5d3xek.c | 123 ++++++++++++++++++++++++++++++++ include/configs/sama5d3xek.h | 37 ++++++++++ 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/at91/u-boot-spl.lds create mode 100644 arch/arm/include/asm/arch-at91/spl.h
[...]
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index 7fa3ae7..4a5aea3 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -20,6 +20,9 @@ #include<micrel.h> #include<net.h> #include<netdev.h> +#include<spl.h> +#include<asm/arch/atmel_mpddrc.h> +#include<asm/arch/at91_wdt.h>
#ifdef CONFIG_USB_GADGET_ATMEL_USBA #include<asm/arch/atmel_usba_udc.h> @@ -293,3 +296,123 @@ void spi_cs_deactivate(struct spi_slave *slave) } } #endif /* CONFIG_ATMEL_SPI */
+/* NAND SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{
- sama5d3xek_mci_hw_init();
+}
+u32 spl_boot_device(void) +{
- return BOOT_DEVICE_MMC1;
+}
+u32 spl_boot_mode(void) +{
- switch (spl_boot_device()) {
- case BOOT_DEVICE_MMC1:
return MMCSD_MODE_FAT;
break;
- default:
hang();
- }
+}
+void ddr2_conf(struct atmel_mpddr *ddr2) +{
- ddr2->mdr = (ATMEL_MPDDRC_MDR_DBW_32BITS | ATMEL_MPDDRC_MDR_DDR2_SDRAM);
- ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 |
ATMEL_MPDDRC_CR_NR_ROW_14 |
ATMEL_MPDDRC_CR_CAS_3 |
ATMEL_MPDDRC_CR_EN_ENRDM |
ATMEL_MPDDRC_CR_NB_8BANKS |
ATMEL_MPDDRC_CR_DIS_NDQS |
ATMEL_MPDDRC_CR_DECOD_INTERLEAVED |
ATMEL_MPDDRC_CR_UNAL_SUPPORTED);
- ddr2->rtr = 0x411;
- ddr2->tp0r = (6<< ATMEL_MPDDRC_TP0R_TRAS_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TRCD_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TWR_OFFSET |
8<< ATMEL_MPDDRC_TP0R_TRC_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TRP_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TRRD_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TWTR_OFFSET |
2<< ATMEL_MPDDRC_TP0R_TMRD_OFFSET);
- ddr2->tp1r = (2<< ATMEL_MPDDRC_TP1R_TXP_OFFSET |
200<< ATMEL_MPDDRC_TP1R_TXSRD_OFFSET |
28<< ATMEL_MPDDRC_TP1R_TXSNR_OFFSET |
26<< ATMEL_MPDDRC_TP1R_TRFC_OFFSET);
- ddr2->tp2r = (7<< ATMEL_MPDDRC_TP2R_TFAW_OFFSET |
2<< ATMEL_MPDDRC_TP2R_TRTP_OFFSET |
2<< ATMEL_MPDDRC_TP2R_TRPA_OFFSET |
7<< ATMEL_MPDDRC_TP2R_TXARDS_OFFSET |
8<< ATMEL_MPDDRC_TP2R_TXARD_OFFSET);
+}
+void mem_init(void) +{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- struct atmel_mpddr ddr2;
- ddr2_conf(&ddr2);
- /* enable MPDDR clock */
- at91_periph_clk_enable(ATMEL_ID_MPDDRC);
- writel(0x4,&pmc->scer);
- /* DDRAM2 Controller initialize */
- ddr2_init(ATMEL_BASE_DDRCS,&ddr2);
+}
+static void at91_disable_wdt(void) +{
- struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
- writel(AT91_WDT_MR_WDDIS,&wdt->mr);
+}
+static void sama5d3xek_plla_init(void) +{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- u32 tmp;
- tmp = AT91_PMC_PLLAR_29 |
AT91_PMC_PLLXR_PLLCOUNT(0x3f) |
AT91_PMC_PLLXR_MUL(43) |
AT91_PMC_PLLXR_DIV(1);
- at91_plla_init(tmp, 10000);
- writel(0x3<< 8,&pmc->pllicpr);
+}
+void s_init(void) +{
- u32 tmp;
- /* disable watchdog */
- at91_disable_wdt();
- /* PMC configuration */
- sama5d3xek_plla_init();
- tmp = AT91_PMC_MCKR_MDIV_4 |
AT91_PMC_MCKR_CSS_PLLA;
- at91_mck_init(tmp, 10000);
- at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
- timer_init();
- board_early_init_f();
- preloader_console_init();
- mem_init();
+} +#endif
All this functions could be moved to a common file, I vote for:
arch/arm/cpu/arm926ejs/at91/spl.c
What do you think?
bye, Heiko

Hello Heiko,
On 10/30/2013 11:15 AM, Heiko Schocher wrote:
Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
<snip code>
All this functions could be moved to a common file, I vote for:
arch/arm/cpu/arm926ejs/at91/spl.c
What do you think?
That's not that easy ... sama5 is an armv7 SoC. So we need some special at91 library directory or something like this.
Best regards
Andreas Bießmann

Hello Andreas,
Am 30.10.2013 11:43, schrieb Andreas Bießmann:
Hello Heiko,
On 10/30/2013 11:15 AM, Heiko Schocher wrote:
Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
<snip code>
All this functions could be moved to a common file, I vote for:
arch/arm/cpu/arm926ejs/at91/spl.c
What do you think?
That's not that easy ... sama5 is an armv7 SoC. So we need some special at91 library directory or something like this.
Ah, armv7 and I work on an at91sam920, which is arm926 ... Hmm... I started with a
arch/arm/cpu/arm926ejs/at91/spl.c
Ok... so we need a place for both archs ... Hmm, something like
arch/arm/cpu/at91-common/spl.c ?
bye, Heiko

Hi Heiko,
+Albert
On 10/30/2013 11:57 AM, Heiko Schocher wrote:
Hello Andreas,
Am 30.10.2013 11:43, schrieb Andreas Bießmann:
Hello Heiko,
On 10/30/2013 11:15 AM, Heiko Schocher wrote:
Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
<snip code>
All this functions could be moved to a common file, I vote for:
arch/arm/cpu/arm926ejs/at91/spl.c
What do you think?
That's not that easy ... sama5 is an armv7 SoC. So we need some special at91 library directory or something like this.
Ah, armv7 and I work on an at91sam920, which is arm926 ... Hmm... I started with a
arch/arm/cpu/arm926ejs/at91/spl.c
Ok... so we need a place for both archs ... Hmm, something like
arch/arm/cpu/at91-common/spl.c ?
I think that is Ok.
Best regards
Andreas Bießmann

Hi Heiko, Andreas,
On 10/30/2013 19:02, Andreas Bießmann wrote:
Hi Heiko,
+Albert
On 10/30/2013 11:57 AM, Heiko Schocher wrote:
Hello Andreas,
Am 30.10.2013 11:43, schrieb Andreas Bießmann:
Hello Heiko,
On 10/30/2013 11:15 AM, Heiko Schocher wrote:
Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
<snip code>
All this functions could be moved to a common file, I vote for:
arch/arm/cpu/arm926ejs/at91/spl.c
What do you think?
That's not that easy ... sama5 is an armv7 SoC. So we need some special at91 library directory or something like this.
Ah, armv7 and I work on an at91sam920, which is arm926 ... Hmm... I started with a
arch/arm/cpu/arm926ejs/at91/spl.c
Ok... so we need a place for both archs ... Hmm, something like
arch/arm/cpu/at91-common/spl.c ?
I think that is Ok.
OK, I will try this in RFC v2.
Best regards
Andreas Bießmann
Best Regards, Bo Shen

Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
Enable SPL support which can load u-boot from SD card in FAT format.
Signed-off-by: Bo Shenvoice.shen@atmel.com
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/u-boot-spl.lds | 50 +++++++++++++
Why do you need a special lds file?
Does arch/arm/cpu/u-boot-spl.lds not fit for you?
bye, Heiko

Hi Heiko,
On 10/31/2013 15:42, Heiko Schocher wrote:
Hello Bo,
Am 30.10.2013 10:15, schrieb Bo Shen:
Enable SPL support which can load u-boot from SD card in FAT format.
Signed-off-by: Bo Shenvoice.shen@atmel.com
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/u-boot-spl.lds | 50 +++++++++++++
Why do you need a special lds file?
Does arch/arm/cpu/u-boot-spl.lds not fit for you?
As the bss segment is too big, which exceed the size of sram, it needs to put the bss into sdram. So, I add this lds file.
bye, Heiko
Best Regards, Bo Shen
participants (3)
-
Andreas Bießmann
-
Bo Shen
-
Heiko Schocher