[U-Boot] [PATCH 062/172] ddr: altera: Implement universal scc_mgr_set_all_ranks()

Marek Vasut marex at denx.de
Mon Jul 27 22:50:25 CEST 2015


Implement universal scc_mgr_set_all_ranks() function and convert
various ad-hoc implementations of similar functionality to use
this single function. Document the function in kerneldoc.

Signed-off-by: Marek Vasut <marex at denx.de>
---
 drivers/ddr/altera/sequencer.c | 95 +++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 53 deletions(-)

diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c
index 1718ebf..df78146 100644
--- a/drivers/ddr/altera/sequencer.c
+++ b/drivers/ddr/altera/sequencer.c
@@ -361,77 +361,64 @@ static void scc_mgr_load_dm(uint32_t dm)
 	writel(dm, &sdr_scc_mgr->dm_ena);
 }
 
-static void scc_mgr_set_dqs_en_phase_all_ranks(uint32_t read_group,
-					       uint32_t phase)
+/**
+ * scc_mgr_set_all_ranks() - Set SCC Manager register for all ranks
+ * @off:	Base offset in SCC Manager space
+ * @grp:	Read/Write group
+ * @val:	Value to be set
+ * @update:	If non-zero, trigger SCC Manager update for all ranks
+ *
+ * This function sets the SCC Manager (Scan Chain Control Manager) register
+ * and optionally triggers the SCC update for all ranks.
+ */
+static void scc_mgr_set_all_ranks(const u32 off, const u32 grp, const u32 val,
+				  const int update)
 {
-	uint32_t r;
+	u32 r;
 
 	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
-		scc_mgr_set_dqs_en_phase(read_group, phase);
-
-		/*
-		 * USER although the h/w doesn't support different phases per
-		 * shadow register, for simplicity our scc manager modeling
-		 * keeps different phase settings per shadow reg, and it's
-		 * important for us to keep them in sync to match h/w.
-		 * for efficiency, the scan chain update should occur only
-		 * once to sr0.
-		 */
+		scc_mgr_set(off, grp, val);
 
-		if (r == 0) {
-			writel(read_group, &sdr_scc_mgr->dqs_ena);
+		if (update || (r == 0)) {
+			writel(grp, &sdr_scc_mgr->dqs_ena);
 			writel(0, &sdr_scc_mgr->update);
 		}
 	}
 }
 
+static void scc_mgr_set_dqs_en_phase_all_ranks(u32 read_group, u32 phase)
+{
+	/*
+	 * USER although the h/w doesn't support different phases per
+	 * shadow register, for simplicity our scc manager modeling
+	 * keeps different phase settings per shadow reg, and it's
+	 * important for us to keep them in sync to match h/w.
+	 * for efficiency, the scan chain update should occur only
+	 * once to sr0.
+	 */
+	scc_mgr_set_all_ranks(SCC_MGR_DQS_EN_PHASE_OFFSET,
+			      read_group, phase, 0);
+}
+
 static void scc_mgr_set_dqdqs_output_phase_all_ranks(uint32_t write_group,
 						     uint32_t phase)
 {
-	uint32_t r;
-
-	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS;
-	     r += NUM_RANKS_PER_SHADOW_REG) {
-		scc_mgr_set_dqdqs_output_phase(write_group, phase);
-
-		/*
-		 * USER although the h/w doesn't support different phases per
-		 * shadow register, for simplicity our scc manager modeling
-		 * keeps different phase settings per shadow reg, and it's
-		 * important for us to keep them in sync to match h/w.
-		 * for efficiency, the scan chain update should occur only
-		 * once to sr0.
-		 */
-
-		if (r == 0) {
-			writel(write_group, &sdr_scc_mgr->dqs_ena);
-			writel(0, &sdr_scc_mgr->update);
-		}
-	}
+	/*
+	 * USER although the h/w doesn't support different phases per
+	 * shadow register, for simplicity our scc manager modeling
+	 * keeps different phase settings per shadow reg, and it's
+	 * important for us to keep them in sync to match h/w.
+	 * for efficiency, the scan chain update should occur only
+	 * once to sr0.
+	 */
+	scc_mgr_set_all_ranks(SCC_MGR_DQDQS_OUT_PHASE_OFFSET,
+			      write_group, phase, 0);
 }
 
 static void scc_mgr_set_dqs_en_delay_all_ranks(uint32_t read_group,
 					       uint32_t delay)
 {
-	uint32_t r;
-
-	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS;
-		r += NUM_RANKS_PER_SHADOW_REG) {
-		scc_mgr_set_dqs_en_delay(read_group, delay);
-
-		/*
-		 * In shadow register mode, the T11 settings are stored in
-		 * registers in the core, which are updated by the DQS_ENA
-		 * signals. Not issuing the SCC_MGR_UPD command allows us to
-		 * save lots of rank switching overhead, by calling
-		 * select_shadow_regs_for_update with update_scan_chains
-		 * set to 0.
-		 */
-
-		writel(read_group, &sdr_scc_mgr->dqs_ena);
-		writel(0, &sdr_scc_mgr->update);
-	}
 	/*
 	 * In shadow register mode, the T11 settings are stored in
 	 * registers in the core, which are updated by the DQS_ENA
@@ -440,6 +427,8 @@ static void scc_mgr_set_dqs_en_delay_all_ranks(uint32_t read_group,
 	 * select_shadow_regs_for_update with update_scan_chains
 	 * set to 0.
 	 */
+	scc_mgr_set_all_ranks(SCC_MGR_DQS_EN_DELAY_OFFSET,
+			      read_group, delay, 1);
 	writel(0, &sdr_scc_mgr->update);
 }
 
-- 
2.1.4



More information about the U-Boot mailing list