diff options
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 3 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/options.c | 244 | ||||
-rw-r--r-- | arch/powerpc/include/asm/fsl_ddr_sdram.h | 5 | ||||
-rw-r--r-- | doc/README.fsl-ddr | 52 |
4 files changed, 287 insertions, 17 deletions
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 8132e68..20c7db0 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -448,7 +448,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, #if defined(CONFIG_FSL_DDR2) if (lowest_good_caslat < 4) { - additive_latency = picos_to_mclk(tRCD_ps) - lowest_good_caslat; + additive_latency = (picos_to_mclk(tRCD_ps) > lowest_good_caslat) + ? picos_to_mclk(tRCD_ps) - lowest_good_caslat : 0; if (mclk_to_picos(additive_latency) > tRCD_ps) { additive_latency = picos_to_mclk(tRCD_ps); debug("setting additive_latency to %u because it was " diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 89dc479..4dc748b 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -26,14 +26,15 @@ extern void fsl_ddr_board_options(memctl_options_t *popts, dimm_params_t *pdimm, unsigned int ctrl_num); -typedef struct { +struct dynamic_odt { unsigned int odt_rd_cfg; unsigned int odt_wr_cfg; unsigned int odt_rtt_norm; unsigned int odt_rtt_wr; -} dynamic_odt_t; +}; -static const dynamic_odt_t single_Q[4] = { +#ifdef CONFIG_FSL_DDR3 +static const struct dynamic_odt single_Q[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS_AND_OTHER_DIMM, @@ -60,7 +61,7 @@ static const dynamic_odt_t single_Q[4] = { } }; -static const dynamic_odt_t single_D[4] = { +static const struct dynamic_odt single_D[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -77,7 +78,7 @@ static const dynamic_odt_t single_D[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t single_S[4] = { +static const struct dynamic_odt single_S[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -89,7 +90,7 @@ static const dynamic_odt_t single_S[4] = { {0, 0, 0, 0}, }; -static const dynamic_odt_t dual_DD[4] = { +static const struct dynamic_odt dual_DD[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -116,7 +117,7 @@ static const dynamic_odt_t dual_DD[4] = { } }; -static const dynamic_odt_t dual_DS[4] = { +static const struct dynamic_odt dual_DS[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -137,7 +138,7 @@ static const dynamic_odt_t dual_DS[4] = { }, {0, 0, 0, 0} }; -static const dynamic_odt_t dual_SD[4] = { +static const struct dynamic_odt dual_SD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -159,7 +160,7 @@ static const dynamic_odt_t dual_SD[4] = { } }; -static const dynamic_odt_t dual_SS[4] = { +static const struct dynamic_odt dual_SS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -176,7 +177,7 @@ static const dynamic_odt_t dual_SS[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t dual_D0[4] = { +static const struct dynamic_odt dual_D0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -193,7 +194,7 @@ static const dynamic_odt_t dual_D0[4] = { {0, 0, 0, 0} }; -static const dynamic_odt_t dual_0D[4] = { +static const struct dynamic_odt dual_0D[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -210,7 +211,7 @@ static const dynamic_odt_t dual_0D[4] = { } }; -static const dynamic_odt_t dual_S0[4] = { +static const struct dynamic_odt dual_S0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -223,7 +224,7 @@ static const dynamic_odt_t dual_S0[4] = { }; -static const dynamic_odt_t dual_0S[4] = { +static const struct dynamic_odt dual_0S[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -236,7 +237,7 @@ static const dynamic_odt_t dual_0S[4] = { }; -static const dynamic_odt_t odt_unknown[4] = { +static const struct dynamic_odt odt_unknown[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -262,7 +263,218 @@ static const dynamic_odt_t odt_unknown[4] = { DDR3_RTT_OFF } }; +#else /* CONFIG_FSL_DDR3 */ +static const struct dynamic_odt single_Q[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt single_D[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt single_S[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, +}; + +static const struct dynamic_odt dual_DD[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; + +static const struct dynamic_odt dual_DS[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_SD[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; +static const struct dynamic_odt dual_SS[4] = { + { /* cs0 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_OTHER_DIMM, + FSL_DDR_ODT_OTHER_DIMM, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_D0[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static const struct dynamic_odt dual_0D[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_ALL, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; + +static const struct dynamic_odt dual_S0[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + +}; + +static const struct dynamic_odt dual_0S[4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_150_OHM, + DDR2_RTT_OFF + }, + {0, 0, 0, 0} + +}; + +static const struct dynamic_odt odt_unknown[4] = { + { /* cs0 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs1 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + }, + { /* cs2 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_CS, + DDR2_RTT_75_OHM, + DDR2_RTT_OFF + }, + { /* cs3 */ + FSL_DDR_ODT_NEVER, + FSL_DDR_ODT_NEVER, + DDR2_RTT_OFF, + DDR2_RTT_OFF + } +}; +#endif unsigned int populate_memctl_options(int all_DIMMs_registered, memctl_options_t *popts, dimm_params_t *pdimm, @@ -271,7 +483,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, unsigned int i; char buffer[HWCONFIG_BUFFER_SIZE]; char *buf = NULL; - const dynamic_odt_t *pdodt = odt_unknown; + const struct dynamic_odt *pdodt = odt_unknown; ulong ddr_freq; /* @@ -337,7 +549,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, /* Pick chip-select local options. */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { -#if defined(CONFIG_FSL_DDR3) +#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2) popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 5b6e8d9..93639ba 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -31,6 +31,11 @@ #define DDR3_RTT_20_OHM 4 /* RTT_Nom = RZQ/12 */ #define DDR3_RTT_30_OHM 5 /* RTT_Nom = RZQ/8 */ +#define DDR2_RTT_OFF 0 +#define DDR2_RTT_75_OHM 1 +#define DDR2_RTT_150_OHM 2 +#define DDR2_RTT_50_OHM 3 + #if defined(CONFIG_FSL_DDR1) #define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (1) typedef ddr1_spd_eeprom_t generic_spd_eeprom_t; diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr index c1ee0a6..abfb7f1 100644 --- a/doc/README.fsl-ddr +++ b/doc/README.fsl-ddr @@ -170,3 +170,55 @@ Single slot system Reference http://www.xrosstalkmag.com/mag_issues/xrosstalk_oct08_final.pdf http://download.micron.com/pdf/technotes/ddr3/tn4108_ddr3_design_guide.pdf + + +Table for ODT for DDR2 +====================== +Two slots system ++-----------------------+----------+---------------+-----------------------------+-----------------------------+ +| Configuration | |DRAM controller| Slot 1 | Slot 2 | ++-----------+-----------+----------+-------+-------+--------------+--------------+--------------+--------------+ +| | | | | | Rank 1 | Rank 2 | Rank 1 | Rank 2 | ++ Slot 1 | Slot 2 |Write/Read| Write | Read |-------+------+-------+------+-------+------+-------+------+ +| | | | | | Write | Read | Write | Read | Write | Read | Write | Read | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 1 | off | 150 | off | off | off | off | 75 | 75 | off | off | +| Dual Rank | Dual Rank |----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 2 | off | 150 | 75 | 75 | off | off | off | off | off | off | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 1 | off | 150 | off | off | off | off | 75 | 75 | | | +| Dual Rank |Single Rank|----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 2 | off | 150 | 75 | 75 | off | off | off | off | | | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 1 | off | 150 | off | off | | | 75 | 75 | off | off | +|Single Rank| Dual Rank |----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 2 | off | 150 | 75 | 75 | | | off | off | off | off | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 1 | off | 150 | off | off | | | 75 | 75 | | | +|Single Rank|Single Rank|----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| | | Slot 2 | off | 150 | 75 | 75 | | | off | off | | | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| Dual Rank | Empty | Slot 1 | off | 75 | 150 | off | off | off | | | | | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| Empty | Dual Rank | Slot 2 | off | 75 | | | | | 150 | off | off | off | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +|Single Rank| Empty | Slot 1 | off | 75 | 150 | off | | | | | | | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ +| Empty |Single Rank| Slot 2 | off | 75 | | | | | 150 | off | | | ++-----------+-----------+----------+-------+-------+-------+------+-------+------+-------+------+-------+------+ + +Single slot system ++-------------+------------+---------------+-----------------------------+ +| | |DRAM controller| Rank 1 | Rank 2 | +|Configuration| Write/Read |-------+-------+-------+------+-------+------+ +| | | Write | Read | Write | Read | Write | Read | ++-------------+------------+-------+-------+-------+------+-------+------+ +| | R1 | off | 75 | 150 | off | off | off | +| Dual Rank |------------+-------+-------+-------+------+-------+------+ +| | R2 | off | 75 | 150 | off | off | off | ++-------------+------------+-------+-------+-------+------+-------+------+ +| Single Rank | R1 | off | 75 | 150 | off | ++-------------+------------+-------+-------+-------+------+ + +Reference http://www.samsung.com/global/business/semiconductor/products/dram/downloads/applicationnote/ddr2_odt_control_200603.pdf + |