|
@@ -25,10 +25,6 @@ void fsl_ddr_set_lawbar(
|
|
unsigned int ctrl_num);
|
|
unsigned int ctrl_num);
|
|
void fsl_ddr_set_intl3r(const unsigned int granule_size);
|
|
void fsl_ddr_set_intl3r(const unsigned int granule_size);
|
|
|
|
|
|
-/* processor specific function */
|
|
|
|
-extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
|
|
|
- unsigned int ctrl_num);
|
|
|
|
-
|
|
|
|
#if defined(SPD_EEPROM_ADDRESS) || \
|
|
#if defined(SPD_EEPROM_ADDRESS) || \
|
|
defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \
|
|
defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \
|
|
defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4)
|
|
defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4)
|
|
@@ -365,9 +361,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
|
{
|
|
{
|
|
unsigned int i, j;
|
|
unsigned int i, j;
|
|
unsigned long long total_mem = 0;
|
|
unsigned long long total_mem = 0;
|
|
|
|
+ int assert_reset;
|
|
|
|
|
|
fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
|
|
fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
|
|
common_timing_params_t *timing_params = pinfo->common_timing_params;
|
|
common_timing_params_t *timing_params = pinfo->common_timing_params;
|
|
|
|
+ assert_reset = board_need_mem_reset();
|
|
|
|
|
|
/* data bus width capacity adjust shift amount */
|
|
/* data bus width capacity adjust shift amount */
|
|
unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
|
|
unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
|
|
@@ -462,7 +460,20 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
|
timing_params[i].all_DIMMs_registered,
|
|
timing_params[i].all_DIMMs_registered,
|
|
&pinfo->memctl_opts[i],
|
|
&pinfo->memctl_opts[i],
|
|
pinfo->dimm_params[i], i);
|
|
pinfo->dimm_params[i], i);
|
|
|
|
+ /*
|
|
|
|
+ * For RDIMMs, JEDEC spec requires clocks to be stable
|
|
|
|
+ * before reset signal is deasserted. For the boards
|
|
|
|
+ * using fixed parameters, this function should be
|
|
|
|
+ * be called from board init file.
|
|
|
|
+ */
|
|
|
|
+ if (timing_params[i].all_DIMMs_registered)
|
|
|
|
+ assert_reset = 1;
|
|
|
|
+ }
|
|
|
|
+ if (assert_reset) {
|
|
|
|
+ debug("Asserting mem reset\n");
|
|
|
|
+ board_assert_mem_reset();
|
|
}
|
|
}
|
|
|
|
+
|
|
case STEP_ASSIGN_ADDRESSES:
|
|
case STEP_ASSIGN_ADDRESSES:
|
|
/* STEP 5: Assign addresses to chip selects */
|
|
/* STEP 5: Assign addresses to chip selects */
|
|
check_interleaving_options(pinfo);
|
|
check_interleaving_options(pinfo);
|
|
@@ -537,6 +548,7 @@ phys_size_t fsl_ddr_sdram(void)
|
|
unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
|
|
unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
|
|
unsigned long long total_memory;
|
|
unsigned long long total_memory;
|
|
fsl_ddr_info_t info;
|
|
fsl_ddr_info_t info;
|
|
|
|
+ int deassert_reset;
|
|
|
|
|
|
/* Reset info structure. */
|
|
/* Reset info structure. */
|
|
memset(&info, 0, sizeof(fsl_ddr_info_t));
|
|
memset(&info, 0, sizeof(fsl_ddr_info_t));
|
|
@@ -565,7 +577,21 @@ phys_size_t fsl_ddr_sdram(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* Program configuration registers. */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Program configuration registers.
|
|
|
|
+ * JEDEC specs requires clocks to be stable before deasserting reset
|
|
|
|
+ * for RDIMMs. Clocks start after chip select is enabled and clock
|
|
|
|
+ * control register is set. During step 1, all controllers have their
|
|
|
|
+ * registers set but not enabled. Step 2 proceeds after deasserting
|
|
|
|
+ * reset through board FPGA or GPIO.
|
|
|
|
+ * For non-registered DIMMs, initialization can go through but it is
|
|
|
|
+ * also OK to follow the same flow.
|
|
|
|
+ */
|
|
|
|
+ deassert_reset = board_need_mem_reset();
|
|
|
|
+ for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
|
|
|
+ if (info.common_timing_params[i].all_DIMMs_registered)
|
|
|
|
+ deassert_reset = 1;
|
|
|
|
+ }
|
|
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
|
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
|
debug("Programming controller %u\n", i);
|
|
debug("Programming controller %u\n", i);
|
|
if (info.common_timing_params[i].ndimms_present == 0) {
|
|
if (info.common_timing_params[i].ndimms_present == 0) {
|
|
@@ -573,8 +599,22 @@ phys_size_t fsl_ddr_sdram(void)
|
|
"skipping programming\n", i);
|
|
"skipping programming\n", i);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
-
|
|
|
|
- fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * The following call with step = 1 returns before enabling
|
|
|
|
+ * the controller. It has to finish with step = 2 later.
|
|
|
|
+ */
|
|
|
|
+ fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i,
|
|
|
|
+ deassert_reset ? 1 : 0);
|
|
|
|
+ }
|
|
|
|
+ if (deassert_reset) {
|
|
|
|
+ /* Use board FPGA or GPIO to deassert reset signal */
|
|
|
|
+ debug("Deasserting mem reset\n");
|
|
|
|
+ board_deassert_mem_reset();
|
|
|
|
+ for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
|
|
|
+ /* Call with step = 2 to continue initialization */
|
|
|
|
+ fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]),
|
|
|
|
+ i, 2);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* program LAWs */
|
|
/* program LAWs */
|