summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen3.c41
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c2
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c3
-rw-r--r--arch/powerpc/include/asm/fsl_ddr_dimm_params.h4
-rw-r--r--board/freescale/mpc8572ds/ddr.c110
-rw-r--r--board/freescale/p1_p2_rdb/tlb.c4
-rw-r--r--include/configs/P1_P2_RDB.h24
7 files changed, 141 insertions, 47 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index 73b320b..c8c84a1 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -24,6 +24,8 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR;
u32 total_gb_size_per_controller;
+ unsigned int csn_bnds_backup = 0, cs_sa, cs_ea, *csn_bnds_t;
+ int csn = -1;
#endif
switch (ctrl_num) {
@@ -40,6 +42,22 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
out_be32(&ddr->eor, regs->ddr_eor);
+#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
+ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+ cs_sa = (regs->cs[i].bnds >> 16) & 0xfff;
+ cs_ea = regs->cs[i].bnds & 0xfff;
+ if ((cs_sa <= 0xff) && (cs_ea >= 0xff)) {
+ csn = i;
+ csn_bnds_backup = regs->cs[i].bnds;
+ csn_bnds_t = (unsigned int *) &regs->cs[i].bnds;
+ *csn_bnds_t = regs->cs[i].bnds ^ 0x0F000F00;
+ debug("Found cs%d_bns (0x%08x) covering 0xff000000, "
+ "change it to 0x%x\n",
+ csn, csn_bnds_backup, regs->cs[i].bnds);
+ break;
+ }
+ }
+#endif
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
@@ -308,5 +326,28 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
/* 10. Clear EEBACR[3] */
clrbits_be32(&ecm->eebacr, 10000000);
debug("Clearing EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr));
+
+ if (csn != -1) {
+ csn_bnds_t = (unsigned int *) &regs->cs[csn].bnds;
+ *csn_bnds_t = csn_bnds_backup;
+ debug("Change cs%d_bnds back to 0x%08x\n",
+ csn, regs->cs[csn].bnds);
+ setbits_be32(&ddr->sdram_cfg, 0x2); /* MEM_HALT */
+ switch (csn) {
+ case 0:
+ out_be32(&ddr->cs0_bnds, regs->cs[csn].bnds);
+ break;
+ case 1:
+ out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
+ break;
+ case 2:
+ out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
+ break;
+ case 3:
+ out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
+ break;
+ }
+ clrbits_be32(&ddr->sdram_cfg, 0x2);
+ }
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
}
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 8ef6ca8..cefabe7 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -682,7 +682,9 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
| ((obc_cfg & 0x1) << 6)
| ((ap_en & 0x1) << 5)
| ((d_init & 0x1) << 4)
+#ifdef CONFIG_FSL_DDR3
| ((rcw_en & 0x1) << 2)
+#endif
| ((md_en & 0x1) << 0)
);
debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2);
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 a58e5a9..8b31ec0 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
@@ -367,7 +367,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
/* Determine if all DIMMs ECC capable. */
temp1 = 1;
for (i = 0; i < number_of_dimms; i++) {
- if (dimm_params[i].n_ranks && dimm_params[i].edc_config != 2) {
+ if (dimm_params[i].n_ranks &&
+ !(dimm_params[i].edc_config & EDC_ECC)) {
temp1 = 0;
break;
}
diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
index be82602..982b809 100644
--- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
+++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h
@@ -9,6 +9,10 @@
#ifndef DDR2_DIMM_PARAMS_H
#define DDR2_DIMM_PARAMS_H
+#define EDC_DATA_PARITY 1
+#define EDC_ECC 2
+#define EDC_AC_PARITY 4
+
/* Parameters for a DDR2 dimm computed from the SPD */
typedef struct dimm_params_s {
diff --git a/board/freescale/mpc8572ds/ddr.c b/board/freescale/mpc8572ds/ddr.c
index d66ede2..cdde6ec 100644
--- a/board/freescale/mpc8572ds/ddr.c
+++ b/board/freescale/mpc8572ds/ddr.c
@@ -49,28 +49,27 @@ typedef struct {
u32 force_2T;
} board_specific_parameters_t;
-/* ranges for parameters:
- * wr_data_delay = 0-6
- * clk adjust = 0-8
- * cpo 2-0x1E (30)
+/*
+ * CPO value doesn't matter if workaround for errata 111 and 134 enabled.
+ *
+ * For DDR2 DIMM, all combinations of clk_adjust and write_data_delay have been
+ * tested. For RDIMM, clk_adjust = 4 and write_data_delay = 3 is optimized for
+ * all clocks from 400MT/s to 800MT/s, verified with Kingston KVR800D2D8P6/2G.
+ * For UDIMM, clk_adjust = 8 and write_delay = 5 is optimized for all clocks
+ * from 400MT/s to 800MT/s, verified with Micron MT18HTF25672AY-800E1.
*/
-
-
-/* XXX: these values need to be checked for all interleaving modes. */
-/* XXX: No reliable dual-rank 800 MHz setting has been found. It may
- * seem reliable, but errors will appear when memory intensive
- * program is run. */
-/* XXX: Single rank at 800 MHz is OK. */
-const board_specific_parameters_t board_specific_parameters[][20] = {
+const board_specific_parameters_t board_specific_parameters_udimm[][20] = {
{
- /* memory controller 0 */
- /* lo| hi| num| clk| cpo|wrdata|2T */
- /* mhz| mhz|ranks|adjst| | delay| */
- { 0, 333, 2, 6, 7, 3, 0},
- {334, 400, 2, 6, 9, 3, 0},
- {401, 549, 2, 6, 11, 3, 0},
- {550, 680, 2, 1, 10, 5, 0},
- {681, 850, 2, 1, 12, 5, 1},
+ /*
+ * memory controller 0
+ * lo| hi| num| clk| cpo|wrdata|2T
+ * mhz| mhz|ranks|adjst| | delay|
+ */
+ { 0, 333, 2, 8, 7, 5, 0},
+ {334, 400, 2, 8, 9, 5, 0},
+ {401, 549, 2, 8, 11, 5, 0},
+ {550, 680, 2, 8, 10, 5, 0},
+ {681, 850, 2, 8, 12, 5, 1},
{ 0, 333, 1, 6, 7, 3, 0},
{334, 400, 1, 6, 9, 3, 0},
{401, 549, 1, 6, 11, 3, 0},
@@ -79,14 +78,16 @@ const board_specific_parameters_t board_specific_parameters[][20] = {
},
{
- /* memory controller 1 */
- /* lo| hi| num| clk| cpo|wrdata|2T */
- /* mhz| mhz|ranks|adjst| | delay| */
- { 0, 333, 2, 6, 7, 3, 0},
- {334, 400, 2, 6, 9, 3, 0},
- {401, 549, 2, 6, 11, 3, 0},
- {550, 680, 2, 1, 11, 6, 0},
- {681, 850, 2, 1, 13, 6, 1},
+ /*
+ * memory controller 1
+ * lo| hi| num| clk| cpo|wrdata|2T
+ * mhz| mhz|ranks|adjst| | delay|
+ */
+ { 0, 333, 2, 8, 7, 5, 0},
+ {334, 400, 2, 8, 9, 5, 0},
+ {401, 549, 2, 8, 11, 5, 0},
+ {550, 680, 2, 8, 11, 5, 0},
+ {681, 850, 2, 8, 13, 5, 1},
{ 0, 333, 1, 6, 7, 3, 0},
{334, 400, 1, 6, 9, 3, 0},
{401, 549, 1, 6, 11, 3, 0},
@@ -95,16 +96,56 @@ const board_specific_parameters_t board_specific_parameters[][20] = {
}
};
+const board_specific_parameters_t board_specific_parameters_rdimm[][20] = {
+ {
+ /*
+ * memory controller 0
+ * lo| hi| num| clk| cpo|wrdata|2T
+ * mhz| mhz|ranks|adjst| | delay|
+ */
+ { 0, 333, 2, 4, 7, 3, 0},
+ {334, 400, 2, 4, 9, 3, 0},
+ {401, 549, 2, 4, 11, 3, 0},
+ {550, 680, 2, 4, 10, 3, 0},
+ {681, 850, 2, 4, 12, 3, 1},
+ },
+
+ {
+ /*
+ * memory controller 1
+ * lo| hi| num| clk| cpo|wrdata|2T
+ * mhz| mhz|ranks|adjst| | delay|
+ */
+ { 0, 333, 2, 4, 7, 3, 0},
+ {334, 400, 2, 4, 9, 3, 0},
+ {401, 549, 2, 4, 11, 3, 0},
+ {550, 680, 2, 4, 11, 3, 0},
+ {681, 850, 2, 4, 13, 3, 1},
+ }
+};
+
void fsl_ddr_board_options(memctl_options_t *popts,
dimm_params_t *pdimm,
unsigned int ctrl_num)
{
- const board_specific_parameters_t *pbsp =
- &(board_specific_parameters[ctrl_num][0]);
- u32 num_params = sizeof(board_specific_parameters[ctrl_num]) /
- sizeof(board_specific_parameters[0][0]);
+ const board_specific_parameters_t *pbsp;
+ u32 num_params;
u32 i;
ulong ddr_freq;
+ int matched = 0;
+
+ if (!pdimm->n_ranks)
+ return;
+
+ if (popts->registered_dimm_en) {
+ pbsp = &(board_specific_parameters_rdimm[ctrl_num][0]);
+ num_params = sizeof(board_specific_parameters_rdimm[ctrl_num]) /
+ sizeof(board_specific_parameters_rdimm[0][0]);
+ } else {
+ pbsp = &(board_specific_parameters_udimm[ctrl_num][0]);
+ num_params = sizeof(board_specific_parameters_udimm[ctrl_num]) /
+ sizeof(board_specific_parameters_udimm[0][0]);
+ }
/* set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in
* that controller, set odt_wr_cfg to 4 for CS0, and 0 to CS1. If
@@ -138,10 +179,15 @@ void fsl_ddr_board_options(memctl_options_t *popts,
popts->cpo_override = pbsp->cpo;
popts->write_data_delay = pbsp->write_data_delay;
popts->twoT_en = pbsp->force_2T;
+ matched = 1;
+ break;
}
pbsp++;
}
+ if (!matched)
+ printf("Warning: board specific timing not found!\n");
+
/*
* Factors to consider for half-strength driver enable:
* - number of DIMMs installed
diff --git a/board/freescale/p1_p2_rdb/tlb.c b/board/freescale/p1_p2_rdb/tlb.c
index b85c268..a46b1b5 100644
--- a/board/freescale/p1_p2_rdb/tlb.c
+++ b/board/freescale/p1_p2_rdb/tlb.c
@@ -60,12 +60,12 @@ struct fsl_e_tlb_entry tlb_table[] = {
#if defined(CONFIG_PCI)
/* *I*G* - PCI */
- SET_TLB_ENTRY(1, CONFIG_SYS_PCIE2_MEM_VIRT, CONFIG_SYS_PCIE2_MEM_PHYS,
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 3, BOOKE_PAGESZ_1G, 1),
/* *I*G* - PCI I/O */
- SET_TLB_ENTRY(1, CONFIG_SYS_PCIE2_IO_VIRT, CONFIG_SYS_PCIE2_IO_PHYS,
+ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 4, BOOKE_PAGESZ_256K, 1),
diff --git a/include/configs/P1_P2_RDB.h b/include/configs/P1_P2_RDB.h
index 982cdd5..95b85e3 100644
--- a/include/configs/P1_P2_RDB.h
+++ b/include/configs/P1_P2_RDB.h
@@ -177,8 +177,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
* Memory map
*
* 0x0000_0000 0x3fff_ffff DDR 1G cacheablen
- * 0xa000_0000 0xbfff_ffff PCI Express Mem 1G non-cacheable
- * 0xffc2_0000 0xffc5_ffff PCI IO range 256K non-cacheable
+ * 0x8000_0000 0xbfff_ffff PCI Express Mem 1G non-cacheable
+ * 0xffc0_0000 0xffc3_ffff PCI IO range 256k non-cacheable
*
* Localbus cacheable (TBD)
* 0xXXXX_XXXX 0xXXXX_XXXX SRAM YZ M Cacheable
@@ -368,27 +368,27 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
* Memory space is mapped 1-1, but I/O space must start from 0.
*/
-/* controller 2, Slot 2, tgtid 2, Base address 9000 */
#if defined(CONFIG_PCI)
+/* controller 2, Slot 2, tgtid 2, Base address 9000 */
#define CONFIG_SYS_PCIE2_NAME "Slot 1"
#define CONFIG_SYS_PCIE2_MEM_VIRT 0xa0000000
#define CONFIG_SYS_PCIE2_MEM_BUS 0xa0000000
#define CONFIG_SYS_PCIE2_MEM_PHYS 0xa0000000
#define CONFIG_SYS_PCIE2_MEM_SIZE 0x20000000 /* 512M */
-#define CONFIG_SYS_PCIE2_IO_VIRT 0xffc20000
-#define CONFIG_SYS_PCIE2_IO_BUS 0x00000000
-#define CONFIG_SYS_PCIE2_IO_PHYS 0xffc20000
+#define CONFIG_SYS_PCIE2_IO_VIRT 0xffc10000
+#define CONFIG_SYS_PCIE2_IO_BUS 0x00000000
+#define CONFIG_SYS_PCIE2_IO_PHYS 0xffc10000
#define CONFIG_SYS_PCIE2_IO_SIZE 0x00010000 /* 64k */
/* controller 1, Slot 1, tgtid 1, Base address a000 */
#define CONFIG_SYS_PCIE1_NAME "Slot 2"
-#define CONFIG_SYS_PCIE1_MEM_VIRT 0xc0000000
-#define CONFIG_SYS_PCIE1_MEM_BUS 0xc0000000
-#define CONFIG_SYS_PCIE1_MEM_PHYS 0xc0000000
+#define CONFIG_SYS_PCIE1_MEM_VIRT 0x80000000
+#define CONFIG_SYS_PCIE1_MEM_BUS 0x80000000
+#define CONFIG_SYS_PCIE1_MEM_PHYS 0x80000000
#define CONFIG_SYS_PCIE1_MEM_SIZE 0x20000000 /* 512M */
-#define CONFIG_SYS_PCIE1_IO_VIRT 0xffc30000
-#define CONFIG_SYS_PCIE1_IO_BUS 0x00000000
-#define CONFIG_SYS_PCIE1_IO_PHYS 0xffc30000
+#define CONFIG_SYS_PCIE1_IO_VIRT 0xffc00000
+#define CONFIG_SYS_PCIE1_IO_BUS 0x00000000
+#define CONFIG_SYS_PCIE1_IO_PHYS 0xffc00000
#define CONFIG_SYS_PCIE1_IO_SIZE 0x00010000 /* 64k */
#define CONFIG_PCI_PNP /* do pci plug-and-play */