From b4670a0c2bb9fd0a141436626d1853f995c8ed54 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 5 Nov 2015 20:58:30 +0100 Subject: [PATCH 01/11] mmc: atmel: Properly fix clock configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Timing issue occurs on eMMC not only when modifying the frequency but also for all the switch command(CMD6). According to the MMC spec waiting 8 clocks after a switch command would be the thing to do. This patch allows fixing CPU hang observed when trying to changing the bus width on a eMMC on SAMA5D4. Signed-off-by: Gregory CLEMENT Tested-by: Marek Vasut # on DENX MA5D4EV Acked-by: Marek Vasut Tested-by: Andreas Bießmann # on atngw100 Acked-by: Andreas Bießmann [fixed minor checkpatch warning] Signed-off-by: Andreas Bießmann --- drivers/mmc/gen_atmel_mci.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index da870c646e..0474a15484 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -36,6 +36,7 @@ struct atmel_mci_priv { struct mmc_config cfg; struct atmel_mci *mci; unsigned int initialized:1; + unsigned int curr_clk; }; /* Read Atmel MCI IP version */ @@ -91,7 +92,10 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) } } - + if (version >= 0x500) + priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2); + else + priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2; blklen &= 0xfffc; mr = MMCI_BF(CLKDIV, clkdiv); @@ -118,8 +122,6 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS) writel(MMCI_BIT(HSMODE), &mci->cfg); - udelay(50); - priv->initialized = 1; } @@ -323,6 +325,13 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) } } + /* + * After the switch command, wait for 8 clocks before the next + * command + */ + if (cmd->cmdidx == MMC_CMD_SWITCH) + udelay(8*1000000 / priv->curr_clk); /* 8 clk in us */ + return 0; } From 75b03cf14ccbe2371cd11e410238fff0a02e72b5 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 16 Dec 2015 14:50:34 +0100 Subject: [PATCH 02/11] net: macb: Not all the GEM are gigabit capable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the initialization of PHY the gigabit bit capable is set if the controller is a GEM. However, for sama5d2 and sama5d4, the GEM is configured to support only 10/100. Improperly setting the GBE capability leads to an unresponsive MAC controller. This patch fixes this behavior allowing using the gmac with these SoCs. Suggested-by: Nicolas Ferre Signed-off-by: Gregory CLEMENT Acked-by: Nicolas Ferre Acked-by: Joe Hershberger Reviewed-by: Andreas Bießmann [fixed minor checkpatch warning] Signed-off-by: Andreas Bießmann --- drivers/net/macb.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index a5c188066c..be0659a52c 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -109,6 +109,23 @@ static int macb_is_gem(struct macb_device *macb) return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2; } +#ifndef cpu_is_sama5d2 +#define cpu_is_sama5d2() 0 +#endif + +#ifndef cpu_is_sama5d4 +#define cpu_is_sama5d4() 0 +#endif + +static int gem_is_gigabit_capable(struct macb_device *macb) +{ + /* + * The GEM controllers embeded in SAMA5D2 and SAMA5D4 are + * configured to support only 10/100. + */ + return macb_is_gem(macb) && !cpu_is_sama5d2() && !cpu_is_sama5d4(); +} + static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value) { unsigned long netctl; @@ -480,8 +497,8 @@ static int macb_phy_init(struct macb_device *macb) return 0; } - /* First check for GMAC */ - if (macb_is_gem(macb)) { + /* First check for GMAC and that it is GiB capable */ + if (gem_is_gigabit_capable(macb)) { lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (LPA_1000FULL | LPA_1000HALF)) { From 3a2056719968c82fb0b5e079b47a146f68330879 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:33 +0800 Subject: [PATCH 03/11] atmel_nand: use nand ecc_{strength, step}_ds instead of our own function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since ecc_{strength,step}_ds is introduced in nand_chip structure for minimum ecc requirements. So we can use them directly and remove our own get_onfi_ecc_param function. Signed-off-by: Josh Wu Reviewed-by: Andreas Bießmann Signed-off-by: Wenyou Yang --- drivers/mtd/nand/atmel_nand.c | 44 ++++++----------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 0d4f327ed7..e179f74229 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -676,34 +676,6 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd) } #ifdef CONFIG_SYS_NAND_ONFI_DETECTION -/* - * get_onfi_ecc_param - Get ECC requirement from ONFI parameters - * @ecc_bits: store the ONFI ECC correct bits capbility - * @sector_size: in how many bytes that ONFI require to correct @ecc_bits - * - * Returns -1 if ONFI parameters is not supported. In this case @ecc_bits, - * @sector_size are initialize to 0. - * Return 0 if success to get the ECC requirement. - */ -static int get_onfi_ecc_param(struct nand_chip *chip, - int *ecc_bits, int *sector_size) -{ - *ecc_bits = *sector_size = 0; - - if (chip->onfi_params.ecc_bits == 0xff) - /* TODO: the sector_size and ecc_bits need to be find in - * extended ecc parameter, currently we don't support it. - */ - return -1; - - *ecc_bits = chip->onfi_params.ecc_bits; - - /* The default sector size (ecc codeword size) is 512 */ - *sector_size = 512; - - return 0; -} - /* * pmecc_choose_ecc - Get ecc requirement from ONFI parameters. If * pmecc_corr_cap or pmecc_sector_size is 0, then set it as @@ -724,17 +696,15 @@ static int pmecc_choose_ecc(struct atmel_nand_host *host, /* Get ECC requirement from ONFI parameters */ *cap = *sector_size = 0; if (chip->onfi_version) { - if (!get_onfi_ecc_param(chip, cap, sector_size)) { - MTDDEBUG(MTD_DEBUG_LEVEL1, "ONFI params, minimum required ECC: %d bits in %d bytes\n", - *cap, *sector_size); - } else { - dev_info(host->dev, "NAND chip ECC reqirement is in Extended ONFI parameter, we don't support yet.\n"); - } - } else { - dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes"); + *cap = chip->ecc_strength_ds; + *sector_size = chip->ecc_step_ds; + MTDDEBUG(MTD_DEBUG_LEVEL1, "ONFI params, minimum required ECC: %d bits in %d bytes\n", + *cap, *sector_size); } + if (*cap == 0 && *sector_size == 0) { - /* Non-ONFI compliant or use extended ONFI parameters */ + /* Non-ONFI compliant */ + dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes\n"); *cap = 2; *sector_size = 512; } From 4c6a6ea3e11844f1b7242d7ed4468bb80ae81369 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:34 +0800 Subject: [PATCH 04/11] atmel_nand: add '\n' in the end of error message for better display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also align the open parenthesis. Signed-off-by: Josh Wu Signed-off-by: Wenyou Yang Reviewed-by: Andreas Bießmann --- drivers/mtd/nand/atmel_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e179f74229..852883bfb2 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -821,8 +821,8 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, * from ONFI. */ if (pmecc_choose_ecc(host, nand, &cap, §or_size)) { - dev_err(host->dev, "The NAND flash's ECC requirement(ecc_bits: %d, sector_size: %d) are not support!", - cap, sector_size); + dev_err(host->dev, "Required ECC %d bits in %d bytes not supported!\n", + cap, sector_size); return -EINVAL; } From 422b49e2895ef61a1cc454aca6dd79a8e2279eff Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:35 +0800 Subject: [PATCH 05/11] atmel_nand: use the definition: PMECC_OOB_RESERVED_BYTES instead magic number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As atmel_nand_ecc.h is sync with v4.1 kernel, which adds the PMECC_OOB_RESERVED_BYTES. So use it in the driver. Signed-off-by: Josh Wu Reviewed-by: Andreas Bießmann Signed-off-by: Wenyou Yang --- drivers/mtd/nand/atmel_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 852883bfb2..73fd403886 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -901,7 +901,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, return -EINVAL; } - if (nand->ecc.bytes > mtd->oobsize - 2) { + if (nand->ecc.bytes > mtd->oobsize - PMECC_OOB_RESERVED_BYTES) { dev_err(host->dev, "No room for ECC bytes\n"); return -EINVAL; } From fa651f5d53372dd7a40fd2bcf701694d359820ce Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 24 Nov 2015 16:34:00 +0800 Subject: [PATCH 06/11] atmel_nand_ecc: update pmecc registers according to sama5d2 chip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. add the pmecc register mapping for sama5d2. 2. add the pmecc error location register mapping for sama5d2. 3. add some new field that is different from old ip. 4. add sama5d2 pmecc ip version number. Signed-off-by: Josh Wu Reviewed-by: Andreas Bießmann --- drivers/mtd/nand/atmel_nand_ecc.h | 36 +++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index 79e399489e..e13f38503f 100644 --- a/drivers/mtd/nand/atmel_nand_ecc.h +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -58,14 +58,23 @@ struct pmecc_regs { /* 0x40 + sector_num * (0x40), Redundancy Registers */ struct { +#ifdef CONFIG_SAMA5D2 + u8 ecc[56]; /* PMECC Generated Redundancy Byte Per Sector */ + u32 reserved1[2]; +#else u8 ecc[44]; /* PMECC Generated Redundancy Byte Per Sector */ u32 reserved1[5]; +#endif } ecc_port[PMECC_MAX_SECTOR_NUM]; /* 0x240 + sector_num * (0x40) Remainder Registers */ struct { +#ifdef CONFIG_SAMA5D2 + u32 rem[16]; +#else u32 rem[12]; u32 reserved2[4]; +#endif } rem_port[PMECC_MAX_SECTOR_NUM]; u32 reserved3[16]; /* 0x440-0x47C Reserved */ }; @@ -76,6 +85,7 @@ struct pmecc_regs { #define PMECC_CFG_BCH_ERR8 (2 << 0) #define PMECC_CFG_BCH_ERR12 (3 << 0) #define PMECC_CFG_BCH_ERR24 (4 << 0) +#define PMECC_CFG_BCH_ERR32 (5 << 0) #define PMECC_CFG_SECTOR512 (0 << 4) #define PMECC_CFG_SECTOR1024 (1 << 4) @@ -120,19 +130,31 @@ struct pmecc_errloc_regs { u32 elimr; /* 0x0C Error Location Interrupt Mask Register */ u32 elisr; /* 0x20 Error Location Interrupt Status Register */ u32 reserved0; /* 0x24 Reserved */ +#ifdef CONFIG_SAMA5D2 + u32 sigma[33]; /* 0x28-0xA8 Error Location Sigma Registers */ + u32 el[32]; /* 0xAC-0x128 Error Location Registers */ + + /* + * 0x12C-0x1FC: + * Reserved for SAMA5D2. + */ + u32 reserved1[53]; +#else u32 sigma[25]; /* 0x28-0x88 Error Location Sigma Registers */ u32 el[24]; /* 0x8C-0xE8 Error Location Registers */ u32 reserved1[5]; /* 0xEC-0xFC Reserved */ +#endif /* - * 0x100-0x1F8: - * Reserved for AT91SAM9X5, AT91SAM9N12. - * HSMC registers for SAMA5D3, SAMA5D4. + * SAMA5 chip HSMC registers start here. But for 9X5 chip it is just + * reserved. + * + * Offset 0x00-0xF8: */ u32 reserved2[63]; /* - * 0x1FC: + * Offset 0xFC: * PMECC version for AT91SAM9X5, AT91SAM9N12. * HSMC version for SAMA5D3, SAMA5D4. Can refer as PMECC version. */ @@ -148,10 +170,16 @@ struct pmecc_errloc_regs { #define PMERRLOC_DISABLE (1 << 0) /* For Error Location Interrupt Status Register */ +#ifdef CONFIG_SAMA5D2 +#define PMERRLOC_ERR_NUM_MASK (0x3f << 8) +#else #define PMERRLOC_ERR_NUM_MASK (0x1f << 8) +#endif + #define PMERRLOC_CALC_DONE (1 << 0) /* PMECC IP version */ +#define PMECC_VERSION_SAMA5D2 0x210 #define PMECC_VERSION_SAMA5D4 0x113 #define PMECC_VERSION_SAMA5D3 0x112 #define PMECC_VERSION_AT91SAM9N12 0x102 From 258b21fc69c93172d8e4afaeff3a7303740ce7c6 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 24 Nov 2015 16:34:01 +0800 Subject: [PATCH 07/11] atmel_nand: Add 32 bit ecc support for sama5d2 chip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also if minimum ecc requirment is bigger then what we support, then just use our maxium pmecc support. But it is not safe, so we'll output a warning about this. Signed-off-by: Josh Wu Acked-by: Scott Wood Reviewed-by: Andreas Bießmann --- drivers/mtd/nand/atmel_nand.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 73fd403886..7cc1de0313 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -80,6 +80,7 @@ static struct nand_ecclayout atmel_pmecc_oobinfo; * 8-bits 13-bytes 14-bytes * 12-bits 20-bytes 21-bytes * 24-bits 39-bytes 42-bytes + * 32-bits 52-bytes 56-bytes */ static int pmecc_get_ecc_bytes(int cap, int sector_size) { @@ -638,6 +639,9 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd) case 24: val = PMECC_CFG_BCH_ERR24; break; + case 32: + val = PMECC_CFG_BCH_ERR32; + break; } if (host->pmecc_sector_size == 512) @@ -723,7 +727,11 @@ static int pmecc_choose_ecc(struct atmel_nand_host *host, else if (*cap <= 24) host->pmecc_corr_cap = 24; else - return -EINVAL; +#ifdef CONFIG_SAMA5D2 + host->pmecc_corr_cap = 32; +#else + host->pmecc_corr_cap = 24; +#endif } if (host->pmecc_sector_size == 0) { /* use the most fitable sector size (the near smaller one ) */ From 7e8702a00fe88590c2ece93061da4a40adf3c242 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Mon, 1 Feb 2016 18:12:15 +0800 Subject: [PATCH 08/11] arm: at91/spl: mpddrc: add struct atmel_mpddrc_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add struct atmel_mpddrc_config to accommodate the mpddrc register configurations, not using the mpddrc register map structure, struct atmel_mpddrc, in order to increase readability and reduce run-time memory use. Signed-off-by: Wenyou Yang Reviewed-by: Andreas Bießmann --- arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 12 +++++++++++- arch/arm/mach-at91/mpddrc.c | 2 +- board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c | 4 ++-- board/atmel/at91sam9n12ek/at91sam9n12ek.c | 4 ++-- board/atmel/at91sam9x5ek/at91sam9x5ek.c | 4 ++-- board/atmel/sama5d3_xplained/sama5d3_xplained.c | 4 ++-- board/atmel/sama5d3xek/sama5d3xek.c | 4 ++-- board/atmel/sama5d4_xplained/sama5d4_xplained.c | 4 ++-- board/atmel/sama5d4ek/sama5d4ek.c | 4 ++-- board/mini-box/picosam9g45/picosam9g45.c | 4 ++-- board/siemens/corvus/board.c | 4 ++-- 11 files changed, 30 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h index c6c8dda803..47b4cd4914 100644 --- a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h +++ b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h @@ -8,6 +8,16 @@ #ifndef __ATMEL_MPDDRC_H__ #define __ATMEL_MPDDRC_H__ +struct atmel_mpddrc_config { + u32 mr; + u32 rtr; + u32 cr; + u32 tpr0; + u32 tpr1; + u32 tpr2; + u32 md; +}; + /* * Only define the needed register in mpddr * If other register needed, will add them later @@ -26,7 +36,7 @@ struct atmel_mpddr { int ddr2_init(const unsigned int base, const unsigned int ram_address, - const struct atmel_mpddr *mpddr); + const struct atmel_mpddrc_config *mpddr_value); /* Bit field in mode register */ #define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD 0x0 diff --git a/arch/arm/mach-at91/mpddrc.c b/arch/arm/mach-at91/mpddrc.c index 47e6e5a3cd..9ba2a00e92 100644 --- a/arch/arm/mach-at91/mpddrc.c +++ b/arch/arm/mach-at91/mpddrc.c @@ -30,7 +30,7 @@ static int ddr2_decodtype_is_seq(u32 cr) int ddr2_init(const unsigned int base, const unsigned int ram_address, - const struct atmel_mpddr *mpddr_value) + const struct atmel_mpddrc_config *mpddr_value) { const struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base; diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c index 2fea56ffe7..0a51fcd9aa 100644 --- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c +++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c @@ -97,7 +97,7 @@ void at91_spl_board_init(void) } #include -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -131,7 +131,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); diff --git a/board/atmel/at91sam9n12ek/at91sam9n12ek.c b/board/atmel/at91sam9n12ek/at91sam9n12ek.c index 59bc5350de..0b0177df2b 100644 --- a/board/atmel/at91sam9n12ek/at91sam9n12ek.c +++ b/board/atmel/at91sam9n12ek/at91sam9n12ek.c @@ -274,7 +274,7 @@ void at91_spl_board_init(void) } #include -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -310,7 +310,7 @@ void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; unsigned long csa; ddr2_conf(&ddr2); diff --git a/board/atmel/at91sam9x5ek/at91sam9x5ek.c b/board/atmel/at91sam9x5ek/at91sam9x5ek.c index 1738a2b309..833e38335a 100644 --- a/board/atmel/at91sam9x5ek/at91sam9x5ek.c +++ b/board/atmel/at91sam9x5ek/at91sam9x5ek.c @@ -310,7 +310,7 @@ void at91_spl_board_init(void) } #include -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -347,7 +347,7 @@ void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; unsigned long csa; ddr2_conf(&ddr2); diff --git a/board/atmel/sama5d3_xplained/sama5d3_xplained.c b/board/atmel/sama5d3_xplained/sama5d3_xplained.c index 7a01149e11..7acb8d0974 100644 --- a/board/atmel/sama5d3_xplained/sama5d3_xplained.c +++ b/board/atmel/sama5d3_xplained/sama5d3_xplained.c @@ -143,7 +143,7 @@ void spl_board_init(void) #endif } -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -185,7 +185,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index 7c95f33590..0d824fc0ba 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -402,7 +402,7 @@ void spl_board_init(void) #endif } -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -444,7 +444,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); diff --git a/board/atmel/sama5d4_xplained/sama5d4_xplained.c b/board/atmel/sama5d4_xplained/sama5d4_xplained.c index db45331480..e2f33a3e8b 100644 --- a/board/atmel/sama5d4_xplained/sama5d4_xplained.c +++ b/board/atmel/sama5d4_xplained/sama5d4_xplained.c @@ -346,7 +346,7 @@ void spl_board_init(void) #endif } -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -384,7 +384,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); diff --git a/board/atmel/sama5d4ek/sama5d4ek.c b/board/atmel/sama5d4ek/sama5d4ek.c index 357b223e1b..1799059f87 100644 --- a/board/atmel/sama5d4ek/sama5d4ek.c +++ b/board/atmel/sama5d4ek/sama5d4ek.c @@ -342,7 +342,7 @@ void spl_board_init(void) #endif } -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -380,7 +380,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); diff --git a/board/mini-box/picosam9g45/picosam9g45.c b/board/mini-box/picosam9g45/picosam9g45.c index afbd6ce599..193f14d75a 100644 --- a/board/mini-box/picosam9g45/picosam9g45.c +++ b/board/mini-box/picosam9g45/picosam9g45.c @@ -47,7 +47,7 @@ void at91_spl_board_init(void) } #include -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -82,7 +82,7 @@ void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; struct at91_matrix *mat = (struct at91_matrix *)ATMEL_BASE_MATRIX; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; unsigned long csa; ddr2_conf(&ddr2); diff --git a/board/siemens/corvus/board.c b/board/siemens/corvus/board.c index 28985b8b08..38c0ca3aae 100644 --- a/board/siemens/corvus/board.c +++ b/board/siemens/corvus/board.c @@ -114,7 +114,7 @@ void spl_board_init(void) } #include -static void ddr2_conf(struct atmel_mpddr *ddr2) +static void ddr2_conf(struct atmel_mpddrc_config *ddr2) { ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); @@ -148,7 +148,7 @@ static void ddr2_conf(struct atmel_mpddr *ddr2) void mem_init(void) { struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - struct atmel_mpddr ddr2; + struct atmel_mpddrc_config ddr2; ddr2_conf(&ddr2); From c2ad76c4bdfb8ffbe8946c0e6627b37a11effdf7 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Mon, 1 Feb 2016 18:12:16 +0800 Subject: [PATCH 09/11] arm: at91/spl: mpddrc: add mpddrc DDR3-SDRAM initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DDR3-SDRAM initialization sequence is implemented in accordance with the DDR3-SRAM/DDR3L-SDRAM initialization section described in the SAMA5D2 datasheet. Add registers and definitions of mpddrc controller, which is used to support DDR3 devices. Signed-off-by: Wenyou Yang Reviewed-by: Andreas Bießmann --- .../arm/mach-at91/include/mach/atmel_mpddrc.h | 86 ++++++++++++++++-- arch/arm/mach-at91/mpddrc.c | 89 +++++++++++++++++++ 2 files changed, 167 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h index 47b4cd4914..d37d9082cd 100644 --- a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h +++ b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h @@ -2,6 +2,9 @@ * Copyright (C) 2013 Atmel Corporation * Bo Shen * + * Copyright (C) 2015 Atmel Corporation + * Wenyou Yang + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -23,14 +26,35 @@ struct atmel_mpddrc_config { * 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; + u32 mr; /* 0x00: Mode Register */ + u32 rtr; /* 0x04: Refresh Timer Register */ + u32 cr; /* 0x08: Configuration Register */ + u32 tpr0; /* 0x0c: Timing Parameter 0 Register */ + u32 tpr1; /* 0x10: Timing Parameter 1 Register */ + u32 tpr2; /* 0x14: Timing Parameter 2 Register */ + u32 reserved; /* 0x18: Reserved */ + u32 lpr; /* 0x1c: Low-power Register */ + u32 md; /* 0x20: Memory Device Register */ + u32 reserved1; /* 0x24: Reserved */ + u32 lpddr23_lpr; /* 0x28: LPDDR2-LPDDR3 Low-power Register*/ + u32 cal_mr4; /* 0x2c: Calibration and MR4 Register */ + u32 tim_cal; /* 0x30: Timing Calibration Register */ + u32 io_calibr; /* 0x34: IO Calibration */ + u32 ocms; /* 0x38: OCMS Register */ + u32 ocms_key1; /* 0x3c: OCMS KEY1 Register */ + u32 ocms_key2; /* 0x40: OCMS KEY2 Register */ + u32 conf_arbiter; /* 0x44: Configuration Arbiter Register */ + u32 timeout; /* 0x48: Timeout Port 0/1/2/3 Register */ + u32 req_port0123; /* 0x4c: Request Port 0/1/2/3 Register */ + u32 req_port4567; /* 0x50: Request Port 4/5/6/7 Register */ + u32 bdw_port0123; /* 0x54: Bandwidth Port 0/1/2/3 Register */ + u32 bdw_port4567; /* 0x58: Bandwidth Port 4/5/6/7 Register */ + u32 rd_data_path; /* 0x5c: Read Datapath Register */ + u32 reserved2[33]; + u32 wpmr; /* 0xe4: Write Protection Mode Register */ + u32 wpsr; /* 0xe8: Write Protection Status Register */ + u32 reserved3[4]; + u32 version; /* 0xfc: IP version */ }; @@ -38,6 +62,10 @@ int ddr2_init(const unsigned int base, const unsigned int ram_address, const struct atmel_mpddrc_config *mpddr_value); +int ddr3_init(const unsigned int base, + const unsigned int ram_address, + const struct atmel_mpddrc_config *mpddr_value); + /* Bit field in mode register */ #define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD 0x0 #define ATMEL_MPDDRC_MR_MODE_NOP_CMD 0x1 @@ -120,9 +148,51 @@ int ddr2_init(const unsigned int base, /* Bit field in Memory Device Register */ #define ATMEL_MPDDRC_MD_LPDDR_SDRAM 0x3 +#define ATMEL_MPDDRC_MD_DDR3_SDRAM 0x4 +#define ATMEL_MPDDRC_MD_LPDDR3_SDRAM 0x5 #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) +/* Bit field in I/O Calibration Register */ +#define ATMEL_MPDDRC_IO_CALIBR_RDIV 0x7 + +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_34_3 0x1 +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_40 0x2 +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_48 0x3 +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_60 0x4 +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_80 0x6 +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_120 0x7 + +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_35 0x2 +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_43 0x3 +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_52 0x4 +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_70 0x6 +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_105 0x7 + +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_37 0x2 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_44 0x3 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55 0x4 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_73 0x6 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_110 0x7 + +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_37 0x2 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_44 0x3 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55 0x4 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_73 0x6 +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_110 0x7 + +#define ATMEL_MPDDRC_IO_CALIBR_TZQIO 0x7f +#define ATMEL_MPDDRC_IO_CALIBR_TZQIO_(x) (((x) & 0x7f) << 8) + +#define ATMEL_MPDDRC_IO_CALIBR_EN_CALIB (0x1 << 4) + +/* Bit field in Read Data Path Register */ +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING 0x3 +#define ATMEL_MPDDRC_RD_DATA_PATH_NO_SHIFT 0x0 +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_ONE_CYCLE 0x1 +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_TWO_CYCLE 0x2 +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_THREE_CYCLE 0x3 + #endif diff --git a/arch/arm/mach-at91/mpddrc.c b/arch/arm/mach-at91/mpddrc.c index 9ba2a00e92..1e1ff1d5fc 100644 --- a/arch/arm/mach-at91/mpddrc.c +++ b/arch/arm/mach-at91/mpddrc.c @@ -2,6 +2,9 @@ * Copyright (C) 2013 Atmel Corporation * Bo Shen * + * Copyright (C) 2015 Atmel Corporation + * Wenyou Yang + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -135,3 +138,89 @@ int ddr2_init(const unsigned int base, return 0; } + +int ddr3_init(const unsigned int base, + const unsigned int ram_address, + const struct atmel_mpddrc_config *mpddr_value) +{ + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base; + u32 ba_off; + + /* Compute bank offset according to NC in configuration register */ + ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; + if (ddr2_decodtype_is_seq(mpddr_value->cr)) + ba_off += ((mpddr_value->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 */ + writel(mpddr_value->md, &mpddr->md); + + /* + * Program features of the DDR3-SDRAM device and timing parameters + */ + writel(mpddr_value->cr, &mpddr->cr); + + writel(mpddr_value->tpr0, &mpddr->tpr0); + writel(mpddr_value->tpr1, &mpddr->tpr1); + writel(mpddr_value->tpr2, &mpddr->tpr2); + + /* A NOP command is issued to the DDR3-SRAM */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); + + /* A pause of at least 500us must be observed before a single toggle. */ + udelay(500); + + /* A NOP command is issued to the DDR3-SDRAM */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); + + /* + * An Extended Mode Register Set (EMRS2) cycle is issued to choose + * between commercial or high temperature operations. + */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x2 << ba_off)); + /* + * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set + * the Extended Mode Register to 0. + */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x3 << ba_off)); + /* + * An Extended Mode Register Set (EMRS1) cycle is issued to disable and + * to program O.D.S. (Output Driver Strength). + */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* + * Write a one to the DLL bit (enable DLL reset) in the MPDDRC + * Configuration Register. + */ + + /* A Mode Register Set (MRS) cycle is issued to reset DLL. */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); + + udelay(50); + + /* + * A Calibration command (MRS) is issued to calibrate RTT and RON + * values for the Process Voltage Temperature (PVT). + */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address); + + /* A Normal Mode command is provided. */ + atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address); + + /* Perform a write access to any DDR3-SDRAM address. */ + writel(0, ram_address); + + /* + * Write the refresh rate into the COUNT field in the MPDDRC + * Refresh Timer Register (MPDDRC_RTR): + */ + writel(mpddr_value->rtr, &mpddr->rtr); + + return 0; +} From 4245701ef58c9c7c1dbccc8fa2f1bdd248b97b8b Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Mon, 1 Feb 2016 18:12:17 +0800 Subject: [PATCH 10/11] arm: at91/spl: mpddrc: use IP version to check configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To remove the unnecessary #ifdef-endif, use the mpddrc IP version to check whether or not the interleaved decoding type is supported. Signed-off-by: Wenyou Yang Reviewed-by: Andreas Bießmann --- arch/arm/mach-at91/mpddrc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-at91/mpddrc.c b/arch/arm/mach-at91/mpddrc.c index 1e1ff1d5fc..16e089c3a0 100644 --- a/arch/arm/mach-at91/mpddrc.c +++ b/arch/arm/mach-at91/mpddrc.c @@ -12,6 +12,8 @@ #include #include +#define SAMA5D3_MPDDRC_VERSION 0x140 + static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr, int mode, u32 ram_address) @@ -20,13 +22,15 @@ static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr, writel(0, ram_address); } -static int ddr2_decodtype_is_seq(u32 cr) +static int ddr2_decodtype_is_seq(const unsigned int base, u32 cr) { -#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \ - defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12) - if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED) + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base; + u16 version = readl(&mpddr->version) & 0xffff; + + if ((version >= SAMA5D3_MPDDRC_VERSION) && + (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED)) return 0; -#endif + return 1; } @@ -41,7 +45,7 @@ int ddr2_init(const unsigned int base, /* Compute bank offset according to NC in configuration register */ ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; - if (ddr2_decodtype_is_seq(mpddr_value->cr)) + if (ddr2_decodtype_is_seq(base, mpddr_value->cr)) ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; @@ -148,7 +152,7 @@ int ddr3_init(const unsigned int base, /* Compute bank offset according to NC in configuration register */ ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; - if (ddr2_decodtype_is_seq(mpddr_value->cr)) + if (ddr2_decodtype_is_seq(base, mpddr_value->cr)) ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; From 37dadbca0c8b9bff00f892fd87a978cbe0a98b3a Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Mon, 1 Feb 2016 18:18:21 +0800 Subject: [PATCH 11/11] board: atmel: sama5d2_xplained: add SPL support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sama5d2 Xplained SPL supports the boot medias: spi flash and SD Card. Signed-off-by: Wenyou Yang Reviewed-by: Andreas Bießmann --- arch/arm/mach-at91/Kconfig | 1 + arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/include/mach/sama5d2.h | 32 ++++++ .../atmel/sama5d2_xplained/sama5d2_xplained.c | 103 ++++++++++++++++++ configs/sama5d2_xplained_mmc_defconfig | 1 + configs/sama5d2_xplained_spiflash_defconfig | 1 + include/configs/sama5d2_xplained.h | 39 +++++++ 7 files changed, 178 insertions(+) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index c33364758b..9426302b38 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -74,6 +74,7 @@ config TARGET_AT91SAM9X5EK config TARGET_SAMA5D2_XPLAINED bool "SAMA5D2 Xplained board" select CPU_V7 + select SUPPORT_SPL config TARGET_SAMA5D3_XPLAINED bool "SAMA5D3 Xplained board" diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 5b89617623..abd1d13da7 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o obj-$(CONFIG_AT91SAM9N12) += mpddrc.o spl_at91.o obj-$(CONFIG_AT91SAM9X5) += mpddrc.o spl_at91.o +obj-$(CONFIG_SAMA5D2) += mpddrc.o spl_atmel.o matrix.o atmel_sfr.o obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o obj-$(CONFIG_SAMA5D4) += mpddrc.o spl_atmel.o matrix.o atmel_sfr.o obj-y += spl.o diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h index c85571c999..dd5a2a7523 100644 --- a/arch/arm/mach-at91/include/mach/sama5d2.h +++ b/arch/arm/mach-at91/include/mach/sama5d2.h @@ -106,6 +106,7 @@ #define ATMEL_BASE_MPDDRC 0xf000c000 #define ATMEL_BASE_XDMAC0 0xf0010000 #define ATMEL_BASE_PMC 0xf0014000 +#define ATMEL_BASE_MATRIX0 0xf0018000 #define ATMEL_BASE_QSPI0 0xf0020000 #define ATMEL_BASE_QSPI1 0xf0024000 #define ATMEL_BASE_SPI0 0xf8000000 @@ -117,6 +118,7 @@ #define ATMEL_BASE_UART1 0xf8020000 #define ATMEL_BASE_UART2 0xf8024000 #define ATMEL_BASE_TWI0 0xf8028000 +#define ATMEL_BASE_SFR 0xf8030000 #define ATMEL_BASE_SYSC 0xf8048000 #define ATMEL_BASE_SPI1 0xfc000000 #define ATMEL_BASE_UART3 0xfc008000 @@ -125,6 +127,7 @@ #define ATMEL_BASE_UDPHS 0xfc02c000 #define ATMEL_BASE_PIOA 0xfc038000 +#define ATMEL_BASE_MATRIX1 0xfc03c000 #define ATMEL_CHIPID_CIDR 0xfc069000 #define ATMEL_CHIPID_EXID 0xfc069004 @@ -171,6 +174,35 @@ #define CPU_HAS_PCR #define CPU_HAS_H32MXDIV +/* AICREDIR Unlock Key */ +#define ATMEL_SFR_AICREDIR_KEY 0xB6D81C4D + +/* MATRIX0(H64MX) slave id definitions */ +#define H64MX_SLAVE_AXIMX_BRIDGE 0 /* Bridge from H64MX to AXIMX */ +#define H64MX_SLAVE_PERIPH_BRIDGE 1 /* H64MX Peripheral Bridge */ +#define H64MX_SLAVE_DDRC_PORT0 2 /* DDR2 Port0-AESOTF */ +#define H64MX_SLAVE_DDRC_PORT1 3 /* DDR2 Port1 */ +#define H64MX_SLAVE_DDRC_PORT2 4 /* DDR2 Port2 */ +#define H64MX_SLAVE_DDRC_PORT3 5 /* DDR2 Port3 */ +#define H64MX_SLAVE_DDRC_PORT4 6 /* DDR2 Port4 */ +#define H64MX_SLAVE_DDRC_PORT5 7 /* DDR2 Port5 */ +#define H64MX_SLAVE_DDRC_PORT6 8 /* DDR2 Port6 */ +#define H64MX_SLAVE_DDRC_PORT7 9 /* DDR2 Port7 */ +#define H64MX_SLAVE_SRAM 10 /* Internal SRAM 128K */ +#define H64MX_SLAVE_CACHE_L2 11 /* Internal SRAM 128K(L2) */ +#define H64MX_SLAVE_QSPI0 12 /* QSPI0 */ +#define H64MX_SLAVE_QSPI1 13 /* QSPI1 */ +#define H64MX_SLAVE_AESB 14 /* AESB */ + +/* MATRIX1(H32MX) slave id definitions */ +#define H32MX_SLAVE_H64MX_BRIDGE 0 /* Bridge from H32MX to H64MX */ +#define H32MX_SLAVE_PERIPH_BRIDGE0 1 /* H32MX Peripheral Bridge 0 */ +#define H32MX_SLAVE_PERIPH_BRIDGE1 2 /* H32MX Peripheral Bridge 1 */ +#define H32MX_SLAVE_EBI 3 /* External Bus Interface */ +#define H32MX_SLAVE_NFC_CMD 3 /* NFC command Register */ +#define H32MX_SLAVE_NFC_SRAM 4 /* NFC SRAM */ +#define H32MX_SLAVE_USB 5 /* USB Device & Host */ + /* SAMA5D2 series chip id definitions */ #define ARCH_ID_SAMA5D2 0x8a5c08c0 #define ARCH_EXID_SAMA5D21CU 0x0000005a diff --git a/board/atmel/sama5d2_xplained/sama5d2_xplained.c b/board/atmel/sama5d2_xplained/sama5d2_xplained.c index 0b3397fa09..8ed01ddbea 100644 --- a/board/atmel/sama5d2_xplained/sama5d2_xplained.c +++ b/board/atmel/sama5d2_xplained/sama5d2_xplained.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -281,3 +282,105 @@ int board_eth_init(bd_t *bis) return rc; } + +/* SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ +#ifdef CONFIG_SYS_USE_SERIALFLASH + board_spi0_hw_init(); +#endif +#ifdef CONFIG_ATMEL_SDHCI +#ifdef CONFIG_ATMEL_SDHCI0 + board_sdhci0_hw_init(); +#endif +#ifdef CONFIG_ATMEL_SDHCI1 + board_sdhci1_hw_init(); +#endif +#endif +} + +static void ddrc_conf(struct atmel_mpddrc_config *ddrc) +{ + ddrc->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR3_SDRAM); + + ddrc->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_DDR_CAS5 | + ATMEL_MPDDRC_CR_DIC_DS | + ATMEL_MPDDRC_CR_DIS_DLL | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + + ddrc->rtr = 0x511; + + ddrc->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET | + 4 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | + 9 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | + 4 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | + 4 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | + 4 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); + + ddrc->tpr1 = (27 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET | + 29 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | + 0 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | + 3 << ATMEL_MPDDRC_TPR1_TXP_OFFSET); + + ddrc->tpr2 = (0 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET | + 0 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | + 0 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | + 4 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | + 7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET); +} + +void mem_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + struct atmel_mpddr *mpddrc = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; + struct atmel_mpddrc_config ddrc_config; + u32 reg; + + ddrc_conf(&ddrc_config); + + at91_periph_clk_enable(ATMEL_ID_MPDDRC); + writel(AT91_PMC_DDR, &pmc->scer); + + reg = readl(&mpddrc->io_calibr); + reg &= ~ATMEL_MPDDRC_IO_CALIBR_RDIV; + reg |= ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55; + reg &= ~ATMEL_MPDDRC_IO_CALIBR_TZQIO; + reg |= ATMEL_MPDDRC_IO_CALIBR_TZQIO_(100); + writel(reg, &mpddrc->io_calibr); + + writel(ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_TWO_CYCLE, + &mpddrc->rd_data_path); + + ddr3_init(ATMEL_BASE_MPDDRC, ATMEL_BASE_DDRCS, &ddrc_config); + + writel(0x3, &mpddrc->cal_mr4); + writel(64, &mpddrc->tim_cal); +} + +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(82) | + AT91_PMC_PLLXR_DIV(1); + at91_plla_init(tmp); + + writel(0x0 << 8, &pmc->pllicpr); + + tmp = AT91_PMC_MCKR_H32MXDIV | + AT91_PMC_MCKR_PLLADIV_2 | + AT91_PMC_MCKR_MDIV_3 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp); +} +#endif diff --git a/configs/sama5d2_xplained_mmc_defconfig b/configs/sama5d2_xplained_mmc_defconfig index c1dcbefcc3..75b17131be 100644 --- a/configs/sama5d2_xplained_mmc_defconfig +++ b/configs/sama5d2_xplained_mmc_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_AT91=y CONFIG_TARGET_SAMA5D2_XPLAINED=y +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_MMC" # CONFIG_CMD_IMI is not set # CONFIG_CMD_IMLS is not set diff --git a/configs/sama5d2_xplained_spiflash_defconfig b/configs/sama5d2_xplained_spiflash_defconfig index 0271e8ef8d..6d61a7eb23 100644 --- a/configs/sama5d2_xplained_spiflash_defconfig +++ b/configs/sama5d2_xplained_spiflash_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_AT91=y CONFIG_TARGET_SAMA5D2_XPLAINED=y +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_SERIALFLASH" # CONFIG_CMD_IMI is not set # CONFIG_CMD_IMLS is not set diff --git a/include/configs/sama5d2_xplained.h b/include/configs/sama5d2_xplained.h index ae5ba3dd57..272257ea0e 100644 --- a/include/configs/sama5d2_xplained.h +++ b/include/configs/sama5d2_xplained.h @@ -25,8 +25,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 0x210000 +#else #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) +#endif #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ @@ -119,4 +123,39 @@ #endif +/* SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x200000 +#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 +#define CONFIG_SYS_MONITOR_LEN (512 << 10) + +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_SPL_LDSCRIPT arch/arm/mach-at91/armv7/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_MMCSD_FS_BOOT_PARTITION 1 +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +#define CONFIG_SPL_FAT_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT + +#elif CONFIG_SYS_USE_SERIALFLASH +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x8000 + +#endif + #endif