1*983e3700STom Rini /* 2*983e3700STom Rini * Timing and Organization details of the Elpida parts used in OMAP4 3*983e3700STom Rini * SDPs and Panda 4*983e3700STom Rini * 5*983e3700STom Rini * (C) Copyright 2010 6*983e3700STom Rini * Texas Instruments, <www.ti.com> 7*983e3700STom Rini * 8*983e3700STom Rini * Aneesh V <aneesh@ti.com> 9*983e3700STom Rini * 10*983e3700STom Rini * SPDX-License-Identifier: GPL-2.0+ 11*983e3700STom Rini */ 12*983e3700STom Rini 13*983e3700STom Rini #include <asm/emif.h> 14*983e3700STom Rini #include <asm/arch/sys_proto.h> 15*983e3700STom Rini 16*983e3700STom Rini /* 17*983e3700STom Rini * This file provides details of the LPDDR2 SDRAM parts used on OMAP4430 18*983e3700STom Rini * SDP and Panda. Since the parts used and geometry are identical for 19*983e3700STom Rini * SDP and Panda for a given OMAP4 revision, this information is kept 20*983e3700STom Rini * here instead of being in board directory. However the key functions 21*983e3700STom Rini * exported are weakly linked so that they can be over-ridden in the board 22*983e3700STom Rini * directory if there is a OMAP4 board in the future that uses a different 23*983e3700STom Rini * memory device or geometry. 24*983e3700STom Rini * 25*983e3700STom Rini * For any new board with different memory devices over-ride one or more 26*983e3700STom Rini * of the following functions as per the CONFIG flags you intend to enable: 27*983e3700STom Rini * - emif_get_reg_dump() 28*983e3700STom Rini * - emif_get_dmm_regs() 29*983e3700STom Rini * - emif_get_device_details() 30*983e3700STom Rini * - emif_get_device_timings() 31*983e3700STom Rini */ 32*983e3700STom Rini 33*983e3700STom Rini #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS 34*983e3700STom Rini 35*983e3700STom Rini const struct emif_regs emif_regs_elpida_200_mhz_2cs = { 36*983e3700STom Rini .sdram_config_init = 0x80000eb9, 37*983e3700STom Rini .sdram_config = 0x80001ab9, 38*983e3700STom Rini .ref_ctrl = 0x0000030c, 39*983e3700STom Rini .sdram_tim1 = 0x08648311, 40*983e3700STom Rini .sdram_tim2 = 0x101b06ca, 41*983e3700STom Rini .sdram_tim3 = 0x0048a19f, 42*983e3700STom Rini .read_idle_ctrl = 0x000501ff, 43*983e3700STom Rini .zq_config = 0x500b3214, 44*983e3700STom Rini .temp_alert_config = 0xd8016893, 45*983e3700STom Rini .emif_ddr_phy_ctlr_1_init = 0x049ffff5, 46*983e3700STom Rini .emif_ddr_phy_ctlr_1 = 0x049ff808 47*983e3700STom Rini }; 48*983e3700STom Rini 49*983e3700STom Rini const struct emif_regs emif_regs_elpida_380_mhz_1cs = { 50*983e3700STom Rini .sdram_config_init = 0x80000eb1, 51*983e3700STom Rini .sdram_config = 0x80001ab1, 52*983e3700STom Rini .ref_ctrl = 0x000005cd, 53*983e3700STom Rini .sdram_tim1 = 0x10cb0622, 54*983e3700STom Rini .sdram_tim2 = 0x20350d52, 55*983e3700STom Rini .sdram_tim3 = 0x00b1431f, 56*983e3700STom Rini .read_idle_ctrl = 0x000501ff, 57*983e3700STom Rini .zq_config = 0x500b3214, 58*983e3700STom Rini .temp_alert_config = 0x58016893, 59*983e3700STom Rini .emif_ddr_phy_ctlr_1_init = 0x049ffff5, 60*983e3700STom Rini .emif_ddr_phy_ctlr_1 = 0x049ff418 61*983e3700STom Rini }; 62*983e3700STom Rini 63*983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_1cs = { 64*983e3700STom Rini .sdram_config_init = 0x80800eb2, 65*983e3700STom Rini .sdram_config = 0x80801ab2, 66*983e3700STom Rini .ref_ctrl = 0x00000618, 67*983e3700STom Rini .sdram_tim1 = 0x10eb0662, 68*983e3700STom Rini .sdram_tim2 = 0x20370dd2, 69*983e3700STom Rini .sdram_tim3 = 0x00b1c33f, 70*983e3700STom Rini .read_idle_ctrl = 0x000501ff, 71*983e3700STom Rini .zq_config = 0x500b3215, 72*983e3700STom Rini .temp_alert_config = 0x58016893, 73*983e3700STom Rini .emif_ddr_phy_ctlr_1_init = 0x049ffff5, 74*983e3700STom Rini .emif_ddr_phy_ctlr_1 = 0x049ff418 75*983e3700STom Rini }; 76*983e3700STom Rini 77*983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_2cs = { 78*983e3700STom Rini .sdram_config_init = 0x80000eb9, 79*983e3700STom Rini .sdram_config = 0x80001ab9, 80*983e3700STom Rini .ref_ctrl = 0x00000618, 81*983e3700STom Rini .sdram_tim1 = 0x10eb0662, 82*983e3700STom Rini .sdram_tim2 = 0x20370dd2, 83*983e3700STom Rini .sdram_tim3 = 0x00b1c33f, 84*983e3700STom Rini .read_idle_ctrl = 0x000501ff, 85*983e3700STom Rini .zq_config = 0xd00b3214, 86*983e3700STom Rini .temp_alert_config = 0xd8016893, 87*983e3700STom Rini .emif_ddr_phy_ctlr_1_init = 0x049ffff5, 88*983e3700STom Rini .emif_ddr_phy_ctlr_1 = 0x049ff418 89*983e3700STom Rini }; 90*983e3700STom Rini 91*983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { 92*983e3700STom Rini .dmm_lisa_map_0 = 0xFF020100, 93*983e3700STom Rini .dmm_lisa_map_1 = 0, 94*983e3700STom Rini .dmm_lisa_map_2 = 0, 95*983e3700STom Rini .dmm_lisa_map_3 = 0x80540300, 96*983e3700STom Rini .is_ma_present = 0x0 97*983e3700STom Rini }; 98*983e3700STom Rini 99*983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = { 100*983e3700STom Rini .dmm_lisa_map_0 = 0xFF020100, 101*983e3700STom Rini .dmm_lisa_map_1 = 0, 102*983e3700STom Rini .dmm_lisa_map_2 = 0, 103*983e3700STom Rini .dmm_lisa_map_3 = 0x80640300, 104*983e3700STom Rini .is_ma_present = 0x0 105*983e3700STom Rini }; 106*983e3700STom Rini 107*983e3700STom Rini const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2 = { 108*983e3700STom Rini .dmm_lisa_map_0 = 0xFF020100, 109*983e3700STom Rini .dmm_lisa_map_1 = 0, 110*983e3700STom Rini .dmm_lisa_map_2 = 0, 111*983e3700STom Rini .dmm_lisa_map_3 = 0x80640300, 112*983e3700STom Rini .is_ma_present = 0x1 113*983e3700STom Rini }; 114*983e3700STom Rini 115*983e3700STom Rini static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) 116*983e3700STom Rini { 117*983e3700STom Rini u32 omap4_rev = omap_revision(); 118*983e3700STom Rini 119*983e3700STom Rini /* Same devices and geometry on both EMIFs */ 120*983e3700STom Rini if (omap4_rev == OMAP4430_ES1_0) 121*983e3700STom Rini *regs = &emif_regs_elpida_380_mhz_1cs; 122*983e3700STom Rini else if (omap4_rev == OMAP4430_ES2_0) 123*983e3700STom Rini *regs = &emif_regs_elpida_200_mhz_2cs; 124*983e3700STom Rini else if (omap4_rev < OMAP4470_ES1_0) 125*983e3700STom Rini *regs = &emif_regs_elpida_400_mhz_2cs; 126*983e3700STom Rini else 127*983e3700STom Rini *regs = &emif_regs_elpida_400_mhz_1cs; 128*983e3700STom Rini } 129*983e3700STom Rini void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) 130*983e3700STom Rini __attribute__((weak, alias("emif_get_reg_dump_sdp"))); 131*983e3700STom Rini 132*983e3700STom Rini static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs 133*983e3700STom Rini **dmm_lisa_regs) 134*983e3700STom Rini { 135*983e3700STom Rini u32 omap_rev = omap_revision(); 136*983e3700STom Rini 137*983e3700STom Rini if (omap_rev == OMAP4430_ES1_0) 138*983e3700STom Rini *dmm_lisa_regs = &lisa_map_2G_x_1_x_2; 139*983e3700STom Rini else if (omap_rev < OMAP4460_ES1_0) 140*983e3700STom Rini *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; 141*983e3700STom Rini else 142*983e3700STom Rini *dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2; 143*983e3700STom Rini } 144*983e3700STom Rini 145*983e3700STom Rini void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) 146*983e3700STom Rini __attribute__((weak, alias("emif_get_dmm_regs_sdp"))); 147*983e3700STom Rini 148*983e3700STom Rini #else 149*983e3700STom Rini 150*983e3700STom Rini const struct lpddr2_device_details elpida_2G_S4_details = { 151*983e3700STom Rini .type = LPDDR2_TYPE_S4, 152*983e3700STom Rini .density = LPDDR2_DENSITY_2Gb, 153*983e3700STom Rini .io_width = LPDDR2_IO_WIDTH_32, 154*983e3700STom Rini .manufacturer = LPDDR2_MANUFACTURER_ELPIDA 155*983e3700STom Rini }; 156*983e3700STom Rini 157*983e3700STom Rini const struct lpddr2_device_details elpida_4G_S4_details = { 158*983e3700STom Rini .type = LPDDR2_TYPE_S4, 159*983e3700STom Rini .density = LPDDR2_DENSITY_4Gb, 160*983e3700STom Rini .io_width = LPDDR2_IO_WIDTH_32, 161*983e3700STom Rini .manufacturer = LPDDR2_MANUFACTURER_ELPIDA 162*983e3700STom Rini }; 163*983e3700STom Rini 164*983e3700STom Rini struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs, 165*983e3700STom Rini struct lpddr2_device_details *lpddr2_dev_details) 166*983e3700STom Rini { 167*983e3700STom Rini u32 omap_rev = omap_revision(); 168*983e3700STom Rini 169*983e3700STom Rini /* EMIF1 & EMIF2 have identical configuration */ 170*983e3700STom Rini if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0)) 171*983e3700STom Rini && (cs == CS1)) { 172*983e3700STom Rini /* Nothing connected on CS1 for 4430/4470 ES1.0 */ 173*983e3700STom Rini return NULL; 174*983e3700STom Rini } else if (omap_rev < OMAP4470_ES1_0) { 175*983e3700STom Rini /* In all other 4430/4460 cases Elpida 2G device */ 176*983e3700STom Rini *lpddr2_dev_details = elpida_2G_S4_details; 177*983e3700STom Rini } else { 178*983e3700STom Rini /* 4470: 4G device */ 179*983e3700STom Rini *lpddr2_dev_details = elpida_4G_S4_details; 180*983e3700STom Rini } 181*983e3700STom Rini return lpddr2_dev_details; 182*983e3700STom Rini } 183*983e3700STom Rini 184*983e3700STom Rini struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs, 185*983e3700STom Rini struct lpddr2_device_details *lpddr2_dev_details) 186*983e3700STom Rini __attribute__((weak, alias("emif_get_device_details_sdp"))); 187*983e3700STom Rini 188*983e3700STom Rini #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ 189*983e3700STom Rini 190*983e3700STom Rini #ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS 191*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_400_mhz = { 192*983e3700STom Rini .max_freq = 400000000, 193*983e3700STom Rini .RL = 6, 194*983e3700STom Rini .tRPab = 21, 195*983e3700STom Rini .tRCD = 18, 196*983e3700STom Rini .tWR = 15, 197*983e3700STom Rini .tRASmin = 42, 198*983e3700STom Rini .tRRD = 10, 199*983e3700STom Rini .tWTRx2 = 15, 200*983e3700STom Rini .tXSR = 140, 201*983e3700STom Rini .tXPx2 = 15, 202*983e3700STom Rini .tRFCab = 130, 203*983e3700STom Rini .tRTPx2 = 15, 204*983e3700STom Rini .tCKE = 3, 205*983e3700STom Rini .tCKESR = 15, 206*983e3700STom Rini .tZQCS = 90, 207*983e3700STom Rini .tZQCL = 360, 208*983e3700STom Rini .tZQINIT = 1000, 209*983e3700STom Rini .tDQSCKMAXx2 = 11, 210*983e3700STom Rini .tRASmax = 70, 211*983e3700STom Rini .tFAW = 50 212*983e3700STom Rini }; 213*983e3700STom Rini 214*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_333_mhz = { 215*983e3700STom Rini .max_freq = 333000000, 216*983e3700STom Rini .RL = 5, 217*983e3700STom Rini .tRPab = 21, 218*983e3700STom Rini .tRCD = 18, 219*983e3700STom Rini .tWR = 15, 220*983e3700STom Rini .tRASmin = 42, 221*983e3700STom Rini .tRRD = 10, 222*983e3700STom Rini .tWTRx2 = 15, 223*983e3700STom Rini .tXSR = 140, 224*983e3700STom Rini .tXPx2 = 15, 225*983e3700STom Rini .tRFCab = 130, 226*983e3700STom Rini .tRTPx2 = 15, 227*983e3700STom Rini .tCKE = 3, 228*983e3700STom Rini .tCKESR = 15, 229*983e3700STom Rini .tZQCS = 90, 230*983e3700STom Rini .tZQCL = 360, 231*983e3700STom Rini .tZQINIT = 1000, 232*983e3700STom Rini .tDQSCKMAXx2 = 11, 233*983e3700STom Rini .tRASmax = 70, 234*983e3700STom Rini .tFAW = 50 235*983e3700STom Rini }; 236*983e3700STom Rini 237*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_200_mhz = { 238*983e3700STom Rini .max_freq = 200000000, 239*983e3700STom Rini .RL = 3, 240*983e3700STom Rini .tRPab = 21, 241*983e3700STom Rini .tRCD = 18, 242*983e3700STom Rini .tWR = 15, 243*983e3700STom Rini .tRASmin = 42, 244*983e3700STom Rini .tRRD = 10, 245*983e3700STom Rini .tWTRx2 = 20, 246*983e3700STom Rini .tXSR = 140, 247*983e3700STom Rini .tXPx2 = 15, 248*983e3700STom Rini .tRFCab = 130, 249*983e3700STom Rini .tRTPx2 = 15, 250*983e3700STom Rini .tCKE = 3, 251*983e3700STom Rini .tCKESR = 15, 252*983e3700STom Rini .tZQCS = 90, 253*983e3700STom Rini .tZQCL = 360, 254*983e3700STom Rini .tZQINIT = 1000, 255*983e3700STom Rini .tDQSCKMAXx2 = 11, 256*983e3700STom Rini .tRASmax = 70, 257*983e3700STom Rini .tFAW = 50 258*983e3700STom Rini }; 259*983e3700STom Rini 260*983e3700STom Rini static const struct lpddr2_min_tck min_tck_elpida = { 261*983e3700STom Rini .tRL = 3, 262*983e3700STom Rini .tRP_AB = 3, 263*983e3700STom Rini .tRCD = 3, 264*983e3700STom Rini .tWR = 3, 265*983e3700STom Rini .tRAS_MIN = 3, 266*983e3700STom Rini .tRRD = 2, 267*983e3700STom Rini .tWTR = 2, 268*983e3700STom Rini .tXP = 2, 269*983e3700STom Rini .tRTP = 2, 270*983e3700STom Rini .tCKE = 3, 271*983e3700STom Rini .tCKESR = 3, 272*983e3700STom Rini .tFAW = 8 273*983e3700STom Rini }; 274*983e3700STom Rini 275*983e3700STom Rini static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = { 276*983e3700STom Rini &timings_elpida_200_mhz, 277*983e3700STom Rini &timings_elpida_333_mhz, 278*983e3700STom Rini &timings_elpida_400_mhz 279*983e3700STom Rini }; 280*983e3700STom Rini 281*983e3700STom Rini const struct lpddr2_device_timings elpida_2G_S4_timings = { 282*983e3700STom Rini .ac_timings = elpida_ac_timings, 283*983e3700STom Rini .min_tck = &min_tck_elpida, 284*983e3700STom Rini }; 285*983e3700STom Rini 286*983e3700STom Rini void emif_get_device_timings_sdp(u32 emif_nr, 287*983e3700STom Rini const struct lpddr2_device_timings **cs0_device_timings, 288*983e3700STom Rini const struct lpddr2_device_timings **cs1_device_timings) 289*983e3700STom Rini { 290*983e3700STom Rini u32 omap_rev = omap_revision(); 291*983e3700STom Rini 292*983e3700STom Rini /* Identical devices on EMIF1 & EMIF2 */ 293*983e3700STom Rini *cs0_device_timings = &elpida_2G_S4_timings; 294*983e3700STom Rini 295*983e3700STom Rini if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0)) 296*983e3700STom Rini *cs1_device_timings = NULL; 297*983e3700STom Rini else 298*983e3700STom Rini *cs1_device_timings = &elpida_2G_S4_timings; 299*983e3700STom Rini } 300*983e3700STom Rini 301*983e3700STom Rini void emif_get_device_timings(u32 emif_nr, 302*983e3700STom Rini const struct lpddr2_device_timings **cs0_device_timings, 303*983e3700STom Rini const struct lpddr2_device_timings **cs1_device_timings) 304*983e3700STom Rini __attribute__((weak, alias("emif_get_device_timings_sdp"))); 305*983e3700STom Rini 306*983e3700STom Rini #endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ 307*983e3700STom Rini 308*983e3700STom Rini const struct lpddr2_mr_regs mr_regs = { 309*983e3700STom Rini .mr1 = MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3, 310*983e3700STom Rini .mr2 = 0x4, 311*983e3700STom Rini .mr3 = -1, 312*983e3700STom Rini .mr10 = MR10_ZQ_ZQINIT, 313*983e3700STom Rini .mr16 = MR16_REF_FULL_ARRAY 314*983e3700STom Rini }; 315*983e3700STom Rini 316*983e3700STom Rini void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs) 317*983e3700STom Rini { 318*983e3700STom Rini *regs = &mr_regs; 319*983e3700STom Rini } 320*983e3700STom Rini 321*983e3700STom Rini __weak const struct read_write_regs *get_bug_regs(u32 *iterations) 322*983e3700STom Rini { 323*983e3700STom Rini return 0; 324*983e3700STom Rini } 325