Commit 1d71efbb authored by York Sun's avatar York Sun

driver/ddr: Restruct driver to allow standalone memory space

U-boot has been initializing DDR for the main memory. The presumption
is the memory stays as a big continuous block, either linear or
interleaved. This change is to support putting some DDR controllers
to separated space without counting into main memory. The standalone
memory controller could use different number of DIMM slots.
Signed-off-by: default avatarYork Sun <yorksun@freescale.com>
parent e211c12e
......@@ -538,6 +538,12 @@ The following options need to be configured:
interleaving mode, handled by Dickens for Freescale layerscape
SoCs with ARM core.
CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS
Number of controllers used as main memory.
CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
Number of controllers used for other than main memory.
- Intel Monahans options:
CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
......
......@@ -441,7 +441,7 @@ phys_size_t initdram(int board_type)
/* Board-specific functions defined in each board's ddr.c */
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
unsigned int ctrl_num);
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
phys_addr_t *rpn);
unsigned int
......@@ -459,7 +459,7 @@ static void dump_spd_ddr_reg(void)
spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR];
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
fsl_ddr_get_spd(spd[i], i);
fsl_ddr_get_spd(spd[i], i, CONFIG_DIMM_SLOTS_PER_CTLR);
puts("SPD data of all dimms (zero vaule is omitted)...\n");
puts("Byte (hex) ");
......
......@@ -113,7 +113,7 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
#define spd_to_ps(mtb, ftb) \
(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10)
/*
* ddr_compute_dimm_parameters for DDR3 SPD
* ddr_compute_dimm_parameters for DDR4 SPD
*
* Compute DIMM parameters based upon the SPD information in spd.
* Writes the results to the dimm_params_t structure pointed by pdimm.
......@@ -165,17 +165,17 @@ ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
+ pdimm->ec_sdram_width;
pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
/* These are the types defined by the JEDEC DDR3 SPD spec */
/* These are the types defined by the JEDEC SPD spec */
pdimm->mirrored_dimm = 0;
pdimm->registered_dimm = 0;
switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
case DDR3_SPD_MODULETYPE_RDIMM:
switch (spd->module_type & DDR4_SPD_MODULETYPE_MASK) {
case DDR4_SPD_MODULETYPE_RDIMM:
/* Registered/buffered DIMMs */
pdimm->registered_dimm = 1;
break;
case DDR3_SPD_MODULETYPE_UDIMM:
case DDR3_SPD_MODULETYPE_SO_DIMM:
case DDR4_SPD_MODULETYPE_UDIMM:
case DDR4_SPD_MODULETYPE_SO_DIMM:
/* Unbuffered DIMMs */
if (spd->mod_section.unbuffered.addr_mapping & 0x1)
pdimm->mirrored_dimm = 1;
......
This diff is collapsed.
......@@ -1065,18 +1065,21 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
unsigned long long check_rank_density;
struct dimm_params_s *dimm;
int first_ctrl = pinfo->first_ctrl;
int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
/*
* Check if all controllers are configured for memory
* controller interleaving. Identical dimms are recommended. At least
* the size, row and col address should be checked.
*/
j = 0;
check_n_ranks = pinfo->dimm_params[0][0].n_ranks;
check_rank_density = pinfo->dimm_params[0][0].rank_density;
check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr;
check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr;
check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode;
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks;
check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density;
check_n_row_addr = pinfo->dimm_params[first_ctrl][0].n_row_addr;
check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr;
check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode;
for (i = first_ctrl; i <= last_ctrl; i++) {
dimm = &pinfo->dimm_params[i][0];
if (!pinfo->memctl_opts[i].memctl_interleaving) {
continue;
......@@ -1094,7 +1097,7 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
}
if (intlv_invalid) {
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
for (i = first_ctrl; i <= last_ctrl; i++)
pinfo->memctl_opts[i].memctl_interleaving = 0;
printf("Not all DIMMs are identical. "
"Memory controller interleaving disabled.\n");
......@@ -1123,10 +1126,10 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
}
debug("%d of %d controllers are interleaving.\n", j, k);
if (j && (j != k)) {
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
for (i = first_ctrl; i <= last_ctrl; i++)
pinfo->memctl_opts[i].memctl_interleaving = 0;
printf("Not all controllers have compatible "
"interleaving mode. All disabled.\n");
if ((last_ctrl - first_ctrl) > 1)
puts("Not all controllers have compatible interleaving mode. All disabled.\n");
}
}
debug("Checking interleaving options completed\n");
......
......@@ -149,7 +149,7 @@ u32 fsl_ddr_get_intl3r(void)
return val;
}
void board_add_ram_info(int use_default)
void print_ddr_info(unsigned int start_ctrl)
{
struct ccsr_ddr __iomem *ddr =
(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);
......@@ -164,17 +164,25 @@ void board_add_ram_info(int use_default)
int cas_lat;
#if CONFIG_NUM_DDR_CONTROLLERS >= 2
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
(start_ctrl == 1)) {
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
}
#endif
#if CONFIG_NUM_DDR_CONTROLLERS >= 3
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
(start_ctrl == 2)) {
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
}
#endif
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
puts(" (DDR not enabled)\n");
return;
}
puts(" (DDR");
switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >>
SDRAM_CFG_SDRAM_TYPE_SHIFT) {
......@@ -241,7 +249,7 @@ void board_add_ram_info(int use_default)
#endif
#endif
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
if (cs0_config & 0x20000000) {
if ((cs0_config & 0x20000000) && (start_ctrl == 0)) {
puts("\n");
puts(" DDR Controller Interleaving Mode: ");
......@@ -290,3 +298,13 @@ void board_add_ram_info(int use_default)
}
}
}
void __weak detail_board_ddr_info(void)
{
print_ddr_info(0);
}
void board_add_ram_info(int use_default)
{
detail_board_ddr_info();
}
......@@ -15,6 +15,11 @@
#include <common_timing_params.h>
#ifndef CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS
/* All controllers are for main memory */
#define CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS CONFIG_NUM_DDR_CONTROLLERS
#endif
#ifdef CONFIG_SYS_FSL_DDR_LE
#define ddr_in32(a) in_le32(a)
#define ddr_out32(a, v) out_le32(a, v)
......@@ -57,6 +62,13 @@ typedef struct {
memctl_options_t memctl_opts[CONFIG_SYS_NUM_DDR_CTLRS];
common_timing_params_t common_timing_params[CONFIG_SYS_NUM_DDR_CTLRS];
fsl_ddr_cfg_regs_t fsl_ddr_config_reg[CONFIG_SYS_NUM_DDR_CTLRS];
unsigned int first_ctrl;
unsigned int num_ctrls;
unsigned long long mem_base;
unsigned int dimm_slots_per_ctrl;
int (*board_need_mem_reset)(void);
void (*board_mem_reset)(void);
void (*board_mem_de_reset)(void);
} fsl_ddr_info_t;
/* Compute steps */
......@@ -72,7 +84,6 @@ typedef struct {
unsigned long long
fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
unsigned int size_only);
const char *step_to_string(unsigned int step);
unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts,
......@@ -102,7 +113,7 @@ void fsl_ddr_set_lawbar(
int fsl_ddr_interactive_env_var_exists(void);
unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set);
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
unsigned int ctrl_num);
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr);
......
......@@ -379,12 +379,20 @@ typedef struct memctl_options_s {
unsigned int trwt; /* read-to-write turnaround */
} memctl_options_t;
extern phys_size_t fsl_ddr_sdram(void);
extern phys_size_t fsl_ddr_sdram_size(void);
phys_size_t fsl_ddr_sdram(void);
phys_size_t fsl_ddr_sdram_size(void);
phys_size_t fsl_other_ddr_sdram(unsigned long long base,
unsigned int first_ctrl,
unsigned int num_ctrls,
unsigned int dimm_slots_per_ctrl,
int (*board_need_reset)(void),
void (*board_reset)(void),
void (*board_de_reset)(void));
extern int fsl_use_spd(void);
extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step);
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step);
u32 fsl_ddr_get_intl3r(void);
void print_ddr_info(unsigned int start_ctrl);
static void __board_assert_mem_reset(void)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment