
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@lists.denx.de https://lists.denx.de/listinfo/u-boot
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot