[U-Boot] [PATCH v4 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.
Changes in v4: - Using blank replace table after defined - Align the register define with datasheet - constify the ram_address and ddr configuration value - Add comments to DDR refresh timing register.
Changes in v3: - Correct the clock enable code, the ID can not OR - Move to at91 common folder - Move plla and mck configure to spl.c file
Changes in v2: - Move spl related code to at91-common folder
Bo Shen (7): arm: atmel: sama5d3: correct the ID for DBGU and PIT arm: at91: pm9261: remove undefined bit in mckr arm: atmel: sama5d3: correct the error define of DIV arm: atmel: sama5d3: the offset of MULA is 18 arm: atmel: sama5d3: early enable PIO peripherals arm: atmel: add ddr2 initialization function arm: atmel: sama5d3: spl boot from fat fs SD card
arch/arm/cpu/Makefile | 1 + arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- arch/arm/cpu/at91-common/Makefile | 11 +++ arch/arm/cpu/at91-common/mpddrc.c | 124 +++++++++++++++++++++++++ arch/arm/cpu/at91-common/spl.c | 90 ++++++++++++++++++ arch/arm/cpu/at91-common/u-boot-spl.lds | 50 ++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 4 + arch/arm/include/asm/arch-at91/at91_pmc.h | 8 +- arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 115 +++++++++++++++++++++++ arch/arm/include/asm/arch-at91/spl.h | 20 ++++ board/atmel/sama5d3xek/sama5d3xek.c | 91 ++++++++++++++++++ include/configs/pm9261.h | 6 +- include/configs/sama5d3xek.h | 34 +++++++ 15 files changed, 551 insertions(+), 9 deletions(-) create mode 100644 arch/arm/cpu/at91-common/Makefile create mode 100644 arch/arm/cpu/at91-common/mpddrc.c create mode 100644 arch/arm/cpu/at91-common/spl.c create mode 100644 arch/arm/cpu/at91-common/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

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
--- Changes in v4: - None Changes in v3: - None Changes in v2: - None
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);

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
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
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- None
arch/arm/cpu/armv7/at91/sama5d3_devices.c | 2 +- arch/arm/cpu/armv7/at91/timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

The PLLADIV2 bit is not defined in at91sam9261 SoC, so remove it.
Signed-off-by: Bo Shen voice.shen@atmel.com
--- Changes in v4: - New Changes in v3: - None Changes in v2: - None
include/configs/pm9261.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index fc95cf0..acf6d61 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -50,15 +50,13 @@ #define CONFIG_SYS_MCKR1_VAL \ (AT91_PMC_MCKR_CSS_SLOW | \ AT91_PMC_MCKR_PRES_1 | \ - AT91_PMC_MCKR_MDIV_2 | \ - AT91_PMC_MCKR_PLLADIV_1) + AT91_PMC_MCKR_MDIV_2)
/* PCK/2 = MCK Master Clock from PLLA */ #define CONFIG_SYS_MCKR2_VAL \ (AT91_PMC_MCKR_CSS_PLLA | \ AT91_PMC_MCKR_PRES_1 | \ - AT91_PMC_MCKR_MDIV_2 | \ - AT91_PMC_MCKR_PLLADIV_1) + AT91_PMC_MCKR_MDIV_2)
/* define PDC[31:16] as DATA[31:16] */ #define CONFIG_SYS_PIOC_PDR_VAL1 0xFFFF0000

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
The PLLADIV2 bit is not defined in at91sam9261 SoC, so remove it.
Signed-off-by: Bo Shen voice.shen@atmel.com
Changes in v4:
- New
Changes in v3:
- None
Changes in v2:
- None
include/configs/pm9261.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

