Created
April 24, 2022 07:06
-
-
Save qinghon/422164726d26b1d0b51254ba7a26ca8a to your computer and use it in GitHub Desktop.
Revisions
-
qinghon renamed this gist
Apr 24, 2022 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
qinghon created this gist
Apr 24, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,199 @@ // plat/nxp/drivers/ddr/nxp-ddr/ddr.c /* Return the bit mask of valid DIMMs found */ static int parse_spd(struct ddr_info *priv) { struct ddr_conf *conf = &priv->conf; struct dimm_params *dimm = &priv->dimm; int j, valid_mask = 0; #ifdef CONFIG_DDR_NODIMM valid_mask = ddr_get_ddr_params(dimm, conf); if (valid_mask < 0) { ERROR("DDR params error\n"); return valid_mask; } #else const int *spd_addr = priv->spd_addr; const int num_ctlrs = priv->num_ctlrs; const int num_dimm = priv->dimm_on_ctlr; struct ddr4_spd spd[2]; unsigned int spd_checksum[2]; int addr_idx = 0; int spd_idx = 0; int ret, addr, i; /* Scan all DIMMs */ for (i = 0; i < num_ctlrs; i++) { debug("Controller %d\n", i); for (j = 0; j < num_dimm; j++, addr_idx++) { debug("DIMM %d\n", j); addr = spd_addr[addr_idx]; if (!addr) { if (!j) { ERROR("First SPD addr wrong.\n"); return -EINVAL; } continue; } debug("addr 0x%x\n", addr); ret = read_spd(addr, &spd[spd_idx], sizeof(struct ddr4_spd)); if (ret) { /* invalid */ debug("Invalid SPD at address 0x%x\n", addr); continue; } spd_checksum[spd_idx] = (spd[spd_idx].crc[1] << 24) | (spd[spd_idx].crc[0] << 16) | (spd[spd_idx].mod_section.uc[127] << 8) | (spd[spd_idx].mod_section.uc[126] << 0); debug("checksum 0x%x\n", spd_checksum[spd_idx]); if (!spd_checksum[spd_idx]) { debug("Bad checksum, ignored.\n"); continue; } if (!spd_idx) { /* first valid SPD */ ret = cal_dimm_params(&spd[0], dimm); if (ret) { ERROR("SPD calculation error\n"); return -EINVAL; } } if (spd_idx && spd_checksum[0] != spd_checksum[spd_idx]) { ERROR("Not identical DIMMs.\n"); return -EINVAL; } conf->dimm_in_use[j] = 1; valid_mask |= 1 << addr_idx; spd_idx = 1; } debug("done with controller %d\n", i); } switch (num_ctlrs) { case 1: if (!(valid_mask & 0x1)) { ERROR("First slot cannot be empty.\n"); return -EINVAL; } break; case 2: switch (num_dimm) { case 1: if (!valid_mask) { ERROR("Both slot empty\n"); i2c_bus_release(); // 这个地方 soc_sys_reset(); return -EINVAL; } break; case 2: if (valid_mask != 0x5 && valid_mask != 0xf && (valid_mask & 0x7) != 0x4 && (valid_mask & 0xd) != 0x1) { ERROR("Invalid DIMM combination.\n"); return -EINVAL; } break; default: ERROR("Invalid number of DIMMs.\n"); return -EINVAL; } break; default: ERROR("Invalid number of controllers.\n"); return -EINVAL; } /* now we have valid and identical DIMMs on controllers */ #endif /* CONFIG_DDR_NODIMM */ debug("cal cs\n"); conf->cs_in_use = 0; for (j = 0; j < DDRC_NUM_DIMM; j++) { if (!conf->dimm_in_use[j]) continue; switch (dimm->n_ranks) { case 4: ERROR("Quad-rank DIMM not supported\n"); return -EINVAL; case 2: conf->cs_on_dimm[j] = 0x3 << (j * CONFIG_CS_PER_SLOT); conf->cs_in_use |= conf->cs_on_dimm[j]; break; case 1: conf->cs_on_dimm[j] = 0x1 << (j * CONFIG_CS_PER_SLOT); conf->cs_in_use |= conf->cs_on_dimm[j]; break; default: ERROR("SPD error with n_ranks\n"); return -EINVAL; } debug("cs_in_use = %x\n", conf->cs_in_use); debug("cs_on_dimm[%d] = %x\n", j, conf->cs_on_dimm[j]); } #ifndef CONFIG_DDR_NODIMM if (priv->dimm.rdimm) NOTICE("RDIMM %s\n", priv->dimm.mpart); else NOTICE("UDIMM %s\n", priv->dimm.mpart); #else NOTICE("%s\n", priv->dimm.mpart); #endif return valid_mask; } // plat/nxp/soc-lx2160/lx2160a_dpn4025/ddr_init.c void soc_sys_reset(void) { *(int *)(NXP_RST_ADDR + RSTCNTL_OFFSET) = SW_RST_REQ_INIT; asm volatile("dc cvac,%0" : :"r"((unsigned long long)(NXP_RST_ADDR + RSTCNTL_OFFSET)) : ); asm volatile("dsb st": : :); asm volatile("isb": : :); } /* * errata: a-010650 */ void i2c_bus_release(void) { uint reg_a; int i; //step 2 ERROR("Step 1\n"); reg_a = in_be32(0x700100134); ERROR("Step 2\n"); //step 3 out_be32(0x700100134, reg_a | 0x400); udelay(10); ERROR("Step 3\n"); //step 4 out_be32(0x2300000, 0x10000000); udelay(10); ERROR("Step 4\n"); //step 5 for (i = 0; i < 9; ++i) { out_be32(0x2300008, 0x10000000); udelay(10); out_be32(0x2300008, 0); udelay(10); } ERROR("Step 5\n"); //step 6 out8(0x2000002, 0); udelay(10); out8(0x2000002, 0x80); ERROR("Step 6\n"); //step 7 out32(0x700100134, 0); ERROR("Step 7\n"); //step 8 out8(0x2000003, in8(0x2000003) & 0xef); ERROR("Step 8\n"); ERROR("DDR bus 0 released . reseting\n"); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ NOTICE: BL2: v1.5(release):LSDK-20.04-4-gdcfc62e80-dirty NOTICE: BL2: Built : 21:23:22, Apr 22 2022 NOTICE: time base 7 ms NOTICE: BL2: v1.5(release):LSDK-20.04-4-gdcfc62e80-dirty NOTICE: BL2: Built : 21:23:22, Apr 22 2022 NOTICE: time base 7 ms ERROR: Both slot empty ERROR: Step 1