* [U-Boot] [PATCH 1/9] ram: rockchip: rename sdram driver files
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 2/9] ram: rockchip: add common sdram driver Kever Yang
` (8 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
sdram.h is more for rk3288, rename it to sdram_rk3288.h;
rename sdram_common.c in arch/arm/mach-rockchip to sdram.c;
clean the related file who has use the header file at the same time.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
arch/arm/include/asm/arch-rockchip/sdram.h | 223 +++++++++++-------
.../include/asm/arch-rockchip/sdram_common.h | 147 ------------
.../include/asm/arch-rockchip/sdram_rk3288.h | 102 ++++++++
arch/arm/mach-rockchip/Makefile | 2 +-
arch/arm/mach-rockchip/rk3036/rk3036.c | 2 +-
arch/arm/mach-rockchip/rk3288/rk3288.c | 2 +-
.../mach-rockchip/{sdram_common.c => sdram.c} | 2 +-
drivers/ram/rockchip/dmc-rk3368.c | 2 +-
drivers/ram/rockchip/sdram_debug.c | 2 +-
drivers/ram/rockchip/sdram_rk3128.c | 2 +-
drivers/ram/rockchip/sdram_rk3188.c | 2 +-
drivers/ram/rockchip/sdram_rk322x.c | 2 +-
drivers/ram/rockchip/sdram_rk3288.c | 2 +-
drivers/ram/rockchip/sdram_rk3328.c | 2 +-
drivers/ram/rockchip/sdram_rk3399.c | 2 +-
15 files changed, 248 insertions(+), 248 deletions(-)
delete mode 100644 arch/arm/include/asm/arch-rockchip/sdram_common.h
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3288.h
rename arch/arm/mach-rockchip/{sdram_common.c => sdram.c} (99%)
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index 9220763fa7..3866d0b4d4 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -1,102 +1,147 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright (c) 2015 Google, Inc
- *
- * Copyright 2014 Rockchip Inc.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
*/
-#ifndef _ASM_ARCH_RK3288_SDRAM_H__
-#define _ASM_ARCH_RK3288_SDRAM_H__
+#ifndef _ASM_ARCH_SDRAM_COMMON_H
+#define _ASM_ARCH_SDRAM_COMMON_H
-struct rk3288_sdram_channel {
- /*
- * bit width in address, eg:
- * 8 banks using 3 bit to address,
- * 2 cs using 1 bit to address.
- */
- u8 rank;
- u8 col;
- u8 bk;
- u8 bw;
- u8 dbw;
- u8 row_3_4;
- u8 cs0_row;
- u8 cs1_row;
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+enum {
+ DDR4 = 0,
+ DDR3 = 0x3,
+ LPDDR2 = 0x5,
+ LPDDR3 = 0x6,
+ LPDDR4 = 0x7,
+ UNUSED = 0xFF
+};
+
+struct sdram_cap_info {
+ unsigned int rank;
+ /* dram column number, 0 means this channel is invalid */
+ unsigned int col;
+ /* dram bank number, 3:8bank, 2:4bank */
+ unsigned int bk;
+ /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int bw;
+ /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int dbw;
/*
- * For of-platdata, which would otherwise convert this into two
- * byte-swapped integers. With a size of 9 bytes, this struct will
- * appear in of-platdata as a byte array.
- *
- * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
+ * row_3_4 = 1: 6Gb or 12Gb die
+ * row_3_4 = 0: normal die, power of 2
*/
- u8 dummy;
-#endif
+ unsigned int row_3_4;
+ unsigned int cs0_row;
+ unsigned int cs1_row;
+ unsigned int ddrconfig;
};
-struct rk3288_sdram_pctl_timing {
- u32 togcnt1u;
- u32 tinit;
- u32 trsth;
- u32 togcnt100n;
- u32 trefi;
- u32 tmrd;
- u32 trfc;
- u32 trp;
- u32 trtw;
- u32 tal;
- u32 tcl;
- u32 tcwl;
- u32 tras;
- u32 trc;
- u32 trcd;
- u32 trrd;
- u32 trtp;
- u32 twr;
- u32 twtr;
- u32 texsr;
- u32 txp;
- u32 txpdll;
- u32 tzqcs;
- u32 tzqcsi;
- u32 tdqs;
- u32 tcksre;
- u32 tcksrx;
- u32 tcke;
- u32 tmod;
- u32 trstl;
- u32 tzqcl;
- u32 tmrr;
- u32 tckesr;
- u32 tdpd;
+struct sdram_base_params {
+ unsigned int ddr_freq;
+ unsigned int dramtype;
+ unsigned int num_channels;
+ unsigned int stride;
+ unsigned int odt;
};
-check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
-struct rk3288_sdram_phy_timing {
- u32 dtpr0;
- u32 dtpr1;
- u32 dtpr2;
- u32 mr[4];
-};
+/*
+ * sys_reg bitfield struct
+ * [31] row_3_4_ch1
+ * [30] row_3_4_ch0
+ * [29:28] chinfo
+ * [27] rank_ch1
+ * [26:25] col_ch1
+ * [24] bk_ch1
+ * [23:22] cs0_row_ch1
+ * [21:20] cs1_row_ch1
+ * [19:18] bw_ch1
+ * [17:16] dbw_ch1;
+ * [15:13] ddrtype
+ * [12] channelnum
+ * [11] rank_ch0
+ * [10:9] col_ch0
+ * [8] bk_ch0
+ * [7:6] cs0_row_ch0
+ * [5:4] cs1_row_ch0
+ * [3:2] bw_ch0
+ * [1:0] dbw_ch0
+ */
+#define SYS_REG_DDRTYPE_SHIFT 13
+#define DDR_SYS_REG_VERSION 2
+#define SYS_REG_DDRTYPE_MASK 7
+#define SYS_REG_NUM_CH_SHIFT 12
+#define SYS_REG_NUM_CH_MASK 1
+#define SYS_REG_ROW_3_4_SHIFT(ch) (30 + (ch))
+#define SYS_REG_ROW_3_4_MASK 1
+#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
+#define SYS_REG_CHINFO_SHIFT(ch) (28 + (ch))
+#define SYS_REG_ENC_CHINFO(ch) (1 << SYS_REG_CHINFO_SHIFT(ch))
+#define SYS_REG_ENC_DDRTYPE(n) ((n) << SYS_REG_DDRTYPE_SHIFT)
+#define SYS_REG_ENC_NUM_CH(n) (((n) - SYS_REG_NUM_CH_MASK) << \
+ SYS_REG_NUM_CH_SHIFT)
+#define SYS_REG_RANK_SHIFT(ch) (11 + (ch) * 16)
+#define SYS_REG_RANK_MASK 1
+#define SYS_REG_ENC_RANK(n, ch) (((n) - SYS_REG_RANK_MASK) << \
+ SYS_REG_RANK_SHIFT(ch))
+#define SYS_REG_COL_SHIFT(ch) (9 + (ch) * 16)
+#define SYS_REG_COL_MASK 3
+#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << SYS_REG_COL_SHIFT(ch))
+#define SYS_REG_BK_SHIFT(ch) (8 + (ch) * 16)
+#define SYS_REG_BK_MASK 1
+#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) << \
+ SYS_REG_BK_SHIFT(ch))
+#define SYS_REG_CS0_ROW_SHIFT(ch) (6 + (ch) * 16)
+#define SYS_REG_CS0_ROW_MASK 3
+#define SYS_REG_CS1_ROW_SHIFT(ch) (4 + (ch) * 16)
+#define SYS_REG_CS1_ROW_MASK 3
+#define SYS_REG_BW_SHIFT(ch) (2 + (ch) * 16)
+#define SYS_REG_BW_MASK 3
+#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << SYS_REG_BW_SHIFT(ch))
+#define SYS_REG_DBW_SHIFT(ch) ((ch) * 16)
+#define SYS_REG_DBW_MASK 3
+#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << SYS_REG_DBW_SHIFT(ch))
-struct rk3288_base_params {
- u32 noc_timing;
- u32 noc_activate;
- u32 ddrconfig;
- u32 ddr_freq;
- u32 dramtype;
- /*
- * DDR Stride is address mapping for DRAM space
- * Stride Ch 0 range Ch1 range Total
- * 0x00 0-256MB 256MB-512MB 512MB
- * 0x05 0-1GB 0-1GB 1GB
- * 0x09 0-2GB 0-2GB 2GB
- * 0x0d 0-4GB 0-4GB 4GB
- * 0x17 N/A 0-4GB 4GB
- * 0x1a 0-4GB 4GB-8GB 8GB
- */
- u32 stride;
- u32 odt;
-};
+#define SYS_REG_ENC_VERSION(n) ((n) << 28)
+#define SYS_REG_ENC_CS0_ROW(n, os_reg2, os_reg3, ch) do { \
+ (os_reg2) |= (((n) - 13) & 0x3) << (6 + 16 * (ch)); \
+ (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
+ (5 + 2 * (ch)); \
+ } while (0)
+
+#define SYS_REG_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
+ (os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
+ (os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
+ (os_reg2) |= (((n) - 13) & 0x3) << (4 + 16 * (ch)); \
+ (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
+ (4 + 2 * (ch)); \
+ } while (0)
+
+#define SYS_REG_CS1_COL_SHIFT(ch) (0 + 2 * (ch))
+#define SYS_REG_ENC_CS1_COL(n, ch) (((n) - 9) << SYS_REG_CS1_COL_SHIFT(ch))
+
+/* Get sdram size decode from reg */
+size_t rockchip_sdram_size(phys_addr_t reg);
+
+/* Called by U-Boot board_init_r for Rockchip SoCs */
+int dram_init(void);
+
+#if !defined(CONFIG_RAM_ROCKCHIP_DEBUG)
+inline void sdram_print_dram_type(unsigned char dramtype)
+{
+}
+
+inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base)
+{
+}
+
+inline void sdram_print_stride(unsigned int stride)
+{
+}
+#else
+void sdram_print_dram_type(unsigned char dramtype);
+void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base);
+void sdram_print_stride(unsigned int stride);
+#endif /* CONFIG_RAM_ROCKCHIP_DEBUG */
#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h
deleted file mode 100644
index 8027b53636..0000000000
--- a/arch/arm/include/asm/arch-rockchip/sdram_common.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _ASM_ARCH_SDRAM_COMMON_H
-#define _ASM_ARCH_SDRAM_COMMON_H
-
-enum {
- DDR4 = 0,
- DDR3 = 0x3,
- LPDDR2 = 0x5,
- LPDDR3 = 0x6,
- LPDDR4 = 0x7,
- UNUSED = 0xFF
-};
-
-struct sdram_cap_info {
- unsigned int rank;
- /* dram column number, 0 means this channel is invalid */
- unsigned int col;
- /* dram bank number, 3:8bank, 2:4bank */
- unsigned int bk;
- /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int bw;
- /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int dbw;
- /*
- * row_3_4 = 1: 6Gb or 12Gb die
- * row_3_4 = 0: normal die, power of 2
- */
- unsigned int row_3_4;
- unsigned int cs0_row;
- unsigned int cs1_row;
- unsigned int ddrconfig;
-};
-
-struct sdram_base_params {
- unsigned int ddr_freq;
- unsigned int dramtype;
- unsigned int num_channels;
- unsigned int stride;
- unsigned int odt;
-};
-
-/*
- * sys_reg bitfield struct
- * [31] row_3_4_ch1
- * [30] row_3_4_ch0
- * [29:28] chinfo
- * [27] rank_ch1
- * [26:25] col_ch1
- * [24] bk_ch1
- * [23:22] cs0_row_ch1
- * [21:20] cs1_row_ch1
- * [19:18] bw_ch1
- * [17:16] dbw_ch1;
- * [15:13] ddrtype
- * [12] channelnum
- * [11] rank_ch0
- * [10:9] col_ch0
- * [8] bk_ch0
- * [7:6] cs0_row_ch0
- * [5:4] cs1_row_ch0
- * [3:2] bw_ch0
- * [1:0] dbw_ch0
-*/
-#define SYS_REG_DDRTYPE_SHIFT 13
-#define DDR_SYS_REG_VERSION 2
-#define SYS_REG_DDRTYPE_MASK 7
-#define SYS_REG_NUM_CH_SHIFT 12
-#define SYS_REG_NUM_CH_MASK 1
-#define SYS_REG_ROW_3_4_SHIFT(ch) (30 + (ch))
-#define SYS_REG_ROW_3_4_MASK 1
-#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
-#define SYS_REG_CHINFO_SHIFT(ch) (28 + (ch))
-#define SYS_REG_ENC_CHINFO(ch) (1 << SYS_REG_CHINFO_SHIFT(ch))
-#define SYS_REG_ENC_DDRTYPE(n) ((n) << SYS_REG_DDRTYPE_SHIFT)
-#define SYS_REG_ENC_NUM_CH(n) (((n) - SYS_REG_NUM_CH_MASK) << \
- SYS_REG_NUM_CH_SHIFT)
-#define SYS_REG_RANK_SHIFT(ch) (11 + (ch) * 16)
-#define SYS_REG_RANK_MASK 1
-#define SYS_REG_ENC_RANK(n, ch) (((n) - SYS_REG_RANK_MASK) << \
- SYS_REG_RANK_SHIFT(ch))
-#define SYS_REG_COL_SHIFT(ch) (9 + (ch) * 16)
-#define SYS_REG_COL_MASK 3
-#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << SYS_REG_COL_SHIFT(ch))
-#define SYS_REG_BK_SHIFT(ch) (8 + (ch) * 16)
-#define SYS_REG_BK_MASK 1
-#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) << \
- SYS_REG_BK_SHIFT(ch))
-#define SYS_REG_CS0_ROW_SHIFT(ch) (6 + (ch) * 16)
-#define SYS_REG_CS0_ROW_MASK 3
-#define SYS_REG_CS1_ROW_SHIFT(ch) (4 + (ch) * 16)
-#define SYS_REG_CS1_ROW_MASK 3
-#define SYS_REG_BW_SHIFT(ch) (2 + (ch) * 16)
-#define SYS_REG_BW_MASK 3
-#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << SYS_REG_BW_SHIFT(ch))
-#define SYS_REG_DBW_SHIFT(ch) ((ch) * 16)
-#define SYS_REG_DBW_MASK 3
-#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << SYS_REG_DBW_SHIFT(ch))
-
-#define SYS_REG_ENC_VERSION(n) ((n) << 28)
-#define SYS_REG_ENC_CS0_ROW(n, os_reg2, os_reg3, ch) do { \
- (os_reg2) |= (((n) - 13) & 0x3) << (6 + 16 * (ch)); \
- (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
- (5 + 2 * (ch)); \
- } while (0)
-
-#define SYS_REG_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
- (os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
- (os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
- (os_reg2) |= (((n) - 13) & 0x3) << (4 + 16 * (ch)); \
- (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
- (4 + 2 * (ch)); \
- } while (0)
-
-#define SYS_REG_CS1_COL_SHIFT(ch) (0 + 2 * (ch))
-#define SYS_REG_ENC_CS1_COL(n, ch) (((n) - 9) << SYS_REG_CS1_COL_SHIFT(ch))
-
-/* Get sdram size decode from reg */
-size_t rockchip_sdram_size(phys_addr_t reg);
-
-/* Called by U-Boot board_init_r for Rockchip SoCs */
-int dram_init(void);
-
-#if !defined(CONFIG_RAM_ROCKCHIP_DEBUG)
-inline void sdram_print_dram_type(unsigned char dramtype)
-{
-}
-
-inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base)
-{
-}
-
-inline void sdram_print_stride(unsigned int stride)
-{
-}
-#else
-void sdram_print_dram_type(unsigned char dramtype);
-void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base);
-void sdram_print_stride(unsigned int stride);
-#endif /* CONFIG_RAM_ROCKCHIP_DEBUG */
-
-#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h
new file mode 100644
index 0000000000..9220763fa7
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3288.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * Copyright 2014 Rockchip Inc.
+ */
+
+#ifndef _ASM_ARCH_RK3288_SDRAM_H__
+#define _ASM_ARCH_RK3288_SDRAM_H__
+
+struct rk3288_sdram_channel {
+ /*
+ * bit width in address, eg:
+ * 8 banks using 3 bit to address,
+ * 2 cs using 1 bit to address.
+ */
+ u8 rank;
+ u8 col;
+ u8 bk;
+ u8 bw;
+ u8 dbw;
+ u8 row_3_4;
+ u8 cs0_row;
+ u8 cs1_row;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ /*
+ * For of-platdata, which would otherwise convert this into two
+ * byte-swapped integers. With a size of 9 bytes, this struct will
+ * appear in of-platdata as a byte array.
+ *
+ * If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
+ */
+ u8 dummy;
+#endif
+};
+
+struct rk3288_sdram_pctl_timing {
+ u32 togcnt1u;
+ u32 tinit;
+ u32 trsth;
+ u32 togcnt100n;
+ u32 trefi;
+ u32 tmrd;
+ u32 trfc;
+ u32 trp;
+ u32 trtw;
+ u32 tal;
+ u32 tcl;
+ u32 tcwl;
+ u32 tras;
+ u32 trc;
+ u32 trcd;
+ u32 trrd;
+ u32 trtp;
+ u32 twr;
+ u32 twtr;
+ u32 texsr;
+ u32 txp;
+ u32 txpdll;
+ u32 tzqcs;
+ u32 tzqcsi;
+ u32 tdqs;
+ u32 tcksre;
+ u32 tcksrx;
+ u32 tcke;
+ u32 tmod;
+ u32 trstl;
+ u32 tzqcl;
+ u32 tmrr;
+ u32 tckesr;
+ u32 tdpd;
+};
+check_member(rk3288_sdram_pctl_timing, tdpd, 0x144 - 0xc0);
+
+struct rk3288_sdram_phy_timing {
+ u32 dtpr0;
+ u32 dtpr1;
+ u32 dtpr2;
+ u32 mr[4];
+};
+
+struct rk3288_base_params {
+ u32 noc_timing;
+ u32 noc_activate;
+ u32 ddrconfig;
+ u32 ddr_freq;
+ u32 dramtype;
+ /*
+ * DDR Stride is address mapping for DRAM space
+ * Stride Ch 0 range Ch1 range Total
+ * 0x00 0-256MB 256MB-512MB 512MB
+ * 0x05 0-1GB 0-1GB 1GB
+ * 0x09 0-2GB 0-2GB 2GB
+ * 0x0d 0-4GB 0-4GB 4GB
+ * 0x17 N/A 0-4GB 4GB
+ * 0x1a 0-4GB 4GB-8GB 8GB
+ */
+ u32 stride;
+ u32 odt;
+};
+
+#endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 45d9b06233..a9563ade4f 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o
obj-$(CONFIG_MISC_INIT_R) += misc.o
endif
-obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
+obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
diff --git a/arch/arm/mach-rockchip/rk3036/rk3036.c b/arch/arm/mach-rockchip/rk3036/rk3036.c
index be458cfb64..e9ada6dea3 100644
--- a/arch/arm/mach-rockchip/rk3036/rk3036.c
+++ b/arch/arm/mach-rockchip/rk3036/rk3036.c
@@ -43,7 +43,7 @@ void board_debug_uart_init(void)
#if !CONFIG_IS_ENABLED(RAM)
/*
* When CONFIG_RAM is enabled, the dram_init() function is implemented
- * in sdram_common.c.
+ * in sdram.c.
*/
int dram_init(void)
{
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 057ce92080..3e84523379 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -15,7 +15,7 @@
#include <asm/arch-rockchip/grf_rk3288.h>
#include <asm/arch-rockchip/pmu_rk3288.h>
#include <asm/arch-rockchip/qos_rk3288.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/arm/mach-rockchip/sdram_common.c b/arch/arm/mach-rockchip/sdram.c
similarity index 99%
rename from arch/arm/mach-rockchip/sdram_common.c
rename to arch/arm/mach-rockchip/sdram.c
index 22a4aca940..acb1af765e 100644
--- a/arch/arm/mach-rockchip/sdram_common.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -7,7 +7,7 @@
#include <dm.h>
#include <ram.h>
#include <asm/io.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
#include <dm/uclass-internal.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index e52fc3baad..9df8f8f4af 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -17,7 +17,7 @@
#include <asm/arch-rockchip/grf_rk3368.h>
#include <asm/arch-rockchip/ddr_rk3368.h>
#include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
struct dram_info {
struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_debug.c b/drivers/ram/rockchip/sdram_debug.c
index 9cf662675b..133d1938d5 100644
--- a/drivers/ram/rockchip/sdram_debug.c
+++ b/drivers/ram/rockchip/sdram_debug.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <debug_uart.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
void sdram_print_dram_type(unsigned char dramtype)
{
diff --git a/drivers/ram/rockchip/sdram_rk3128.c b/drivers/ram/rockchip/sdram_rk3128.c
index bfabc22a7d..8486653c6f 100644
--- a/drivers/ram/rockchip/sdram_rk3128.c
+++ b/drivers/ram/rockchip/sdram_rk3128.c
@@ -9,7 +9,7 @@
#include <syscon.h>
#include <asm/arch-rockchip/clock.h>
#include <asm/arch-rockchip/grf_rk3128.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
struct dram_info {
struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index 00e52ec949..d3e4316ef0 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -21,7 +21,7 @@
#include <asm/arch-rockchip/grf_rk3188.h>
#include <asm/arch-rockchip/pmu_rk3188.h>
#include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
#include <linux/err.h>
struct chan_info {
diff --git a/drivers/ram/rockchip/sdram_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
index 94893e17cf..223f048161 100644
--- a/drivers/ram/rockchip/sdram_rk322x.c
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -17,7 +17,7 @@
#include <asm/arch-rockchip/hardware.h>
#include <asm/arch-rockchip/sdram_rk322x.h>
#include <asm/arch-rockchip/uart.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
#include <asm/types.h>
#include <linux/err.h>
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index 5775254007..690751d074 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -21,7 +21,7 @@
#include <asm/arch-rockchip/grf_rk3288.h>
#include <asm/arch-rockchip/pmu_rk3288.h>
#include <asm/arch-rockchip/sdram.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3288.h>
#include <linux/err.h>
#include <power/regulator.h>
#include <power/rk8xx_pmic.h>
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index e84c9be6a2..e7919337ea 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -14,7 +14,7 @@
#include <asm/arch-rockchip/clock.h>
#include <asm/arch-rockchip/cru_rk3328.h>
#include <asm/arch-rockchip/grf_rk3328.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
#include <asm/arch-rockchip/sdram_rk3328.h>
#include <asm/arch-rockchip/uart.h>
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index ed70137ce7..9b7de4ae41 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -18,7 +18,7 @@
#include <asm/arch-rockchip/grf_rk3399.h>
#include <asm/arch-rockchip/pmu_rk3399.h>
#include <asm/arch-rockchip/hardware.h>
-#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram.h>
#include <asm/arch-rockchip/sdram_rk3399.h>
#include <linux/err.h>
#include <time.h>
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 2/9] ram: rockchip: add common sdram driver
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 1/9] ram: rockchip: rename sdram driver files Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 3/9] ram: px30: add " Kever Yang
` (7 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
Add common sdram driver including functions share for all SoCs, controller
and phy common functions.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
arch/arm/include/asm/arch-rockchip/sdram.h | 104 +----
.../include/asm/arch-rockchip/sdram_common.h | 144 +++++++
.../include/asm/arch-rockchip/sdram_msch.h | 85 ++++
.../asm/arch-rockchip/sdram_pctl_px30.h | 139 ++++++
.../asm/arch-rockchip/sdram_phy_px30.h | 62 +++
.../arch-rockchip/sdram_phy_ron_rtt_px30.h | 59 +++
.../include/asm/arch-rockchip/sdram_rk3328.h | 1 +
.../include/asm/arch-rockchip/sdram_rk3399.h | 1 +
drivers/ram/rockchip/Kconfig | 6 +
drivers/ram/rockchip/Makefile | 2 +-
drivers/ram/rockchip/sdram_common.c | 400 ++++++++++++++++++
drivers/ram/rockchip/sdram_debug.c | 147 -------
drivers/ram/rockchip/sdram_pctl_px30.c | 205 +++++++++
drivers/ram/rockchip/sdram_phy_px30.c | 205 +++++++++
drivers/ram/rockchip/sdram_rk3399.c | 4 -
15 files changed, 1329 insertions(+), 235 deletions(-)
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_common.h
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_msch.h
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h
create mode 100644 drivers/ram/rockchip/sdram_common.c
delete mode 100644 drivers/ram/rockchip/sdram_debug.c
create mode 100644 drivers/ram/rockchip/sdram_pctl_px30.c
create mode 100644 drivers/ram/rockchip/sdram_phy_px30.c
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index 3866d0b4d4..2aaeb4327d 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -15,34 +15,6 @@ enum {
UNUSED = 0xFF
};
-struct sdram_cap_info {
- unsigned int rank;
- /* dram column number, 0 means this channel is invalid */
- unsigned int col;
- /* dram bank number, 3:8bank, 2:4bank */
- unsigned int bk;
- /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int bw;
- /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int dbw;
- /*
- * row_3_4 = 1: 6Gb or 12Gb die
- * row_3_4 = 0: normal die, power of 2
- */
- unsigned int row_3_4;
- unsigned int cs0_row;
- unsigned int cs1_row;
- unsigned int ddrconfig;
-};
-
-struct sdram_base_params {
- unsigned int ddr_freq;
- unsigned int dramtype;
- unsigned int num_channels;
- unsigned int stride;
- unsigned int odt;
-};
-
/*
* sys_reg bitfield struct
* [31] row_3_4_ch1
@@ -51,72 +23,58 @@ struct sdram_base_params {
* [27] rank_ch1
* [26:25] col_ch1
* [24] bk_ch1
- * [23:22] cs0_row_ch1
- * [21:20] cs1_row_ch1
+ * [23:22] low bits of cs0_row_ch1
+ * [21:20] low bits of cs1_row_ch1
* [19:18] bw_ch1
* [17:16] dbw_ch1;
* [15:13] ddrtype
* [12] channelnum
* [11] rank_ch0
- * [10:9] col_ch0
+ * [10:9] col_ch0,
* [8] bk_ch0
- * [7:6] cs0_row_ch0
- * [5:4] cs1_row_ch0
+ * [7:6] low bits of cs0_row_ch0
+ * [5:4] low bits of cs1_row_ch0
* [3:2] bw_ch0
* [1:0] dbw_ch0
+ *
+ * sys_reg1 bitfield struct
+ * [7] high bit of cs0_row_ch1
+ * [6] high bit of cs1_row_ch1
+ * [5] high bit of cs0_row_ch0
+ * [4] high bit of cs1_row_ch0
+ * [3:2] cs1_col_ch1
+ * [1:0] cs1_col_ch0
*/
#define SYS_REG_DDRTYPE_SHIFT 13
-#define DDR_SYS_REG_VERSION 2
#define SYS_REG_DDRTYPE_MASK 7
#define SYS_REG_NUM_CH_SHIFT 12
#define SYS_REG_NUM_CH_MASK 1
#define SYS_REG_ROW_3_4_SHIFT(ch) (30 + (ch))
#define SYS_REG_ROW_3_4_MASK 1
-#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
#define SYS_REG_CHINFO_SHIFT(ch) (28 + (ch))
-#define SYS_REG_ENC_CHINFO(ch) (1 << SYS_REG_CHINFO_SHIFT(ch))
-#define SYS_REG_ENC_DDRTYPE(n) ((n) << SYS_REG_DDRTYPE_SHIFT)
-#define SYS_REG_ENC_NUM_CH(n) (((n) - SYS_REG_NUM_CH_MASK) << \
- SYS_REG_NUM_CH_SHIFT)
#define SYS_REG_RANK_SHIFT(ch) (11 + (ch) * 16)
#define SYS_REG_RANK_MASK 1
-#define SYS_REG_ENC_RANK(n, ch) (((n) - SYS_REG_RANK_MASK) << \
- SYS_REG_RANK_SHIFT(ch))
#define SYS_REG_COL_SHIFT(ch) (9 + (ch) * 16)
#define SYS_REG_COL_MASK 3
-#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << SYS_REG_COL_SHIFT(ch))
#define SYS_REG_BK_SHIFT(ch) (8 + (ch) * 16)
#define SYS_REG_BK_MASK 1
-#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) << \
- SYS_REG_BK_SHIFT(ch))
#define SYS_REG_CS0_ROW_SHIFT(ch) (6 + (ch) * 16)
#define SYS_REG_CS0_ROW_MASK 3
#define SYS_REG_CS1_ROW_SHIFT(ch) (4 + (ch) * 16)
#define SYS_REG_CS1_ROW_MASK 3
#define SYS_REG_BW_SHIFT(ch) (2 + (ch) * 16)
#define SYS_REG_BW_MASK 3
-#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << SYS_REG_BW_SHIFT(ch))
#define SYS_REG_DBW_SHIFT(ch) ((ch) * 16)
#define SYS_REG_DBW_MASK 3
-#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << SYS_REG_DBW_SHIFT(ch))
-
-#define SYS_REG_ENC_VERSION(n) ((n) << 28)
-#define SYS_REG_ENC_CS0_ROW(n, os_reg2, os_reg3, ch) do { \
- (os_reg2) |= (((n) - 13) & 0x3) << (6 + 16 * (ch)); \
- (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
- (5 + 2 * (ch)); \
- } while (0)
-#define SYS_REG_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
- (os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
- (os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
- (os_reg2) |= (((n) - 13) & 0x3) << (4 + 16 * (ch)); \
- (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
- (4 + 2 * (ch)); \
- } while (0)
-
-#define SYS_REG_CS1_COL_SHIFT(ch) (0 + 2 * (ch))
-#define SYS_REG_ENC_CS1_COL(n, ch) (((n) - 9) << SYS_REG_CS1_COL_SHIFT(ch))
+#define SYS_REG1_VERSION_SHIFT 28
+#define SYS_REG1_VERSION_MASK 0xf
+#define SYS_REG1_EXTEND_CS0_ROW_SHIFT(ch) (5 + (ch) * 2)
+#define SYS_REG1_EXTEND_CS0_ROW_MASK 1
+#define SYS_REG1_EXTEND_CS1_ROW_SHIFT(ch) (4 + (ch) * 2)
+#define SYS_REG1_EXTEND_CS1_ROW_MASK 1
+#define SYS_REG1_CS1_COL_SHIFT(ch) (0 + (ch) * 2)
+#define SYS_REG1_CS1_COL_MASK 3
/* Get sdram size decode from reg */
size_t rockchip_sdram_size(phys_addr_t reg);
@@ -124,24 +82,4 @@ size_t rockchip_sdram_size(phys_addr_t reg);
/* Called by U-Boot board_init_r for Rockchip SoCs */
int dram_init(void);
-#if !defined(CONFIG_RAM_ROCKCHIP_DEBUG)
-inline void sdram_print_dram_type(unsigned char dramtype)
-{
-}
-
-inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base)
-{
-}
-
-inline void sdram_print_stride(unsigned int stride)
-{
-}
-#else
-void sdram_print_dram_type(unsigned char dramtype);
-void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base);
-void sdram_print_stride(unsigned int stride);
-#endif /* CONFIG_RAM_ROCKCHIP_DEBUG */
-
#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h
new file mode 100644
index 0000000000..dd593ae5e0
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_common.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_SHARE_H
+#define _ASM_ARCH_SDRAM_SHARE_H
+
+#ifndef MHZ
+#define MHZ (1000 * 1000)
+#endif
+
+#define PATTERN (0x5aa5f00f)
+
+#define MIN(a, b) (((a) > (b)) ? (b) : (a))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+struct sdram_cap_info {
+ unsigned int rank;
+ /* dram column number, 0 means this channel is invalid */
+ unsigned int col;
+ /* dram bank number, 3:8bank, 2:4bank */
+ unsigned int bk;
+ /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int bw;
+ /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
+ unsigned int dbw;
+ /*
+ * row_3_4 = 1: 6Gb or 12Gb die
+ * row_3_4 = 0: normal die, power of 2
+ */
+ unsigned int row_3_4;
+ unsigned int cs0_row;
+ unsigned int cs1_row;
+ unsigned int cs0_high16bit_row;
+ unsigned int cs1_high16bit_row;
+ unsigned int ddrconfig;
+};
+
+struct sdram_base_params {
+ unsigned int ddr_freq;
+ unsigned int dramtype;
+ unsigned int num_channels;
+ unsigned int stride;
+ unsigned int odt;
+};
+
+/*
+ * sys_reg bitfield struct
+ * [31] row_3_4_ch1
+ * [30] row_3_4_ch0
+ * [29:28] chinfo
+ * [27] rank_ch1
+ * [26:25] col_ch1
+ * [24] bk_ch1
+ * [23:22] cs0_row_ch1
+ * [21:20] cs1_row_ch1
+ * [19:18] bw_ch1
+ * [17:16] dbw_ch1;
+ * [15:13] ddrtype
+ * [12] channelnum
+ * [11] rank_ch0
+ * [10:9] col_ch0
+ * [8] bk_ch0
+ * [7:6] cs0_row_ch0
+ * [5:4] cs1_row_ch0
+ * [3:2] bw_ch0
+ * [1:0] dbw_ch0
+ */
+
+#define DDR_SYS_REG_VERSION (0x2)
+#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
+#define SYS_REG_DEC_ROW_3_4(n, ch) (((n) >> (30 + (ch))) & 0x1)
+#define SYS_REG_ENC_CHINFO(ch) (1 << (28 + (ch)))
+#define SYS_REG_ENC_DDRTYPE(n) ((n) << 13)
+#define SYS_REG_DEC_DDRTYPE(n) (((n) >> 13) & 0x7)
+#define SYS_REG_ENC_NUM_CH(n) (((n) - 1) << 12)
+#define SYS_REG_DEC_NUM_CH(n) (1 + (((n) >> 12) & 0x1))
+#define SYS_REG_ENC_RANK(n, ch) (((n) - 1) << (11 + ((ch) * 16)))
+#define SYS_REG_DEC_RANK(n, ch) (1 + (((n) >> (11 + 16 * (ch))) & 0x1))
+#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << (9 + ((ch) * 16)))
+#define SYS_REG_DEC_COL(n, ch) (9 + (((n) >> (9 + 16 * (ch))) & 0x3))
+#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) << \
+ (8 + ((ch) * 16)))
+#define SYS_REG_DEC_BK(n, ch) (3 - (((n) >> (8 + 16 * (ch))) & 0x1))
+#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << (2 + ((ch) * 16)))
+#define SYS_REG_DEC_BW(n, ch) (2 >> (((n) >> (2 + 16 * (ch))) & 0x3))
+#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + ((ch) * 16)))
+#define SYS_REG_DEC_DBW(n, ch) (2 >> (((n) >> (0 + 16 * (ch))) & 0x3))
+/* sys reg 3 */
+#define SYS_REG_ENC_VERSION(n) ((n) << 28)
+#define SYS_REG_DEC_VERSION(n) (((n) >> 28) & 0xf)
+#define SYS_REG_ENC_CS0_ROW(n, os_reg2, os_reg3, ch) do { \
+ (os_reg2) |= (((n) - 13) & 0x3) << (6 + 16 * (ch)); \
+ (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
+ (5 + 2 * (ch)); \
+ } while (0)
+
+#define SYS_REG_DEC_CS0_ROW(os_reg2, os_reg3, ch) \
+ ((((((os_reg2) >> (6 + 16 * (ch)) & 0x3) | \
+ ((((os_reg3) >> (5 + 2 * (ch))) & 0x1) << 2)) + 1) & 0x7) + 12)
+
+#define SYS_REG_ENC_CS1_ROW(n, os_reg2, os_reg3, ch) do { \
+ (os_reg2) &= (~(0x3 << (4 + 16 * (ch)))); \
+ (os_reg3) &= (~(0x1 << (4 + 2 * (ch)))); \
+ (os_reg2) |= (((n) - 13) & 0x3) << (4 + 16 * (ch)); \
+ (os_reg3) |= ((((n) - 13) & 0x4) >> 2) << \
+ (4 + 2 * (ch)); \
+ } while (0)
+
+#define SYS_REG_DEC_CS1_ROW(os_reg2, os_reg3, ch) \
+ ((((((os_reg2) >> (4 + 16 * (ch)) & 0x3) | \
+ ((((os_reg3) >> (4 + 2 * (ch))) & 0x1) << 2)) + 1) & 0x7) + 12)
+
+#define SYS_REG_ENC_CS1_COL(n, ch) (((n) - 9) << (0 + 2 * (ch)))
+#define SYS_REG_DEC_CS1_COL(n, ch) (9 + (((n) >> (0 + 2 * (ch))) & 0x3))
+
+void sdram_org_config(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base,
+ u32 *p_os_reg2, u32 *p_os_reg3, u32 channel);
+
+int sdram_detect_bw(struct sdram_cap_info *cap_info);
+int sdram_detect_cs(struct sdram_cap_info *cap_info);
+int sdram_detect_col(struct sdram_cap_info *cap_info,
+ u32 coltmp);
+int sdram_detect_bank(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp);
+int sdram_detect_bg(struct sdram_cap_info *cap_info,
+ u32 coltmp);
+int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type);
+int sdram_detect_row(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp, u32 rowtmp);
+int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp);
+int sdram_detect_high_row(struct sdram_cap_info *cap_info);
+int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type);
+
+void sdram_print_dram_type(unsigned char dramtype);
+void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base, u32 split);
+u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type);
+void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_msch.h b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
new file mode 100644
index 0000000000..cfb3d9cc86
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_MSCH_H
+#define _ASM_ARCH_SDRAM_MSCH_H
+
+union noc_ddrtiminga0 {
+ u32 d32;
+ struct {
+ unsigned acttoact : 6;
+ unsigned reserved0 : 2;
+ unsigned rdtomiss : 6;
+ unsigned reserved1 : 2;
+ unsigned wrtomiss : 6;
+ unsigned reserved2 : 2;
+ unsigned readlatency : 8;
+ } b;
+};
+
+union noc_ddrtimingb0 {
+ u32 d32;
+ struct {
+ unsigned rdtowr : 5;
+ unsigned reserved0 : 3;
+ unsigned wrtord : 5;
+ unsigned reserved1 : 3;
+ unsigned rrd : 4;
+ unsigned reserved2 : 4;
+ unsigned faw : 6;
+ unsigned reserved3 : 2;
+ } b;
+};
+
+union noc_ddrtimingc0 {
+ u32 d32;
+ struct {
+ unsigned burstpenalty : 4;
+ unsigned reserved0 : 4;
+ unsigned wrtomwr : 6;
+ unsigned reserved1 : 18;
+ } b;
+};
+
+union noc_devtodev0 {
+ u32 d32;
+ struct {
+ unsigned busrdtord : 3;
+ unsigned reserved0 : 1;
+ unsigned busrdtowr : 3;
+ unsigned reserved1 : 1;
+ unsigned buswrtord : 3;
+ unsigned reserved2 : 1;
+ unsigned buswrtowr : 3;
+ unsigned reserved3 : 17;
+ } b;
+};
+
+union noc_ddrmode {
+ u32 d32;
+ struct {
+ unsigned autoprecharge : 1;
+ unsigned bypassfiltering : 1;
+ unsigned fawbank : 1;
+ unsigned burstsize : 2;
+ unsigned mwrsize : 2;
+ unsigned reserved2 : 1;
+ unsigned forceorder : 8;
+ unsigned forceorderstate : 8;
+ unsigned reserved3 : 8;
+ } b;
+};
+
+union noc_ddr4timing {
+ u32 d32;
+ struct {
+ unsigned ccdl : 3;
+ unsigned wrtordl : 5;
+ unsigned rrdl : 4;
+ unsigned reserved1 : 20;
+ } b;
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
new file mode 100644
index 0000000000..9781881738
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PCTL_PX30_H
+#define _ASM_ARCH_SDRAM_PCTL_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+
+struct ddr_pctl_regs {
+ u32 pctl[30][2];
+};
+
+/* ddr pctl registers define */
+#define DDR_PCTL2_MSTR 0x0
+#define DDR_PCTL2_STAT 0x4
+#define DDR_PCTL2_MSTR1 0x8
+#define DDR_PCTL2_MRCTRL0 0x10
+#define DDR_PCTL2_MRCTRL1 0x14
+#define DDR_PCTL2_MRSTAT 0x18
+#define DDR_PCTL2_MRCTRL2 0x1c
+#define DDR_PCTL2_DERATEEN 0x20
+#define DDR_PCTL2_DERATEINT 0x24
+#define DDR_PCTL2_PWRCTL 0x30
+#define DDR_PCTL2_PWRTMG 0x34
+#define DDR_PCTL2_HWLPCTL 0x38
+#define DDR_PCTL2_RFSHCTL0 0x50
+#define DDR_PCTL2_RFSHCTL1 0x54
+#define DDR_PCTL2_RFSHCTL2 0x58
+#define DDR_PCTL2_RFSHCTL4 0x5c
+#define DDR_PCTL2_RFSHCTL3 0x60
+#define DDR_PCTL2_RFSHTMG 0x64
+#define DDR_PCTL2_RFSHTMG1 0x68
+#define DDR_PCTL2_RFSHCTL5 0x6c
+#define DDR_PCTL2_INIT0 0xd0
+#define DDR_PCTL2_INIT1 0xd4
+#define DDR_PCTL2_INIT2 0xd8
+#define DDR_PCTL2_INIT3 0xdc
+#define DDR_PCTL2_INIT4 0xe0
+#define DDR_PCTL2_INIT5 0xe4
+#define DDR_PCTL2_INIT6 0xe8
+#define DDR_PCTL2_INIT7 0xec
+#define DDR_PCTL2_DIMMCTL 0xf0
+#define DDR_PCTL2_RANKCTL 0xf4
+#define DDR_PCTL2_CHCTL 0xfc
+#define DDR_PCTL2_DRAMTMG0 0x100
+#define DDR_PCTL2_DRAMTMG1 0x104
+#define DDR_PCTL2_DRAMTMG2 0x108
+#define DDR_PCTL2_DRAMTMG3 0x10c
+#define DDR_PCTL2_DRAMTMG4 0x110
+#define DDR_PCTL2_DRAMTMG5 0x114
+#define DDR_PCTL2_DRAMTMG6 0x118
+#define DDR_PCTL2_DRAMTMG7 0x11c
+#define DDR_PCTL2_DRAMTMG8 0x120
+#define DDR_PCTL2_DRAMTMG9 0x124
+#define DDR_PCTL2_DRAMTMG10 0x128
+#define DDR_PCTL2_DRAMTMG11 0x12c
+#define DDR_PCTL2_DRAMTMG12 0x130
+#define DDR_PCTL2_DRAMTMG13 0x134
+#define DDR_PCTL2_DRAMTMG14 0x138
+#define DDR_PCTL2_DRAMTMG15 0x13c
+#define DDR_PCTL2_DRAMTMG16 0x140
+#define DDR_PCTL2_ZQCTL0 0x180
+#define DDR_PCTL2_ZQCTL1 0x184
+#define DDR_PCTL2_ZQCTL2 0x188
+#define DDR_PCTL2_ZQSTAT 0x18c
+#define DDR_PCTL2_DFITMG0 0x190
+#define DDR_PCTL2_DFITMG1 0x194
+#define DDR_PCTL2_DFILPCFG0 0x198
+#define DDR_PCTL2_DFILPCFG1 0x19c
+#define DDR_PCTL2_DFIUPD0 0x1a0
+#define DDR_PCTL2_DFIUPD1 0x1a4
+#define DDR_PCTL2_DFIUPD2 0x1a8
+#define DDR_PCTL2_DFIMISC 0x1b0
+#define DDR_PCTL2_DFITMG2 0x1b4
+#define DDR_PCTL2_DFITMG3 0x1b8
+#define DDR_PCTL2_DFISTAT 0x1bc
+#define DDR_PCTL2_DBICTL 0x1c0
+#define DDR_PCTL2_ADDRMAP0 0x200
+#define DDR_PCTL2_ADDRMAP1 0x204
+#define DDR_PCTL2_ADDRMAP2 0x208
+#define DDR_PCTL2_ADDRMAP3 0x20c
+#define DDR_PCTL2_ADDRMAP4 0x210
+#define DDR_PCTL2_ADDRMAP5 0x214
+#define DDR_PCTL2_ADDRMAP6 0x218
+#define DDR_PCTL2_ADDRMAP7 0x21c
+#define DDR_PCTL2_ADDRMAP8 0x220
+#define DDR_PCTL2_ADDRMAP9 0x224
+#define DDR_PCTL2_ADDRMAP10 0x228
+#define DDR_PCTL2_ADDRMAP11 0x22c
+#define DDR_PCTL2_ODTCFG 0x240
+#define DDR_PCTL2_ODTMAP 0x244
+#define DDR_PCTL2_SCHED 0x250
+#define DDR_PCTL2_SCHED1 0x254
+#define DDR_PCTL2_PERFHPR1 0x25c
+#define DDR_PCTL2_PERFLPR1 0x264
+#define DDR_PCTL2_PERFWR1 0x26c
+#define DDR_PCTL2_DQMAP0 0x280
+#define DDR_PCTL2_DQMAP1 0x284
+#define DDR_PCTL2_DQMAP2 0x288
+#define DDR_PCTL2_DQMAP3 0x28c
+#define DDR_PCTL2_DQMAP4 0x290
+#define DDR_PCTL2_DQMAP5 0x294
+#define DDR_PCTL2_DBG0 0x300
+#define DDR_PCTL2_DBG1 0x304
+#define DDR_PCTL2_DBGCAM 0x308
+#define DDR_PCTL2_DBGCMD 0x30c
+#define DDR_PCTL2_DBGSTAT 0x310
+#define DDR_PCTL2_SWCTL 0x320
+#define DDR_PCTL2_SWSTAT 0x324
+#define DDR_PCTL2_POISONCFG 0x36c
+#define DDR_PCTL2_POISONSTAT 0x370
+#define DDR_PCTL2_ADVECCINDEX 0x374
+#define DDR_PCTL2_ADVECCSTAT 0x378
+#define DDR_PCTL2_PSTAT 0x3fc
+#define DDR_PCTL2_PCCFG 0x400
+#define DDR_PCTL2_PCFGR_n 0x404
+#define DDR_PCTL2_PCFGW_n 0x408
+#define DDR_PCTL2_PCTRL_n 0x490
+
+/* PCTL2_MRSTAT */
+#define MR_WR_BUSY BIT(0)
+
+void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num);
+int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
+ u32 dramtype);
+int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
+ u32 dramtype);
+
+u32 pctl_dis_zqcs_aref(void __iomem *pctl_base);
+void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq);
+
+u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
+ struct sdram_cap_info *cap_info,
+ u32 dram_type);
+int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
+ u32 sr_idle, u32 pd_idle);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h
new file mode 100644
index 0000000000..c75a633c91
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_px30.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PHY_PX30_H
+#define _ASM_ARCH_SDRAM_PHY_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
+
+struct ddr_phy_regs {
+ u32 phy[5][2];
+};
+
+#define PHY_REG(base, n) ((base) + 4 * (n))
+
+/* PHY_REG0 */
+#define DIGITAL_DERESET BIT(3)
+#define ANALOG_DERESET BIT(2)
+#define DIGITAL_RESET (0 << 3)
+#define ANALOG_RESET (0 << 2)
+
+/* PHY_REG1 */
+#define PHY_DDR2 (0)
+#define PHY_LPDDR2 (1)
+#define PHY_DDR3 (2)
+#define PHY_LPDDR3 (3)
+#define PHY_DDR4 (4)
+#define PHY_BL_4 (0 << 2)
+#define PHY_BL_8 BIT(2)
+
+/* PHY_REG2 */
+#define PHY_DTT_EN BIT(0)
+#define PHY_DTT_DISB (0 << 0)
+#define PHY_WRITE_LEVELING_EN BIT(2)
+#define PHY_WRITE_LEVELING_DISB (0 << 2)
+#define PHY_SELECT_CS0 (2)
+#define PHY_SELECT_CS1 (1)
+#define PHY_SELECT_CS0_1 (0)
+#define PHY_WRITE_LEVELING_SELECTCS(n) ((n) << 6)
+#define PHY_DATA_TRAINING_SELECTCS(n) ((n) << 4)
+
+struct ddr_phy_skew {
+ u32 a0_a1_skew[15];
+ u32 cs0_dm0_skew[11];
+ u32 cs0_dm1_skew[11];
+ u32 cs0_dm2_skew[11];
+ u32 cs0_dm3_skew[11];
+ u32 cs1_dm0_skew[11];
+ u32 cs1_dm1_skew[11];
+ u32 cs1_dm2_skew[11];
+ u32 cs1_dm3_skew[11];
+};
+
+void phy_soft_reset(void __iomem *phy_base);
+void phy_dram_set_bw(void __iomem *phy_base, u32 bw);
+void phy_cfg(void __iomem *phy_base,
+ struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
+ struct sdram_base_params *base, u32 bw);
+int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h
new file mode 100644
index 0000000000..9c15232047
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_ron_rtt_px30.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PHY_RON_RTT_PX30_H
+#define _ASM_ARCH_SDRAM_PHY_RON_RTT_PX30_H
+
+#define PHY_DDR3_RON_RTT_DISABLE (0)
+#define PHY_DDR3_RON_RTT_451ohm (1)
+#define PHY_DDR3_RON_RTT_225ohm (2)
+#define PHY_DDR3_RON_RTT_150ohm (3)
+#define PHY_DDR3_RON_RTT_112ohm (4)
+#define PHY_DDR3_RON_RTT_90ohm (5)
+#define PHY_DDR3_RON_RTT_75ohm (6)
+#define PHY_DDR3_RON_RTT_64ohm (7)
+#define PHY_DDR3_RON_RTT_56ohm (16)
+#define PHY_DDR3_RON_RTT_50ohm (17)
+#define PHY_DDR3_RON_RTT_45ohm (18)
+#define PHY_DDR3_RON_RTT_41ohm (19)
+#define PHY_DDR3_RON_RTT_37ohm (20)
+#define PHY_DDR3_RON_RTT_34ohm (21)
+#define PHY_DDR3_RON_RTT_33ohm (22)
+#define PHY_DDR3_RON_RTT_30ohm (23)
+#define PHY_DDR3_RON_RTT_28ohm (24)
+#define PHY_DDR3_RON_RTT_26ohm (25)
+#define PHY_DDR3_RON_RTT_25ohm (26)
+#define PHY_DDR3_RON_RTT_23ohm (27)
+#define PHY_DDR3_RON_RTT_22ohm (28)
+#define PHY_DDR3_RON_RTT_21ohm (29)
+#define PHY_DDR3_RON_RTT_20ohm (30)
+#define PHY_DDR3_RON_RTT_19ohm (31)
+
+#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
+#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1)
+#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2)
+#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3)
+#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4)
+#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5)
+#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6)
+#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7)
+#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16)
+#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17)
+#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18)
+#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19)
+#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20)
+#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21)
+#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22)
+#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23)
+#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24)
+#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25)
+#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26)
+#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27)
+#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28)
+#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29)
+#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30)
+#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31)
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
index 11411ead10..c747b461a1 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
@@ -6,6 +6,7 @@
#ifndef _ASM_ARCH_SDRAM_RK3328_H
#define _ASM_ARCH_SDRAM_RK3328_H
+#include <asm/arch-rockchip/sdram_common.h>
#define SR_IDLE 93
#define PD_IDLE 13
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
index dc65ae7924..485bb3d889 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -5,6 +5,7 @@
#ifndef _ASM_ARCH_SDRAM_RK3399_H
#define _ASM_ARCH_SDRAM_RK3399_H
+#include <asm/arch-rockchip/sdram_common.h>
struct rk3399_ddr_pctl_regs {
u32 denali_ctl[332];
diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig
index 4f274e01b3..dcc06b3fd3 100644
--- a/drivers/ram/rockchip/Kconfig
+++ b/drivers/ram/rockchip/Kconfig
@@ -5,6 +5,12 @@ config RAM_ROCKCHIP
help
This enables support for ram drivers Rockchip SoCs.
+config ROCKCHIP_SDRAM_COMMON
+ bool "Enable rockchip sdram common driver"
+ depends on TPL_RAM || SPL_RAM
+ help
+ This enable sdram common driver
+
if RAM_ROCKCHIP
config RAM_ROCKCHIP_DEBUG
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index feb1f82d00..3d4f2f4ebf 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -2,7 +2,7 @@
#
# Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
#
-
+obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.o
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
diff --git a/drivers/ram/rockchip/sdram_common.c b/drivers/ram/rockchip/sdram_common.c
new file mode 100644
index 0000000000..47c29f6b52
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_common.c
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
+
+void sdram_print_dram_type(unsigned char dramtype)
+{
+ switch (dramtype) {
+ case DDR3:
+ printascii("DDR3");
+ break;
+ case DDR4:
+ printascii("DDR4");
+ break;
+ case LPDDR2:
+ printascii("LPDDR2");
+ break;
+ case LPDDR3:
+ printascii("LPDDR3");
+ break;
+ case LPDDR4:
+ printascii("LPDDR4");
+ break;
+ default:
+ printascii("Unknown Device");
+ break;
+ }
+}
+
+void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base, u32 split)
+{
+ u64 cap;
+ u32 bg;
+
+ bg = (cap_info->dbw == 0) ? 2 : 1;
+
+ sdram_print_dram_type(base->dramtype);
+
+ printascii(", ");
+ printdec(base->ddr_freq);
+ printascii("MHz\n");
+
+ printascii("BW=");
+ printdec(8 << cap_info->bw);
+ printascii(" Col=");
+ printdec(cap_info->col);
+ printascii(" Bk=");
+ printdec(0x1 << cap_info->bk);
+ if (base->dramtype == DDR4) {
+ printascii(" BG=");
+ printdec(1 << bg);
+ }
+ printascii(" CS0 Row=");
+ printdec(cap_info->cs0_row);
+ if (cap_info->cs0_high16bit_row !=
+ cap_info->cs0_row) {
+ printascii("/");
+ printdec(cap_info->cs0_high16bit_row);
+ }
+ if (cap_info->rank > 1) {
+ printascii(" CS1 Row=");
+ printdec(cap_info->cs1_row);
+ if (cap_info->cs1_high16bit_row !=
+ cap_info->cs1_row) {
+ printascii("/");
+ printdec(cap_info->cs1_high16bit_row);
+ }
+ }
+ printascii(" CS=");
+ printdec(cap_info->rank);
+ printascii(" Die BW=");
+ printdec(8 << cap_info->dbw);
+
+ cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
+ if (cap_info->row_3_4)
+ cap = cap * 3 / 4;
+ else if (split)
+ cap = cap / 2 + (split << 24) / 2;
+
+ printascii(" Size=");
+ printdec(cap >> 20);
+ printascii("MB\n");
+}
+
+/*
+ * cs: 0:cs0
+ * 1:cs1
+ * else cs0+cs1
+ * note: it didn't consider about row_3_4
+ */
+u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
+{
+ u32 bg;
+ u64 cap[2];
+
+ if (dram_type == DDR4)
+ /* DDR4 8bit dram BG = 2(4bank groups),
+ * 16bit dram BG = 1 (2 bank groups)
+ */
+ bg = (cap_info->dbw == 0) ? 2 : 1;
+ else
+ bg = 0;
+ cap[0] = 1llu << (cap_info->bw + cap_info->col +
+ bg + cap_info->bk + cap_info->cs0_row);
+
+ if (cap_info->rank == 2)
+ cap[1] = 1llu << (cap_info->bw + cap_info->col +
+ bg + cap_info->bk + cap_info->cs1_row);
+ else
+ cap[1] = 0;
+
+ if (cs == 0)
+ return cap[0];
+ else if (cs == 1)
+ return cap[1];
+ else
+ return (cap[0] + cap[1]);
+}
+
+/* n: Unit bytes */
+void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
+{
+ int i;
+
+ for (i = 0; i < n / sizeof(u32); i++) {
+ writel(*src, dest);
+ src++;
+ dest++;
+ }
+}
+
+void sdram_org_config(struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base,
+ u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
+{
+ *p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
+ *p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
+
+ *p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
+ *p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
+ *p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
+ *p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
+ *p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
+ *p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
+ *p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
+
+ SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
+ if (cap_info->cs1_row)
+ SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
+ *p_os_reg3, channel);
+ *p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
+ *p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
+}
+
+int sdram_detect_bw(struct sdram_cap_info *cap_info)
+{
+ return 0;
+}
+
+int sdram_detect_cs(struct sdram_cap_info *cap_info)
+{
+ return 0;
+}
+
+int sdram_detect_col(struct sdram_cap_info *cap_info,
+ u32 coltmp)
+{
+ void __iomem *test_addr;
+ u32 col;
+ u32 bw = cap_info->bw;
+
+ for (col = coltmp; col >= 9; col -= 1) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ (1ul << (col + bw - 1ul)));
+ writel(PATTERN, test_addr);
+ if ((readl(test_addr) == PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (col == 8) {
+ printascii("col error\n");
+ return -1;
+ }
+
+ cap_info->col = col;
+
+ return 0;
+}
+
+int sdram_detect_bank(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp)
+{
+ void __iomem *test_addr;
+ u32 bk;
+ u32 bw = cap_info->bw;
+
+ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ (1ul << (coltmp + bktmp + bw - 1ul)));
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ writel(PATTERN, test_addr);
+ if ((readl(test_addr) == PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ bk = 3;
+ else
+ bk = 2;
+
+ cap_info->bk = bk;
+
+ return 0;
+}
+
+/* detect bg for ddr4 */
+int sdram_detect_bg(struct sdram_cap_info *cap_info,
+ u32 coltmp)
+{
+ void __iomem *test_addr;
+ u32 dbw;
+ u32 bw = cap_info->bw;
+
+ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ (1ul << (coltmp + bw + 1ul)));
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ writel(PATTERN, test_addr);
+ if ((readl(test_addr) == PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ dbw = 0;
+ else
+ dbw = 1;
+
+ cap_info->dbw = dbw;
+
+ return 0;
+}
+
+/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
+int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
+{
+ u32 row, col, bk, bw, cs_cap, cs;
+ u32 die_bw_0 = 0, die_bw_1 = 0;
+
+ if (dram_type == DDR3 || dram_type == LPDDR4) {
+ cap_info->dbw = 1;
+ } else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
+ row = cap_info->cs0_row;
+ col = cap_info->col;
+ bk = cap_info->bk;
+ cs = cap_info->rank;
+ bw = cap_info->bw;
+ cs_cap = (1 << (row + col + bk + bw - 20));
+ if (bw == 2) {
+ if (cs_cap <= 0x2000000) /* 256Mb */
+ die_bw_0 = (col < 9) ? 2 : 1;
+ else if (cs_cap <= 0x10000000) /* 2Gb */
+ die_bw_0 = (col < 10) ? 2 : 1;
+ else if (cs_cap <= 0x40000000) /* 8Gb */
+ die_bw_0 = (col < 11) ? 2 : 1;
+ else
+ die_bw_0 = (col < 12) ? 2 : 1;
+ if (cs > 1) {
+ row = cap_info->cs1_row;
+ cs_cap = (1 << (row + col + bk + bw - 20));
+ if (cs_cap <= 0x2000000) /* 256Mb */
+ die_bw_0 = (col < 9) ? 2 : 1;
+ else if (cs_cap <= 0x10000000) /* 2Gb */
+ die_bw_0 = (col < 10) ? 2 : 1;
+ else if (cs_cap <= 0x40000000) /* 8Gb */
+ die_bw_0 = (col < 11) ? 2 : 1;
+ else
+ die_bw_0 = (col < 12) ? 2 : 1;
+ }
+ } else {
+ die_bw_1 = 1;
+ die_bw_0 = 1;
+ }
+ cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
+ }
+
+ return 0;
+}
+
+int sdram_detect_row(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp, u32 rowtmp)
+{
+ u32 row;
+ u32 bw = cap_info->bw;
+ void __iomem *test_addr;
+
+ for (row = rowtmp; row > 12; row--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ (1ul << (row + bktmp + coltmp + bw - 1ul)));
+ writel(PATTERN, test_addr);
+ if ((readl(test_addr) == PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (row == 12) {
+ printascii("row error");
+ return -1;
+ }
+
+ cap_info->cs0_row = row;
+
+ return 0;
+}
+
+int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
+ u32 coltmp, u32 bktmp)
+{
+ u32 row_3_4;
+ u32 bw = cap_info->bw;
+ u32 row = cap_info->cs0_row;
+ void __iomem *test_addr, *test_addr1;
+
+ test_addr = CONFIG_SYS_SDRAM_BASE;
+ test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
+
+ writel(0, test_addr);
+ writel(PATTERN, test_addr1);
+ if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
+ row_3_4 = 0;
+ else
+ row_3_4 = 1;
+
+ cap_info->row_3_4 = row_3_4;
+
+ return 0;
+}
+
+int sdram_detect_high_row(struct sdram_cap_info *cap_info)
+{
+ cap_info->cs0_high16bit_row = cap_info->cs0_row;
+ cap_info->cs1_high16bit_row = cap_info->cs1_row;
+
+ return 0;
+}
+
+int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
+{
+ void __iomem *test_addr;
+ u32 row = 0, bktmp, coltmp, bw;
+ ulong cs0_cap;
+ u32 byte_mask;
+
+ if (cap_info->rank == 2) {
+ cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
+
+ if (dram_type == DDR4) {
+ if (cap_info->dbw == 0)
+ bktmp = cap_info->bk + 2;
+ else
+ bktmp = cap_info->bk + 1;
+ } else {
+ bktmp = cap_info->bk;
+ }
+ bw = cap_info->bw;
+ coltmp = cap_info->col;
+
+ /*
+ * because px30 support axi split,min bandwidth
+ * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
+ * so we check low 16bit data when detect cs1 row.
+ * if cs0 is 16bit/8bit, we check low 8bit data.
+ */
+ if (bw == 2)
+ byte_mask = 0xFFFF;
+ else
+ byte_mask = 0xFF;
+
+ /* detect cs1 row */
+ for (row = cap_info->cs0_row; row > 12; row--) {
+ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+ cs0_cap +
+ (1ul << (row + bktmp + coltmp + bw - 1ul)));
+ writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
+ writel(PATTERN, test_addr);
+
+ if (((readl(test_addr) & byte_mask) ==
+ (PATTERN & byte_mask)) &&
+ ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
+ byte_mask) == 0)) {
+ break;
+ }
+ }
+ }
+
+ cap_info->cs1_row = row;
+
+ return 0;
+}
diff --git a/drivers/ram/rockchip/sdram_debug.c b/drivers/ram/rockchip/sdram_debug.c
deleted file mode 100644
index 133d1938d5..0000000000
--- a/drivers/ram/rockchip/sdram_debug.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * (C) Copyright 2019 Rockchip Electronics Co., Ltd
- * (C) Copyright 2019 Amarula Solutions.
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
-
-#include <common.h>
-#include <debug_uart.h>
-#include <asm/arch-rockchip/sdram.h>
-
-void sdram_print_dram_type(unsigned char dramtype)
-{
- switch (dramtype) {
- case DDR3:
- printascii("DDR3");
- break;
- case DDR4:
- printascii("DDR4");
- break;
- case LPDDR2:
- printascii("LPDDR2");
- break;
- case LPDDR3:
- printascii("LPDDR3");
- break;
- case LPDDR4:
- printascii("LPDDR4");
- break;
- default:
- printascii("Unknown Device");
- break;
- }
-}
-
-/**
- * cs = 0, cs0
- * cs = 1, cs1
- * cs => 2, cs0+cs1
- * note: it didn't consider about row_3_4
- */
-u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
-{
- u32 bg;
- u64 cap[2];
-
- if (dram_type == DDR4)
- /* DDR4 8bit dram BG = 2(4bank groups),
- * 16bit dram BG = 1 (2 bank groups)
- */
- bg = (cap_info->dbw == 0) ? 2 : 1;
- else
- bg = 0;
-
- cap[0] = 1llu << (cap_info->bw + cap_info->col +
- bg + cap_info->bk + cap_info->cs0_row);
-
- if (cap_info->rank == 2)
- cap[1] = 1llu << (cap_info->bw + cap_info->col +
- bg + cap_info->bk + cap_info->cs1_row);
- else
- cap[1] = 0;
-
- if (cs == 0)
- return cap[0];
- else if (cs == 1)
- return cap[1];
- else
- return (cap[0] + cap[1]);
-}
-
-void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base)
-{
- u32 bg, cap;
-
- bg = (cap_info->dbw == 0) ? 2 : 1;
-
- sdram_print_dram_type(base->dramtype);
-
- printascii(", ");
- printdec(base->ddr_freq);
- printascii("MHz\n");
-
- printascii("BW=");
- printdec(8 << cap_info->bw);
-
- printascii(" Col=");
- printdec(cap_info->col);
-
- printascii(" Bk=");
- printdec(0x1 << cap_info->bk);
- if (base->dramtype == DDR4) {
- printascii(" BG=");
- printdec(1 << bg);
- }
-
- printascii(" CS0 Row=");
- printdec(cap_info->cs0_row);
- if (cap_info->rank > 1) {
- printascii(" CS1 Row=");
- printdec(cap_info->cs1_row);
- }
-
- printascii(" CS=");
- printdec(cap_info->rank);
-
- printascii(" Die BW=");
- printdec(8 << cap_info->dbw);
-
- cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
- if (cap_info->row_3_4)
- cap = cap * 3 / 4;
-
- printascii(" Size=");
- printdec(cap >> 20);
- printascii("MB\n");
-}
-
-void sdram_print_stride(unsigned int stride)
-{
- switch (stride) {
- case 0xc:
- printf("128B stride\n");
- break;
- case 5:
- case 9:
- case 0xd:
- case 0x11:
- case 0x19:
- printf("256B stride\n");
- break;
- case 0xa:
- case 0xe:
- case 0x12:
- printf("512B stride\n");
- break;
- case 0xf:
- printf("4K stride\n");
- break;
- case 0x1f:
- printf("32MB + 256B stride\n");
- break;
- default:
- printf("no stride\n");
- }
-}
diff --git a/drivers/ram/rockchip/sdram_pctl_px30.c b/drivers/ram/rockchip/sdram_pctl_px30.c
new file mode 100644
index 0000000000..1839cebb67
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_pctl_px30.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
+{
+ writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0);
+ writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1);
+ setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+ while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+ continue;
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ continue;
+}
+
+/* rank = 1: cs0
+ * rank = 2: cs1
+ * rank = 3: cs0 & cs1
+ * note: be careful of keep mr original val
+ */
+int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
+ u32 dramtype)
+{
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ continue;
+ if (dramtype == DDR3 || dramtype == DDR4) {
+ writel((mr_num << 12) | (rank << 4) | (0 << 0),
+ pctl_base + DDR_PCTL2_MRCTRL0);
+ writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
+ } else {
+ writel((rank << 4) | (0 << 0),
+ pctl_base + DDR_PCTL2_MRCTRL0);
+ writel((mr_num << 8) | (arg & 0xff),
+ pctl_base + DDR_PCTL2_MRCTRL1);
+ }
+
+ setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+ while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+ continue;
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ continue;
+
+ return 0;
+}
+
+/*
+ * rank : 1:cs0, 2:cs1, 3:cs0&cs1
+ * vrefrate: 4500: 45%,
+ */
+int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
+ u32 dramtype)
+{
+ u32 tccd_l, value;
+ u32 dis_auto_zq = 0;
+
+ if (dramtype != DDR4 || vrefrate < 4500 ||
+ vrefrate > 9200)
+ return (-1);
+
+ tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
+ tccd_l = (tccd_l - 4) << 10;
+
+ if (vrefrate > 7500) {
+ /* range 1 */
+ value = ((vrefrate - 6000) / 65) | tccd_l;
+ } else {
+ /* range 2 */
+ value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
+ }
+
+ dis_auto_zq = pctl_dis_zqcs_aref(pctl_base);
+
+ /* enable vrefdq calibratin */
+ pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+ udelay(1);/* tvrefdqe */
+ /* write vrefdq value */
+ pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+ udelay(1);/* tvref_time */
+ pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype);
+ udelay(1);/* tvrefdqx */
+
+ pctl_rest_zqcs_aref(pctl_base, dis_auto_zq);
+
+ return 0;
+}
+
+static int upctl2_update_ref_reg(void __iomem *pctl_base)
+{
+ u32 ret;
+
+ ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
+ writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
+
+ return 0;
+}
+
+u32 pctl_dis_zqcs_aref(void __iomem *pctl_base)
+{
+ u32 dis_auto_zq = 0;
+
+ /* disable zqcs */
+ if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
+ (1ul << 31))) {
+ dis_auto_zq = 1;
+ setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+ }
+
+ /* disable auto refresh */
+ setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+ upctl2_update_ref_reg(pctl_base);
+
+ return dis_auto_zq;
+}
+
+void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq)
+{
+ /* restore zqcs */
+ if (dis_auto_zq)
+ clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+
+ /* restore auto refresh */
+ clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+ upctl2_update_ref_reg(pctl_base);
+}
+
+u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
+ struct sdram_cap_info *cap_info,
+ u32 dram_type)
+{
+ u32 tmp = 0, tmp_adr = 0, i;
+
+ for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+ if (pctl_regs->pctl[i][0] == 0) {
+ tmp = pctl_regs->pctl[i][1];/* MSTR */
+ tmp_adr = i;
+ }
+ }
+
+ tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
+
+ switch (cap_info->dbw) {
+ case 2:
+ tmp |= (3ul << 30);
+ break;
+ case 1:
+ tmp |= (2ul << 30);
+ break;
+ case 0:
+ default:
+ tmp |= (1ul << 30);
+ break;
+ }
+
+ /*
+ * If DDR3 or DDR4 MSTR.active_ranks=1,
+ * it will gate memory clock when enter power down.
+ * Force set active_ranks to 3 to workaround it.
+ */
+ if (cap_info->rank == 2 || dram_type == DDR3 ||
+ dram_type == DDR4)
+ tmp |= 3 << 24;
+ else
+ tmp |= 1 << 24;
+
+ tmp |= (2 - cap_info->bw) << 12;
+
+ pctl_regs->pctl[tmp_adr][1] = tmp;
+
+ return 0;
+}
+
+int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
+ u32 sr_idle, u32 pd_idle)
+{
+ u32 i;
+
+ for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+ writel(pctl_regs->pctl[i][1],
+ pctl_base + pctl_regs->pctl[i][0]);
+ }
+ clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
+ (0xff << 16) | 0x1f,
+ ((sr_idle & 0xff) << 16) | (pd_idle & 0x1f));
+
+ clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
+ 0xfff << 16,
+ 5 << 16);
+ /* disable zqcs */
+ setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
+
+ return 0;
+}
diff --git a/drivers/ram/rockchip/sdram_phy_px30.c b/drivers/ram/rockchip/sdram_phy_px30.c
new file mode 100644
index 0000000000..5de73770a8
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_phy_px30.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+
+static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
+{
+ u32 tmp;
+ u32 i, j;
+ u32 dqs_dll_freq;
+
+ setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
+ clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
+ for (i = 0; i < 4; i++) {
+ j = 0x26 + i * 0x10;
+ setbits_le32(PHY_REG(phy_base, j), 1 << 4);
+ clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
+ }
+
+ if (freq <= 400)
+ /* DLL bypass */
+ setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+ else
+ clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+
+ #ifdef CONFIG_ROCKCHIP_RK3328
+ dqs_dll_freq = 680;
+ #else
+ dqs_dll_freq = 801;
+ #endif
+
+ if (freq <= dqs_dll_freq)
+ tmp = 2;
+ else
+ tmp = 1;
+
+ for (i = 0; i < 4; i++) {
+ j = 0x28 + i * 0x10;
+ writel(tmp, PHY_REG(phy_base, j));
+ }
+}
+
+static void sdram_phy_set_ds_odt(void __iomem *phy_base,
+ u32 dram_type)
+{
+ u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
+ u32 i, j;
+
+ if (dram_type == DDR3) {
+ cmd_drv = PHY_DDR3_RON_RTT_34ohm;
+ clk_drv = PHY_DDR3_RON_RTT_45ohm;
+ dqs_drv = PHY_DDR3_RON_RTT_34ohm;
+ dqs_odt = PHY_DDR3_RON_RTT_225ohm;
+ } else {
+ cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+ clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
+ dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+ if (dram_type == LPDDR2)
+ dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
+ else
+ dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
+ }
+ /* DS */
+ writel(cmd_drv, PHY_REG(phy_base, 0x11));
+ clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
+ writel(clk_drv, PHY_REG(phy_base, 0x16));
+ writel(clk_drv, PHY_REG(phy_base, 0x18));
+
+ for (i = 0; i < 4; i++) {
+ j = 0x20 + i * 0x10;
+ writel(dqs_drv, PHY_REG(phy_base, j));
+ writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
+ /* ODT */
+ writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
+ writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
+ }
+}
+
+void phy_soft_reset(void __iomem *phy_base)
+{
+ clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
+ udelay(1);
+ setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
+ udelay(5);
+ setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
+ udelay(1);
+}
+
+void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
+{
+ if (bw == 2) {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+ setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+ setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+ } else if (bw == 1) {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+ } else if (bw == 0) {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+ clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+ }
+
+ phy_soft_reset(phy_base);
+}
+
+int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
+{
+ u32 ret;
+ u32 odt_val;
+ u32 i, j;
+
+ odt_val = readl(PHY_REG(phy_base, 0x2e));
+
+ for (i = 0; i < 4; i++) {
+ j = 0x20 + i * 0x10;
+ writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
+ writel(0, PHY_REG(phy_base, j + 0xe));
+ }
+
+ if (dramtype == DDR4) {
+ clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
+ clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
+ clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
+ clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
+ }
+ /* choose training cs */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
+ /* enable gate training */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
+ udelay(50);
+ ret = readl(PHY_REG(phy_base, 0xff));
+ /* disable gate training */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
+ #ifndef CONFIG_ROCKCHIP_RK3328
+ clrbits_le32(PHY_REG(phy_base, 2), 0x30);
+ #endif
+
+ if (dramtype == DDR4) {
+ clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
+ clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
+ clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
+ clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
+ }
+
+ if (ret & 0x10) {
+ ret = -1;
+ } else {
+ ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
+ ret = (ret == 0) ? 0 : -1;
+ }
+
+ for (i = 0; i < 4; i++) {
+ j = 0x20 + i * 0x10;
+ writel(odt_val, PHY_REG(phy_base, j + 0x1));
+ writel(odt_val, PHY_REG(phy_base, j + 0xe));
+ }
+ return ret;
+}
+
+void phy_cfg(void __iomem *phy_base,
+ struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
+ struct sdram_base_params *base, u32 bw)
+{
+ u32 i;
+
+ sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
+ for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
+ writel(phy_regs->phy[i][1],
+ phy_base + phy_regs->phy[i][0]);
+ }
+ if (bw == 2) {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+ } else if (bw == 1) {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+ /* disable DQS2,DQS3 tx dll for saving power */
+ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+ } else {
+ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+ /* disable DQS2,DQS3 tx dll for saving power */
+ clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+ }
+ sdram_phy_set_ds_odt(phy_base, base->dramtype);
+
+ /* deskew */
+ setbits_le32(PHY_REG(phy_base, 2), 8);
+ sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
+ &skew->a0_a1_skew[0], 15 * 4);
+ sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
+ &skew->cs0_dm0_skew[0], 44 * 4);
+ sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
+ &skew->cs1_dm0_skew[0], 44 * 4);
+}
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 9b7de4ae41..b5a0bac99b 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -2473,8 +2473,6 @@ static unsigned char calculate_stride(struct rk3399_sdram_params *params)
}
}
- sdram_print_stride(stride);
-
return stride;
}
@@ -2591,7 +2589,6 @@ static int sdram_init(struct dram_info *dram,
}
}
- sdram_print_ddr_info(cap_info, ¶ms->base);
set_memory_map(chan, channel, params);
cap_info->ddrconfig = calculate_ddrconfig(params, channel);
@@ -2601,7 +2598,6 @@ static int sdram_init(struct dram_info *dram,
if (params->base.num_channels == 0) {
printf("%s: ", __func__);
- sdram_print_dram_type(params->base.dramtype);
printf(" - %dMHz failed!\n", params->base.ddr_freq);
return -EINVAL;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 3/9] ram: px30: add sdram driver
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 1/9] ram: rockchip: rename sdram driver files Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 2/9] ram: rockchip: add common sdram driver Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 4/9] ram: rk3328: use common " Kever Yang
` (6 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
Add the sdram driver for PX30 to support ddr3, ddr4, lpddr2 and lpddr3.
The PX30 SoC support driver is suppose to follow up later.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
.../include/asm/arch-rockchip/sdram_px30.h | 212 ++++++
.../rockchip/sdram-px30-ddr3-detect-333.inc | 72 ++
.../rockchip/sdram-px30-ddr4-detect-333.inc | 75 ++
drivers/ram/rockchip/sdram-px30-ddr_skew.inc | 121 ++++
.../rockchip/sdram-px30-lpddr2-detect-333.inc | 73 ++
.../rockchip/sdram-px30-lpddr3-detect-333.inc | 74 ++
drivers/ram/rockchip/sdram_px30.c | 670 ++++++++++++++++++
7 files changed, 1297 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
create mode 100644 drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc
create mode 100644 drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc
create mode 100644 drivers/ram/rockchip/sdram-px30-ddr_skew.inc
create mode 100644 drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc
create mode 100644 drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc
create mode 100644 drivers/ram/rockchip/sdram_px30.c
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
new file mode 100644
index 0000000000..9b608a9224
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PX30_H
+#define _ASM_ARCH_SDRAM_PX30_H
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_msch.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
+
+#define SR_IDLE 93
+#define PD_IDLE 13
+
+/* PMUGRF */
+#define PMUGRF_OS_REG0 (0x200)
+#define PMUGRF_OS_REG(n) (PMUGRF_OS_REG0 + (n) * 4)
+
+/* DDR GRF */
+#define DDR_GRF_CON(n) (0 + (n) * 4)
+#define DDR_GRF_STATUS_BASE (0X100)
+#define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
+#define DDR_GRF_LP_CON (0x20)
+
+#define SPLIT_MODE_32_L16_VALID (0)
+#define SPLIT_MODE_32_H16_VALID (1)
+#define SPLIT_MODE_16_L8_VALID (2)
+#define SPLIT_MODE_16_H8_VALID (3)
+
+#define DDR_GRF_SPLIT_CON (0x8)
+#define SPLIT_MODE_MASK (0x3)
+#define SPLIT_MODE_OFFSET (9)
+#define SPLIT_BYPASS_MASK (1)
+#define SPLIT_BYPASS_OFFSET (8)
+#define SPLIT_SIZE_MASK (0xff)
+#define SPLIT_SIZE_OFFSET (0)
+
+/* CRU define */
+/* CRU_PLL_CON0 */
+#define PB(n) ((0x1 << (15 + 16)) | ((n) << 15))
+#define POSTDIV1(n) ((0x7 << (12 + 16)) | ((n) << 12))
+#define FBDIV(n) ((0xFFF << 16) | (n))
+
+/* CRU_PLL_CON1 */
+#define RSTMODE(n) ((0x1 << (15 + 16)) | ((n) << 15))
+#define RST(n) ((0x1 << (14 + 16)) | ((n) << 14))
+#define PD(n) ((0x1 << (13 + 16)) | ((n) << 13))
+#define DSMPD(n) ((0x1 << (12 + 16)) | ((n) << 12))
+#define LOCK(n) (((n) >> 10) & 0x1)
+#define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
+#define REFDIV(n) ((0x3F << 16) | (n))
+
+/* CRU_MODE */
+#define CLOCK_FROM_XIN_OSC (0)
+#define CLOCK_FROM_PLL (1)
+#define CLOCK_FROM_RTC_32K (2)
+#define DPLL_MODE(n) ((0x3 << (4 + 16)) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON1 */
+#define upctl2_psrstn_req(n) (((0x1 << 6) << 16) | ((n) << 6))
+#define upctl2_asrstn_req(n) (((0x1 << 5) << 16) | ((n) << 5))
+#define upctl2_srstn_req(n) (((0x1 << 4) << 16) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON2 */
+#define ddrphy_psrstn_req(n) (((0x1 << 2) << 16) | ((n) << 2))
+#define ddrphy_srstn_req(n) (((0x1 << 0) << 16) | ((n) << 0))
+
+/* CRU register */
+#define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
+#define CRU_MODE (0xa0)
+#define CRU_GLB_CNT_TH (0xb0)
+#define CRU_CLKSEL_CON_BASE 0x100
+#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON_BASE + ((i) * 4))
+#define CRU_CLKGATE_CON_BASE 0x200
+#define CRU_CLKGATE_CON(i) (CRU_CLKGATE_CON_BASE + ((i) * 4))
+#define CRU_CLKSFTRST_CON_BASE 0x300
+#define CRU_CLKSFTRST_CON(i) (CRU_CLKSFTRST_CON_BASE + ((i) * 4))
+
+u8 ddr_cfg_2_rbc[] = {
+ /*
+ * [6:4] max row: 13+n
+ * [3] bank(0:4bank,1:8bank)
+ * [2:0] col(10+n)
+ */
+ ((5 << 4) | (1 << 3) | 0), /* 0 */
+ ((5 << 4) | (1 << 3) | 1), /* 1 */
+ ((4 << 4) | (1 << 3) | 2), /* 2 */
+ ((3 << 4) | (1 << 3) | 3), /* 3 */
+ ((2 << 4) | (1 << 3) | 4), /* 4 */
+ ((5 << 4) | (0 << 3) | 2), /* 5 */
+ ((4 << 4) | (1 << 3) | 2), /* 6 */
+ /*((0<<3)|3),*/ /* 12 for ddr4 */
+ /*((1<<3)|1),*/ /* 13 B,C exchange for rkvdec */
+};
+
+/*
+ * for ddr4 if ddrconfig=7, upctl should set 7 and noc should
+ * set to 1 for more efficient.
+ * noc ddrconf, upctl addrmap
+ * 1 7
+ * 2 8
+ * 3 9
+ * 12 10
+ * 5 11
+ */
+u8 d4_rbc_2_d3_rbc[] = {
+ 1, /* 7 */
+ 2, /* 8 */
+ 3, /* 9 */
+ 12, /* 10 */
+ 5, /* 11 */
+};
+
+/*
+ * row higher than cs should be disabled by set to 0xf
+ * rank addrmap calculate by real cap.
+ */
+u32 addrmap[][8] = {
+ /* map0 map1, map2, map3, map4, map5
+ * map6, map7, map8
+ * -------------------------------------------------------
+ * bk2-0 col 5-2 col 9-6 col 11-10 row 11-0
+ * row 15-12 row 17-16 bg1,0
+ * -------------------------------------------------------
+ * 4,3,2 5-2 9-6 6
+ * 3,2
+ */
+ {0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
+ 0x05050505, 0x00000505, 0x3f3f}, /* 0 */
+ {0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x06060606, 0x3f3f}, /* 1 */
+ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f3f}, /* 2 */
+ {0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */
+ {0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
+ 0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
+ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000606, 0x3f3f}, /* 5 */
+ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */
+ {0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000606, 0x0600}, /* 7 */
+ {0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x0700}, /* 8 */
+ {0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x0801}, /* 9 */
+ {0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+ {0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000606, 0x3f00}, /* 11 */
+ /* when ddr4 12 map to 10, when ddr3 12 unused */
+ {0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+ {0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000606, 0x3f3f}, /* 13 */
+};
+
+struct px30_ddr_grf_regs {
+ u32 ddr_grf_con[4];
+ u32 reserved1[(0x20 - 0x10) / 4];
+ u32 ddr_grf_lp_con;
+ u32 reserved2[(0x100 - 0x24) / 4];
+ u32 ddr_grf_status[11];
+};
+
+struct msch_regs {
+ u32 coreid;
+ u32 revisionid;
+ u32 deviceconf;
+ u32 devicesize;
+ u32 ddrtiminga0;
+ u32 ddrtimingb0;
+ u32 ddrtimingc0;
+ u32 devtodev0;
+ u32 reserved1[(0x110 - 0x20) / 4];
+ u32 ddrmode;
+ u32 ddr4timing;
+ u32 reserved2[(0x1000 - 0x118) / 4];
+ u32 agingx0;
+ u32 reserved3[(0x1040 - 0x1004) / 4];
+ u32 aging0;
+ u32 aging1;
+ u32 aging2;
+ u32 aging3;
+};
+
+struct sdram_msch_timings {
+ union noc_ddrtiminga0 ddrtiminga0;
+ union noc_ddrtimingb0 ddrtimingb0;
+ union noc_ddrtimingc0 ddrtimingc0;
+ union noc_devtodev0 devtodev0;
+ union noc_ddrmode ddrmode;
+ union noc_ddr4timing ddr4timing;
+ u32 agingx0;
+};
+
+struct px30_sdram_channel {
+ struct sdram_cap_info cap_info;
+ struct sdram_msch_timings noc_timings;
+};
+
+struct px30_sdram_params {
+ struct px30_sdram_channel ch;
+ struct sdram_base_params base;
+ struct ddr_pctl_regs pctl_regs;
+ struct ddr_phy_regs phy_regs;
+ struct ddr_phy_skew *skew;
+};
+#endif
diff --git a/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc b/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc
new file mode 100644
index 0000000000..76cd8dc1a5
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr3-detect-333.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0,
+ },
+ {
+ {0x290b0609},
+ {0x08020401},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000222},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 333,
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0,
+ },
+ {
+ {
+ {0x00000000, 0x43041001}, /* MSTR */
+ {0x00000064, 0x0028003b}, /* RFSHTMG */
+ {0x000000d0, 0x00020053}, /* INIT0 */
+ {0x000000d4, 0x00020000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x03200000}, /* INIT3 */
+ {0x000000e0, 0x00000000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f012f}, /* RANKCTL */
+ {0x00000100, 0x07090b06}, /* DRAMTMG0 */
+ {0x00000104, 0x00050209}, /* DRAMTMG1 */
+ {0x00000108, 0x03030407}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x03020204}, /* DRAMTMG4 */
+ {0x00000114, 0x03030202}, /* DRAMTMG5 */
+ {0x00000120, 0x00000903}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07010001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000604}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000000a}, /* PHYREG01 */
+ {0x00000028, 0x00000006}, /* PHYREG0A */
+ {0x0000002c, 0x00000000}, /* PHYREG0B */
+ {0x00000030, 0x00000005}, /* PHYREG0C */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc b/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc
new file mode 100644
index 0000000000..f804d28393
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr4-detect-333.inc
@@ -0,0 +1,75 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xA,
+ .bk = 0x2,
+ .bw = 0x1,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x0,
+ .cs0_high16bit_row = 0x11,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0,
+ },
+ {
+ {0x4d110a08},
+ {0x06020501},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x0000022a},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 333,
+ .dramtype = DDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0,
+ },
+ {
+ {
+ {0x00000000, 0x43049010}, /* MSTR */
+ {0x00000064, 0x0028003b}, /* RFSHTMG */
+ {0x000000d0, 0x00020053}, /* INIT0 */
+ {0x000000d4, 0x00220000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x00040000}, /* INIT3 */
+ {0x000000e0, 0x00000000}, /* INIT4 */
+ {0x000000e4, 0x00110000}, /* INIT5 */
+ {0x000000e8, 0x00000420}, /* INIT6 */
+ {0x000000ec, 0x00000400}, /* INIT7 */
+ {0x000000f4, 0x000f012f}, /* RANKCTL */
+ {0x00000100, 0x09060b06}, /* DRAMTMG0 */
+ {0x00000104, 0x00020209}, /* DRAMTMG1 */
+ {0x00000108, 0x0505040a}, /* DRAMTMG2 */
+ {0x0000010c, 0x0040400c}, /* DRAMTMG3 */
+ {0x00000110, 0x05030206}, /* DRAMTMG4 */
+ {0x00000114, 0x03030202}, /* DRAMTMG5 */
+ {0x00000120, 0x03030b03}, /* DRAMTMG8 */
+ {0x00000124, 0x00020208}, /* DRAMTMG9 */
+ {0x00000180, 0x01000040}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07030003}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000604}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000000c}, /* PHYREG01 */
+ {0x00000028, 0x0000000a}, /* PHYREG0A */
+ {0x0000002c, 0x00000000}, /* PHYREG0B */
+ {0x00000030, 0x00000009}, /* PHYREG0C */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
\ No newline@end of file
diff --git a/drivers/ram/rockchip/sdram-px30-ddr_skew.inc b/drivers/ram/rockchip/sdram-px30-ddr_skew.inc
new file mode 100644
index 0000000000..f24343dda1
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-ddr_skew.inc
@@ -0,0 +1,121 @@
+ {
+ 0x77,
+ 0x88,
+ 0x79,
+ 0x79,
+ 0x87,
+ 0x97,
+ 0x87,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x87,
+ 0x88,
+ 0x87,
+ 0x87,
+ 0x77
+ },
+ {
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x69,
+ 0x9,
+ },
+ {
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x79,
+ 0x9,
+ },
+ {
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x69,
+ 0x9,
+ },
+ {
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x79,
+ 0x9,
+ },
+ {
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x69,
+ 0x9,
+ },
+ {
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x79,
+ 0x9,
+ },
+ {
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x78,
+ 0x69,
+ 0x9,
+ },
+ {
+ 0x77,
+ 0x78,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x79,
+ 0x9,
+ }
diff --git a/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc b/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc
new file mode 100644
index 0000000000..948ade483b
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-lpddr2-detect-333.inc
@@ -0,0 +1,73 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0xF,
+ .cs1_row = 0xF,
+ .cs0_high16bit_row = 0xF,
+ .cs1_high16bit_row = 0xF,
+ .ddrconfig = 0,
+ },
+ {
+ {0x2b0c070a},
+ {0x08020303},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000219},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 333,
+ .dramtype = LPDDR2,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0,
+ },
+ {
+ {
+ {0x00000000, 0x41041004}, /* MSTR */
+ {0x00000064, 0x00140023}, /* RFSHTMG */
+ {0x000000d0, 0x00220002}, /* INIT0 */
+ {0x000000d4, 0x00010000}, /* INIT1 */
+ {0x000000d8, 0x00000703}, /* INIT2 */
+ {0x000000dc, 0x00630005}, /* INIT3 */
+ {0x000000e0, 0x00010000}, /* INIT4 */
+ {0x000000e4, 0x00070003}, /* INIT5 */
+ {0x000000f4, 0x000f012f}, /* RANKCTL */
+ {0x00000100, 0x07090b07}, /* DRAMTMG0 */
+ {0x00000104, 0x0002010b}, /* DRAMTMG1 */
+ {0x00000108, 0x02040506}, /* DRAMTMG2 */
+ {0x0000010c, 0x00303000}, /* DRAMTMG3 */
+ {0x00000110, 0x04010204}, /* DRAMTMG4 */
+ {0x00000114, 0x01010303}, /* DRAMTMG5 */
+ {0x00000118, 0x02020003}, /* DRAMTMG6 */
+ {0x00000120, 0x00000303}, /* DRAMTMG8 */
+ {0x00000138, 0x00000025}, /* DRAMTMG14 */
+ {0x00000180, 0x003c000f}, /* ZQCTL0 */
+ {0x00000184, 0x00900000}, /* ZQCTL1 */
+ {0x00000190, 0x07020001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x07030718}, /* ODTCFG */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x00000009}, /* PHYREG01 */
+ {0x00000028, 0x00000007}, /* PHYREG0A */
+ {0x0000002c, 0x00000000}, /* PHYREG0B */
+ {0x00000030, 0x00000004}, /* PHYREG0C */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc b/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc
new file mode 100644
index 0000000000..f694a0e5b0
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-px30-lpddr3-detect-333.inc
@@ -0,0 +1,74 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0,
+ },
+ {
+ {0x290a060a},
+ {0x08020303},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x0000021a},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 333,
+ .dramtype = LPDDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0,
+ },
+ {
+ {
+ {0x00000000, 0x43041008}, /* MSTR */
+ {0x00000064, 0x00140023}, /* RFSHTMG */
+ {0x000000d0, 0x00220002}, /* INIT0 */
+ {0x000000d4, 0x00010000}, /* INIT1 */
+ {0x000000d8, 0x00000703}, /* INIT2 */
+ {0x000000dc, 0x00830004}, /* INIT3 */
+ {0x000000e0, 0x00010000}, /* INIT4 */
+ {0x000000e4, 0x00070003}, /* INIT5 */
+ {0x000000f4, 0x000f012f}, /* RANKCTL */
+ {0x00000100, 0x06090b07}, /* DRAMTMG0 */
+ {0x00000104, 0x0002020b}, /* DRAMTMG1 */
+ {0x00000108, 0x02030506}, /* DRAMTMG2 */
+ {0x0000010c, 0x00505000}, /* DRAMTMG3 */
+ {0x00000110, 0x03020204}, /* DRAMTMG4 */
+ {0x00000114, 0x01010303}, /* DRAMTMG5 */
+ {0x00000118, 0x02020003}, /* DRAMTMG6 */
+ {0x00000120, 0x00000303}, /* DRAMTMG8 */
+ {0x00000138, 0x00000025}, /* DRAMTMG14 */
+ {0x00000180, 0x003c000f}, /* ZQCTL0 */
+ {0x00000184, 0x00900000}, /* ZQCTL1 */
+ {0x00000190, 0x07020000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0900090c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000000b}, /* PHYREG01 */
+ {0x00000028, 0x00000006}, /* PHYREG0A */
+ {0x0000002c, 0x00000000}, /* PHYREG0B */
+ {0x00000030, 0x00000003}, /* PHYREG0C */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram_px30.c b/drivers/ram/rockchip/sdram_px30.c
new file mode 100644
index 0000000000..2f54e47e64
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_px30.c
@@ -0,0 +1,670 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_px30.h>
+
+/*
+ * Because px30 sram size is small, so need define CONFIG_TPL_TINY_FRAMEWORK
+ * to reduce TPL size when build TPL firmware.
+ */
+#ifdef CONFIG_TPL_BUILD
+#ifndef CONFIG_TPL_TINY_FRAMEWORK
+#error please defined CONFIG_TPL_TINY_FRAMEWORK for px30 !!!
+#endif
+#endif
+
+#ifdef CONFIG_TPL_BUILD
+
+struct dram_info {
+ struct ddr_pctl_regs *pctl;
+ struct ddr_phy_regs *phy;
+ struct px30_cru *cru;
+ struct msch_regs *msch;
+ struct px30_ddr_grf_regs *ddr_grf;
+ struct px30_grf *grf;
+ struct ram_info info;
+ struct px30_pmugrf *pmugrf;
+};
+
+#define PMUGRF_BASE_ADDR 0xFF010000
+#define CRU_BASE_ADDR 0xFF2B0000
+#define GRF_BASE_ADDR 0xFF140000
+#define DDRC_BASE_ADDR 0xFF600000
+#define DDR_PHY_BASE_ADDR 0xFF2A0000
+#define SERVER_MSCH0_BASE_ADDR 0xFF530000
+#define DDR_GRF_BASE_ADDR 0xff630000
+
+struct dram_info dram_info;
+
+struct px30_sdram_params sdram_configs[] = {
+#include "sdram-px30-ddr3-detect-333.inc"
+};
+
+struct ddr_phy_skew skew = {
+#include "sdram-px30-ddr_skew.inc"
+};
+
+static void rkclk_ddr_reset(struct dram_info *dram,
+ u32 ctl_srstn, u32 ctl_psrstn,
+ u32 phy_srstn, u32 phy_psrstn)
+{
+ writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) |
+ upctl2_asrstn_req(ctl_srstn),
+ &dram->cru->softrst_con[1]);
+ writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
+ &dram->cru->softrst_con[2]);
+}
+
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
+{
+ unsigned int refdiv, postdiv1, postdiv2, fbdiv;
+ int delay = 1000;
+ u32 mhz = hz / MHz;
+
+ refdiv = 1;
+ if (mhz <= 300) {
+ postdiv1 = 4;
+ postdiv2 = 2;
+ } else if (mhz <= 400) {
+ postdiv1 = 6;
+ postdiv2 = 1;
+ } else if (mhz <= 600) {
+ postdiv1 = 4;
+ postdiv2 = 1;
+ } else if (mhz <= 800) {
+ postdiv1 = 3;
+ postdiv2 = 1;
+ } else if (mhz <= 1600) {
+ postdiv1 = 2;
+ postdiv2 = 1;
+ } else {
+ postdiv1 = 1;
+ postdiv2 = 1;
+ }
+ fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
+
+ writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
+
+ writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
+ writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
+ &dram->cru->pll[1].con1);
+
+ while (delay > 0) {
+ udelay(1);
+ if (LOCK(readl(&dram->cru->pll[1].con1)))
+ break;
+ delay--;
+ }
+
+ writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
+}
+
+static void rkclk_configure_ddr(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params)
+{
+ /* for inno ddr phy need 2*freq */
+ rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHz * 2);
+}
+
+/* return ddrconfig value
+ * (-1), find ddrconfig fail
+ * other, the ddrconfig value
+ * only support cs0_row >= cs1_row
+ */
+static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 bw, die_bw, col, bank;
+ u32 i, tmp;
+ u32 ddrconf = -1;
+
+ bw = cap_info->bw;
+ die_bw = cap_info->dbw;
+ col = cap_info->col;
+ bank = cap_info->bk;
+
+ if (sdram_params->base.dramtype == DDR4) {
+ if (die_bw == 0)
+ ddrconf = 7 + bw;
+ else
+ ddrconf = 12 - bw;
+ ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7];
+ } else {
+ tmp = ((bank - 2) << 3) | (col + bw - 10);
+ for (i = 0; i < 7; i++)
+ if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) {
+ ddrconf = i;
+ break;
+ }
+ if (i > 6)
+ printascii("calculate ddrconfig error\n");
+ }
+
+ return ddrconf;
+}
+
+/*
+ * calculate controller dram address map, and setting to register.
+ * argument sdram_params->ch.ddrconf must be right value before
+ * call this function.
+ */
+static void set_ctl_address_map(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *pctl_base = dram->pctl;
+ u32 cs_pst, bg, max_row, ddrconf;
+ u32 i;
+
+ if (sdram_params->base.dramtype == DDR4)
+ /*
+ * DDR4 8bit dram BG = 2(4bank groups),
+ * 16bit dram BG = 1 (2 bank groups)
+ */
+ bg = (cap_info->dbw == 0) ? 2 : 1;
+ else
+ bg = 0;
+
+ cs_pst = cap_info->bw + cap_info->col +
+ bg + cap_info->bk + cap_info->cs0_row;
+ if (cs_pst >= 32 || cap_info->rank == 1)
+ writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0);
+ else
+ writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0);
+
+ ddrconf = cap_info->ddrconfig;
+ if (sdram_params->base.dramtype == DDR4) {
+ for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) {
+ if (d4_rbc_2_d3_rbc[i] == ddrconf) {
+ ddrconf = 7 + i;
+ break;
+ }
+ }
+ }
+
+ sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1),
+ &addrmap[ddrconf][0], 8 * 4);
+ max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf);
+
+ if (max_row < 12)
+ printascii("set addrmap fail\n");
+ /* need to disable row ahead of rank by set to 0xf */
+ for (i = 17; i > max_row; i--)
+ clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
+ ((i - 12) * 8 / 32) * 4,
+ 0xf << ((i - 12) * 8 % 32),
+ 0xf << ((i - 12) * 8 % 32));
+
+ if ((sdram_params->base.dramtype == LPDDR3 ||
+ sdram_params->base.dramtype == LPDDR2) &&
+ cap_info->row_3_4)
+ setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
+ if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2)
+ setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
+}
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+int read_mr(struct dram_info *dram, u32 rank, u32 mr_num)
+{
+ void __iomem *ddr_grf_base = dram->ddr_grf;
+
+ pctl_read_mr(dram->pctl, rank, mr_num);
+
+ return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff);
+}
+
+#define MIN(a, b) (((a) > (b)) ? (b) : (a))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+static u32 check_rd_gate(struct dram_info *dram)
+{
+ void __iomem *phy_base = dram->phy;
+
+ u32 max_val = 0;
+ u32 min_val = 0xff;
+ u32 gate[4];
+ u32 i, bw;
+
+ bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf;
+ switch (bw) {
+ case 0x1:
+ bw = 1;
+ break;
+ case 0x3:
+ bw = 2;
+ break;
+ case 0xf:
+ default:
+ bw = 4;
+ break;
+ }
+
+ for (i = 0; i < bw; i++) {
+ gate[i] = readl(PHY_REG(phy_base, 0xfb + i));
+ max_val = MAX(max_val, gate[i]);
+ min_val = MIN(min_val, gate[i]);
+ }
+
+ if (max_val > 0x80 || min_val < 0x20)
+ return -1;
+ else
+ return 0;
+}
+
+static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 dis_auto_zq = 0;
+ u32 pwrctl;
+ u32 ret;
+
+ /* disable auto low-power */
+ pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+ writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+ ret = phy_data_training(dram->phy, cs, dramtype);
+
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+ /* restore auto low-power */
+ writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
+
+ return ret;
+}
+
+static void dram_set_bw(struct dram_info *dram, u32 bw)
+{
+ phy_dram_set_bw(dram->phy, bw);
+}
+
+static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
+{
+ writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf);
+ rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14);
+}
+
+static void sdram_msch_config(struct msch_regs *msch,
+ struct sdram_msch_timings *noc_timings,
+ struct sdram_cap_info *cap_info,
+ struct sdram_base_params *base)
+{
+ u64 cs_cap[2];
+
+ cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype);
+ cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype);
+ writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
+ (((cs_cap[0] >> 20) / 64) & 0xff),
+ &msch->devicesize);
+
+ writel(noc_timings->ddrtiminga0.d32,
+ &msch->ddrtiminga0);
+ writel(noc_timings->ddrtimingb0.d32,
+ &msch->ddrtimingb0);
+ writel(noc_timings->ddrtimingc0.d32,
+ &msch->ddrtimingc0);
+ writel(noc_timings->devtodev0.d32,
+ &msch->devtodev0);
+ writel(noc_timings->ddrmode.d32, &msch->ddrmode);
+ writel(noc_timings->ddr4timing.d32,
+ &msch->ddr4timing);
+ writel(noc_timings->agingx0, &msch->agingx0);
+ writel(noc_timings->agingx0, &msch->aging0);
+ writel(noc_timings->agingx0, &msch->aging1);
+ writel(noc_timings->agingx0, &msch->aging2);
+ writel(noc_timings->agingx0, &msch->aging3);
+}
+
+static void dram_all_config(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 sys_reg2 = 0;
+ u32 sys_reg3 = 0;
+
+ set_ddrconfig(dram, cap_info->ddrconfig);
+ sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+ &sys_reg3, 0);
+ writel(sys_reg2, &dram->pmugrf->os_reg[2]);
+ writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+ sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info,
+ &sdram_params->base);
+}
+
+static void enable_low_power(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ void __iomem *ddr_grf_base = dram->ddr_grf;
+ u32 grf_lp_con;
+
+ /*
+ * bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating
+ * bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access
+ * bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating
+ * bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr
+ * bit4: grf_upctl_syscreq_cg_en = 1
+ * ungating coreclk when c_sysreq assert
+ * bit8-11: grf_auto_sr_dly = 6
+ */
+ writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]);
+
+ if (sdram_params->base.dramtype == DDR4)
+ grf_lp_con = (0x7 << 16) | (1 << 1);
+ else if (sdram_params->base.dramtype == DDR3)
+ grf_lp_con = (0x7 << 16) | (1 << 0);
+ else
+ grf_lp_con = (0x7 << 16) | (1 << 2);
+
+ /* en lpckdis_en */
+ grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
+ writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON);
+
+ /* off digit module clock when enter power down */
+ setbits_le32(PHY_REG(phy_base, 7), 1 << 7);
+
+ /* enable sr, pd */
+ if (PD_IDLE == 0)
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+ else
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+ if (SR_IDLE == 0)
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+ else
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
+}
+
+/*
+ * pre_init: 0: pre init for dram cap detect
+ * 1: detect correct cap(except cs1 row)info, than reinit
+ * 2: after reinit, we detect cs1_row, if cs1_row not equal
+ * to cs0_row and cs is in middle on ddrconf map, we need
+ * to reinit dram, than set the correct ddrconf.
+ */
+static int sdram_init_(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params, u32 pre_init)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *pctl_base = dram->pctl;
+
+ rkclk_ddr_reset(dram, 1, 1, 1, 1);
+ udelay(10);
+ /*
+ * dereset ddr phy psrstn to config pll,
+ * if using phy pll psrstn must be dereset
+ * before config pll
+ */
+ rkclk_ddr_reset(dram, 1, 1, 1, 0);
+ rkclk_configure_ddr(dram, sdram_params);
+
+ /* release phy srst to provide clk to ctrl */
+ rkclk_ddr_reset(dram, 1, 1, 0, 0);
+ udelay(10);
+ phy_soft_reset(dram->phy);
+ /* release ctrl presetn, and config ctl registers */
+ rkclk_ddr_reset(dram, 1, 0, 0, 0);
+ pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+ cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
+ set_ctl_address_map(dram, sdram_params);
+ phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew,
+ &sdram_params->base, cap_info->bw);
+
+ /* enable dfi_init_start to init phy after ctl srstn deassert */
+ setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
+
+ rkclk_ddr_reset(dram, 0, 0, 0, 0);
+ /* wait for dfi_init_done and dram init complete */
+ while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
+ continue;
+
+ if (sdram_params->base.dramtype == LPDDR3)
+ pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3);
+
+ /* do ddr gate training */
+redo_cs0_training:
+ if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+ if (pre_init != 0)
+ printascii("DTT cs0 error\n");
+ return -1;
+ }
+ if (check_rd_gate(dram)) {
+ printascii("re training cs0");
+ goto redo_cs0_training;
+ }
+
+ if (sdram_params->base.dramtype == LPDDR3) {
+ if ((read_mr(dram, 1, 8) & 0x3) != 0x3)
+ return -1;
+ } else if (sdram_params->base.dramtype == LPDDR2) {
+ if ((read_mr(dram, 1, 8) & 0x3) != 0x0)
+ return -1;
+ }
+ /* for px30: when 2cs, both 2 cs should be training */
+ if (pre_init != 0 && cap_info->rank == 2) {
+redo_cs1_training:
+ if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
+ printascii("DTT cs1 error\n");
+ return -1;
+ }
+ if (check_rd_gate(dram)) {
+ printascii("re training cs1");
+ goto redo_cs1_training;
+ }
+ }
+
+ if (sdram_params->base.dramtype == DDR4)
+ pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+ sdram_params->base.dramtype);
+
+ dram_all_config(dram, sdram_params);
+ enable_low_power(dram, sdram_params);
+
+ return 0;
+}
+
+static int dram_detect_cap(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params,
+ unsigned char channel)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+
+ /*
+ * for ddr3: ddrconf = 3
+ * for ddr4: ddrconf = 12
+ * for lpddr3: ddrconf = 3
+ * default bw = 1
+ */
+ u32 bk, bktmp;
+ u32 col, coltmp;
+ u32 rowtmp;
+ u32 cs;
+ u32 bw = 1;
+ u32 dram_type = sdram_params->base.dramtype;
+
+ if (dram_type != DDR4) {
+ /* detect col and bk for ddr3/lpddr3 */
+ coltmp = 12;
+ bktmp = 3;
+ if (dram_type == LPDDR2)
+ rowtmp = 15;
+ else
+ rowtmp = 16;
+
+ if (sdram_detect_col(cap_info, coltmp) != 0)
+ goto cap_err;
+ sdram_detect_bank(cap_info, coltmp, bktmp);
+ sdram_detect_dbw(cap_info, dram_type);
+ } else {
+ /* detect bg for ddr4 */
+ coltmp = 10;
+ bktmp = 4;
+ rowtmp = 17;
+
+ col = 10;
+ bk = 2;
+ cap_info->col = col;
+ cap_info->bk = bk;
+ sdram_detect_bg(cap_info, coltmp);
+ }
+
+ /* detect row */
+ if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
+ goto cap_err;
+
+ /* detect row_3_4 */
+ sdram_detect_row_3_4(cap_info, coltmp, bktmp);
+
+ /* bw and cs detect using data training */
+ if (data_training(dram, 1, dram_type) == 0)
+ cs = 1;
+ else
+ cs = 0;
+ cap_info->rank = cs + 1;
+
+ dram_set_bw(dram, 2);
+ if (data_training(dram, 0, dram_type) == 0)
+ bw = 2;
+ else
+ bw = 1;
+ cap_info->bw = bw;
+
+ cap_info->cs0_high16bit_row = cap_info->cs0_row;
+ if (cs) {
+ cap_info->cs1_row = cap_info->cs0_row;
+ cap_info->cs1_high16bit_row = cap_info->cs0_row;
+ } else {
+ cap_info->cs1_row = 0;
+ cap_info->cs1_high16bit_row = 0;
+ }
+
+ return 0;
+cap_err:
+ return -1;
+}
+
+void get_ddr_param(struct px30_sdram_params *sdram_params,
+ struct ddr_param *ddr_param)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 dram_type = sdram_params->base.dramtype;
+ u64 cs_cap[2];
+
+ cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dram_type);
+ cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dram_type);
+
+ if (cap_info->row_3_4) {
+ cs_cap[0] = cs_cap[0] * 3 / 4;
+ cs_cap[1] = cs_cap[1] * 3 / 4;
+ }
+
+ if (cap_info->row_3_4 && cap_info->rank == 2) {
+ ddr_param->count = 2;
+ ddr_param->para[0] = 0;
+ ddr_param->para[1] = cs_cap[0] * 4 / 3;
+ ddr_param->para[2] = cs_cap[0];
+ ddr_param->para[3] = cs_cap[1];
+ } else {
+ ddr_param->count = 1;
+ ddr_param->para[0] = 0;
+ ddr_param->para[1] = (u64)cs_cap[0] + (u64)cs_cap[1];
+ }
+}
+
+/* return: 0 = success, other = fail */
+static int sdram_init_detect(struct dram_info *dram,
+ struct px30_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 ret;
+ u32 sys_reg = 0;
+ u32 sys_reg3 = 0;
+
+ if (sdram_init_(dram, sdram_params, 0) != 0)
+ return -1;
+
+ if (dram_detect_cap(dram, sdram_params, 0) != 0)
+ return -1;
+
+ /* modify bw, cs related timing */
+ pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+ sdram_params->base.dramtype);
+ /* reinit sdram by real dram cap */
+ ret = sdram_init_(dram, sdram_params, 1);
+ if (ret != 0)
+ goto out;
+
+ /* redetect cs1 row */
+ sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+ if (cap_info->cs1_row) {
+ sys_reg = readl(&dram->pmugrf->os_reg[2]);
+ sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
+ SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+ sys_reg, sys_reg3, 0);
+ writel(sys_reg, &dram->pmugrf->os_reg[2]);
+ writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+ }
+
+ ret = sdram_detect_high_row(cap_info);
+
+out:
+ return ret;
+}
+
+struct px30_sdram_params
+ *get_default_sdram_config(void)
+{
+ sdram_configs[0].skew = &skew;
+
+ return &sdram_configs[0];
+}
+
+/* return: 0 = success, other = fail */
+int sdram_init(void)
+{
+ struct px30_sdram_params *sdram_params;
+ int ret = 0;
+ struct ddr_param ddr_param;
+
+ dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
+ dram_info.pctl = (void *)DDRC_BASE_ADDR;
+ dram_info.grf = (void *)GRF_BASE_ADDR;
+ dram_info.cru = (void *)CRU_BASE_ADDR;
+ dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR;
+ dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR;
+ dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR;
+
+ sdram_params = get_default_sdram_config();
+ ret = sdram_init_detect(&dram_info, sdram_params);
+
+ if (ret)
+ goto error;
+
+ get_ddr_param(sdram_params, &ddr_param);
+ rockchip_setup_ddr_param(&ddr_param);
+ sdram_print_ddr_info(&sdram_params->ch.cap_info,
+ &sdram_params->base, 0);
+
+ printascii("out\n");
+ return ret;
+error:
+ return (-1);
+}
+#endif /* CONFIG_TPL_BUILD */
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (2 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 3/9] ram: px30: add " Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 17:37 ` Matwey V. Kornilov
2019-10-22 8:04 ` [U-Boot] [PATCH 5/9] ram: rk3399: use common sdram driver Kever Yang
` (5 subsequent siblings)
9 siblings, 1 reply; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
RK3328 has a similar controller and phy with PX30, so we can use the
common driver for it and remove the duplicate codes.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
arch/arm/dts/rk3328-sdram-ddr3-666.dtsi | 4 +
arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi | 4 +
arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi | 4 +
.../include/asm/arch-rockchip/sdram_rk3328.h | 419 +++-------
arch/arm/mach-rockchip/Kconfig | 1 +
configs/evb-rk3328_defconfig | 2 +-
configs/rock64-rk3328_defconfig | 2 +-
drivers/ram/rockchip/Makefile | 2 +-
drivers/ram/rockchip/sdram_rk3328.c | 764 ++++--------------
9 files changed, 296 insertions(+), 906 deletions(-)
diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
index d99e7e0352..3e88ed443b 100644
--- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
@@ -14,6 +14,8 @@
0x0
0x10
0x10
+ 0x10
+ 0x10
0
0x9028b189
@@ -26,6 +28,8 @@
333
3
+ 1
+ 0
0
0x00000000
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
index cc0011cf7b..d63c761a02 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
@@ -14,6 +14,8 @@
0x0
0x10
0x10
+ 0x10
+ 0x10
0
0x98899459
@@ -27,6 +29,8 @@
800
6
1
+ 0
+ 1
0x00000000
0x43041008
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
index 62d809e833..b9d3b3b948 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
@@ -14,6 +14,8 @@
0x0
0x10
0x10
+ 0x10
+ 0x10
0
0x0c48a18a
@@ -26,6 +28,8 @@
333
6
+ 1
+ 0
0
0x00000000
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
index c747b461a1..10923505d6 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
@@ -7,197 +7,13 @@
#ifndef _ASM_ARCH_SDRAM_RK3328_H
#define _ASM_ARCH_SDRAM_RK3328_H
#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
#define SR_IDLE 93
#define PD_IDLE 13
#define SDRAM_ADDR 0x00000000
-#define PATTERN (0x5aa5f00f)
-
-/* ddr pctl registers define */
-#define DDR_PCTL2_MSTR 0x0
-#define DDR_PCTL2_STAT 0x4
-#define DDR_PCTL2_MSTR1 0x8
-#define DDR_PCTL2_MRCTRL0 0x10
-#define DDR_PCTL2_MRCTRL1 0x14
-#define DDR_PCTL2_MRSTAT 0x18
-#define DDR_PCTL2_MRCTRL2 0x1c
-#define DDR_PCTL2_DERATEEN 0x20
-#define DDR_PCTL2_DERATEINT 0x24
-#define DDR_PCTL2_PWRCTL 0x30
-#define DDR_PCTL2_PWRTMG 0x34
-#define DDR_PCTL2_HWLPCTL 0x38
-#define DDR_PCTL2_RFSHCTL0 0x50
-#define DDR_PCTL2_RFSHCTL1 0x54
-#define DDR_PCTL2_RFSHCTL2 0x58
-#define DDR_PCTL2_RFSHCTL4 0x5c
-#define DDR_PCTL2_RFSHCTL3 0x60
-#define DDR_PCTL2_RFSHTMG 0x64
-#define DDR_PCTL2_RFSHTMG1 0x68
-#define DDR_PCTL2_RFSHCTL5 0x6c
-#define DDR_PCTL2_INIT0 0xd0
-#define DDR_PCTL2_INIT1 0xd4
-#define DDR_PCTL2_INIT2 0xd8
-#define DDR_PCTL2_INIT3 0xdc
-#define DDR_PCTL2_INIT4 0xe0
-#define DDR_PCTL2_INIT5 0xe4
-#define DDR_PCTL2_INIT6 0xe8
-#define DDR_PCTL2_INIT7 0xec
-#define DDR_PCTL2_DIMMCTL 0xf0
-#define DDR_PCTL2_RANKCTL 0xf4
-#define DDR_PCTL2_CHCTL 0xfc
-#define DDR_PCTL2_DRAMTMG0 0x100
-#define DDR_PCTL2_DRAMTMG1 0x104
-#define DDR_PCTL2_DRAMTMG2 0x108
-#define DDR_PCTL2_DRAMTMG3 0x10c
-#define DDR_PCTL2_DRAMTMG4 0x110
-#define DDR_PCTL2_DRAMTMG5 0x114
-#define DDR_PCTL2_DRAMTMG6 0x118
-#define DDR_PCTL2_DRAMTMG7 0x11c
-#define DDR_PCTL2_DRAMTMG8 0x120
-#define DDR_PCTL2_DRAMTMG9 0x124
-#define DDR_PCTL2_DRAMTMG10 0x128
-#define DDR_PCTL2_DRAMTMG11 0x12c
-#define DDR_PCTL2_DRAMTMG12 0x130
-#define DDR_PCTL2_DRAMTMG13 0x134
-#define DDR_PCTL2_DRAMTMG14 0x138
-#define DDR_PCTL2_DRAMTMG15 0x13c
-#define DDR_PCTL2_DRAMTMG16 0x140
-#define DDR_PCTL2_ZQCTL0 0x180
-#define DDR_PCTL2_ZQCTL1 0x184
-#define DDR_PCTL2_ZQCTL2 0x188
-#define DDR_PCTL2_ZQSTAT 0x18c
-#define DDR_PCTL2_DFITMG0 0x190
-#define DDR_PCTL2_DFITMG1 0x194
-#define DDR_PCTL2_DFILPCFG0 0x198
-#define DDR_PCTL2_DFILPCFG1 0x19c
-#define DDR_PCTL2_DFIUPD0 0x1a0
-#define DDR_PCTL2_DFIUPD1 0x1a4
-#define DDR_PCTL2_DFIUPD2 0x1a8
-#define DDR_PCTL2_DFIMISC 0x1b0
-#define DDR_PCTL2_DFITMG2 0x1b4
-#define DDR_PCTL2_DFITMG3 0x1b8
-#define DDR_PCTL2_DFISTAT 0x1bc
-#define DDR_PCTL2_DBICTL 0x1c0
-#define DDR_PCTL2_ADDRMAP0 0x200
-#define DDR_PCTL2_ADDRMAP1 0x204
-#define DDR_PCTL2_ADDRMAP2 0x208
-#define DDR_PCTL2_ADDRMAP3 0x20c
-#define DDR_PCTL2_ADDRMAP4 0x210
-#define DDR_PCTL2_ADDRMAP5 0x214
-#define DDR_PCTL2_ADDRMAP6 0x218
-#define DDR_PCTL2_ADDRMAP7 0x21c
-#define DDR_PCTL2_ADDRMAP8 0x220
-#define DDR_PCTL2_ADDRMAP9 0x224
-#define DDR_PCTL2_ADDRMAP10 0x228
-#define DDR_PCTL2_ADDRMAP11 0x22c
-#define DDR_PCTL2_ODTCFG 0x240
-#define DDR_PCTL2_ODTMAP 0x244
-#define DDR_PCTL2_SCHED 0x250
-#define DDR_PCTL2_SCHED1 0x254
-#define DDR_PCTL2_PERFHPR1 0x25c
-#define DDR_PCTL2_PERFLPR1 0x264
-#define DDR_PCTL2_PERFWR1 0x26c
-#define DDR_PCTL2_DQMAP0 0x280
-#define DDR_PCTL2_DQMAP1 0x284
-#define DDR_PCTL2_DQMAP2 0x288
-#define DDR_PCTL2_DQMAP3 0x28c
-#define DDR_PCTL2_DQMAP4 0x290
-#define DDR_PCTL2_DQMAP5 0x294
-#define DDR_PCTL2_DBG0 0x300
-#define DDR_PCTL2_DBG1 0x304
-#define DDR_PCTL2_DBGCAM 0x308
-#define DDR_PCTL2_DBGCMD 0x30c
-#define DDR_PCTL2_DBGSTAT 0x310
-#define DDR_PCTL2_SWCTL 0x320
-#define DDR_PCTL2_SWSTAT 0x324
-#define DDR_PCTL2_POISONCFG 0x36c
-#define DDR_PCTL2_POISONSTAT 0x370
-#define DDR_PCTL2_ADVECCINDEX 0x374
-#define DDR_PCTL2_ADVECCSTAT 0x378
-#define DDR_PCTL2_PSTAT 0x3fc
-#define DDR_PCTL2_PCCFG 0x400
-#define DDR_PCTL2_PCFGR_n 0x404
-#define DDR_PCTL2_PCFGW_n 0x408
-#define DDR_PCTL2_PCTRL_n 0x490
-
-/* PCTL2_MRSTAT */
-#define MR_WR_BUSY BIT(0)
-
-/* PHY_REG0 */
-#define DIGITAL_DERESET BIT(3)
-#define ANALOG_DERESET BIT(2)
-#define DIGITAL_RESET (0 << 3)
-#define ANALOG_RESET (0 << 2)
-
-/* PHY_REG1 */
-#define PHY_DDR2 (0)
-#define PHY_LPDDR2 (1)
-#define PHY_DDR3 (2)
-#define PHY_LPDDR3 (3)
-#define PHY_DDR4 (4)
-#define PHY_BL_4 (0 << 2)
-#define PHY_BL_8 BIT(2)
-
-/* PHY_REG2 */
-#define PHY_DTT_EN BIT(0)
-#define PHY_DTT_DISB (0 << 0)
-#define PHY_WRITE_LEVELING_EN BIT(2)
-#define PHY_WRITE_LEVELING_DISB (0 << 2)
-#define PHY_SELECT_CS0 (2)
-#define PHY_SELECT_CS1 (1)
-#define PHY_SELECT_CS0_1 (0)
-#define PHY_WRITE_LEVELING_SELECTCS(n) (n << 6)
-#define PHY_DATA_TRAINING_SELECTCS(n) (n << 4)
-
-#define PHY_DDR3_RON_RTT_DISABLE (0)
-#define PHY_DDR3_RON_RTT_451ohm (1)
-#define PHY_DDR3_RON_RTT_225ohm (2)
-#define PHY_DDR3_RON_RTT_150ohm (3)
-#define PHY_DDR3_RON_RTT_112ohm (4)
-#define PHY_DDR3_RON_RTT_90ohm (5)
-#define PHY_DDR3_RON_RTT_75ohm (6)
-#define PHY_DDR3_RON_RTT_64ohm (7)
-#define PHY_DDR3_RON_RTT_56ohm (16)
-#define PHY_DDR3_RON_RTT_50ohm (17)
-#define PHY_DDR3_RON_RTT_45ohm (18)
-#define PHY_DDR3_RON_RTT_41ohm (19)
-#define PHY_DDR3_RON_RTT_37ohm (20)
-#define PHY_DDR3_RON_RTT_34ohm (21)
-#define PHY_DDR3_RON_RTT_33ohm (22)
-#define PHY_DDR3_RON_RTT_30ohm (23)
-#define PHY_DDR3_RON_RTT_28ohm (24)
-#define PHY_DDR3_RON_RTT_26ohm (25)
-#define PHY_DDR3_RON_RTT_25ohm (26)
-#define PHY_DDR3_RON_RTT_23ohm (27)
-#define PHY_DDR3_RON_RTT_22ohm (28)
-#define PHY_DDR3_RON_RTT_21ohm (29)
-#define PHY_DDR3_RON_RTT_20ohm (30)
-#define PHY_DDR3_RON_RTT_19ohm (31)
-
-#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
-#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1)
-#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2)
-#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3)
-#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4)
-#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5)
-#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6)
-#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7)
-#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16)
-#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17)
-#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18)
-#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19)
-#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20)
-#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21)
-#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22)
-#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23)
-#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24)
-#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25)
-#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26)
-#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27)
-#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28)
-#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29)
-#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30)
-#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31)
/* noc registers define */
#define DDRCONF 0x8
@@ -220,16 +36,16 @@
#define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
/* CRU_SOFTRESET_CON5 */
-#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | (n << 15))
-#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | (n << 14))
-#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | (n << 13))
-#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | (n << 12))
-#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | (n << 11))
-#define msch_srstn_req(n) (((0x1 << 9) << 16) | (n << 9))
-#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | (n << 8))
-#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | (n << 7))
+#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | ((n) << 15))
+#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | ((n) << 14))
+#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | ((n) << 13))
+#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | ((n) << 12))
+#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | ((n) << 11))
+#define msch_srstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
+#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | ((n) << 8))
+#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | ((n) << 7))
/* CRU_SOFTRESET_CON9 */
-#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | (n << 9))
+#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
/* CRU register */
#define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
@@ -256,56 +72,46 @@
#define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
#define REFDIV(n) ((0x3F << 16) | (n))
-union noc_ddrtiming {
- u32 d32;
- struct {
- unsigned acttoact:6;
- unsigned rdtomiss:6;
- unsigned wrtomiss:6;
- unsigned burstlen:3;
- unsigned rdtowr:5;
- unsigned wrtord:5;
- unsigned bwratio:1;
- } b;
-} NOC_TIMING_T;
-
-union noc_activate {
- u32 d32;
- struct {
- unsigned rrd:4;
- unsigned faw:6;
- unsigned fawbank:1;
- unsigned reserved1:21;
- } b;
-};
-
-union noc_devtodev {
- u32 d32;
- struct {
- unsigned busrdtord:2;
- unsigned busrdtowr:2;
- unsigned buswrtord:2;
- unsigned reserved2:26;
- } b;
-};
-
-union noc_ddr4timing {
- u32 d32;
- struct {
- unsigned ccdl:3;
- unsigned wrtordl:5;
- unsigned rrdl:4;
- unsigned reserved2:20;
- } b;
+u16 ddr_cfg_2_rbc[] = {
+ /*
+ * [5:4] row(13+n)
+ * [3] cs(0:0 cs, 1:2 cs)
+ * [2] bank(0:0bank,1:8bank)
+ * [1:0] col(11+n)
+ */
+ /* row, cs, bank, col */
+ ((3 << 4) | (0 << 3) | (1 << 2) | 0),
+ ((3 << 4) | (0 << 3) | (1 << 2) | 1),
+ ((2 << 4) | (0 << 3) | (1 << 2) | 2),
+ ((3 << 4) | (0 << 3) | (1 << 2) | 2),
+ ((2 << 4) | (0 << 3) | (1 << 2) | 3),
+ ((3 << 4) | (1 << 3) | (1 << 2) | 0),
+ ((3 << 4) | (1 << 3) | (1 << 2) | 1),
+ ((2 << 4) | (1 << 3) | (1 << 2) | 2),
+ ((3 << 4) | (0 << 3) | (0 << 2) | 1),
+ ((2 << 4) | (0 << 3) | (1 << 2) | 1),
};
-union noc_ddrmode {
- u32 d32;
- struct {
- unsigned autoprecharge:1;
- unsigned bwratioextended:1;
- unsigned reserved3:30;
- } b;
+u16 ddr4_cfg_2_rbc[] = {
+ /***************************
+ * [6] cs 0:0cs 1:2 cs
+ * [5:3] row(13+n)
+ * [2] cs(0:0 cs, 1:2 cs)
+ * [1] bw 0: 16bit 1:32bit
+ * [0] diebw 0:8bit 1:16bit
+ ***************************/
+ /* cs, row, cs, bw, diebw */
+ ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
+ ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
+ ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
+ ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
+ ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
+ ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
+ ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
+ ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
+ ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
+ ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
+ ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
};
u32 addrmap[21][9] = {
@@ -356,17 +162,65 @@ u32 addrmap[21][9] = {
0x07070707, 0x00000f07, 0x3f00}
};
-struct rk3328_msch_timings {
- union noc_ddrtiming ddrtiming;
- union noc_ddrmode ddrmode;
- u32 readlatency;
- union noc_activate activate;
- union noc_devtodev devtodev;
- union noc_ddr4timing ddr4timing;
- u32 agingx0;
+struct rk3328_ddr_grf_regs {
+ u32 ddr_grf_con[4];
+ u32 reserved[(0x100 - 0x10) / 4];
+ u32 ddr_grf_status[11];
};
-struct rk3328_msch_regs {
+union noc_ddrtiming {
+ u32 d32;
+ struct {
+ unsigned acttoact:6;
+ unsigned rdtomiss:6;
+ unsigned wrtomiss:6;
+ unsigned burstlen:3;
+ unsigned rdtowr:5;
+ unsigned wrtord:5;
+ unsigned bwratio:1;
+ } b;
+};
+
+union noc_activate {
+ u32 d32;
+ struct {
+ unsigned rrd:4;
+ unsigned faw:6;
+ unsigned fawbank:1;
+ unsigned reserved1:21;
+ } b;
+};
+
+union noc_devtodev {
+ u32 d32;
+ struct {
+ unsigned busrdtord:2;
+ unsigned busrdtowr:2;
+ unsigned buswrtord:2;
+ unsigned reserved2:26;
+ } b;
+};
+
+union noc_ddr4timing {
+ u32 d32;
+ struct {
+ unsigned ccdl:3;
+ unsigned wrtordl:5;
+ unsigned rrdl:4;
+ unsigned reserved2:20;
+ } b;
+};
+
+union noc_ddrmode {
+ u32 d32;
+ struct {
+ unsigned autoprecharge:1;
+ unsigned bwratioextended:1;
+ unsigned reserved3:30;
+ } b;
+};
+
+struct msch_regs {
u32 coreid;
u32 revisionid;
u32 ddrconf;
@@ -385,58 +239,27 @@ struct rk3328_msch_regs {
u32 ddr4_timing;
};
-struct rk3328_ddr_grf_regs {
- u32 ddr_grf_con[4];
- u32 reserved[(0x100 - 0x10) / 4];
- u32 ddr_grf_status[11];
-};
-
-struct rk3328_ddr_pctl_regs {
- u32 pctl[30][2];
-};
-
-struct rk3328_ddr_phy_regs {
- u32 phy[5][2];
-};
-
-struct rk3328_ddr_skew {
- u32 a0_a1_skew[15];
- u32 cs0_dm0_skew[11];
- u32 cs0_dm1_skew[11];
- u32 cs0_dm2_skew[11];
- u32 cs0_dm3_skew[11];
- u32 cs1_dm0_skew[11];
- u32 cs1_dm1_skew[11];
- u32 cs1_dm2_skew[11];
- u32 cs1_dm3_skew[11];
+struct sdram_msch_timings {
+ union noc_ddrtiming ddrtiming;
+ union noc_ddrmode ddrmode;
+ u32 readlatency;
+ union noc_activate activate;
+ union noc_devtodev devtodev;
+ union noc_ddr4timing ddr4timing;
+ u32 agingx0;
};
struct rk3328_sdram_channel {
- unsigned int rank;
- unsigned int col;
- /* 3:8bank, 2:4bank */
- unsigned int bk;
- /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int bw;
- /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
- unsigned int dbw;
- unsigned int row_3_4;
- unsigned int cs0_row;
- unsigned int cs1_row;
- unsigned int ddrconfig;
- struct rk3328_msch_timings noc_timings;
+ struct sdram_cap_info cap_info;
+ struct sdram_msch_timings noc_timings;
};
struct rk3328_sdram_params {
struct rk3328_sdram_channel ch;
- unsigned int ddr_freq;
- unsigned int dramtype;
- unsigned int odt;
- struct rk3328_ddr_pctl_regs pctl_regs;
- struct rk3328_ddr_phy_regs phy_regs;
- struct rk3328_ddr_skew skew;
+ struct sdram_base_params base;
+ struct ddr_pctl_regs pctl_regs;
+ struct ddr_phy_regs phy_regs;
+ struct ddr_phy_skew skew;
};
-#define PHY_REG(base, n) (base + 4 * (n))
-
#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index f5a80b4f0c..5f1ad51cac 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -115,6 +115,7 @@ config ROCKCHIP_RK3328
select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
select TPL_NEEDS_SEPARATE_STACK if TPL
imply ROCKCHIP_COMMON_BOARD
+ imply ROCKCHIP_SDRAM_COMMON
imply SPL_ROCKCHIP_COMMON_BOARD
imply SPL_SERIAL_SUPPORT
imply TPL_SERIAL_SUPPORT
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 37610774c1..fdabee842d 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -46,7 +46,6 @@ CONFIG_SPL_SYSCON=y
CONFIG_TPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
CONFIG_FASTBOOT_BUF_ADDR=0x800800
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -77,6 +76,7 @@ CONFIG_DEBUG_UART_SHIFT=2
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
index 3ab0af1158..0fb4b42c6e 100644
--- a/configs/rock64-rk3328_defconfig
+++ b/configs/rock64-rk3328_defconfig
@@ -49,7 +49,6 @@ CONFIG_SPL_SYSCON=y
CONFIG_TPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
CONFIG_FASTBOOT_BUF_ADDR=0x800800
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -79,6 +78,7 @@ CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 3d4f2f4ebf..3f19fa09a5 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -9,5 +9,5 @@ obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
-obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3328) += sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index e7919337ea..72ae7555bc 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -20,11 +20,11 @@
struct dram_info {
#ifdef CONFIG_TPL_BUILD
- struct rk3328_ddr_pctl_regs *pctl;
- struct rk3328_ddr_phy_regs *phy;
+ struct ddr_pctl_regs *pctl;
+ struct ddr_phy_regs *phy;
struct clk ddr_clk;
struct rk3328_cru *cru;
- struct rk3328_msch_regs *msch;
+ struct msch_regs *msch;
struct rk3328_ddr_grf_regs *ddr_grf;
#endif
struct ram_info info;
@@ -71,10 +71,11 @@ static void rkclk_ddr_reset(struct dram_info *dram,
writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
}
-static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
{
unsigned int refdiv, postdiv1, postdiv2, fbdiv;
int delay = 1000;
+ u32 mhz = hz / MHZ;
refdiv = 1;
if (mhz <= 300) {
@@ -122,52 +123,7 @@ static void rkclk_configure_ddr(struct dram_info *dram,
clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
/* for inno ddr phy need 2*freq */
- rkclk_set_dpll(dram, sdram_params->ddr_freq * 2);
-}
-
-static void phy_soft_reset(struct dram_info *dram)
-{
- void __iomem *phy_base = dram->phy;
-
- clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
- udelay(1);
- setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
- udelay(5);
- setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
- udelay(1);
-}
-
-static int pctl_cfg(struct dram_info *dram,
- struct rk3328_sdram_params *sdram_params)
-{
- u32 i;
- void __iomem *pctl_base = dram->pctl;
-
- for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
- writel(sdram_params->pctl_regs.pctl[i][1],
- pctl_base + sdram_params->pctl_regs.pctl[i][0]);
- }
- clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
- (0xff << 16) | 0x1f,
- ((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
- /*
- * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
- * hw_lp_idle_x32=1
- */
- if (sdram_params->dramtype == LPDDR3) {
- setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
- clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
- 0xf << 4,
- 2 << 4);
- }
- clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
- 0xfff << 16,
- 1 << 16);
- /* disable zqcs */
- setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
- setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
-
- return 0;
+ rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ * 2);
}
/* return ddrconfig value
@@ -175,62 +131,39 @@ static int pctl_cfg(struct dram_info *dram,
* other, the ddrconfig value
* only support cs0_row >= cs1_row
*/
-static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
+static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
{
- static const u16 ddr_cfg_2_rbc[] = {
- /***************************
- * [5:4] row(13+n)
- * [3] cs(0:0 cs, 1:2 cs)
- * [2] bank(0:0bank,1:8bank)
- * [1:0] col(11+n)
- ****************************/
- /* row, cs, bank, col */
- ((3 << 4) | (0 << 3) | (1 << 2) | 0),
- ((3 << 4) | (0 << 3) | (1 << 2) | 1),
- ((2 << 4) | (0 << 3) | (1 << 2) | 2),
- ((3 << 4) | (0 << 3) | (1 << 2) | 2),
- ((2 << 4) | (0 << 3) | (1 << 2) | 3),
- ((3 << 4) | (1 << 3) | (1 << 2) | 0),
- ((3 << 4) | (1 << 3) | (1 << 2) | 1),
- ((2 << 4) | (1 << 3) | (1 << 2) | 2),
- ((3 << 4) | (0 << 3) | (0 << 2) | 1),
- ((2 << 4) | (0 << 3) | (1 << 2) | 1),
- };
-
- static const u16 ddr4_cfg_2_rbc[] = {
- /***************************
- * [6] cs 0:0cs 1:2 cs
- * [5:3] row(13+n)
- * [2] cs(0:0 cs, 1:2 cs)
- * [1] bw 0: 16bit 1:32bit
- * [0] diebw 0:8bit 1:16bit
- ***************************/
- /* cs, row, cs, bw, diebw */
- ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
- ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
- ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
- ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
- ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
- ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
- ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
- ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
- ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
- ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
- ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
- };
-
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
u32 cs, bw, die_bw, col, row, bank;
+ u32 cs1_row;
u32 i, tmp;
u32 ddrconf = -1;
- cs = sdram_ch.rank;
- bw = sdram_ch.bw;
- die_bw = sdram_ch.dbw;
- col = sdram_ch.col;
- row = sdram_ch.cs0_row;
- bank = sdram_ch.bk;
+ cs = cap_info->rank;
+ bw = cap_info->bw;
+ die_bw = cap_info->dbw;
+ col = cap_info->col;
+ row = cap_info->cs0_row;
+ cs1_row = cap_info->cs1_row;
+ bank = cap_info->bk;
+
+ if (sdram_params->base.dramtype == DDR4) {
+ /* when DDR_TEST, CS always at MSB position for easy test */
+ if (cs == 2 && row == cs1_row) {
+ /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
+ tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
+ die_bw;
+ for (i = 17; i < 21; i++) {
+ if (((tmp & 0x7) ==
+ (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
+ ((tmp & 0x3c) <=
+ (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
+ ddrconf = i;
+ goto out;
+ }
+ }
+ }
- if (sdram_params->dramtype == DDR4) {
tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
for (i = 10; i < 17; i++) {
if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
@@ -246,6 +179,18 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
goto out;
}
+ /* when DDR_TEST, CS always@MSB position for easy test */
+ if (cs == 2 && row == cs1_row) {
+ /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
+ for (i = 5; i < 8; i++) {
+ if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
+ 0x3)) {
+ ddrconf = i;
+ goto out;
+ }
+ }
+ }
+
tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
for (i = 0; i < 5; i++)
if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
@@ -257,23 +202,11 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
out:
if (ddrconf > 20)
- printf("calculate_ddrconfig error\n");
+ printf("calculate ddrconfig error\n");
return ddrconf;
}
-/* n: Unit bytes */
-static void copy_to_reg(u32 *dest, u32 *src, u32 n)
-{
- int i;
-
- for (i = 0; i < n / sizeof(u32); i++) {
- writel(*src, dest);
- src++;
- dest++;
- }
-}
-
/*******
* calculate controller dram address map, and setting to register.
* argument sdram_ch.ddrconf must be right value before
@@ -282,273 +215,42 @@ static void copy_to_reg(u32 *dest, u32 *src, u32 n)
static void set_ctl_address_map(struct dram_info *dram,
struct rk3328_sdram_params *sdram_params)
{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
void __iomem *pctl_base = dram->pctl;
- copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
- &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
- if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
+ sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
+ &addrmap[cap_info->ddrconfig][0], 9 * 4);
+ if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
- if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
+ if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
- if (sdram_ch.rank == 1)
+ if (cap_info->rank == 1)
clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
}
-static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
-{
- u32 tmp;
- void __iomem *phy_base = dram->phy;
-
- setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
- clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
- setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
- clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
- setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
- clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
- setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
- clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
- setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
- clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
-
- if (freq <= 400)
- /* DLL bypass */
- setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
- else
- clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
- if (freq <= 680)
- tmp = 2;
- else
- tmp = 1;
- writel(tmp, PHY_REG(phy_base, 0x28));
- writel(tmp, PHY_REG(phy_base, 0x38));
- writel(tmp, PHY_REG(phy_base, 0x48));
- writel(tmp, PHY_REG(phy_base, 0x58));
-}
-
-static void set_ds_odt(struct dram_info *dram,
- struct rk3328_sdram_params *sdram_params)
-{
- u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
- void __iomem *phy_base = dram->phy;
-
- if (sdram_params->dramtype == DDR3) {
- cmd_drv = PHY_DDR3_RON_RTT_34ohm;
- clk_drv = PHY_DDR3_RON_RTT_45ohm;
- dqs_drv = PHY_DDR3_RON_RTT_34ohm;
- dqs_odt = PHY_DDR3_RON_RTT_225ohm;
- } else {
- cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
- clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
- dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
- dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
- }
- /* DS */
- writel(cmd_drv, PHY_REG(phy_base, 0x11));
- clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
- writel(clk_drv, PHY_REG(phy_base, 0x16));
- writel(clk_drv, PHY_REG(phy_base, 0x18));
- writel(dqs_drv, PHY_REG(phy_base, 0x20));
- writel(dqs_drv, PHY_REG(phy_base, 0x2f));
- writel(dqs_drv, PHY_REG(phy_base, 0x30));
- writel(dqs_drv, PHY_REG(phy_base, 0x3f));
- writel(dqs_drv, PHY_REG(phy_base, 0x40));
- writel(dqs_drv, PHY_REG(phy_base, 0x4f));
- writel(dqs_drv, PHY_REG(phy_base, 0x50));
- writel(dqs_drv, PHY_REG(phy_base, 0x5f));
- /* ODT */
- writel(dqs_odt, PHY_REG(phy_base, 0x21));
- writel(dqs_odt, PHY_REG(phy_base, 0x2e));
- writel(dqs_odt, PHY_REG(phy_base, 0x31));
- writel(dqs_odt, PHY_REG(phy_base, 0x3e));
- writel(dqs_odt, PHY_REG(phy_base, 0x41));
- writel(dqs_odt, PHY_REG(phy_base, 0x4e));
- writel(dqs_odt, PHY_REG(phy_base, 0x51));
- writel(dqs_odt, PHY_REG(phy_base, 0x5e));
-}
-
-static void phy_cfg(struct dram_info *dram,
- struct rk3328_sdram_params *sdram_params)
-{
- u32 i;
- void __iomem *phy_base = dram->phy;
-
- phy_dll_bypass_set(dram, sdram_params->ddr_freq);
- for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
- writel(sdram_params->phy_regs.phy[i][1],
- phy_base + sdram_params->phy_regs.phy[i][0]);
- }
- if (sdram_ch.bw == 2) {
- clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
- } else {
- clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
- /* disable DQS2,DQS3 tx dll for saving power */
- clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
- clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
- }
- set_ds_odt(dram, sdram_params);
- /* deskew */
- setbits_le32(PHY_REG(phy_base, 2), 8);
- copy_to_reg(PHY_REG(phy_base, 0xb0),
- &sdram_params->skew.a0_a1_skew[0], 15 * 4);
- copy_to_reg(PHY_REG(phy_base, 0x70),
- &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
- copy_to_reg(PHY_REG(phy_base, 0xc0),
- &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
-}
-
-static int update_refresh_reg(struct dram_info *dram)
-{
- void __iomem *pctl_base = dram->pctl;
- u32 ret;
-
- ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
- writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
-
- return 0;
-}
-
static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
-{
- u32 ret;
- u32 dis_auto_zq = 0;
- void __iomem *pctl_base = dram->pctl;
- void __iomem *phy_base = dram->phy;
-
- /* disable zqcs */
- if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
- (1ul << 31))) {
- dis_auto_zq = 1;
- setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
- }
- /* disable auto refresh */
- setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
- update_refresh_reg(dram);
-
- if (dramtype == DDR4) {
- clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
- clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
- clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
- clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
- }
- /* choose training cs */
- clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
- /* enable gate training */
- clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
- udelay(50);
- ret = readl(PHY_REG(phy_base, 0xff));
- /* disable gate training */
- clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
- /* restore zqcs */
- if (dis_auto_zq)
- clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
- /* restore auto refresh */
- clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
- update_refresh_reg(dram);
-
- if (dramtype == DDR4) {
- clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
- clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
- clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
- clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
- }
-
- if (ret & 0x10) {
- ret = -1;
- } else {
- ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
- ret = (ret == 0) ? 0 : -1;
- }
- return ret;
-}
-
-/* rank = 1: cs0
- * rank = 2: cs1
- * rank = 3: cs0 & cs1
- * note: be careful of keep mr original val
- */
-static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 arg,
- u32 dramtype)
{
void __iomem *pctl_base = dram->pctl;
-
- while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
- continue;
- if (dramtype == DDR3 || dramtype == DDR4) {
- writel((mr_num << 12) | (rank << 4) | (0 << 0),
- pctl_base + DDR_PCTL2_MRCTRL0);
- writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
- } else {
- writel((rank << 4) | (0 << 0),
- pctl_base + DDR_PCTL2_MRCTRL0);
- writel((mr_num << 8) | (arg & 0xff),
- pctl_base + DDR_PCTL2_MRCTRL1);
- }
-
- setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
- while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
- continue;
- while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
- continue;
-
- return 0;
-}
-
-/*
- * rank : 1:cs0, 2:cs1, 3:cs0&cs1
- * vrefrate: 4500: 45%,
- */
-static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
- u32 dramtype)
-{
- u32 tccd_l, value;
u32 dis_auto_zq = 0;
- void __iomem *pctl_base = dram->pctl;
+ u32 pwrctl;
+ u32 ret;
- if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
- return -1;
+ /* disable auto low-power */
+ pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+ writel(0, pctl_base + DDR_PCTL2_PWRCTL);
- tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
- tccd_l = (tccd_l - 4) << 10;
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
- if (vrefrate > 7500) {
- /* range 1 */
- value = ((vrefrate - 6000) / 65) | tccd_l;
- } else {
- /* range 2 */
- value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
- }
+ ret = phy_data_training(dram->phy, cs, dramtype);
- /* disable zqcs */
- if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
- (1ul << 31))) {
- dis_auto_zq = 1;
- setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
- }
- /* disable auto refresh */
- setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
- update_refresh_reg(dram);
-
- /* enable vrefdq calibratin */
- write_mr(dram, rank, 6, value | (1 << 7), dramtype);
- udelay(1);/* tvrefdqe */
- /* write vrefdq value */
- write_mr(dram, rank, 6, value | (1 << 7), dramtype);
- udelay(1);/* tvref_time */
- write_mr(dram, rank, 6, value | (0 << 7), dramtype);
- udelay(1);/* tvrefdqx */
-
- /* restore zqcs */
- if (dis_auto_zq)
- clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
- /* restore auto refresh */
- clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
- update_refresh_reg(dram);
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
- return 0;
-}
+ /* restore auto low-power */
+ writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
-#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
+ return ret;
+}
static void rx_deskew_switch_adjust(struct dram_info *dram)
{
@@ -557,7 +259,7 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
void __iomem *phy_base = dram->phy;
for (i = 0; i < 4; i++)
- gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
+ gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
deskew_val = (gate_val >> 3) + 1;
deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
@@ -566,8 +268,6 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
(deskew_val & 0x1c) << 2);
}
-#undef _MAX_
-
static void tx_deskew_switch_adjust(struct dram_info *dram)
{
void __iomem *phy_base = dram->phy;
@@ -580,40 +280,39 @@ static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
writel(ddrconfig, &dram->msch->ddrconf);
}
+static void sdram_msch_config(struct msch_regs *msch,
+ struct sdram_msch_timings *noc_timings)
+{
+ writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
+
+ writel(noc_timings->ddrmode.d32, &msch->ddrmode);
+ writel(noc_timings->readlatency, &msch->readlatency);
+
+ writel(noc_timings->activate.d32, &msch->activate);
+ writel(noc_timings->devtodev.d32, &msch->devtodev);
+ writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
+ writel(noc_timings->agingx0, &msch->aging0);
+ writel(noc_timings->agingx0, &msch->aging1);
+ writel(noc_timings->agingx0, &msch->aging2);
+ writel(noc_timings->agingx0, &msch->aging3);
+ writel(noc_timings->agingx0, &msch->aging4);
+ writel(noc_timings->agingx0, &msch->aging5);
+}
+
static void dram_all_config(struct dram_info *dram,
struct rk3328_sdram_params *sdram_params)
{
- u32 sys_reg = 0, tmp = 0;
-
- set_ddrconfig(dram, sdram_ch.ddrconfig);
-
- sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
- sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
- sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
- sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
- sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
- SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
- if (sdram_ch.cs1_row)
- SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
- sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
- sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
-
- writel(sys_reg, &dram->grf->os_reg[2]);
-
- writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
-
- writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
- writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
-
- writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
- writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
- writel(sdram_ch.noc_timings.ddr4timing.d32, &dram->msch->ddr4_timing);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
- writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 sys_reg2 = 0;
+ u32 sys_reg3 = 0;
+
+ set_ddrconfig(dram, cap_info->ddrconfig);
+ sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+ &sys_reg3, 0);
+ writel(sys_reg2, &dram->grf->os_reg[2]);
+ writel(sys_reg3, &dram->grf->os_reg[3]);
+
+ sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
}
static void enable_low_power(struct dram_info *dram,
@@ -641,6 +340,7 @@ static void enable_low_power(struct dram_info *dram,
static int sdram_init(struct dram_info *dram,
struct rk3328_sdram_params *sdram_params, u32 pre_init)
{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
void __iomem *pctl_base = dram->pctl;
rkclk_ddr_reset(dram, 1, 1, 1, 1);
@@ -652,30 +352,18 @@ static int sdram_init(struct dram_info *dram,
*/
rkclk_ddr_reset(dram, 1, 1, 1, 0);
rkclk_configure_ddr(dram, sdram_params);
- if (pre_init == 0) {
- switch (sdram_params->dramtype) {
- case DDR3:
- printf("DDR3\n");
- break;
- case DDR4:
- printf("DDR4\n");
- break;
- case LPDDR3:
- default:
- printf("LPDDR3\n");
- break;
- }
- }
+
/* release phy srst to provide clk to ctrl */
rkclk_ddr_reset(dram, 1, 1, 0, 0);
udelay(10);
- phy_soft_reset(dram);
+ phy_soft_reset(dram->phy);
/* release ctrl presetn, and config ctl registers */
rkclk_ddr_reset(dram, 1, 0, 0, 0);
- pctl_cfg(dram, sdram_params);
- sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
+ pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+ cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
set_ctl_address_map(dram, sdram_params);
- phy_cfg(dram, sdram_params);
+ phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
+ &sdram_params->base, cap_info->bw);
/* enable dfi_init_start to init phy after ctl srstn deassert */
setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
@@ -685,13 +373,18 @@ static int sdram_init(struct dram_info *dram,
continue;
/* do ddr gate training */
- if (data_training(dram, 0, sdram_params->dramtype) != 0) {
+ if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+ printf("data training error\n");
+ return -1;
+ }
+ if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
printf("data training error\n");
return -1;
}
- if (sdram_params->dramtype == DDR4)
- write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
+ if (sdram_params->base.dramtype == DDR4)
+ pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+ sdram_params->base.dramtype);
if (pre_init == 0) {
rx_deskew_switch_adjust(dram);
@@ -708,7 +401,7 @@ static u64 dram_detect_cap(struct dram_info *dram,
struct rk3328_sdram_params *sdram_params,
unsigned char channel)
{
- void __iomem *pctl_base = dram->pctl;
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
/*
* for ddr3: ddrconf = 3
@@ -718,14 +411,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
*/
u32 bk, bktmp;
u32 col, coltmp;
- u32 row, rowtmp, row_3_4;
- void __iomem *test_addr, *test_addr1;
- u32 dbw;
+ u32 rowtmp;
u32 cs;
u32 bw = 1;
- u64 cap = 0;
- u32 dram_type = sdram_params->dramtype;
- u32 pwrctl;
+ u32 dram_type = sdram_params->base.dramtype;
if (dram_type != DDR4) {
/* detect col and bk for ddr3/lpddr3 */
@@ -733,33 +422,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
bktmp = 3;
rowtmp = 16;
- for (col = coltmp; col >= 9; col -= 1) {
- writel(0, SDRAM_ADDR);
- test_addr = (void __iomem *)(SDRAM_ADDR +
- (1ul << (col + bw - 1ul)));
- writel(PATTERN, test_addr);
- if ((readl(test_addr) == PATTERN) &&
- (readl(SDRAM_ADDR) == 0))
- break;
- }
- if (col == 8) {
- printf("col error\n");
+ if (sdram_detect_col(cap_info, coltmp) != 0)
goto cap_err;
- }
-
- test_addr = (void __iomem *)(SDRAM_ADDR +
- (1ul << (coltmp + bktmp + bw - 1ul)));
- writel(0, SDRAM_ADDR);
- writel(PATTERN, test_addr);
- if ((readl(test_addr) == PATTERN) &&
- (readl(SDRAM_ADDR) == 0))
- bk = 3;
- else
- bk = 2;
- if (dram_type == LPDDR3)
- dbw = 2;
- else
- dbw = 1;
+ sdram_detect_bank(cap_info, coltmp, bktmp);
+ sdram_detect_dbw(cap_info, dram_type);
} else {
/* detect bg for ddr4 */
coltmp = 10;
@@ -768,178 +434,49 @@ static u64 dram_detect_cap(struct dram_info *dram,
col = 10;
bk = 2;
- test_addr = (void __iomem *)(SDRAM_ADDR +
- (1ul << (coltmp + bw + 1ul)));
- writel(0, SDRAM_ADDR);
- writel(PATTERN, test_addr);
- if ((readl(test_addr) == PATTERN) &&
- (readl(SDRAM_ADDR) == 0))
- dbw = 0;
- else
- dbw = 1;
+ cap_info->col = col;
+ cap_info->bk = bk;
+ sdram_detect_bg(cap_info, coltmp);
}
+
/* detect row */
- for (row = rowtmp; row > 12; row--) {
- writel(0, SDRAM_ADDR);
- test_addr = (void __iomem *)(SDRAM_ADDR +
- (1ul << (row + bktmp + coltmp + bw - 1ul)));
- writel(PATTERN, test_addr);
- if ((readl(test_addr) == PATTERN) &&
- (readl(SDRAM_ADDR) == 0))
- break;
- }
- if (row == 12) {
- printf("row error");
+ if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
goto cap_err;
- }
- /* detect row_3_4 */
- test_addr = SDRAM_ADDR;
- test_addr1 = (void __iomem *)(SDRAM_ADDR +
- (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
-
- writel(0, test_addr);
- writel(PATTERN, test_addr1);
- if ((readl(test_addr) == 0) &&
- (readl(test_addr1) == PATTERN))
- row_3_4 = 0;
- else
- row_3_4 = 1;
- /* disable auto low-power */
- pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
- writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+ /* detect row_3_4 */
+ sdram_detect_row_3_4(cap_info, coltmp, bktmp);
- /* bw and cs detect using phy read gate training */
+ /* bw and cs detect using data training */
if (data_training(dram, 1, dram_type) == 0)
cs = 1;
else
cs = 0;
+ cap_info->rank = cs + 1;
bw = 2;
+ cap_info->bw = bw;
- /* restore auto low-power */
- writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
-
- sdram_ch.rank = cs + 1;
- sdram_ch.col = col;
- sdram_ch.bk = bk;
- sdram_ch.dbw = dbw;
- sdram_ch.bw = bw;
- sdram_ch.cs0_row = row;
- if (cs)
- sdram_ch.cs1_row = row;
- else
- sdram_ch.cs1_row = 0;
- sdram_ch.row_3_4 = row_3_4;
-
- if (dram_type == DDR4)
- cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) + bw);
- else
- cap = 1llu << (cs + row + bk + col + bw);
-
- return cap;
-
-cap_err:
- return 0;
-}
-
-static u32 remodify_sdram_params(struct rk3328_sdram_params *sdram_params)
-{
- u32 tmp = 0, tmp_adr = 0, i;
-
- for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
- if (sdram_params->pctl_regs.pctl[i][0] == 0) {
- tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
- tmp_adr = i;
- }
- }
-
- tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
-
- switch (sdram_ch.dbw) {
- case 2:
- tmp |= (3ul << 30);
- break;
- case 1:
- tmp |= (2ul << 30);
- break;
- case 0:
- default:
- tmp |= (1ul << 30);
- break;
+ cap_info->cs0_high16bit_row = cap_info->cs0_row;
+ if (cs) {
+ cap_info->cs1_row = cap_info->cs0_row;
+ cap_info->cs1_high16bit_row = cap_info->cs0_row;
+ } else {
+ cap_info->cs1_row = 0;
+ cap_info->cs1_high16bit_row = 0;
}
- if (sdram_ch.rank == 2)
- tmp |= 3 << 24;
- else
- tmp |= 1 << 24;
-
- tmp |= (2 - sdram_ch.bw) << 12;
-
- sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
-
- if (sdram_ch.bw == 2)
- sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
- else
- sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
-
return 0;
-}
-
-static int dram_detect_cs1_row(struct rk3328_sdram_params *sdram_params,
- unsigned char channel)
-{
- u32 ret = 0;
- u32 cs1_bit;
- void __iomem *test_addr, *cs1_addr;
- u32 row, bktmp, coltmp, bw;
- u32 ddrconf = sdram_ch.ddrconfig;
-
- if (sdram_ch.rank == 2) {
- cs1_bit = addrmap[ddrconf][0] + 8;
-
- if (cs1_bit > 31)
- goto out;
-
- cs1_addr = (void __iomem *)(1ul << cs1_bit);
- if (cs1_bit < 20)
- cs1_bit = 1;
- else
- cs1_bit = 0;
-
- if (sdram_params->dramtype == DDR4) {
- if (sdram_ch.dbw == 0)
- bktmp = sdram_ch.bk + 2;
- else
- bktmp = sdram_ch.bk + 1;
- } else {
- bktmp = sdram_ch.bk;
- }
- bw = sdram_ch.bw;
- coltmp = sdram_ch.col;
-
- /* detect cs1 row */
- for (row = sdram_ch.cs0_row; row > 12; row--) {
- test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
- (1ul << (row + cs1_bit + bktmp +
- coltmp + bw - 1ul)));
- writel(0, SDRAM_ADDR + cs1_addr);
- writel(PATTERN, test_addr);
- if ((readl(test_addr) == PATTERN) &&
- (readl(SDRAM_ADDR + cs1_addr) == 0)) {
- ret = row;
- break;
- }
- }
- }
-
-out:
- return ret;
+cap_err:
+ return -1;
}
static int sdram_init_detect(struct dram_info *dram,
struct rk3328_sdram_params *sdram_params)
{
+ u32 sys_reg = 0;
+ u32 sys_reg3 = 0;
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+
debug("Starting SDRAM initialization...\n");
memcpy(&sdram_ch, &sdram_params->ch,
@@ -949,13 +486,30 @@ static int sdram_init_detect(struct dram_info *dram,
dram_detect_cap(dram, sdram_params, 0);
/* modify bw, cs related timing */
- remodify_sdram_params(sdram_params);
+ pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+ sdram_params->base.dramtype);
+
+ if (cap_info->bw == 2)
+ sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
+ else
+ sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
+
/* reinit sdram by real dram cap */
sdram_init(dram, sdram_params, 0);
/* redetect cs1 row */
- sdram_ch.cs1_row =
- dram_detect_cs1_row(sdram_params, 0);
+ sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+ if (cap_info->cs1_row) {
+ sys_reg = readl(&dram->grf->os_reg[2]);
+ sys_reg3 = readl(&dram->grf->os_reg[3]);
+ SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+ sys_reg, sys_reg3, 0);
+ writel(sys_reg, &dram->grf->os_reg[2]);
+ writel(sys_reg3, &dram->grf->os_reg[3]);
+ }
+
+ sdram_print_ddr_info(&sdram_params->ch.cap_info,
+ &sdram_params->base, 0);
return 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver
2019-10-22 8:04 ` [U-Boot] [PATCH 4/9] ram: rk3328: use common " Kever Yang
@ 2019-10-22 17:37 ` Matwey V. Kornilov
2019-10-23 8:49 ` [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver【请注意,邮件由u-boot-bounces@lists.denx.de代发】 Kever Yang
0 siblings, 1 reply; 14+ messages in thread
From: Matwey V. Kornilov @ 2019-10-22 17:37 UTC (permalink / raw)
To: u-boot
Hi,
Thank you. Currently, I see the following at Rock64 SBC:
U-Boot TPL 2019.10-00024-g8b580d5b93 (Oct 22 2019 - 20:29:01)
data training error
LPDDR3, 800MHz
BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=2048MB
Trying to boot from BOOTROM
Returning to boot ROM...
The rest seems to be working fine, but I am confused by "data training
error" message.
22.10.2019 11:04, Kever Yang пишет:
> From: YouMin Chen <cym@rock-chips.com>
>
> RK3328 has a similar controller and phy with PX30, so we can use the
> common driver for it and remove the duplicate codes.
>
> Signed-off-by: YouMin Chen <cym@rock-chips.com>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> arch/arm/dts/rk3328-sdram-ddr3-666.dtsi | 4 +
> arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi | 4 +
> arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi | 4 +
> .../include/asm/arch-rockchip/sdram_rk3328.h | 419 +++-------
> arch/arm/mach-rockchip/Kconfig | 1 +
> configs/evb-rk3328_defconfig | 2 +-
> configs/rock64-rk3328_defconfig | 2 +-
> drivers/ram/rockchip/Makefile | 2 +-
> drivers/ram/rockchip/sdram_rk3328.c | 764 ++++--------------
> 9 files changed, 296 insertions(+), 906 deletions(-)
>
> diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
> index d99e7e0352..3e88ed443b 100644
> --- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
> +++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
> @@ -14,6 +14,8 @@
> 0x0
> 0x10
> 0x10
> + 0x10
> + 0x10
> 0
>
> 0x9028b189
> @@ -26,6 +28,8 @@
>
> 333
> 3
> + 1
> + 0
> 0
>
> 0x00000000
> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
> index cc0011cf7b..d63c761a02 100644
> --- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
> @@ -14,6 +14,8 @@
> 0x0
> 0x10
> 0x10
> + 0x10
> + 0x10
> 0
>
> 0x98899459
> @@ -27,6 +29,8 @@
> 800
> 6
> 1
> + 0
> + 1
>
> 0x00000000
> 0x43041008
> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
> index 62d809e833..b9d3b3b948 100644
> --- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
> @@ -14,6 +14,8 @@
> 0x0
> 0x10
> 0x10
> + 0x10
> + 0x10
> 0
>
> 0x0c48a18a
> @@ -26,6 +28,8 @@
>
> 333
> 6
> + 1
> + 0
> 0
>
> 0x00000000
> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
> index c747b461a1..10923505d6 100644
> --- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
> +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
> @@ -7,197 +7,13 @@
> #ifndef _ASM_ARCH_SDRAM_RK3328_H
> #define _ASM_ARCH_SDRAM_RK3328_H
> #include <asm/arch-rockchip/sdram_common.h>
> +#include <asm/arch-rockchip/sdram_pctl_px30.h>
> +#include <asm/arch-rockchip/sdram_phy_px30.h>
> +#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
>
> #define SR_IDLE 93
> #define PD_IDLE 13
> #define SDRAM_ADDR 0x00000000
> -#define PATTERN (0x5aa5f00f)
> -
> -/* ddr pctl registers define */
> -#define DDR_PCTL2_MSTR 0x0
> -#define DDR_PCTL2_STAT 0x4
> -#define DDR_PCTL2_MSTR1 0x8
> -#define DDR_PCTL2_MRCTRL0 0x10
> -#define DDR_PCTL2_MRCTRL1 0x14
> -#define DDR_PCTL2_MRSTAT 0x18
> -#define DDR_PCTL2_MRCTRL2 0x1c
> -#define DDR_PCTL2_DERATEEN 0x20
> -#define DDR_PCTL2_DERATEINT 0x24
> -#define DDR_PCTL2_PWRCTL 0x30
> -#define DDR_PCTL2_PWRTMG 0x34
> -#define DDR_PCTL2_HWLPCTL 0x38
> -#define DDR_PCTL2_RFSHCTL0 0x50
> -#define DDR_PCTL2_RFSHCTL1 0x54
> -#define DDR_PCTL2_RFSHCTL2 0x58
> -#define DDR_PCTL2_RFSHCTL4 0x5c
> -#define DDR_PCTL2_RFSHCTL3 0x60
> -#define DDR_PCTL2_RFSHTMG 0x64
> -#define DDR_PCTL2_RFSHTMG1 0x68
> -#define DDR_PCTL2_RFSHCTL5 0x6c
> -#define DDR_PCTL2_INIT0 0xd0
> -#define DDR_PCTL2_INIT1 0xd4
> -#define DDR_PCTL2_INIT2 0xd8
> -#define DDR_PCTL2_INIT3 0xdc
> -#define DDR_PCTL2_INIT4 0xe0
> -#define DDR_PCTL2_INIT5 0xe4
> -#define DDR_PCTL2_INIT6 0xe8
> -#define DDR_PCTL2_INIT7 0xec
> -#define DDR_PCTL2_DIMMCTL 0xf0
> -#define DDR_PCTL2_RANKCTL 0xf4
> -#define DDR_PCTL2_CHCTL 0xfc
> -#define DDR_PCTL2_DRAMTMG0 0x100
> -#define DDR_PCTL2_DRAMTMG1 0x104
> -#define DDR_PCTL2_DRAMTMG2 0x108
> -#define DDR_PCTL2_DRAMTMG3 0x10c
> -#define DDR_PCTL2_DRAMTMG4 0x110
> -#define DDR_PCTL2_DRAMTMG5 0x114
> -#define DDR_PCTL2_DRAMTMG6 0x118
> -#define DDR_PCTL2_DRAMTMG7 0x11c
> -#define DDR_PCTL2_DRAMTMG8 0x120
> -#define DDR_PCTL2_DRAMTMG9 0x124
> -#define DDR_PCTL2_DRAMTMG10 0x128
> -#define DDR_PCTL2_DRAMTMG11 0x12c
> -#define DDR_PCTL2_DRAMTMG12 0x130
> -#define DDR_PCTL2_DRAMTMG13 0x134
> -#define DDR_PCTL2_DRAMTMG14 0x138
> -#define DDR_PCTL2_DRAMTMG15 0x13c
> -#define DDR_PCTL2_DRAMTMG16 0x140
> -#define DDR_PCTL2_ZQCTL0 0x180
> -#define DDR_PCTL2_ZQCTL1 0x184
> -#define DDR_PCTL2_ZQCTL2 0x188
> -#define DDR_PCTL2_ZQSTAT 0x18c
> -#define DDR_PCTL2_DFITMG0 0x190
> -#define DDR_PCTL2_DFITMG1 0x194
> -#define DDR_PCTL2_DFILPCFG0 0x198
> -#define DDR_PCTL2_DFILPCFG1 0x19c
> -#define DDR_PCTL2_DFIUPD0 0x1a0
> -#define DDR_PCTL2_DFIUPD1 0x1a4
> -#define DDR_PCTL2_DFIUPD2 0x1a8
> -#define DDR_PCTL2_DFIMISC 0x1b0
> -#define DDR_PCTL2_DFITMG2 0x1b4
> -#define DDR_PCTL2_DFITMG3 0x1b8
> -#define DDR_PCTL2_DFISTAT 0x1bc
> -#define DDR_PCTL2_DBICTL 0x1c0
> -#define DDR_PCTL2_ADDRMAP0 0x200
> -#define DDR_PCTL2_ADDRMAP1 0x204
> -#define DDR_PCTL2_ADDRMAP2 0x208
> -#define DDR_PCTL2_ADDRMAP3 0x20c
> -#define DDR_PCTL2_ADDRMAP4 0x210
> -#define DDR_PCTL2_ADDRMAP5 0x214
> -#define DDR_PCTL2_ADDRMAP6 0x218
> -#define DDR_PCTL2_ADDRMAP7 0x21c
> -#define DDR_PCTL2_ADDRMAP8 0x220
> -#define DDR_PCTL2_ADDRMAP9 0x224
> -#define DDR_PCTL2_ADDRMAP10 0x228
> -#define DDR_PCTL2_ADDRMAP11 0x22c
> -#define DDR_PCTL2_ODTCFG 0x240
> -#define DDR_PCTL2_ODTMAP 0x244
> -#define DDR_PCTL2_SCHED 0x250
> -#define DDR_PCTL2_SCHED1 0x254
> -#define DDR_PCTL2_PERFHPR1 0x25c
> -#define DDR_PCTL2_PERFLPR1 0x264
> -#define DDR_PCTL2_PERFWR1 0x26c
> -#define DDR_PCTL2_DQMAP0 0x280
> -#define DDR_PCTL2_DQMAP1 0x284
> -#define DDR_PCTL2_DQMAP2 0x288
> -#define DDR_PCTL2_DQMAP3 0x28c
> -#define DDR_PCTL2_DQMAP4 0x290
> -#define DDR_PCTL2_DQMAP5 0x294
> -#define DDR_PCTL2_DBG0 0x300
> -#define DDR_PCTL2_DBG1 0x304
> -#define DDR_PCTL2_DBGCAM 0x308
> -#define DDR_PCTL2_DBGCMD 0x30c
> -#define DDR_PCTL2_DBGSTAT 0x310
> -#define DDR_PCTL2_SWCTL 0x320
> -#define DDR_PCTL2_SWSTAT 0x324
> -#define DDR_PCTL2_POISONCFG 0x36c
> -#define DDR_PCTL2_POISONSTAT 0x370
> -#define DDR_PCTL2_ADVECCINDEX 0x374
> -#define DDR_PCTL2_ADVECCSTAT 0x378
> -#define DDR_PCTL2_PSTAT 0x3fc
> -#define DDR_PCTL2_PCCFG 0x400
> -#define DDR_PCTL2_PCFGR_n 0x404
> -#define DDR_PCTL2_PCFGW_n 0x408
> -#define DDR_PCTL2_PCTRL_n 0x490
> -
> -/* PCTL2_MRSTAT */
> -#define MR_WR_BUSY BIT(0)
> -
> -/* PHY_REG0 */
> -#define DIGITAL_DERESET BIT(3)
> -#define ANALOG_DERESET BIT(2)
> -#define DIGITAL_RESET (0 << 3)
> -#define ANALOG_RESET (0 << 2)
> -
> -/* PHY_REG1 */
> -#define PHY_DDR2 (0)
> -#define PHY_LPDDR2 (1)
> -#define PHY_DDR3 (2)
> -#define PHY_LPDDR3 (3)
> -#define PHY_DDR4 (4)
> -#define PHY_BL_4 (0 << 2)
> -#define PHY_BL_8 BIT(2)
> -
> -/* PHY_REG2 */
> -#define PHY_DTT_EN BIT(0)
> -#define PHY_DTT_DISB (0 << 0)
> -#define PHY_WRITE_LEVELING_EN BIT(2)
> -#define PHY_WRITE_LEVELING_DISB (0 << 2)
> -#define PHY_SELECT_CS0 (2)
> -#define PHY_SELECT_CS1 (1)
> -#define PHY_SELECT_CS0_1 (0)
> -#define PHY_WRITE_LEVELING_SELECTCS(n) (n << 6)
> -#define PHY_DATA_TRAINING_SELECTCS(n) (n << 4)
> -
> -#define PHY_DDR3_RON_RTT_DISABLE (0)
> -#define PHY_DDR3_RON_RTT_451ohm (1)
> -#define PHY_DDR3_RON_RTT_225ohm (2)
> -#define PHY_DDR3_RON_RTT_150ohm (3)
> -#define PHY_DDR3_RON_RTT_112ohm (4)
> -#define PHY_DDR3_RON_RTT_90ohm (5)
> -#define PHY_DDR3_RON_RTT_75ohm (6)
> -#define PHY_DDR3_RON_RTT_64ohm (7)
> -#define PHY_DDR3_RON_RTT_56ohm (16)
> -#define PHY_DDR3_RON_RTT_50ohm (17)
> -#define PHY_DDR3_RON_RTT_45ohm (18)
> -#define PHY_DDR3_RON_RTT_41ohm (19)
> -#define PHY_DDR3_RON_RTT_37ohm (20)
> -#define PHY_DDR3_RON_RTT_34ohm (21)
> -#define PHY_DDR3_RON_RTT_33ohm (22)
> -#define PHY_DDR3_RON_RTT_30ohm (23)
> -#define PHY_DDR3_RON_RTT_28ohm (24)
> -#define PHY_DDR3_RON_RTT_26ohm (25)
> -#define PHY_DDR3_RON_RTT_25ohm (26)
> -#define PHY_DDR3_RON_RTT_23ohm (27)
> -#define PHY_DDR3_RON_RTT_22ohm (28)
> -#define PHY_DDR3_RON_RTT_21ohm (29)
> -#define PHY_DDR3_RON_RTT_20ohm (30)
> -#define PHY_DDR3_RON_RTT_19ohm (31)
> -
> -#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
> -#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1)
> -#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2)
> -#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3)
> -#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4)
> -#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5)
> -#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6)
> -#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7)
> -#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16)
> -#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17)
> -#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18)
> -#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19)
> -#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20)
> -#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21)
> -#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22)
> -#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23)
> -#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24)
> -#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25)
> -#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26)
> -#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27)
> -#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28)
> -#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29)
> -#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30)
> -#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31)
>
> /* noc registers define */
> #define DDRCONF 0x8
> @@ -220,16 +36,16 @@
> #define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
>
> /* CRU_SOFTRESET_CON5 */
> -#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | (n << 15))
> -#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | (n << 14))
> -#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | (n << 13))
> -#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | (n << 12))
> -#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | (n << 11))
> -#define msch_srstn_req(n) (((0x1 << 9) << 16) | (n << 9))
> -#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | (n << 8))
> -#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | (n << 7))
> +#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | ((n) << 15))
> +#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | ((n) << 14))
> +#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | ((n) << 13))
> +#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | ((n) << 12))
> +#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | ((n) << 11))
> +#define msch_srstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
> +#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | ((n) << 8))
> +#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | ((n) << 7))
> /* CRU_SOFTRESET_CON9 */
> -#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | (n << 9))
> +#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
>
> /* CRU register */
> #define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
> @@ -256,56 +72,46 @@
> #define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
> #define REFDIV(n) ((0x3F << 16) | (n))
>
> -union noc_ddrtiming {
> - u32 d32;
> - struct {
> - unsigned acttoact:6;
> - unsigned rdtomiss:6;
> - unsigned wrtomiss:6;
> - unsigned burstlen:3;
> - unsigned rdtowr:5;
> - unsigned wrtord:5;
> - unsigned bwratio:1;
> - } b;
> -} NOC_TIMING_T;
> -
> -union noc_activate {
> - u32 d32;
> - struct {
> - unsigned rrd:4;
> - unsigned faw:6;
> - unsigned fawbank:1;
> - unsigned reserved1:21;
> - } b;
> -};
> -
> -union noc_devtodev {
> - u32 d32;
> - struct {
> - unsigned busrdtord:2;
> - unsigned busrdtowr:2;
> - unsigned buswrtord:2;
> - unsigned reserved2:26;
> - } b;
> -};
> -
> -union noc_ddr4timing {
> - u32 d32;
> - struct {
> - unsigned ccdl:3;
> - unsigned wrtordl:5;
> - unsigned rrdl:4;
> - unsigned reserved2:20;
> - } b;
> +u16 ddr_cfg_2_rbc[] = {
> + /*
> + * [5:4] row(13+n)
> + * [3] cs(0:0 cs, 1:2 cs)
> + * [2] bank(0:0bank,1:8bank)
> + * [1:0] col(11+n)
> + */
> + /* row, cs, bank, col */
> + ((3 << 4) | (0 << 3) | (1 << 2) | 0),
> + ((3 << 4) | (0 << 3) | (1 << 2) | 1),
> + ((2 << 4) | (0 << 3) | (1 << 2) | 2),
> + ((3 << 4) | (0 << 3) | (1 << 2) | 2),
> + ((2 << 4) | (0 << 3) | (1 << 2) | 3),
> + ((3 << 4) | (1 << 3) | (1 << 2) | 0),
> + ((3 << 4) | (1 << 3) | (1 << 2) | 1),
> + ((2 << 4) | (1 << 3) | (1 << 2) | 2),
> + ((3 << 4) | (0 << 3) | (0 << 2) | 1),
> + ((2 << 4) | (0 << 3) | (1 << 2) | 1),
> };
>
> -union noc_ddrmode {
> - u32 d32;
> - struct {
> - unsigned autoprecharge:1;
> - unsigned bwratioextended:1;
> - unsigned reserved3:30;
> - } b;
> +u16 ddr4_cfg_2_rbc[] = {
> + /***************************
> + * [6] cs 0:0cs 1:2 cs
> + * [5:3] row(13+n)
> + * [2] cs(0:0 cs, 1:2 cs)
> + * [1] bw 0: 16bit 1:32bit
> + * [0] diebw 0:8bit 1:16bit
> + ***************************/
> + /* cs, row, cs, bw, diebw */
> + ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
> + ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
> + ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
> + ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
> + ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
> + ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
> + ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
> + ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
> + ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
> + ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
> + ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
> };
>
> u32 addrmap[21][9] = {
> @@ -356,17 +162,65 @@ u32 addrmap[21][9] = {
> 0x07070707, 0x00000f07, 0x3f00}
> };
>
> -struct rk3328_msch_timings {
> - union noc_ddrtiming ddrtiming;
> - union noc_ddrmode ddrmode;
> - u32 readlatency;
> - union noc_activate activate;
> - union noc_devtodev devtodev;
> - union noc_ddr4timing ddr4timing;
> - u32 agingx0;
> +struct rk3328_ddr_grf_regs {
> + u32 ddr_grf_con[4];
> + u32 reserved[(0x100 - 0x10) / 4];
> + u32 ddr_grf_status[11];
> };
>
> -struct rk3328_msch_regs {
> +union noc_ddrtiming {
> + u32 d32;
> + struct {
> + unsigned acttoact:6;
> + unsigned rdtomiss:6;
> + unsigned wrtomiss:6;
> + unsigned burstlen:3;
> + unsigned rdtowr:5;
> + unsigned wrtord:5;
> + unsigned bwratio:1;
> + } b;
> +};
> +
> +union noc_activate {
> + u32 d32;
> + struct {
> + unsigned rrd:4;
> + unsigned faw:6;
> + unsigned fawbank:1;
> + unsigned reserved1:21;
> + } b;
> +};
> +
> +union noc_devtodev {
> + u32 d32;
> + struct {
> + unsigned busrdtord:2;
> + unsigned busrdtowr:2;
> + unsigned buswrtord:2;
> + unsigned reserved2:26;
> + } b;
> +};
> +
> +union noc_ddr4timing {
> + u32 d32;
> + struct {
> + unsigned ccdl:3;
> + unsigned wrtordl:5;
> + unsigned rrdl:4;
> + unsigned reserved2:20;
> + } b;
> +};
> +
> +union noc_ddrmode {
> + u32 d32;
> + struct {
> + unsigned autoprecharge:1;
> + unsigned bwratioextended:1;
> + unsigned reserved3:30;
> + } b;
> +};
> +
> +struct msch_regs {
> u32 coreid;
> u32 revisionid;
> u32 ddrconf;
> @@ -385,58 +239,27 @@ struct rk3328_msch_regs {
> u32 ddr4_timing;
> };
>
> -struct rk3328_ddr_grf_regs {
> - u32 ddr_grf_con[4];
> - u32 reserved[(0x100 - 0x10) / 4];
> - u32 ddr_grf_status[11];
> -};
> -
> -struct rk3328_ddr_pctl_regs {
> - u32 pctl[30][2];
> -};
> -
> -struct rk3328_ddr_phy_regs {
> - u32 phy[5][2];
> -};
> -
> -struct rk3328_ddr_skew {
> - u32 a0_a1_skew[15];
> - u32 cs0_dm0_skew[11];
> - u32 cs0_dm1_skew[11];
> - u32 cs0_dm2_skew[11];
> - u32 cs0_dm3_skew[11];
> - u32 cs1_dm0_skew[11];
> - u32 cs1_dm1_skew[11];
> - u32 cs1_dm2_skew[11];
> - u32 cs1_dm3_skew[11];
> +struct sdram_msch_timings {
> + union noc_ddrtiming ddrtiming;
> + union noc_ddrmode ddrmode;
> + u32 readlatency;
> + union noc_activate activate;
> + union noc_devtodev devtodev;
> + union noc_ddr4timing ddr4timing;
> + u32 agingx0;
> };
>
> struct rk3328_sdram_channel {
> - unsigned int rank;
> - unsigned int col;
> - /* 3:8bank, 2:4bank */
> - unsigned int bk;
> - /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
> - unsigned int bw;
> - /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
> - unsigned int dbw;
> - unsigned int row_3_4;
> - unsigned int cs0_row;
> - unsigned int cs1_row;
> - unsigned int ddrconfig;
> - struct rk3328_msch_timings noc_timings;
> + struct sdram_cap_info cap_info;
> + struct sdram_msch_timings noc_timings;
> };
>
> struct rk3328_sdram_params {
> struct rk3328_sdram_channel ch;
> - unsigned int ddr_freq;
> - unsigned int dramtype;
> - unsigned int odt;
> - struct rk3328_ddr_pctl_regs pctl_regs;
> - struct rk3328_ddr_phy_regs phy_regs;
> - struct rk3328_ddr_skew skew;
> + struct sdram_base_params base;
> + struct ddr_pctl_regs pctl_regs;
> + struct ddr_phy_regs phy_regs;
> + struct ddr_phy_skew skew;
> };
>
> -#define PHY_REG(base, n) (base + 4 * (n))
> -
> #endif
> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
> index f5a80b4f0c..5f1ad51cac 100644
> --- a/arch/arm/mach-rockchip/Kconfig
> +++ b/arch/arm/mach-rockchip/Kconfig
> @@ -115,6 +115,7 @@ config ROCKCHIP_RK3328
> select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
> select TPL_NEEDS_SEPARATE_STACK if TPL
> imply ROCKCHIP_COMMON_BOARD
> + imply ROCKCHIP_SDRAM_COMMON
> imply SPL_ROCKCHIP_COMMON_BOARD
> imply SPL_SERIAL_SUPPORT
> imply TPL_SERIAL_SUPPORT
> diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
> index 37610774c1..fdabee842d 100644
> --- a/configs/evb-rk3328_defconfig
> +++ b/configs/evb-rk3328_defconfig
> @@ -46,7 +46,6 @@ CONFIG_SPL_SYSCON=y
> CONFIG_TPL_SYSCON=y
> CONFIG_CLK=y
> CONFIG_SPL_CLK=y
> -CONFIG_TPL_CLK=y
> CONFIG_FASTBOOT_BUF_ADDR=0x800800
> CONFIG_FASTBOOT_FLASH=y
> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
> @@ -77,6 +76,7 @@ CONFIG_DEBUG_UART_SHIFT=2
> CONFIG_DEBUG_UART_ANNOUNCE=y
> CONFIG_DEBUG_UART_SKIP_INIT=y
> CONFIG_SYSRESET=y
> +# CONFIG_TPL_SYSRESET is not set
> CONFIG_USB=y
> CONFIG_USB_XHCI_HCD=y
> CONFIG_USB_XHCI_DWC3=y
> diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
> index 3ab0af1158..0fb4b42c6e 100644
> --- a/configs/rock64-rk3328_defconfig
> +++ b/configs/rock64-rk3328_defconfig
> @@ -49,7 +49,6 @@ CONFIG_SPL_SYSCON=y
> CONFIG_TPL_SYSCON=y
> CONFIG_CLK=y
> CONFIG_SPL_CLK=y
> -CONFIG_TPL_CLK=y
> CONFIG_FASTBOOT_BUF_ADDR=0x800800
> CONFIG_FASTBOOT_FLASH=y
> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
> @@ -79,6 +78,7 @@ CONFIG_DM_RESET=y
> CONFIG_BAUDRATE=1500000
> CONFIG_DEBUG_UART_SHIFT=2
> CONFIG_SYSRESET=y
> +# CONFIG_TPL_SYSRESET is not set
> CONFIG_USB=y
> CONFIG_USB_XHCI_HCD=y
> CONFIG_USB_XHCI_DWC3=y
> diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
> index 3d4f2f4ebf..3f19fa09a5 100644
> --- a/drivers/ram/rockchip/Makefile
> +++ b/drivers/ram/rockchip/Makefile
> @@ -9,5 +9,5 @@ obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
> obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
> obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
> obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
> -obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
> +obj-$(CONFIG_ROCKCHIP_RK3328) += sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
> obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
> diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
> index e7919337ea..72ae7555bc 100644
> --- a/drivers/ram/rockchip/sdram_rk3328.c
> +++ b/drivers/ram/rockchip/sdram_rk3328.c
> @@ -20,11 +20,11 @@
>
> struct dram_info {
> #ifdef CONFIG_TPL_BUILD
> - struct rk3328_ddr_pctl_regs *pctl;
> - struct rk3328_ddr_phy_regs *phy;
> + struct ddr_pctl_regs *pctl;
> + struct ddr_phy_regs *phy;
> struct clk ddr_clk;
> struct rk3328_cru *cru;
> - struct rk3328_msch_regs *msch;
> + struct msch_regs *msch;
> struct rk3328_ddr_grf_regs *ddr_grf;
> #endif
> struct ram_info info;
> @@ -71,10 +71,11 @@ static void rkclk_ddr_reset(struct dram_info *dram,
> writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
> }
>
> -static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
> +static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
> {
> unsigned int refdiv, postdiv1, postdiv2, fbdiv;
> int delay = 1000;
> + u32 mhz = hz / MHZ;
>
> refdiv = 1;
> if (mhz <= 300) {
> @@ -122,52 +123,7 @@ static void rkclk_configure_ddr(struct dram_info *dram,
> clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
>
> /* for inno ddr phy need 2*freq */
> - rkclk_set_dpll(dram, sdram_params->ddr_freq * 2);
> -}
> -
> -static void phy_soft_reset(struct dram_info *dram)
> -{
> - void __iomem *phy_base = dram->phy;
> -
> - clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
> - udelay(1);
> - setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
> - udelay(5);
> - setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
> - udelay(1);
> -}
> -
> -static int pctl_cfg(struct dram_info *dram,
> - struct rk3328_sdram_params *sdram_params)
> -{
> - u32 i;
> - void __iomem *pctl_base = dram->pctl;
> -
> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
> - writel(sdram_params->pctl_regs.pctl[i][1],
> - pctl_base + sdram_params->pctl_regs.pctl[i][0]);
> - }
> - clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
> - (0xff << 16) | 0x1f,
> - ((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
> - /*
> - * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
> - * hw_lp_idle_x32=1
> - */
> - if (sdram_params->dramtype == LPDDR3) {
> - setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
> - clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
> - 0xf << 4,
> - 2 << 4);
> - }
> - clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
> - 0xfff << 16,
> - 1 << 16);
> - /* disable zqcs */
> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
> - setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
> -
> - return 0;
> + rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ * 2);
> }
>
> /* return ddrconfig value
> @@ -175,62 +131,39 @@ static int pctl_cfg(struct dram_info *dram,
> * other, the ddrconfig value
> * only support cs0_row >= cs1_row
> */
> -static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
> +static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
> {
> - static const u16 ddr_cfg_2_rbc[] = {
> - /***************************
> - * [5:4] row(13+n)
> - * [3] cs(0:0 cs, 1:2 cs)
> - * [2] bank(0:0bank,1:8bank)
> - * [1:0] col(11+n)
> - ****************************/
> - /* row, cs, bank, col */
> - ((3 << 4) | (0 << 3) | (1 << 2) | 0),
> - ((3 << 4) | (0 << 3) | (1 << 2) | 1),
> - ((2 << 4) | (0 << 3) | (1 << 2) | 2),
> - ((3 << 4) | (0 << 3) | (1 << 2) | 2),
> - ((2 << 4) | (0 << 3) | (1 << 2) | 3),
> - ((3 << 4) | (1 << 3) | (1 << 2) | 0),
> - ((3 << 4) | (1 << 3) | (1 << 2) | 1),
> - ((2 << 4) | (1 << 3) | (1 << 2) | 2),
> - ((3 << 4) | (0 << 3) | (0 << 2) | 1),
> - ((2 << 4) | (0 << 3) | (1 << 2) | 1),
> - };
> -
> - static const u16 ddr4_cfg_2_rbc[] = {
> - /***************************
> - * [6] cs 0:0cs 1:2 cs
> - * [5:3] row(13+n)
> - * [2] cs(0:0 cs, 1:2 cs)
> - * [1] bw 0: 16bit 1:32bit
> - * [0] diebw 0:8bit 1:16bit
> - ***************************/
> - /* cs, row, cs, bw, diebw */
> - ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
> - ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
> - ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
> - ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
> - ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
> - ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
> - ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
> - ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
> - ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
> - ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
> - ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
> - };
> -
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
> u32 cs, bw, die_bw, col, row, bank;
> + u32 cs1_row;
> u32 i, tmp;
> u32 ddrconf = -1;
>
> - cs = sdram_ch.rank;
> - bw = sdram_ch.bw;
> - die_bw = sdram_ch.dbw;
> - col = sdram_ch.col;
> - row = sdram_ch.cs0_row;
> - bank = sdram_ch.bk;
> + cs = cap_info->rank;
> + bw = cap_info->bw;
> + die_bw = cap_info->dbw;
> + col = cap_info->col;
> + row = cap_info->cs0_row;
> + cs1_row = cap_info->cs1_row;
> + bank = cap_info->bk;
> +
> + if (sdram_params->base.dramtype == DDR4) {
> + /* when DDR_TEST, CS always at MSB position for easy test */
> + if (cs == 2 && row == cs1_row) {
> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
> + tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
> + die_bw;
> + for (i = 17; i < 21; i++) {
> + if (((tmp & 0x7) ==
> + (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
> + ((tmp & 0x3c) <=
> + (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
> + ddrconf = i;
> + goto out;
> + }
> + }
> + }
>
> - if (sdram_params->dramtype == DDR4) {
> tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
> for (i = 10; i < 17; i++) {
> if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
> @@ -246,6 +179,18 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
> goto out;
> }
>
> + /* when DDR_TEST, CS always at MSB position for easy test */
> + if (cs == 2 && row == cs1_row) {
> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
> + for (i = 5; i < 8; i++) {
> + if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
> + 0x3)) {
> + ddrconf = i;
> + goto out;
> + }
> + }
> + }
> +
> tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
> for (i = 0; i < 5; i++)
> if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
> @@ -257,23 +202,11 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
>
> out:
> if (ddrconf > 20)
> - printf("calculate_ddrconfig error\n");
> + printf("calculate ddrconfig error\n");
>
> return ddrconf;
> }
>
> -/* n: Unit bytes */
> -static void copy_to_reg(u32 *dest, u32 *src, u32 n)
> -{
> - int i;
> -
> - for (i = 0; i < n / sizeof(u32); i++) {
> - writel(*src, dest);
> - src++;
> - dest++;
> - }
> -}
> -
> /*******
> * calculate controller dram address map, and setting to register.
> * argument sdram_ch.ddrconf must be right value before
> @@ -282,273 +215,42 @@ static void copy_to_reg(u32 *dest, u32 *src, u32 n)
> static void set_ctl_address_map(struct dram_info *dram,
> struct rk3328_sdram_params *sdram_params)
> {
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
> void __iomem *pctl_base = dram->pctl;
>
> - copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
> - &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
> - if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
> + sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
> + &addrmap[cap_info->ddrconfig][0], 9 * 4);
> + if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
> setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
> - if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
> + if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
> setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
>
> - if (sdram_ch.rank == 1)
> + if (cap_info->rank == 1)
> clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
> }
>
> -static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
> -{
> - u32 tmp;
> - void __iomem *phy_base = dram->phy;
> -
> - setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
> - clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
> - setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
> - clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
> - setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
> - clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
> - setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
> - clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
> - setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
> - clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
> -
> - if (freq <= 400)
> - /* DLL bypass */
> - setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
> - else
> - clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
> - if (freq <= 680)
> - tmp = 2;
> - else
> - tmp = 1;
> - writel(tmp, PHY_REG(phy_base, 0x28));
> - writel(tmp, PHY_REG(phy_base, 0x38));
> - writel(tmp, PHY_REG(phy_base, 0x48));
> - writel(tmp, PHY_REG(phy_base, 0x58));
> -}
> -
> -static void set_ds_odt(struct dram_info *dram,
> - struct rk3328_sdram_params *sdram_params)
> -{
> - u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
> - void __iomem *phy_base = dram->phy;
> -
> - if (sdram_params->dramtype == DDR3) {
> - cmd_drv = PHY_DDR3_RON_RTT_34ohm;
> - clk_drv = PHY_DDR3_RON_RTT_45ohm;
> - dqs_drv = PHY_DDR3_RON_RTT_34ohm;
> - dqs_odt = PHY_DDR3_RON_RTT_225ohm;
> - } else {
> - cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
> - clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
> - dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
> - dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
> - }
> - /* DS */
> - writel(cmd_drv, PHY_REG(phy_base, 0x11));
> - clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
> - writel(clk_drv, PHY_REG(phy_base, 0x16));
> - writel(clk_drv, PHY_REG(phy_base, 0x18));
> - writel(dqs_drv, PHY_REG(phy_base, 0x20));
> - writel(dqs_drv, PHY_REG(phy_base, 0x2f));
> - writel(dqs_drv, PHY_REG(phy_base, 0x30));
> - writel(dqs_drv, PHY_REG(phy_base, 0x3f));
> - writel(dqs_drv, PHY_REG(phy_base, 0x40));
> - writel(dqs_drv, PHY_REG(phy_base, 0x4f));
> - writel(dqs_drv, PHY_REG(phy_base, 0x50));
> - writel(dqs_drv, PHY_REG(phy_base, 0x5f));
> - /* ODT */
> - writel(dqs_odt, PHY_REG(phy_base, 0x21));
> - writel(dqs_odt, PHY_REG(phy_base, 0x2e));
> - writel(dqs_odt, PHY_REG(phy_base, 0x31));
> - writel(dqs_odt, PHY_REG(phy_base, 0x3e));
> - writel(dqs_odt, PHY_REG(phy_base, 0x41));
> - writel(dqs_odt, PHY_REG(phy_base, 0x4e));
> - writel(dqs_odt, PHY_REG(phy_base, 0x51));
> - writel(dqs_odt, PHY_REG(phy_base, 0x5e));
> -}
> -
> -static void phy_cfg(struct dram_info *dram,
> - struct rk3328_sdram_params *sdram_params)
> -{
> - u32 i;
> - void __iomem *phy_base = dram->phy;
> -
> - phy_dll_bypass_set(dram, sdram_params->ddr_freq);
> - for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
> - writel(sdram_params->phy_regs.phy[i][1],
> - phy_base + sdram_params->phy_regs.phy[i][0]);
> - }
> - if (sdram_ch.bw == 2) {
> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
> - } else {
> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
> - /* disable DQS2,DQS3 tx dll for saving power */
> - clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> - clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> - }
> - set_ds_odt(dram, sdram_params);
> - /* deskew */
> - setbits_le32(PHY_REG(phy_base, 2), 8);
> - copy_to_reg(PHY_REG(phy_base, 0xb0),
> - &sdram_params->skew.a0_a1_skew[0], 15 * 4);
> - copy_to_reg(PHY_REG(phy_base, 0x70),
> - &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
> - copy_to_reg(PHY_REG(phy_base, 0xc0),
> - &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
> -}
> -
> -static int update_refresh_reg(struct dram_info *dram)
> -{
> - void __iomem *pctl_base = dram->pctl;
> - u32 ret;
> -
> - ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
> - writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
> -
> - return 0;
> -}
> -
> static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
> -{
> - u32 ret;
> - u32 dis_auto_zq = 0;
> - void __iomem *pctl_base = dram->pctl;
> - void __iomem *phy_base = dram->phy;
> -
> - /* disable zqcs */
> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
> - (1ul << 31))) {
> - dis_auto_zq = 1;
> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> - }
> - /* disable auto refresh */
> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> - update_refresh_reg(dram);
> -
> - if (dramtype == DDR4) {
> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
> - }
> - /* choose training cs */
> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
> - /* enable gate training */
> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
> - udelay(50);
> - ret = readl(PHY_REG(phy_base, 0xff));
> - /* disable gate training */
> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
> - /* restore zqcs */
> - if (dis_auto_zq)
> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> - /* restore auto refresh */
> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> - update_refresh_reg(dram);
> -
> - if (dramtype == DDR4) {
> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
> - }
> -
> - if (ret & 0x10) {
> - ret = -1;
> - } else {
> - ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
> - ret = (ret == 0) ? 0 : -1;
> - }
> - return ret;
> -}
> -
> -/* rank = 1: cs0
> - * rank = 2: cs1
> - * rank = 3: cs0 & cs1
> - * note: be careful of keep mr original val
> - */
> -static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 arg,
> - u32 dramtype)
> {
> void __iomem *pctl_base = dram->pctl;
> -
> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
> - continue;
> - if (dramtype == DDR3 || dramtype == DDR4) {
> - writel((mr_num << 12) | (rank << 4) | (0 << 0),
> - pctl_base + DDR_PCTL2_MRCTRL0);
> - writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
> - } else {
> - writel((rank << 4) | (0 << 0),
> - pctl_base + DDR_PCTL2_MRCTRL0);
> - writel((mr_num << 8) | (arg & 0xff),
> - pctl_base + DDR_PCTL2_MRCTRL1);
> - }
> -
> - setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
> - while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
> - continue;
> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
> - continue;
> -
> - return 0;
> -}
> -
> -/*
> - * rank : 1:cs0, 2:cs1, 3:cs0&cs1
> - * vrefrate: 4500: 45%,
> - */
> -static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
> - u32 dramtype)
> -{
> - u32 tccd_l, value;
> u32 dis_auto_zq = 0;
> - void __iomem *pctl_base = dram->pctl;
> + u32 pwrctl;
> + u32 ret;
>
> - if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
> - return -1;
> + /* disable auto low-power */
> + pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
> + writel(0, pctl_base + DDR_PCTL2_PWRCTL);
>
> - tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
> - tccd_l = (tccd_l - 4) << 10;
> + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
>
> - if (vrefrate > 7500) {
> - /* range 1 */
> - value = ((vrefrate - 6000) / 65) | tccd_l;
> - } else {
> - /* range 2 */
> - value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
> - }
> + ret = phy_data_training(dram->phy, cs, dramtype);
>
> - /* disable zqcs */
> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
> - (1ul << 31))) {
> - dis_auto_zq = 1;
> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> - }
> - /* disable auto refresh */
> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> - update_refresh_reg(dram);
> -
> - /* enable vrefdq calibratin */
> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
> - udelay(1);/* tvrefdqe */
> - /* write vrefdq value */
> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
> - udelay(1);/* tvref_time */
> - write_mr(dram, rank, 6, value | (0 << 7), dramtype);
> - udelay(1);/* tvrefdqx */
> -
> - /* restore zqcs */
> - if (dis_auto_zq)
> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> - /* restore auto refresh */
> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> - update_refresh_reg(dram);
> + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
>
> - return 0;
> -}
> + /* restore auto low-power */
> + writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
>
> -#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
> + return ret;
> +}
>
> static void rx_deskew_switch_adjust(struct dram_info *dram)
> {
> @@ -557,7 +259,7 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
> void __iomem *phy_base = dram->phy;
>
> for (i = 0; i < 4; i++)
> - gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
> + gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
>
> deskew_val = (gate_val >> 3) + 1;
> deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
> @@ -566,8 +268,6 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
> (deskew_val & 0x1c) << 2);
> }
>
> -#undef _MAX_
> -
> static void tx_deskew_switch_adjust(struct dram_info *dram)
> {
> void __iomem *phy_base = dram->phy;
> @@ -580,40 +280,39 @@ static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
> writel(ddrconfig, &dram->msch->ddrconf);
> }
>
> +static void sdram_msch_config(struct msch_regs *msch,
> + struct sdram_msch_timings *noc_timings)
> +{
> + writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
> +
> + writel(noc_timings->ddrmode.d32, &msch->ddrmode);
> + writel(noc_timings->readlatency, &msch->readlatency);
> +
> + writel(noc_timings->activate.d32, &msch->activate);
> + writel(noc_timings->devtodev.d32, &msch->devtodev);
> + writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
> + writel(noc_timings->agingx0, &msch->aging0);
> + writel(noc_timings->agingx0, &msch->aging1);
> + writel(noc_timings->agingx0, &msch->aging2);
> + writel(noc_timings->agingx0, &msch->aging3);
> + writel(noc_timings->agingx0, &msch->aging4);
> + writel(noc_timings->agingx0, &msch->aging5);
> +}
> +
> static void dram_all_config(struct dram_info *dram,
> struct rk3328_sdram_params *sdram_params)
> {
> - u32 sys_reg = 0, tmp = 0;
> -
> - set_ddrconfig(dram, sdram_ch.ddrconfig);
> -
> - sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
> - sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
> - sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
> - sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
> - sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
> - SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
> - if (sdram_ch.cs1_row)
> - SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
> - sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
> - sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
> -
> - writel(sys_reg, &dram->grf->os_reg[2]);
> -
> - writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
> -
> - writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
> - writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
> -
> - writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
> - writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
> - writel(sdram_ch.noc_timings.ddr4timing.d32, &dram->msch->ddr4_timing);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
> + u32 sys_reg2 = 0;
> + u32 sys_reg3 = 0;
> +
> + set_ddrconfig(dram, cap_info->ddrconfig);
> + sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
> + &sys_reg3, 0);
> + writel(sys_reg2, &dram->grf->os_reg[2]);
> + writel(sys_reg3, &dram->grf->os_reg[3]);
> +
> + sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
> }
>
> static void enable_low_power(struct dram_info *dram,
> @@ -641,6 +340,7 @@ static void enable_low_power(struct dram_info *dram,
> static int sdram_init(struct dram_info *dram,
> struct rk3328_sdram_params *sdram_params, u32 pre_init)
> {
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
> void __iomem *pctl_base = dram->pctl;
>
> rkclk_ddr_reset(dram, 1, 1, 1, 1);
> @@ -652,30 +352,18 @@ static int sdram_init(struct dram_info *dram,
> */
> rkclk_ddr_reset(dram, 1, 1, 1, 0);
> rkclk_configure_ddr(dram, sdram_params);
> - if (pre_init == 0) {
> - switch (sdram_params->dramtype) {
> - case DDR3:
> - printf("DDR3\n");
> - break;
> - case DDR4:
> - printf("DDR4\n");
> - break;
> - case LPDDR3:
> - default:
> - printf("LPDDR3\n");
> - break;
> - }
> - }
> +
> /* release phy srst to provide clk to ctrl */
> rkclk_ddr_reset(dram, 1, 1, 0, 0);
> udelay(10);
> - phy_soft_reset(dram);
> + phy_soft_reset(dram->phy);
> /* release ctrl presetn, and config ctl registers */
> rkclk_ddr_reset(dram, 1, 0, 0, 0);
> - pctl_cfg(dram, sdram_params);
> - sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
> + pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
> + cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
> set_ctl_address_map(dram, sdram_params);
> - phy_cfg(dram, sdram_params);
> + phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
> + &sdram_params->base, cap_info->bw);
>
> /* enable dfi_init_start to init phy after ctl srstn deassert */
> setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
> @@ -685,13 +373,18 @@ static int sdram_init(struct dram_info *dram,
> continue;
>
> /* do ddr gate training */
> - if (data_training(dram, 0, sdram_params->dramtype) != 0) {
> + if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
> + printf("data training error\n");
> + return -1;
> + }
> + if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
> printf("data training error\n");
> return -1;
> }
>
> - if (sdram_params->dramtype == DDR4)
> - write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
> + if (sdram_params->base.dramtype == DDR4)
> + pctl_write_vrefdq(dram->pctl, 0x3, 5670,
> + sdram_params->base.dramtype);
>
> if (pre_init == 0) {
> rx_deskew_switch_adjust(dram);
> @@ -708,7 +401,7 @@ static u64 dram_detect_cap(struct dram_info *dram,
> struct rk3328_sdram_params *sdram_params,
> unsigned char channel)
> {
> - void __iomem *pctl_base = dram->pctl;
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>
> /*
> * for ddr3: ddrconf = 3
> @@ -718,14 +411,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
> */
> u32 bk, bktmp;
> u32 col, coltmp;
> - u32 row, rowtmp, row_3_4;
> - void __iomem *test_addr, *test_addr1;
> - u32 dbw;
> + u32 rowtmp;
> u32 cs;
> u32 bw = 1;
> - u64 cap = 0;
> - u32 dram_type = sdram_params->dramtype;
> - u32 pwrctl;
> + u32 dram_type = sdram_params->base.dramtype;
>
> if (dram_type != DDR4) {
> /* detect col and bk for ddr3/lpddr3 */
> @@ -733,33 +422,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
> bktmp = 3;
> rowtmp = 16;
>
> - for (col = coltmp; col >= 9; col -= 1) {
> - writel(0, SDRAM_ADDR);
> - test_addr = (void __iomem *)(SDRAM_ADDR +
> - (1ul << (col + bw - 1ul)));
> - writel(PATTERN, test_addr);
> - if ((readl(test_addr) == PATTERN) &&
> - (readl(SDRAM_ADDR) == 0))
> - break;
> - }
> - if (col == 8) {
> - printf("col error\n");
> + if (sdram_detect_col(cap_info, coltmp) != 0)
> goto cap_err;
> - }
> -
> - test_addr = (void __iomem *)(SDRAM_ADDR +
> - (1ul << (coltmp + bktmp + bw - 1ul)));
> - writel(0, SDRAM_ADDR);
> - writel(PATTERN, test_addr);
> - if ((readl(test_addr) == PATTERN) &&
> - (readl(SDRAM_ADDR) == 0))
> - bk = 3;
> - else
> - bk = 2;
> - if (dram_type == LPDDR3)
> - dbw = 2;
> - else
> - dbw = 1;
> + sdram_detect_bank(cap_info, coltmp, bktmp);
> + sdram_detect_dbw(cap_info, dram_type);
> } else {
> /* detect bg for ddr4 */
> coltmp = 10;
> @@ -768,178 +434,49 @@ static u64 dram_detect_cap(struct dram_info *dram,
>
> col = 10;
> bk = 2;
> - test_addr = (void __iomem *)(SDRAM_ADDR +
> - (1ul << (coltmp + bw + 1ul)));
> - writel(0, SDRAM_ADDR);
> - writel(PATTERN, test_addr);
> - if ((readl(test_addr) == PATTERN) &&
> - (readl(SDRAM_ADDR) == 0))
> - dbw = 0;
> - else
> - dbw = 1;
> + cap_info->col = col;
> + cap_info->bk = bk;
> + sdram_detect_bg(cap_info, coltmp);
> }
> +
> /* detect row */
> - for (row = rowtmp; row > 12; row--) {
> - writel(0, SDRAM_ADDR);
> - test_addr = (void __iomem *)(SDRAM_ADDR +
> - (1ul << (row + bktmp + coltmp + bw - 1ul)));
> - writel(PATTERN, test_addr);
> - if ((readl(test_addr) == PATTERN) &&
> - (readl(SDRAM_ADDR) == 0))
> - break;
> - }
> - if (row == 12) {
> - printf("row error");
> + if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
> goto cap_err;
> - }
> - /* detect row_3_4 */
> - test_addr = SDRAM_ADDR;
> - test_addr1 = (void __iomem *)(SDRAM_ADDR +
> - (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
> -
> - writel(0, test_addr);
> - writel(PATTERN, test_addr1);
> - if ((readl(test_addr) == 0) &&
> - (readl(test_addr1) == PATTERN))
> - row_3_4 = 0;
> - else
> - row_3_4 = 1;
>
> - /* disable auto low-power */
> - pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
> - writel(0, pctl_base + DDR_PCTL2_PWRCTL);
> + /* detect row_3_4 */
> + sdram_detect_row_3_4(cap_info, coltmp, bktmp);
>
> - /* bw and cs detect using phy read gate training */
> + /* bw and cs detect using data training */
> if (data_training(dram, 1, dram_type) == 0)
> cs = 1;
> else
> cs = 0;
> + cap_info->rank = cs + 1;
>
> bw = 2;
> + cap_info->bw = bw;
>
> - /* restore auto low-power */
> - writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
> -
> - sdram_ch.rank = cs + 1;
> - sdram_ch.col = col;
> - sdram_ch.bk = bk;
> - sdram_ch.dbw = dbw;
> - sdram_ch.bw = bw;
> - sdram_ch.cs0_row = row;
> - if (cs)
> - sdram_ch.cs1_row = row;
> - else
> - sdram_ch.cs1_row = 0;
> - sdram_ch.row_3_4 = row_3_4;
> -
> - if (dram_type == DDR4)
> - cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) + bw);
> - else
> - cap = 1llu << (cs + row + bk + col + bw);
> -
> - return cap;
> -
> -cap_err:
> - return 0;
> -}
> -
> -static u32 remodify_sdram_params(struct rk3328_sdram_params *sdram_params)
> -{
> - u32 tmp = 0, tmp_adr = 0, i;
> -
> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
> - if (sdram_params->pctl_regs.pctl[i][0] == 0) {
> - tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
> - tmp_adr = i;
> - }
> - }
> -
> - tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
> -
> - switch (sdram_ch.dbw) {
> - case 2:
> - tmp |= (3ul << 30);
> - break;
> - case 1:
> - tmp |= (2ul << 30);
> - break;
> - case 0:
> - default:
> - tmp |= (1ul << 30);
> - break;
> + cap_info->cs0_high16bit_row = cap_info->cs0_row;
> + if (cs) {
> + cap_info->cs1_row = cap_info->cs0_row;
> + cap_info->cs1_high16bit_row = cap_info->cs0_row;
> + } else {
> + cap_info->cs1_row = 0;
> + cap_info->cs1_high16bit_row = 0;
> }
>
> - if (sdram_ch.rank == 2)
> - tmp |= 3 << 24;
> - else
> - tmp |= 1 << 24;
> -
> - tmp |= (2 - sdram_ch.bw) << 12;
> -
> - sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
> -
> - if (sdram_ch.bw == 2)
> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
> - else
> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
> -
> return 0;
> -}
> -
> -static int dram_detect_cs1_row(struct rk3328_sdram_params *sdram_params,
> - unsigned char channel)
> -{
> - u32 ret = 0;
> - u32 cs1_bit;
> - void __iomem *test_addr, *cs1_addr;
> - u32 row, bktmp, coltmp, bw;
> - u32 ddrconf = sdram_ch.ddrconfig;
> -
> - if (sdram_ch.rank == 2) {
> - cs1_bit = addrmap[ddrconf][0] + 8;
> -
> - if (cs1_bit > 31)
> - goto out;
> -
> - cs1_addr = (void __iomem *)(1ul << cs1_bit);
> - if (cs1_bit < 20)
> - cs1_bit = 1;
> - else
> - cs1_bit = 0;
> -
> - if (sdram_params->dramtype == DDR4) {
> - if (sdram_ch.dbw == 0)
> - bktmp = sdram_ch.bk + 2;
> - else
> - bktmp = sdram_ch.bk + 1;
> - } else {
> - bktmp = sdram_ch.bk;
> - }
> - bw = sdram_ch.bw;
> - coltmp = sdram_ch.col;
> -
> - /* detect cs1 row */
> - for (row = sdram_ch.cs0_row; row > 12; row--) {
> - test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
> - (1ul << (row + cs1_bit + bktmp +
> - coltmp + bw - 1ul)));
> - writel(0, SDRAM_ADDR + cs1_addr);
> - writel(PATTERN, test_addr);
> - if ((readl(test_addr) == PATTERN) &&
> - (readl(SDRAM_ADDR + cs1_addr) == 0)) {
> - ret = row;
> - break;
> - }
> - }
> - }
> -
> -out:
> - return ret;
> +cap_err:
> + return -1;
> }
>
> static int sdram_init_detect(struct dram_info *dram,
> struct rk3328_sdram_params *sdram_params)
> {
> + u32 sys_reg = 0;
> + u32 sys_reg3 = 0;
> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
> +
> debug("Starting SDRAM initialization...\n");
>
> memcpy(&sdram_ch, &sdram_params->ch,
> @@ -949,13 +486,30 @@ static int sdram_init_detect(struct dram_info *dram,
> dram_detect_cap(dram, sdram_params, 0);
>
> /* modify bw, cs related timing */
> - remodify_sdram_params(sdram_params);
> + pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
> + sdram_params->base.dramtype);
> +
> + if (cap_info->bw == 2)
> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
> + else
> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
> +
> /* reinit sdram by real dram cap */
> sdram_init(dram, sdram_params, 0);
>
> /* redetect cs1 row */
> - sdram_ch.cs1_row =
> - dram_detect_cs1_row(sdram_params, 0);
> + sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
> + if (cap_info->cs1_row) {
> + sys_reg = readl(&dram->grf->os_reg[2]);
> + sys_reg3 = readl(&dram->grf->os_reg[3]);
> + SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
> + sys_reg, sys_reg3, 0);
> + writel(sys_reg, &dram->grf->os_reg[2]);
> + writel(sys_reg3, &dram->grf->os_reg[3]);
> + }
> +
> + sdram_print_ddr_info(&sdram_params->ch.cap_info,
> + &sdram_params->base, 0);
>
> return 0;
> }
>
^ permalink raw reply [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver【请注意,邮件由u-boot-bounces@lists.denx.de代发】
2019-10-22 17:37 ` Matwey V. Kornilov
@ 2019-10-23 8:49 ` Kever Yang
2019-10-23 9:01 ` Matwey V. Kornilov
0 siblings, 1 reply; 14+ messages in thread
From: Kever Yang @ 2019-10-23 8:49 UTC (permalink / raw)
To: u-boot
Matway,
On 2019/10/23 上午1:37, Matwey V. Kornilov wrote:
> Hi,
>
> Thank you. Currently, I see the following at Rock64 SBC:
>
> U-Boot TPL 2019.10-00024-g8b580d5b93 (Oct 22 2019 - 20:29:01)
> data training error
> LPDDR3, 800MHz
> BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=2048MB
> Trying to boot from BOOTROM
> Returning to boot ROM...
I test with my rock64 SBC 4GB, it does not have a "data training error",
does the system later
works fine?
U-Boot TPL 2019.10-00019-g26c7312fa6 (Oct 23 2019 - 16:43:35)
LPDDR3, 800MHz
BW=32 Col=11 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=4096MB
Trying to boot from BOOTROM
Returning to boot ROM...
Thanks,
- Kever
>
>
> The rest seems to be working fine, but I am confused by "data training
> error" message.
>
>
> 22.10.2019 11:04, Kever Yang пишет:
>> From: YouMin Chen <cym@rock-chips.com>
>>
>> RK3328 has a similar controller and phy with PX30, so we can use the
>> common driver for it and remove the duplicate codes.
>>
>> Signed-off-by: YouMin Chen <cym@rock-chips.com>
>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>> ---
>>
>> arch/arm/dts/rk3328-sdram-ddr3-666.dtsi | 4 +
>> arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi | 4 +
>> arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi | 4 +
>> .../include/asm/arch-rockchip/sdram_rk3328.h | 419 +++-------
>> arch/arm/mach-rockchip/Kconfig | 1 +
>> configs/evb-rk3328_defconfig | 2 +-
>> configs/rock64-rk3328_defconfig | 2 +-
>> drivers/ram/rockchip/Makefile | 2 +-
>> drivers/ram/rockchip/sdram_rk3328.c | 764 ++++--------------
>> 9 files changed, 296 insertions(+), 906 deletions(-)
>>
>> diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>> index d99e7e0352..3e88ed443b 100644
>> --- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>> +++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>> @@ -14,6 +14,8 @@
>> 0x0
>> 0x10
>> 0x10
>> + 0x10
>> + 0x10
>> 0
>>
>> 0x9028b189
>> @@ -26,6 +28,8 @@
>>
>> 333
>> 3
>> + 1
>> + 0
>> 0
>>
>> 0x00000000
>> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>> index cc0011cf7b..d63c761a02 100644
>> --- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>> @@ -14,6 +14,8 @@
>> 0x0
>> 0x10
>> 0x10
>> + 0x10
>> + 0x10
>> 0
>>
>> 0x98899459
>> @@ -27,6 +29,8 @@
>> 800
>> 6
>> 1
>> + 0
>> + 1
>>
>> 0x00000000
>> 0x43041008
>> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>> index 62d809e833..b9d3b3b948 100644
>> --- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>> @@ -14,6 +14,8 @@
>> 0x0
>> 0x10
>> 0x10
>> + 0x10
>> + 0x10
>> 0
>>
>> 0x0c48a18a
>> @@ -26,6 +28,8 @@
>>
>> 333
>> 6
>> + 1
>> + 0
>> 0
>>
>> 0x00000000
>> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>> index c747b461a1..10923505d6 100644
>> --- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>> +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>> @@ -7,197 +7,13 @@
>> #ifndef _ASM_ARCH_SDRAM_RK3328_H
>> #define _ASM_ARCH_SDRAM_RK3328_H
>> #include <asm/arch-rockchip/sdram_common.h>
>> +#include <asm/arch-rockchip/sdram_pctl_px30.h>
>> +#include <asm/arch-rockchip/sdram_phy_px30.h>
>> +#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
>>
>> #define SR_IDLE 93
>> #define PD_IDLE 13
>> #define SDRAM_ADDR 0x00000000
>> -#define PATTERN (0x5aa5f00f)
>> -
>> -/* ddr pctl registers define */
>> -#define DDR_PCTL2_MSTR 0x0
>> -#define DDR_PCTL2_STAT 0x4
>> -#define DDR_PCTL2_MSTR1 0x8
>> -#define DDR_PCTL2_MRCTRL0 0x10
>> -#define DDR_PCTL2_MRCTRL1 0x14
>> -#define DDR_PCTL2_MRSTAT 0x18
>> -#define DDR_PCTL2_MRCTRL2 0x1c
>> -#define DDR_PCTL2_DERATEEN 0x20
>> -#define DDR_PCTL2_DERATEINT 0x24
>> -#define DDR_PCTL2_PWRCTL 0x30
>> -#define DDR_PCTL2_PWRTMG 0x34
>> -#define DDR_PCTL2_HWLPCTL 0x38
>> -#define DDR_PCTL2_RFSHCTL0 0x50
>> -#define DDR_PCTL2_RFSHCTL1 0x54
>> -#define DDR_PCTL2_RFSHCTL2 0x58
>> -#define DDR_PCTL2_RFSHCTL4 0x5c
>> -#define DDR_PCTL2_RFSHCTL3 0x60
>> -#define DDR_PCTL2_RFSHTMG 0x64
>> -#define DDR_PCTL2_RFSHTMG1 0x68
>> -#define DDR_PCTL2_RFSHCTL5 0x6c
>> -#define DDR_PCTL2_INIT0 0xd0
>> -#define DDR_PCTL2_INIT1 0xd4
>> -#define DDR_PCTL2_INIT2 0xd8
>> -#define DDR_PCTL2_INIT3 0xdc
>> -#define DDR_PCTL2_INIT4 0xe0
>> -#define DDR_PCTL2_INIT5 0xe4
>> -#define DDR_PCTL2_INIT6 0xe8
>> -#define DDR_PCTL2_INIT7 0xec
>> -#define DDR_PCTL2_DIMMCTL 0xf0
>> -#define DDR_PCTL2_RANKCTL 0xf4
>> -#define DDR_PCTL2_CHCTL 0xfc
>> -#define DDR_PCTL2_DRAMTMG0 0x100
>> -#define DDR_PCTL2_DRAMTMG1 0x104
>> -#define DDR_PCTL2_DRAMTMG2 0x108
>> -#define DDR_PCTL2_DRAMTMG3 0x10c
>> -#define DDR_PCTL2_DRAMTMG4 0x110
>> -#define DDR_PCTL2_DRAMTMG5 0x114
>> -#define DDR_PCTL2_DRAMTMG6 0x118
>> -#define DDR_PCTL2_DRAMTMG7 0x11c
>> -#define DDR_PCTL2_DRAMTMG8 0x120
>> -#define DDR_PCTL2_DRAMTMG9 0x124
>> -#define DDR_PCTL2_DRAMTMG10 0x128
>> -#define DDR_PCTL2_DRAMTMG11 0x12c
>> -#define DDR_PCTL2_DRAMTMG12 0x130
>> -#define DDR_PCTL2_DRAMTMG13 0x134
>> -#define DDR_PCTL2_DRAMTMG14 0x138
>> -#define DDR_PCTL2_DRAMTMG15 0x13c
>> -#define DDR_PCTL2_DRAMTMG16 0x140
>> -#define DDR_PCTL2_ZQCTL0 0x180
>> -#define DDR_PCTL2_ZQCTL1 0x184
>> -#define DDR_PCTL2_ZQCTL2 0x188
>> -#define DDR_PCTL2_ZQSTAT 0x18c
>> -#define DDR_PCTL2_DFITMG0 0x190
>> -#define DDR_PCTL2_DFITMG1 0x194
>> -#define DDR_PCTL2_DFILPCFG0 0x198
>> -#define DDR_PCTL2_DFILPCFG1 0x19c
>> -#define DDR_PCTL2_DFIUPD0 0x1a0
>> -#define DDR_PCTL2_DFIUPD1 0x1a4
>> -#define DDR_PCTL2_DFIUPD2 0x1a8
>> -#define DDR_PCTL2_DFIMISC 0x1b0
>> -#define DDR_PCTL2_DFITMG2 0x1b4
>> -#define DDR_PCTL2_DFITMG3 0x1b8
>> -#define DDR_PCTL2_DFISTAT 0x1bc
>> -#define DDR_PCTL2_DBICTL 0x1c0
>> -#define DDR_PCTL2_ADDRMAP0 0x200
>> -#define DDR_PCTL2_ADDRMAP1 0x204
>> -#define DDR_PCTL2_ADDRMAP2 0x208
>> -#define DDR_PCTL2_ADDRMAP3 0x20c
>> -#define DDR_PCTL2_ADDRMAP4 0x210
>> -#define DDR_PCTL2_ADDRMAP5 0x214
>> -#define DDR_PCTL2_ADDRMAP6 0x218
>> -#define DDR_PCTL2_ADDRMAP7 0x21c
>> -#define DDR_PCTL2_ADDRMAP8 0x220
>> -#define DDR_PCTL2_ADDRMAP9 0x224
>> -#define DDR_PCTL2_ADDRMAP10 0x228
>> -#define DDR_PCTL2_ADDRMAP11 0x22c
>> -#define DDR_PCTL2_ODTCFG 0x240
>> -#define DDR_PCTL2_ODTMAP 0x244
>> -#define DDR_PCTL2_SCHED 0x250
>> -#define DDR_PCTL2_SCHED1 0x254
>> -#define DDR_PCTL2_PERFHPR1 0x25c
>> -#define DDR_PCTL2_PERFLPR1 0x264
>> -#define DDR_PCTL2_PERFWR1 0x26c
>> -#define DDR_PCTL2_DQMAP0 0x280
>> -#define DDR_PCTL2_DQMAP1 0x284
>> -#define DDR_PCTL2_DQMAP2 0x288
>> -#define DDR_PCTL2_DQMAP3 0x28c
>> -#define DDR_PCTL2_DQMAP4 0x290
>> -#define DDR_PCTL2_DQMAP5 0x294
>> -#define DDR_PCTL2_DBG0 0x300
>> -#define DDR_PCTL2_DBG1 0x304
>> -#define DDR_PCTL2_DBGCAM 0x308
>> -#define DDR_PCTL2_DBGCMD 0x30c
>> -#define DDR_PCTL2_DBGSTAT 0x310
>> -#define DDR_PCTL2_SWCTL 0x320
>> -#define DDR_PCTL2_SWSTAT 0x324
>> -#define DDR_PCTL2_POISONCFG 0x36c
>> -#define DDR_PCTL2_POISONSTAT 0x370
>> -#define DDR_PCTL2_ADVECCINDEX 0x374
>> -#define DDR_PCTL2_ADVECCSTAT 0x378
>> -#define DDR_PCTL2_PSTAT 0x3fc
>> -#define DDR_PCTL2_PCCFG 0x400
>> -#define DDR_PCTL2_PCFGR_n 0x404
>> -#define DDR_PCTL2_PCFGW_n 0x408
>> -#define DDR_PCTL2_PCTRL_n 0x490
>> -
>> -/* PCTL2_MRSTAT */
>> -#define MR_WR_BUSY BIT(0)
>> -
>> -/* PHY_REG0 */
>> -#define DIGITAL_DERESET BIT(3)
>> -#define ANALOG_DERESET BIT(2)
>> -#define DIGITAL_RESET (0 << 3)
>> -#define ANALOG_RESET (0 << 2)
>> -
>> -/* PHY_REG1 */
>> -#define PHY_DDR2 (0)
>> -#define PHY_LPDDR2 (1)
>> -#define PHY_DDR3 (2)
>> -#define PHY_LPDDR3 (3)
>> -#define PHY_DDR4 (4)
>> -#define PHY_BL_4 (0 << 2)
>> -#define PHY_BL_8 BIT(2)
>> -
>> -/* PHY_REG2 */
>> -#define PHY_DTT_EN BIT(0)
>> -#define PHY_DTT_DISB (0 << 0)
>> -#define PHY_WRITE_LEVELING_EN BIT(2)
>> -#define PHY_WRITE_LEVELING_DISB (0 << 2)
>> -#define PHY_SELECT_CS0 (2)
>> -#define PHY_SELECT_CS1 (1)
>> -#define PHY_SELECT_CS0_1 (0)
>> -#define PHY_WRITE_LEVELING_SELECTCS(n) (n << 6)
>> -#define PHY_DATA_TRAINING_SELECTCS(n) (n << 4)
>> -
>> -#define PHY_DDR3_RON_RTT_DISABLE (0)
>> -#define PHY_DDR3_RON_RTT_451ohm (1)
>> -#define PHY_DDR3_RON_RTT_225ohm (2)
>> -#define PHY_DDR3_RON_RTT_150ohm (3)
>> -#define PHY_DDR3_RON_RTT_112ohm (4)
>> -#define PHY_DDR3_RON_RTT_90ohm (5)
>> -#define PHY_DDR3_RON_RTT_75ohm (6)
>> -#define PHY_DDR3_RON_RTT_64ohm (7)
>> -#define PHY_DDR3_RON_RTT_56ohm (16)
>> -#define PHY_DDR3_RON_RTT_50ohm (17)
>> -#define PHY_DDR3_RON_RTT_45ohm (18)
>> -#define PHY_DDR3_RON_RTT_41ohm (19)
>> -#define PHY_DDR3_RON_RTT_37ohm (20)
>> -#define PHY_DDR3_RON_RTT_34ohm (21)
>> -#define PHY_DDR3_RON_RTT_33ohm (22)
>> -#define PHY_DDR3_RON_RTT_30ohm (23)
>> -#define PHY_DDR3_RON_RTT_28ohm (24)
>> -#define PHY_DDR3_RON_RTT_26ohm (25)
>> -#define PHY_DDR3_RON_RTT_25ohm (26)
>> -#define PHY_DDR3_RON_RTT_23ohm (27)
>> -#define PHY_DDR3_RON_RTT_22ohm (28)
>> -#define PHY_DDR3_RON_RTT_21ohm (29)
>> -#define PHY_DDR3_RON_RTT_20ohm (30)
>> -#define PHY_DDR3_RON_RTT_19ohm (31)
>> -
>> -#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30)
>> -#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31)
>>
>> /* noc registers define */
>> #define DDRCONF 0x8
>> @@ -220,16 +36,16 @@
>> #define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
>>
>> /* CRU_SOFTRESET_CON5 */
>> -#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | (n << 15))
>> -#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | (n << 14))
>> -#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | (n << 13))
>> -#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | (n << 12))
>> -#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | (n << 11))
>> -#define msch_srstn_req(n) (((0x1 << 9) << 16) | (n << 9))
>> -#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | (n << 8))
>> -#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | (n << 7))
>> +#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | ((n) << 15))
>> +#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | ((n) << 14))
>> +#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | ((n) << 13))
>> +#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | ((n) << 12))
>> +#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | ((n) << 11))
>> +#define msch_srstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
>> +#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | ((n) << 8))
>> +#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | ((n) << 7))
>> /* CRU_SOFTRESET_CON9 */
>> -#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | (n << 9))
>> +#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
>>
>> /* CRU register */
>> #define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
>> @@ -256,56 +72,46 @@
>> #define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
>> #define REFDIV(n) ((0x3F << 16) | (n))
>>
>> -union noc_ddrtiming {
>> - u32 d32;
>> - struct {
>> - unsigned acttoact:6;
>> - unsigned rdtomiss:6;
>> - unsigned wrtomiss:6;
>> - unsigned burstlen:3;
>> - unsigned rdtowr:5;
>> - unsigned wrtord:5;
>> - unsigned bwratio:1;
>> - } b;
>> -} NOC_TIMING_T;
>> -
>> -union noc_activate {
>> - u32 d32;
>> - struct {
>> - unsigned rrd:4;
>> - unsigned faw:6;
>> - unsigned fawbank:1;
>> - unsigned reserved1:21;
>> - } b;
>> -};
>> -
>> -union noc_devtodev {
>> - u32 d32;
>> - struct {
>> - unsigned busrdtord:2;
>> - unsigned busrdtowr:2;
>> - unsigned buswrtord:2;
>> - unsigned reserved2:26;
>> - } b;
>> -};
>> -
>> -union noc_ddr4timing {
>> - u32 d32;
>> - struct {
>> - unsigned ccdl:3;
>> - unsigned wrtordl:5;
>> - unsigned rrdl:4;
>> - unsigned reserved2:20;
>> - } b;
>> +u16 ddr_cfg_2_rbc[] = {
>> + /*
>> + * [5:4] row(13+n)
>> + * [3] cs(0:0 cs, 1:2 cs)
>> + * [2] bank(0:0bank,1:8bank)
>> + * [1:0] col(11+n)
>> + */
>> + /* row, cs, bank, col */
>> + ((3 << 4) | (0 << 3) | (1 << 2) | 0),
>> + ((3 << 4) | (0 << 3) | (1 << 2) | 1),
>> + ((2 << 4) | (0 << 3) | (1 << 2) | 2),
>> + ((3 << 4) | (0 << 3) | (1 << 2) | 2),
>> + ((2 << 4) | (0 << 3) | (1 << 2) | 3),
>> + ((3 << 4) | (1 << 3) | (1 << 2) | 0),
>> + ((3 << 4) | (1 << 3) | (1 << 2) | 1),
>> + ((2 << 4) | (1 << 3) | (1 << 2) | 2),
>> + ((3 << 4) | (0 << 3) | (0 << 2) | 1),
>> + ((2 << 4) | (0 << 3) | (1 << 2) | 1),
>> };
>>
>> -union noc_ddrmode {
>> - u32 d32;
>> - struct {
>> - unsigned autoprecharge:1;
>> - unsigned bwratioextended:1;
>> - unsigned reserved3:30;
>> - } b;
>> +u16 ddr4_cfg_2_rbc[] = {
>> + /***************************
>> + * [6] cs 0:0cs 1:2 cs
>> + * [5:3] row(13+n)
>> + * [2] cs(0:0 cs, 1:2 cs)
>> + * [1] bw 0: 16bit 1:32bit
>> + * [0] diebw 0:8bit 1:16bit
>> + ***************************/
>> + /* cs, row, cs, bw, diebw */
>> + ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
>> + ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
>> + ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
>> + ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
>> + ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
>> + ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
>> + ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
>> + ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
>> + ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
>> + ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
>> + ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
>> };
>>
>> u32 addrmap[21][9] = {
>> @@ -356,17 +162,65 @@ u32 addrmap[21][9] = {
>> 0x07070707, 0x00000f07, 0x3f00}
>> };
>>
>> -struct rk3328_msch_timings {
>> - union noc_ddrtiming ddrtiming;
>> - union noc_ddrmode ddrmode;
>> - u32 readlatency;
>> - union noc_activate activate;
>> - union noc_devtodev devtodev;
>> - union noc_ddr4timing ddr4timing;
>> - u32 agingx0;
>> +struct rk3328_ddr_grf_regs {
>> + u32 ddr_grf_con[4];
>> + u32 reserved[(0x100 - 0x10) / 4];
>> + u32 ddr_grf_status[11];
>> };
>>
>> -struct rk3328_msch_regs {
>> +union noc_ddrtiming {
>> + u32 d32;
>> + struct {
>> + unsigned acttoact:6;
>> + unsigned rdtomiss:6;
>> + unsigned wrtomiss:6;
>> + unsigned burstlen:3;
>> + unsigned rdtowr:5;
>> + unsigned wrtord:5;
>> + unsigned bwratio:1;
>> + } b;
>> +};
>> +
>> +union noc_activate {
>> + u32 d32;
>> + struct {
>> + unsigned rrd:4;
>> + unsigned faw:6;
>> + unsigned fawbank:1;
>> + unsigned reserved1:21;
>> + } b;
>> +};
>> +
>> +union noc_devtodev {
>> + u32 d32;
>> + struct {
>> + unsigned busrdtord:2;
>> + unsigned busrdtowr:2;
>> + unsigned buswrtord:2;
>> + unsigned reserved2:26;
>> + } b;
>> +};
>> +
>> +union noc_ddr4timing {
>> + u32 d32;
>> + struct {
>> + unsigned ccdl:3;
>> + unsigned wrtordl:5;
>> + unsigned rrdl:4;
>> + unsigned reserved2:20;
>> + } b;
>> +};
>> +
>> +union noc_ddrmode {
>> + u32 d32;
>> + struct {
>> + unsigned autoprecharge:1;
>> + unsigned bwratioextended:1;
>> + unsigned reserved3:30;
>> + } b;
>> +};
>> +
>> +struct msch_regs {
>> u32 coreid;
>> u32 revisionid;
>> u32 ddrconf;
>> @@ -385,58 +239,27 @@ struct rk3328_msch_regs {
>> u32 ddr4_timing;
>> };
>>
>> -struct rk3328_ddr_grf_regs {
>> - u32 ddr_grf_con[4];
>> - u32 reserved[(0x100 - 0x10) / 4];
>> - u32 ddr_grf_status[11];
>> -};
>> -
>> -struct rk3328_ddr_pctl_regs {
>> - u32 pctl[30][2];
>> -};
>> -
>> -struct rk3328_ddr_phy_regs {
>> - u32 phy[5][2];
>> -};
>> -
>> -struct rk3328_ddr_skew {
>> - u32 a0_a1_skew[15];
>> - u32 cs0_dm0_skew[11];
>> - u32 cs0_dm1_skew[11];
>> - u32 cs0_dm2_skew[11];
>> - u32 cs0_dm3_skew[11];
>> - u32 cs1_dm0_skew[11];
>> - u32 cs1_dm1_skew[11];
>> - u32 cs1_dm2_skew[11];
>> - u32 cs1_dm3_skew[11];
>> +struct sdram_msch_timings {
>> + union noc_ddrtiming ddrtiming;
>> + union noc_ddrmode ddrmode;
>> + u32 readlatency;
>> + union noc_activate activate;
>> + union noc_devtodev devtodev;
>> + union noc_ddr4timing ddr4timing;
>> + u32 agingx0;
>> };
>>
>> struct rk3328_sdram_channel {
>> - unsigned int rank;
>> - unsigned int col;
>> - /* 3:8bank, 2:4bank */
>> - unsigned int bk;
>> - /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
>> - unsigned int bw;
>> - /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
>> - unsigned int dbw;
>> - unsigned int row_3_4;
>> - unsigned int cs0_row;
>> - unsigned int cs1_row;
>> - unsigned int ddrconfig;
>> - struct rk3328_msch_timings noc_timings;
>> + struct sdram_cap_info cap_info;
>> + struct sdram_msch_timings noc_timings;
>> };
>>
>> struct rk3328_sdram_params {
>> struct rk3328_sdram_channel ch;
>> - unsigned int ddr_freq;
>> - unsigned int dramtype;
>> - unsigned int odt;
>> - struct rk3328_ddr_pctl_regs pctl_regs;
>> - struct rk3328_ddr_phy_regs phy_regs;
>> - struct rk3328_ddr_skew skew;
>> + struct sdram_base_params base;
>> + struct ddr_pctl_regs pctl_regs;
>> + struct ddr_phy_regs phy_regs;
>> + struct ddr_phy_skew skew;
>> };
>>
>> -#define PHY_REG(base, n) (base + 4 * (n))
>> -
>> #endif
>> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
>> index f5a80b4f0c..5f1ad51cac 100644
>> --- a/arch/arm/mach-rockchip/Kconfig
>> +++ b/arch/arm/mach-rockchip/Kconfig
>> @@ -115,6 +115,7 @@ config ROCKCHIP_RK3328
>> select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
>> select TPL_NEEDS_SEPARATE_STACK if TPL
>> imply ROCKCHIP_COMMON_BOARD
>> + imply ROCKCHIP_SDRAM_COMMON
>> imply SPL_ROCKCHIP_COMMON_BOARD
>> imply SPL_SERIAL_SUPPORT
>> imply TPL_SERIAL_SUPPORT
>> diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
>> index 37610774c1..fdabee842d 100644
>> --- a/configs/evb-rk3328_defconfig
>> +++ b/configs/evb-rk3328_defconfig
>> @@ -46,7 +46,6 @@ CONFIG_SPL_SYSCON=y
>> CONFIG_TPL_SYSCON=y
>> CONFIG_CLK=y
>> CONFIG_SPL_CLK=y
>> -CONFIG_TPL_CLK=y
>> CONFIG_FASTBOOT_BUF_ADDR=0x800800
>> CONFIG_FASTBOOT_FLASH=y
>> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
>> @@ -77,6 +76,7 @@ CONFIG_DEBUG_UART_SHIFT=2
>> CONFIG_DEBUG_UART_ANNOUNCE=y
>> CONFIG_DEBUG_UART_SKIP_INIT=y
>> CONFIG_SYSRESET=y
>> +# CONFIG_TPL_SYSRESET is not set
>> CONFIG_USB=y
>> CONFIG_USB_XHCI_HCD=y
>> CONFIG_USB_XHCI_DWC3=y
>> diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
>> index 3ab0af1158..0fb4b42c6e 100644
>> --- a/configs/rock64-rk3328_defconfig
>> +++ b/configs/rock64-rk3328_defconfig
>> @@ -49,7 +49,6 @@ CONFIG_SPL_SYSCON=y
>> CONFIG_TPL_SYSCON=y
>> CONFIG_CLK=y
>> CONFIG_SPL_CLK=y
>> -CONFIG_TPL_CLK=y
>> CONFIG_FASTBOOT_BUF_ADDR=0x800800
>> CONFIG_FASTBOOT_FLASH=y
>> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
>> @@ -79,6 +78,7 @@ CONFIG_DM_RESET=y
>> CONFIG_BAUDRATE=1500000
>> CONFIG_DEBUG_UART_SHIFT=2
>> CONFIG_SYSRESET=y
>> +# CONFIG_TPL_SYSRESET is not set
>> CONFIG_USB=y
>> CONFIG_USB_XHCI_HCD=y
>> CONFIG_USB_XHCI_DWC3=y
>> diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
>> index 3d4f2f4ebf..3f19fa09a5 100644
>> --- a/drivers/ram/rockchip/Makefile
>> +++ b/drivers/ram/rockchip/Makefile
>> @@ -9,5 +9,5 @@ obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
>> obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
>> obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
>> obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
>> -obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
>> +obj-$(CONFIG_ROCKCHIP_RK3328) += sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
>> obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
>> diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
>> index e7919337ea..72ae7555bc 100644
>> --- a/drivers/ram/rockchip/sdram_rk3328.c
>> +++ b/drivers/ram/rockchip/sdram_rk3328.c
>> @@ -20,11 +20,11 @@
>>
>> struct dram_info {
>> #ifdef CONFIG_TPL_BUILD
>> - struct rk3328_ddr_pctl_regs *pctl;
>> - struct rk3328_ddr_phy_regs *phy;
>> + struct ddr_pctl_regs *pctl;
>> + struct ddr_phy_regs *phy;
>> struct clk ddr_clk;
>> struct rk3328_cru *cru;
>> - struct rk3328_msch_regs *msch;
>> + struct msch_regs *msch;
>> struct rk3328_ddr_grf_regs *ddr_grf;
>> #endif
>> struct ram_info info;
>> @@ -71,10 +71,11 @@ static void rkclk_ddr_reset(struct dram_info *dram,
>> writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
>> }
>>
>> -static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
>> +static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
>> {
>> unsigned int refdiv, postdiv1, postdiv2, fbdiv;
>> int delay = 1000;
>> + u32 mhz = hz / MHZ;
>>
>> refdiv = 1;
>> if (mhz <= 300) {
>> @@ -122,52 +123,7 @@ static void rkclk_configure_ddr(struct dram_info *dram,
>> clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
>>
>> /* for inno ddr phy need 2*freq */
>> - rkclk_set_dpll(dram, sdram_params->ddr_freq * 2);
>> -}
>> -
>> -static void phy_soft_reset(struct dram_info *dram)
>> -{
>> - void __iomem *phy_base = dram->phy;
>> -
>> - clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
>> - udelay(1);
>> - setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
>> - udelay(5);
>> - setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
>> - udelay(1);
>> -}
>> -
>> -static int pctl_cfg(struct dram_info *dram,
>> - struct rk3328_sdram_params *sdram_params)
>> -{
>> - u32 i;
>> - void __iomem *pctl_base = dram->pctl;
>> -
>> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
>> - writel(sdram_params->pctl_regs.pctl[i][1],
>> - pctl_base + sdram_params->pctl_regs.pctl[i][0]);
>> - }
>> - clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
>> - (0xff << 16) | 0x1f,
>> - ((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
>> - /*
>> - * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
>> - * hw_lp_idle_x32=1
>> - */
>> - if (sdram_params->dramtype == LPDDR3) {
>> - setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
>> - clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
>> - 0xf << 4,
>> - 2 << 4);
>> - }
>> - clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
>> - 0xfff << 16,
>> - 1 << 16);
>> - /* disable zqcs */
>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
>> - setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
>> -
>> - return 0;
>> + rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ * 2);
>> }
>>
>> /* return ddrconfig value
>> @@ -175,62 +131,39 @@ static int pctl_cfg(struct dram_info *dram,
>> * other, the ddrconfig value
>> * only support cs0_row >= cs1_row
>> */
>> -static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
>> +static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
>> {
>> - static const u16 ddr_cfg_2_rbc[] = {
>> - /***************************
>> - * [5:4] row(13+n)
>> - * [3] cs(0:0 cs, 1:2 cs)
>> - * [2] bank(0:0bank,1:8bank)
>> - * [1:0] col(11+n)
>> - ****************************/
>> - /* row, cs, bank, col */
>> - ((3 << 4) | (0 << 3) | (1 << 2) | 0),
>> - ((3 << 4) | (0 << 3) | (1 << 2) | 1),
>> - ((2 << 4) | (0 << 3) | (1 << 2) | 2),
>> - ((3 << 4) | (0 << 3) | (1 << 2) | 2),
>> - ((2 << 4) | (0 << 3) | (1 << 2) | 3),
>> - ((3 << 4) | (1 << 3) | (1 << 2) | 0),
>> - ((3 << 4) | (1 << 3) | (1 << 2) | 1),
>> - ((2 << 4) | (1 << 3) | (1 << 2) | 2),
>> - ((3 << 4) | (0 << 3) | (0 << 2) | 1),
>> - ((2 << 4) | (0 << 3) | (1 << 2) | 1),
>> - };
>> -
>> - static const u16 ddr4_cfg_2_rbc[] = {
>> - /***************************
>> - * [6] cs 0:0cs 1:2 cs
>> - * [5:3] row(13+n)
>> - * [2] cs(0:0 cs, 1:2 cs)
>> - * [1] bw 0: 16bit 1:32bit
>> - * [0] diebw 0:8bit 1:16bit
>> - ***************************/
>> - /* cs, row, cs, bw, diebw */
>> - ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
>> - ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
>> - ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
>> - ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
>> - ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
>> - ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
>> - ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
>> - ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
>> - ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
>> - ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
>> - ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
>> - };
>> -
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>> u32 cs, bw, die_bw, col, row, bank;
>> + u32 cs1_row;
>> u32 i, tmp;
>> u32 ddrconf = -1;
>>
>> - cs = sdram_ch.rank;
>> - bw = sdram_ch.bw;
>> - die_bw = sdram_ch.dbw;
>> - col = sdram_ch.col;
>> - row = sdram_ch.cs0_row;
>> - bank = sdram_ch.bk;
>> + cs = cap_info->rank;
>> + bw = cap_info->bw;
>> + die_bw = cap_info->dbw;
>> + col = cap_info->col;
>> + row = cap_info->cs0_row;
>> + cs1_row = cap_info->cs1_row;
>> + bank = cap_info->bk;
>> +
>> + if (sdram_params->base.dramtype == DDR4) {
>> + /* when DDR_TEST, CS always at MSB position for easy test */
>> + if (cs == 2 && row == cs1_row) {
>> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
>> + tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
>> + die_bw;
>> + for (i = 17; i < 21; i++) {
>> + if (((tmp & 0x7) ==
>> + (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
>> + ((tmp & 0x3c) <=
>> + (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
>> + ddrconf = i;
>> + goto out;
>> + }
>> + }
>> + }
>>
>> - if (sdram_params->dramtype == DDR4) {
>> tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
>> for (i = 10; i < 17; i++) {
>> if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
>> @@ -246,6 +179,18 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
>> goto out;
>> }
>>
>> + /* when DDR_TEST, CS always at MSB position for easy test */
>> + if (cs == 2 && row == cs1_row) {
>> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
>> + for (i = 5; i < 8; i++) {
>> + if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
>> + 0x3)) {
>> + ddrconf = i;
>> + goto out;
>> + }
>> + }
>> + }
>> +
>> tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
>> for (i = 0; i < 5; i++)
>> if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
>> @@ -257,23 +202,11 @@ static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params
>>
>> out:
>> if (ddrconf > 20)
>> - printf("calculate_ddrconfig error\n");
>> + printf("calculate ddrconfig error\n");
>>
>> return ddrconf;
>> }
>>
>> -/* n: Unit bytes */
>> -static void copy_to_reg(u32 *dest, u32 *src, u32 n)
>> -{
>> - int i;
>> -
>> - for (i = 0; i < n / sizeof(u32); i++) {
>> - writel(*src, dest);
>> - src++;
>> - dest++;
>> - }
>> -}
>> -
>> /*******
>> * calculate controller dram address map, and setting to register.
>> * argument sdram_ch.ddrconf must be right value before
>> @@ -282,273 +215,42 @@ static void copy_to_reg(u32 *dest, u32 *src, u32 n)
>> static void set_ctl_address_map(struct dram_info *dram,
>> struct rk3328_sdram_params *sdram_params)
>> {
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>> void __iomem *pctl_base = dram->pctl;
>>
>> - copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
>> - &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
>> - if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
>> + sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
>> + &addrmap[cap_info->ddrconfig][0], 9 * 4);
>> + if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
>> setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
>> - if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
>> + if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
>> setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
>>
>> - if (sdram_ch.rank == 1)
>> + if (cap_info->rank == 1)
>> clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
>> }
>>
>> -static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
>> -{
>> - u32 tmp;
>> - void __iomem *phy_base = dram->phy;
>> -
>> - setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
>> - clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
>> - setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
>> - clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
>> - setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
>> - clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
>> - setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
>> - clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
>> - setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
>> - clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
>> -
>> - if (freq <= 400)
>> - /* DLL bypass */
>> - setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
>> - else
>> - clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
>> - if (freq <= 680)
>> - tmp = 2;
>> - else
>> - tmp = 1;
>> - writel(tmp, PHY_REG(phy_base, 0x28));
>> - writel(tmp, PHY_REG(phy_base, 0x38));
>> - writel(tmp, PHY_REG(phy_base, 0x48));
>> - writel(tmp, PHY_REG(phy_base, 0x58));
>> -}
>> -
>> -static void set_ds_odt(struct dram_info *dram,
>> - struct rk3328_sdram_params *sdram_params)
>> -{
>> - u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
>> - void __iomem *phy_base = dram->phy;
>> -
>> - if (sdram_params->dramtype == DDR3) {
>> - cmd_drv = PHY_DDR3_RON_RTT_34ohm;
>> - clk_drv = PHY_DDR3_RON_RTT_45ohm;
>> - dqs_drv = PHY_DDR3_RON_RTT_34ohm;
>> - dqs_odt = PHY_DDR3_RON_RTT_225ohm;
>> - } else {
>> - cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
>> - clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
>> - dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
>> - dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
>> - }
>> - /* DS */
>> - writel(cmd_drv, PHY_REG(phy_base, 0x11));
>> - clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
>> - writel(clk_drv, PHY_REG(phy_base, 0x16));
>> - writel(clk_drv, PHY_REG(phy_base, 0x18));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x20));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x2f));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x30));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x3f));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x40));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x4f));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x50));
>> - writel(dqs_drv, PHY_REG(phy_base, 0x5f));
>> - /* ODT */
>> - writel(dqs_odt, PHY_REG(phy_base, 0x21));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x2e));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x31));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x3e));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x41));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x4e));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x51));
>> - writel(dqs_odt, PHY_REG(phy_base, 0x5e));
>> -}
>> -
>> -static void phy_cfg(struct dram_info *dram,
>> - struct rk3328_sdram_params *sdram_params)
>> -{
>> - u32 i;
>> - void __iomem *phy_base = dram->phy;
>> -
>> - phy_dll_bypass_set(dram, sdram_params->ddr_freq);
>> - for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
>> - writel(sdram_params->phy_regs.phy[i][1],
>> - phy_base + sdram_params->phy_regs.phy[i][0]);
>> - }
>> - if (sdram_ch.bw == 2) {
>> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
>> - } else {
>> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
>> - /* disable DQS2,DQS3 tx dll for saving power */
>> - clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
>> - clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
>> - }
>> - set_ds_odt(dram, sdram_params);
>> - /* deskew */
>> - setbits_le32(PHY_REG(phy_base, 2), 8);
>> - copy_to_reg(PHY_REG(phy_base, 0xb0),
>> - &sdram_params->skew.a0_a1_skew[0], 15 * 4);
>> - copy_to_reg(PHY_REG(phy_base, 0x70),
>> - &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
>> - copy_to_reg(PHY_REG(phy_base, 0xc0),
>> - &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
>> -}
>> -
>> -static int update_refresh_reg(struct dram_info *dram)
>> -{
>> - void __iomem *pctl_base = dram->pctl;
>> - u32 ret;
>> -
>> - ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
>> - writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
>> -
>> - return 0;
>> -}
>> -
>> static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
>> -{
>> - u32 ret;
>> - u32 dis_auto_zq = 0;
>> - void __iomem *pctl_base = dram->pctl;
>> - void __iomem *phy_base = dram->phy;
>> -
>> - /* disable zqcs */
>> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
>> - (1ul << 31))) {
>> - dis_auto_zq = 1;
>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>> - }
>> - /* disable auto refresh */
>> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>> - update_refresh_reg(dram);
>> -
>> - if (dramtype == DDR4) {
>> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
>> - }
>> - /* choose training cs */
>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
>> - /* enable gate training */
>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
>> - udelay(50);
>> - ret = readl(PHY_REG(phy_base, 0xff));
>> - /* disable gate training */
>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
>> - /* restore zqcs */
>> - if (dis_auto_zq)
>> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>> - /* restore auto refresh */
>> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>> - update_refresh_reg(dram);
>> -
>> - if (dramtype == DDR4) {
>> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
>> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
>> - }
>> -
>> - if (ret & 0x10) {
>> - ret = -1;
>> - } else {
>> - ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
>> - ret = (ret == 0) ? 0 : -1;
>> - }
>> - return ret;
>> -}
>> -
>> -/* rank = 1: cs0
>> - * rank = 2: cs1
>> - * rank = 3: cs0 & cs1
>> - * note: be careful of keep mr original val
>> - */
>> -static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 arg,
>> - u32 dramtype)
>> {
>> void __iomem *pctl_base = dram->pctl;
>> -
>> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
>> - continue;
>> - if (dramtype == DDR3 || dramtype == DDR4) {
>> - writel((mr_num << 12) | (rank << 4) | (0 << 0),
>> - pctl_base + DDR_PCTL2_MRCTRL0);
>> - writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
>> - } else {
>> - writel((rank << 4) | (0 << 0),
>> - pctl_base + DDR_PCTL2_MRCTRL0);
>> - writel((mr_num << 8) | (arg & 0xff),
>> - pctl_base + DDR_PCTL2_MRCTRL1);
>> - }
>> -
>> - setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
>> - while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
>> - continue;
>> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
>> - continue;
>> -
>> - return 0;
>> -}
>> -
>> -/*
>> - * rank : 1:cs0, 2:cs1, 3:cs0&cs1
>> - * vrefrate: 4500: 45%,
>> - */
>> -static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
>> - u32 dramtype)
>> -{
>> - u32 tccd_l, value;
>> u32 dis_auto_zq = 0;
>> - void __iomem *pctl_base = dram->pctl;
>> + u32 pwrctl;
>> + u32 ret;
>>
>> - if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
>> - return -1;
>> + /* disable auto low-power */
>> + pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
>> + writel(0, pctl_base + DDR_PCTL2_PWRCTL);
>>
>> - tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
>> - tccd_l = (tccd_l - 4) << 10;
>> + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
>>
>> - if (vrefrate > 7500) {
>> - /* range 1 */
>> - value = ((vrefrate - 6000) / 65) | tccd_l;
>> - } else {
>> - /* range 2 */
>> - value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
>> - }
>> + ret = phy_data_training(dram->phy, cs, dramtype);
>>
>> - /* disable zqcs */
>> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
>> - (1ul << 31))) {
>> - dis_auto_zq = 1;
>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>> - }
>> - /* disable auto refresh */
>> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>> - update_refresh_reg(dram);
>> -
>> - /* enable vrefdq calibratin */
>> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
>> - udelay(1);/* tvrefdqe */
>> - /* write vrefdq value */
>> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
>> - udelay(1);/* tvref_time */
>> - write_mr(dram, rank, 6, value | (0 << 7), dramtype);
>> - udelay(1);/* tvrefdqx */
>> -
>> - /* restore zqcs */
>> - if (dis_auto_zq)
>> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>> - /* restore auto refresh */
>> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>> - update_refresh_reg(dram);
>> + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
>>
>> - return 0;
>> -}
>> + /* restore auto low-power */
>> + writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
>>
>> -#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
>> + return ret;
>> +}
>>
>> static void rx_deskew_switch_adjust(struct dram_info *dram)
>> {
>> @@ -557,7 +259,7 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
>> void __iomem *phy_base = dram->phy;
>>
>> for (i = 0; i < 4; i++)
>> - gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
>> + gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
>>
>> deskew_val = (gate_val >> 3) + 1;
>> deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
>> @@ -566,8 +268,6 @@ static void rx_deskew_switch_adjust(struct dram_info *dram)
>> (deskew_val & 0x1c) << 2);
>> }
>>
>> -#undef _MAX_
>> -
>> static void tx_deskew_switch_adjust(struct dram_info *dram)
>> {
>> void __iomem *phy_base = dram->phy;
>> @@ -580,40 +280,39 @@ static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
>> writel(ddrconfig, &dram->msch->ddrconf);
>> }
>>
>> +static void sdram_msch_config(struct msch_regs *msch,
>> + struct sdram_msch_timings *noc_timings)
>> +{
>> + writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
>> +
>> + writel(noc_timings->ddrmode.d32, &msch->ddrmode);
>> + writel(noc_timings->readlatency, &msch->readlatency);
>> +
>> + writel(noc_timings->activate.d32, &msch->activate);
>> + writel(noc_timings->devtodev.d32, &msch->devtodev);
>> + writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
>> + writel(noc_timings->agingx0, &msch->aging0);
>> + writel(noc_timings->agingx0, &msch->aging1);
>> + writel(noc_timings->agingx0, &msch->aging2);
>> + writel(noc_timings->agingx0, &msch->aging3);
>> + writel(noc_timings->agingx0, &msch->aging4);
>> + writel(noc_timings->agingx0, &msch->aging5);
>> +}
>> +
>> static void dram_all_config(struct dram_info *dram,
>> struct rk3328_sdram_params *sdram_params)
>> {
>> - u32 sys_reg = 0, tmp = 0;
>> -
>> - set_ddrconfig(dram, sdram_ch.ddrconfig);
>> -
>> - sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
>> - sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
>> - sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
>> - sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
>> - sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
>> - SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
>> - if (sdram_ch.cs1_row)
>> - SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
>> - sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
>> - sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
>> -
>> - writel(sys_reg, &dram->grf->os_reg[2]);
>> -
>> - writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
>> -
>> - writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
>> - writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
>> -
>> - writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
>> - writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
>> - writel(sdram_ch.noc_timings.ddr4timing.d32, &dram->msch->ddr4_timing);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>> + u32 sys_reg2 = 0;
>> + u32 sys_reg3 = 0;
>> +
>> + set_ddrconfig(dram, cap_info->ddrconfig);
>> + sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
>> + &sys_reg3, 0);
>> + writel(sys_reg2, &dram->grf->os_reg[2]);
>> + writel(sys_reg3, &dram->grf->os_reg[3]);
>> +
>> + sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
>> }
>>
>> static void enable_low_power(struct dram_info *dram,
>> @@ -641,6 +340,7 @@ static void enable_low_power(struct dram_info *dram,
>> static int sdram_init(struct dram_info *dram,
>> struct rk3328_sdram_params *sdram_params, u32 pre_init)
>> {
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>> void __iomem *pctl_base = dram->pctl;
>>
>> rkclk_ddr_reset(dram, 1, 1, 1, 1);
>> @@ -652,30 +352,18 @@ static int sdram_init(struct dram_info *dram,
>> */
>> rkclk_ddr_reset(dram, 1, 1, 1, 0);
>> rkclk_configure_ddr(dram, sdram_params);
>> - if (pre_init == 0) {
>> - switch (sdram_params->dramtype) {
>> - case DDR3:
>> - printf("DDR3\n");
>> - break;
>> - case DDR4:
>> - printf("DDR4\n");
>> - break;
>> - case LPDDR3:
>> - default:
>> - printf("LPDDR3\n");
>> - break;
>> - }
>> - }
>> +
>> /* release phy srst to provide clk to ctrl */
>> rkclk_ddr_reset(dram, 1, 1, 0, 0);
>> udelay(10);
>> - phy_soft_reset(dram);
>> + phy_soft_reset(dram->phy);
>> /* release ctrl presetn, and config ctl registers */
>> rkclk_ddr_reset(dram, 1, 0, 0, 0);
>> - pctl_cfg(dram, sdram_params);
>> - sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
>> + pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
>> + cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
>> set_ctl_address_map(dram, sdram_params);
>> - phy_cfg(dram, sdram_params);
>> + phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
>> + &sdram_params->base, cap_info->bw);
>>
>> /* enable dfi_init_start to init phy after ctl srstn deassert */
>> setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
>> @@ -685,13 +373,18 @@ static int sdram_init(struct dram_info *dram,
>> continue;
>>
>> /* do ddr gate training */
>> - if (data_training(dram, 0, sdram_params->dramtype) != 0) {
>> + if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
>> + printf("data training error\n");
>> + return -1;
>> + }
>> + if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
>> printf("data training error\n");
>> return -1;
>> }
>>
>> - if (sdram_params->dramtype == DDR4)
>> - write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
>> + if (sdram_params->base.dramtype == DDR4)
>> + pctl_write_vrefdq(dram->pctl, 0x3, 5670,
>> + sdram_params->base.dramtype);
>>
>> if (pre_init == 0) {
>> rx_deskew_switch_adjust(dram);
>> @@ -708,7 +401,7 @@ static u64 dram_detect_cap(struct dram_info *dram,
>> struct rk3328_sdram_params *sdram_params,
>> unsigned char channel)
>> {
>> - void __iomem *pctl_base = dram->pctl;
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>
>> /*
>> * for ddr3: ddrconf = 3
>> @@ -718,14 +411,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
>> */
>> u32 bk, bktmp;
>> u32 col, coltmp;
>> - u32 row, rowtmp, row_3_4;
>> - void __iomem *test_addr, *test_addr1;
>> - u32 dbw;
>> + u32 rowtmp;
>> u32 cs;
>> u32 bw = 1;
>> - u64 cap = 0;
>> - u32 dram_type = sdram_params->dramtype;
>> - u32 pwrctl;
>> + u32 dram_type = sdram_params->base.dramtype;
>>
>> if (dram_type != DDR4) {
>> /* detect col and bk for ddr3/lpddr3 */
>> @@ -733,33 +422,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
>> bktmp = 3;
>> rowtmp = 16;
>>
>> - for (col = coltmp; col >= 9; col -= 1) {
>> - writel(0, SDRAM_ADDR);
>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>> - (1ul << (col + bw - 1ul)));
>> - writel(PATTERN, test_addr);
>> - if ((readl(test_addr) == PATTERN) &&
>> - (readl(SDRAM_ADDR) == 0))
>> - break;
>> - }
>> - if (col == 8) {
>> - printf("col error\n");
>> + if (sdram_detect_col(cap_info, coltmp) != 0)
>> goto cap_err;
>> - }
>> -
>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>> - (1ul << (coltmp + bktmp + bw - 1ul)));
>> - writel(0, SDRAM_ADDR);
>> - writel(PATTERN, test_addr);
>> - if ((readl(test_addr) == PATTERN) &&
>> - (readl(SDRAM_ADDR) == 0))
>> - bk = 3;
>> - else
>> - bk = 2;
>> - if (dram_type == LPDDR3)
>> - dbw = 2;
>> - else
>> - dbw = 1;
>> + sdram_detect_bank(cap_info, coltmp, bktmp);
>> + sdram_detect_dbw(cap_info, dram_type);
>> } else {
>> /* detect bg for ddr4 */
>> coltmp = 10;
>> @@ -768,178 +434,49 @@ static u64 dram_detect_cap(struct dram_info *dram,
>>
>> col = 10;
>> bk = 2;
>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>> - (1ul << (coltmp + bw + 1ul)));
>> - writel(0, SDRAM_ADDR);
>> - writel(PATTERN, test_addr);
>> - if ((readl(test_addr) == PATTERN) &&
>> - (readl(SDRAM_ADDR) == 0))
>> - dbw = 0;
>> - else
>> - dbw = 1;
>> + cap_info->col = col;
>> + cap_info->bk = bk;
>> + sdram_detect_bg(cap_info, coltmp);
>> }
>> +
>> /* detect row */
>> - for (row = rowtmp; row > 12; row--) {
>> - writel(0, SDRAM_ADDR);
>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>> - (1ul << (row + bktmp + coltmp + bw - 1ul)));
>> - writel(PATTERN, test_addr);
>> - if ((readl(test_addr) == PATTERN) &&
>> - (readl(SDRAM_ADDR) == 0))
>> - break;
>> - }
>> - if (row == 12) {
>> - printf("row error");
>> + if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
>> goto cap_err;
>> - }
>> - /* detect row_3_4 */
>> - test_addr = SDRAM_ADDR;
>> - test_addr1 = (void __iomem *)(SDRAM_ADDR +
>> - (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
>> -
>> - writel(0, test_addr);
>> - writel(PATTERN, test_addr1);
>> - if ((readl(test_addr) == 0) &&
>> - (readl(test_addr1) == PATTERN))
>> - row_3_4 = 0;
>> - else
>> - row_3_4 = 1;
>>
>> - /* disable auto low-power */
>> - pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
>> - writel(0, pctl_base + DDR_PCTL2_PWRCTL);
>> + /* detect row_3_4 */
>> + sdram_detect_row_3_4(cap_info, coltmp, bktmp);
>>
>> - /* bw and cs detect using phy read gate training */
>> + /* bw and cs detect using data training */
>> if (data_training(dram, 1, dram_type) == 0)
>> cs = 1;
>> else
>> cs = 0;
>> + cap_info->rank = cs + 1;
>>
>> bw = 2;
>> + cap_info->bw = bw;
>>
>> - /* restore auto low-power */
>> - writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
>> -
>> - sdram_ch.rank = cs + 1;
>> - sdram_ch.col = col;
>> - sdram_ch.bk = bk;
>> - sdram_ch.dbw = dbw;
>> - sdram_ch.bw = bw;
>> - sdram_ch.cs0_row = row;
>> - if (cs)
>> - sdram_ch.cs1_row = row;
>> - else
>> - sdram_ch.cs1_row = 0;
>> - sdram_ch.row_3_4 = row_3_4;
>> -
>> - if (dram_type == DDR4)
>> - cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) + bw);
>> - else
>> - cap = 1llu << (cs + row + bk + col + bw);
>> -
>> - return cap;
>> -
>> -cap_err:
>> - return 0;
>> -}
>> -
>> -static u32 remodify_sdram_params(struct rk3328_sdram_params *sdram_params)
>> -{
>> - u32 tmp = 0, tmp_adr = 0, i;
>> -
>> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
>> - if (sdram_params->pctl_regs.pctl[i][0] == 0) {
>> - tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
>> - tmp_adr = i;
>> - }
>> - }
>> -
>> - tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
>> -
>> - switch (sdram_ch.dbw) {
>> - case 2:
>> - tmp |= (3ul << 30);
>> - break;
>> - case 1:
>> - tmp |= (2ul << 30);
>> - break;
>> - case 0:
>> - default:
>> - tmp |= (1ul << 30);
>> - break;
>> + cap_info->cs0_high16bit_row = cap_info->cs0_row;
>> + if (cs) {
>> + cap_info->cs1_row = cap_info->cs0_row;
>> + cap_info->cs1_high16bit_row = cap_info->cs0_row;
>> + } else {
>> + cap_info->cs1_row = 0;
>> + cap_info->cs1_high16bit_row = 0;
>> }
>>
>> - if (sdram_ch.rank == 2)
>> - tmp |= 3 << 24;
>> - else
>> - tmp |= 1 << 24;
>> -
>> - tmp |= (2 - sdram_ch.bw) << 12;
>> -
>> - sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
>> -
>> - if (sdram_ch.bw == 2)
>> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
>> - else
>> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
>> -
>> return 0;
>> -}
>> -
>> -static int dram_detect_cs1_row(struct rk3328_sdram_params *sdram_params,
>> - unsigned char channel)
>> -{
>> - u32 ret = 0;
>> - u32 cs1_bit;
>> - void __iomem *test_addr, *cs1_addr;
>> - u32 row, bktmp, coltmp, bw;
>> - u32 ddrconf = sdram_ch.ddrconfig;
>> -
>> - if (sdram_ch.rank == 2) {
>> - cs1_bit = addrmap[ddrconf][0] + 8;
>> -
>> - if (cs1_bit > 31)
>> - goto out;
>> -
>> - cs1_addr = (void __iomem *)(1ul << cs1_bit);
>> - if (cs1_bit < 20)
>> - cs1_bit = 1;
>> - else
>> - cs1_bit = 0;
>> -
>> - if (sdram_params->dramtype == DDR4) {
>> - if (sdram_ch.dbw == 0)
>> - bktmp = sdram_ch.bk + 2;
>> - else
>> - bktmp = sdram_ch.bk + 1;
>> - } else {
>> - bktmp = sdram_ch.bk;
>> - }
>> - bw = sdram_ch.bw;
>> - coltmp = sdram_ch.col;
>> -
>> - /* detect cs1 row */
>> - for (row = sdram_ch.cs0_row; row > 12; row--) {
>> - test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
>> - (1ul << (row + cs1_bit + bktmp +
>> - coltmp + bw - 1ul)));
>> - writel(0, SDRAM_ADDR + cs1_addr);
>> - writel(PATTERN, test_addr);
>> - if ((readl(test_addr) == PATTERN) &&
>> - (readl(SDRAM_ADDR + cs1_addr) == 0)) {
>> - ret = row;
>> - break;
>> - }
>> - }
>> - }
>> -
>> -out:
>> - return ret;
>> +cap_err:
>> + return -1;
>> }
>>
>> static int sdram_init_detect(struct dram_info *dram,
>> struct rk3328_sdram_params *sdram_params)
>> {
>> + u32 sys_reg = 0;
>> + u32 sys_reg3 = 0;
>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>> +
>> debug("Starting SDRAM initialization...\n");
>>
>> memcpy(&sdram_ch, &sdram_params->ch,
>> @@ -949,13 +486,30 @@ static int sdram_init_detect(struct dram_info *dram,
>> dram_detect_cap(dram, sdram_params, 0);
>>
>> /* modify bw, cs related timing */
>> - remodify_sdram_params(sdram_params);
>> + pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
>> + sdram_params->base.dramtype);
>> +
>> + if (cap_info->bw == 2)
>> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
>> + else
>> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
>> +
>> /* reinit sdram by real dram cap */
>> sdram_init(dram, sdram_params, 0);
>>
>> /* redetect cs1 row */
>> - sdram_ch.cs1_row =
>> - dram_detect_cs1_row(sdram_params, 0);
>> + sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
>> + if (cap_info->cs1_row) {
>> + sys_reg = readl(&dram->grf->os_reg[2]);
>> + sys_reg3 = readl(&dram->grf->os_reg[3]);
>> + SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
>> + sys_reg, sys_reg3, 0);
>> + writel(sys_reg, &dram->grf->os_reg[2]);
>> + writel(sys_reg3, &dram->grf->os_reg[3]);
>> + }
>> +
>> + sdram_print_ddr_info(&sdram_params->ch.cap_info,
>> + &sdram_params->base, 0);
>>
>> return 0;
>> }
>>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
^ permalink raw reply [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver【请注意,邮件由u-boot-bounces@lists.denx.de代发】
2019-10-23 8:49 ` [U-Boot] [PATCH 4/9] ram: rk3328: use common sdram driver【请注意,邮件由u-boot-bounces@lists.denx.de代发】 Kever Yang
@ 2019-10-23 9:01 ` Matwey V. Kornilov
0 siblings, 0 replies; 14+ messages in thread
From: Matwey V. Kornilov @ 2019-10-23 9:01 UTC (permalink / raw)
To: u-boot
23.10.2019 11:49, Kever Yang пишет:
> Matway,
>
> On 2019/10/23 上午1:37, Matwey V. Kornilov wrote:
>> Hi,
>>
>> Thank you. Currently, I see the following at Rock64 SBC:
>>
>> U-Boot TPL 2019.10-00024-g8b580d5b93 (Oct 22 2019 - 20:29:01)
>> data training error
>> LPDDR3, 800MHz
>> BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=2048MB
>> Trying to boot from BOOTROM
>> Returning to boot ROM...
>
>
> I test with my rock64 SBC 4GB, it does not have a "data training error",
> does the system later
>
> works fine?
The system works fine. There is also no such message after soft warm reboot.
But after cold power up, there is always 'data training error'.
>
> U-Boot TPL 2019.10-00019-g26c7312fa6 (Oct 23 2019 - 16:43:35)
> LPDDR3, 800MHz
> BW=32 Col=11 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=4096MB
> Trying to boot from BOOTROM
> Returning to boot ROM...
>
> Thanks,
>
> - Kever
>
>>
>>
>> The rest seems to be working fine, but I am confused by "data training
>> error" message.
>>
>>
>> 22.10.2019 11:04, Kever Yang пишет:
>>> From: YouMin Chen <cym@rock-chips.com>
>>>
>>> RK3328 has a similar controller and phy with PX30, so we can use the
>>> common driver for it and remove the duplicate codes.
>>>
>>> Signed-off-by: YouMin Chen <cym@rock-chips.com>
>>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>>> ---
>>>
>>> arch/arm/dts/rk3328-sdram-ddr3-666.dtsi | 4 +
>>> arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi | 4 +
>>> arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi | 4 +
>>> .../include/asm/arch-rockchip/sdram_rk3328.h | 419 +++-------
>>> arch/arm/mach-rockchip/Kconfig | 1 +
>>> configs/evb-rk3328_defconfig | 2 +-
>>> configs/rock64-rk3328_defconfig | 2 +-
>>> drivers/ram/rockchip/Makefile | 2 +-
>>> drivers/ram/rockchip/sdram_rk3328.c | 764 ++++--------------
>>> 9 files changed, 296 insertions(+), 906 deletions(-)
>>>
>>> diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>>> b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>>> index d99e7e0352..3e88ed443b 100644
>>> --- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>>> +++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
>>> @@ -14,6 +14,8 @@
>>> 0x0
>>> 0x10
>>> 0x10
>>> + 0x10
>>> + 0x10
>>> 0
>>> 0x9028b189
>>> @@ -26,6 +28,8 @@
>>> 333
>>> 3
>>> + 1
>>> + 0
>>> 0
>>> 0x00000000
>>> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>>> b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>>> index cc0011cf7b..d63c761a02 100644
>>> --- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>>> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
>>> @@ -14,6 +14,8 @@
>>> 0x0
>>> 0x10
>>> 0x10
>>> + 0x10
>>> + 0x10
>>> 0
>>> 0x98899459
>>> @@ -27,6 +29,8 @@
>>> 800
>>> 6
>>> 1
>>> + 0
>>> + 1
>>> 0x00000000
>>> 0x43041008
>>> diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>>> b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>>> index 62d809e833..b9d3b3b948 100644
>>> --- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>>> +++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
>>> @@ -14,6 +14,8 @@
>>> 0x0
>>> 0x10
>>> 0x10
>>> + 0x10
>>> + 0x10
>>> 0
>>> 0x0c48a18a
>>> @@ -26,6 +28,8 @@
>>> 333
>>> 6
>>> + 1
>>> + 0
>>> 0
>>> 0x00000000
>>> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>>> b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>>> index c747b461a1..10923505d6 100644
>>> --- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>>> +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
>>> @@ -7,197 +7,13 @@
>>> #ifndef _ASM_ARCH_SDRAM_RK3328_H
>>> #define _ASM_ARCH_SDRAM_RK3328_H
>>> #include <asm/arch-rockchip/sdram_common.h>
>>> +#include <asm/arch-rockchip/sdram_pctl_px30.h>
>>> +#include <asm/arch-rockchip/sdram_phy_px30.h>
>>> +#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
>>> #define SR_IDLE 93
>>> #define PD_IDLE 13
>>> #define SDRAM_ADDR 0x00000000
>>> -#define PATTERN (0x5aa5f00f)
>>> -
>>> -/* ddr pctl registers define */
>>> -#define DDR_PCTL2_MSTR 0x0
>>> -#define DDR_PCTL2_STAT 0x4
>>> -#define DDR_PCTL2_MSTR1 0x8
>>> -#define DDR_PCTL2_MRCTRL0 0x10
>>> -#define DDR_PCTL2_MRCTRL1 0x14
>>> -#define DDR_PCTL2_MRSTAT 0x18
>>> -#define DDR_PCTL2_MRCTRL2 0x1c
>>> -#define DDR_PCTL2_DERATEEN 0x20
>>> -#define DDR_PCTL2_DERATEINT 0x24
>>> -#define DDR_PCTL2_PWRCTL 0x30
>>> -#define DDR_PCTL2_PWRTMG 0x34
>>> -#define DDR_PCTL2_HWLPCTL 0x38
>>> -#define DDR_PCTL2_RFSHCTL0 0x50
>>> -#define DDR_PCTL2_RFSHCTL1 0x54
>>> -#define DDR_PCTL2_RFSHCTL2 0x58
>>> -#define DDR_PCTL2_RFSHCTL4 0x5c
>>> -#define DDR_PCTL2_RFSHCTL3 0x60
>>> -#define DDR_PCTL2_RFSHTMG 0x64
>>> -#define DDR_PCTL2_RFSHTMG1 0x68
>>> -#define DDR_PCTL2_RFSHCTL5 0x6c
>>> -#define DDR_PCTL2_INIT0 0xd0
>>> -#define DDR_PCTL2_INIT1 0xd4
>>> -#define DDR_PCTL2_INIT2 0xd8
>>> -#define DDR_PCTL2_INIT3 0xdc
>>> -#define DDR_PCTL2_INIT4 0xe0
>>> -#define DDR_PCTL2_INIT5 0xe4
>>> -#define DDR_PCTL2_INIT6 0xe8
>>> -#define DDR_PCTL2_INIT7 0xec
>>> -#define DDR_PCTL2_DIMMCTL 0xf0
>>> -#define DDR_PCTL2_RANKCTL 0xf4
>>> -#define DDR_PCTL2_CHCTL 0xfc
>>> -#define DDR_PCTL2_DRAMTMG0 0x100
>>> -#define DDR_PCTL2_DRAMTMG1 0x104
>>> -#define DDR_PCTL2_DRAMTMG2 0x108
>>> -#define DDR_PCTL2_DRAMTMG3 0x10c
>>> -#define DDR_PCTL2_DRAMTMG4 0x110
>>> -#define DDR_PCTL2_DRAMTMG5 0x114
>>> -#define DDR_PCTL2_DRAMTMG6 0x118
>>> -#define DDR_PCTL2_DRAMTMG7 0x11c
>>> -#define DDR_PCTL2_DRAMTMG8 0x120
>>> -#define DDR_PCTL2_DRAMTMG9 0x124
>>> -#define DDR_PCTL2_DRAMTMG10 0x128
>>> -#define DDR_PCTL2_DRAMTMG11 0x12c
>>> -#define DDR_PCTL2_DRAMTMG12 0x130
>>> -#define DDR_PCTL2_DRAMTMG13 0x134
>>> -#define DDR_PCTL2_DRAMTMG14 0x138
>>> -#define DDR_PCTL2_DRAMTMG15 0x13c
>>> -#define DDR_PCTL2_DRAMTMG16 0x140
>>> -#define DDR_PCTL2_ZQCTL0 0x180
>>> -#define DDR_PCTL2_ZQCTL1 0x184
>>> -#define DDR_PCTL2_ZQCTL2 0x188
>>> -#define DDR_PCTL2_ZQSTAT 0x18c
>>> -#define DDR_PCTL2_DFITMG0 0x190
>>> -#define DDR_PCTL2_DFITMG1 0x194
>>> -#define DDR_PCTL2_DFILPCFG0 0x198
>>> -#define DDR_PCTL2_DFILPCFG1 0x19c
>>> -#define DDR_PCTL2_DFIUPD0 0x1a0
>>> -#define DDR_PCTL2_DFIUPD1 0x1a4
>>> -#define DDR_PCTL2_DFIUPD2 0x1a8
>>> -#define DDR_PCTL2_DFIMISC 0x1b0
>>> -#define DDR_PCTL2_DFITMG2 0x1b4
>>> -#define DDR_PCTL2_DFITMG3 0x1b8
>>> -#define DDR_PCTL2_DFISTAT 0x1bc
>>> -#define DDR_PCTL2_DBICTL 0x1c0
>>> -#define DDR_PCTL2_ADDRMAP0 0x200
>>> -#define DDR_PCTL2_ADDRMAP1 0x204
>>> -#define DDR_PCTL2_ADDRMAP2 0x208
>>> -#define DDR_PCTL2_ADDRMAP3 0x20c
>>> -#define DDR_PCTL2_ADDRMAP4 0x210
>>> -#define DDR_PCTL2_ADDRMAP5 0x214
>>> -#define DDR_PCTL2_ADDRMAP6 0x218
>>> -#define DDR_PCTL2_ADDRMAP7 0x21c
>>> -#define DDR_PCTL2_ADDRMAP8 0x220
>>> -#define DDR_PCTL2_ADDRMAP9 0x224
>>> -#define DDR_PCTL2_ADDRMAP10 0x228
>>> -#define DDR_PCTL2_ADDRMAP11 0x22c
>>> -#define DDR_PCTL2_ODTCFG 0x240
>>> -#define DDR_PCTL2_ODTMAP 0x244
>>> -#define DDR_PCTL2_SCHED 0x250
>>> -#define DDR_PCTL2_SCHED1 0x254
>>> -#define DDR_PCTL2_PERFHPR1 0x25c
>>> -#define DDR_PCTL2_PERFLPR1 0x264
>>> -#define DDR_PCTL2_PERFWR1 0x26c
>>> -#define DDR_PCTL2_DQMAP0 0x280
>>> -#define DDR_PCTL2_DQMAP1 0x284
>>> -#define DDR_PCTL2_DQMAP2 0x288
>>> -#define DDR_PCTL2_DQMAP3 0x28c
>>> -#define DDR_PCTL2_DQMAP4 0x290
>>> -#define DDR_PCTL2_DQMAP5 0x294
>>> -#define DDR_PCTL2_DBG0 0x300
>>> -#define DDR_PCTL2_DBG1 0x304
>>> -#define DDR_PCTL2_DBGCAM 0x308
>>> -#define DDR_PCTL2_DBGCMD 0x30c
>>> -#define DDR_PCTL2_DBGSTAT 0x310
>>> -#define DDR_PCTL2_SWCTL 0x320
>>> -#define DDR_PCTL2_SWSTAT 0x324
>>> -#define DDR_PCTL2_POISONCFG 0x36c
>>> -#define DDR_PCTL2_POISONSTAT 0x370
>>> -#define DDR_PCTL2_ADVECCINDEX 0x374
>>> -#define DDR_PCTL2_ADVECCSTAT 0x378
>>> -#define DDR_PCTL2_PSTAT 0x3fc
>>> -#define DDR_PCTL2_PCCFG 0x400
>>> -#define DDR_PCTL2_PCFGR_n 0x404
>>> -#define DDR_PCTL2_PCFGW_n 0x408
>>> -#define DDR_PCTL2_PCTRL_n 0x490
>>> -
>>> -/* PCTL2_MRSTAT */
>>> -#define MR_WR_BUSY BIT(0)
>>> -
>>> -/* PHY_REG0 */
>>> -#define DIGITAL_DERESET BIT(3)
>>> -#define ANALOG_DERESET BIT(2)
>>> -#define DIGITAL_RESET (0 << 3)
>>> -#define ANALOG_RESET (0 << 2)
>>> -
>>> -/* PHY_REG1 */
>>> -#define PHY_DDR2 (0)
>>> -#define PHY_LPDDR2 (1)
>>> -#define PHY_DDR3 (2)
>>> -#define PHY_LPDDR3 (3)
>>> -#define PHY_DDR4 (4)
>>> -#define PHY_BL_4 (0 << 2)
>>> -#define PHY_BL_8 BIT(2)
>>> -
>>> -/* PHY_REG2 */
>>> -#define PHY_DTT_EN BIT(0)
>>> -#define PHY_DTT_DISB (0 << 0)
>>> -#define PHY_WRITE_LEVELING_EN BIT(2)
>>> -#define PHY_WRITE_LEVELING_DISB (0 << 2)
>>> -#define PHY_SELECT_CS0 (2)
>>> -#define PHY_SELECT_CS1 (1)
>>> -#define PHY_SELECT_CS0_1 (0)
>>> -#define PHY_WRITE_LEVELING_SELECTCS(n) (n << 6)
>>> -#define PHY_DATA_TRAINING_SELECTCS(n) (n << 4)
>>> -
>>> -#define PHY_DDR3_RON_RTT_DISABLE (0)
>>> -#define PHY_DDR3_RON_RTT_451ohm (1)
>>> -#define PHY_DDR3_RON_RTT_225ohm (2)
>>> -#define PHY_DDR3_RON_RTT_150ohm (3)
>>> -#define PHY_DDR3_RON_RTT_112ohm (4)
>>> -#define PHY_DDR3_RON_RTT_90ohm (5)
>>> -#define PHY_DDR3_RON_RTT_75ohm (6)
>>> -#define PHY_DDR3_RON_RTT_64ohm (7)
>>> -#define PHY_DDR3_RON_RTT_56ohm (16)
>>> -#define PHY_DDR3_RON_RTT_50ohm (17)
>>> -#define PHY_DDR3_RON_RTT_45ohm (18)
>>> -#define PHY_DDR3_RON_RTT_41ohm (19)
>>> -#define PHY_DDR3_RON_RTT_37ohm (20)
>>> -#define PHY_DDR3_RON_RTT_34ohm (21)
>>> -#define PHY_DDR3_RON_RTT_33ohm (22)
>>> -#define PHY_DDR3_RON_RTT_30ohm (23)
>>> -#define PHY_DDR3_RON_RTT_28ohm (24)
>>> -#define PHY_DDR3_RON_RTT_26ohm (25)
>>> -#define PHY_DDR3_RON_RTT_25ohm (26)
>>> -#define PHY_DDR3_RON_RTT_23ohm (27)
>>> -#define PHY_DDR3_RON_RTT_22ohm (28)
>>> -#define PHY_DDR3_RON_RTT_21ohm (29)
>>> -#define PHY_DDR3_RON_RTT_20ohm (30)
>>> -#define PHY_DDR3_RON_RTT_19ohm (31)
>>> -
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30)
>>> -#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31)
>>> /* noc registers define */
>>> #define DDRCONF 0x8
>>> @@ -220,16 +36,16 @@
>>> #define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
>>> /* CRU_SOFTRESET_CON5 */
>>> -#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | (n << 15))
>>> -#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | (n << 14))
>>> -#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | (n << 13))
>>> -#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | (n << 12))
>>> -#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | (n << 11))
>>> -#define msch_srstn_req(n) (((0x1 << 9) << 16) | (n << 9))
>>> -#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | (n << 8))
>>> -#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | (n << 7))
>>> +#define ddrphy_psrstn_req(n) (((0x1 << 15) << 16) | ((n) << 15))
>>> +#define ddrphy_srstn_req(n) (((0x1 << 14) << 16) | ((n) << 14))
>>> +#define ddrctrl_psrstn_req(n) (((0x1 << 13) << 16) | ((n) << 13))
>>> +#define ddrctrl_srstn_req(n) (((0x1 << 12) << 16) | ((n) << 12))
>>> +#define ddrmsch_srstn_req(n) (((0x1 << 11) << 16) | ((n) << 11))
>>> +#define msch_srstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
>>> +#define dfimon_srstn_req(n) (((0x1 << 8) << 16) | ((n) << 8))
>>> +#define grf_ddr_srstn_req(n) (((0x1 << 7) << 16) | ((n) << 7))
>>> /* CRU_SOFTRESET_CON9 */
>>> -#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | (n << 9))
>>> +#define ddrctrl_asrstn_req(n) (((0x1 << 9) << 16) | ((n) << 9))
>>> /* CRU register */
>>> #define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
>>> @@ -256,56 +72,46 @@
>>> #define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
>>> #define REFDIV(n) ((0x3F << 16) | (n))
>>> -union noc_ddrtiming {
>>> - u32 d32;
>>> - struct {
>>> - unsigned acttoact:6;
>>> - unsigned rdtomiss:6;
>>> - unsigned wrtomiss:6;
>>> - unsigned burstlen:3;
>>> - unsigned rdtowr:5;
>>> - unsigned wrtord:5;
>>> - unsigned bwratio:1;
>>> - } b;
>>> -} NOC_TIMING_T;
>>> -
>>> -union noc_activate {
>>> - u32 d32;
>>> - struct {
>>> - unsigned rrd:4;
>>> - unsigned faw:6;
>>> - unsigned fawbank:1;
>>> - unsigned reserved1:21;
>>> - } b;
>>> -};
>>> -
>>> -union noc_devtodev {
>>> - u32 d32;
>>> - struct {
>>> - unsigned busrdtord:2;
>>> - unsigned busrdtowr:2;
>>> - unsigned buswrtord:2;
>>> - unsigned reserved2:26;
>>> - } b;
>>> -};
>>> -
>>> -union noc_ddr4timing {
>>> - u32 d32;
>>> - struct {
>>> - unsigned ccdl:3;
>>> - unsigned wrtordl:5;
>>> - unsigned rrdl:4;
>>> - unsigned reserved2:20;
>>> - } b;
>>> +u16 ddr_cfg_2_rbc[] = {
>>> + /*
>>> + * [5:4] row(13+n)
>>> + * [3] cs(0:0 cs, 1:2 cs)
>>> + * [2] bank(0:0bank,1:8bank)
>>> + * [1:0] col(11+n)
>>> + */
>>> + /* row, cs, bank, col */
>>> + ((3 << 4) | (0 << 3) | (1 << 2) | 0),
>>> + ((3 << 4) | (0 << 3) | (1 << 2) | 1),
>>> + ((2 << 4) | (0 << 3) | (1 << 2) | 2),
>>> + ((3 << 4) | (0 << 3) | (1 << 2) | 2),
>>> + ((2 << 4) | (0 << 3) | (1 << 2) | 3),
>>> + ((3 << 4) | (1 << 3) | (1 << 2) | 0),
>>> + ((3 << 4) | (1 << 3) | (1 << 2) | 1),
>>> + ((2 << 4) | (1 << 3) | (1 << 2) | 2),
>>> + ((3 << 4) | (0 << 3) | (0 << 2) | 1),
>>> + ((2 << 4) | (0 << 3) | (1 << 2) | 1),
>>> };
>>> -union noc_ddrmode {
>>> - u32 d32;
>>> - struct {
>>> - unsigned autoprecharge:1;
>>> - unsigned bwratioextended:1;
>>> - unsigned reserved3:30;
>>> - } b;
>>> +u16 ddr4_cfg_2_rbc[] = {
>>> + /***************************
>>> + * [6] cs 0:0cs 1:2 cs
>>> + * [5:3] row(13+n)
>>> + * [2] cs(0:0 cs, 1:2 cs)
>>> + * [1] bw 0: 16bit 1:32bit
>>> + * [0] diebw 0:8bit 1:16bit
>>> + ***************************/
>>> + /* cs, row, cs, bw, diebw */
>>> + ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
>>> + ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
>>> + ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
>>> + ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
>>> + ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
>>> + ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
>>> + ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
>>> + ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
>>> + ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
>>> + ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
>>> + ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
>>> };
>>> u32 addrmap[21][9] = {
>>> @@ -356,17 +162,65 @@ u32 addrmap[21][9] = {
>>> 0x07070707, 0x00000f07, 0x3f00}
>>> };
>>> -struct rk3328_msch_timings {
>>> - union noc_ddrtiming ddrtiming;
>>> - union noc_ddrmode ddrmode;
>>> - u32 readlatency;
>>> - union noc_activate activate;
>>> - union noc_devtodev devtodev;
>>> - union noc_ddr4timing ddr4timing;
>>> - u32 agingx0;
>>> +struct rk3328_ddr_grf_regs {
>>> + u32 ddr_grf_con[4];
>>> + u32 reserved[(0x100 - 0x10) / 4];
>>> + u32 ddr_grf_status[11];
>>> };
>>> -struct rk3328_msch_regs {
>>> +union noc_ddrtiming {
>>> + u32 d32;
>>> + struct {
>>> + unsigned acttoact:6;
>>> + unsigned rdtomiss:6;
>>> + unsigned wrtomiss:6;
>>> + unsigned burstlen:3;
>>> + unsigned rdtowr:5;
>>> + unsigned wrtord:5;
>>> + unsigned bwratio:1;
>>> + } b;
>>> +};
>>> +
>>> +union noc_activate {
>>> + u32 d32;
>>> + struct {
>>> + unsigned rrd:4;
>>> + unsigned faw:6;
>>> + unsigned fawbank:1;
>>> + unsigned reserved1:21;
>>> + } b;
>>> +};
>>> +
>>> +union noc_devtodev {
>>> + u32 d32;
>>> + struct {
>>> + unsigned busrdtord:2;
>>> + unsigned busrdtowr:2;
>>> + unsigned buswrtord:2;
>>> + unsigned reserved2:26;
>>> + } b;
>>> +};
>>> +
>>> +union noc_ddr4timing {
>>> + u32 d32;
>>> + struct {
>>> + unsigned ccdl:3;
>>> + unsigned wrtordl:5;
>>> + unsigned rrdl:4;
>>> + unsigned reserved2:20;
>>> + } b;
>>> +};
>>> +
>>> +union noc_ddrmode {
>>> + u32 d32;
>>> + struct {
>>> + unsigned autoprecharge:1;
>>> + unsigned bwratioextended:1;
>>> + unsigned reserved3:30;
>>> + } b;
>>> +};
>>> +
>>> +struct msch_regs {
>>> u32 coreid;
>>> u32 revisionid;
>>> u32 ddrconf;
>>> @@ -385,58 +239,27 @@ struct rk3328_msch_regs {
>>> u32 ddr4_timing;
>>> };
>>> -struct rk3328_ddr_grf_regs {
>>> - u32 ddr_grf_con[4];
>>> - u32 reserved[(0x100 - 0x10) / 4];
>>> - u32 ddr_grf_status[11];
>>> -};
>>> -
>>> -struct rk3328_ddr_pctl_regs {
>>> - u32 pctl[30][2];
>>> -};
>>> -
>>> -struct rk3328_ddr_phy_regs {
>>> - u32 phy[5][2];
>>> -};
>>> -
>>> -struct rk3328_ddr_skew {
>>> - u32 a0_a1_skew[15];
>>> - u32 cs0_dm0_skew[11];
>>> - u32 cs0_dm1_skew[11];
>>> - u32 cs0_dm2_skew[11];
>>> - u32 cs0_dm3_skew[11];
>>> - u32 cs1_dm0_skew[11];
>>> - u32 cs1_dm1_skew[11];
>>> - u32 cs1_dm2_skew[11];
>>> - u32 cs1_dm3_skew[11];
>>> +struct sdram_msch_timings {
>>> + union noc_ddrtiming ddrtiming;
>>> + union noc_ddrmode ddrmode;
>>> + u32 readlatency;
>>> + union noc_activate activate;
>>> + union noc_devtodev devtodev;
>>> + union noc_ddr4timing ddr4timing;
>>> + u32 agingx0;
>>> };
>>> struct rk3328_sdram_channel {
>>> - unsigned int rank;
>>> - unsigned int col;
>>> - /* 3:8bank, 2:4bank */
>>> - unsigned int bk;
>>> - /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
>>> - unsigned int bw;
>>> - /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
>>> - unsigned int dbw;
>>> - unsigned int row_3_4;
>>> - unsigned int cs0_row;
>>> - unsigned int cs1_row;
>>> - unsigned int ddrconfig;
>>> - struct rk3328_msch_timings noc_timings;
>>> + struct sdram_cap_info cap_info;
>>> + struct sdram_msch_timings noc_timings;
>>> };
>>> struct rk3328_sdram_params {
>>> struct rk3328_sdram_channel ch;
>>> - unsigned int ddr_freq;
>>> - unsigned int dramtype;
>>> - unsigned int odt;
>>> - struct rk3328_ddr_pctl_regs pctl_regs;
>>> - struct rk3328_ddr_phy_regs phy_regs;
>>> - struct rk3328_ddr_skew skew;
>>> + struct sdram_base_params base;
>>> + struct ddr_pctl_regs pctl_regs;
>>> + struct ddr_phy_regs phy_regs;
>>> + struct ddr_phy_skew skew;
>>> };
>>> -#define PHY_REG(base, n) (base + 4 * (n))
>>> -
>>> #endif
>>> diff --git a/arch/arm/mach-rockchip/Kconfig
>>> b/arch/arm/mach-rockchip/Kconfig
>>> index f5a80b4f0c..5f1ad51cac 100644
>>> --- a/arch/arm/mach-rockchip/Kconfig
>>> +++ b/arch/arm/mach-rockchip/Kconfig
>>> @@ -115,6 +115,7 @@ config ROCKCHIP_RK3328
>>> select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
>>> select TPL_NEEDS_SEPARATE_STACK if TPL
>>> imply ROCKCHIP_COMMON_BOARD
>>> + imply ROCKCHIP_SDRAM_COMMON
>>> imply SPL_ROCKCHIP_COMMON_BOARD
>>> imply SPL_SERIAL_SUPPORT
>>> imply TPL_SERIAL_SUPPORT
>>> diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
>>> index 37610774c1..fdabee842d 100644
>>> --- a/configs/evb-rk3328_defconfig
>>> +++ b/configs/evb-rk3328_defconfig
>>> @@ -46,7 +46,6 @@ CONFIG_SPL_SYSCON=y
>>> CONFIG_TPL_SYSCON=y
>>> CONFIG_CLK=y
>>> CONFIG_SPL_CLK=y
>>> -CONFIG_TPL_CLK=y
>>> CONFIG_FASTBOOT_BUF_ADDR=0x800800
>>> CONFIG_FASTBOOT_FLASH=y
>>> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
>>> @@ -77,6 +76,7 @@ CONFIG_DEBUG_UART_SHIFT=2
>>> CONFIG_DEBUG_UART_ANNOUNCE=y
>>> CONFIG_DEBUG_UART_SKIP_INIT=y
>>> CONFIG_SYSRESET=y
>>> +# CONFIG_TPL_SYSRESET is not set
>>> CONFIG_USB=y
>>> CONFIG_USB_XHCI_HCD=y
>>> CONFIG_USB_XHCI_DWC3=y
>>> diff --git a/configs/rock64-rk3328_defconfig
>>> b/configs/rock64-rk3328_defconfig
>>> index 3ab0af1158..0fb4b42c6e 100644
>>> --- a/configs/rock64-rk3328_defconfig
>>> +++ b/configs/rock64-rk3328_defconfig
>>> @@ -49,7 +49,6 @@ CONFIG_SPL_SYSCON=y
>>> CONFIG_TPL_SYSCON=y
>>> CONFIG_CLK=y
>>> CONFIG_SPL_CLK=y
>>> -CONFIG_TPL_CLK=y
>>> CONFIG_FASTBOOT_BUF_ADDR=0x800800
>>> CONFIG_FASTBOOT_FLASH=y
>>> CONFIG_FASTBOOT_FLASH_MMC_DEV=1
>>> @@ -79,6 +78,7 @@ CONFIG_DM_RESET=y
>>> CONFIG_BAUDRATE=1500000
>>> CONFIG_DEBUG_UART_SHIFT=2
>>> CONFIG_SYSRESET=y
>>> +# CONFIG_TPL_SYSRESET is not set
>>> CONFIG_USB=y
>>> CONFIG_USB_XHCI_HCD=y
>>> CONFIG_USB_XHCI_DWC3=y
>>> diff --git a/drivers/ram/rockchip/Makefile
>>> b/drivers/ram/rockchip/Makefile
>>> index 3d4f2f4ebf..3f19fa09a5 100644
>>> --- a/drivers/ram/rockchip/Makefile
>>> +++ b/drivers/ram/rockchip/Makefile
>>> @@ -9,5 +9,5 @@ obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
>>> obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
>>> obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
>>> obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
>>> -obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
>>> +obj-$(CONFIG_ROCKCHIP_RK3328) += sdram_rk3328.o sdram_pctl_px30.o
>>> sdram_phy_px30.o
>>> obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
>>> diff --git a/drivers/ram/rockchip/sdram_rk3328.c
>>> b/drivers/ram/rockchip/sdram_rk3328.c
>>> index e7919337ea..72ae7555bc 100644
>>> --- a/drivers/ram/rockchip/sdram_rk3328.c
>>> +++ b/drivers/ram/rockchip/sdram_rk3328.c
>>> @@ -20,11 +20,11 @@
>>> struct dram_info {
>>> #ifdef CONFIG_TPL_BUILD
>>> - struct rk3328_ddr_pctl_regs *pctl;
>>> - struct rk3328_ddr_phy_regs *phy;
>>> + struct ddr_pctl_regs *pctl;
>>> + struct ddr_phy_regs *phy;
>>> struct clk ddr_clk;
>>> struct rk3328_cru *cru;
>>> - struct rk3328_msch_regs *msch;
>>> + struct msch_regs *msch;
>>> struct rk3328_ddr_grf_regs *ddr_grf;
>>> #endif
>>> struct ram_info info;
>>> @@ -71,10 +71,11 @@ static void rkclk_ddr_reset(struct dram_info *dram,
>>> writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
>>> }
>>> -static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
>>> +static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
>>> {
>>> unsigned int refdiv, postdiv1, postdiv2, fbdiv;
>>> int delay = 1000;
>>> + u32 mhz = hz / MHZ;
>>> refdiv = 1;
>>> if (mhz <= 300) {
>>> @@ -122,52 +123,7 @@ static void rkclk_configure_ddr(struct dram_info
>>> *dram,
>>> clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
>>> /* for inno ddr phy need 2*freq */
>>> - rkclk_set_dpll(dram, sdram_params->ddr_freq * 2);
>>> -}
>>> -
>>> -static void phy_soft_reset(struct dram_info *dram)
>>> -{
>>> - void __iomem *phy_base = dram->phy;
>>> -
>>> - clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
>>> - udelay(1);
>>> - setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
>>> - udelay(5);
>>> - setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
>>> - udelay(1);
>>> -}
>>> -
>>> -static int pctl_cfg(struct dram_info *dram,
>>> - struct rk3328_sdram_params *sdram_params)
>>> -{
>>> - u32 i;
>>> - void __iomem *pctl_base = dram->pctl;
>>> -
>>> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF;
>>> i++) {
>>> - writel(sdram_params->pctl_regs.pctl[i][1],
>>> - pctl_base + sdram_params->pctl_regs.pctl[i][0]);
>>> - }
>>> - clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
>>> - (0xff << 16) | 0x1f,
>>> - ((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
>>> - /*
>>> - * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
>>> - * hw_lp_idle_x32=1
>>> - */
>>> - if (sdram_params->dramtype == LPDDR3) {
>>> - setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
>>> - clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
>>> - 0xf << 4,
>>> - 2 << 4);
>>> - }
>>> - clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
>>> - 0xfff << 16,
>>> - 1 << 16);
>>> - /* disable zqcs */
>>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
>>> - setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
>>> -
>>> - return 0;
>>> + rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ * 2);
>>> }
>>> /* return ddrconfig value
>>> @@ -175,62 +131,39 @@ static int pctl_cfg(struct dram_info *dram,
>>> * other, the ddrconfig value
>>> * only support cs0_row >= cs1_row
>>> */
>>> -static unsigned int calculate_ddrconfig(struct rk3328_sdram_params
>>> *sdram_params)
>>> +static u32 calculate_ddrconfig(struct rk3328_sdram_params
>>> *sdram_params)
>>> {
>>> - static const u16 ddr_cfg_2_rbc[] = {
>>> - /***************************
>>> - * [5:4] row(13+n)
>>> - * [3] cs(0:0 cs, 1:2 cs)
>>> - * [2] bank(0:0bank,1:8bank)
>>> - * [1:0] col(11+n)
>>> - ****************************/
>>> - /* row, cs, bank, col */
>>> - ((3 << 4) | (0 << 3) | (1 << 2) | 0),
>>> - ((3 << 4) | (0 << 3) | (1 << 2) | 1),
>>> - ((2 << 4) | (0 << 3) | (1 << 2) | 2),
>>> - ((3 << 4) | (0 << 3) | (1 << 2) | 2),
>>> - ((2 << 4) | (0 << 3) | (1 << 2) | 3),
>>> - ((3 << 4) | (1 << 3) | (1 << 2) | 0),
>>> - ((3 << 4) | (1 << 3) | (1 << 2) | 1),
>>> - ((2 << 4) | (1 << 3) | (1 << 2) | 2),
>>> - ((3 << 4) | (0 << 3) | (0 << 2) | 1),
>>> - ((2 << 4) | (0 << 3) | (1 << 2) | 1),
>>> - };
>>> -
>>> - static const u16 ddr4_cfg_2_rbc[] = {
>>> - /***************************
>>> - * [6] cs 0:0cs 1:2 cs
>>> - * [5:3] row(13+n)
>>> - * [2] cs(0:0 cs, 1:2 cs)
>>> - * [1] bw 0: 16bit 1:32bit
>>> - * [0] diebw 0:8bit 1:16bit
>>> - ***************************/
>>> - /* cs, row, cs, bw, diebw */
>>> - ((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
>>> - ((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
>>> - ((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
>>> - ((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
>>> - ((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
>>> - ((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
>>> - ((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
>>> - ((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
>>> - ((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
>>> - ((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
>>> - ((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
>>> - };
>>> -
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> u32 cs, bw, die_bw, col, row, bank;
>>> + u32 cs1_row;
>>> u32 i, tmp;
>>> u32 ddrconf = -1;
>>> - cs = sdram_ch.rank;
>>> - bw = sdram_ch.bw;
>>> - die_bw = sdram_ch.dbw;
>>> - col = sdram_ch.col;
>>> - row = sdram_ch.cs0_row;
>>> - bank = sdram_ch.bk;
>>> + cs = cap_info->rank;
>>> + bw = cap_info->bw;
>>> + die_bw = cap_info->dbw;
>>> + col = cap_info->col;
>>> + row = cap_info->cs0_row;
>>> + cs1_row = cap_info->cs1_row;
>>> + bank = cap_info->bk;
>>> +
>>> + if (sdram_params->base.dramtype == DDR4) {
>>> + /* when DDR_TEST, CS always at MSB position for easy test */
>>> + if (cs == 2 && row == cs1_row) {
>>> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
>>> + tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
>>> + die_bw;
>>> + for (i = 17; i < 21; i++) {
>>> + if (((tmp & 0x7) ==
>>> + (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
>>> + ((tmp & 0x3c) <=
>>> + (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
>>> + ddrconf = i;
>>> + goto out;
>>> + }
>>> + }
>>> + }
>>> - if (sdram_params->dramtype == DDR4) {
>>> tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) |
>>> die_bw;
>>> for (i = 10; i < 17; i++) {
>>> if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
>>> @@ -246,6 +179,18 @@ static unsigned int calculate_ddrconfig(struct
>>> rk3328_sdram_params *sdram_params
>>> goto out;
>>> }
>>> + /* when DDR_TEST, CS always at MSB position for easy test */
>>> + if (cs == 2 && row == cs1_row) {
>>> + /* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
>>> + for (i = 5; i < 8; i++) {
>>> + if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
>>> + 0x3)) {
>>> + ddrconf = i;
>>> + goto out;
>>> + }
>>> + }
>>> + }
>>> +
>>> tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
>>> for (i = 0; i < 5; i++)
>>> if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
>>> @@ -257,23 +202,11 @@ static unsigned int calculate_ddrconfig(struct
>>> rk3328_sdram_params *sdram_params
>>> out:
>>> if (ddrconf > 20)
>>> - printf("calculate_ddrconfig error\n");
>>> + printf("calculate ddrconfig error\n");
>>> return ddrconf;
>>> }
>>> -/* n: Unit bytes */
>>> -static void copy_to_reg(u32 *dest, u32 *src, u32 n)
>>> -{
>>> - int i;
>>> -
>>> - for (i = 0; i < n / sizeof(u32); i++) {
>>> - writel(*src, dest);
>>> - src++;
>>> - dest++;
>>> - }
>>> -}
>>> -
>>> /*******
>>> * calculate controller dram address map, and setting to register.
>>> * argument sdram_ch.ddrconf must be right value before
>>> @@ -282,273 +215,42 @@ static void copy_to_reg(u32 *dest, u32 *src,
>>> u32 n)
>>> static void set_ctl_address_map(struct dram_info *dram,
>>> struct rk3328_sdram_params *sdram_params)
>>> {
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> void __iomem *pctl_base = dram->pctl;
>>> - copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
>>> - &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
>>> - if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
>>> + sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
>>> + &addrmap[cap_info->ddrconfig][0], 9 * 4);
>>> + if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
>>> setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
>>> - if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
>>> + if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
>>> setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
>>> - if (sdram_ch.rank == 1)
>>> + if (cap_info->rank == 1)
>>> clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
>>> }
>>> -static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
>>> -{
>>> - u32 tmp;
>>> - void __iomem *phy_base = dram->phy;
>>> -
>>> - setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
>>> - clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
>>> - setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
>>> - clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
>>> - setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
>>> - clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
>>> - setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
>>> - clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
>>> - setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
>>> - clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
>>> -
>>> - if (freq <= 400)
>>> - /* DLL bypass */
>>> - setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
>>> - else
>>> - clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
>>> - if (freq <= 680)
>>> - tmp = 2;
>>> - else
>>> - tmp = 1;
>>> - writel(tmp, PHY_REG(phy_base, 0x28));
>>> - writel(tmp, PHY_REG(phy_base, 0x38));
>>> - writel(tmp, PHY_REG(phy_base, 0x48));
>>> - writel(tmp, PHY_REG(phy_base, 0x58));
>>> -}
>>> -
>>> -static void set_ds_odt(struct dram_info *dram,
>>> - struct rk3328_sdram_params *sdram_params)
>>> -{
>>> - u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
>>> - void __iomem *phy_base = dram->phy;
>>> -
>>> - if (sdram_params->dramtype == DDR3) {
>>> - cmd_drv = PHY_DDR3_RON_RTT_34ohm;
>>> - clk_drv = PHY_DDR3_RON_RTT_45ohm;
>>> - dqs_drv = PHY_DDR3_RON_RTT_34ohm;
>>> - dqs_odt = PHY_DDR3_RON_RTT_225ohm;
>>> - } else {
>>> - cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
>>> - clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
>>> - dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
>>> - dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
>>> - }
>>> - /* DS */
>>> - writel(cmd_drv, PHY_REG(phy_base, 0x11));
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
>>> - writel(clk_drv, PHY_REG(phy_base, 0x16));
>>> - writel(clk_drv, PHY_REG(phy_base, 0x18));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x20));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x2f));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x30));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x3f));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x40));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x4f));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x50));
>>> - writel(dqs_drv, PHY_REG(phy_base, 0x5f));
>>> - /* ODT */
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x21));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x2e));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x31));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x3e));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x41));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x4e));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x51));
>>> - writel(dqs_odt, PHY_REG(phy_base, 0x5e));
>>> -}
>>> -
>>> -static void phy_cfg(struct dram_info *dram,
>>> - struct rk3328_sdram_params *sdram_params)
>>> -{
>>> - u32 i;
>>> - void __iomem *phy_base = dram->phy;
>>> -
>>> - phy_dll_bypass_set(dram, sdram_params->ddr_freq);
>>> - for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
>>> - writel(sdram_params->phy_regs.phy[i][1],
>>> - phy_base + sdram_params->phy_regs.phy[i][0]);
>>> - }
>>> - if (sdram_ch.bw == 2) {
>>> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
>>> - } else {
>>> - clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
>>> - /* disable DQS2,DQS3 tx dll for saving power */
>>> - clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
>>> - clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
>>> - }
>>> - set_ds_odt(dram, sdram_params);
>>> - /* deskew */
>>> - setbits_le32(PHY_REG(phy_base, 2), 8);
>>> - copy_to_reg(PHY_REG(phy_base, 0xb0),
>>> - &sdram_params->skew.a0_a1_skew[0], 15 * 4);
>>> - copy_to_reg(PHY_REG(phy_base, 0x70),
>>> - &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
>>> - copy_to_reg(PHY_REG(phy_base, 0xc0),
>>> - &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
>>> -}
>>> -
>>> -static int update_refresh_reg(struct dram_info *dram)
>>> -{
>>> - void __iomem *pctl_base = dram->pctl;
>>> - u32 ret;
>>> -
>>> - ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
>>> - writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
>>> -
>>> - return 0;
>>> -}
>>> -
>>> static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
>>> -{
>>> - u32 ret;
>>> - u32 dis_auto_zq = 0;
>>> - void __iomem *pctl_base = dram->pctl;
>>> - void __iomem *phy_base = dram->phy;
>>> -
>>> - /* disable zqcs */
>>> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
>>> - (1ul << 31))) {
>>> - dis_auto_zq = 1;
>>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>>> - }
>>> - /* disable auto refresh */
>>> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>>> - update_refresh_reg(dram);
>>> -
>>> - if (dramtype == DDR4) {
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
>>> - }
>>> - /* choose training cs */
>>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
>>> - /* enable gate training */
>>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
>>> - udelay(50);
>>> - ret = readl(PHY_REG(phy_base, 0xff));
>>> - /* disable gate training */
>>> - clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
>>> - /* restore zqcs */
>>> - if (dis_auto_zq)
>>> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>>> - /* restore auto refresh */
>>> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>>> - update_refresh_reg(dram);
>>> -
>>> - if (dramtype == DDR4) {
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
>>> - clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
>>> - }
>>> -
>>> - if (ret & 0x10) {
>>> - ret = -1;
>>> - } else {
>>> - ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
>>> - ret = (ret == 0) ? 0 : -1;
>>> - }
>>> - return ret;
>>> -}
>>> -
>>> -/* rank = 1: cs0
>>> - * rank = 2: cs1
>>> - * rank = 3: cs0 & cs1
>>> - * note: be careful of keep mr original val
>>> - */
>>> -static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num,
>>> u32 arg,
>>> - u32 dramtype)
>>> {
>>> void __iomem *pctl_base = dram->pctl;
>>> -
>>> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
>>> - continue;
>>> - if (dramtype == DDR3 || dramtype == DDR4) {
>>> - writel((mr_num << 12) | (rank << 4) | (0 << 0),
>>> - pctl_base + DDR_PCTL2_MRCTRL0);
>>> - writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
>>> - } else {
>>> - writel((rank << 4) | (0 << 0),
>>> - pctl_base + DDR_PCTL2_MRCTRL0);
>>> - writel((mr_num << 8) | (arg & 0xff),
>>> - pctl_base + DDR_PCTL2_MRCTRL1);
>>> - }
>>> -
>>> - setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
>>> - while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
>>> - continue;
>>> - while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
>>> - continue;
>>> -
>>> - return 0;
>>> -}
>>> -
>>> -/*
>>> - * rank : 1:cs0, 2:cs1, 3:cs0&cs1
>>> - * vrefrate: 4500: 45%,
>>> - */
>>> -static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
>>> - u32 dramtype)
>>> -{
>>> - u32 tccd_l, value;
>>> u32 dis_auto_zq = 0;
>>> - void __iomem *pctl_base = dram->pctl;
>>> + u32 pwrctl;
>>> + u32 ret;
>>> - if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
>>> - return -1;
>>> + /* disable auto low-power */
>>> + pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
>>> + writel(0, pctl_base + DDR_PCTL2_PWRCTL);
>>> - tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
>>> - tccd_l = (tccd_l - 4) << 10;
>>> + dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
>>> - if (vrefrate > 7500) {
>>> - /* range 1 */
>>> - value = ((vrefrate - 6000) / 65) | tccd_l;
>>> - } else {
>>> - /* range 2 */
>>> - value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
>>> - }
>>> + ret = phy_data_training(dram->phy, cs, dramtype);
>>> - /* disable zqcs */
>>> - if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
>>> - (1ul << 31))) {
>>> - dis_auto_zq = 1;
>>> - setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>>> - }
>>> - /* disable auto refresh */
>>> - setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>>> - update_refresh_reg(dram);
>>> -
>>> - /* enable vrefdq calibratin */
>>> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
>>> - udelay(1);/* tvrefdqe */
>>> - /* write vrefdq value */
>>> - write_mr(dram, rank, 6, value | (1 << 7), dramtype);
>>> - udelay(1);/* tvref_time */
>>> - write_mr(dram, rank, 6, value | (0 << 7), dramtype);
>>> - udelay(1);/* tvrefdqx */
>>> -
>>> - /* restore zqcs */
>>> - if (dis_auto_zq)
>>> - clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
>>> - /* restore auto refresh */
>>> - clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
>>> - update_refresh_reg(dram);
>>> + pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
>>> - return 0;
>>> -}
>>> + /* restore auto low-power */
>>> + writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
>>> -#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
>>> + return ret;
>>> +}
>>> static void rx_deskew_switch_adjust(struct dram_info *dram)
>>> {
>>> @@ -557,7 +259,7 @@ static void rx_deskew_switch_adjust(struct
>>> dram_info *dram)
>>> void __iomem *phy_base = dram->phy;
>>> for (i = 0; i < 4; i++)
>>> - gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
>>> + gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
>>> deskew_val = (gate_val >> 3) + 1;
>>> deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
>>> @@ -566,8 +268,6 @@ static void rx_deskew_switch_adjust(struct
>>> dram_info *dram)
>>> (deskew_val & 0x1c) << 2);
>>> }
>>> -#undef _MAX_
>>> -
>>> static void tx_deskew_switch_adjust(struct dram_info *dram)
>>> {
>>> void __iomem *phy_base = dram->phy;
>>> @@ -580,40 +280,39 @@ static void set_ddrconfig(struct dram_info
>>> *dram, u32 ddrconfig)
>>> writel(ddrconfig, &dram->msch->ddrconf);
>>> }
>>> +static void sdram_msch_config(struct msch_regs *msch,
>>> + struct sdram_msch_timings *noc_timings)
>>> +{
>>> + writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
>>> +
>>> + writel(noc_timings->ddrmode.d32, &msch->ddrmode);
>>> + writel(noc_timings->readlatency, &msch->readlatency);
>>> +
>>> + writel(noc_timings->activate.d32, &msch->activate);
>>> + writel(noc_timings->devtodev.d32, &msch->devtodev);
>>> + writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
>>> + writel(noc_timings->agingx0, &msch->aging0);
>>> + writel(noc_timings->agingx0, &msch->aging1);
>>> + writel(noc_timings->agingx0, &msch->aging2);
>>> + writel(noc_timings->agingx0, &msch->aging3);
>>> + writel(noc_timings->agingx0, &msch->aging4);
>>> + writel(noc_timings->agingx0, &msch->aging5);
>>> +}
>>> +
>>> static void dram_all_config(struct dram_info *dram,
>>> struct rk3328_sdram_params *sdram_params)
>>> {
>>> - u32 sys_reg = 0, tmp = 0;
>>> -
>>> - set_ddrconfig(dram, sdram_ch.ddrconfig);
>>> -
>>> - sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
>>> - sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
>>> - sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
>>> - sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
>>> - sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
>>> - SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
>>> - if (sdram_ch.cs1_row)
>>> - SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
>>> - sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
>>> - sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
>>> -
>>> - writel(sys_reg, &dram->grf->os_reg[2]);
>>> -
>>> - writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
>>> -
>>> - writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
>>> - writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
>>> -
>>> - writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
>>> - writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
>>> - writel(sdram_ch.noc_timings.ddr4timing.d32,
>>> &dram->msch->ddr4_timing);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
>>> - writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> + u32 sys_reg2 = 0;
>>> + u32 sys_reg3 = 0;
>>> +
>>> + set_ddrconfig(dram, cap_info->ddrconfig);
>>> + sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
>>> + &sys_reg3, 0);
>>> + writel(sys_reg2, &dram->grf->os_reg[2]);
>>> + writel(sys_reg3, &dram->grf->os_reg[3]);
>>> +
>>> + sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
>>> }
>>> static void enable_low_power(struct dram_info *dram,
>>> @@ -641,6 +340,7 @@ static void enable_low_power(struct dram_info *dram,
>>> static int sdram_init(struct dram_info *dram,
>>> struct rk3328_sdram_params *sdram_params, u32 pre_init)
>>> {
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> void __iomem *pctl_base = dram->pctl;
>>> rkclk_ddr_reset(dram, 1, 1, 1, 1);
>>> @@ -652,30 +352,18 @@ static int sdram_init(struct dram_info *dram,
>>> */
>>> rkclk_ddr_reset(dram, 1, 1, 1, 0);
>>> rkclk_configure_ddr(dram, sdram_params);
>>> - if (pre_init == 0) {
>>> - switch (sdram_params->dramtype) {
>>> - case DDR3:
>>> - printf("DDR3\n");
>>> - break;
>>> - case DDR4:
>>> - printf("DDR4\n");
>>> - break;
>>> - case LPDDR3:
>>> - default:
>>> - printf("LPDDR3\n");
>>> - break;
>>> - }
>>> - }
>>> +
>>> /* release phy srst to provide clk to ctrl */
>>> rkclk_ddr_reset(dram, 1, 1, 0, 0);
>>> udelay(10);
>>> - phy_soft_reset(dram);
>>> + phy_soft_reset(dram->phy);
>>> /* release ctrl presetn, and config ctl registers */
>>> rkclk_ddr_reset(dram, 1, 0, 0, 0);
>>> - pctl_cfg(dram, sdram_params);
>>> - sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
>>> + pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
>>> + cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
>>> set_ctl_address_map(dram, sdram_params);
>>> - phy_cfg(dram, sdram_params);
>>> + phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
>>> + &sdram_params->base, cap_info->bw);
>>> /* enable dfi_init_start to init phy after ctl srstn deassert */
>>> setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
>>> @@ -685,13 +373,18 @@ static int sdram_init(struct dram_info *dram,
>>> continue;
>>> /* do ddr gate training */
>>> - if (data_training(dram, 0, sdram_params->dramtype) != 0) {
>>> + if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
>>> + printf("data training error\n");
>>> + return -1;
>>> + }
>>> + if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
>>> printf("data training error\n");
>>> return -1;
>>> }
>>> - if (sdram_params->dramtype == DDR4)
>>> - write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
>>> + if (sdram_params->base.dramtype == DDR4)
>>> + pctl_write_vrefdq(dram->pctl, 0x3, 5670,
>>> + sdram_params->base.dramtype);
>>> if (pre_init == 0) {
>>> rx_deskew_switch_adjust(dram);
>>> @@ -708,7 +401,7 @@ static u64 dram_detect_cap(struct dram_info *dram,
>>> struct rk3328_sdram_params *sdram_params,
>>> unsigned char channel)
>>> {
>>> - void __iomem *pctl_base = dram->pctl;
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> /*
>>> * for ddr3: ddrconf = 3
>>> @@ -718,14 +411,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
>>> */
>>> u32 bk, bktmp;
>>> u32 col, coltmp;
>>> - u32 row, rowtmp, row_3_4;
>>> - void __iomem *test_addr, *test_addr1;
>>> - u32 dbw;
>>> + u32 rowtmp;
>>> u32 cs;
>>> u32 bw = 1;
>>> - u64 cap = 0;
>>> - u32 dram_type = sdram_params->dramtype;
>>> - u32 pwrctl;
>>> + u32 dram_type = sdram_params->base.dramtype;
>>> if (dram_type != DDR4) {
>>> /* detect col and bk for ddr3/lpddr3 */
>>> @@ -733,33 +422,10 @@ static u64 dram_detect_cap(struct dram_info *dram,
>>> bktmp = 3;
>>> rowtmp = 16;
>>> - for (col = coltmp; col >= 9; col -= 1) {
>>> - writel(0, SDRAM_ADDR);
>>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>>> - (1ul << (col + bw - 1ul)));
>>> - writel(PATTERN, test_addr);
>>> - if ((readl(test_addr) == PATTERN) &&
>>> - (readl(SDRAM_ADDR) == 0))
>>> - break;
>>> - }
>>> - if (col == 8) {
>>> - printf("col error\n");
>>> + if (sdram_detect_col(cap_info, coltmp) != 0)
>>> goto cap_err;
>>> - }
>>> -
>>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>>> - (1ul << (coltmp + bktmp + bw - 1ul)));
>>> - writel(0, SDRAM_ADDR);
>>> - writel(PATTERN, test_addr);
>>> - if ((readl(test_addr) == PATTERN) &&
>>> - (readl(SDRAM_ADDR) == 0))
>>> - bk = 3;
>>> - else
>>> - bk = 2;
>>> - if (dram_type == LPDDR3)
>>> - dbw = 2;
>>> - else
>>> - dbw = 1;
>>> + sdram_detect_bank(cap_info, coltmp, bktmp);
>>> + sdram_detect_dbw(cap_info, dram_type);
>>> } else {
>>> /* detect bg for ddr4 */
>>> coltmp = 10;
>>> @@ -768,178 +434,49 @@ static u64 dram_detect_cap(struct dram_info
>>> *dram,
>>> col = 10;
>>> bk = 2;
>>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>>> - (1ul << (coltmp + bw + 1ul)));
>>> - writel(0, SDRAM_ADDR);
>>> - writel(PATTERN, test_addr);
>>> - if ((readl(test_addr) == PATTERN) &&
>>> - (readl(SDRAM_ADDR) == 0))
>>> - dbw = 0;
>>> - else
>>> - dbw = 1;
>>> + cap_info->col = col;
>>> + cap_info->bk = bk;
>>> + sdram_detect_bg(cap_info, coltmp);
>>> }
>>> +
>>> /* detect row */
>>> - for (row = rowtmp; row > 12; row--) {
>>> - writel(0, SDRAM_ADDR);
>>> - test_addr = (void __iomem *)(SDRAM_ADDR +
>>> - (1ul << (row + bktmp + coltmp + bw - 1ul)));
>>> - writel(PATTERN, test_addr);
>>> - if ((readl(test_addr) == PATTERN) &&
>>> - (readl(SDRAM_ADDR) == 0))
>>> - break;
>>> - }
>>> - if (row == 12) {
>>> - printf("row error");
>>> + if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
>>> goto cap_err;
>>> - }
>>> - /* detect row_3_4 */
>>> - test_addr = SDRAM_ADDR;
>>> - test_addr1 = (void __iomem *)(SDRAM_ADDR +
>>> - (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
>>> -
>>> - writel(0, test_addr);
>>> - writel(PATTERN, test_addr1);
>>> - if ((readl(test_addr) == 0) &&
>>> - (readl(test_addr1) == PATTERN))
>>> - row_3_4 = 0;
>>> - else
>>> - row_3_4 = 1;
>>> - /* disable auto low-power */
>>> - pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
>>> - writel(0, pctl_base + DDR_PCTL2_PWRCTL);
>>> + /* detect row_3_4 */
>>> + sdram_detect_row_3_4(cap_info, coltmp, bktmp);
>>> - /* bw and cs detect using phy read gate training */
>>> + /* bw and cs detect using data training */
>>> if (data_training(dram, 1, dram_type) == 0)
>>> cs = 1;
>>> else
>>> cs = 0;
>>> + cap_info->rank = cs + 1;
>>> bw = 2;
>>> + cap_info->bw = bw;
>>> - /* restore auto low-power */
>>> - writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
>>> -
>>> - sdram_ch.rank = cs + 1;
>>> - sdram_ch.col = col;
>>> - sdram_ch.bk = bk;
>>> - sdram_ch.dbw = dbw;
>>> - sdram_ch.bw = bw;
>>> - sdram_ch.cs0_row = row;
>>> - if (cs)
>>> - sdram_ch.cs1_row = row;
>>> - else
>>> - sdram_ch.cs1_row = 0;
>>> - sdram_ch.row_3_4 = row_3_4;
>>> -
>>> - if (dram_type == DDR4)
>>> - cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) +
>>> bw);
>>> - else
>>> - cap = 1llu << (cs + row + bk + col + bw);
>>> -
>>> - return cap;
>>> -
>>> -cap_err:
>>> - return 0;
>>> -}
>>> -
>>> -static u32 remodify_sdram_params(struct rk3328_sdram_params
>>> *sdram_params)
>>> -{
>>> - u32 tmp = 0, tmp_adr = 0, i;
>>> -
>>> - for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF;
>>> i++) {
>>> - if (sdram_params->pctl_regs.pctl[i][0] == 0) {
>>> - tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
>>> - tmp_adr = i;
>>> - }
>>> - }
>>> -
>>> - tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
>>> -
>>> - switch (sdram_ch.dbw) {
>>> - case 2:
>>> - tmp |= (3ul << 30);
>>> - break;
>>> - case 1:
>>> - tmp |= (2ul << 30);
>>> - break;
>>> - case 0:
>>> - default:
>>> - tmp |= (1ul << 30);
>>> - break;
>>> + cap_info->cs0_high16bit_row = cap_info->cs0_row;
>>> + if (cs) {
>>> + cap_info->cs1_row = cap_info->cs0_row;
>>> + cap_info->cs1_high16bit_row = cap_info->cs0_row;
>>> + } else {
>>> + cap_info->cs1_row = 0;
>>> + cap_info->cs1_high16bit_row = 0;
>>> }
>>> - if (sdram_ch.rank == 2)
>>> - tmp |= 3 << 24;
>>> - else
>>> - tmp |= 1 << 24;
>>> -
>>> - tmp |= (2 - sdram_ch.bw) << 12;
>>> -
>>> - sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
>>> -
>>> - if (sdram_ch.bw == 2)
>>> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
>>> - else
>>> - sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
>>> -
>>> return 0;
>>> -}
>>> -
>>> -static int dram_detect_cs1_row(struct rk3328_sdram_params
>>> *sdram_params,
>>> - unsigned char channel)
>>> -{
>>> - u32 ret = 0;
>>> - u32 cs1_bit;
>>> - void __iomem *test_addr, *cs1_addr;
>>> - u32 row, bktmp, coltmp, bw;
>>> - u32 ddrconf = sdram_ch.ddrconfig;
>>> -
>>> - if (sdram_ch.rank == 2) {
>>> - cs1_bit = addrmap[ddrconf][0] + 8;
>>> -
>>> - if (cs1_bit > 31)
>>> - goto out;
>>> -
>>> - cs1_addr = (void __iomem *)(1ul << cs1_bit);
>>> - if (cs1_bit < 20)
>>> - cs1_bit = 1;
>>> - else
>>> - cs1_bit = 0;
>>> -
>>> - if (sdram_params->dramtype == DDR4) {
>>> - if (sdram_ch.dbw == 0)
>>> - bktmp = sdram_ch.bk + 2;
>>> - else
>>> - bktmp = sdram_ch.bk + 1;
>>> - } else {
>>> - bktmp = sdram_ch.bk;
>>> - }
>>> - bw = sdram_ch.bw;
>>> - coltmp = sdram_ch.col;
>>> -
>>> - /* detect cs1 row */
>>> - for (row = sdram_ch.cs0_row; row > 12; row--) {
>>> - test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
>>> - (1ul << (row + cs1_bit + bktmp +
>>> - coltmp + bw - 1ul)));
>>> - writel(0, SDRAM_ADDR + cs1_addr);
>>> - writel(PATTERN, test_addr);
>>> - if ((readl(test_addr) == PATTERN) &&
>>> - (readl(SDRAM_ADDR + cs1_addr) == 0)) {
>>> - ret = row;
>>> - break;
>>> - }
>>> - }
>>> - }
>>> -
>>> -out:
>>> - return ret;
>>> +cap_err:
>>> + return -1;
>>> }
>>> static int sdram_init_detect(struct dram_info *dram,
>>> struct rk3328_sdram_params *sdram_params)
>>> {
>>> + u32 sys_reg = 0;
>>> + u32 sys_reg3 = 0;
>>> + struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
>>> +
>>> debug("Starting SDRAM initialization...\n");
>>> memcpy(&sdram_ch, &sdram_params->ch,
>>> @@ -949,13 +486,30 @@ static int sdram_init_detect(struct dram_info
>>> *dram,
>>> dram_detect_cap(dram, sdram_params, 0);
>>> /* modify bw, cs related timing */
>>> - remodify_sdram_params(sdram_params);
>>> + pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
>>> + sdram_params->base.dramtype);
>>> +
>>> + if (cap_info->bw == 2)
>>> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
>>> + else
>>> + sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
>>> +
>>> /* reinit sdram by real dram cap */
>>> sdram_init(dram, sdram_params, 0);
>>> /* redetect cs1 row */
>>> - sdram_ch.cs1_row =
>>> - dram_detect_cs1_row(sdram_params, 0);
>>> + sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
>>> + if (cap_info->cs1_row) {
>>> + sys_reg = readl(&dram->grf->os_reg[2]);
>>> + sys_reg3 = readl(&dram->grf->os_reg[3]);
>>> + SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
>>> + sys_reg, sys_reg3, 0);
>>> + writel(sys_reg, &dram->grf->os_reg[2]);
>>> + writel(sys_reg3, &dram->grf->os_reg[3]);
>>> + }
>>> +
>>> + sdram_print_ddr_info(&sdram_params->ch.cap_info,
>>> + &sdram_params->base, 0);
>>> return 0;
>>> }
>>>
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> https://lists.denx.de/listinfo/u-boot
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 5/9] ram: rk3399: use common sdram driver
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (3 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 4/9] ram: rk3328: use common " Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 6/9] ram: rockchip: update lpddr4 timing for rk3399 Kever Yang
` (4 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
RK3399's controller and phy are able to re-use the common code, migrate
to use the common driver and remove duplicated code.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi | 4 +
arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi | 4 +
arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi | 4 +
.../arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi | 4 +
.../arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi | 4 +
.../rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi | 4 +
arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi | 4 +
.../include/asm/arch-rockchip/sdram_rk3399.h | 97 +-
arch/arm/mach-rockchip/Kconfig | 1 +
drivers/ram/rockchip/Kconfig | 21 +-
drivers/ram/rockchip/Makefile | 3 +-
.../ram/rockchip/sdram-rk3399-lpddr4-400.inc | 28 +-
.../ram/rockchip/sdram-rk3399-lpddr4-800.inc | 28 +-
drivers/ram/rockchip/sdram_rk3399.c | 970 ++++++++++++------
14 files changed, 787 insertions(+), 389 deletions(-)
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
index 3708bd674b..7fae249536 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
@@ -13,6 +13,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80120e12
0x11030802
@@ -28,6 +30,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80120e12
0x11030802
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
index fcd01f8b46..23c7c34a9a 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
@@ -13,6 +13,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80151015
0x14040902
@@ -28,6 +30,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80151015
0x14040902
diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
index c46c1996be..ea029ca90a 100644
--- a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
+++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
@@ -13,6 +13,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80181219
0x17050a03
@@ -28,6 +30,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80181219
0x17050a03
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
index d14e833d22..7296dbb80e 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
@@ -14,6 +14,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x1d191519
0x14040808
@@ -29,6 +31,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x1d191519
0x14040808
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
index fc4cccb6a0..bf429c21e4 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
@@ -13,6 +13,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x1d191519
0x14040808
@@ -28,6 +30,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x1d191519
0x14040808
diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
index 2a627e1be5..96f459fd0b 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
@@ -13,6 +13,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x801d181e
@@ -30,6 +32,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x801d181e
diff --git a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
index 4a4414a960..f0c478d189 100644
--- a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
+++ b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
@@ -15,6 +15,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80241d22
0x15050f08
@@ -30,6 +32,8 @@
0x0
0xf
0xf
+ 0xf
+ 0xf
1
0x80241d22
0x15050f08
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
index 485bb3d889..9e1e22520f 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h
@@ -6,6 +6,7 @@
#ifndef _ASM_ARCH_SDRAM_RK3399_H
#define _ASM_ARCH_SDRAM_RK3399_H
#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_msch.h>
struct rk3399_ddr_pctl_regs {
u32 denali_ctl[332];
@@ -19,55 +20,6 @@ struct rk3399_ddr_pi_regs {
u32 denali_pi[200];
};
-union noc_ddrtimingc0 {
- u32 d32;
- struct {
- unsigned burstpenalty : 4;
- unsigned reserved0 : 4;
- unsigned wrtomwr : 6;
- unsigned reserved1 : 18;
- } b;
-};
-
-union noc_ddrmode {
- u32 d32;
- struct {
- unsigned autoprecharge : 1;
- unsigned bypassfiltering : 1;
- unsigned fawbank : 1;
- unsigned burstsize : 2;
- unsigned mwrsize : 2;
- unsigned reserved2 : 1;
- unsigned forceorder : 8;
- unsigned forceorderstate : 8;
- unsigned reserved3 : 8;
- } b;
-};
-
-struct rk3399_msch_regs {
- u32 coreid;
- u32 revisionid;
- u32 ddrconf;
- u32 ddrsize;
- u32 ddrtiminga0;
- u32 ddrtimingb0;
- u32 ddrtimingc0;
- u32 devtodev0;
- u32 reserved0[(0x110 - 0x20) / 4];
- u32 ddrmode;
- u32 reserved1[(0x1000 - 0x114) / 4];
- u32 agingx0;
-};
-
-struct rk3399_msch_timings {
- u32 ddrtiminga0;
- u32 ddrtimingb0;
- union noc_ddrtimingc0 ddrtimingc0;
- u32 devtodev0;
- union noc_ddrmode ddrmode;
- u32 agingx0;
-};
-
struct rk3399_ddr_cic_regs {
u32 cic_ctrl0;
u32 cic_ctrl1;
@@ -84,14 +36,38 @@ struct rk3399_ddr_cic_regs {
#define START 1
/* DENALI_CTL_68 */
-#define PWRUP_SREFRESH_EXIT (1 << 16)
+#define PWRUP_SREFRESH_EXIT BIT(16)
/* DENALI_CTL_274 */
#define MEM_RST_VALID 1
+struct msch_regs {
+ u32 coreid;
+ u32 revisionid;
+ u32 ddrconf;
+ u32 ddrsize;
+ union noc_ddrtiminga0 ddrtiminga0;
+ union noc_ddrtimingb0 ddrtimingb0;
+ union noc_ddrtimingc0 ddrtimingc0;
+ union noc_devtodev0 devtodev0;
+ u32 reserved0[(0x110 - 0x20) / 4];
+ union noc_ddrmode ddrmode;
+ u32 reserved1[(0x1000 - 0x114) / 4];
+ u32 agingx0;
+};
+
+struct sdram_msch_timings {
+ union noc_ddrtiminga0 ddrtiminga0;
+ union noc_ddrtimingb0 ddrtimingb0;
+ union noc_ddrtimingc0 ddrtimingc0;
+ union noc_devtodev0 devtodev0;
+ union noc_ddrmode ddrmode;
+ u32 agingx0;
+};
+
struct rk3399_sdram_channel {
struct sdram_cap_info cap_info;
- struct rk3399_msch_timings noc_timings;
+ struct sdram_msch_timings noc_timings;
};
struct rk3399_sdram_params {
@@ -102,11 +78,20 @@ struct rk3399_sdram_params {
struct rk3399_ddr_publ_regs phy_regs;
};
-#define PI_CA_TRAINING (1 << 0)
-#define PI_WRITE_LEVELING (1 << 1)
-#define PI_READ_GATE_TRAINING (1 << 2)
-#define PI_READ_LEVELING (1 << 3)
-#define PI_WDQ_LEVELING (1 << 4)
+#define PI_CA_TRAINING BIT(0)
+#define PI_WRITE_LEVELING BIT(1)
+#define PI_READ_GATE_TRAINING BIT(2)
+#define PI_READ_LEVELING BIT(3)
+#define PI_WDQ_LEVELING BIT(4)
#define PI_FULL_TRAINING 0xff
+enum {
+ STRIDE_128B = 0,
+ STRIDE_256B = 1,
+ STRIDE_512B = 2,
+ STRIDE_4KB = 3,
+ UN_STRIDE = 4,
+ PART_STRIDE = 5
+};
+
#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 5f1ad51cac..7746b661e5 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -184,6 +184,7 @@ config ROCKCHIP_RK3399
select DM_REGULATOR_FIXED
select BOARD_LATE_INIT
imply ROCKCHIP_COMMON_BOARD
+ imply ROCKCHIP_SDRAM_COMMON
imply SPL_ROCKCHIP_COMMON_BOARD
imply TPL_SERIAL_SUPPORT
imply TPL_LIBCOMMON_SUPPORT
diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig
index dcc06b3fd3..3f44fb3fce 100644
--- a/drivers/ram/rockchip/Kconfig
+++ b/drivers/ram/rockchip/Kconfig
@@ -11,29 +11,10 @@ config ROCKCHIP_SDRAM_COMMON
help
This enable sdram common driver
-if RAM_ROCKCHIP
-
-config RAM_ROCKCHIP_DEBUG
- bool "Rockchip ram drivers debugging"
- help
- This enables debugging ram driver API's for the platforms
- based on Rockchip SoCs.
-
- This is an option for developers to understand the ram drivers
- initialization, configurations and etc.
-
-config RAM_RK3399
- bool "Ram driver for Rockchip RK3399"
- default ROCKCHIP_RK3399
- help
- This enables ram drivers support for the platforms based on
- Rockchip RK3399 SoC.
-
config RAM_RK3399_LPDDR4
bool "LPDDR4 support for Rockchip RK3399"
- depends on RAM_RK3399
+ depends on RAM_ROCKCHIP && ROCKCHIP_RK3399
help
This enables LPDDR4 sdram code support for the platforms based
on Rockchip RK3399 SoC.
-endif # RAM_ROCKCHIP
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 3f19fa09a5..47b9b1bebb 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -3,11 +3,10 @@
# Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
#
obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
-obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.o
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
-obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
index c50a03d9dd..6ddc01c49d 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
@@ -16,15 +16,23 @@
.row_3_4 = 0x0,
.cs0_row = 0xF,
.cs1_row = 0xF,
+ .cs0_high16bit_row = 0xF,
+ .cs1_high16bit_row = 0xF,
.ddrconfig = 1,
},
{
- .ddrtiminga0 = 0x80241d22,
- .ddrtimingb0 = 0x15050f08,
+ .ddrtiminga0 = {
+ 0x80241d22,
+ },
+ .ddrtimingb0 = {
+ 0x15050f08,
+ },
.ddrtimingc0 = {
0x00000602,
},
- .devtodev0 = 0x00002122,
+ .devtodev0 = {
+ 0x00002122,
+ },
.ddrmode = {
0x0000004c,
},
@@ -41,15 +49,23 @@
.row_3_4 = 0x0,
.cs0_row = 0xF,
.cs1_row = 0xF,
+ .cs0_high16bit_row = 0xF,
+ .cs1_high16bit_row = 0xF,
.ddrconfig = 1,
},
{
- .ddrtiminga0 = 0x80241d22,
- .ddrtimingb0 = 0x15050f08,
+ .ddrtiminga0 = {
+ 0x80241d22,
+ },
+ .ddrtimingb0 = {
+ 0x15050f08,
+ },
.ddrtimingc0 = {
0x00000602,
},
- .devtodev0 = 0x00002122,
+ .devtodev0 = {
+ 0x00002122,
+ },
.ddrmode = {
0x0000004c,
},
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
index d8ae3359a3..307f6ee458 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
@@ -16,15 +16,23 @@
.row_3_4 = 0x0,
.cs0_row = 0xF,
.cs1_row = 0xF,
+ .cs0_high16bit_row = 0xF,
+ .cs1_high16bit_row = 0xF,
.ddrconfig = 1,
},
{
- .ddrtiminga0 = 0x80241d22,
- .ddrtimingb0 = 0x15050f08,
+ .ddrtiminga0 = {
+ 0x80241d22,
+ },
+ .ddrtimingb0 = {
+ 0x15050f08,
+ },
.ddrtimingc0 = {
0x00000602,
},
- .devtodev0 = 0x00002122,
+ .devtodev0 = {
+ 0x00002122,
+ },
.ddrmode = {
0x0000004c,
},
@@ -41,15 +49,23 @@
.row_3_4 = 0x0,
.cs0_row = 0xF,
.cs1_row = 0xF,
+ .cs0_high16bit_row = 0xF,
+ .cs1_high16bit_row = 0xF,
.ddrconfig = 1,
},
{
- .ddrtiminga0 = 0x80241d22,
- .ddrtimingb0 = 0x15050f08,
+ .ddrtiminga0 = {
+ 0x80241d22,
+ },
+ .ddrtimingb0 = {
+ 0x15050f08,
+ },
.ddrtimingc0 = {
0x00000602,
},
- .devtodev0 = 0x00002122,
+ .devtodev0 = {
+ 0x00002122,
+ },
.ddrmode = {
0x0000004c,
},
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index b5a0bac99b..223ebadaec 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -52,7 +52,7 @@ struct chan_info {
struct rk3399_ddr_pctl_regs *pctl;
struct rk3399_ddr_pi_regs *pi;
struct rk3399_ddr_publ_regs *publ;
- struct rk3399_msch_regs *msch;
+ struct msch_regs *msch;
};
struct dram_info {
@@ -74,10 +74,15 @@ struct dram_info {
};
struct sdram_rk3399_ops {
- int (*data_training)(struct dram_info *dram, u32 channel, u8 rank,
- struct rk3399_sdram_params *sdram);
- int (*set_rate)(struct dram_info *dram,
- struct rk3399_sdram_params *params);
+ int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
+ struct rk3399_sdram_params *sdram);
+ int (*set_rate_index)(struct dram_info *dram,
+ struct rk3399_sdram_params *params);
+ void (*modify_param)(const struct chan_info *chan,
+ struct rk3399_sdram_params *params);
+ struct rk3399_sdram_params *
+ (*get_phy_index_params)(u32 phy_fn,
+ struct rk3399_sdram_params *params);
};
#if defined(CONFIG_TPL_BUILD) || \
@@ -196,11 +201,6 @@ struct io_setting {
},
};
-/**
- * phy = 0, PHY boot freq
- * phy = 1, PHY index 0
- * phy = 2, PHY index 1
- */
static struct io_setting *
lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
{
@@ -223,32 +223,21 @@ lpddr4_get_io_settings(const struct rk3399_sdram_params *params, u32 mr5)
return io;
}
-static void *get_denali_phy(const struct chan_info *chan,
- struct rk3399_sdram_params *params, bool reg)
-{
- return reg ? &chan->publ->denali_phy : ¶ms->phy_regs.denali_phy;
-}
-
static void *get_denali_ctl(const struct chan_info *chan,
struct rk3399_sdram_params *params, bool reg)
{
return reg ? &chan->pctl->denali_ctl : ¶ms->pctl_regs.denali_ctl;
}
-static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
+static void *get_denali_phy(const struct chan_info *chan,
+ struct rk3399_sdram_params *params, bool reg)
{
- return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc0_con1;
+ return reg ? &chan->publ->denali_phy : ¶ms->phy_regs.denali_phy;
}
-static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
+static void *get_ddrc0_con(struct dram_info *dram, u8 channel)
{
- int i;
-
- for (i = 0; i < n / sizeof(u32); i++) {
- writel(*src, dest);
- src++;
- dest++;
- }
+ return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc1_con0;
}
static void rkclk_ddr_reset(struct rk3399_cru *cru, u32 channel, u32 ctl,
@@ -344,7 +333,7 @@ static void set_memory_map(const struct chan_info *chan, u32 channel,
((3 - sdram_ch->cap_info.bk) << 16) |
((16 - row) << 24));
- if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+ if (params->base.dramtype == LPDDR4) {
if (cs_map == 1)
cs_map = 0x5;
else if (cs_map == 2)
@@ -496,7 +485,7 @@ static int phy_io_config(const struct chan_info *chan,
/* PHY_939 PHY_PAD_CS_DRIVE */
clrsetbits_le32(&denali_phy[939], 0x7 << 14, mode_sel << 14);
- if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+ if (params->base.dramtype == LPDDR4) {
/* BOOSTP_EN & BOOSTN_EN */
reg_value = ((PHY_BOOSTP_EN << 4) | PHY_BOOSTN_EN);
/* PHY_925 PHY_PAD_FDBK_DRIVE2 */
@@ -563,7 +552,7 @@ static int phy_io_config(const struct chan_info *chan,
/* PHY_939 PHY_PAD_CS_DRIVE */
clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
- if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+ if (params->base.dramtype == LPDDR4) {
/* RX_CM_INPUT */
reg_value = PHY_RX_CM_INPUT;
/* PHY_924 PHY_PAD_FDBK_DRIVE */
@@ -733,7 +722,7 @@ static void set_ds_odt(const struct chan_info *chan,
/* phy_adr_tsel_select_ 8bits DENALI_PHY_544/672/800 offset_0 */
reg_value = tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 0x4);
- if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+ if (params->base.dramtype == LPDDR4) {
/* LPDDR4 these register read always return 0, so
* can not use clrsetbits_le32(), need to write32
*/
@@ -810,46 +799,107 @@ static void set_ds_odt(const struct chan_info *chan,
phy_io_config(chan, params, mr5);
}
-static void pctl_start(struct dram_info *dram, u8 channel)
+static void pctl_start(struct dram_info *dram,
+ struct rk3399_sdram_params *params,
+ u32 channel_mask)
{
- const struct chan_info *chan = &dram->chan[channel];
- u32 *denali_ctl = chan->pctl->denali_ctl;
- u32 *denali_phy = chan->publ->denali_phy;
- u32 *ddrc0_con = get_ddrc0_con(dram, channel);
+ const struct chan_info *chan_0 = &dram->chan[0];
+ const struct chan_info *chan_1 = &dram->chan[1];
+
+ u32 *denali_ctl_0 = chan_0->pctl->denali_ctl;
+ u32 *denali_phy_0 = chan_0->publ->denali_phy;
+ u32 *ddrc0_con_0 = get_ddrc0_con(dram, 0);
+ u32 *denali_ctl_1 = chan_1->pctl->denali_ctl;
+ u32 *denali_phy_1 = chan_1->publ->denali_phy;
+ u32 *ddrc1_con_0 = get_ddrc0_con(dram, 1);
u32 count = 0;
u32 byte, tmp;
- writel(0x01000000, &ddrc0_con);
+ /* PHY_DLL_RST_EN */
+ if (channel_mask & 1) {
+ writel(0x01000000, &ddrc0_con_0);
+ clrsetbits_le32(&denali_phy_0[957], 0x3 << 24, 0x2 << 24);
+ }
- clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24);
+ if (channel_mask & 1) {
+ count = 0;
+ while (!(readl(&denali_ctl_0[203]) & (1 << 3))) {
+ if (count > 1000) {
+ printf("%s: Failed to init pctl channel 0\n",
+ __func__);
+ while (1)
+ ;
+ }
+ udelay(1);
+ count++;
+ }
- while (!(readl(&denali_ctl[203]) & (1 << 3))) {
- if (count > 1000) {
- printf("%s: Failed to init pctl for channel %d\n",
- __func__, channel);
- while (1)
- ;
+ writel(0x01000100, &ddrc0_con_0);
+ for (byte = 0; byte < 4; byte++) {
+ tmp = 0x820;
+ writel((tmp << 16) | tmp,
+ &denali_phy_0[53 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_0[54 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_0[55 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_0[56 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_0[57 + (128 * byte)]);
+ clrsetbits_le32(&denali_phy_0[58 + (128 * byte)],
+ 0xffff, tmp);
}
+ clrsetbits_le32(&denali_ctl_0[68], PWRUP_SREFRESH_EXIT,
+ dram->pwrup_srefresh_exit[0]);
+ }
- udelay(1);
- count++;
+ if (channel_mask & 2) {
+ writel(0x01000000, &ddrc1_con_0);
+ clrsetbits_le32(&denali_phy_1[957], 0x3 << 24, 0x2 << 24);
}
+ if (channel_mask & 2) {
+ count = 0;
+ while (!(readl(&denali_ctl_1[203]) & (1 << 3))) {
+ if (count > 1000) {
+ printf("%s: Failed to init pctl channel 1\n",
+ __func__);
+ while (1)
+ ;
+ }
+ udelay(1);
+ count++;
+ }
- writel(0x01000100, &ddrc0_con);
+ writel(0x01000100, &ddrc1_con_0);
+ for (byte = 0; byte < 4; byte++) {
+ tmp = 0x820;
+ writel((tmp << 16) | tmp,
+ &denali_phy_1[53 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_1[54 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_1[55 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_1[56 + (128 * byte)]);
+ writel((tmp << 16) | tmp,
+ &denali_phy_1[57 + (128 * byte)]);
+ clrsetbits_le32(&denali_phy_1[58 + (128 * byte)],
+ 0xffff, tmp);
+ }
- for (byte = 0; byte < 4; byte++) {
- tmp = 0x820;
- writel((tmp << 16) | tmp, &denali_phy[53 + (128 * byte)]);
- writel((tmp << 16) | tmp, &denali_phy[54 + (128 * byte)]);
- writel((tmp << 16) | tmp, &denali_phy[55 + (128 * byte)]);
- writel((tmp << 16) | tmp, &denali_phy[56 + (128 * byte)]);
- writel((tmp << 16) | tmp, &denali_phy[57 + (128 * byte)]);
+ clrsetbits_le32(&denali_ctl_1[68], PWRUP_SREFRESH_EXIT,
+ dram->pwrup_srefresh_exit[1]);
- clrsetbits_le32(&denali_phy[58 + (128 * byte)], 0xffff, tmp);
+ /*
+ * restore channel 1 RESET original setting
+ * to avoid 240ohm too weak to prevent ESD test
+ */
+ if (params->base.dramtype == LPDDR4)
+ clrsetbits_le32(&denali_phy_1[937], 0xff,
+ params->phy_regs.denali_phy[937] &
+ 0xFF);
}
-
- clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT,
- dram->pwrup_srefresh_exit[channel]);
}
static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
@@ -861,13 +911,16 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
const u32 *params_ctl = params->pctl_regs.denali_ctl;
const u32 *params_phy = params->phy_regs.denali_phy;
u32 tmp, tmp1, tmp2;
+ struct rk3399_sdram_params *params_cfg;
+ u32 byte;
+ dram->ops->modify_param(chan, params);
/*
* work around controller bug:
* Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
*/
- copy_to_reg(&denali_ctl[1], ¶ms_ctl[1],
- sizeof(struct rk3399_ddr_pctl_regs) - 4);
+ sdram_copy_to_reg(&denali_ctl[1], ¶ms_ctl[1],
+ sizeof(struct rk3399_ddr_pctl_regs) - 4);
writel(params_ctl[0], &denali_ctl[0]);
/*
@@ -884,8 +937,8 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
writel(tmp + tmp1, &denali_ctl[14]);
}
- copy_to_reg(denali_pi, ¶ms->pi_regs.denali_pi[0],
- sizeof(struct rk3399_ddr_pi_regs));
+ sdram_copy_to_reg(denali_pi, ¶ms->pi_regs.denali_pi[0],
+ sizeof(struct rk3399_ddr_pi_regs));
/* rank count need to set for init */
set_memory_map(chan, channel, params);
@@ -894,7 +947,7 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
writel(params->phy_regs.denali_phy[911], &denali_phy[911]);
writel(params->phy_regs.denali_phy[912], &denali_phy[912]);
- if (IS_ENABLED(CONFIG_RAM_RK3399_LPDDR4)) {
+ if (params->base.dramtype == LPDDR4) {
writel(params->phy_regs.denali_phy[898], &denali_phy[898]);
writel(params->phy_regs.denali_phy[919], &denali_phy[919]);
}
@@ -927,41 +980,67 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan,
}
}
- copy_to_reg(&denali_phy[896], ¶ms_phy[896], (958 - 895) * 4);
- copy_to_reg(&denali_phy[0], ¶ms_phy[0], (90 - 0 + 1) * 4);
- copy_to_reg(&denali_phy[128], ¶ms_phy[128], (218 - 128 + 1) * 4);
- copy_to_reg(&denali_phy[256], ¶ms_phy[256], (346 - 256 + 1) * 4);
- copy_to_reg(&denali_phy[384], ¶ms_phy[384], (474 - 384 + 1) * 4);
- copy_to_reg(&denali_phy[512], ¶ms_phy[512], (549 - 512 + 1) * 4);
- copy_to_reg(&denali_phy[640], ¶ms_phy[640], (677 - 640 + 1) * 4);
- copy_to_reg(&denali_phy[768], ¶ms_phy[768], (805 - 768 + 1) * 4);
- set_ds_odt(chan, params, true, 0);
+ sdram_copy_to_reg(&denali_phy[896], ¶ms_phy[896], (958 - 895) * 4);
+ sdram_copy_to_reg(&denali_phy[0], ¶ms_phy[0], (90 - 0 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[128], ¶ms_phy[128],
+ (218 - 128 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[256], ¶ms_phy[256],
+ (346 - 256 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[384], ¶ms_phy[384],
+ (474 - 384 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[512], ¶ms_phy[512],
+ (549 - 512 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[640], ¶ms_phy[640],
+ (677 - 640 + 1) * 4);
+ sdram_copy_to_reg(&denali_phy[768], ¶ms_phy[768],
+ (805 - 768 + 1) * 4);
- /*
- * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_84/212/340/468 offset_8
- * dqs_tsel_wr_end[7:4] add Half cycle
- */
- tmp = (readl(&denali_phy[84]) >> 8) & 0xff;
- clrsetbits_le32(&denali_phy[84], 0xff << 8, (tmp + 0x10) << 8);
- tmp = (readl(&denali_phy[212]) >> 8) & 0xff;
- clrsetbits_le32(&denali_phy[212], 0xff << 8, (tmp + 0x10) << 8);
- tmp = (readl(&denali_phy[340]) >> 8) & 0xff;
- clrsetbits_le32(&denali_phy[340], 0xff << 8, (tmp + 0x10) << 8);
- tmp = (readl(&denali_phy[468]) >> 8) & 0xff;
- clrsetbits_le32(&denali_phy[468], 0xff << 8, (tmp + 0x10) << 8);
+ if (params->base.dramtype == LPDDR4)
+ params_cfg = dram->ops->get_phy_index_params(1, params);
+ else
+ params_cfg = dram->ops->get_phy_index_params(0, params);
+
+ clrsetbits_le32(¶ms_cfg->phy_regs.denali_phy[896], 0x3 << 8,
+ 0 << 8);
+ writel(params_cfg->phy_regs.denali_phy[896], &denali_phy[896]);
+
+ writel(params->phy_regs.denali_phy[83] + (0x10 << 16),
+ &denali_phy[83]);
+ writel(params->phy_regs.denali_phy[84] + (0x10 << 8),
+ &denali_phy[84]);
+ writel(params->phy_regs.denali_phy[211] + (0x10 << 16),
+ &denali_phy[211]);
+ writel(params->phy_regs.denali_phy[212] + (0x10 << 8),
+ &denali_phy[212]);
+ writel(params->phy_regs.denali_phy[339] + (0x10 << 16),
+ &denali_phy[339]);
+ writel(params->phy_regs.denali_phy[340] + (0x10 << 8),
+ &denali_phy[340]);
+ writel(params->phy_regs.denali_phy[467] + (0x10 << 16),
+ &denali_phy[467]);
+ writel(params->phy_regs.denali_phy[468] + (0x10 << 8),
+ &denali_phy[468]);
- /*
- * phy_dqs_tsel_wr_timing_X 8bits DENALI_PHY_83/211/339/467 offset_8
- * dq_tsel_wr_end[7:4] add Half cycle
- */
- tmp = (readl(&denali_phy[83]) >> 16) & 0xff;
- clrsetbits_le32(&denali_phy[83], 0xff << 16, (tmp + 0x10) << 16);
- tmp = (readl(&denali_phy[211]) >> 16) & 0xff;
- clrsetbits_le32(&denali_phy[211], 0xff << 16, (tmp + 0x10) << 16);
- tmp = (readl(&denali_phy[339]) >> 16) & 0xff;
- clrsetbits_le32(&denali_phy[339], 0xff << 16, (tmp + 0x10) << 16);
- tmp = (readl(&denali_phy[467]) >> 16) & 0xff;
- clrsetbits_le32(&denali_phy[467], 0xff << 16, (tmp + 0x10) << 16);
+ if (params->base.dramtype == LPDDR4) {
+ /*
+ * to improve write dqs and dq phase from 1.5ns to 3.5ns
+ * at 50MHz. this's the measure result from oscilloscope
+ * of dqs and dq write signal.
+ */
+ for (byte = 0; byte < 4; byte++) {
+ tmp = 0x680;
+ clrsetbits_le32(&denali_phy[1 + (128 * byte)],
+ 0xfff << 8, tmp << 8);
+ }
+ /*
+ * to workaround 366ball two channel's RESET connect to
+ * one RESET signal of die
+ */
+ if (channel == 1)
+ clrsetbits_le32(&denali_phy[937], 0xff,
+ PHY_DRV_ODT_240 |
+ (PHY_DRV_ODT_240 << 0x4));
+ }
return 0;
}
@@ -1392,7 +1471,7 @@ static void set_ddrconfig(const struct chan_info *chan,
unsigned char channel, u32 ddrconfig)
{
/* only need to set ddrconfig */
- struct rk3399_msch_regs *ddr_msch_regs = chan->msch;
+ struct msch_regs *ddr_msch_regs = chan->msch;
unsigned int cs0_cap = 0;
unsigned int cs1_cap = 0;
@@ -1413,52 +1492,43 @@ static void set_ddrconfig(const struct chan_info *chan,
&ddr_msch_regs->ddrsize);
}
+static void sdram_msch_config(struct msch_regs *msch,
+ struct sdram_msch_timings *noc_timings)
+{
+ writel(noc_timings->ddrtiminga0.d32,
+ &msch->ddrtiminga0.d32);
+ writel(noc_timings->ddrtimingb0.d32,
+ &msch->ddrtimingb0.d32);
+ writel(noc_timings->ddrtimingc0.d32,
+ &msch->ddrtimingc0.d32);
+ writel(noc_timings->devtodev0.d32,
+ &msch->devtodev0.d32);
+ writel(noc_timings->ddrmode.d32,
+ &msch->ddrmode.d32);
+}
+
static void dram_all_config(struct dram_info *dram,
- const struct rk3399_sdram_params *params)
+ struct rk3399_sdram_params *params)
{
u32 sys_reg2 = 0;
u32 sys_reg3 = 0;
unsigned int channel, idx;
- sys_reg2 |= SYS_REG_ENC_DDRTYPE(params->base.dramtype);
- sys_reg2 |= SYS_REG_ENC_NUM_CH(params->base.num_channels);
-
for (channel = 0, idx = 0;
(idx < params->base.num_channels) && (channel < 2);
channel++) {
- const struct rk3399_sdram_channel *info = ¶ms->ch[channel];
- struct rk3399_msch_regs *ddr_msch_regs;
- const struct rk3399_msch_timings *noc_timing;
+ struct msch_regs *ddr_msch_regs;
+ struct sdram_msch_timings *noc_timing;
if (params->ch[channel].cap_info.col == 0)
continue;
idx++;
- sys_reg2 |= SYS_REG_ENC_ROW_3_4(info->cap_info.row_3_4, channel);
- sys_reg2 |= SYS_REG_ENC_CHINFO(channel);
- sys_reg2 |= SYS_REG_ENC_RANK(info->cap_info.rank, channel);
- sys_reg2 |= SYS_REG_ENC_COL(info->cap_info.col, channel);
- sys_reg2 |= SYS_REG_ENC_BK(info->cap_info.bk, channel);
- sys_reg2 |= SYS_REG_ENC_BW(info->cap_info.bw, channel);
- sys_reg2 |= SYS_REG_ENC_DBW(info->cap_info.dbw, channel);
- SYS_REG_ENC_CS0_ROW(info->cap_info.cs0_row, sys_reg2, sys_reg3, channel);
- if (info->cap_info.cs1_row)
- SYS_REG_ENC_CS1_ROW(info->cap_info.cs1_row, sys_reg2,
- sys_reg3, channel);
- sys_reg3 |= SYS_REG_ENC_CS1_COL(info->cap_info.col, channel);
- sys_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
-
+ sdram_org_config(¶ms->ch[channel].cap_info,
+ ¶ms->base, &sys_reg2,
+ &sys_reg3, channel);
ddr_msch_regs = dram->chan[channel].msch;
noc_timing = ¶ms->ch[channel].noc_timings;
- writel(noc_timing->ddrtiminga0,
- &ddr_msch_regs->ddrtiminga0);
- writel(noc_timing->ddrtimingb0,
- &ddr_msch_regs->ddrtimingb0);
- writel(noc_timing->ddrtimingc0.d32,
- &ddr_msch_regs->ddrtimingc0);
- writel(noc_timing->devtodev0,
- &ddr_msch_regs->devtodev0);
- writel(noc_timing->ddrmode.d32,
- &ddr_msch_regs->ddrmode);
+ sdram_msch_config(ddr_msch_regs, noc_timing);
/**
* rank 1 memory clock disable (dfi_dram_clk_disable = 1)
@@ -1494,7 +1564,7 @@ static void set_cap_relate_config(const struct chan_info *chan,
{
u32 *denali_ctl = chan->pctl->denali_ctl;
u32 tmp;
- struct rk3399_msch_timings *noc_timing;
+ struct sdram_msch_timings *noc_timing;
if (params->base.dramtype == LPDDR3) {
tmp = (8 << params->ch[channel].cap_info.bw) /
@@ -1566,9 +1636,14 @@ static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
return i;
}
+static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
+{
+ rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
+}
+
#if !defined(CONFIG_RAM_RK3399_LPDDR4)
-static int default_data_training(struct dram_info *dram, u32 channel, u8 rank,
- struct rk3399_sdram_params *params)
+static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
+ struct rk3399_sdram_params *params)
{
u8 training_flag = PI_READ_GATE_TRAINING;
@@ -1629,31 +1704,72 @@ static int switch_to_phy_index1(struct dram_info *dram,
return 0;
}
+struct rk3399_sdram_params
+ *get_phy_index_params(u32 phy_fn,
+ struct rk3399_sdram_params *params)
+{
+ if (phy_fn == 0)
+ return params;
+ else
+ return NULL;
+}
+
+void modify_param(const struct chan_info *chan,
+ struct rk3399_sdram_params *params)
+{
+ struct rk3399_sdram_params *params_cfg;
+ u32 *denali_pi_params;
+
+ denali_pi_params = params->pi_regs.denali_pi;
+
+ /* modify PHY F0/F1/F2 params */
+ params_cfg = get_phy_index_params(0, params);
+ set_ds_odt(chan, params_cfg, false, 0);
+
+ clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+}
#else
-struct rk3399_sdram_params lpddr4_timings[] = {
- #include "sdram-rk3399-lpddr4-400.inc"
- #include "sdram-rk3399-lpddr4-800.inc"
+struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
+#include "sdram-rk3399-lpddr4-400.inc"
+#include "sdram-rk3399-lpddr4-800.inc"
};
+static struct rk3399_sdram_params
+ *lpddr4_get_phy_index_params(u32 phy_fn,
+ struct rk3399_sdram_params *params)
+{
+ if (phy_fn == 0)
+ return params;
+ else if (phy_fn == 1)
+ return &dfs_cfgs_lpddr4[1];
+ else if (phy_fn == 2)
+ return &dfs_cfgs_lpddr4[0];
+ else
+ return NULL;
+}
+
static void *get_denali_pi(const struct chan_info *chan,
struct rk3399_sdram_params *params, bool reg)
{
return reg ? &chan->pi->denali_pi : ¶ms->pi_regs.denali_pi;
}
-static u32 lpddr4_get_phy(struct rk3399_sdram_params *params, u32 ctl)
+static u32 lpddr4_get_phy_fn(struct rk3399_sdram_params *params, u32 ctl_fn)
{
- u32 lpddr4_phy[] = {1, 0, 0xb};
+ u32 lpddr4_phy_fn[] = {1, 0, 0xb};
- return lpddr4_phy[ctl];
+ return lpddr4_phy_fn[ctl_fn];
}
-static u32 lpddr4_get_ctl(struct rk3399_sdram_params *params, u32 phy)
+static u32 lpddr4_get_ctl_fn(struct rk3399_sdram_params *params, u32 phy_fn)
{
- u32 lpddr4_ctl[] = {1, 0, 2};
+ u32 lpddr4_ctl_fn[] = {1, 0, 2};
- return lpddr4_ctl[phy];
+ return lpddr4_ctl_fn[phy_fn];
}
static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
@@ -1661,12 +1777,7 @@ static u32 get_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf)
return ((readl(&pmusgrf->soc_con4) >> 10) & 0x1F);
}
-static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
-{
- rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
-}
-
-/**
+/*
* read mr_num mode register
* rank = 1: cs0
* rank = 2: cs1
@@ -1797,7 +1908,7 @@ end:
}
static void set_lpddr4_dq_odt(const struct chan_info *chan,
- struct rk3399_sdram_params *params, u32 ctl,
+ struct rk3399_sdram_params *params, u32 ctl_fn,
bool en, bool ctl_phy_reg, u32 mr5)
{
u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1805,14 +1916,13 @@ static void set_lpddr4_dq_odt(const struct chan_info *chan,
struct io_setting *io;
u32 reg_value;
- if (!en)
- return;
-
io = lpddr4_get_io_settings(params, mr5);
+ if (en)
+ reg_value = io->dq_odt;
+ else
+ reg_value = 0;
- reg_value = io->dq_odt;
-
- switch (ctl) {
+ switch (ctl_fn) {
case 0:
clrsetbits_le32(&denali_ctl[139], 0x7 << 24, reg_value << 24);
clrsetbits_le32(&denali_ctl[153], 0x7 << 24, reg_value << 24);
@@ -1845,7 +1955,7 @@ static void set_lpddr4_dq_odt(const struct chan_info *chan,
}
static void set_lpddr4_ca_odt(const struct chan_info *chan,
- struct rk3399_sdram_params *params, u32 ctl,
+ struct rk3399_sdram_params *params, u32 ctl_fn,
bool en, bool ctl_phy_reg, u32 mr5)
{
u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1853,14 +1963,13 @@ static void set_lpddr4_ca_odt(const struct chan_info *chan,
struct io_setting *io;
u32 reg_value;
- if (!en)
- return;
-
io = lpddr4_get_io_settings(params, mr5);
+ if (en)
+ reg_value = io->ca_odt;
+ else
+ reg_value = 0;
- reg_value = io->ca_odt;
-
- switch (ctl) {
+ switch (ctl_fn) {
case 0:
clrsetbits_le32(&denali_ctl[139], 0x7 << 28, reg_value << 28);
clrsetbits_le32(&denali_ctl[153], 0x7 << 28, reg_value << 28);
@@ -1893,7 +2002,7 @@ static void set_lpddr4_ca_odt(const struct chan_info *chan,
}
static void set_lpddr4_MR3(const struct chan_info *chan,
- struct rk3399_sdram_params *params, u32 ctl,
+ struct rk3399_sdram_params *params, u32 ctl_fn,
bool ctl_phy_reg, u32 mr5)
{
u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1905,7 +2014,7 @@ static void set_lpddr4_MR3(const struct chan_info *chan,
reg_value = ((io->pdds << 3) | 1);
- switch (ctl) {
+ switch (ctl_fn) {
case 0:
clrsetbits_le32(&denali_ctl[138], 0xFFFF, reg_value);
clrsetbits_le32(&denali_ctl[152], 0xFFFF, reg_value);
@@ -1940,7 +2049,7 @@ static void set_lpddr4_MR3(const struct chan_info *chan,
}
static void set_lpddr4_MR12(const struct chan_info *chan,
- struct rk3399_sdram_params *params, u32 ctl,
+ struct rk3399_sdram_params *params, u32 ctl_fn,
bool ctl_phy_reg, u32 mr5)
{
u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -1952,7 +2061,7 @@ static void set_lpddr4_MR12(const struct chan_info *chan,
reg_value = io->ca_vref;
- switch (ctl) {
+ switch (ctl_fn) {
case 0:
clrsetbits_le32(&denali_ctl[140], 0xFFFF << 16,
reg_value << 16);
@@ -1989,7 +2098,7 @@ static void set_lpddr4_MR12(const struct chan_info *chan,
}
static void set_lpddr4_MR14(const struct chan_info *chan,
- struct rk3399_sdram_params *params, u32 ctl,
+ struct rk3399_sdram_params *params, u32 ctl_fn,
bool ctl_phy_reg, u32 mr5)
{
u32 *denali_ctl = get_denali_ctl(chan, params, ctl_phy_reg);
@@ -2001,7 +2110,7 @@ static void set_lpddr4_MR14(const struct chan_info *chan,
reg_value = io->dq_vref;
- switch (ctl) {
+ switch (ctl_fn) {
case 0:
clrsetbits_le32(&denali_ctl[142], 0xFFFF << 16,
reg_value << 16);
@@ -2037,22 +2146,73 @@ static void set_lpddr4_MR14(const struct chan_info *chan,
}
}
+void lpddr4_modify_param(const struct chan_info *chan,
+ struct rk3399_sdram_params *params)
+{
+ struct rk3399_sdram_params *params_cfg;
+ u32 *denali_ctl_params;
+ u32 *denali_pi_params;
+ u32 *denali_phy_params;
+
+ denali_ctl_params = params->pctl_regs.denali_ctl;
+ denali_pi_params = params->pi_regs.denali_pi;
+ denali_phy_params = params->phy_regs.denali_phy;
+
+ set_lpddr4_dq_odt(chan, params, 2, true, false, 0);
+ set_lpddr4_ca_odt(chan, params, 2, true, false, 0);
+ set_lpddr4_MR3(chan, params, 2, false, 0);
+ set_lpddr4_MR12(chan, params, 2, false, 0);
+ set_lpddr4_MR14(chan, params, 2, false, 0);
+ params_cfg = lpddr4_get_phy_index_params(0, params);
+ set_ds_odt(chan, params_cfg, false, 0);
+ /* read two cycle preamble */
+ clrsetbits_le32(&denali_ctl_params[200], 0x3 << 24, 0x3 << 24);
+ clrsetbits_le32(&denali_phy_params[7], 0x3 << 24, 0x3 << 24);
+ clrsetbits_le32(&denali_phy_params[135], 0x3 << 24, 0x3 << 24);
+ clrsetbits_le32(&denali_phy_params[263], 0x3 << 24, 0x3 << 24);
+ clrsetbits_le32(&denali_phy_params[391], 0x3 << 24, 0x3 << 24);
+
+ /* boot frequency two cycle preamble */
+ clrsetbits_le32(&denali_phy_params[2], 0x3 << 16, 0x3 << 16);
+ clrsetbits_le32(&denali_phy_params[130], 0x3 << 16, 0x3 << 16);
+ clrsetbits_le32(&denali_phy_params[258], 0x3 << 16, 0x3 << 16);
+ clrsetbits_le32(&denali_phy_params[386], 0x3 << 16, 0x3 << 16);
+
+ clrsetbits_le32(&denali_pi_params[45], 0x3 << 8, 0x3 << 8);
+ clrsetbits_le32(&denali_pi_params[58], 0x1, 0x1);
+
+ /*
+ * bypass mode need PHY_SLICE_PWR_RDC_DISABLE_x = 1,
+ * boot frequency mode use bypass mode
+ */
+ setbits_le32(&denali_phy_params[10], 1 << 16);
+ setbits_le32(&denali_phy_params[138], 1 << 16);
+ setbits_le32(&denali_phy_params[266], 1 << 16);
+ setbits_le32(&denali_phy_params[394], 1 << 16);
+
+ clrsetbits_le32(&denali_pi_params[45], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[61], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+ clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+}
+
static void lpddr4_copy_phy(struct dram_info *dram,
- struct rk3399_sdram_params *params, u32 phy,
- struct rk3399_sdram_params *timings,
+ struct rk3399_sdram_params *params, u32 phy_fn,
+ struct rk3399_sdram_params *params_cfg,
u32 channel)
{
u32 *denali_ctl, *denali_phy;
u32 *denali_phy_params;
u32 speed = 0;
- u32 ctl, mr5;
+ u32 ctl_fn, mr5;
denali_ctl = dram->chan[channel].pctl->denali_ctl;
denali_phy = dram->chan[channel].publ->denali_phy;
- denali_phy_params = timings->phy_regs.denali_phy;
+ denali_phy_params = params_cfg->phy_regs.denali_phy;
/* switch index */
- clrsetbits_le32(&denali_phy_params[896], 0x3 << 8, phy << 8);
+ clrsetbits_le32(&denali_phy_params[896], 0x3 << 8,
+ phy_fn << 8);
writel(denali_phy_params[896], &denali_phy[896]);
/* phy_pll_ctrl_ca, phy_pll_ctrl */
@@ -2112,14 +2272,14 @@ static void lpddr4_copy_phy(struct dram_info *dram,
* phy_clk_wrdqz_slave_delay_x
* phy_clk_wrdqs_slave_delay_x
*/
- copy_to_reg((u32 *)&denali_phy[59], (u32 *)&denali_phy_params[59],
- (63 - 58) * 4);
- copy_to_reg((u32 *)&denali_phy[187], (u32 *)&denali_phy_params[187],
- (191 - 186) * 4);
- copy_to_reg((u32 *)&denali_phy[315], (u32 *)&denali_phy_params[315],
- (319 - 314) * 4);
- copy_to_reg((u32 *)&denali_phy[443], (u32 *)&denali_phy_params[443],
- (447 - 442) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[59],
+ (u32 *)&denali_phy_params[59], (63 - 58) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[187],
+ (u32 *)&denali_phy_params[187], (191 - 186) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[315],
+ (u32 *)&denali_phy_params[315], (319 - 314) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[443],
+ (u32 *)&denali_phy_params[443], (447 - 442) * 4);
/*
* phy_dqs_tsel_wr_timing_x 8bits denali_phy_84/212/340/468 offset_8
@@ -2218,31 +2378,30 @@ static void lpddr4_copy_phy(struct dram_info *dram,
* phy_wrlvl_delay_period_threshold_x
* phy_wrlvl_early_force_zero_x
*/
- copy_to_reg((u32 *)&denali_phy[64], (u32 *)&denali_phy_params[64],
- (67 - 63) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[64],
+ (u32 *)&denali_phy_params[64], (67 - 63) * 4);
clrsetbits_le32(&denali_phy[68], 0xfffffc00,
denali_phy_params[68] & 0xfffffc00);
- copy_to_reg((u32 *)&denali_phy[69], (u32 *)&denali_phy_params[69],
- (79 - 68) * 4);
- copy_to_reg((u32 *)&denali_phy[192], (u32 *)&denali_phy_params[192],
- (195 - 191) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[69],
+ (u32 *)&denali_phy_params[69], (79 - 68) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[192],
+ (u32 *)&denali_phy_params[192], (195 - 191) * 4);
clrsetbits_le32(&denali_phy[196], 0xfffffc00,
denali_phy_params[196] & 0xfffffc00);
- copy_to_reg((u32 *)&denali_phy[197], (u32 *)&denali_phy_params[197],
- (207 - 196) * 4);
- copy_to_reg((u32 *)&denali_phy[320], (u32 *)&denali_phy_params[320],
- (323 - 319) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[197],
+ (u32 *)&denali_phy_params[197], (207 - 196) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[320],
+ (u32 *)&denali_phy_params[320], (323 - 319) * 4);
clrsetbits_le32(&denali_phy[324], 0xfffffc00,
denali_phy_params[324] & 0xfffffc00);
- copy_to_reg((u32 *)&denali_phy[325], (u32 *)&denali_phy_params[325],
- (335 - 324) * 4);
-
- copy_to_reg((u32 *)&denali_phy[448], (u32 *)&denali_phy_params[448],
- (451 - 447) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[325],
+ (u32 *)&denali_phy_params[325], (335 - 324) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[448],
+ (u32 *)&denali_phy_params[448], (451 - 447) * 4);
clrsetbits_le32(&denali_phy[452], 0xfffffc00,
denali_phy_params[452] & 0xfffffc00);
- copy_to_reg((u32 *)&denali_phy[453], (u32 *)&denali_phy_params[453],
- (463 - 452) * 4);
+ sdram_copy_to_reg((u32 *)&denali_phy[453],
+ (u32 *)&denali_phy_params[453], (463 - 452) * 4);
/* phy_two_cyc_preamble_x */
clrsetbits_le32(&denali_phy[7], 0x3 << 24,
@@ -2255,11 +2414,11 @@ static void lpddr4_copy_phy(struct dram_info *dram,
denali_phy_params[391] & (0x3 << 24));
/* speed */
- if (timings->base.ddr_freq < 400 * MHz)
+ if (params_cfg->base.ddr_freq < 400)
speed = 0x0;
- else if (timings->base.ddr_freq < 800 * MHz)
+ else if (params_cfg->base.ddr_freq < 800)
speed = 0x1;
- else if (timings->base.ddr_freq < 1200 * MHz)
+ else if (params_cfg->base.ddr_freq < 1200)
speed = 0x2;
/* phy_924 phy_pad_fdbk_drive */
@@ -2279,52 +2438,75 @@ static void lpddr4_copy_phy(struct dram_info *dram,
/* phy_939 phy_pad_cs_drive */
clrsetbits_le32(&denali_phy[939], 0x3 << 17, speed << 17);
- read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
- set_ds_odt(&dram->chan[channel], timings, true, mr5);
+ if (params_cfg->base.dramtype == LPDDR4) {
+ read_mr(dram->chan[channel].pctl, 1, 5, &mr5);
+ set_ds_odt(&dram->chan[channel], params_cfg, true, mr5);
+ set_ds_odt(&dram->chan[channel], params_cfg, true, mr5);
+
+ ctl_fn = lpddr4_get_ctl_fn(params_cfg, phy_fn);
+ set_lpddr4_dq_odt(&dram->chan[channel], params_cfg,
+ ctl_fn, true, true, mr5);
+ set_lpddr4_ca_odt(&dram->chan[channel], params_cfg,
+ ctl_fn, true, true, mr5);
+ set_lpddr4_MR3(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
+ set_lpddr4_MR12(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
+ set_lpddr4_MR14(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
+
+ set_lpddr4_dq_odt(&dram->chan[channel], params_cfg,
+ ctl_fn, true, true, mr5);
+ set_lpddr4_ca_odt(&dram->chan[channel], params_cfg,
+ ctl_fn, true, true, mr5);
+ set_lpddr4_MR3(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
+ set_lpddr4_MR12(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
+ set_lpddr4_MR14(&dram->chan[channel], params_cfg,
+ ctl_fn, true, mr5);
- ctl = lpddr4_get_ctl(timings, phy);
- set_lpddr4_dq_odt(&dram->chan[channel], timings, ctl, true, true, mr5);
- set_lpddr4_ca_odt(&dram->chan[channel], timings, ctl, true, true, mr5);
- set_lpddr4_MR3(&dram->chan[channel], timings, ctl, true, mr5);
- set_lpddr4_MR12(&dram->chan[channel], timings, ctl, true, mr5);
- set_lpddr4_MR14(&dram->chan[channel], timings, ctl, true, mr5);
-
- /*
- * if phy_sw_master_mode_x not bypass mode,
- * clear phy_slice_pwr_rdc_disable.
- * note: need use timings, not ddr_publ_regs
- */
- if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
- clrbits_le32(&denali_phy[10], 1 << 16);
- clrbits_le32(&denali_phy[138], 1 << 16);
- clrbits_le32(&denali_phy[266], 1 << 16);
- clrbits_le32(&denali_phy[394], 1 << 16);
- }
+ /*
+ * if phy_sw_master_mode_x not bypass mode,
+ * clear phy_slice_pwr_rdc_disable.
+ * note: need use timings, not ddr_publ_regs
+ */
+ if (!((denali_phy_params[86] >> 8) & (1 << 2))) {
+ clrbits_le32(&denali_phy[10], 1 << 16);
+ clrbits_le32(&denali_phy[138], 1 << 16);
+ clrbits_le32(&denali_phy[266], 1 << 16);
+ clrbits_le32(&denali_phy[394], 1 << 16);
+ }
- /*
- * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
- * smaller than 8
- * NOTE: need use timings, not ddr_publ_regs
- */
- if ((denali_phy_params[84] >> 16) & 1) {
- if (((readl(&denali_ctl[217 + ctl]) >> 16) & 0x1f) < 8)
- clrsetbits_le32(&denali_ctl[217 + ctl],
- 0x1f << 16, 8 << 16);
+ /*
+ * when PHY_PER_CS_TRAINING_EN=1, W2W_DIFFCS_DLY_Fx can't
+ * smaller than 8
+ * NOTE: need use timings, not ddr_publ_regs
+ */
+ if ((denali_phy_params[84] >> 16) & 1) {
+ if (((readl(&denali_ctl[217 + ctl_fn]) >>
+ 16) & 0x1f) < 8)
+ clrsetbits_le32(&denali_ctl[217 + ctl_fn],
+ 0x1f << 16,
+ 8 << 16);
+ }
}
}
static void lpddr4_set_phy(struct dram_info *dram,
- struct rk3399_sdram_params *params, u32 phy,
- struct rk3399_sdram_params *timings)
+ struct rk3399_sdram_params *params, u32 phy_fn,
+ struct rk3399_sdram_params *params_cfg)
{
u32 channel;
for (channel = 0; channel < 2; channel++)
- lpddr4_copy_phy(dram, params, phy, timings, channel);
+ lpddr4_copy_phy(dram, params, phy_fn, params_cfg,
+ channel);
}
static int lpddr4_set_ctl(struct dram_info *dram,
- struct rk3399_sdram_params *params, u32 ctl, u32 hz)
+ struct rk3399_sdram_params *params,
+ u32 fn, u32 hz)
{
u32 channel;
int ret_clk, ret;
@@ -2343,7 +2525,7 @@ static int lpddr4_set_ctl(struct dram_info *dram,
/* change freq */
writel((((0x3 << 4) | (1 << 2) | 1) << 16) |
- (ctl << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
+ (fn << 4) | (1 << 2) | 1, &dram->cic->cic_ctrl0);
while (!(readl(&dram->cic->cic_status0) & (1 << 2)))
;
@@ -2366,12 +2548,12 @@ static int lpddr4_set_ctl(struct dram_info *dram,
clrbits_le32(&dram->pmu->pmu_noc_auto_ena, (0x3 << 7));
/* lpddr4 ctl2 can not do training, all training will fail */
- if (!(params->base.dramtype == LPDDR4 && ctl == 2)) {
+ if (!(params->base.dramtype == LPDDR4 && fn == 2)) {
for (channel = 0; channel < 2; channel++) {
if (!(params->ch[channel].cap_info.col))
continue;
ret = data_training(dram, channel, params,
- PI_FULL_TRAINING);
+ PI_FULL_TRAINING);
if (ret)
printf("%s: channel %d training failed!\n",
__func__, channel);
@@ -2387,24 +2569,221 @@ static int lpddr4_set_ctl(struct dram_info *dram,
static int lpddr4_set_rate(struct dram_info *dram,
struct rk3399_sdram_params *params)
{
- u32 ctl;
- u32 phy;
+ u32 ctl_fn;
+ u32 phy_fn;
- for (ctl = 0; ctl < 2; ctl++) {
- phy = lpddr4_get_phy(params, ctl);
+ for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
+ phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
- lpddr4_set_phy(dram, params, phy, &lpddr4_timings[ctl]);
- lpddr4_set_ctl(dram, params, ctl,
- lpddr4_timings[ctl].base.ddr_freq);
+ lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+ lpddr4_set_ctl(dram, params, ctl_fn,
+ dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
- debug("%s: change freq to %d mhz %d, %d\n", __func__,
- lpddr4_timings[ctl].base.ddr_freq / MHz, ctl, phy);
+ printf("%s: change freq to %d mhz %d, %d\n", __func__,
+ dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, ctl_fn, phy_fn);
}
return 0;
}
#endif /* CONFIG_RAM_RK3399_LPDDR4 */
+/* CS0,n=1
+ * CS1,n=2
+ * CS0 & CS1, n=3
+ * cs0_cap: MB unit
+ */
+static void dram_set_cs(const struct chan_info *chan, u32 cs_map, u32 cs0_cap,
+ unsigned char dramtype)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_pi = chan->pi->denali_pi;
+ struct msch_regs *ddr_msch_regs = chan->msch;
+
+ clrsetbits_le32(&denali_ctl[196], 0x3, cs_map);
+ writel((cs0_cap / 32) | (((4096 - cs0_cap) / 32) << 8),
+ &ddr_msch_regs->ddrsize);
+ if (dramtype == LPDDR4) {
+ if (cs_map == 1)
+ cs_map = 0x5;
+ else if (cs_map == 2)
+ cs_map = 0xa;
+ else
+ cs_map = 0xF;
+ }
+ /*PI_41 PI_CS_MAP:RW:24:4*/
+ clrsetbits_le32(&denali_pi[41],
+ 0xf << 24, cs_map << 24);
+ if (cs_map == 1 && dramtype == DDR3)
+ writel(0x2EC7FFFF, &denali_pi[34]);
+}
+
+static void dram_set_bw(const struct chan_info *chan, u32 bw)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+
+ if (bw == 2)
+ clrbits_le32(&denali_ctl[196], 1 << 16);
+ else
+ setbits_le32(&denali_ctl[196], 1 << 16);
+}
+
+static void dram_set_max_col(const struct chan_info *chan, u32 bw, u32 *pcol)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ struct msch_regs *ddr_msch_regs = chan->msch;
+ u32 *denali_pi = chan->pi->denali_pi;
+ u32 ddrconfig;
+
+ clrbits_le32(&denali_ctl[191], 0xf);
+ clrsetbits_le32(&denali_ctl[190],
+ (7 << 24),
+ ((16 - ((bw == 2) ? 14 : 15)) << 24));
+ /*PI_199 PI_COL_DIFF:RW:0:4*/
+ clrbits_le32(&denali_pi[199], 0xf);
+ /*PI_155 PI_ROW_DIFF:RW:24:3*/
+ clrsetbits_le32(&denali_pi[155],
+ (7 << 24),
+ ((16 - 12) << 24));
+ ddrconfig = (bw == 2) ? 3 : 2;
+ writel(ddrconfig | (ddrconfig << 8), &ddr_msch_regs->ddrconf);
+ /* set max cs0 size */
+ writel((4096 / 32) | ((0 / 32) << 8),
+ &ddr_msch_regs->ddrsize);
+
+ *pcol = 12;
+}
+
+static void dram_set_max_bank(const struct chan_info *chan, u32 bw, u32 *pbank,
+ u32 *pcol)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_pi = chan->pi->denali_pi;
+
+ clrbits_le32(&denali_ctl[191], 0xf);
+ clrbits_le32(&denali_ctl[190], (3 << 16));
+ /*PI_199 PI_COL_DIFF:RW:0:4*/
+ clrbits_le32(&denali_pi[199], 0xf);
+ /*PI_155 PI_BANK_DIFF:RW:16:2*/
+ clrbits_le32(&denali_pi[155], (3 << 16));
+
+ *pbank = 3;
+ *pcol = 12;
+}
+
+static void dram_set_max_row(const struct chan_info *chan, u32 bw, u32 *prow,
+ u32 *pbank, u32 *pcol)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 *denali_pi = chan->pi->denali_pi;
+ struct msch_regs *ddr_msch_regs = chan->msch;
+
+ clrsetbits_le32(&denali_ctl[191], 0xf, 12 - 10);
+ clrbits_le32(&denali_ctl[190],
+ (0x3 << 16) | (0x7 << 24));
+ /*PI_199 PI_COL_DIFF:RW:0:4*/
+ clrsetbits_le32(&denali_pi[199], 0xf, 12 - 10);
+ /*PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2*/
+ clrbits_le32(&denali_pi[155],
+ (0x3 << 16) | (0x7 << 24));
+ writel(1 | (1 << 8), &ddr_msch_regs->ddrconf);
+ /* set max cs0 size */
+ writel((4096 / 32) | ((0 / 32) << 8),
+ &ddr_msch_regs->ddrsize);
+
+ *prow = 16;
+ *pbank = 3;
+ *pcol = (bw == 2) ? 10 : 11;
+}
+
+static u64 dram_detect_cap(struct dram_info *dram,
+ struct rk3399_sdram_params *params,
+ unsigned char channel)
+{
+ const struct chan_info *chan = &dram->chan[channel];
+ struct sdram_cap_info *cap_info = ¶ms->ch[channel].cap_info;
+ u32 bw;
+ u32 col_tmp;
+ u32 bk_tmp;
+ u32 row_tmp;
+ u32 cs0_cap;
+ u32 training_flag;
+ u32 ddrconfig;
+
+ /* detect bw */
+ bw = 2;
+ if (params->base.dramtype != LPDDR4) {
+ dram_set_bw(chan, bw);
+ cap_info->bw = bw;
+ if (data_training(dram, channel, params,
+ PI_READ_GATE_TRAINING)) {
+ bw = 1;
+ dram_set_bw(chan, 1);
+ cap_info->bw = bw;
+ if (data_training(dram, channel, params,
+ PI_READ_GATE_TRAINING)) {
+ printf("16bit error!!!\n");
+ goto error;
+ }
+ }
+ }
+ /*
+ * LPDDR3 CA training msut be trigger before other training.
+ * DDR3 is not have CA training.
+ */
+ if (params->base.dramtype == LPDDR3)
+ training_flag = PI_WRITE_LEVELING;
+ else
+ training_flag = PI_FULL_TRAINING;
+
+ if (params->base.dramtype != LPDDR4) {
+ if (data_training(dram, channel, params, training_flag)) {
+ printf("full training error!!!\n");
+ goto error;
+ }
+ }
+
+ /* detect col */
+ dram_set_max_col(chan, bw, &col_tmp);
+ if (sdram_detect_col(cap_info, col_tmp) != 0)
+ goto error;
+
+ /* detect bank */
+ dram_set_max_bank(chan, bw, &bk_tmp, &col_tmp);
+ sdram_detect_bank(cap_info, col_tmp, bk_tmp);
+
+ /* detect row */
+ dram_set_max_row(chan, bw, &row_tmp, &bk_tmp, &col_tmp);
+ if (sdram_detect_row(cap_info, col_tmp, bk_tmp, row_tmp) != 0)
+ goto error;
+
+ /* detect row_3_4 */
+ sdram_detect_row_3_4(cap_info, col_tmp, bk_tmp);
+
+ /* set ddrconfig */
+ cs0_cap = (1 << (cap_info->cs0_row + cap_info->col + cap_info->bk +
+ cap_info->bw - 20));
+ if (cap_info->row_3_4)
+ cs0_cap = cs0_cap * 3 / 4;
+
+ cap_info->cs1_row = cap_info->cs0_row;
+ set_memory_map(chan, channel, params);
+ ddrconfig = calculate_ddrconfig(params, channel);
+ if (-1 == ddrconfig)
+ goto error;
+ set_ddrconfig(chan, params, channel,
+ cap_info->ddrconfig);
+
+ /* detect cs1 row */
+ sdram_detect_cs1_row(cap_info, params->base.dramtype);
+
+ /* detect die bw */
+ sdram_detect_dbw(cap_info, params->base.dramtype);
+
+ return 0;
+error:
+ return (-1);
+}
+
static unsigned char calculate_stride(struct rk3399_sdram_params *params)
{
unsigned int stride = params->base.stride;
@@ -2489,39 +2868,13 @@ static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
params->ch[channel].cap_info.ddrconfig = 0;
}
-static int pctl_init(struct dram_info *dram, struct rk3399_sdram_params *params)
-{
- int channel;
- int ret;
-
- for (channel = 0; channel < 2; channel++) {
- const struct chan_info *chan = &dram->chan[channel];
- struct rk3399_cru *cru = dram->cru;
- struct rk3399_ddr_publ_regs *publ = chan->publ;
-
- phy_pctrl_reset(cru, channel);
- phy_dll_bypass_set(publ, params->base.ddr_freq);
-
- ret = pctl_cfg(dram, chan, channel, params);
- if (ret < 0) {
- printf("%s: pctl config failed\n", __func__);
- return ret;
- }
-
- /* start to trigger initialization */
- pctl_start(dram, channel);
- }
-
- return 0;
-}
-
static int sdram_init(struct dram_info *dram,
struct rk3399_sdram_params *params)
{
unsigned char dramtype = params->base.dramtype;
unsigned int ddr_freq = params->base.ddr_freq;
int channel, ch, rank;
- int ret;
+ u32 tmp, ret;
debug("Starting SDRAM initialization...\n");
@@ -2532,22 +2885,35 @@ static int sdram_init(struct dram_info *dram,
return -E2BIG;
}
+ /* detect rank */
for (ch = 0; ch < 2; ch++) {
params->ch[ch].cap_info.rank = 2;
for (rank = 2; rank != 0; rank--) {
- ret = pctl_init(dram, params);
- if (ret < 0) {
- printf("%s: pctl init failed\n", __func__);
- return ret;
+ for (channel = 0; channel < 2; channel++) {
+ const struct chan_info *chan =
+ &dram->chan[channel];
+ struct rk3399_cru *cru = dram->cru;
+ struct rk3399_ddr_publ_regs *publ = chan->publ;
+
+ phy_pctrl_reset(cru, channel);
+ phy_dll_bypass_set(publ, ddr_freq);
+ pctl_cfg(dram, chan, channel, params);
}
+ /* start to trigger initialization */
+ pctl_start(dram, params, 3);
+
/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
if (dramtype == LPDDR3)
udelay(10);
+ tmp = (rank == 2) ? 3 : 1;
+ dram_set_cs(&dram->chan[ch], tmp, 2048,
+ params->base.dramtype);
params->ch[ch].cap_info.rank = rank;
- ret = dram->ops->data_training(dram, ch, rank, params);
+ ret = dram->ops->data_training_first(dram, ch,
+ rank, params);
if (!ret) {
debug("%s: data trained for rank %d, ch %d\n",
__func__, rank, ch);
@@ -2561,50 +2927,52 @@ static int sdram_init(struct dram_info *dram,
params->base.num_channels = 0;
for (channel = 0; channel < 2; channel++) {
const struct chan_info *chan = &dram->chan[channel];
- struct sdram_cap_info *cap_info = ¶ms->ch[channel].cap_info;
- u8 training_flag = PI_FULL_TRAINING;
+ struct sdram_cap_info *cap_info =
+ ¶ms->ch[channel].cap_info;
if (cap_info->rank == 0) {
- clear_channel_params(params, channel);
+ clear_channel_params(params, 1);
continue;
} else {
params->base.num_channels++;
}
- debug("Channel ");
- debug(channel ? "1: " : "0: ");
+ printf("Channel ");
+ printf(channel ? "1: " : "0: ");
- /* LPDDR3 should have write and read gate training */
- if (params->base.dramtype == LPDDR3)
- training_flag = PI_WRITE_LEVELING |
- PI_READ_GATE_TRAINING;
+ if (channel == 0)
+ set_ddr_stride(dram->pmusgrf, 0x17);
+ else
+ set_ddr_stride(dram->pmusgrf, 0x18);
- if (params->base.dramtype != LPDDR4) {
- ret = data_training(dram, channel, params,
- training_flag);
- if (!ret) {
- debug("%s: data train failed for channel %d\n",
- __func__, ret);
- continue;
- }
+ if (dram_detect_cap(dram, params, channel)) {
+ printf("Cap error!\n");
+ continue;
}
+ sdram_print_ddr_info(cap_info, ¶ms->base, 0);
set_memory_map(chan, channel, params);
- cap_info->ddrconfig = calculate_ddrconfig(params, channel);
-
+ cap_info->ddrconfig =
+ calculate_ddrconfig(params, channel);
+ if (-1 == cap_info->ddrconfig) {
+ printf("no ddrconfig find, Cap not support!\n");
+ continue;
+ }
set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
set_cap_relate_config(chan, params, channel);
}
if (params->base.num_channels == 0) {
printf("%s: ", __func__);
+ sdram_print_dram_type(params->base.dramtype);
printf(" - %dMHz failed!\n", params->base.ddr_freq);
return -EINVAL;
}
params->base.stride = calculate_stride(params);
dram_all_config(dram, params);
- dram->ops->set_rate(dram, params);
+
+ dram->ops->set_rate_index(dram, params);
debug("Finish SDRAM initialization...\n");
return 0;
@@ -2651,11 +3019,15 @@ static int conv_of_platdata(struct udevice *dev)
static const struct sdram_rk3399_ops rk3399_ops = {
#if !defined(CONFIG_RAM_RK3399_LPDDR4)
- .data_training = default_data_training,
- .set_rate = switch_to_phy_index1,
+ .data_training_first = data_training_first,
+ .set_rate_index = switch_to_phy_index1,
+ .modify_param = modify_param,
+ .get_phy_index_params = get_phy_index_params,
#else
- .data_training = lpddr4_mr_detect,
- .set_rate = lpddr4_set_rate,
+ .data_training_first = lpddr4_mr_detect,
+ .set_rate_index = lpddr4_set_rate,
+ .modify_param = lpddr4_modify_param,
+ .get_phy_index_params = lpddr4_get_phy_index_params,
#endif
};
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 6/9] ram: rockchip: update lpddr4 timing for rk3399
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (4 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 5/9] ram: rk3399: use common sdram driver Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 7/9] ram: rk3399: Sync the io setting from Rockchip vendor code Kever Yang
` (3 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
Update lpddr timing in lpddr4-400 and lpddr4-800 file from rockchip
vendor code;
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc | 12 ++++++------
drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc | 6 +++---
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
index 6ddc01c49d..209ef57228 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc
@@ -22,16 +22,16 @@
},
{
.ddrtiminga0 = {
- 0x80241d22,
+ 0x8010100d,
},
.ddrtimingb0 = {
- 0x15050f08,
+ 0x08020b04,
},
.ddrtimingc0 = {
0x00000602,
},
.devtodev0 = {
- 0x00002122,
+ 0x00002562,
},
.ddrmode = {
0x0000004c,
@@ -55,16 +55,16 @@
},
{
.ddrtiminga0 = {
- 0x80241d22,
+ 0x8010100d,
},
.ddrtimingb0 = {
- 0x15050f08,
+ 0x08020b04,
},
.ddrtimingc0 = {
0x00000602,
},
.devtodev0 = {
- 0x00002122,
+ 0x00002562,
},
.ddrmode = {
0x0000004c,
diff --git a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
index 307f6ee458..7d11b4c563 100644
--- a/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
+++ b/drivers/ram/rockchip/sdram-rk3399-lpddr4-800.inc
@@ -22,16 +22,16 @@
},
{
.ddrtiminga0 = {
- 0x80241d22,
+ 0x801c1819,
},
.ddrtimingb0 = {
- 0x15050f08,
+ 0x10040c05,
},
.ddrtimingc0 = {
0x00000602,
},
.devtodev0 = {
- 0x00002122,
+ 0x00002672,
},
.ddrmode = {
0x0000004c,
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 7/9] ram: rk3399: Sync the io setting from Rockchip vendor code
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (5 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 6/9] ram: rockchip: update lpddr4 timing for rk3399 Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 8/9] ram: rk3399: update calculate_stride Kever Yang
` (2 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
The io setting are updated after some bugfix in different rk3399 boards,
sync the code from vendor.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
drivers/ram/rockchip/sdram_rk3399.c | 44 +++++++++--------------------
1 file changed, 14 insertions(+), 30 deletions(-)
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 223ebadaec..9669f7e146 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -149,38 +149,21 @@ struct io_setting {
32, /* rd_vref; (unit %, range 3.3% - 48.7%) */
},
{
- 800 * MHz,
+ 933 * MHz,
0,
/* dram side */
1, /* dq_odt; */
0, /* ca_odt; */
- 1, /* pdds; */
+ 3, /* pdds; */
0x72, /* dq_vref; */
0x72, /* ca_vref; */
/* phy side */
- PHY_DRV_ODT_40, /* rd_odt; */
- PHY_DRV_ODT_48, /* wr_dq_drv; */
+ PHY_DRV_ODT_80, /* rd_odt; */
+ PHY_DRV_ODT_40, /* wr_dq_drv; */
PHY_DRV_ODT_40, /* wr_ca_drv; */
PHY_DRV_ODT_40, /* wr_ckcs_drv; */
1, /* rd_odt_en; */
- 17, /* rd_vref; (unit %, range 3.3% - 48.7%) */
- },
- {
- 933 * MHz,
- 0,
- /* dram side */
- 3, /* dq_odt; */
- 0, /* ca_odt; */
- 6, /* pdds; */
- 0x59, /* dq_vref; 32% */
- 0x72, /* ca_vref; */
- /* phy side */
- PHY_DRV_ODT_HI_Z, /* rd_odt; */
- PHY_DRV_ODT_48, /* wr_dq_drv; */
- PHY_DRV_ODT_40, /* wr_ca_drv; */
- PHY_DRV_ODT_40, /* wr_ckcs_drv; */
- 0, /* rd_odt_en; */
- 32, /* rd_vref; (unit %, range 3.3% - 48.7%) */
+ 20, /* rd_vref; (unit %, range 3.3% - 48.7%) */
},
{
1066 * MHz,
@@ -188,16 +171,16 @@ struct io_setting {
/* dram side */
6, /* dq_odt; */
0, /* ca_odt; */
- 1, /* pdds; */
+ 3, /* pdds; */
0x10, /* dq_vref; */
0x72, /* ca_vref; */
/* phy side */
- PHY_DRV_ODT_40, /* rd_odt; */
+ PHY_DRV_ODT_80, /* rd_odt; */
PHY_DRV_ODT_60, /* wr_dq_drv; */
PHY_DRV_ODT_40, /* wr_ca_drv; */
PHY_DRV_ODT_40, /* wr_ckcs_drv; */
1, /* rd_odt_en; */
- 17, /* rd_vref; (unit %, range 3.3% - 48.7%) */
+ 20, /* rd_vref; (unit %, range 3.3% - 48.7%) */
},
};
@@ -599,16 +582,17 @@ static void set_ds_odt(const struct chan_info *chan,
tsel_rd_select_n = io->rd_odt;
tsel_idle_select_p = PHY_DRV_ODT_HI_Z;
- tsel_idle_select_n = PHY_DRV_ODT_240;
+ tsel_idle_select_n = PHY_DRV_ODT_HI_Z;
tsel_wr_select_dq_p = io->wr_dq_drv;
- tsel_wr_select_dq_n = PHY_DRV_ODT_40;
+ tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
tsel_wr_select_ca_p = io->wr_ca_drv;
- tsel_wr_select_ca_n = PHY_DRV_ODT_40;
+ tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
tsel_ckcs_select_p = io->wr_ckcs_drv;
tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
+
switch (tsel_rd_select_n) {
case PHY_DRV_ODT_240:
soc_odt = 1;
@@ -648,8 +632,8 @@ static void set_ds_odt(const struct chan_info *chan,
tsel_wr_select_dq_p = PHY_DRV_ODT_34_3;
tsel_wr_select_dq_n = PHY_DRV_ODT_34_3;
- tsel_wr_select_ca_p = PHY_DRV_ODT_48;
- tsel_wr_select_ca_n = PHY_DRV_ODT_48;
+ tsel_wr_select_ca_p = PHY_DRV_ODT_34_3;
+ tsel_wr_select_ca_n = PHY_DRV_ODT_34_3;
tsel_ckcs_select_p = PHY_DRV_ODT_34_3;
tsel_ckcs_select_n = PHY_DRV_ODT_34_3;
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 8/9] ram: rk3399: update calculate_stride
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (6 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 7/9] ram: rk3399: Sync the io setting from Rockchip vendor code Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 8:04 ` [U-Boot] [PATCH 9/9] ram: rk3399: Sync code from rockchip vendor code Kever Yang
2019-10-22 18:38 ` [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Jagan Teki
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
Update the calculation of the stride to support all the DRAM case.
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
drivers/ram/rockchip/sdram_rk3399.c | 158 +++++++++++++++++++++-------
1 file changed, 119 insertions(+), 39 deletions(-)
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 9669f7e146..c7c92c4416 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -2770,15 +2770,20 @@ error:
static unsigned char calculate_stride(struct rk3399_sdram_params *params)
{
- unsigned int stride = params->base.stride;
- unsigned int channel, chinfo = 0;
+ unsigned int gstride_type;
+ unsigned int channel;
+ unsigned int chinfo = 0;
+ unsigned int cap = 0;
+ unsigned int stride = -1;
unsigned int ch_cap[2] = {0, 0};
- u64 cap;
+
+ gstride_type = STRIDE_256B;
for (channel = 0; channel < 2; channel++) {
unsigned int cs0_cap = 0;
unsigned int cs1_cap = 0;
- struct sdram_cap_info *cap_info = ¶ms->ch[channel].cap_info;
+ struct sdram_cap_info *cap_info =
+ ¶ms->ch[channel].cap_info;
if (cap_info->col == 0)
continue;
@@ -2796,47 +2801,122 @@ static unsigned char calculate_stride(struct rk3399_sdram_params *params)
chinfo |= 1 << channel;
}
- /* stride calculation for 1 channel */
- if (params->base.num_channels == 1 && chinfo & 1)
- return 0x17; /* channel a */
-
- /* stride calculation for 2 channels, default gstride type is 256B */
- if (ch_cap[0] == ch_cap[1]) {
- cap = ch_cap[0] + ch_cap[1];
- switch (cap) {
- /* 512MB */
- case 512:
- stride = 0;
- break;
- /* 1GB */
- case 1024:
- stride = 0x5;
- break;
+ cap = ch_cap[0] + ch_cap[1];
+ if (params->base.num_channels == 1) {
+ if (chinfo & 1) /* channel a only */
+ stride = 0x17;
+ else /* channel b only */
+ stride = 0x18;
+ } else {/* 2 channel */
+ if (ch_cap[0] == ch_cap[1]) {
+ /* interleaved */
+ if (gstride_type == PART_STRIDE) {
+ /*
+ * first 64MB no interleaved other 256B interleaved
+ * if 786M+768M.useful space from 0-1280MB and
+ * 1536MB-1792MB
+ * if 1.5G+1.5G(continuous).useful space from 0-2560MB
+ * and 3072MB-3584MB
+ */
+ stride = 0x1F;
+ } else {
+ switch (cap) {
+ /* 512MB */
+ case 512:
+ stride = 0;
+ break;
+ /* 1GB unstride or 256B stride*/
+ case 1024:
+ stride = (gstride_type == UN_STRIDE) ?
+ 0x1 : 0x5;
+ break;
+ /*
+ * 768MB + 768MB same as total 2GB memory
+ * useful space: 0-768MB 1GB-1792MB
+ */
+ case 1536:
+ /* 2GB unstride or 256B or 512B stride */
+ case 2048:
+ stride = (gstride_type == UN_STRIDE) ?
+ 0x2 :
+ ((gstride_type == STRIDE_512B) ?
+ 0xA : 0x9);
+ break;
+ /* 1536MB + 1536MB */
+ case 3072:
+ stride = (gstride_type == UN_STRIDE) ?
+ 0x3 :
+ ((gstride_type == STRIDE_512B) ?
+ 0x12 : 0x11);
+ break;
+ /* 4GB unstride or 128B,256B,512B,4KB stride */
+ case 4096:
+ stride = (gstride_type == UN_STRIDE) ?
+ 0x3 : (0xC + gstride_type);
+ break;
+ }
+ }
+ }
+ if (ch_cap[0] == 2048 && ch_cap[1] == 1024) {
+ /* 2GB + 1GB */
+ stride = (gstride_type == UN_STRIDE) ? 0x3 : 0x19;
+ }
/*
- * 768MB + 768MB same as total 2GB memory
- * useful space: 0-768MB 1GB-1792MB
+ * remain two channel capability not equal OR capability
+ * power function of 2
*/
- case 1536:
- /* 2GB */
- case 2048:
- stride = 0x9;
- break;
- /* 1536MB + 1536MB */
- case 3072:
- stride = 0x11;
- break;
- /* 4GB */
- case 4096:
- stride = 0xD;
- break;
- default:
- printf("%s: Unable to calculate stride for ", __func__);
- print_size((cap * (1 << 20)), " capacity\n");
- break;
+ if (stride == (-1)) {
+ switch ((ch_cap[0] > ch_cap[1]) ?
+ ch_cap[0] : ch_cap[1]) {
+ case 256: /* 256MB + 128MB */
+ stride = 0;
+ break;
+ case 512: /* 512MB + 256MB */
+ stride = 1;
+ break;
+ case 1024:/* 1GB + 128MB/256MB/384MB/512MB/768MB */
+ stride = 2;
+ break;
+ case 2048: /* 2GB + 128MB/256MB/384MB/512MB/768MB/1GB */
+ stride = 3;
+ break;
+ default:
+ break;
+ }
}
+ if (stride == (-1))
+ goto error;
+ }
+ switch (stride) {
+ case 0xc:
+ printf("128B stride\n");
+ break;
+ case 5:
+ case 9:
+ case 0xd:
+ case 0x11:
+ case 0x19:
+ printf("256B stride\n");
+ break;
+ case 0xa:
+ case 0xe:
+ case 0x12:
+ printf("512B stride\n");
+ break;
+ case 0xf:
+ printf("4K stride\n");
+ break;
+ case 0x1f:
+ printf("32MB + 256B stride\n");
+ break;
+ default:
+ printf("no stride\n");
}
return stride;
+error:
+ printf("Cap not support!\n");
+ return (-1);
}
static void clear_channel_params(struct rk3399_sdram_params *params, u8 channel)
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 9/9] ram: rk3399: Sync code from rockchip vendor code
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (7 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 8/9] ram: rk3399: update calculate_stride Kever Yang
@ 2019-10-22 8:04 ` Kever Yang
2019-10-22 18:38 ` [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Jagan Teki
9 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2019-10-22 8:04 UTC (permalink / raw)
To: u-boot
From: YouMin Chen <cym@rock-chips.com>
There are some code different with rockchip vendor code which may lead
to different bugs, including:
1) Fix setting error about LPDDR3 dram size ODT.
2) Set phy io speed to 0x2.
3) Fix setting error about phy_pad_fdbk_drive.
4) Fix setting error about PI_WDQLVL_VREF_EN
Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---
drivers/ram/rockchip/sdram_rk3399.c | 41 ++++++++++++++---------------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index c7c92c4416..c34a3deca4 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -44,6 +44,11 @@
#define CS0_MR22_VAL 0
#define CS1_MR22_VAL 3
+/* LPDDR3 DRAM DS */
+#define LPDDR3_DS_34 0x1
+#define LPDDR3_DS_40 0x2
+#define LPDDR3_DS_48 0x3
+
#define CRU_SFTRST_DDR_CTRL(ch, n) ((0x1 << (8 + 16 + (ch) * 4)) | \
((n) << (8 + (ch) * 4)))
#define CRU_SFTRST_DDR_PHY(ch, n) ((0x1 << (9 + 16 + (ch) * 4)) | \
@@ -291,7 +296,8 @@ static void set_memory_map(const struct chan_info *chan, u32 channel,
if (sdram_ch->cap_info.ddrconfig < 2 ||
sdram_ch->cap_info.ddrconfig == 4)
row = 16;
- else if (sdram_ch->cap_info.ddrconfig == 3)
+ else if (sdram_ch->cap_info.ddrconfig == 3 ||
+ sdram_ch->cap_info.ddrconfig == 5)
row = 14;
else
row = 15;
@@ -335,11 +341,12 @@ static int phy_io_config(const struct chan_info *chan,
const struct rk3399_sdram_params *params, u32 mr5)
{
u32 *denali_phy = chan->publ->denali_phy;
+ u32 *denali_ctl = chan->pctl->denali_ctl;
u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac;
u32 mode_sel;
- u32 reg_value;
- u32 drv_value, odt_value;
u32 speed;
+ u32 reg_value;
+ u32 ds_value, odt_value;
/* vref setting & mode setting */
if (params->base.dramtype == LPDDR4) {
@@ -365,12 +372,12 @@ static int phy_io_config(const struct chan_info *chan,
} else if (params->base.dramtype == LPDDR3) {
if (params->base.odt == 1) {
vref_mode_dq = 0x5; /* LPDDR3 ODT */
- drv_value = (readl(&denali_phy[6]) >> 12) & 0xf;
+ ds_value = readl(&denali_ctl[138]) & 0xf;
odt_value = (readl(&denali_phy[6]) >> 4) & 0xf;
- if (drv_value == PHY_DRV_ODT_48) {
+ if (ds_value == LPDDR3_DS_48) {
switch (odt_value) {
case PHY_DRV_ODT_240:
- vref_value_dq = 0x16;
+ vref_value_dq = 0x1B;
break;
case PHY_DRV_ODT_120:
vref_value_dq = 0x26;
@@ -382,7 +389,7 @@ static int phy_io_config(const struct chan_info *chan,
debug("Invalid ODT value.\n");
return -EINVAL;
}
- } else if (drv_value == PHY_DRV_ODT_40) {
+ } else if (ds_value == LPDDR3_DS_40) {
switch (odt_value) {
case PHY_DRV_ODT_240:
vref_value_dq = 0x19;
@@ -397,7 +404,7 @@ static int phy_io_config(const struct chan_info *chan,
debug("Invalid ODT value.\n");
return -EINVAL;
}
- } else if (drv_value == PHY_DRV_ODT_34_3) {
+ } else if (ds_value == LPDDR3_DS_34) {
switch (odt_value) {
case PHY_DRV_ODT_240:
vref_value_dq = 0x17;
@@ -509,14 +516,7 @@ static int phy_io_config(const struct chan_info *chan,
}
/* speed setting */
- if (params->base.ddr_freq < 400)
- speed = 0x0;
- else if (params->base.ddr_freq < 800)
- speed = 0x1;
- else if (params->base.ddr_freq < 1200)
- speed = 0x2;
- else
- speed = 0x3;
+ speed = 0x2;
/* PHY_924 PHY_PAD_FDBK_DRIVE */
clrsetbits_le32(&denali_phy[924], 0x3 << 21, speed << 21);
@@ -739,9 +739,9 @@ static void set_ds_odt(const struct chan_info *chan,
/* phy_pad_fdbk_drive 23bit DENALI_PHY_924/925 */
clrsetbits_le32(&denali_phy[924], 0xff,
- tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
+ tsel_wr_select_ca_n | (tsel_wr_select_ca_p << 4));
clrsetbits_le32(&denali_phy[925], 0xff,
- tsel_rd_select_n | (tsel_rd_select_p << 4));
+ tsel_wr_select_dq_n | (tsel_wr_select_dq_p << 4));
/* phy_dq_tsel_enable_X 3bits DENALI_PHY_5/133/261/389 offset_16 */
reg_value = (tsel_rd_en | (tsel_wr_en << 1) | (tsel_idle_en << 2))
@@ -1340,10 +1340,9 @@ static int data_training_wdql(const struct chan_info *chan, u32 channel,
/*
* disable PI_WDQLVL_VREF_EN before wdq leveling?
- * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
+ * PI_117 PI_WDQLVL_VREF_EN:RW:8:1
*/
- clrbits_le32(&denali_pi[181], 0x1 << 8);
-
+ clrbits_le32(&denali_pi[117], 0x1 << 8);
/* PI_124 PI_WDQLVL_EN:RW:16:2 */
clrsetbits_le32(&denali_pi[124], 0x3 << 16, 0x2 << 16);
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver
2019-10-22 8:04 [U-Boot] [PATCH 0/9] rockchip: ram: add common code for sdram driver Kever Yang
` (8 preceding siblings ...)
2019-10-22 8:04 ` [U-Boot] [PATCH 9/9] ram: rk3399: Sync code from rockchip vendor code Kever Yang
@ 2019-10-22 18:38 ` Jagan Teki
9 siblings, 0 replies; 14+ messages in thread
From: Jagan Teki @ 2019-10-22 18:38 UTC (permalink / raw)
To: u-boot
Hi Kever,
Thanks for new updated changes.
On Tue, Oct 22, 2019 at 1:34 PM Kever Yang <kever.yang@rock-chips.com> wrote:
>
>
> The sdram drivers for Rockchip SoCs was all separate, some of the SoCs
> has similar hardware controller and phy, so we have a change to share
> the flow and some of the functions between different SoCs.
> This patch set implement a first version common code based on PX30,
> other SoCs has similar hardware can migrate to this common code, eg.
> rk3328 and rk3399 can use this common code.
>
> This patch set also fix some bug for rk3399 by sync code from latest
> rockchip vendor code.
>
>
>
> Kever Yang (3):
> ram: rockchip: update lpddr4 timing for rk3399
> ram: rk3399: Sync the io setting from Rockchip vendor code
> ram: rk3399: update calculate_stride
>
> YouMin Chen (6):
> ram: rockchip: rename sdram driver files
> ram: rockchip: add common sdram driver
> ram: px30: add sdram driver
> ram: rk3328: use common sdram driver
> ram: rk3399: use common sdram driver
> ram: rk3399: Sync code from rockchip vendor code
But, indeed it is difficult to review a few of the changes where one
of the patches removing existing code and replacing new code in common
sdram driver. Adding required changes one-after-another would help us
to track the proper changes in future and also more maintainable.
Jagan.
^ permalink raw reply [flat|nested] 14+ messages in thread