From patchwork Wed Jan 26 06:22:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Gala X-Patchwork-Id: 80451 X-Patchwork-Delegate: galak@kernel.crashing.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 113D81007D1 for ; Wed, 26 Jan 2011 17:23:24 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 438EC280C0; Wed, 26 Jan 2011 07:23:00 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZPDSjUepMZxF; Wed, 26 Jan 2011 07:23:00 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EAF62280C8; Wed, 26 Jan 2011 07:22:40 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 237692808D for ; Wed, 26 Jan 2011 07:22:31 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aGNOH3qldSTn for ; Wed, 26 Jan 2011 07:22:30 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) by theia.denx.de (Postfix) with ESMTPS id 605292809D for ; Wed, 26 Jan 2011 07:22:25 +0100 (CET) Received: from localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id p0Q6MLia030988; Wed, 26 Jan 2011 00:22:21 -0600 From: Kumar Gala To: u-boot@lists.denx.de Date: Wed, 26 Jan 2011 00:22:17 -0600 Message-Id: <1296022938-19899-4-git-send-email-galak@kernel.crashing.org> X-Mailer: git-send-email 1.6.0.6 In-Reply-To: <1296022938-19899-3-git-send-email-galak@kernel.crashing.org> References: <1296022938-19899-1-git-send-email-galak@kernel.crashing.org> <1296022938-19899-2-git-send-email-galak@kernel.crashing.org> <1296022938-19899-3-git-send-email-galak@kernel.crashing.org> Cc: York Sun Subject: [U-Boot] [PATCH 4/5] powerpc/mpc85xx: implement workaround for errata DDR111 and DDR134 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: York Sun Workaround for the following errata: DDR111 - MCKE signal may not function correctly at assertion of HRESET DDR134 - The automatic CAS-to-Preamble feature of the DDR controller can calibrate to incorrect values These two workarounds must be implemented together because they touch common registers. Signed-off-by: York Sun Signed-off-by: Kumar Gala --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 4 + arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 107 ++++++++++++++++++++++++++++- arch/powerpc/include/asm/config_mpc85xx.h | 1 + arch/powerpc/include/asm/fsl_ddr_sdram.h | 5 ++ 4 files changed, 116 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 94a5876..feee36c 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -74,6 +74,10 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115 puts("Work-around for Erratum DDR115 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + puts("Work-around for Erratum DDR111 enabled\n"); + puts("Work-around for Erratum DDR134 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 35997f2..73b320b 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -21,6 +21,10 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, unsigned int i; volatile ccsr_ddr_t *ddr; u32 temp_sdram_cfg; +#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR; + u32 total_gb_size_per_controller; +#endif switch (ctrl_num) { case 0: @@ -185,6 +189,26 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, setbits_be32(&ddr->debug[0], 1); } #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + /* + * This is the combined workaround for DDR111 and DDR134 + * following the published errata for MPC8572 + */ + + /* 1. Set EEBACR[3] */ + setbits_be32(&ecm->eebacr, 0x10000000); + debug("Setting EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr)); + + /* 2. Set DINIT in SDRAM_CFG_2*/ + setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_D_INIT); + debug("Setting sdram_cfg_2[D_INIT] to 0x%08x\n", + in_be32(&ddr->sdram_cfg_2)); + + /* 3. Set DEBUG_3[21] */ + setbits_be32(&ddr->debug[2], 0x400); + debug("Setting DEBUG_3[21] to 0x%08x\n", in_be32(&ddr->debug[2])); + +#endif /* part 1 of the workaound */ /* * 500 painful micro-seconds must elapse between @@ -201,7 +225,88 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, asm volatile("sync;isync"); /* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */ - while (in_be32(&ddr->sdram_cfg_2) & 0x10) { + while (in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) udelay(10000); /* throttle polling rate */ + +#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + /* continue this workaround */ + + /* 4. Clear DEBUG3[21] */ + clrbits_be32(&ddr->debug[2], 0x400); + debug("Clearing D3[21] to 0x%08x\n", in_be32(&ddr->debug[2])); + + /* DDR134 workaround starts */ + /* A: Clear sdram_cfg_2[odt_cfg] */ + clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_ODT_CFG_MASK); + debug("Clearing SDRAM_CFG2[ODT_CFG] to 0x%08x\n", + in_be32(&ddr->sdram_cfg_2)); + + /* B: Set DEBUG1[15] */ + setbits_be32(&ddr->debug[0], 0x10000); + debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0])); + + /* C: Set timing_cfg_2[cpo] to 0b11111 */ + setbits_be32(&ddr->timing_cfg_2, TIMING_CFG_2_CPO_MASK); + debug("Setting TMING_CFG_2[CPO] to 0x%08x\n", + in_be32(&ddr->timing_cfg_2)); + + /* D: Set D6 to 0x9f9f9f9f */ + out_be32(&ddr->debug[5], 0x9f9f9f9f); + debug("Setting D6 to 0x%08x\n", in_be32(&ddr->debug[5])); + + /* E: Set D7 to 0x9f9f9f9f */ + out_be32(&ddr->debug[6], 0x9f9f9f9f); + debug("Setting D7 to 0x%08x\n", in_be32(&ddr->debug[6])); + + /* F: Set D2[20] */ + setbits_be32(&ddr->debug[1], 0x800); + debug("Setting D2[20] to 0x%08x\n", in_be32(&ddr->debug[1])); + + /* G: Poll on D2[20] until cleared */ + while (in_be32(&ddr->debug[1]) & 0x800) + udelay(10000); /* throttle polling rate */ + + /* H: Clear D1[15] */ + clrbits_be32(&ddr->debug[0], 0x10000); + debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0])); + + /* I: Set sdram_cfg_2[odt_cfg] */ + setbits_be32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & SDRAM_CFG2_ODT_CFG_MASK); + debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2)); + + /* Continuing with the DDR111 workaround */ + /* 5. Set D2[21] */ + setbits_be32(&ddr->debug[1], 0x400); + debug("Setting D2[21] to 0x%08x\n", in_be32(&ddr->debug[1])); + + /* 6. Poll D2[21] until its cleared */ + while (in_be32(&ddr->debug[1]) & 0x400) + udelay(10000); /* throttle polling rate */ + + /* 7. Wait for 400ms/GB */ + total_gb_size_per_controller = 0; + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + total_gb_size_per_controller += + ((regs->cs[i].bnds & 0xFFFF) >> 6) + - (regs->cs[i].bnds >> 22) + 1; } + if (in_be32(&ddr->sdram_cfg) & 0x80000) + total_gb_size_per_controller <<= 1; + debug("Wait for %d ms\n", total_gb_size_per_controller * 400); + udelay(total_gb_size_per_controller * 400000); + + /* 8. Set sdram_cfg_2[dinit] if options requires */ + setbits_be32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & SDRAM_CFG2_D_INIT); + debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2)); + + /* 9. Poll until dinit is cleared */ + while (in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) + udelay(10000); + + /* 10. Clear EEBACR[3] */ + clrbits_be32(&ecm->eebacr, 10000000); + debug("Clearing EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr)); +#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ } diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 8ef9743..57d252c 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -78,6 +78,7 @@ #define CONFIG_SYS_FSL_NUM_LAWS 12 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_FSL_ERRATUM_DDR_115 +#define CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 #elif defined(CONFIG_P1010) #define CONFIG_MAX_CPUS 1 diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 73bc023..b5b1efe 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -89,6 +89,11 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define SDRAM_CFG_2T_EN 0x00008000 #define SDRAM_CFG_BI 0x00000001 +#define SDRAM_CFG2_D_INIT 0x00000010 +#define SDRAM_CFG2_ODT_CFG_MASK 0x00600000 + +#define TIMING_CFG_2_CPO_MASK 0x0F800000 + #if defined(CONFIG_P4080) #define RD_TO_PRE_MASK 0xf #define RD_TO_PRE_SHIFT 13