Correct the error define of DIV.
Signed-off-by: Bo Shen voice.shen@atmel.com --- Changes in v4: - None Changes in v3: - None Changes in v2: - None
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 7b36f74..3efdc37 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -124,8 +124,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

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
Correct the error define of DIV.
Signed-off-by: Bo Shen voice.shen@atmel.com
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- None
arch/arm/include/asm/arch-at91/at91_pmc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

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
--- Changes in v4: - None Changes in v3: - None Changes in v2: - None
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 3efdc37..b6e542e 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

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
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
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- None
arch/arm/include/asm/arch-at91/at91_pmc.h | 4 ++++ 1 file changed, 4 insertions(+)
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

Enable the PIO peripherals early than other peripherals.
Signed-off-by: Bo Shen voice.shen@atmel.com
--- Changes in v4: - None Changes in v3: - Correct the clock enable code, the ID can not OR
Changes in v2: - None
board/atmel/sama5d3xek/sama5d3xek.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef..f245f98 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -158,6 +158,12 @@ void lcd_show_board_info(void)
int board_early_init_f(void) { + at91_periph_clk_enable(ATMEL_ID_PIOA); + at91_periph_clk_enable(ATMEL_ID_PIOB); + at91_periph_clk_enable(ATMEL_ID_PIOC); + at91_periph_clk_enable(ATMEL_ID_PIOD); + at91_periph_clk_enable(ATMEL_ID_PIOE); + at91_seriald_hw_init();
return 0;

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
Enable the PIO peripherals early than other peripherals.
Signed-off-by: Bo Shen voice.shen@atmel.com
Changes in v4:
- None
Changes in v3:
- Correct the clock enable code, the ID can not OR
Changes in v2:
- None
board/atmel/sama5d3xek/sama5d3xek.c | 6 ++++++ 1 file changed, 6 insertions(+)
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

The MPDDRC supports different type of SDRAM This patch add ddr2 initialization function
Signed-off-by: Bo Shen voice.shen@atmel.com
--- Changes in v4: - Using blank replace table after defined - Align the register define with datasheet - constify the ram_address and ddr configuration value
Changes in v3: - Move to at91 common folder
Changes in v2: - None
arch/arm/cpu/Makefile | 1 + arch/arm/cpu/at91-common/Makefile | 11 +++ arch/arm/cpu/at91-common/mpddrc.c | 124 +++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 115 +++++++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 arch/arm/cpu/at91-common/Makefile create mode 100644 arch/arm/cpu/at91-common/mpddrc.c create mode 100644 arch/arm/include/asm/arch-at91/atmel_mpddrc.h
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index fd0da53..b2d30b1 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,2 +1,3 @@ +obj-$(CONFIG_AT91FAMILY) += at91-common/ obj-$(CONFIG_TEGRA) += $(SOC)-common/ obj-$(CONFIG_TEGRA) += tegra-common/ diff --git a/arch/arm/cpu/at91-common/Makefile b/arch/arm/cpu/at91-common/Makefile new file mode 100644 index 0000000..671a05e --- /dev/null +++ b/arch/arm/cpu/at91-common/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2013 Atmel Corporation +# Bo Shen voice.shen@atmel.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SPL_BUILD) += mpddrc.o diff --git a/arch/arm/cpu/at91-common/mpddrc.c b/arch/arm/cpu/at91-common/mpddrc.c new file mode 100644 index 0000000..8136396 --- /dev/null +++ b/arch/arm/cpu/at91-common/mpddrc.c @@ -0,0 +1,124 @@ +/* + * 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 inline 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(const unsigned int ram_address, + const 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->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; + + /* Program the memory device type into the memory device register */ + writel(mpddr_value->md, &mpddr->md); + + /* Program the configuration register */ + writel(mpddr_value->cr, &mpddr->cr); + + /* Program the timing register */ + writel(mpddr_value->tpr0, &mpddr->tpr0); + writel(mpddr_value->tpr1, &mpddr->tpr1); + writel(mpddr_value->tpr2, &mpddr->tpr2); + + /* Issue a NOP command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_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_MODE_NOP_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); + + /* Issue an extended mode register set(EMRS2) to choose operation */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_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_MODE_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_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* Enable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr); + + /* A mode register set(MRS) cycle is issued to reset DLL */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); + + /* Two auto-refresh (CBR) cycles are provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); + + /* Disable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr); + + /* A mode register set (MRS) cycle is issued to disable DLL reset */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); + + /* Set OCD calibration in default 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_MODE_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_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* A nornal mode command is provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_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..5741f6e --- /dev/null +++ b/arch/arm/include/asm/arch-at91/atmel_mpddrc.h @@ -0,0 +1,115 @@ +/* + * 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__ + +/* + * Only define the needed register in mpddr + * If other register needed, will add them later + */ +struct atmel_mpddr { + u32 mr; + u32 rtr; + u32 cr; + u32 tpr0; + u32 tpr1; + u32 tpr2; + u32 reserved[2]; + u32 md; +}; + +int ddr2_init(const unsigned int ram_address, + const struct atmel_mpddr *mpddr); + +/* Bit field in mode register */ +#define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD 0x0 +#define ATMEL_MPDDRC_MR_MODE_NOP_CMD 0x1 +#define ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD 0x2 +#define ATMEL_MPDDRC_MR_MODE_LMR_CMD 0x3 +#define ATMEL_MPDDRC_MR_MODE_RFSH_CMD 0x4 +#define ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD 0x5 +#define ATMEL_MPDDRC_MR_MODE_DEEP_CMD 0x6 +#define ATMEL_MPDDRC_MR_MODE_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_MASK (0x7 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS2 (0x2 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS3 (0x3 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS4 (0x4 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS5 (0x5 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS6 (0x6 << 4) +#define ATMEL_MPDDRC_CR_DLL_RESET_ENABLED (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_ENRDM_ON (0x1 << 17) +#define ATMEL_MPDDRC_CR_NB_8BANKS (0x1 << 20) +#define ATMEL_MPDDRC_CR_NDQS_DISABLED (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_TPR0_TRAS_OFFSET 0 +#define ATMEL_MPDDRC_TPR0_TRAS_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRCD_OFFSET 4 +#define ATMEL_MPDDRC_TPR0_TRCD_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TWR_OFFSET 8 +#define ATMEL_MPDDRC_TPR0_TWR_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRC_OFFSET 12 +#define ATMEL_MPDDRC_TPR0_TRC_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRP_OFFSET 16 +#define ATMEL_MPDDRC_TPR0_TRP_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRRD_OFFSET 20 +#define ATMEL_MPDDRC_TPR0_TRRD_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TWTR_OFFSET 24 +#define ATMEL_MPDDRC_TPR0_TWTR_MASK 0x7 +#define ATMEL_MPDDRC_TPR0_RDC_WRRD_OFFSET 27 +#define ATMEL_MPDDRC_TPR0_RDC_WRRD_MASK 0x1 +#define ATMEL_MPDDRC_TPR0_TMRD_OFFSET 28 +#define ATMEL_MPDDRC_TPR0_TMRD_MASK 0xf + +/* Bit field in timing parameter 1 register */ +#define ATMEL_MPDDRC_TPR1_TRFC_OFFSET 0 +#define ATMEL_MPDDRC_TPR1_TRFC_MASK 0x7f +#define ATMEL_MPDDRC_TPR1_TXSNR_OFFSET 8 +#define ATMEL_MPDDRC_TPR1_TXSNR_MASK 0xff +#define ATMEL_MPDDRC_TPR1_TXSRD_OFFSET 16 +#define ATMEL_MPDDRC_TPR1_TXSRD_MASK 0xff +#define ATMEL_MPDDRC_TPR1_TXP_OFFSET 24 +#define ATMEL_MPDDRC_TPR1_TXP_MASK 0xf + +/* Bit field in timing parameter 2 register */ +#define ATMEL_MPDDRC_TPR2_TXARD_OFFSET 0 +#define ATMEL_MPDDRC_TPR2_TXARD_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TXARDS_OFFSET 4 +#define ATMEL_MPDDRC_TPR2_TXARDS_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TRPA_OFFSET 8 +#define ATMEL_MPDDRC_TPR2_TRPA_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TRTP_OFFSET 12 +#define ATMEL_MPDDRC_TPR2_TRTP_MASK 0x7 +#define ATMEL_MPDDRC_TPR2_TFAW_OFFSET 16 +#define ATMEL_MPDDRC_TPR2_TFAW_MASK 0xf + +/* Bit field in Memory Device Register */ +#define ATMEL_MPDDRC_MD_LPDDR_SDRAM 0x3 +#define ATMEL_MPDDRC_MD_DDR2_SDRAM 0x6 +#define ATMEL_MPDDRC_MD_DBW_MASK (0x1 << 4) +#define ATMEL_MPDDRC_MD_DBW_32_BITS (0x0 << 4) +#define ATMEL_MPDDRC_MD_DBW_16_BITS (0x1 << 4) + +#endif

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
The MPDDRC supports different type of SDRAM This patch add ddr2 initialization function
Signed-off-by: Bo Shen voice.shen@atmel.com
Changes in v4:
- Using blank replace table after defined
- Align the register define with datasheet
- constify the ram_address and ddr configuration value
Changes in v3:
- Move to at91 common folder
Changes in v2:
- None
arch/arm/cpu/Makefile | 1 + arch/arm/cpu/at91-common/Makefile | 11 +++ arch/arm/cpu/at91-common/mpddrc.c | 124 +++++++++++++++++++++++++ arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 115 +++++++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 arch/arm/cpu/at91-common/Makefile create mode 100644 arch/arm/cpu/at91-common/mpddrc.c create mode 100644 arch/arm/include/asm/arch-at91/atmel_mpddrc.h
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann

Enable Atmel sama5d3xek boart spl boot support, which can load u-boot from SD card with FAT file system.
Signed-off-by: Bo Shen voice.shen@atmel.com
--- Changes in v4: - Add comments to DDR refresh timing register.
Changes in v3: - Move plla and mck configure to spl.c file
Changes in v2: - Move spl related code to at91-common folder
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/at91-common/Makefile | 2 +- arch/arm/cpu/at91-common/spl.c | 90 ++++++++++++++++++++++++++ arch/arm/cpu/at91-common/u-boot-spl.lds | 50 ++++++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 4 ++ arch/arm/include/asm/arch-at91/spl.h | 20 ++++++ board/atmel/sama5d3xek/sama5d3xek.c | 85 ++++++++++++++++++++++++ include/configs/sama5d3xek.h | 34 ++++++++++ 8 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/at91-common/spl.c create mode 100644 arch/arm/cpu/at91-common/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 d3347b3..0467d00 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -12,7 +12,7 @@ obj-y += cache_v7.o obj-y += cpu.o obj-y += 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_AT91FAMILY),) ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) obj-y += lowlevel_init.o endif diff --git a/arch/arm/cpu/at91-common/Makefile b/arch/arm/cpu/at91-common/Makefile index 671a05e..d97053f 100644 --- a/arch/arm/cpu/at91-common/Makefile +++ b/arch/arm/cpu/at91-common/Makefile @@ -8,4 +8,4 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-$(CONFIG_SPL_BUILD) += mpddrc.o +obj-$(CONFIG_SPL_BUILD) += mpddrc.o spl.o diff --git a/arch/arm/cpu/at91-common/spl.c b/arch/arm/cpu/at91-common/spl.c new file mode 100644 index 0000000..37c0cc4 --- /dev/null +++ b/arch/arm/cpu/at91-common/spl.c @@ -0,0 +1,90 @@ +/* + * 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_pmc.h> +#include <asm/arch/at91_wdt.h> +#include <asm/arch/clk.h> +#include <spl.h> + +static void at91_disable_wdt(void) +{ + struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; + + writel(AT91_WDT_MR_WDDIS, &wdt->mr); +} + +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_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)) + ; +} + + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SYS_USE_MMC + return BOOT_DEVICE_MMC1; +#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_FAT; + break; +#endif + case BOOT_DEVICE_NONE: + default: + hang(); + } +} + +void s_init(void) +{ + /* 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(); +} diff --git a/arch/arm/cpu/at91-common/u-boot-spl.lds b/arch/arm/cpu/at91-common/u-boot-spl.lds new file mode 100644 index 0000000..038335d --- /dev/null +++ b/arch/arm/cpu/at91-common/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/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index abcb97d..3ca4d5b 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -22,5 +22,9 @@ 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); +void at91_mck_init(u32 mckr); +void at91_pmc_init(void); +void mem_init(void);
#endif /* AT91_COMMON_H */ 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..68c5349 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/spl.h @@ -0,0 +1,20 @@ +/* + * 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_NONE, +#ifdef CONFIG_SYS_USE_MMC + BOOT_DEVICE_MMC1, + BOOT_DEVICE_MMC2, + BOOT_DEVICE_MMC2_2, +#endif +}; + +#endif diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index f245f98..0ab8020 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> @@ -296,3 +299,85 @@ void spi_cs_deactivate(struct spi_slave *slave) } } #endif /* CONFIG_ATMEL_SPI */ + +/* SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ +#ifdef CONFIG_SYS_USE_MMC + sama5d3xek_mci_hw_init(); +#endif +} + +static void ddr2_conf(struct atmel_mpddr *ddr2) +{ + ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); + + ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_DDR_CAS3 | + ATMEL_MPDDRC_CR_ENRDM_ON | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_NDQS_DISABLED | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + /* + * As the DDR2-SDRAm device requires a refresh time is 7.8125us + * when DDR run at 133MHz, so it needs (7.8125us * 133MHz / 10^9) clocks + */ + ddr2->rtr = 0x411; + + ddr2->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | + 8 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); + + ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | + 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | + 28 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | + 26 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET); + + ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | + 7 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | + 8 << ATMEL_MPDDRC_TPR2_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); +} + +void at91_pmc_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); + + writel(0x3 << 8, &pmc->pllicpr); + + tmp = AT91_PMC_MCKR_MDIV_4 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp); +} +#endif diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h index 5a6f0fc..c34feb5 100644 --- a/include/configs/sama5d3xek.h +++ b/include/configs/sama5d3xek.h @@ -24,7 +24,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
@@ -93,8 +96,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,31 @@ /* 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_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT + +#define CONFIG_SPL_BOARD_INIT +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#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 + #endif

Dear Bo Shen,
Bo Shen voice.shen@atmel.com writes:
Enable Atmel sama5d3xek boart spl boot support, which can load u-boot from SD card with FAT file system.
Signed-off-by: Bo Shen voice.shen@atmel.com
Changes in v4:
- Add comments to DDR refresh timing register.
Changes in v3:
- Move plla and mck configure to spl.c file
Changes in v2:
- Move spl related code to at91-common folder
arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/at91-common/Makefile | 2 +- arch/arm/cpu/at91-common/spl.c | 90 ++++++++++++++++++++++++++ arch/arm/cpu/at91-common/u-boot-spl.lds | 50 ++++++++++++++ arch/arm/include/asm/arch-at91/at91_common.h | 4 ++ arch/arm/include/asm/arch-at91/spl.h | 20 ++++++ board/atmel/sama5d3xek/sama5d3xek.c | 85 ++++++++++++++++++++++++ include/configs/sama5d3xek.h | 34 ++++++++++ 8 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/at91-common/spl.c create mode 100644 arch/arm/cpu/at91-common/u-boot-spl.lds create mode 100644 arch/arm/include/asm/arch-at91/spl.h
applied to u-boot-atmel/master, thanks!
Best regards, Andreas Bießmann
participants (2)
-
Andreas Bießmann
-
Bo Shen