X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fddr%2Ffsl%2Ffsl_ddr_gen4.c;h=3349fc5c3b5907a4195c74b539dbb3002614d4e2;hb=235c5b8315c6a9eb566fd3d99a098cc6db869fc5;hp=49e4688351e224a651bc1b6eaeabc259d34b0a66;hpb=86e6f7eaa15f0aca03bb7c961902563348c2dd05;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 49e4688..3349fc5 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -10,8 +10,14 @@ #include #include #include +#include +#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ + defined(CONFIG_ARM) +#include +#endif -#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \ + defined(CONFIG_SYS_FSL_ERRATUM_A009803) static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) { int timeout = 1000; @@ -23,9 +29,9 @@ static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) timeout--; } if (timeout <= 0) - puts("Error: A007865 wait for clear timeout.\n"); + puts("Error: wait for clear timeout.\n"); } -#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */ +#endif #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL @@ -45,15 +51,15 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, { unsigned int i, bus_width; struct ccsr_ddr __iomem *ddr; - u32 temp_sdram_cfg; + u32 temp32; u32 total_gb_size_per_controller; int timeout; -#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ - defined(CONFIG_SYS_FSL_ERRATUM_A008514) - u32 *eddrtqcr1; -#endif + #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 - u32 temp32, mr6; + u32 mr6; + u32 vref_seq1[3] = {0x80, 0x96, 0x16}; /* for range 1 */ + u32 vref_seq2[3] = {0xc0, 0xf0, 0x70}; /* for range 2 */ + u32 *vref_seq = vref_seq1; #endif #ifdef CONFIG_FSL_DDR_BIST u32 mtcr, err_detect, err_sbe; @@ -62,40 +68,23 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, #ifdef CONFIG_FSL_DDR_BIST char buffer[CONFIG_SYS_CBSIZE]; #endif - switch (ctrl_num) { case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; -#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ - defined(CONFIG_SYS_FSL_ERRATUM_A008514) - eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; -#endif break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; -#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ - defined(CONFIG_SYS_FSL_ERRATUM_A008514) - eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800; -#endif break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; -#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ - defined(CONFIG_SYS_FSL_ERRATUM_A008514) - eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800; -#endif break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; -#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \ - defined(CONFIG_SYS_FSL_ERRATUM_A008514) - eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800; -#endif break; #endif default: @@ -106,20 +95,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, if (step == 2) goto step2; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008336 -#ifdef CONFIG_LS2085A - /* A008336 only applies to general DDR controllers */ - if ((ctrl_num == 0) || (ctrl_num == 1)) -#endif - ddr_out32(eddrtqcr1, 0x63b30002); -#endif -#ifdef CONFIG_SYS_FSL_ERRATUM_A008514 -#ifdef CONFIG_LS2085A - /* A008514 only applies to DP-DDR controler */ - if (ctrl_num == 2) -#endif - ddr_out32(eddrtqcr1, 0x63b20002); -#endif if (regs->ddr_eor) ddr_out32(&ddr->eor, regs->ddr_eor); @@ -181,7 +156,12 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15); ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16); ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl); +#ifdef CONFIG_SYS_FSL_ERRATUM_A009663 + ddr_out32(&ddr->sdram_interval, + regs->ddr_sdram_interval & ~SDRAM_INTERVAL_BSTOPRE); +#else ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); +#endif ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); #ifndef CONFIG_SYS_FSL_DDR_EMU @@ -222,37 +202,70 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); } + +#ifdef CONFIG_SYS_FSL_ERRATUM_A009803 + /* part 1 of 2 */ + if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { + if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */ + ddr_out32(&ddr->ddr_sdram_rcw_2, + regs->ddr_sdram_rcw_2 & ~0x0f000000); + } + ddr_out32(&ddr->err_disable, regs->err_disable | + DDR_ERR_DISABLE_APED); + } +#else ddr_out32(&ddr->err_disable, regs->err_disable); +#endif ddr_out32(&ddr->err_int_en, regs->err_int_en); - for (i = 0; i < 32; i++) { + for (i = 0; i < 64; i++) { if (regs->debug[i]) { debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]); ddr_out32(&ddr->debug[i], regs->debug[i]); } } -#ifdef CONFIG_SYS_FSL_ERRATUM_A008378 - /* Erratum applies when accumulated ECC is used, or DBI is enabled */ -#define IS_ACC_ECC_EN(v) ((v) & 0x4) -#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2) - if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) || - IS_DBI(regs->ddr_sdram_cfg_3)) - ddr_setbits32(ddr->debug[28], 0x9 << 20); -#endif #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 /* Part 1 of 2 */ - /* This erraum only applies to verion 5.2.0 */ if (fsl_ddr_get_version(ctrl_num) == 0x50200) { /* Disable DRAM VRef training */ ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); - /* Disable deskew */ - ddr_out32(&ddr->debug[28], 0x400); - /* Disable D_INIT */ - ddr_out32(&ddr->sdram_cfg_2, - regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + /* disable transmit bit deskew */ + temp32 = ddr_in32(&ddr->debug[28]); + temp32 |= DDR_TX_BD_DIS; + ddr_out32(&ddr->debug[28], temp32); ddr_out32(&ddr->debug[25], 0x9000); + } else if (fsl_ddr_get_version(ctrl_num) == 0x50201) { + /* Output enable forced off */ + ddr_out32(&ddr->debug[37], 1 << 31); + /* Enable Vref training */ + ddr_out32(&ddr->ddr_cdr2, + regs->ddr_cdr2 | DDR_CDR2_VREF_TRAIN_EN); + } else { + debug("Erratum A008511 doesn't apply.\n"); + } +#endif + +#if defined(CONFIG_SYS_FSL_ERRATUM_A009803) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A008511) + /* Disable D_INIT */ + ddr_out32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); +#endif + +#ifdef CONFIG_SYS_FSL_ERRATUM_A009801 + temp32 = ddr_in32(&ddr->debug[25]); + temp32 &= ~DDR_CAS_TO_PRE_SUB_MASK; + temp32 |= 9 << DDR_CAS_TO_PRE_SUB_SHIFT; + ddr_out32(&ddr->debug[25], temp32); +#endif + +#ifdef CONFIG_SYS_FSL_ERRATUM_A010165 + temp32 = get_ddr_freq(ctrl_num) / 1000000; + if ((temp32 > 1900) && (temp32 < 2300)) { + temp32 = ddr_in32(&ddr->debug[28]); + ddr_out32(&ddr->debug[28], temp32 | 0x000a0000); } #endif /* @@ -270,9 +283,9 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, step2: /* Set, but do not enable the memory */ - temp_sdram_cfg = regs->ddr_sdram_cfg; - temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); - ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg); + temp32 = regs->ddr_sdram_cfg; + temp32 &= ~(SDRAM_CFG_MEM_EN); + ddr_out32(&ddr->sdram_cfg, temp32); /* * 500 painful micro-seconds must elapse between @@ -287,36 +300,43 @@ step2: #ifdef CONFIG_DEEP_SLEEP if (is_warm_boot()) { /* enter self-refresh */ - temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); - temp_sdram_cfg |= SDRAM_CFG2_FRC_SR; - ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + temp32 = ddr_in32(&ddr->sdram_cfg_2); + temp32 |= SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp32); /* do board specific memory setup */ board_mem_sleep_setup(); - temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); + temp32 = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); } else #endif - temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; + temp32 = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; /* Let the controller go */ - ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); + ddr_out32(&ddr->sdram_cfg, temp32 | SDRAM_CFG_MEM_EN); mb(); isb(); -#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 +#if defined(CONFIG_SYS_FSL_ERRATUM_A008511) || \ + defined(CONFIG_SYS_FSL_ERRATUM_A009803) /* Part 2 of 2 */ + timeout = 40; + /* Wait for idle. D_INIT needs to be cleared earlier, or timeout */ + while (!(ddr_in32(&ddr->debug[1]) & 0x2) && + (timeout > 0)) { + udelay(1000); + timeout--; + } + if (timeout <= 0) { + printf("Controler %d timeout, debug_2 = %x\n", + ctrl_num, ddr_in32(&ddr->debug[1])); + } + +#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 /* This erraum only applies to verion 5.2.0 */ if (fsl_ddr_get_version(ctrl_num) == 0x50200) { - /* Wait for idle */ - timeout = 200; - while (!(ddr_in32(&ddr->debug[1]) & 0x2) && - (timeout > 0)) { - udelay(100); - timeout--; - } - if (timeout <= 0) { - printf("Controler %d timeout, debug_2 = %x\n", - ctrl_num, ddr_in32(&ddr->debug[1])); - } + /* The vref setting sequence is different for range 2 */ + if (regs->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2) + vref_seq = vref_seq2; + /* Set VREF */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN)) @@ -327,41 +347,65 @@ step2: MD_CNTL_CS_SEL(i) | MD_CNTL_MD_SEL(6) | 0x00200000; - temp32 = mr6 | 0xc0; + temp32 = mr6 | vref_seq[0]; set_wait_for_bits_clear(&ddr->sdram_md_cntl, temp32, MD_CNTL_MD_EN); udelay(1); debug("MR6 = 0x%08x\n", temp32); - temp32 = mr6 | 0xf0; + temp32 = mr6 | vref_seq[1]; set_wait_for_bits_clear(&ddr->sdram_md_cntl, temp32, MD_CNTL_MD_EN); udelay(1); debug("MR6 = 0x%08x\n", temp32); - temp32 = mr6 | 0x70; + temp32 = mr6 | vref_seq[2]; set_wait_for_bits_clear(&ddr->sdram_md_cntl, temp32, MD_CNTL_MD_EN); udelay(1); debug("MR6 = 0x%08x\n", temp32); } ddr_out32(&ddr->sdram_md_cntl, 0); - ddr_out32(&ddr->debug[28], 0); /* Enable deskew */ + temp32 = ddr_in32(&ddr->debug[28]); + temp32 &= ~DDR_TX_BD_DIS; /* Enable deskew */ + ddr_out32(&ddr->debug[28], temp32); ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */ /* wait for idle */ - timeout = 200; + timeout = 40; while (!(ddr_in32(&ddr->debug[1]) & 0x2) && (timeout > 0)) { - udelay(100); + udelay(1000); timeout--; } if (timeout <= 0) { printf("Controler %d timeout, debug_2 = %x\n", ctrl_num, ddr_in32(&ddr->debug[1])); } - /* Restore D_INIT */ - ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); } #endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009803 + if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { + /* if it's RDIMM */ + if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN)) + continue; + set_wait_for_bits_clear(&ddr->sdram_md_cntl, + MD_CNTL_MD_EN | + MD_CNTL_CS_SEL(i) | + 0x070000ed, + MD_CNTL_MD_EN); + udelay(1); + } + } + + ddr_out32(&ddr->err_disable, + regs->err_disable & ~DDR_ERR_DISABLE_APED); + } +#endif + /* Restore D_INIT */ + ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); +#endif + total_gb_size_per_controller = 0; for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (!(regs->cs[i].config & 0x80000000)) @@ -402,12 +446,17 @@ step2: if (timeout <= 0) printf("Waiting for D_INIT timeout. Memory may not work.\n"); + +#ifdef CONFIG_SYS_FSL_ERRATUM_A009663 + ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); +#endif + #ifdef CONFIG_DEEP_SLEEP if (is_warm_boot()) { /* exit self-refresh */ - temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); - temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR; - ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + temp32 = ddr_in32(&ddr->sdram_cfg_2); + temp32 &= ~SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp32); } #endif @@ -423,16 +472,16 @@ step2: if (getenv_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) { puts("Running BIST test. This will take a while..."); cs0_config = ddr_in32(&ddr->cs0_config); + cs0_bnds = ddr_in32(&ddr->cs0_bnds); + cs1_bnds = ddr_in32(&ddr->cs1_bnds); + cs2_bnds = ddr_in32(&ddr->cs2_bnds); + cs3_bnds = ddr_in32(&ddr->cs3_bnds); if (cs0_config & CTLR_INTLV_MASK) { - cs0_bnds = ddr_in32(&cs0_bnds); - cs1_bnds = ddr_in32(&cs1_bnds); - cs2_bnds = ddr_in32(&cs2_bnds); - cs3_bnds = ddr_in32(&cs3_bnds); /* set bnds to non-interleaving */ - ddr_out32(&cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1); - ddr_out32(&cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1); - ddr_out32(&cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1); - ddr_out32(&cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1); + ddr_out32(&ddr->cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1); + ddr_out32(&ddr->cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1); + ddr_out32(&ddr->cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1); + ddr_out32(&ddr->cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1); } ddr_out32(&ddr->mtp1, BIST_PATTERN1); ddr_out32(&ddr->mtp2, BIST_PATTERN1); @@ -469,10 +518,10 @@ step2: if (cs0_config & CTLR_INTLV_MASK) { /* restore bnds registers */ - ddr_out32(&cs0_bnds, cs0_bnds); - ddr_out32(&cs1_bnds, cs1_bnds); - ddr_out32(&cs2_bnds, cs2_bnds); - ddr_out32(&cs3_bnds, cs3_bnds); + ddr_out32(&ddr->cs0_bnds, cs0_bnds); + ddr_out32(&ddr->cs1_bnds, cs1_bnds); + ddr_out32(&ddr->cs2_bnds, cs2_bnds); + ddr_out32(&ddr->cs3_bnds, cs3_bnds); } } #endif