public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Kumar Gala <galak@kernel.crashing.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs.
Date: Wed, 14 Jul 2010 10:14:57 -0500	[thread overview]
Message-ID: <1279120502-6289-3-git-send-email-galak@kernel.crashing.org> (raw)
In-Reply-To: <1279120502-6289-2-git-send-email-galak@kernel.crashing.org>

From: york <yorksun@freescale.com>

Previous code presumes each DIMM has up to two rank (chip select). Newer
DDR controller supports up to four chip select on one DIMM.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c           |   52 ++++++++++++++-----
 .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c        |   12 +++++
 arch/powerpc/cpu/mpc8xxx/ddr/options.c             |   17 ++++---
 arch/powerpc/include/asm/fsl_ddr_sdram.h           |    1 +
 4 files changed, 61 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 69c1c7c..6e73b1d 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -93,7 +93,7 @@ static inline unsigned int compute_cas_write_latency(void)
 }
 
 /* Chip Select Configuration (CSn_CONFIG) */
-static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr,
+static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,
 			       const memctl_options_t *popts,
 			       const dimm_params_t *dimm_params)
 {
@@ -106,28 +106,49 @@ static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr,
 	unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */
 	unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */
 	unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */
+	int go_config = 0;
 
 	/* Compute CS_CONFIG only for existing ranks of each DIMM.  */
-	if ((((i&1) == 0)
-	    && (dimm_params[i/2].n_ranks == 1))
-	    || (dimm_params[i/2].n_ranks == 2)) {
-		unsigned int n_banks_per_sdram_device;
-		cs_n_en = 1;
-		if (i == 0) {
+	switch (i) {
+	case 0:
+		if (dimm_params[dimm_number].n_ranks > 0) {
+			go_config = 1;
 			/* These fields only available in CS0_CONFIG */
 			intlv_en = popts->memctl_interleaving;
 			intlv_ctl = popts->memctl_interleaving_mode;
 		}
+		break;
+	case 1:
+		if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \
+		    (dimm_number == 1 && dimm_params[1].n_ranks > 0))
+			go_config = 1;
+		break;
+	case 2:
+		if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \
+		   (dimm_number > 1 && dimm_params[dimm_number].n_ranks > 0))
+			go_config = 1;
+		break;
+	case 3:
+		if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \
+		    (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \
+		    (dimm_number == 3 && dimm_params[3].n_ranks > 0))
+			go_config = 1;
+		break;
+	default:
+		break;
+	}
+	if (go_config) {
+		unsigned int n_banks_per_sdram_device;
+		cs_n_en = 1;
 		ap_n_en = popts->cs_local_opts[i].auto_precharge;
 		odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
 		odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
 		n_banks_per_sdram_device
-			= dimm_params[i/2].n_banks_per_sdram_device;
+			= dimm_params[dimm_number].n_banks_per_sdram_device;
 		ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2;
-		row_bits_cs_n = dimm_params[i/2].n_row_addr - 12;
-		col_bits_cs_n = dimm_params[i/2].n_col_addr - 8;
+		row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12;
+		col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8;
 	}
-
 	ddr->cs[i].config = (0
 		| ((cs_n_en & 0x1) << 31)
 		| ((intlv_en & 0x3) << 29)
@@ -521,6 +542,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 	unsigned int d_init;		/* DRAM data initialization */
 	unsigned int rcw_en = 0;	/* Register Control Word Enable */
 	unsigned int md_en = 0;		/* Mirrored DIMM Enable */
+	unsigned int qd_en = 0;		/* quad-rank DIMM Enable */
 
 	dll_rst_dis = 1;	/* Make this configurable */
 	dqs_cfg = popts->DQS_config;
@@ -562,6 +584,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 #if defined(CONFIG_FSL_DDR3)
 	md_en = popts->mirrored_dimm;
 #endif
+	qd_en = popts->quad_rank_present ? 1 : 0;
 	ddr->ddr_sdram_cfg_2 = (0
 		| ((frc_sr & 0x1) << 31)
 		| ((sr_ie & 0x1) << 30)
@@ -569,6 +592,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 		| ((dqs_cfg & 0x3) << 26)
 		| ((odt_cfg & 0x3) << 21)
 		| ((num_pr & 0xf) << 12)
+		| (qd_en << 9)
 		| ((obc_cfg & 0x1) << 6)
 		| ((ap_en & 0x1) << 5)
 		| ((d_init & 0x1) << 4)
@@ -1219,12 +1243,12 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 			 * But we need to set the ODT_RD_CFG and
 			 * ODT_WR_CFG for CS1_CONFIG here.
 			 */
-			set_csn_config(i, ddr, popts, dimm_params);
+			set_csn_config(dimm_number, i, ddr, popts, dimm_params);
 			continue;
 		}
 		if (dimm_params[dimm_number].n_ranks == 0) {
 			debug("Skipping setup of CS%u "
-				"because n_ranks on DIMM %u is 0\n", i, i/2);
+				"because n_ranks on DIMM %u is 0\n", i, dimm_number);
 			continue;
 		}
 		if (popts->memctl_interleaving && popts->ba_intlv_ctl) {
@@ -1364,7 +1388,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 			);
 
 		debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds);
-		set_csn_config(i, ddr, popts, dimm_params);
+		set_csn_config(dimm_number, i, ddr, popts, dimm_params);
 		set_csn_config_2(i, ddr);
 	}
 
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 e888e3e..ce6c148 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
@@ -118,6 +118,18 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
 			temp1++;
 			continue;
 		}
