diff --git a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi index f032eece23..d0d7c6439d 100644 --- a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi +++ b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi @@ -14,6 +14,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80120e12 0x11030802 @@ -29,6 +31,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 d54ea82d1e..cab72af48b 100644 --- a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi +++ b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi @@ -14,6 +14,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80151015 0x14040902 @@ -29,6 +31,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 80e946e35e..db407df2de 100644 --- a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi +++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi @@ -14,6 +14,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80181219 0x17050a03 @@ -29,6 +31,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80181219 0x17050a03 diff --git a/arch/arm/dts/rk3399-sdram-ddr3-4G-1600.dtsi b/arch/arm/dts/rk3399-sdram-ddr3-4G-1600.dtsi index 745e2a5f2e..45db141f08 100644 --- a/arch/arm/dts/rk3399-sdram-ddr3-4G-1600.dtsi +++ b/arch/arm/dts/rk3399-sdram-ddr3-4G-1600.dtsi @@ -14,6 +14,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80151015 0x14040902 @@ -29,6 +31,8 @@ 0x0 0xf 0xf + 0xf + 0xf 1 0x80151015 0x14040902 diff --git a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi index 65dfc3806c..ad2d943ced 100644 --- a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi +++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-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/include/asm/arch-rockchip/sdram_rk3399.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3399.h index 2cee2e5ee5..9f608d72ad 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 struct rk3399_ddr_pctl_regs { u32 denali_ctl[332]; @@ -19,30 +20,6 @@ struct rk3399_ddr_pi_regs { u32 denali_pi[200]; }; -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; - u32 ddrtimingc0; - u32 devtodev0; - u32 ddrmode; - u32 agingx0; -}; - struct rk3399_ddr_cic_regs { u32 cic_ctrl0; u32 cic_ctrl1; @@ -65,37 +42,13 @@ struct rk3399_ddr_cic_regs { #define MEM_RST_VALID 1 struct rk3399_sdram_channel { - 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 rk3399_msch_timings noc_timings; -}; - -struct rk3399_base_params { - unsigned int ddr_freq; - unsigned int dramtype; - unsigned int num_channels; - unsigned int stride; - unsigned int odt; + struct sdram_cap_info cap_info; + struct sdram_msch_timings noc_timings; }; struct rk3399_sdram_params { struct rk3399_sdram_channel ch[2]; - struct rk3399_base_params base; + struct sdram_base_params base; struct rk3399_ddr_pctl_regs pctl_regs; struct rk3399_ddr_pi_regs pi_regs; struct rk3399_ddr_publ_regs phy_regs; @@ -108,4 +61,13 @@ struct rk3399_sdram_params { #define PI_WDQ_LEVELING (1 << 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/configs/android6.0-rk3399_defconfig b/configs/android6.0-rk3399_defconfig index f56103356f..b45169552f 100644 --- a/configs/android6.0-rk3399_defconfig +++ b/configs/android6.0-rk3399_defconfig @@ -67,6 +67,10 @@ CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_BASE=0xFF1A0000 diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index a28d8fdd2d..23ab932de6 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -67,6 +67,10 @@ CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_BASE=0xFF1A0000 diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig index 95b4d07a8f..da68739877 100644 --- a/configs/firefly-rk3399_defconfig +++ b/configs/firefly-rk3399_defconfig @@ -65,6 +65,10 @@ CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_BASE=0xFF1A0000 diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig index cb014631e5..52411bbdab 100644 --- a/configs/puma-rk3399_defconfig +++ b/configs/puma-rk3399_defconfig @@ -77,6 +77,10 @@ CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DEBUG_UART_BASE=0xFF180000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART_SHIFT=2 diff --git a/configs/rk3399_defconfig b/configs/rk3399_defconfig index 27830c60bd..3803831b90 100644 --- a/configs/rk3399_defconfig +++ b/configs/rk3399_defconfig @@ -80,6 +80,10 @@ CONFIG_CHARGE_ANIMATION=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_BASE=0xFF1A0000 diff --git a/configs/rk3399pro_defconfig b/configs/rk3399pro_defconfig index 862689987e..1e463ce644 100644 --- a/configs/rk3399pro_defconfig +++ b/configs/rk3399pro_defconfig @@ -82,6 +82,10 @@ CONFIG_CHARGE_ANIMATION=y CONFIG_PWM_ROCKCHIP=y CONFIG_RAM=y CONFIG_SPL_RAM=y +CONFIG_ROCKCHIP_SDRAM_COMMON=y +CONFIG_SDRAM_COMMON_CAP_DETECT=y +CONFIG_SDRAM_COMMON_OSREG=y +CONFIG_SDRAM_COMMON_MSCH_RK3399=y CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_BASE=0xFF1A0000 diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile index d0f74a4f9f..fa2b99d24c 100644 --- a/drivers/ram/rockchip/Makefile +++ b/drivers/ram/rockchip/Makefile @@ -12,7 +12,7 @@ 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_RK3399) = sdram_rk3399.o +obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o obj-$(CONFIG_ROCKCHIP_PX30) += rockchip_sdram.o obj-$(CONFIG_ROCKCHIP_RK1808) = rockchip_sdram.o diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index fa8da66f4e..ee6767bada 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -28,7 +28,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 { @@ -68,15 +68,30 @@ struct rockchip_dmc_plat { struct regmap *map; }; -static void copy_to_reg(u32 *dest, const u32 *src, u32 n) +#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)) | \ + ((n) << (9 + (ch) * 4))) +static void rkclk_ddr_reset(struct rk3399_cru *cru, u32 channel, u32 ctl, + u32 phy) { - int i; + channel &= 0x1; + ctl &= 0x1; + phy &= 0x1; + writel(CRU_SFTRST_DDR_CTRL(channel, ctl) | + CRU_SFTRST_DDR_PHY(channel, phy), + &cru->softrst_con[4]); +} - for (i = 0; i < n / sizeof(u32); i++) { - writel(*src, dest); - src++; - dest++; - } +static void phy_pctrl_reset(struct rk3399_cru *cru, + u32 channel) +{ + rkclk_ddr_reset(cru, channel, 1, 1); + udelay(10); + rkclk_ddr_reset(cru, channel, 1, 0); + udelay(10); + rkclk_ddr_reset(cru, channel, 0, 0); + udelay(10); } static void phy_dll_bypass_set(struct rk3399_ddr_publ_regs *ddr_publ_regs, @@ -122,35 +137,37 @@ static void set_memory_map(const struct chan_info *chan, u32 channel, u32 row; /* Get row number from ddrconfig setting */ - if (sdram_ch->ddrconfig < 2 || sdram_ch->ddrconfig == 4) + if (sdram_ch->cap_info.ddrconfig < 2 || + sdram_ch->cap_info.ddrconfig == 4) row = 16; - else if (sdram_ch->ddrconfig == 3) + else if (sdram_ch->cap_info.ddrconfig == 3) row = 14; else row = 15; - cs_map = (sdram_ch->rank > 1) ? 3 : 1; - reduc = (sdram_ch->bw == 2) ? 0 : 1; + cs_map = (sdram_ch->cap_info.rank > 1) ? 3 : 1; + reduc = (sdram_ch->cap_info.bw == 2) ? 0 : 1; /* Set the dram configuration to ctrl */ - clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->col)); + clrsetbits_le32(&denali_ctl[191], 0xF, (12 - sdram_ch->cap_info.col)); clrsetbits_le32(&denali_ctl[190], (0x3 << 16) | (0x7 << 24), - ((3 - sdram_ch->bk) << 16) | + ((3 - sdram_ch->cap_info.bk) << 16) | ((16 - row) << 24)); clrsetbits_le32(&denali_ctl[196], 0x3 | (1 << 16), cs_map | (reduc << 16)); /* PI_199 PI_COL_DIFF:RW:0:4 */ - clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->col)); + clrsetbits_le32(&denali_pi[199], 0xF, (12 - sdram_ch->cap_info.col)); /* PI_155 PI_ROW_DIFF:RW:24:3 PI_BANK_DIFF:RW:16:2 */ clrsetbits_le32(&denali_pi[155], (0x3 << 16) | (0x7 << 24), - ((3 - sdram_ch->bk) << 16) | + ((3 - sdram_ch->cap_info.bk) << 16) | ((16 - row) << 24)); /* PI_41 PI_CS_MAP:RW:24:4 */ clrsetbits_le32(&denali_pi[41], 0xf << 24, cs_map << 24); - if ((sdram_ch->rank == 1) && (sdram_params->base.dramtype == DDR3)) + if (sdram_ch->cap_info.rank == 1 && + sdram_params->base.dramtype == DDR3) writel(0x2EC7FFFF, &denali_pi[34]); } @@ -294,7 +311,7 @@ static void set_ds_odt(const struct chan_info *chan, } static int phy_io_config(const struct chan_info *chan, - const struct rk3399_sdram_params *sdram_params) + const struct rk3399_sdram_params *sdram_params) { u32 *denali_phy = chan->publ->denali_phy; u32 vref_mode_dq, vref_value_dq, vref_mode_ac, vref_value_ac; @@ -423,7 +440,6 @@ 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); - /* speed setting */ if (sdram_params->base.ddr_freq < 400) speed = 0x0; @@ -471,11 +487,11 @@ static int pctl_cfg(const struct chan_info *chan, u32 channel, * 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]); - copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0], - sizeof(struct rk3399_ddr_pi_regs)); + sdram_copy_to_reg(denali_pi, &sdram_params->pi_regs.denali_pi[0], + sizeof(struct rk3399_ddr_pi_regs)); /* rank count need to set for init */ set_memory_map(chan, channel, sdram_params); @@ -492,7 +508,7 @@ static int pctl_cfg(const struct chan_info *chan, u32 channel, setbits_le32(&denali_pi[0], START); setbits_le32(&denali_ctl[0], START); - /* Wating for phy DLL lock */ + /* Waiting for phy DLL lock */ while (1) { tmp = readl(&denali_phy[920]); tmp1 = readl(&denali_phy[921]); @@ -504,14 +520,20 @@ static int pctl_cfg(const struct chan_info *chan, u32 channel, break; } - 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); + 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); set_ds_odt(chan, sdram_params); /* @@ -547,12 +569,12 @@ static int pctl_cfg(const struct chan_info *chan, u32 channel, /* PHY_DLL_RST_EN */ clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); - /* Wating for PHY and DRAM init complete */ + /* Waiting for PHY and DRAM init complete */ tmp = get_timer(0); do { if (get_timer(tmp) > timeout_ms) { pr_err("DRAM (%s): phy failed to lock within %ld ms\n", - __func__, timeout_ms); + __func__, timeout_ms); return -ETIME; } } while (!(readl(&denali_ctl[203]) & (1 << 3))); @@ -569,7 +591,7 @@ static void select_per_cs_training_index(const struct chan_info *chan, u32 *denali_phy = chan->publ->denali_phy; /* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */ - if ((readl(&denali_phy[84])>>16) & 1) { + if ((readl(&denali_phy[84]) >> 16) & 1) { /* * PHY_8/136/264/392 * phy_per_cs_training_index_X 1bit offset_24 @@ -617,7 +639,7 @@ static int data_training_ca(const struct chan_info *chan, u32 channel, u32 *denali_phy = chan->publ->denali_phy; u32 i, tmp; u32 obs_0, obs_1, obs_2, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; + u32 rank = sdram_params->ch[channel].cap_info.rank; for (i = 0; i < rank; i++) { select_per_cs_training_index(chan, i); @@ -667,7 +689,7 @@ static int data_training_wl(const struct chan_info *chan, u32 channel, u32 *denali_phy = chan->publ->denali_phy; u32 i, tmp; u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; + u32 rank = sdram_params->ch[channel].cap_info.rank; for (i = 0; i < rank; i++) { select_per_cs_training_index(chan, i); @@ -723,7 +745,7 @@ static int data_training_rg(const struct chan_info *chan, u32 channel, u32 *denali_phy = chan->publ->denali_phy; u32 i, tmp; u32 obs_0, obs_1, obs_2, obs_3, obs_err = 0; - u32 rank = sdram_params->ch[channel].rank; + u32 rank = sdram_params->ch[channel].cap_info.rank; for (i = 0; i < rank; i++) { select_per_cs_training_index(chan, i); @@ -778,7 +800,7 @@ static int data_training_rl(const struct chan_info *chan, u32 channel, { u32 *denali_pi = chan->pi->denali_pi; u32 i, tmp; - u32 rank = sdram_params->ch[channel].rank; + u32 rank = sdram_params->ch[channel].cap_info.rank; for (i = 0; i < rank; i++) { select_per_cs_training_index(chan, i); @@ -819,7 +841,7 @@ static int data_training_wdql(const struct chan_info *chan, u32 channel, { u32 *denali_pi = chan->pi->denali_pi; u32 i, tmp; - u32 rank = sdram_params->ch[channel].rank; + u32 rank = sdram_params->ch[channel].cap_info.rank; for (i = 0; i < rank; i++) { select_per_cs_training_index(chan, i); @@ -859,6 +881,7 @@ static int data_training(const struct chan_info *chan, u32 channel, u32 training_flag) { u32 *denali_phy = chan->publ->denali_phy; + int ret = 0; /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */ setbits_le32(&denali_phy[927], (1 << 22)); @@ -879,29 +902,45 @@ static int data_training(const struct chan_info *chan, u32 channel, } /* ca training(LPDDR4,LPDDR3 support) */ - if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) - data_training_ca(chan, channel, sdram_params); + if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) { + ret = data_training_ca(chan, channel, sdram_params); + if (ret != 0) + goto out; + } /* write leveling(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) - data_training_wl(chan, channel, sdram_params); + if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) { + ret = data_training_wl(chan, channel, sdram_params); + if (ret != 0) + goto out; + } /* read gate training(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) - data_training_rg(chan, channel, sdram_params); + if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) { + ret = data_training_rg(chan, channel, sdram_params); + if (ret != 0) + goto out; + } /* read leveling(LPDDR4,LPDDR3,DDR3 support) */ - if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) - data_training_rl(chan, channel, sdram_params); + if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) { + ret = data_training_rl(chan, channel, sdram_params); + if (ret != 0) + goto out; + } /* wdq leveling(LPDDR4 support) */ - if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) - data_training_wdql(chan, channel, sdram_params); + if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) { + ret = data_training_wdql(chan, channel, sdram_params); + if (ret != 0) + goto out; + } /* PHY_927 PHY_PAD_DQS_DRIVE RPULL offset_22 */ clrbits_le32(&denali_phy[927], (1 << 22)); - return 0; +out: + return ret; } static void set_ddrconfig(const struct chan_info *chan, @@ -909,18 +948,18 @@ 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; - cs0_cap = (1 << (sdram_params->ch[channel].cs0_row - + sdram_params->ch[channel].col - + sdram_params->ch[channel].bk - + sdram_params->ch[channel].bw - 20)); - if (sdram_params->ch[channel].rank > 1) - cs1_cap = cs0_cap >> (sdram_params->ch[channel].cs0_row - - sdram_params->ch[channel].cs1_row); - if (sdram_params->ch[channel].row_3_4) { + cs0_cap = (1 << (sdram_params->ch[channel].cap_info.cs0_row + + sdram_params->ch[channel].cap_info.col + + sdram_params->ch[channel].cap_info.bk + + sdram_params->ch[channel].cap_info.bw - 20)); + if (sdram_params->ch[channel].cap_info.rank > 1) + cs1_cap = cs0_cap >> (sdram_params->ch[channel].cap_info.cs0_row + - sdram_params->ch[channel].cap_info.cs1_row); + if (sdram_params->ch[channel].cap_info.row_3_4) { cs0_cap = cs0_cap * 3 / 4; cs1_cap = cs1_cap * 3 / 4; } @@ -931,55 +970,36 @@ static void set_ddrconfig(const struct chan_info *chan, } static void dram_all_config(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) + struct rk3399_sdram_params *sdram_params) { - u32 sys_reg = 0; + u32 sys_reg2 = 0; + u32 sys_reg3 = 0; unsigned int channel, idx; - sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT; - sys_reg |= (sdram_params->base.num_channels - 1) - << SYS_REG_NUM_CH_SHIFT; for (channel = 0, idx = 0; (idx < sdram_params->base.num_channels) && (channel < 2); channel++) { - const struct rk3399_sdram_channel *info = - &sdram_params->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 (sdram_params->ch[channel].col == 0) + if (sdram_params->ch[channel].cap_info.col == 0) continue; idx++; - sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel); - sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(channel); - sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel); - sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(channel); - sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel); - sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel); - sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel); - sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel); - sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel); - + sdram_org_config(&sdram_params->ch[channel].cap_info, + &sdram_params->base, &sys_reg2, + &sys_reg3, channel); ddr_msch_regs = dram->chan[channel].msch; noc_timing = &sdram_params->ch[channel].noc_timings; - writel(noc_timing->ddrtiminga0, - &ddr_msch_regs->ddrtiminga0); - writel(noc_timing->ddrtimingb0, - &ddr_msch_regs->ddrtimingb0); - writel(noc_timing->ddrtimingc0, - &ddr_msch_regs->ddrtimingc0); - writel(noc_timing->devtodev0, - &ddr_msch_regs->devtodev0); - writel(noc_timing->ddrmode, - &ddr_msch_regs->ddrmode); + sdram_msch_config(ddr_msch_regs, noc_timing); /* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */ - if (sdram_params->ch[channel].rank == 1) + if (sdram_params->ch[channel].cap_info.rank == 1) setbits_le32(&dram->chan[channel].pctl->denali_ctl[276], 1 << 17); } - writel(sys_reg, &dram->pmugrf->os_reg2); + writel(sys_reg2, &dram->pmugrf->os_reg2); + writel(sys_reg3, &dram->pmugrf->os_reg3); rk_clrsetreg(&dram->pmusgrf->soc_con4, 0x1f << 10, sdram_params->base.stride << 10); @@ -991,7 +1011,7 @@ static void dram_all_config(struct dram_info *dram, } static int switch_to_phy_index1(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) + const struct rk3399_sdram_params *sdram_params) { u32 channel; u32 *denali_phy; @@ -1025,7 +1045,7 @@ static int switch_to_phy_index1(struct dram_info *dram, denali_phy = dram->chan[channel].publ->denali_phy; clrsetbits_le32(&denali_phy[896], (0x3 << 8) | 1, 1 << 8); ret = data_training(&dram->chan[channel], channel, - sdram_params, PI_FULL_TRAINING); + sdram_params, PI_FULL_TRAINING); if (ret) { debug("index1 training failed\n"); return ret; @@ -1035,12 +1055,458 @@ static int switch_to_phy_index1(struct dram_info *dram, return 0; } +u16 ddr_cfg_2_rbc[] = { + /* + * [6] highest bit col + * [5:3] max row(14+n) + * [2] insertion row + * [1:0] col(9+n),col, data bus 32bit + * + * highbitcol, max_row, insertion_row, col + */ + ((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */ + ((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */ + ((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */ + ((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */ + ((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */ + ((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */ + ((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */ + ((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */ +}; + +unsigned int calculate_ddrconfig(struct rk3399_sdram_params *sdram_params, + unsigned int channel) +{ + unsigned int i; + unsigned int cs0_row = sdram_params->ch[channel].cap_info.cs0_row; + unsigned int col = sdram_params->ch[channel].cap_info.col; + unsigned int bw = sdram_params->ch[channel].cap_info.bw; + + col -= (bw == 2) ? 0 : 1; + col -= 9; + + for (i = 0; i < 4; i++) { + if ((col == (ddr_cfg_2_rbc[i] & 0x3)) && + (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14))) + break; + } + + if (i >= 4) + i = -1; + + return i; +} + +unsigned char calculate_stride(struct rk3399_sdram_params *sdram_params) +{ + 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}; + + 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 = + &sdram_params->ch[channel].cap_info; + + if (cap_info->col == 0) + continue; + + cs0_cap = (1 << (cap_info->cs0_row + cap_info->col + + cap_info->bk + cap_info->bw - 20)); + if (cap_info->rank > 1) + cs1_cap = cs0_cap >> (cap_info->cs0_row + - cap_info->cs1_row); + if (cap_info->row_3_4) { + cs0_cap = cs0_cap * 3 / 4; + cs1_cap = cs1_cap * 3 / 4; + } + ch_cap[channel] = cs0_cap + cs1_cap; + chinfo |= 1 << channel; + } + + cap = ch_cap[0] + ch_cap[1]; + if (sdram_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; + } + /* + * remain two channel capability not equal OR capability + * power function of 2 + */ + 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 set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride) +{ + rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, + stride << 10); +} + +void set_cap_relate_config(const struct chan_info *chan, + struct rk3399_sdram_params *sdram_params, + unsigned int channel) +{ + u32 *denali_ctl = chan->pctl->denali_ctl; + u32 tmp; + struct sdram_msch_timings *noc_timing; + + if (sdram_params->base.dramtype == LPDDR3) { + tmp = (8 << sdram_params->ch[channel].cap_info.bw) / + (8 << sdram_params->ch[channel].cap_info.dbw); + /* memdata_ratio + * 1 -> 0, 2 -> 1, 4 -> 2 + */ + clrsetbits_le32(&denali_ctl[197], 0x7, + (tmp >> 1)); + clrsetbits_le32(&denali_ctl[198], 0x7 << 8, + (tmp >> 1) << 8); + } + noc_timing = &sdram_params->ch[channel].noc_timings; + /* + * noc timing bw relate timing is 32 bit, and real bw is 16bit + * actually noc reg is setting at function dram_all_config + */ + if (sdram_params->ch[channel].cap_info.bw == 16 && + noc_timing->ddrmode.b.mwrsize == 2) { + if (noc_timing->ddrmode.b.burstsize) + noc_timing->ddrmode.b.burstsize -= 1; + noc_timing->ddrmode.b.mwrsize -= 1; + noc_timing->ddrtimingc0.b.burstpenalty *= 2; + noc_timing->ddrtimingc0.b.wrtomwr *= 2; + } +} + +void clear_channel_params(struct rk3399_sdram_params *sdram_params, + unsigned int channel) +{ + sdram_params->ch[channel].cap_info.rank = 0; + sdram_params->ch[channel].cap_info.col = 0; + sdram_params->ch[channel].cap_info.bk = 0; + sdram_params->ch[channel].cap_info.bw = 32; + sdram_params->ch[channel].cap_info.dbw = 32; + sdram_params->ch[channel].cap_info.row_3_4 = 0; + sdram_params->ch[channel].cap_info.cs0_row = 0; + sdram_params->ch[channel].cap_info.cs1_row = 0; + sdram_params->ch[channel].cap_info.ddrconfig = 0; +} + +/* CS0,n=1 + * CS1,n=2 + * CS0 & CS1, n=3 + * cs0_cap: MB unit + */ +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]); +} + +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); +} + +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; +} + +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; +} + +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 *sdram_params, + unsigned char channel) +{ + const struct chan_info *chan = &dram->chan[channel]; + struct sdram_cap_info *cap_info = &sdram_params->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; + dram_set_bw(chan, bw); + cap_info->bw = bw; + if (data_training(chan, channel, sdram_params, PI_READ_GATE_TRAINING)) { + bw = 1; + dram_set_bw(chan, 1); + cap_info->bw = bw; + if (data_training(chan, channel, sdram_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 (sdram_params->base.dramtype == LPDDR3) + training_flag = PI_WRITE_LEVELING; + else + training_flag = PI_FULL_TRAINING; + + if (sdram_params->base.dramtype != LPDDR4) { + if (data_training(chan, channel, sdram_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, sdram_params); + ddrconfig = calculate_ddrconfig(sdram_params, channel); + if (-1 == ddrconfig) + goto error; + set_ddrconfig(chan, sdram_params, channel, + cap_info->ddrconfig); + + /* detect cs1 row */ + sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype); + + /* detect die bw */ + sdram_detect_dbw(cap_info, sdram_params->base.dramtype); + + return 0; +error: + return (-1); +} + static int sdram_init(struct dram_info *dram, - const struct rk3399_sdram_params *sdram_params) + struct rk3399_sdram_params *sdram_params) { unsigned char dramtype = sdram_params->base.dramtype; unsigned int ddr_freq = sdram_params->base.ddr_freq; int channel; + u32 rank; + int ch; + u32 tmp; + u32 training_flag; debug("Starting SDRAM initialization...\n"); @@ -1051,33 +1517,87 @@ static int sdram_init(struct dram_info *dram, return -E2BIG; } + /* detect rank */ + for (ch = 0; ch < 2; ch++) { + sdram_params->ch[ch].cap_info.rank = 2; + for (rank = 2; rank != 0; rank--) { + 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); + if (pctl_cfg(chan, channel, sdram_params) != 0) + printf("pctl_cfg fail\n"); + } + + /* 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, + sdram_params->base.dramtype); + sdram_params->ch[ch].cap_info.rank = rank; + /* + * LPDDR3 CA training msut be trigger before + * other training. + * DDR3 is not have CA training. + * LPDDR4 need confirm here! + */ + if (sdram_params->base.dramtype == LPDDR3) + training_flag = PI_CA_TRAINING | + PI_READ_GATE_TRAINING; + else + training_flag = PI_READ_GATE_TRAINING; + if (!(data_training(&dram->chan[ch], ch, sdram_params, + training_flag))) + break; + } + sdram_params->ch[ch].cap_info.rank = rank; + } + + sdram_params->base.num_channels = 0; for (channel = 0; channel < 2; channel++) { const struct chan_info *chan = &dram->chan[channel]; - struct rk3399_ddr_publ_regs *publ = chan->publ; + struct sdram_cap_info *cap_info = + &sdram_params->ch[channel].cap_info; - phy_dll_bypass_set(publ, ddr_freq); - - if (channel >= sdram_params->base.num_channels) + if (cap_info->rank == 0) { + clear_channel_params(sdram_params, 1); continue; - - if (pctl_cfg(chan, channel, sdram_params) != 0) { - printf("pctl_cfg fail, reset\n"); - return -EIO; + } else { + sdram_params->base.num_channels++; } - /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ - if (dramtype == LPDDR3) - udelay(10); + printf("Channel "); + printf(channel ? "1: " : "0: "); - if (data_training(chan, channel, - sdram_params, PI_FULL_TRAINING)) { - printf("SDRAM initialization failed, reset\n"); - return -EIO; + if (channel == 0) + set_ddr_stride(dram->pmusgrf, 0x17); + else + set_ddr_stride(dram->pmusgrf, 0x18); + + if (dram_detect_cap(dram, sdram_params, channel)) { + printf("Cap error!\n"); + continue; } - set_ddrconfig(chan, sdram_params, channel, - sdram_params->ch[channel].ddrconfig); + sdram_print_ddr_info(cap_info, &sdram_params->base, 0); + set_memory_map(chan, channel, sdram_params); + cap_info->ddrconfig = + calculate_ddrconfig(sdram_params, channel); + if (-1 == cap_info->ddrconfig) { + printf("no ddrconfig find, Cap not support!\n"); + continue; + } + set_ddrconfig(chan, sdram_params, channel, cap_info->ddrconfig); + set_cap_relate_config(chan, sdram_params, channel); } + + sdram_params->base.stride = calculate_stride(sdram_params); dram_all_config(dram, sdram_params); switch_to_phy_index1(dram, sdram_params); @@ -1115,8 +1635,8 @@ static int conv_of_platdata(struct udevice *dev) int ret; ret = regmap_init_mem_platdata(dev, dtplat->reg, - ARRAY_SIZE(dtplat->reg) / 2, - &plat->map); + ARRAY_SIZE(dtplat->reg) / 2, + &plat->map); if (ret) return ret; @@ -1225,7 +1745,6 @@ static struct ram_ops rk3399_dmc_ops = { .get_info = rk3399_dmc_get_info, }; - static const struct udevice_id rk3399_dmc_ids[] = { { .compatible = "rockchip,rk3399-dmc" }, { }