From b4670a0c2bb9fd0a141436626d1853f995c8ed54 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 5 Nov 2015 20:58:30 +0100 Subject: mmc: atmel: Properly fix clock configuration 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(-) (limited to 'drivers') diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index da870c646eb..0474a154843 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; } -- cgit v1.2.3 From 75b03cf14ccbe2371cd11e410238fff0a02e72b5 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 16 Dec 2015 14:50:34 +0100 Subject: net: macb: Not all the GEM are gigabit capable 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(-) (limited to 'drivers') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index a5c188066ca..be0659a52c8 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)) { -- cgit v1.2.3 From 3a2056719968c82fb0b5e079b47a146f68330879 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:33 +0800 Subject: atmel_nand: use nand ecc_{strength, step}_ds instead of our own function 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(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 0d4f327ed71..e179f742297 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; } -- cgit v1.2.3 From 4c6a6ea3e11844f1b7242d7ed4468bb80ae81369 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:34 +0800 Subject: atmel_nand: add '\n' in the end of error message for better display 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(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e179f742297..852883bfb2e 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; } -- cgit v1.2.3 From 422b49e2895ef61a1cc454aca6dd79a8e2279eff Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 25 Jan 2016 14:06:35 +0800 Subject: atmel_nand: use the definition: PMECC_OOB_RESERVED_BYTES instead magic number 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(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 852883bfb2e..73fd403886a 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; } -- cgit v1.2.3 From fa651f5d53372dd7a40fd2bcf701694d359820ce Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 24 Nov 2015 16:34:00 +0800 Subject: atmel_nand_ecc: update pmecc registers according to sama5d2 chip 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(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index 79e399489ea..e13f38503fa 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 -- cgit v1.2.3 From 258b21fc69c93172d8e4afaeff3a7303740ce7c6 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 24 Nov 2015 16:34:01 +0800 Subject: atmel_nand: Add 32 bit ecc support for sama5d2 chip 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(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 73fd403886a..7cc1de03134 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 ) */ -- cgit v1.2.3