in arch/x86/cpu/quark/smc.c [252:1145]
void ddrphy_init(struct mrc_params *mrc_params)
{
uint32_t temp;
uint8_t ch; /* channel counter */
uint8_t rk; /* rank counter */
uint8_t bl_grp; /* byte lane group counter (2 BLs per module) */
uint8_t bl_divisor = 1; /* byte lane divisor */
/* For DDR3 --> 0 == 800, 1 == 1066, 2 == 1333 */
uint8_t speed = mrc_params->ddr_speed & 3;
uint8_t cas;
uint8_t cwl;
ENTERFN();
cas = mrc_params->params.cl;
cwl = 5 + mrc_params->ddr_speed;
/* ddrphy_init starts */
mrc_post_code(0x03, 0x00);
/*
* HSD#231531
* Make sure IOBUFACT is deasserted before initializing the DDR PHY
*
* HSD#234845
* Make sure WRPTRENABLE is deasserted before initializing the DDR PHY
*/
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* Deassert DDRPHY Initialization Complete */
mrc_alt_write_mask(DDRPHY,
CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
~(1 << 20), 1 << 20); /* SPID_INIT_COMPLETE=0 */
/* Deassert IOBUFACT */
mrc_alt_write_mask(DDRPHY,
CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
~(1 << 2), 1 << 2); /* IOBUFACTRST_N=0 */
/* Disable WRPTR */
mrc_alt_write_mask(DDRPHY,
CMDPTRREG + ch * DDRIOCCC_CH_OFFSET,
~(1 << 0), 1 << 0); /* WRPTRENABLE=0 */
}
}
/* Put PHY in reset */
mrc_alt_write_mask(DDRPHY, MASTERRSTN, 0, 1);
/* Initialize DQ01, DQ23, CMD, CLK-CTL, COMP modules */
/* STEP0 */
mrc_post_code(0x03, 0x10);
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* DQ01-DQ23 */
for (bl_grp = 0;
bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
bl_grp++) {
/* Analog MUX select - IO2xCLKSEL */
mrc_alt_write_mask(DDRPHY,
DQOBSCKEBBCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
bl_grp ? 0 : (1 << 22), 1 << 22);
/* ODT Strength */
switch (mrc_params->rd_odt_value) {
case 1:
temp = 0x3;
break; /* 60 ohm */
case 2:
temp = 0x3;
break; /* 120 ohm */
case 3:
temp = 0x3;
break; /* 180 ohm */
default:
temp = 0x3;
break; /* 120 ohm */
}
/* ODT strength */
mrc_alt_write_mask(DDRPHY,
B0RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp << 5, 0x60);
/* ODT strength */
mrc_alt_write_mask(DDRPHY,
B1RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp << 5, 0x60);
/* Dynamic ODT/DIFFAMP */
temp = (cas << 24) | (cas << 16) |
(cas << 8) | (cas << 0);
switch (speed) {
case 0:
temp -= 0x01010101;
break; /* 800 */
case 1:
temp -= 0x02020202;
break; /* 1066 */
case 2:
temp -= 0x03030303;
break; /* 1333 */
case 3:
temp -= 0x04040404;
break; /* 1600 */
}
/* Launch Time: ODT, DIFFAMP, ODT, DIFFAMP */
mrc_alt_write_mask(DDRPHY,
B01LATCTL1 +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0x1f1f1f1f);
switch (speed) {
/* HSD#234715 */
case 0:
temp = (0x06 << 16) | (0x07 << 8);
break; /* 800 */
case 1:
temp = (0x07 << 16) | (0x08 << 8);
break; /* 1066 */
case 2:
temp = (0x09 << 16) | (0x0a << 8);
break; /* 1333 */
case 3:
temp = (0x0a << 16) | (0x0b << 8);
break; /* 1600 */
}
/* On Duration: ODT, DIFFAMP */
mrc_alt_write_mask(DDRPHY,
B0ONDURCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0x003f3f00);
/* On Duration: ODT, DIFFAMP */
mrc_alt_write_mask(DDRPHY,
B1ONDURCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0x003f3f00);
switch (mrc_params->rd_odt_value) {
case 0:
/* override DIFFAMP=on, ODT=off */
temp = (0x3f << 16) | (0x3f << 10);
break;
default:
/* override DIFFAMP=on, ODT=on */
temp = (0x3f << 16) | (0x2a << 10);
break;
}
/* Override: DIFFAMP, ODT */
mrc_alt_write_mask(DDRPHY,
B0OVRCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0x003ffc00);
/* Override: DIFFAMP, ODT */
mrc_alt_write_mask(DDRPHY,
B1OVRCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0x003ffc00);
/* DLL Setup */
/* 1xCLK Domain Timings: tEDP,RCVEN,WDQS (PO) */
mrc_alt_write_mask(DDRPHY,
B0LATCTL0 +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
((cas + 7) << 16) | ((cas - 4) << 8) |
((cwl - 2) << 0), 0x003f1f1f);
mrc_alt_write_mask(DDRPHY,
B1LATCTL0 +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
((cas + 7) << 16) | ((cas - 4) << 8) |
((cwl - 2) << 0), 0x003f1f1f);
/* RCVEN Bypass (PO) */
mrc_alt_write_mask(DDRPHY,
B0RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0, 0x81);
mrc_alt_write_mask(DDRPHY,
B1RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0, 0x81);
/* TX */
mrc_alt_write_mask(DDRPHY,
DQCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
1 << 16, 1 << 16);
mrc_alt_write_mask(DDRPHY,
B01PTRCTL1 +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
1 << 8, 1 << 8);
/* RX (PO) */
/* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
mrc_alt_write_mask(DDRPHY,
B0VREFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
(0x03 << 2) | (0x0 << 1) | (0x0 << 0),
0xff);
/* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
mrc_alt_write_mask(DDRPHY,
B1VREFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
(0x03 << 2) | (0x0 << 1) | (0x0 << 0),
0xff);
/* Per-Bit De-Skew Enable */
mrc_alt_write_mask(DDRPHY,
B0RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0, 0x10);
/* Per-Bit De-Skew Enable */
mrc_alt_write_mask(DDRPHY,
B1RXIOBUFCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0, 0x10);
}
/* CLKEBB */
mrc_alt_write_mask(DDRPHY,
CMDOBSCKEBBCTL + ch * DDRIOCCC_CH_OFFSET,
0, 1 << 23);
/* Enable tristate control of cmd/address bus */
mrc_alt_write_mask(DDRPHY,
CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
0, 0x03);
/* ODT RCOMP */
mrc_alt_write_mask(DDRPHY,
CMDRCOMPODT + ch * DDRIOCCC_CH_OFFSET,
(0x03 << 5) | (0x03 << 0), 0x3ff);
/* CMDPM* registers must be programmed in this order */
/* Turn On Delays: SFR (regulator), MPLL */
mrc_alt_write_mask(DDRPHY,
CMDPMDLYREG4 + ch * DDRIOCCC_CH_OFFSET,
0xffffffff, 0xffffffff);
/*
* Delays: ASSERT_IOBUFACT_to_ALLON0_for_PM_MSG_3,
* VREG (MDLL) Turn On, ALLON0_to_DEASSERT_IOBUFACT
* for_PM_MSG_gt0, MDLL Turn On
*/
mrc_alt_write_mask(DDRPHY,
CMDPMDLYREG3 + ch * DDRIOCCC_CH_OFFSET,
0xfffff616, 0xffffffff);
/* MPLL Divider Reset Delays */
mrc_alt_write_mask(DDRPHY,
CMDPMDLYREG2 + ch * DDRIOCCC_CH_OFFSET,
0xffffffff, 0xffffffff);
/* Turn Off Delays: VREG, Staggered MDLL, MDLL, PI */
mrc_alt_write_mask(DDRPHY,
CMDPMDLYREG1 + ch * DDRIOCCC_CH_OFFSET,
0xffffffff, 0xffffffff);
/* Turn On Delays: MPLL, Staggered MDLL, PI, IOBUFACT */
mrc_alt_write_mask(DDRPHY,
CMDPMDLYREG0 + ch * DDRIOCCC_CH_OFFSET,
0xffffffff, 0xffffffff);
/* Allow PUnit signals */
mrc_alt_write_mask(DDRPHY,
CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
(0x6 << 8) | (0x1 << 6) | (0x4 << 0),
0xffe00f4f);
/* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
mrc_alt_write_mask(DDRPHY,
CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
(0x3 << 4) | (0x7 << 0), 0x7f);
/* CLK-CTL */
mrc_alt_write_mask(DDRPHY,
CCOBSCKEBBCTL + ch * DDRIOCCC_CH_OFFSET,
0, 1 << 24); /* CLKEBB */
/* Buffer Enable: CS,CKE,ODT,CLK */
mrc_alt_write_mask(DDRPHY,
CCCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
0x1f, 0x000ffff1);
/* ODT RCOMP */
mrc_alt_write_mask(DDRPHY,
CCRCOMPODT + ch * DDRIOCCC_CH_OFFSET,
(0x03 << 8) | (0x03 << 0), 0x00001f1f);
/* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
mrc_alt_write_mask(DDRPHY,
CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
(0x3 << 4) | (0x7 << 0), 0x7f);
/*
* COMP (RON channel specific)
* - DQ/DQS/DM RON: 32 Ohm
* - CTRL/CMD RON: 27 Ohm
* - CLK RON: 26 Ohm
*/
/* RCOMP Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
DQVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x08 << 24) | (0x03 << 16), 0x3f3f0000);
/* RCOMP Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
CMDVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x0C << 24) | (0x03 << 16), 0x3f3f0000);
/* RCOMP Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
CLKVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x0F << 24) | (0x03 << 16), 0x3f3f0000);
/* RCOMP Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
DQSVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x08 << 24) | (0x03 << 16), 0x3f3f0000);
/* RCOMP Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
CTLVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x0C << 24) | (0x03 << 16), 0x3f3f0000);
/* DQS Swapped Input Enable */
mrc_alt_write_mask(DDRPHY,
COMPEN1CH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 19) | (1 << 17), 0xc00ac000);
/* ODT VREF = 1.5 x 274/360+274 = 0.65V (code of ~50) */
/* ODT Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
DQVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x32 << 8) | (0x03 << 0), 0x00003f3f);
/* ODT Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
DQSVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x32 << 8) | (0x03 << 0), 0x00003f3f);
/* ODT Vref PU/PD */
mrc_alt_write_mask(DDRPHY,
CLKVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x0E << 8) | (0x05 << 0), 0x00003f3f);
/*
* Slew rate settings are frequency specific,
* numbers below are for 800Mhz (speed == 0)
* - DQ/DQS/DM/CLK SR: 4V/ns,
* - CTRL/CMD SR: 1.5V/ns
*/
temp = (0x0e << 16) | (0x0e << 12) | (0x08 << 8) |
(0x0b << 4) | (0x0b << 0);
/* DCOMP Delay Select: CTL,CMD,CLK,DQS,DQ */
mrc_alt_write_mask(DDRPHY,
DLYSELCH0 + ch * DDRCOMP_CH_OFFSET,
temp, 0x000fffff);
/* TCO Vref CLK,DQS,DQ */
mrc_alt_write_mask(DDRPHY,
TCOVREFCH0 + ch * DDRCOMP_CH_OFFSET,
(0x05 << 16) | (0x05 << 8) | (0x05 << 0),
0x003f3f3f);
/* ODTCOMP CMD/CTL PU/PD */
mrc_alt_write_mask(DDRPHY,
CCBUFODTCH0 + ch * DDRCOMP_CH_OFFSET,
(0x03 << 8) | (0x03 << 0),
0x00001f1f);
/* COMP */
mrc_alt_write_mask(DDRPHY,
COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
0, 0xc0000100);
#ifdef BACKUP_COMPS
/* DQ COMP Overrides */
/* RCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* RCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* DCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x10 << 16),
0x801f0000);
/* DCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x10 << 16),
0x801f0000);
/* ODTCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* ODTCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* DQS COMP Overrides */
/* RCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQSDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* RCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQSDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* DCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQSDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x10 << 16),
0x801f0000);
/* DCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQSDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x10 << 16),
0x801f0000);
/* ODTCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQSODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* ODTCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQSODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQSTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQSTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* CLK COMP Overrides */
/* RCOMP PU */
mrc_alt_write_mask(DDRPHY,
CLKDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0c << 16),
0x801f0000);
/* RCOMP PD */
mrc_alt_write_mask(DDRPHY,
CLKDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0c << 16),
0x801f0000);
/* DCOMP PU */
mrc_alt_write_mask(DDRPHY,
CLKDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x07 << 16),
0x801f0000);
/* DCOMP PD */
mrc_alt_write_mask(DDRPHY,
CLKDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x07 << 16),
0x801f0000);
/* ODTCOMP PU */
mrc_alt_write_mask(DDRPHY,
CLKODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* ODTCOMP PD */
mrc_alt_write_mask(DDRPHY,
CLKODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0b << 16),
0x801f0000);
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
CLKTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
CLKTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
1 << 31, 1 << 31);
/* CMD COMP Overrides */
/* RCOMP PU */
mrc_alt_write_mask(DDRPHY,
CMDDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0d << 16),
0x803f0000);
/* RCOMP PD */
mrc_alt_write_mask(DDRPHY,
CMDDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0d << 16),
0x803f0000);
/* DCOMP PU */
mrc_alt_write_mask(DDRPHY,
CMDDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* DCOMP PD */
mrc_alt_write_mask(DDRPHY,
CMDDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* CTL COMP Overrides */
/* RCOMP PU */
mrc_alt_write_mask(DDRPHY,
CTLDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0d << 16),
0x803f0000);
/* RCOMP PD */
mrc_alt_write_mask(DDRPHY,
CTLDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0d << 16),
0x803f0000);
/* DCOMP PU */
mrc_alt_write_mask(DDRPHY,
CTLDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
/* DCOMP PD */
mrc_alt_write_mask(DDRPHY,
CTLDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x0a << 16),
0x801f0000);
#else
/* DQ TCOCOMP Overrides */
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
/* DQS TCOCOMP Overrides */
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
DQSTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
DQSTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
/* CLK TCOCOMP Overrides */
/* TCOCOMP PU */
mrc_alt_write_mask(DDRPHY,
CLKTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
/* TCOCOMP PD */
mrc_alt_write_mask(DDRPHY,
CLKTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
(1 << 31) | (0x1f << 16),
0x801f0000);
#endif
/* program STATIC delays */
#ifdef BACKUP_WCMD
set_wcmd(ch, ddr_wcmd[PLATFORM_ID]);
#else
set_wcmd(ch, ddr_wclk[PLATFORM_ID] + HALF_CLK);
#endif
for (rk = 0; rk < NUM_RANKS; rk++) {
if (mrc_params->rank_enables & (1 << rk)) {
set_wclk(ch, rk, ddr_wclk[PLATFORM_ID]);
#ifdef BACKUP_WCTL
set_wctl(ch, rk, ddr_wctl[PLATFORM_ID]);
#else
set_wctl(ch, rk, ddr_wclk[PLATFORM_ID] + HALF_CLK);
#endif
}
}
}
}
/* COMP (non channel specific) */
/* RCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQANADRVPUCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQANADRVPDCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CMDANADRVPUCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CMDANADRVPDCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CLKANADRVPUCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CLKANADRVPDCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQSANADRVPUCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQSANADRVPDCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CTLANADRVPUCTL, 1 << 30, 1 << 30);
/* RCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CTLANADRVPDCTL, 1 << 30, 1 << 30);
/* ODT: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQANAODTPUCTL, 1 << 30, 1 << 30);
/* ODT: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQANAODTPDCTL, 1 << 30, 1 << 30);
/* ODT: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CLKANAODTPUCTL, 1 << 30, 1 << 30);
/* ODT: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CLKANAODTPDCTL, 1 << 30, 1 << 30);
/* ODT: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQSANAODTPUCTL, 1 << 30, 1 << 30);
/* ODT: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQSANAODTPDCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQANADLYPUCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQANADLYPDCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CMDANADLYPUCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CMDANADLYPDCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CLKANADLYPUCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CLKANADLYPDCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQSANADLYPUCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQSANADLYPDCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CTLANADLYPUCTL, 1 << 30, 1 << 30);
/* DCOMP: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CTLANADLYPDCTL, 1 << 30, 1 << 30);
/* TCO: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQANATCOPUCTL, 1 << 30, 1 << 30);
/* TCO: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQANATCOPDCTL, 1 << 30, 1 << 30);
/* TCO: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, CLKANATCOPUCTL, 1 << 30, 1 << 30);
/* TCO: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, CLKANATCOPDCTL, 1 << 30, 1 << 30);
/* TCO: Dither PU Enable */
mrc_alt_write_mask(DDRPHY, DQSANATCOPUCTL, 1 << 30, 1 << 30);
/* TCO: Dither PD Enable */
mrc_alt_write_mask(DDRPHY, DQSANATCOPDCTL, 1 << 30, 1 << 30);
/* TCOCOMP: Pulse Count */
mrc_alt_write_mask(DDRPHY, TCOCNTCTRL, 1, 3);
/* ODT: CMD/CTL PD/PU */
mrc_alt_write_mask(DDRPHY, CHNLBUFSTATIC,
(0x03 << 24) | (0x03 << 16), 0x1f1f0000);
/* Set 1us counter */
mrc_alt_write_mask(DDRPHY, MSCNTR, 0x64, 0xff);
mrc_alt_write_mask(DDRPHY, LATCH1CTL, 0x1 << 28, 0x70000000);
/* Release PHY from reset */
mrc_alt_write_mask(DDRPHY, MASTERRSTN, 1, 1);
/* STEP1 */
mrc_post_code(0x03, 0x11);
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* DQ01-DQ23 */
for (bl_grp = 0;
bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
bl_grp++) {
mrc_alt_write_mask(DDRPHY,
DQMDLLCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
1 << 13,
1 << 13); /* Enable VREG */
delay_n(3);
}
/* ECC */
mrc_alt_write_mask(DDRPHY, ECCMDLLCTL,
1 << 13, 1 << 13); /* Enable VREG */
delay_n(3);
/* CMD */
mrc_alt_write_mask(DDRPHY,
CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
1 << 13, 1 << 13); /* Enable VREG */
delay_n(3);
/* CLK-CTL */
mrc_alt_write_mask(DDRPHY,
CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
1 << 13, 1 << 13); /* Enable VREG */
delay_n(3);
}
}
/* STEP2 */
mrc_post_code(0x03, 0x12);
delay_n(200);
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* DQ01-DQ23 */
for (bl_grp = 0;
bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
bl_grp++) {
mrc_alt_write_mask(DDRPHY,
DQMDLLCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
1 << 17,
1 << 17); /* Enable MCDLL */
delay_n(50);
}
/* ECC */
mrc_alt_write_mask(DDRPHY, ECCMDLLCTL,
1 << 17, 1 << 17); /* Enable MCDLL */
delay_n(50);
/* CMD */
mrc_alt_write_mask(DDRPHY,
CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
1 << 18, 1 << 18); /* Enable MCDLL */
delay_n(50);
/* CLK-CTL */
mrc_alt_write_mask(DDRPHY,
CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
1 << 18, 1 << 18); /* Enable MCDLL */
delay_n(50);
}
}
/* STEP3: */
mrc_post_code(0x03, 0x13);
delay_n(100);
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* DQ01-DQ23 */
for (bl_grp = 0;
bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
bl_grp++) {
#ifdef FORCE_16BIT_DDRIO
temp = (bl_grp &&
(mrc_params->channel_width == X16)) ?
0x11ff : 0xffff;
#else
temp = 0xffff;
#endif
/* Enable TXDLL */
mrc_alt_write_mask(DDRPHY,
DQDLLTXCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
temp, 0xffff);
delay_n(3);
/* Enable RXDLL */
mrc_alt_write_mask(DDRPHY,
DQDLLRXCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0xf, 0xf);
delay_n(3);
/* Enable RXDLL Overrides BL0 */
mrc_alt_write_mask(DDRPHY,
B0OVRCTL +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
0xf, 0xf);
}
/* ECC */
temp = 0xffff;
mrc_alt_write_mask(DDRPHY, ECCDLLTXCTL,
temp, 0xffff);
delay_n(3);
/* CMD (PO) */
mrc_alt_write_mask(DDRPHY,
CMDDLLTXCTL + ch * DDRIOCCC_CH_OFFSET,
temp, 0xffff);
delay_n(3);
}
}
/* STEP4 */
mrc_post_code(0x03, 0x14);
for (ch = 0; ch < NUM_CHANNELS; ch++) {
if (mrc_params->channel_enables & (1 << ch)) {
/* Host To Memory Clock Alignment (HMC) for 800/1066 */
for (bl_grp = 0;
bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
bl_grp++) {
/* CLK_ALIGN_MOD_ID */
mrc_alt_write_mask(DDRPHY,
DQCLKALIGNREG2 +
bl_grp * DDRIODQ_BL_OFFSET +
ch * DDRIODQ_CH_OFFSET,
bl_grp ? 3 : 1,
0xf);
}
mrc_alt_write_mask(DDRPHY,
ECCCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
0x2, 0xf);
mrc_alt_write_mask(DDRPHY,
CMDCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
0x0, 0xf);
mrc_alt_write_mask(DDRPHY,
CCCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
0x2, 0xf);
mrc_alt_write_mask(DDRPHY,
CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET,
0x20, 0x30);
/*
* NUM_SAMPLES, MAX_SAMPLES,
* MACRO_PI_STEP, MICRO_PI_STEP
*/
mrc_alt_write_mask(DDRPHY,
CMDCLKALIGNREG1 + ch * DDRIOCCC_CH_OFFSET,
(0x18 << 16) | (0x10 << 8) |
(0x8 << 2) | (0x1 << 0),
0x007f7fff);
/* TOTAL_NUM_MODULES, FIRST_U_PARTITION */
mrc_alt_write_mask(DDRPHY,
CMDCLKALIGNREG2 + ch * DDRIOCCC_CH_OFFSET,
(0x10 << 16) | (0x4 << 8) | (0x2 << 4),
0x001f0ff0);
#ifdef HMC_TEST
/* START_CLK_ALIGN=1 */
mrc_alt_write_mask(DDRPHY,
CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET,
1 << 24, 1 << 24);
while (msg_port_alt_read(DDRPHY,
CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET) &
(1 << 24))
; /* wait for START_CLK_ALIGN=0 */
#endif
/* Set RD/WR Pointer Seperation & COUNTEN & FIFOPTREN */
mrc_alt_write_mask(DDRPHY,
CMDPTRREG + ch * DDRIOCCC_CH_OFFSET,
1, 1); /* WRPTRENABLE=1 */
/* COMP initial */
/* enable bypass for CLK buffer (PO) */
mrc_alt_write_mask(DDRPHY,
COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
1 << 5, 1 << 5);
/* Initial COMP Enable */
mrc_alt_write_mask(DDRPHY, CMPCTRL, 1, 1);
/* wait for Initial COMP Enable = 0 */
while (msg_port_alt_read(DDRPHY, CMPCTRL) & 1)
;
/* disable bypass for CLK buffer (PO) */
mrc_alt_write_mask(DDRPHY,
COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
~(1 << 5), 1 << 5);
/* IOBUFACT */
/* STEP4a */
mrc_alt_write_mask(DDRPHY,
CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
1 << 2, 1 << 2); /* IOBUFACTRST_N=1 */
/* DDRPHY initialization complete */
mrc_alt_write_mask(DDRPHY,
CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
1 << 20, 1 << 20); /* SPID_INIT_COMPLETE=1 */
}
}
LEAVEFN();
}