1*b35ce0c4SPankaj Gupta /* 2*b35ce0c4SPankaj Gupta * Copyright 2021 NXP 3*b35ce0c4SPankaj Gupta * 4*b35ce0c4SPankaj Gupta * SPDX-License-Identifier: BSD-3-Clause 5*b35ce0c4SPankaj Gupta * 6*b35ce0c4SPankaj Gupta */ 7*b35ce0c4SPankaj Gupta 8*b35ce0c4SPankaj Gupta #include <errno.h> 9*b35ce0c4SPankaj Gupta #include <stdbool.h> 10*b35ce0c4SPankaj Gupta #include <stdint.h> 11*b35ce0c4SPankaj Gupta #include <stdio.h> 12*b35ce0c4SPankaj Gupta #include <stdlib.h> 13*b35ce0c4SPankaj Gupta 14*b35ce0c4SPankaj Gupta #include <common/debug.h> 15*b35ce0c4SPankaj Gupta #include <ddr.h> 16*b35ce0c4SPankaj Gupta #include <drivers/delay_timer.h> 17*b35ce0c4SPankaj Gupta #include <immap.h> 18*b35ce0c4SPankaj Gupta 19*b35ce0c4SPankaj Gupta #define BIST_CR 0x80060000 20*b35ce0c4SPankaj Gupta #define BIST_CR_EN 0x80000000 21*b35ce0c4SPankaj Gupta #define BIST_CR_STAT 0x00000001 22*b35ce0c4SPankaj Gupta #define CTLR_INTLV_MASK 0x20000000 23*b35ce0c4SPankaj Gupta 24*b35ce0c4SPankaj Gupta #pragma weak run_bist 25*b35ce0c4SPankaj Gupta 26*b35ce0c4SPankaj Gupta bool run_bist(void) 27*b35ce0c4SPankaj Gupta { 28*b35ce0c4SPankaj Gupta #ifdef BIST_EN 29*b35ce0c4SPankaj Gupta return true; 30*b35ce0c4SPankaj Gupta #else 31*b35ce0c4SPankaj Gupta return false; 32*b35ce0c4SPankaj Gupta #endif 33*b35ce0c4SPankaj Gupta } 34*b35ce0c4SPankaj Gupta 35*b35ce0c4SPankaj Gupta /* 36*b35ce0c4SPankaj Gupta * Perform build-in test on memory 37*b35ce0c4SPankaj Gupta * timeout value in 10ms 38*b35ce0c4SPankaj Gupta */ 39*b35ce0c4SPankaj Gupta int bist(const struct ccsr_ddr *ddr, int timeout) 40*b35ce0c4SPankaj Gupta { 41*b35ce0c4SPankaj Gupta const unsigned int test_pattern[10] = { 42*b35ce0c4SPankaj Gupta 0xffffffff, 43*b35ce0c4SPankaj Gupta 0x00000000, 44*b35ce0c4SPankaj Gupta 0xaaaaaaaa, 45*b35ce0c4SPankaj Gupta 0x55555555, 46*b35ce0c4SPankaj Gupta 0xcccccccc, 47*b35ce0c4SPankaj Gupta 0x33333333, 48*b35ce0c4SPankaj Gupta 0x12345678, 49*b35ce0c4SPankaj Gupta 0xabcdef01, 50*b35ce0c4SPankaj Gupta 0xaa55aa55, 51*b35ce0c4SPankaj Gupta 0x55aa55aa 52*b35ce0c4SPankaj Gupta }; 53*b35ce0c4SPankaj Gupta unsigned int mtcr, err_detect, err_sbe; 54*b35ce0c4SPankaj Gupta unsigned int cs0_config; 55*b35ce0c4SPankaj Gupta unsigned int csn_bnds[4]; 56*b35ce0c4SPankaj Gupta int ret = 0; 57*b35ce0c4SPankaj Gupta uint32_t i; 58*b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC 59*b35ce0c4SPankaj Gupta uint32_t dec_9 = ddr_in32(&ddr->dec[9]); 60*b35ce0c4SPankaj Gupta uint32_t pos = 0U; 61*b35ce0c4SPankaj Gupta uint32_t map_save = 0U; 62*b35ce0c4SPankaj Gupta uint32_t temp32 = 0U; 63*b35ce0c4SPankaj Gupta uint32_t map, shift, highest; 64*b35ce0c4SPankaj Gupta #endif 65*b35ce0c4SPankaj Gupta 66*b35ce0c4SPankaj Gupta cs0_config = ddr_in32(&ddr->csn_cfg[0]); 67*b35ce0c4SPankaj Gupta if ((cs0_config & CTLR_INTLV_MASK) != 0U) { 68*b35ce0c4SPankaj Gupta /* set bnds to non-interleaving */ 69*b35ce0c4SPankaj Gupta for (i = 0U; i < 4U; i++) { 70*b35ce0c4SPankaj Gupta csn_bnds[i] = ddr_in32(&ddr->bnds[i].a); 71*b35ce0c4SPankaj Gupta ddr_out32(&ddr->bnds[i].a, 72*b35ce0c4SPankaj Gupta (csn_bnds[i] & U(0xfffefffe)) >> 1U); 73*b35ce0c4SPankaj Gupta } 74*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg[0], cs0_config & ~CTLR_INTLV_MASK); 75*b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC 76*b35ce0c4SPankaj Gupta if ((dec_9 & 0x1U) != 0U) { 77*b35ce0c4SPankaj Gupta highest = (dec_9 >> 26U) == U(0x3F) ? 0U : dec_9 >> 26U; 78*b35ce0c4SPankaj Gupta pos = 37U; 79*b35ce0c4SPankaj Gupta for (i = 0U; i < 36U; i++) { /* Go through all 37 */ 80*b35ce0c4SPankaj Gupta if ((i % 4U) == 0U) { 81*b35ce0c4SPankaj Gupta temp32 = ddr_in32(&ddr->dec[i >> 2U]); 82*b35ce0c4SPankaj Gupta } 83*b35ce0c4SPankaj Gupta shift = (3U - i % 4U) * 8U + 2U; 84*b35ce0c4SPankaj Gupta map = (temp32 >> shift) & U(0x3F); 85*b35ce0c4SPankaj Gupta if (map > highest && map != U(0x3F)) { 86*b35ce0c4SPankaj Gupta highest = map; 87*b35ce0c4SPankaj Gupta pos = i; 88*b35ce0c4SPankaj Gupta } 89*b35ce0c4SPankaj Gupta } 90*b35ce0c4SPankaj Gupta debug("\nFound highest position %d, mapping to %d, ", 91*b35ce0c4SPankaj Gupta pos, highest); 92*b35ce0c4SPankaj Gupta map_save = ddr_in32(&ddr->dec[pos >> 2]); 93*b35ce0c4SPankaj Gupta shift = (3U - pos % 4U) * 8U + 2U; 94*b35ce0c4SPankaj Gupta debug("in dec[%d], bit %d (0x%x)\n", 95*b35ce0c4SPankaj Gupta pos >> 2U, shift, map_save); 96*b35ce0c4SPankaj Gupta temp32 = map_save & ~(U(0x3F) << shift); 97*b35ce0c4SPankaj Gupta temp32 |= 8U << shift; 98*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dec[pos >> 2U], temp32); 99*b35ce0c4SPankaj Gupta timeout <<= 2U; 100*b35ce0c4SPankaj Gupta debug("Increase wait time to %d ms\n", timeout * 10); 101*b35ce0c4SPankaj Gupta } 102*b35ce0c4SPankaj Gupta #endif 103*b35ce0c4SPankaj Gupta } 104*b35ce0c4SPankaj Gupta for (i = 0U; i < 10U; i++) { 105*b35ce0c4SPankaj Gupta ddr_out32(&ddr->mtp[i], test_pattern[i]); 106*b35ce0c4SPankaj Gupta } 107*b35ce0c4SPankaj Gupta mtcr = BIST_CR; 108*b35ce0c4SPankaj Gupta ddr_out32(&ddr->mtcr, mtcr); 109*b35ce0c4SPankaj Gupta do { 110*b35ce0c4SPankaj Gupta mdelay(10); 111*b35ce0c4SPankaj Gupta mtcr = ddr_in32(&ddr->mtcr); 112*b35ce0c4SPankaj Gupta } while (timeout-- > 0 && ((mtcr & BIST_CR_EN) != 0)); 113*b35ce0c4SPankaj Gupta if (timeout <= 0) { 114*b35ce0c4SPankaj Gupta ERROR("Timeout\n"); 115*b35ce0c4SPankaj Gupta } else { 116*b35ce0c4SPankaj Gupta debug("Timer remains %d\n", timeout); 117*b35ce0c4SPankaj Gupta } 118*b35ce0c4SPankaj Gupta 119*b35ce0c4SPankaj Gupta err_detect = ddr_in32(&ddr->err_detect); 120*b35ce0c4SPankaj Gupta err_sbe = ddr_in32(&ddr->err_sbe); 121*b35ce0c4SPankaj Gupta if (err_detect != 0U || ((err_sbe & U(0xffff)) != 0U)) { 122*b35ce0c4SPankaj Gupta ERROR("ECC error detected\n"); 123*b35ce0c4SPankaj Gupta ret = -EIO; 124*b35ce0c4SPankaj Gupta } 125*b35ce0c4SPankaj Gupta 126*b35ce0c4SPankaj Gupta if ((cs0_config & CTLR_INTLV_MASK) != 0) { 127*b35ce0c4SPankaj Gupta for (i = 0U; i < 4U; i++) { 128*b35ce0c4SPankaj Gupta ddr_out32(&ddr->bnds[i].a, csn_bnds[i]); 129*b35ce0c4SPankaj Gupta } 130*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg[0], cs0_config); 131*b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC 132*b35ce0c4SPankaj Gupta if ((dec_9 & U(0x1)) != 0U) { 133*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dec[pos >> 2], map_save); 134*b35ce0c4SPankaj Gupta } 135*b35ce0c4SPankaj Gupta #endif 136*b35ce0c4SPankaj Gupta } 137*b35ce0c4SPankaj Gupta if ((mtcr & BIST_CR_STAT) != 0) { 138*b35ce0c4SPankaj Gupta ERROR("Built-in self test failed\n"); 139*b35ce0c4SPankaj Gupta ret = -EIO; 140*b35ce0c4SPankaj Gupta } else { 141*b35ce0c4SPankaj Gupta NOTICE("Build-in self test passed\n"); 142*b35ce0c4SPankaj Gupta } 143*b35ce0c4SPankaj Gupta 144*b35ce0c4SPankaj Gupta return ret; 145*b35ce0c4SPankaj Gupta } 146*b35ce0c4SPankaj Gupta 147*b35ce0c4SPankaj Gupta void dump_ddrc(unsigned int *ddr) 148*b35ce0c4SPankaj Gupta { 149*b35ce0c4SPankaj Gupta #ifdef DDR_DEBUG 150*b35ce0c4SPankaj Gupta uint32_t i; 151*b35ce0c4SPankaj Gupta unsigned long val; 152*b35ce0c4SPankaj Gupta 153*b35ce0c4SPankaj Gupta for (i = 0U; i < U(0x400); i++, ddr++) { 154*b35ce0c4SPankaj Gupta val = ddr_in32(ddr); 155*b35ce0c4SPankaj Gupta if (val != 0U) { /* skip zeros */ 156*b35ce0c4SPankaj Gupta debug("*0x%lx = 0x%lx\n", (unsigned long)ddr, val); 157*b35ce0c4SPankaj Gupta } 158*b35ce0c4SPankaj Gupta } 159*b35ce0c4SPankaj Gupta #endif 160*b35ce0c4SPankaj Gupta } 161*b35ce0c4SPankaj Gupta 162*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803 163*b35ce0c4SPankaj Gupta static void set_wait_for_bits_clear(const void *ptr, 164*b35ce0c4SPankaj Gupta unsigned int value, 165*b35ce0c4SPankaj Gupta unsigned int bits) 166*b35ce0c4SPankaj Gupta { 167*b35ce0c4SPankaj Gupta int timeout = 1000; 168*b35ce0c4SPankaj Gupta 169*b35ce0c4SPankaj Gupta ddr_out32(ptr, value); 170*b35ce0c4SPankaj Gupta do { 171*b35ce0c4SPankaj Gupta udelay(100); 172*b35ce0c4SPankaj Gupta } while (timeout-- > 0 && ((ddr_in32(ptr) & bits) != 0)); 173*b35ce0c4SPankaj Gupta 174*b35ce0c4SPankaj Gupta if (timeout <= 0) { 175*b35ce0c4SPankaj Gupta ERROR("wait for clear timeout.\n"); 176*b35ce0c4SPankaj Gupta } 177*b35ce0c4SPankaj Gupta } 178*b35ce0c4SPankaj Gupta #endif 179*b35ce0c4SPankaj Gupta 180*b35ce0c4SPankaj Gupta #if (DDRC_NUM_CS > 4) 181*b35ce0c4SPankaj Gupta #error Invalid setting for DDRC_NUM_CS 182*b35ce0c4SPankaj Gupta #endif 183*b35ce0c4SPankaj Gupta 184*b35ce0c4SPankaj Gupta /* 185*b35ce0c4SPankaj Gupta * If supported by the platform, writing to DDR controller takes two 186*b35ce0c4SPankaj Gupta * passes to deassert DDR reset to comply with JEDEC specs for RDIMMs. 187*b35ce0c4SPankaj Gupta */ 188*b35ce0c4SPankaj Gupta int ddrc_set_regs(const unsigned long clk, 189*b35ce0c4SPankaj Gupta const struct ddr_cfg_regs *regs, 190*b35ce0c4SPankaj Gupta const struct ccsr_ddr *ddr, 191*b35ce0c4SPankaj Gupta int twopass) 192*b35ce0c4SPankaj Gupta { 193*b35ce0c4SPankaj Gupta unsigned int i, bus_width; 194*b35ce0c4SPankaj Gupta unsigned int temp_sdram_cfg; 195*b35ce0c4SPankaj Gupta unsigned int total_mem_per_ctrl, total_mem_per_ctrl_adj; 196*b35ce0c4SPankaj Gupta const int mod_bnds = regs->cs[0].config & CTLR_INTLV_MASK; 197*b35ce0c4SPankaj Gupta int timeout; 198*b35ce0c4SPankaj Gupta int ret = 0; 199*b35ce0c4SPankaj Gupta #if defined(ERRATA_DDR_A009942) || defined(ERRATA_DDR_A010165) 200*b35ce0c4SPankaj Gupta unsigned long ddr_freq; 201*b35ce0c4SPankaj Gupta unsigned int tmp; 202*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942 203*b35ce0c4SPankaj Gupta unsigned int check; 204*b35ce0c4SPankaj Gupta unsigned int cpo_min = U(0xff); 205*b35ce0c4SPankaj Gupta unsigned int cpo_max = 0U; 206*b35ce0c4SPankaj Gupta #endif 207*b35ce0c4SPankaj Gupta #endif 208*b35ce0c4SPankaj Gupta 209*b35ce0c4SPankaj Gupta if (twopass == 2U) { 210*b35ce0c4SPankaj Gupta goto after_reset; 211*b35ce0c4SPankaj Gupta } 212*b35ce0c4SPankaj Gupta 213*b35ce0c4SPankaj Gupta /* Set cdr1 first in case 0.9v VDD is enabled for some SoCs*/ 214*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_cdr1, regs->cdr[0]); 215*b35ce0c4SPankaj Gupta 216*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_clk_cntl, regs->clk_cntl); 217*b35ce0c4SPankaj Gupta 218*b35ce0c4SPankaj Gupta for (i = 0U; i < DDRC_NUM_CS; i++) { 219*b35ce0c4SPankaj Gupta if (mod_bnds != 0U) { 220*b35ce0c4SPankaj Gupta ddr_out32(&ddr->bnds[i].a, 221*b35ce0c4SPankaj Gupta (regs->cs[i].bnds & U(0xfffefffe)) >> 1U); 222*b35ce0c4SPankaj Gupta } else { 223*b35ce0c4SPankaj Gupta ddr_out32(&ddr->bnds[i].a, regs->cs[i].bnds); 224*b35ce0c4SPankaj Gupta } 225*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg_2[i], regs->cs[i].config_2); 226*b35ce0c4SPankaj Gupta } 227*b35ce0c4SPankaj Gupta 228*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg[0]); 229*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg[1]); 230*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg[2]); 231*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg[3]); 232*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg[4]); 233*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg[5]); 234*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg[6]); 235*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg[7]); 236*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg[8]); 237*b35ce0c4SPankaj Gupta ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg[9]); 238*b35ce0c4SPankaj Gupta ddr_out32(&ddr->zq_cntl, regs->zq_cntl); 239*b35ce0c4SPankaj Gupta for (i = 0U; i < 4U; i++) { 240*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dq_map[i], regs->dq_map[i]); 241*b35ce0c4SPankaj Gupta } 242*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_cfg_3, regs->sdram_cfg[2]); 243*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode, regs->sdram_mode[0]); 244*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_2, regs->sdram_mode[1]); 245*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_3, regs->sdram_mode[2]); 246*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_4, regs->sdram_mode[3]); 247*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_5, regs->sdram_mode[4]); 248*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_6, regs->sdram_mode[5]); 249*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_7, regs->sdram_mode[6]); 250*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_8, regs->sdram_mode[7]); 251*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_9, regs->sdram_mode[8]); 252*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_10, regs->sdram_mode[9]); 253*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_11, regs->sdram_mode[10]); 254*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_12, regs->sdram_mode[11]); 255*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_13, regs->sdram_mode[12]); 256*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_14, regs->sdram_mode[13]); 257*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_15, regs->sdram_mode[14]); 258*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_mode_16, regs->sdram_mode[15]); 259*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_md_cntl, regs->md_cntl); 260*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009663 261*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_interval, 262*b35ce0c4SPankaj Gupta regs->interval & ~SDRAM_INTERVAL_BSTOPRE); 263*b35ce0c4SPankaj Gupta #else 264*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_interval, regs->interval); 265*b35ce0c4SPankaj Gupta #endif 266*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_data_init, regs->data_init); 267*b35ce0c4SPankaj Gupta if (regs->eor != 0) { 268*b35ce0c4SPankaj Gupta ddr_out32(&ddr->eor, regs->eor); 269*b35ce0c4SPankaj Gupta } 270*b35ce0c4SPankaj Gupta 271*b35ce0c4SPankaj Gupta ddr_out32(&ddr->wrlvl_cntl, regs->wrlvl_cntl[0]); 272*b35ce0c4SPankaj Gupta #ifndef NXP_DDR_EMU 273*b35ce0c4SPankaj Gupta /* 274*b35ce0c4SPankaj Gupta * Skip these two registers if running on emulator 275*b35ce0c4SPankaj Gupta * because emulator doesn't have skew between bytes. 276*b35ce0c4SPankaj Gupta */ 277*b35ce0c4SPankaj Gupta 278*b35ce0c4SPankaj Gupta if (regs->wrlvl_cntl[1] != 0) { 279*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->wrlvl_cntl[1]); 280*b35ce0c4SPankaj Gupta } 281*b35ce0c4SPankaj Gupta if (regs->wrlvl_cntl[2] != 0) { 282*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->wrlvl_cntl[2]); 283*b35ce0c4SPankaj Gupta } 284*b35ce0c4SPankaj Gupta #endif 285*b35ce0c4SPankaj Gupta 286*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr); 287*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_1, regs->sdram_rcw[0]); 288*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_2, regs->sdram_rcw[1]); 289*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_3, regs->sdram_rcw[2]); 290*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_4, regs->sdram_rcw[3]); 291*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_5, regs->sdram_rcw[4]); 292*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_6, regs->sdram_rcw[5]); 293*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_cdr2, regs->cdr[1]); 294*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_cfg_2, regs->sdram_cfg[1]); 295*b35ce0c4SPankaj Gupta ddr_out32(&ddr->init_addr, regs->init_addr); 296*b35ce0c4SPankaj Gupta ddr_out32(&ddr->init_ext_addr, regs->init_ext_addr); 297*b35ce0c4SPankaj Gupta 298*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803 299*b35ce0c4SPankaj Gupta /* part 1 of 2 */ 300*b35ce0c4SPankaj Gupta if ((regs->sdram_cfg[1] & SDRAM_CFG2_AP_EN) != 0) { 301*b35ce0c4SPankaj Gupta if ((regs->sdram_cfg[0] & SDRAM_CFG_RD_EN) != 0) { 302*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_sdram_rcw_2, 303*b35ce0c4SPankaj Gupta regs->sdram_rcw[1] & ~0xf0); 304*b35ce0c4SPankaj Gupta } 305*b35ce0c4SPankaj Gupta 306*b35ce0c4SPankaj Gupta ddr_out32(&ddr->err_disable, 307*b35ce0c4SPankaj Gupta regs->err_disable | DDR_ERR_DISABLE_APED); 308*b35ce0c4SPankaj Gupta } 309*b35ce0c4SPankaj Gupta #else 310*b35ce0c4SPankaj Gupta ddr_out32(&ddr->err_disable, regs->err_disable); 311*b35ce0c4SPankaj Gupta #endif 312*b35ce0c4SPankaj Gupta ddr_out32(&ddr->err_int_en, regs->err_int_en); 313*b35ce0c4SPankaj Gupta 314*b35ce0c4SPankaj Gupta /* For DDRC 5.05 only */ 315*b35ce0c4SPankaj Gupta if (get_ddrc_version(ddr) == 0x50500) { 316*b35ce0c4SPankaj Gupta ddr_out32(&ddr->tx_cfg[1], 0x1f1f1f1f); 317*b35ce0c4SPankaj Gupta ddr_out32(&ddr->debug[3], 0x124a02c0); 318*b35ce0c4SPankaj Gupta } 319*b35ce0c4SPankaj Gupta 320*b35ce0c4SPankaj Gupta for (i = 0U; i < 4U; i++) { 321*b35ce0c4SPankaj Gupta if (regs->tx_cfg[i] != 0) { 322*b35ce0c4SPankaj Gupta ddr_out32(&ddr->tx_cfg[i], regs->tx_cfg[i]); 323*b35ce0c4SPankaj Gupta } 324*b35ce0c4SPankaj Gupta } 325*b35ce0c4SPankaj Gupta for (i = 0U; i < 64U; i++) { 326*b35ce0c4SPankaj Gupta if (regs->debug[i] != 0) { 327*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942 328*b35ce0c4SPankaj Gupta if (i == 28U) { 329*b35ce0c4SPankaj Gupta continue; 330*b35ce0c4SPankaj Gupta } 331*b35ce0c4SPankaj Gupta #endif 332*b35ce0c4SPankaj Gupta ddr_out32(&ddr->debug[i], regs->debug[i]); 333*b35ce0c4SPankaj Gupta } 334*b35ce0c4SPankaj Gupta } 335*b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC 336*b35ce0c4SPankaj Gupta if ((regs->dec[9] & 1) != 0U) { 337*b35ce0c4SPankaj Gupta for (i = 0U; i < 10U; i++) { 338*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dec[i], regs->dec[i]); 339*b35ce0c4SPankaj Gupta } 340*b35ce0c4SPankaj Gupta if (mod_bnds != 0) { 341*b35ce0c4SPankaj Gupta debug("Disable address decoding\n"); 342*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dec[9], 0); 343*b35ce0c4SPankaj Gupta } 344*b35ce0c4SPankaj Gupta } 345*b35ce0c4SPankaj Gupta #endif 346*b35ce0c4SPankaj Gupta 347*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A008511 348*b35ce0c4SPankaj Gupta /* Part 1 of 2 */ 349*b35ce0c4SPankaj Gupta /* This erraum only applies to verion 5.2.1 */ 350*b35ce0c4SPankaj Gupta if (get_ddrc_version(ddr) == 0x50200) { 351*b35ce0c4SPankaj Gupta ERROR("Unsupported SoC.\n"); 352*b35ce0c4SPankaj Gupta } else if (get_ddrc_version(ddr) == 0x50201) { 353*b35ce0c4SPankaj Gupta ddr_out32(&ddr->debug[37], (U(1) << 31)); 354*b35ce0c4SPankaj Gupta ddr_out32(&ddr->ddr_cdr2, 355*b35ce0c4SPankaj Gupta regs->cdr[1] | DDR_CDR2_VREF_TRAIN_EN); 356*b35ce0c4SPankaj Gupta } else { 357*b35ce0c4SPankaj Gupta debug("Erratum A008511 doesn't apply.\n"); 358*b35ce0c4SPankaj Gupta } 359*b35ce0c4SPankaj Gupta #endif 360*b35ce0c4SPankaj Gupta 361*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942 362*b35ce0c4SPankaj Gupta ddr_freq = clk / 1000000U; 363*b35ce0c4SPankaj Gupta tmp = ddr_in32(&ddr->debug[28]); 364*b35ce0c4SPankaj Gupta tmp &= U(0xff0fff00); 365*b35ce0c4SPankaj Gupta tmp |= ddr_freq <= 1333U ? U(0x0080006a) : 366*b35ce0c4SPankaj Gupta (ddr_freq <= 1600U ? U(0x0070006f) : 367*b35ce0c4SPankaj Gupta (ddr_freq <= 1867U ? U(0x00700076) : U(0x0060007b))); 368*b35ce0c4SPankaj Gupta if (regs->debug[28] != 0) { 369*b35ce0c4SPankaj Gupta tmp &= ~0xff; 370*b35ce0c4SPankaj Gupta tmp |= regs->debug[28] & 0xff; 371*b35ce0c4SPankaj Gupta } else { 372*b35ce0c4SPankaj Gupta WARN("Warning: Optimal CPO value not set.\n"); 373*b35ce0c4SPankaj Gupta } 374*b35ce0c4SPankaj Gupta ddr_out32(&ddr->debug[28], tmp); 375*b35ce0c4SPankaj Gupta #endif 376*b35ce0c4SPankaj Gupta 377*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A010165 378*b35ce0c4SPankaj Gupta ddr_freq = clk / 1000000U; 379*b35ce0c4SPankaj Gupta if ((ddr_freq > 1900) && (ddr_freq < 2300)) { 380*b35ce0c4SPankaj Gupta tmp = ddr_in32(&ddr->debug[28]); 381*b35ce0c4SPankaj Gupta ddr_out32(&ddr->debug[28], tmp | 0x000a0000); 382*b35ce0c4SPankaj Gupta } 383*b35ce0c4SPankaj Gupta #endif 384*b35ce0c4SPankaj Gupta /* 385*b35ce0c4SPankaj Gupta * For RDIMMs, JEDEC spec requires clocks to be stable before reset is 386*b35ce0c4SPankaj Gupta * deasserted. Clocks start when any chip select is enabled and clock 387*b35ce0c4SPankaj Gupta * control register is set. Because all DDR components are connected to 388*b35ce0c4SPankaj Gupta * one reset signal, this needs to be done in two steps. Step 1 is to 389*b35ce0c4SPankaj Gupta * get the clocks started. Step 2 resumes after reset signal is 390*b35ce0c4SPankaj Gupta * deasserted. 391*b35ce0c4SPankaj Gupta */ 392*b35ce0c4SPankaj Gupta if (twopass == 1) { 393*b35ce0c4SPankaj Gupta udelay(200); 394*b35ce0c4SPankaj Gupta return 0; 395*b35ce0c4SPankaj Gupta } 396*b35ce0c4SPankaj Gupta 397*b35ce0c4SPankaj Gupta /* As per new sequence flow shall be write CSn_CONFIG registers needs to 398*b35ce0c4SPankaj Gupta * be set after all the other DDR controller registers are set, then poll 399*b35ce0c4SPankaj Gupta * for PHY_INIT_CMPLT = 1 , then wait at least 100us (micro seconds), 400*b35ce0c4SPankaj Gupta * then set the MEM_EN = 1 401*b35ce0c4SPankaj Gupta */ 402*b35ce0c4SPankaj Gupta for (i = 0U; i < DDRC_NUM_CS; i++) { 403*b35ce0c4SPankaj Gupta if (mod_bnds != 0U && i == 0U) { 404*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg[i], 405*b35ce0c4SPankaj Gupta (regs->cs[i].config & ~CTLR_INTLV_MASK)); 406*b35ce0c4SPankaj Gupta } else { 407*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg[i], regs->cs[i].config); 408*b35ce0c4SPankaj Gupta } 409*b35ce0c4SPankaj Gupta } 410*b35ce0c4SPankaj Gupta 411*b35ce0c4SPankaj Gupta after_reset: 412*b35ce0c4SPankaj Gupta /* Set, but do not enable the memory */ 413*b35ce0c4SPankaj Gupta temp_sdram_cfg = regs->sdram_cfg[0]; 414*b35ce0c4SPankaj Gupta temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); 415*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg); 416*b35ce0c4SPankaj Gupta 417*b35ce0c4SPankaj Gupta if (get_ddrc_version(ddr) < U(0x50500)) { 418*b35ce0c4SPankaj Gupta /* 419*b35ce0c4SPankaj Gupta * 500 painful micro-seconds must elapse between 420*b35ce0c4SPankaj Gupta * the DDR clock setup and the DDR config enable. 421*b35ce0c4SPankaj Gupta * DDR2 need 200 us, and DDR3 need 500 us from spec, 422*b35ce0c4SPankaj Gupta * we choose the max, that is 500 us for all of case. 423*b35ce0c4SPankaj Gupta */ 424*b35ce0c4SPankaj Gupta udelay(500); 425*b35ce0c4SPankaj Gupta /* applied memory barrier */ 426*b35ce0c4SPankaj Gupta mb(); 427*b35ce0c4SPankaj Gupta isb(); 428*b35ce0c4SPankaj Gupta } else { 429*b35ce0c4SPankaj Gupta /* wait for PHY complete */ 430*b35ce0c4SPankaj Gupta timeout = 40; 431*b35ce0c4SPankaj Gupta while (((ddr_in32(&ddr->ddr_dsr2) & 0x4) != 0) && 432*b35ce0c4SPankaj Gupta (timeout > 0)) { 433*b35ce0c4SPankaj Gupta udelay(500); 434*b35ce0c4SPankaj Gupta timeout--; 435*b35ce0c4SPankaj Gupta } 436*b35ce0c4SPankaj Gupta if (timeout <= 0) { 437*b35ce0c4SPankaj Gupta printf("PHY handshake timeout, ddr_dsr2 = %x\n", 438*b35ce0c4SPankaj Gupta ddr_in32(&ddr->ddr_dsr2)); 439*b35ce0c4SPankaj Gupta } else { 440*b35ce0c4SPankaj Gupta debug("PHY handshake completed, timer remains %d\n", 441*b35ce0c4SPankaj Gupta timeout); 442*b35ce0c4SPankaj Gupta } 443*b35ce0c4SPankaj Gupta } 444*b35ce0c4SPankaj Gupta 445*b35ce0c4SPankaj Gupta temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg); 446*b35ce0c4SPankaj Gupta /* Let the controller go */ 447*b35ce0c4SPankaj Gupta udelay(100); 448*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); 449*b35ce0c4SPankaj Gupta 450*b35ce0c4SPankaj Gupta /* applied memory barrier */ 451*b35ce0c4SPankaj Gupta mb(); 452*b35ce0c4SPankaj Gupta isb(); 453*b35ce0c4SPankaj Gupta 454*b35ce0c4SPankaj Gupta total_mem_per_ctrl = 0; 455*b35ce0c4SPankaj Gupta for (i = 0; i < DDRC_NUM_CS; i++) { 456*b35ce0c4SPankaj Gupta if ((regs->cs[i].config & 0x80000000) == 0) { 457*b35ce0c4SPankaj Gupta continue; 458*b35ce0c4SPankaj Gupta } 459*b35ce0c4SPankaj Gupta total_mem_per_ctrl += 1 << ( 460*b35ce0c4SPankaj Gupta ((regs->cs[i].config >> 14) & 0x3) + 2 + 461*b35ce0c4SPankaj Gupta ((regs->cs[i].config >> 8) & 0x7) + 12 + 462*b35ce0c4SPankaj Gupta ((regs->cs[i].config >> 4) & 0x3) + 0 + 463*b35ce0c4SPankaj Gupta ((regs->cs[i].config >> 0) & 0x7) + 8 + 464*b35ce0c4SPankaj Gupta ((regs->sdram_cfg[2] >> 4) & 0x3) + 465*b35ce0c4SPankaj Gupta 3 - ((regs->sdram_cfg[0] >> 19) & 0x3) - 466*b35ce0c4SPankaj Gupta 26); /* minus 26 (count of 64M) */ 467*b35ce0c4SPankaj Gupta } 468*b35ce0c4SPankaj Gupta total_mem_per_ctrl_adj = total_mem_per_ctrl; 469*b35ce0c4SPankaj Gupta /* 470*b35ce0c4SPankaj Gupta * total memory / bus width = transactions needed 471*b35ce0c4SPankaj Gupta * transactions needed / data rate = seconds 472*b35ce0c4SPankaj Gupta * to add plenty of buffer, double the time 473*b35ce0c4SPankaj Gupta * For example, 2GB on 666MT/s 64-bit bus takes about 402ms 474*b35ce0c4SPankaj Gupta * Let's wait for 800ms 475*b35ce0c4SPankaj Gupta */ 476*b35ce0c4SPankaj Gupta bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) 477*b35ce0c4SPankaj Gupta >> SDRAM_CFG_DBW_SHIFT); 478*b35ce0c4SPankaj Gupta timeout = ((total_mem_per_ctrl_adj << (6 - bus_width)) * 100 / 479*b35ce0c4SPankaj Gupta (clk >> 20)) << 2; 480*b35ce0c4SPankaj Gupta total_mem_per_ctrl_adj >>= 4; /* shift down to gb size */ 481*b35ce0c4SPankaj Gupta if ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) != 0) { 482*b35ce0c4SPankaj Gupta debug("total size %d GB\n", total_mem_per_ctrl_adj); 483*b35ce0c4SPankaj Gupta debug("Need to wait up to %d ms\n", timeout * 10); 484*b35ce0c4SPankaj Gupta 485*b35ce0c4SPankaj Gupta do { 486*b35ce0c4SPankaj Gupta mdelay(10); 487*b35ce0c4SPankaj Gupta } while (timeout-- > 0 && 488*b35ce0c4SPankaj Gupta ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT)) != 0); 489*b35ce0c4SPankaj Gupta 490*b35ce0c4SPankaj Gupta if (timeout <= 0) { 491*b35ce0c4SPankaj Gupta if (ddr_in32(&ddr->debug[1]) & 0x3d00) { 492*b35ce0c4SPankaj Gupta ERROR("Found training error(s): 0x%x\n", 493*b35ce0c4SPankaj Gupta ddr_in32(&ddr->debug[1])); 494*b35ce0c4SPankaj Gupta } 495*b35ce0c4SPankaj Gupta ERROR("Error: Waiting for D_INIT timeout.\n"); 496*b35ce0c4SPankaj Gupta return -EIO; 497*b35ce0c4SPankaj Gupta } 498*b35ce0c4SPankaj Gupta } 499*b35ce0c4SPankaj Gupta 500*b35ce0c4SPankaj Gupta if (mod_bnds != 0U) { 501*b35ce0c4SPankaj Gupta debug("Restore original bnds\n"); 502*b35ce0c4SPankaj Gupta for (i = 0U; i < DDRC_NUM_CS; i++) { 503*b35ce0c4SPankaj Gupta ddr_out32(&ddr->bnds[i].a, regs->cs[i].bnds); 504*b35ce0c4SPankaj Gupta } 505*b35ce0c4SPankaj Gupta ddr_out32(&ddr->csn_cfg[0], regs->cs[0].config); 506*b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC 507*b35ce0c4SPankaj Gupta if ((regs->dec[9] & U(0x1)) != 0U) { 508*b35ce0c4SPankaj Gupta debug("Restore address decoding\n"); 509*b35ce0c4SPankaj Gupta ddr_out32(&ddr->dec[9], regs->dec[9]); 510*b35ce0c4SPankaj Gupta } 511*b35ce0c4SPankaj Gupta #endif 512*b35ce0c4SPankaj Gupta } 513*b35ce0c4SPankaj Gupta 514*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803 515*b35ce0c4SPankaj Gupta /* Part 2 of 2 */ 516*b35ce0c4SPankaj Gupta if ((regs->sdram_cfg[1] & SDRAM_CFG2_AP_EN) != 0) { 517*b35ce0c4SPankaj Gupta timeout = 400; 518*b35ce0c4SPankaj Gupta do { 519*b35ce0c4SPankaj Gupta mdelay(1); 520*b35ce0c4SPankaj Gupta } while (timeout-- > 0 && ((ddr_in32(&ddr->debug[1]) & 0x2) == 0)); 521*b35ce0c4SPankaj Gupta 522*b35ce0c4SPankaj Gupta if ((regs->sdram_cfg[0] & SDRAM_CFG_RD_EN) != 0) { 523*b35ce0c4SPankaj Gupta for (i = 0U; i < DDRC_NUM_CS; i++) { 524*b35ce0c4SPankaj Gupta if ((regs->cs[i].config & SDRAM_CS_CONFIG_EN) == 0) { 525*b35ce0c4SPankaj Gupta continue; 526*b35ce0c4SPankaj Gupta } 527*b35ce0c4SPankaj Gupta set_wait_for_bits_clear(&ddr->sdram_md_cntl, 528*b35ce0c4SPankaj Gupta MD_CNTL_MD_EN | 529*b35ce0c4SPankaj Gupta MD_CNTL_CS_SEL(i) | 530*b35ce0c4SPankaj Gupta 0x070000ed, 531*b35ce0c4SPankaj Gupta MD_CNTL_MD_EN); 532*b35ce0c4SPankaj Gupta udelay(1); 533*b35ce0c4SPankaj Gupta } 534*b35ce0c4SPankaj Gupta } 535*b35ce0c4SPankaj Gupta 536*b35ce0c4SPankaj Gupta ddr_out32(&ddr->err_disable, 537*b35ce0c4SPankaj Gupta regs->err_disable & ~DDR_ERR_DISABLE_APED); 538*b35ce0c4SPankaj Gupta } 539*b35ce0c4SPankaj Gupta #endif 540*b35ce0c4SPankaj Gupta 541*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009663 542*b35ce0c4SPankaj Gupta ddr_out32(&ddr->sdram_interval, regs->interval); 543*b35ce0c4SPankaj Gupta #endif 544*b35ce0c4SPankaj Gupta 545*b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942 546*b35ce0c4SPankaj Gupta timeout = 400; 547*b35ce0c4SPankaj Gupta do { 548*b35ce0c4SPankaj Gupta mdelay(1); 549*b35ce0c4SPankaj Gupta } while (timeout-- > 0 && ((ddr_in32(&ddr->debug[1]) & 0x2) == 0)); 550*b35ce0c4SPankaj Gupta tmp = (regs->sdram_cfg[0] >> 19) & 0x3; 551*b35ce0c4SPankaj Gupta check = (tmp == DDR_DBUS_64) ? 4 : ((tmp == DDR_DBUS_32) ? 2 : 1); 552*b35ce0c4SPankaj Gupta for (i = 0; i < check; i++) { 553*b35ce0c4SPankaj Gupta tmp = ddr_in32(&ddr->debug[9 + i]); 554*b35ce0c4SPankaj Gupta debug("Reading debug[%d] as 0x%x\n", i + 9, tmp); 555*b35ce0c4SPankaj Gupta cpo_min = min(cpo_min, 556*b35ce0c4SPankaj Gupta min((tmp >> 24) & 0xff, (tmp >> 8) & 0xff)); 557*b35ce0c4SPankaj Gupta cpo_max = max(cpo_max, 558*b35ce0c4SPankaj Gupta max((tmp >> 24) & 0xff, (tmp >> 8) & 0xff)); 559*b35ce0c4SPankaj Gupta } 560*b35ce0c4SPankaj Gupta if ((regs->sdram_cfg[0] & SDRAM_CFG_ECC_EN) != 0) { 561*b35ce0c4SPankaj Gupta tmp = ddr_in32(&ddr->debug[13]); 562*b35ce0c4SPankaj Gupta cpo_min = min(cpo_min, (tmp >> 24) & 0xff); 563*b35ce0c4SPankaj Gupta cpo_max = max(cpo_max, (tmp >> 24) & 0xff); 564*b35ce0c4SPankaj Gupta } 565*b35ce0c4SPankaj Gupta debug("cpo_min 0x%x\n", cpo_min); 566*b35ce0c4SPankaj Gupta debug("cpo_max 0x%x\n", cpo_max); 567*b35ce0c4SPankaj Gupta tmp = ddr_in32(&ddr->debug[28]); 568*b35ce0c4SPankaj Gupta debug("debug[28] 0x%x\n", tmp); 569*b35ce0c4SPankaj Gupta if ((cpo_min + 0x3B) < (tmp & 0xff)) { 570*b35ce0c4SPankaj Gupta WARN("Warning: A009942 requires setting cpo_sample to 0x%x\n", 571*b35ce0c4SPankaj Gupta (cpo_min + cpo_max) / 2 + 0x27); 572*b35ce0c4SPankaj Gupta } else { 573*b35ce0c4SPankaj Gupta debug("Optimal cpo_sample 0x%x\n", 574*b35ce0c4SPankaj Gupta (cpo_min + cpo_max) / 2 + 0x27); 575*b35ce0c4SPankaj Gupta } 576*b35ce0c4SPankaj Gupta #endif 577*b35ce0c4SPankaj Gupta if (run_bist() != 0) { 578*b35ce0c4SPankaj Gupta if ((ddr_in32(&ddr->debug[1]) & 579*b35ce0c4SPankaj Gupta ((get_ddrc_version(ddr) == 0x50500) ? 0x3c00 : 0x3d00)) != 0) { 580*b35ce0c4SPankaj Gupta ERROR("Found training error(s): 0x%x\n", 581*b35ce0c4SPankaj Gupta ddr_in32(&ddr->debug[1])); 582*b35ce0c4SPankaj Gupta return -EIO; 583*b35ce0c4SPankaj Gupta } 584*b35ce0c4SPankaj Gupta INFO("Running built-in self test ...\n"); 585*b35ce0c4SPankaj Gupta /* give it 10x time to cover whole memory */ 586*b35ce0c4SPankaj Gupta timeout = ((total_mem_per_ctrl << (6 - bus_width)) * 587*b35ce0c4SPankaj Gupta 100 / (clk >> 20)) * 10; 588*b35ce0c4SPankaj Gupta INFO("\tWait up to %d ms\n", timeout * 10); 589*b35ce0c4SPankaj Gupta ret = bist(ddr, timeout); 590*b35ce0c4SPankaj Gupta } 591*b35ce0c4SPankaj Gupta dump_ddrc((void *)ddr); 592*b35ce0c4SPankaj Gupta 593*b35ce0c4SPankaj Gupta return ret; 594*b35ce0c4SPankaj Gupta } 595