[U-Boot] [PATCH RFC 4/7] MIPS: AR7240: DRAM Initialization file

Nikolaos Pasaloukos Nikolaos.Pasaloukos at imgtec.com
Fri Nov 29 10:48:05 CET 2013


Add support for DRAM initialization on ar7240 and similar SoC

Signed-off-by: Nikolaos Pasaloukos <Nikolaos.Pasaloukos at imgtec.com>
Cc: Daniel Schwierzeck <daniel.schwierzeck at gmail.com>
---
 arch/mips/cpu/mips32/ar7240/Makefile      |   7 +
 arch/mips/cpu/mips32/ar7240/ar7240_dram.c | 298 ++++++++++++++++++++++++++++++
 2 files changed, 305 insertions(+)
 create mode 100644 arch/mips/cpu/mips32/ar7240/Makefile
 create mode 100644 arch/mips/cpu/mips32/ar7240/ar7240_dram.c

diff --git a/arch/mips/cpu/mips32/ar7240/Makefile b/arch/mips/cpu/mips32/ar7240/Makefile
new file mode 100644
index 0000000..75fee0a
--- /dev/null
+++ b/arch/mips/cpu/mips32/ar7240/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2013 Imagination Technologies
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y = ar7240_dram.o
diff --git a/arch/mips/cpu/mips32/ar7240/ar7240_dram.c b/arch/mips/cpu/mips32/ar7240/ar7240_dram.c
new file mode 100644
index 0000000..575882e
--- /dev/null
+++ b/arch/mips/cpu/mips32/ar7240/ar7240_dram.c
@@ -0,0 +1,298 @@
+/*
+ * Memory controller config:
+ * Assumes that the caches are initialized.
+ *
+ * 0) Figure out the Tap controller settings.
+ * 1) Figure out whether the interface is 16bit or 32bit.
+ * 2) Size the DRAM
+ *
+ *  0) Tap controller settings
+ *  --------------------------
+ * The Table below provides all possible values of TAP controllers. We need to
+ * find the extreme left and extreme right of the spectrum (of max_udelay and
+ * min_udelay). We then program the TAP to be in the middle.
+ * Note for this we would need to be able to read and write memory. So,
+ * initially we assume that a 16bit interface, which will always work unless
+ * there is exactly _1_ 32 bit part...for now we assume this is not the case.
+ *
+ * The algo:
+ * 0) Program the controller in 16bit mode.
+ * 1) Start with the extreme left of the table
+ * 2) Write 0xa4, 0xb5, 0xc6, 0xd7 to 0, 2, 4, 6
+ * 3) Read 0 - this will fetch the entire cacheline.
+ * 4) If the value at address 4 is good, record this table entry, goto 6
+ * 5) Increment to get the next table entry. Goto 2.
+ * 6) Start with extreme right. Do the same as above.
+ *
+ * 1) 16bit or 32bit
+ * -----------------
+ *  31st bit of reg 0x1800_0000 will  determine the mode. By default,
+ *  controller is set to 32-bit mode. In 32 bit mode, full data bus DQ [31:0]
+ *  will be used to write 32 bit data. Suppose you have 16bit DDR memory
+ *  (it will have 16bit wide data bus). If you try to write 16 bit DDR in 32
+ *  bit mode, you are going to miss upper 16 bits of data. Reading to that
+ *  location will give you only lower 16 bits correctly, upper 16 bits will
+ *  have some junk value. E.g.,
+ *
+ *  write to 0x0000_0000 0x12345678
+ *  write to 0x0000_1000 0x00000000 (just to discharge DQ[31:16] )
+ *  read from 0x0000_0000
+ *  if u see something like 0x0000_5678 (or XXXX_5678 but not equal to
+ *  0x12345678) - its a 16 bit interface
+ *
+ *  2) Size the DRAM
+ *  -------------------
+ *  DDR wraps around. Write a pattern to 0x0000_0000. Write an address
+ *  pattern at 4M, 8M, 16M etc. and check when 0x0000_0000 gets overwritten.
+ *
+ *  Copyright (C) 2013 Imagination Technologies
+ *
+ *  Derived from works by OpenWRT
+ *
+ *  SPDX-License-Identifier:	GPL-2.0
+ */
+#include <common.h>
+#include <config.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/ar7240_addrspace.h>
+#include <asm/ar934x_reg_cfg.h>
+
+/*
+ * WASP BootStrap Register
+ */
+
+#define WASP_RAM_TYPE(a)			((a) & 0x3)
+
+#define CONFIG_934X_SDRAM_CONFIG_VAL		0x7fbe8cd0
+#define CONFIG_934X_SDRAM_MODE_VAL_INIT		0x133
+#define CONFIG_934X_SDRAM_MODE_VAL		0x33
+#define CONFIG_934X_SDRAM_CONFIG2_VAL		0x959f66a8
+#define CONFIG_934X_SDRAM_TAP_VAL		0x1f1f
+
+#define CONFIG_934X_DDR1_CONFIG_VAL		0x7fd48cd0
+#define CONFIG_934X_DDR1_MODE_VAL_INIT		0x133
+#define CONFIG_934X_DDR1_EXT_MODE_VAL		0x2
+#define CONFIG_934X_DDR1_MODE_VAL		0x33
+#define CONFIG_934X_DDR1_CONFIG2_VAL		0x99d0e6a8
+#define CONFIG_934X_DDR1_TAP_VAL		0x14
+
+#if (CONFIG_SYS_PLL_FREQ == CONFIG_PLL_500_500_250)
+#define CONFIG_934X_DDR2_CONFIG_VAL		0xcfbc8cd0
+#define CONFIG_934X_DDR2_MODE_VAL_INIT		0x143
+#define CONFIG_934X_DDR2_EXT_MODE_VAL		0x402
+#define CONFIG_934X_DDR2_MODE_VAL		0x43
+#define CONFIG_934X_DDR2_CONFIG2_VAL		0xa5d0e6a8
+#define CONFIG_934X_DDR2_EN_TWL_VAL		0x1659
+#define CONFIG_934X_DDR2_TAP_VAL		0
+#elif (CONFIG_SYS_PLL_FREQ == CONFIG_PLL_650_600_300) || \
+	(CONFIG_SYS_PLL_FREQ == CONFIG_PLL_600_600_300) || \
+	(CONFIG_SYS_PLL_FREQ == CONFIG_PLL_600_550_275) || \
+	(CONFIG_SYS_PLL_FREQ == CONFIG_PLL_600_575_287)
+
+#define CONFIG_934X_DDR2_CONFIG_VAL		0xcfd48cd0
+#define CONFIG_934X_DDR2_MODE_VAL_INIT		0x143
+#define CONFIG_934X_DDR2_EXT_MODE_VAL		0x402
+#define CONFIG_934X_DDR2_MODE_VAL		0x43
+#define CONFIG_934X_DDR2_CONFIG2_VAL		0xa1d0e6a8
+#define CONFIG_934X_DDR2_EN_TWL_VAL		0x1659
+#define CONFIG_934X_DDR2_TAP_VAL		0x5
+#else
+#define CONFIG_934X_DDR2_CONFIG_VAL		0xc7d48cd0
+#define CONFIG_934X_DDR2_MODE_VAL_INIT		0x133
+#define CONFIG_934X_DDR2_EXT_MODE_VAL_INIT	0x382
+#define CONFIG_934X_DDR2_EXT_MODE_VAL		0x402
+#define CONFIG_934X_DDR2_MODE_VAL		0x33
+#define CONFIG_934X_DDR2_CONFIG2_VAL		0x9dd0e6a8
+#define CONFIG_934X_DDR2_EN_TWL_VAL		0xe59
+#define CONFIG_934X_DDR2_TAP_VAL		0x10012
+#endif
+
+#define DRAM_TYPE_SDRAM				0
+#define DRAM_TYPE_DDR2				1
+#define DRAM_TYPE_DDR1				2
+
+#define FORCE_MRS_UPDATE			0x01
+#define FORCE_EMRS_UPDATE			0x02
+#define FORCE_AUTO_REFRESH			0x04
+#define FORCE_PRECHARGE_ALL			0x08
+#define FORCE_EMR2_UPDATE			0x10
+#define FORCE_EMR3_UPDATE			0x20
+
+#define dram_init_wait()			udelay(1000)
+#define dram_wait()				udelay(100)
+#define tap_wait()				udelay(10)
+
+/* ram type */
+int wasp_ddr_initial_config(uint32_t refresh)
+{
+	int		ddr_config, ddr_config2, ext_mod, mod_val,
+			mod_val_init, cycle_val, tap_val, type;
+	uint32_t	*pll = (unsigned *)PLL_CONFIG_VAL_F;
+
+	debug("Wasp 1.%d\n", ar_reg_rd(&ar7240_rst2->rev_id) & 0xf);
+
+	switch (WASP_RAM_TYPE(ar_reg_rd(&ar7240_rst2->bootstrap))) {
+	case 0:
+	case 1: /* SDRAM */
+		debug("Wasp sdram\n");
+		ddr_config	= CONFIG_934X_SDRAM_CONFIG_VAL;
+		ddr_config2	= CONFIG_934X_SDRAM_CONFIG2_VAL;
+		mod_val_init	= CONFIG_934X_SDRAM_MODE_VAL_INIT;
+		mod_val		= CONFIG_934X_SDRAM_MODE_VAL;
+		cycle_val	= CONFIG_SDRAM_RD_DATA_THIS_CYCLE_VAL;
+		tap_val		= CONFIG_934X_SDRAM_TAP_VAL;
+
+		ar_reg_wr(&ar7240_ddr_ctl->config, 0x13b);
+		dram_wait();
+
+		ar_reg_wr(&ar7240_ddr_ctl->debug_read_ctrl, 0x3000001f);
+		dram_wait();
+
+		type = DRAM_TYPE_SDRAM;
+
+		break;
+	case 2: /* DDR2 */
+		ddr_config	= CONFIG_934X_DDR2_CONFIG_VAL;
+		ddr_config2	= CONFIG_934X_DDR2_CONFIG2_VAL;
+		ext_mod		= CONFIG_934X_DDR2_EXT_MODE_VAL;
+		mod_val_init	= CONFIG_934X_DDR2_MODE_VAL_INIT;
+		mod_val		= CONFIG_934X_DDR2_MODE_VAL;
+		cycle_val	= CONFIG_DDR2_RD_DATA_THIS_CYCLE_VAL;
+		tap_val		= CONFIG_934X_DDR2_TAP_VAL;
+
+		ar_reg_wr(&ar7240_ddr2->config, CONFIG_934X_DDR2_EN_TWL_VAL);
+		dram_wait();
+		ar_reg_wr(&ar7240_ddr->ctrl, FORCE_EMR2_UPDATE);
+		tap_wait();
+		ar_reg_wr(&ar7240_ddr->ctrl, FORCE_EMR3_UPDATE);
+		tap_wait();
+		if (ar_reg_rd(&ar7240_rst2->rev_id) & 0xf) {
+			/* NAND Clear */
+			if (ar_reg_rd(&ar7240_rst2->bootstrap) &
+			    (1 << RST_BOOTSTRAP_DDR_WIDTH_LSB)) {
+				debug("Wasp DDR2 32bit init\n");
+				ar_reg_wr(&ar7240_ddr_ctl->config,
+					  DDR_CTL_CONFIG_DDR2_EN_SET(1));
+			} else {
+				debug("Wasp DDR2 16bit init\n");
+				ar_reg_rd_set(&ar7240_ddr_ctl->config,
+					      DDR_CTL_CONFIG_DDR2_EN_SET(1));
+			}
+		} else {
+#if DDR2_32BIT_SUPPORT
+			debug("DDR2 32bit init\n");
+			ar_reg_wr(&ar7240_ddr_ctl->config, 0);
+#else
+			debug("DDR2 16bit init\n");
+#endif
+		}
+		type = DRAM_TYPE_DDR2;
+
+		break;
+	case 3: /* DDR1 */
+		debug("Wasp DDR1 16bit init\n");
+		ddr_config	= CONFIG_934X_DDR1_CONFIG_VAL;
+		ddr_config2	= CONFIG_934X_DDR1_CONFIG2_VAL;
+		ext_mod		= CONFIG_934X_DDR1_EXT_MODE_VAL;
+		mod_val_init	= CONFIG_934X_DDR1_MODE_VAL_INIT;
+		mod_val		= CONFIG_934X_DDR1_MODE_VAL;
+		cycle_val	= CONFIG_DDR1_RD_DATA_THIS_CYCLE_VAL;
+		tap_val		= CONFIG_934X_DDR1_TAP_VAL;
+		type = DRAM_TYPE_DDR1;
+		break;
+	}
+	if (*pll == PLL_MAGIC) {
+		uint32_t cas = pll[5];
+		if (cas == 3 || cas == 4) {
+			cas = (cas * 2) + 2;
+			ddr_config &= ~(DDR_CONFIG_CAS_LATENCY_MSB_MASK |
+					DDR_CONFIG_CAS_LATENCY_MASK);
+			ddr_config |= DDR_CONFIG_CAS_LATENCY_SET(cas & 0x7) |
+				DDR_CONFIG_CAS_LATENCY_MSB_SET((cas >> 3) & 1);
+
+			cas = pll[5];
+
+			ddr_config2 &= ~DDR_CONFIG2_GATE_OPEN_LATENCY_MASK;
+			ddr_config2 |= DDR_CONFIG2_GATE_OPEN_LATENCY_SET(
+								 (2 * cas) + 1);
+
+			if (type == DRAM_TYPE_DDR2) {
+				uint32_t tmp;
+				tmp = ar_reg_rd(&ar7240_ddr2->config);
+				tmp &= ~DDR2_CONFIG_DDR2_TWL_MASK;
+				tmp |= DDR2_CONFIG_DDR2_TWL_SET(cas == 3 ? 3 :
+									   5);
+				ar_reg_wr(&ar7240_ddr2->config, tmp);
+			}
+
+			mod_val_init = (cas == 3) ?
+				       CONFIG_934X_DDR1_MODE_VAL_INIT :
+				       CONFIG_934X_DDR2_MODE_VAL_INIT;
+		}
+	}
+
+	ar_reg_wr(&ar7240_ddr->config, ddr_config);
+	dram_wait();
+	ar_reg_wr(&ar7240_ddr->config2, ddr_config2 | 0x80);
+	dram_wait();
+	ar_reg_wr(&ar7240_ddr->ctrl, FORCE_PRECHARGE_ALL);
+	tap_wait();
+
+	ar_reg_wr(&ar7240_ddr->mode, mod_val_init);
+	dram_init_wait();
+
+	ar_reg_wr(&ar7240_ddr->ctrl, FORCE_MRS_UPDATE);
+	tap_wait();
+
+	if (type == DRAM_TYPE_DDR2) {
+		ar_reg_wr(&ar7240_ddr->ext_mode,
+			  CONFIG_934X_DDR2_EXT_MODE_VAL_INIT);
+		dram_wait();
+		ar_reg_wr(&ar7240_ddr->ctrl, FORCE_EMRS_UPDATE);
+		tap_wait();
+	}
+	if (type != DRAM_TYPE_SDRAM)
+		ar_reg_wr(&ar7240_ddr->ext_mode, ext_mod);
+
+	dram_wait();
+	ar_reg_wr(&ar7240_ddr->ctrl, FORCE_EMRS_UPDATE);
+	tap_wait();
+	ar_reg_wr(&ar7240_ddr->ctrl, FORCE_PRECHARGE_ALL);
+	tap_wait();
+	ar_reg_wr(&ar7240_ddr->mode, mod_val);
+	dram_wait();
+	ar_reg_wr(&ar7240_ddr->ctrl, FORCE_MRS_UPDATE);
+	tap_wait();
+	ar_reg_wr(&ar7240_ddr->refresh, refresh);
+	dram_wait();
+
+	ar_reg_wr(&ar7240_ddr->tap_ctrl0, tap_val);
+	ar_reg_wr(&ar7240_ddr->tap_ctrl1, tap_val);
+
+	if (ar_reg_rd(&ar7240_rst2->rev_id) & 0xf) {
+		/* NAND Clear */
+		if ((ar_reg_rd(&ar7240_rst2->bootstrap) & (1 << 3)) && type) {
+			ar_reg_wr(&ar7240_ddr->tap_ctrl2, tap_val);
+			ar_reg_wr(&ar7240_ddr->tap_ctrl3, tap_val);
+		}
+	} else {
+#if DDR2_32BIT_SUPPORT
+		if (type != DRAM_TYPE_SDRAM) {
+			ar_reg_wr(&ar7240_ddr->tap_ctrl2, tap_val);
+			ar_reg_wr(&ar7240_ddr->tap_ctrl3, tap_val);
+		}
+#endif
+	}
+
+	ar_reg_wr(&ar7240_ddr->rd_data_this_cycle, cycle_val);
+	dram_wait();
+#if ((CONFIG_SYS_PLL_FREQ == CONFIG_PLL_600_500_250) || \
+	(CONFIG_SYS_PLL_FREQ == CONFIG_PLL_500_500_250))
+	/* PMU2 ddr ldo tune */
+	/* Address differs in Qualcomm's Datasheet */
+	ar_reg_rd_set(AR7240_PMU2, PMU2_LDO_TUNE_SET(3));
+	dram_wait();
+#endif
+	return type;
+}
-- 
1.8.3.2




More information about the U-Boot mailing list