[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