summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Redfearn <matt.redfearn@imgtec.com>2015-08-17 17:12:39 +0300
committerMatt Redfearn <matt.redfearn@imgtec.com>2015-08-17 17:37:52 +0300
commit21dc18dbc4347d730eb965580bf74663230cff04 (patch)
tree51d34399aff6816680715c2a234c85197413621f
parent6fa087dad330e2ea1ccc1fa4527b3f2d99c6348d (diff)
downloadCI20_u-boot-21dc18dbc4347d730eb965580bf74663230cff04.tar.xz
jz4780: Select RAM device and apply settings from structure
Replace calculation of DDR parameters from header files with the pre-determined register values in the configuration structure. This is not as portable because the settings must be determined and hard-coded, however, it was necessary to allow selection of different RAM devices at runtime, and free's up some storage for additional device parameters if they become necessary. Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
-rw-r--r--arch/mips/cpu/xburst/jz4780/sdram.c288
1 files changed, 62 insertions, 226 deletions
diff --git a/arch/mips/cpu/xburst/jz4780/sdram.c b/arch/mips/cpu/xburst/jz4780/sdram.c
index 309b25142..56401dbe7 100644
--- a/arch/mips/cpu/xburst/jz4780/sdram.c
+++ b/arch/mips/cpu/xburst/jz4780/sdram.c
@@ -29,7 +29,7 @@
#ifdef __CONFIG_CI20_H__
/* Configured for Ci20 - we can get the board revision from here */
-extern int ci20_revision;
+extern int ci20_revision(void);
#endif /* ci20 */
#ifdef CONFIG_SYS_DDR3_H5TQ2G83CFR
@@ -39,7 +39,7 @@ extern int ci20_revision;
#include "sdram/K4B2G0846Q.h"
#endif
-static uint32_t get_mem_clk(void)
+static const uint32_t get_mem_clk(void)
{
uint32_t mpll_out;
mpll_out = (uint64_t)CONFIG_SYS_EXTAL * JZ4780_MPLL_M / (JZ4780_MPLL_N * JZ4780_MPLL_OD);
@@ -95,83 +95,25 @@ static void ddr_cfg_init(void)
#define DDRP_PTR2_DINIT2_DDR3 200 * 1000 // 200us
#define DDRP_PTR2_DINIT3_DDR3 512 // 512 tck
-static void ddr_phy_init(unsigned long ps, unsigned int dtpr0_reg)
+static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
{
register unsigned int tmp;
- unsigned int ptr0_reg = 0, ptr1_reg = 0, ptr2_reg = 0, dtpr1_reg = 0, dtpr2_reg = 0;
- unsigned int count = 0, dinit1 = 0, i;
+ unsigned int count = 0, i;
writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), DDRP_DCR);
- tmp = DIV_ROUND_UP(DDR_tWR * 1000, ps);
- if (tmp < 5)
- tmp = 5;
- if (tmp > 12)
- tmp = 12;
- if (tmp <= 8)
- tmp -= 4;
- else
- tmp = (tmp + 1) / 2;
-
- /* BL 8 = 0, 0x410 */
- writel(tmp << DDR3_MR0_WR_BIT | (DDR_CL - 4) << 4 | ((8 - DDR_BL) / 2), DDRP_MR0);
-#ifdef SDRAM_DISABLE_DLL
- writel(DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE, DDRP_MR1);
-#else
- writel(DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS, DDRP_MR1);
-#endif
+ writel(ddr_config->mr0, DDRP_MR0);
+ writel(ddr_config->mr1, DDRP_MR1);
writel(0, DDRP_ODTCR);
- writel((DDR_tCWL - 5) << DDR3_MR2_CWL_BIT, DDRP_MR2);
-
- /* DLL Soft Rest time */
- ptr0_reg |= min(DIV_ROUND_UP(DDRP_PTR0_tDLLSRST * 1000, ps), 63);
- /* DLL Lock time */
- ptr0_reg |= min(DIV_ROUND_UP(DDRP_tDLLLOCK, ps), 0xfff) << 6;
- ptr0_reg |= DDRP_PTR0_ITMSRST_8 << 18;
- writel(ptr0_reg, DDRP_PTR0);
-
- ptr1_reg |= min(DIV_ROUND_UP(DDRP_PTR1_DINIT0_DDR3 * 1000, ps), 0x7ffff);
- if (((DDR_tRFC + 10) * 1000) > (5 * ps)) //ddr3 only
- dinit1 = (DDR_tRFC + 10) * 1000;
- else
- dinit1 = 5 * ps;
- ptr1_reg |= min(DIV_ROUND_UP(dinit1, ps), 0xff) << 19;
- writel(ptr1_reg, DDRP_PTR1);
-
- ptr2_reg |= min(DIV_ROUND_UP(DDRP_PTR2_DINIT2_DDR3 * 1000, ps), 0x1ffff);
- ptr2_reg |= min(DDRP_PTR2_DINIT3_DDR3, 0x3ff) << 17;
- writel(ptr2_reg, DDRP_PTR2);
-
- dtpr0_reg |= (DDR_tMRD - 4); // valid values: 4 - 7
- if (DDR_tCCD > 4)
- dtpr0_reg |= 1 << 31;
- writel(dtpr0_reg, DDRP_DTPR0);
-
- dtpr1_reg |= min(max(DIV_ROUND_UP(DDR_tFAW * 1000, ps), 2), 31) << 3;
- dtpr1_reg |= min(max(DIV_ROUND_UP(DDR_tRFC * 1000, ps), 1), 255) << 16;
- dtpr1_reg |= min(DIV_ROUND_UP(DDR_tMOD * 1000, ps) - 12, 3) << 9;
- dtpr1_reg |= (1 << 11); /* ODT may not be turned on until one clock after the read post-amble */
- writel(dtpr1_reg, DDRP_DTPR1);
-
- tmp = (DDR_tXS > DDR_tXSDLL) ? DDR_tXS : DDR_tXSDLL; //only ddr3
- tmp = DIV_ROUND_UP(tmp * 1000, ps);
- if (tmp < 2) tmp = 2;
- if (tmp > 1023) tmp = 1023;
- dtpr2_reg |= tmp;
- tmp = (DDR_tXP > DDR_tXPDLL) ? DDR_tXP : DDR_tXPDLL;
- tmp = DIV_ROUND_UP(tmp * 1000, ps);
- if (tmp < 2) tmp = 2;
- if (tmp > 31) tmp = 31;
- dtpr2_reg |= tmp << 10;
- tmp = DDR_tCKE;
- if (tmp < 2) tmp = 2;
- if (tmp > 15) tmp = 15;
- dtpr2_reg |= tmp << 15;
- tmp = DDR_tDLLLOCK;
- if (tmp < 2) tmp = 2;
- if (tmp > 1023) tmp = 1023;
- dtpr2_reg |= tmp << 19;
- writel(dtpr2_reg, DDRP_DTPR2);
+ writel(0, DDRP_MR2);
+
+ writel(ddr_config->ptr0, DDRP_PTR0);
+ writel(ddr_config->ptr1, DDRP_PTR1);
+ writel(ddr_config->ptr2, DDRP_PTR2);
+
+ writel(ddr_config->dtpr0, DDRP_DTPR0);
+ writel(ddr_config->dtpr1, DDRP_DTPR1);
+ writel(ddr_config->dtpr2, DDRP_DTPR2);
writel(DDRP_PGCR_DQSCFG |
7 << DDRP_PGCR_CKEN_BIT |
@@ -190,19 +132,19 @@ static void ddr_phy_init(unsigned long ps, unsigned int dtpr0_reg)
hang();
}
- // DQS extension and early set to 1
- tmp = readl(DDRP_DSGCR);
- tmp &= ~(0x7E << 4);
- tmp |= 0x12 << 4;
- writel(tmp, DDRP_DSGCR);
+ // DQS extension and early set to 1
+ tmp = readl(DDRP_DSGCR);
+ tmp &= ~(0x7E << 4);
+ tmp |= 0x12 << 4;
+ writel(tmp, DDRP_DSGCR);
- // 500 pull up and 500 pull down
- tmp = readl(DDRP_DXCCR);
- tmp &= ~(0xFF << 4);
- tmp |= 0xC4 << 4;
- writel(tmp, DDRP_DXCCR);
+ // 500 pull up and 500 pull down
+ tmp = readl(DDRP_DXCCR);
+ tmp &= ~(0xFF << 4);
+ tmp |= 0xC4 << 4;
+ writel(tmp, DDRP_DXCCR);
- // Initialise phy
+ // Initialise phy
writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST, DDRP_PIR);
count = 0;
@@ -232,7 +174,6 @@ static void ddr_phy_init(unsigned long ps, unsigned int dtpr0_reg)
DDRP_ZQXCR_PULLDOWN_IMPE_BIT;
tmp |= DDRP_ZQXCR_ZDEN;
writel(tmp, DDRP_ZQXCR0(0));
-
}
#define BIT(bit) ((bit % 4) * 8)
@@ -277,20 +218,46 @@ static void mem_remap(void)
void sdram_init(void)
{
+ int board_revision;
uint32_t mem_clk, ps, tmp;
uint32_t ddrc_timing1 = 0, ddrc_timing2 = 0, ddrc_timing3 = 0;
uint32_t ddrc_timing4 = 0, ddrc_timing5 = 0, ddrc_timing6 = 0;
uint32_t ddrc_refcnt = 0;
- uint32_t ddrp_dtpr0 = 0;
uint32_t mem_base0, mem_base1;
uint32_t mem_mask0, mem_mask1;
uint32_t mem_size0, mem_size1;
+ const struct jz4780_ddr_config *ddr_config;
+
+ board_revision = ci20_revision();
+
+ if (board_revision == 2)
+#ifdef CONFIG_SYS_DDR3_K4B2G0846Q
+#if CONFIG_SYS_CPU_SPEED == 1200000000 && CONFIG_SYS_EXTAL == 48000000
+ ddr_config = &K4B2G0846Q_48_config;
+#else
+#error No DDR configuration for CPU speed
+#endif
+#else
+#error K4B2G0846Q support disabled
+#endif
+ else /* Fall back to H5TQ2G83CFR RAM */
+#ifdef CONFIG_SYS_DDR3_H5TQ2G83CFR
+#if CONFIG_SYS_CPU_SPEED == 1200000000 && CONFIG_SYS_EXTAL == 48000000
+ ddr_config = &H5TQ2G83CFR_48_config;
+#else
+#error No DDR configuration for CPU speed
+#endif
+#else
+#error H5TQ2G83CFR support disabled
+#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
- puts("SDRAM " SDRAM_PART_NAME " initialization...");
+ puts("SDRAM ");
+ puts(ddr_config->name);
+ puts(" initialization...\n");
#endif
- /* ??? */
+ /* Reset DLL in DDR PHY */
writel(0x3, 0xb00000d0);
udelay(400000);
writel(0x1, 0xb00000d0);
@@ -302,143 +269,12 @@ void sdram_init(void)
mem_clk = get_mem_clk();
ps = 1000000000 / (mem_clk / 1000); /* ns per tck ns <= real value , ns * 1000*/
- /* READ to PRECHARGE command period. */
- tmp = DIV_ROUND_UP(DDR_tRTP * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 6) tmp = 6;
- ddrc_timing1 |= (tmp << DDRC_TIMING1_TRTP_BIT);
- if (tmp < 2) tmp = 2;
- ddrp_dtpr0 |= tmp << 2;
-
- tmp = DIV_ROUND_UP(DDR_tWTR * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 6) tmp = 6;
- ddrc_timing1 |= ((DDR_tWL + DDR_BL / 2 + tmp) << DDRC_TIMING1_TWTR_BIT);
- ddrp_dtpr0 |= tmp << 5;
-
- /* WRITE Recovery Time defined by register MR of DDR3 memory */
- tmp = DIV_ROUND_UP(DDR_tWR * 1000, ps);
- if (tmp < 5) tmp = 5;
- if (tmp > 12) tmp = 12;
- ddrc_timing1 |= (tmp << DDRC_TIMING1_TWR_BIT);
- /* Write latency: dif ddr dif tWL, unit - tCK*/
- tmp = DDR_tWL;
- if (tmp < 1) tmp = 1;
- if (tmp > 63) tmp = 63;
- ddrc_timing1 |= (tmp << DDRC_TIMING1_TWL_BIT);
-
- /* CAS to CAS command delay , unit - tCK*/
- tmp = DDR_tCCD;
- if (tmp < 1) tmp = 1;
- if (tmp > 63) tmp = 63;
- ddrc_timing2 |= (tmp << DDRC_TIMING2_TCCD_BIT);
-
- /* ACTIVE to PRECHARGE command period */
- tmp = DIV_ROUND_UP(DDR_tRAS * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 31) tmp = 31;
- ddrc_timing2 |= (tmp << DDRC_TIMING2_TRAS_BIT);
- if (tmp < 2) tmp = 2;
- ddrp_dtpr0 |= tmp << 16;
-
- /* ACTIVE to READ or WRITE command period. */
- tmp = DIV_ROUND_UP(DDR_tRCD * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 11) tmp = 11;
- ddrc_timing2 |= (tmp << DDRC_TIMING2_TRCD_BIT);
- if (tmp < 2) tmp = 2;
- ddrp_dtpr0 |= tmp << 12;
-
- /* Read latency , unit tCK*/
- tmp = DDR_tRL;
- if (tmp < 1) tmp = 1;
- if (tmp > 63) tmp = 63;
- ddrc_timing2 |= (tmp << DDRC_TIMING2_TRL_BIT);
-
- ddrc_timing3 |= (4 << DDRC_TIMING3_ONUM);
-
- tmp = DIV_ROUND_UP(DDR_tCKSRE * 1000, ps) / 8;
- if (tmp < 1) tmp = 1;
- if (tmp > 7) tmp = 7;
- /*
- * Set DDR_tCKSRE to max to ensafe suspend & resume
- */
- tmp = 7;
- ddrc_timing3 |= (tmp << DDRC_TIMING3_TCKSRE_BIT);
-
- /* PRECHARGE command period. */
- tmp = DIV_ROUND_UP(DDR_tRP * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 11) tmp = 11;
- ddrc_timing3 |= (tmp << DDRC_TIMING3_TRP_BIT);
- if (tmp < 2) tmp = 2;
- ddrp_dtpr0 |= tmp << 8;
-
- /* ACTIVE bank A to ACTIVE bank B command period. */
- tmp = DIV_ROUND_UP(DDR_tRRD * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 8) tmp = 8;
- ddrc_timing3 |= (tmp << DDRC_TIMING3_TRRD_BIT);
- ddrp_dtpr0 |= tmp << 21;
-
- /* ACTIVE to ACTIVE command period. */
- tmp = DIV_ROUND_UP(DDR_tRC * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 42) tmp = 42;
- ddrc_timing3 |= (tmp << DDRC_TIMING3_TRC_BIT);
- if (tmp < 2) tmp = 2;
- ddrp_dtpr0 |= tmp << 25;
-
- /* AUTO-REFRESH command period. */
- tmp = DIV_ROUND_UP(DDR_tRFC * 1000, ps) - 1;
- tmp = tmp / 2;
- if (tmp < 1) tmp = 1;
- if (tmp > 63) tmp = 63;
- ddrc_timing4 |= (tmp << DDRC_TIMING4_TRFC_BIT);
-
- /* RWCOV: */
- tmp = 1;
- ddrc_timing4 |= (tmp << DDRC_TIMING4_TRWCOV_BIT);
-
- tmp = DIV_ROUND_UP(DDR_tCKE * 1000, ps);
- ddrc_timing4 |= (tmp << DDRC_TIMING4_TCKE_BIT);
-
- /* Minimum Self-Refresh / Deep-Power-Down time */
- tmp = DDR_tMINSR;
- if (tmp < 9) tmp = 9; //unit: tCK
- if (tmp > 129) tmp = 129;
- tmp = ((tmp - 1) % 8) ? ((tmp - 1) / 8) : ((tmp - 1) / 8 - 1);
- ddrc_timing4 |= (tmp << DDRC_TIMING4_TMINSR_BIT);
- ddrc_timing4 |= (DDR_tXP << DDRC_TIMING4_TXP_BIT) | (DDR_tMRD - 1);
-
- /* RTW: read to write*/
- tmp = DDR_tRTW;
- if (tmp < 1) tmp = 1;
- if (tmp > 63) tmp = 63;
- ddrc_timing5 |= (tmp << DDRC_TIMING5_TRTW_BIT);
-
- /* trdlat: */
- tmp = DDR_tRDLAT;
- if (tmp > 63) tmp = 63;
- ddrc_timing5 |= (tmp << DDRC_TIMING5_TRDLAT_BIT);
-
- /* twdlat: */
- tmp = DDR_tWDLAT;
- if (tmp > 63) tmp = 63;
- ddrc_timing5 |= (tmp << DDRC_TIMING5_TWDLAT_BIT);
-
- tmp = DDR_tXSRD / 4;
- if (tmp < 1) tmp = 1;
- if (tmp > 255) tmp = 255;
- ddrc_timing6 |= (tmp << DDRC_TIMING6_TXSRD_BIT);
-
- /* FAW: Four bank activate period - tCK */
- tmp = DIV_ROUND_UP(DDR_tFAW * 1000, ps);
- if (tmp < 1) tmp = 1;
- if (tmp > 31) tmp = 31;
- ddrc_timing6 |= (tmp << DDRC_TIMING6_TFAW_BIT);
- ddrc_timing6 |= (2 << DDRC_TIMING6_TCFGW_BIT);
- ddrc_timing6 |= (2 << DDRC_TIMING6_TCFGR_BIT);
+ ddrc_timing1 = ddr_config->timing1;
+ ddrc_timing2 = ddr_config->timing2;
+ ddrc_timing3 = ddr_config->timing3;
+ ddrc_timing4 = ddr_config->timing4;
+ ddrc_timing5 = ddr_config->timing5;
+ ddrc_timing6 = ddr_config->timing6;
ddrc_refcnt = DDR_CLK_DIV << 1 | DDRC_REFCNT_REF_EN;
tmp = (1000000000 % mem_clk == 0) ? (1000000000 / mem_clk) : (1000000000 / mem_clk + 1);
@@ -454,7 +290,7 @@ void sdram_init(void)
writel(0x0, DDRC_CTRL);
writel(0x150000, DDRP_DTAR);
- ddr_phy_init(ps, ddrp_dtpr0);
+ ddr_phy_init(ddr_config);
writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, DDRC_CTRL);
writel(0x0, DDRC_CTRL);