+		if (dimm_params[i].n_ranks == 4 && i != 0) {
+			printf("Found Quad-rank DIMM in wrong bank, ignored."
+				" Software may not run as expected.\n");
+			temp1++;
+			continue;
+		}
+		if (dimm_params[i].n_ranks == 4 && \
+		  CONFIG_CHIP_SELECTS_PER_CTRL/CONFIG_DIMM_SLOTS_PER_CTLR < 4) {
+			printf("Found Quad-rank DIMM, not able to support.");
+			temp1++;
+			continue;
+		}
 
 		/*
 		 * Find minimum tCKmax_ps to find fastest slow speed,
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index ebbdb69..1d5f3e2 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -274,14 +274,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 		switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
 		case FSL_DDR_CS0_CS1_CS2_CS3:
 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
-			if (pdimm[0].n_ranks != 4) {
+			if (pdimm[0].n_ranks < 4) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for "
 					"CS0+CS1+CS2+CS3 on controller %d, "
 					"force non-interleaving!\n", ctrl_num);
 			}
 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
-			if ((pdimm[0].n_ranks != 2) && (pdimm[1].n_ranks != 2)) {
+			if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for "
 					"CS0+CS1+CS2+CS3 on controller %d, "
@@ -296,7 +296,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 #endif
 			break;
 		case FSL_DDR_CS0_CS1:
-			if (pdimm[0].n_ranks != 2) {
+			if (pdimm[0].n_ranks < 2) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for "
 					"CS0+CS1 on controller %d, "
@@ -305,13 +305,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 			break;
 		case FSL_DDR_CS2_CS3:
 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
-			if (pdimm[0].n_ranks != 4) {
+			if (pdimm[0].n_ranks < 4) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for CS2+CS3 "
 					"on controller %d, force non-interleaving!\n", ctrl_num);
 			}
 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
-			if (pdimm[1].n_ranks != 2) {
+			if (pdimm[1].n_ranks < 2) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(chip-select) for CS2+CS3 "
 					"on controller %d, force non-interleaving!\n", ctrl_num);
@@ -320,14 +320,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 			break;
 		case FSL_DDR_CS0_CS1_AND_CS2_CS3:
 #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
-			if (pdimm[0].n_ranks != 4) {
+			if (pdimm[0].n_ranks < 4) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(CS) for CS0+CS1 and "
 					"CS2+CS3 on controller %d, "
 					"force non-interleaving!\n", ctrl_num);
 			}
 #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
-			if ((pdimm[0].n_ranks != 2)||(pdimm[1].n_ranks != 2)) {
+			if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
 				popts->ba_intlv_ctl = 0;
 				printf("Not enough bank(CS) for CS0+CS1 and "
 					"CS2+CS3 on controller %d, "
@@ -341,6 +341,9 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
 		}
 	}
 
+	if (pdimm[0].n_ranks == 4)
+		popts->quad_rank_present = 1;
+
 	fsl_ddr_board_options(popts, pdimm, ctrl_num);
 
 	return 0;
diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h
index 02920db..431327e 100644
--- a/arch/powerpc/include/asm/fsl_ddr_sdram.h
+++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h
@@ -172,6 +172,7 @@ typedef struct memctl_options_s {
 	unsigned int OTF_burst_chop_en;
 	/* mirrior DIMMs for DDR3 */
 	unsigned int mirrored_dimm;
+	unsigned int quad_rank_present;
 
 	/* Global Timing Parameters */
 	unsigned int cas_latency_override;
-- 
1.6.0.6

  reply	other threads:[~2010-07-14 15:14 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-14 15:14 [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala
2010-07-14 15:14 ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
2010-07-14 15:14   ` Kumar Gala [this message]
2010-07-14 15:14     ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
2010-07-14 15:14       ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
2010-07-14 15:15         ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
2010-07-14 15:15           ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
2010-07-14 15:15             ` [U-Boot] [PATCH 8/8] powerpc/85xx: Add memory test feature for mpc85xx Kumar Gala
2010-07-14 20:16               ` Wolfgang Denk
2010-07-14 22:13                 ` Timur Tabi
2010-07-15  9:07                   ` Wolfgang Denk
2010-07-28 21:06                     ` York Sun
2010-07-28 21:50                       ` Wolfgang Denk
2010-07-26 18:16             ` [U-Boot] [PATCH 7/8] powerpc/p2020ds: Integrated with P2020DS DDR change and enabled hwconfig Kumar Gala
2010-07-26 18:15           ` [U-Boot] [PATCH 6/8] powerpc/8xxx: Improvement to DDR parameters Kumar Gala
2010-07-26 18:15         ` [U-Boot] [PATCH 5/8] powerpc/8xxx: Enable DDR3 RDIMM support Kumar Gala
2010-07-26 18:15       ` [U-Boot] [PATCH 4/8] powerpc/8xxx: Enabled address hashing for 85xx Kumar Gala
2010-07-26 18:15     ` [U-Boot] [PATCH 3/8] powerpc/8xxx: Enable quad-rank DIMMs Kumar Gala
2010-07-26 18:15   ` [U-Boot] [PATCH 2/8] powerpc/8xxx: Fix bug in memctrl interleaving & bank interleaving on cs0~cs4 Kumar Gala
2010-07-26 18:15 ` [U-Boot] [PATCH 1/8] powerpc/8xxx: Enabled hwconfig for memory interleaving Kumar Gala

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1279120502-6289-3-git-send-email-galak@kernel.crashing.org \
    --to=galak@kernel.crashing.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox