diff options
author | davidcunado-arm <david.cunado@arm.com> | 2017-02-27 15:25:45 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-27 15:25:45 +0000 |
commit | d6845d3dc3030335e9c13cf37f9ba1333a776629 (patch) | |
tree | b2401a8db7c76232e046fd8a3857af606b77841e /plat/rockchip/rk3399/drivers/dram | |
parent | 86a3b266006503725fdff58334ccec043566d680 (diff) | |
parent | ccdc044acfced5ae754d865b41e3064ff96f2d0c (diff) | |
download | trusted-firmware-a-d6845d3dc3030335e9c13cf37f9ba1333a776629.tar.gz |
Merge pull request #835 from rockchip-linux/rk3399-atf-cleanup-20170210
RK3399 ARM TF clean up 20170210
Diffstat (limited to 'plat/rockchip/rk3399/drivers/dram')
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dcf_code.inc | 364 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dfs.c | 960 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dfs.h | 52 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dram.c | 1 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dram.h | 105 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c | 151 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/dram/suspend.c | 31 |
7 files changed, 494 insertions, 1170 deletions
diff --git a/plat/rockchip/rk3399/drivers/dram/dcf_code.inc b/plat/rockchip/rk3399/drivers/dram/dcf_code.inc deleted file mode 100644 index 53196a028c..0000000000 --- a/plat/rockchip/rk3399/drivers/dram/dcf_code.inc +++ /dev/null @@ -1,364 +0,0 @@ - 0x0 , - 0x4f8c120c , - 0x0 , - 0x4f8c1210 , - 0x100000 , - 0x1f310019 , - 0x0 , - 0xb0000001 , - 0x58 , - 0xd0000000 , - 0x1300 , - 0x1f760329 , - 0x0 , - 0xb0000001 , - 0x40 , - 0xd0000000 , - 0xc , - 0x1f760371 , - 0x0 , - 0xb0000001 , - 0x28 , - 0xd0000000 , - 0x400000 , - 0x1f900009 , - 0x0 , - 0xb0000001 , - 0x10 , - 0xd0000000 , - 0x1 , - 0x4f8c120c , - 0x100000 , - 0x1f310019 , - 0x0 , - 0xb0000001 , - 0x58 , - 0xd0000000 , - 0x2c00 , - 0x1f760329 , - 0x0 , - 0xb0000001 , - 0x40 , - 0xd0000000 , - 0xc0 , - 0x1f760371 , - 0x0 , - 0xb0000001 , - 0x28 , - 0xd0000000 , - 0x400000 , - 0x1f8f0009 , - 0x0 , - 0xb0000001 , - 0x10 , - 0xd0000000 , - 0x1 , - 0x4f8c1210 , - 0x0 , - 0x4f8c1220 , - 0x0 , - 0x4f8c121c , - 0x0 , - 0xaf8c120d , - 0x108 , - 0xd0000000 , - 0x2000 , - 0x1f900009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x0 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0xb0 , - 0xd0000000 , - 0x8000 , - 0x1f900009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x1 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x70 , - 0xd0000000 , - 0x4000 , - 0x1f900009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x1000 , - 0x1f900009 , - 0x0 , - 0xa0000001 , - 0x18 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x100 , - 0xd0000000 , - 0x0 , - 0xaf8c1211 , - 0xf0 , - 0xd0000000 , - 0x2000 , - 0x1f8f0009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x0 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0xb0 , - 0xd0000000 , - 0x8000 , - 0x1f8f0009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x1 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x70 , - 0xd0000000 , - 0x4000 , - 0x1f8f0009 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x30 , - 0xd0000000 , - 0x1000 , - 0x1f8f0009 , - 0x0 , - 0xa0000001 , - 0x18 , - 0xd0000000 , - 0x0 , - 0x4f8c1220 , - 0x1 , - 0x4f8c121c , - 0x0 , - 0xaf8c120d , - 0x40 , - 0xd0000000 , - 0x80008000 , - 0x7f900284 , - 0x1 , - 0x0 , - 0x8000 , - 0x1f90028d , - 0x0 , - 0x60000001 , - 0x0 , - 0x10000001 , - 0x0 , - 0xa0000001 , - 0x38 , - 0xd0000000 , - 0x0 , - 0xaf8c1211 , - 0x28 , - 0xd0000000 , - 0x80008000 , - 0x7f8f0284 , - 0x1 , - 0x0 , - 0x8000 , - 0x1f8f028d , - 0x0 , - 0x60000001 , - 0xffffffff , - 0x4f77e200 , - 0xffffffff , - 0x4f77e204 , - 0xffffffff , - 0x4f77e208 , - 0xffffffff , - 0x4f77e20c , - 0x70007000 , - 0x4f77e210 , - 0x3fffffff , - 0x7f750130 , - 0x0 , - 0x2f310061 , - 0xc0000 , - 0x20000001 , - 0x0 , - 0x4f310061 , - 0xc0000 , - 0x1f310065 , - 0xc0000 , - 0xb0000001 , - 0x10 , - 0xc0000000 , - 0x0 , - 0xaf8c121d , - 0x48 , - 0xd0000000 , - 0x0 , - 0xaf8c120d , - 0x18 , - 0xd0000000 , - 0x80000000 , - 0x2f90000d , - 0x0 , - 0x4f90000d , - 0x0 , - 0xaf8c1211 , - 0x18 , - 0xd0000000 , - 0x80000000 , - 0x2f90000d , - 0x0 , - 0x4f8f000d , - 0x0 , - 0x2f8c101d , - 0x350005 , - 0x20000001 , - 0x0 , - 0x4f620001 , - 0x1 , - 0x0 , - 0x4 , - 0x1f620011 , - 0x0 , - 0x60000001 , - 0x3000000 , - 0x7f76004c , - 0x18 , - 0x0 , - 0x10001 , - 0x7f76004c , - 0x0 , - 0x2f8c1005 , - 0x0 , - 0x4f760041 , - 0x0 , - 0x2f8c1009 , - 0x0 , - 0x4f760045 , - 0x10000 , - 0x7f76004c , - 0x18 , - 0x0 , - 0x1 , - 0x0 , - 0x80000000 , - 0x1f760049 , - 0x0 , - 0x60000001 , - 0x3000100 , - 0x7f76004c , - 0x3e8 , - 0x0 , - 0x20002 , - 0x4f620000 , - 0x1 , - 0x0 , - 0x1 , - 0x1f620011 , - 0x0 , - 0x60000001 , - 0x0 , - 0xaf8c121d , - 0x48 , - 0xd0000000 , - 0x0 , - 0xaf8c120d , - 0x18 , - 0xd0000000 , - 0x7fffffff , - 0x1f90000d , - 0x0 , - 0x4f90000d , - 0x0 , - 0xaf8c1211 , - 0x18 , - 0xd0000000 , - 0x7fffffff , - 0x1f90000d , - 0x0 , - 0x4f8f000d , - 0xfff3ffff , - 0x1f310061 , - 0x0 , - 0x7f310061 , - 0xc0000 , - 0x1f310065 , - 0x0 , - 0xb0000001 , - 0x10 , - 0xc0000000 , - 0x0 , - 0x7f750130 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x1 , - 0x0 , - 0x0 , - 0xe0000000 , diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c index 4fdd3894d3..f589a8ad54 100644 --- a/plat/rockchip/rk3399/drivers/dram/dfs.c +++ b/plat/rockchip/rk3399/drivers/dram/dfs.c @@ -28,8 +28,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <arch_helpers.h> #include <debug.h> #include <mmio.h> +#include <m0_ctl.h> #include <plat_private.h> #include "dfs.h" #include "dram.h" @@ -40,31 +42,14 @@ #include <delay_timer.h> -#define CTL_TRAINING (1) -#define PI_TRAINING (!CTL_TRAINING) - -#define EN_READ_GATE_TRAINING (1) -#define EN_CA_TRAINING (0) -#define EN_WRITE_LEVELING (0) -#define EN_READ_LEVELING (0) -#define EN_WDQ_LEVELING (0) - -#define ENPER_CS_TRAINING_FREQ (933) - -struct pll_div { - unsigned int mhz; - unsigned int refdiv; - unsigned int fbdiv; - unsigned int postdiv1; - unsigned int postdiv2; - unsigned int frac; - unsigned int freq; -}; +#define ENPER_CS_TRAINING_FREQ (666) +#define TDFI_LAT_THRESHOLD_FREQ (928) +#define PHY_DLL_BYPASS_FREQ (260) static const struct pll_div dpll_rates_table[] = { /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */ - {.mhz = 933, .refdiv = 3, .fbdiv = 350, .postdiv1 = 3, .postdiv2 = 1}, + {.mhz = 928, .refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1}, {.mhz = 800, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1}, {.mhz = 732, .refdiv = 1, .fbdiv = 61, .postdiv1 = 2, .postdiv2 = 1}, {.mhz = 666, .refdiv = 1, .fbdiv = 111, .postdiv1 = 4, .postdiv2 = 1}, @@ -78,128 +63,44 @@ static const struct pll_div dpll_rates_table[] = { struct rk3399_dram_status { uint32_t current_index; uint32_t index_freq[2]; + uint32_t boot_freq; uint32_t low_power_stat; struct timing_related_config timing_config; struct drv_odt_lp_config drv_odt_lp_cfg; }; -static struct rk3399_dram_status rk3399_dram_status; -static struct ddr_dts_config_timing dts_parameter = { - .available = 0 +struct rk3399_saved_status { + uint32_t freq; + uint32_t low_power_stat; + uint32_t odt; }; +static struct rk3399_dram_status rk3399_dram_status; +static struct rk3399_saved_status rk3399_suspend_status; +static uint32_t wrdqs_delay_val[2][2][4]; + static struct rk3399_sdram_default_config ddr3_default_config = { .bl = 8, .ap = 0, - .dramds = 40, - .dramodt = 120, .burst_ref_cnt = 1, .zqcsi = 0 }; -static struct drv_odt_lp_config ddr3_drv_odt_default_config = { - .ddr3_speed_bin = DDR3_DEFAULT, - .pd_idle = 0, - .sr_idle = 0, - .sr_mc_gate_idle = 0, - .srpd_lite_idle = 0, - .standby_idle = 0, - - .ddr3_dll_dis_freq = 300, - .phy_dll_dis_freq = 125, - .odt_dis_freq = 933, - - .dram_side_drv = 40, - .dram_side_dq_odt = 120, - .dram_side_ca_odt = 120, - - .phy_side_ca_drv = 40, - .phy_side_ck_cs_drv = 40, - .phy_side_dq_drv = 40, - .phy_side_odt = 240, -}; - static struct rk3399_sdram_default_config lpddr3_default_config = { .bl = 8, .ap = 0, - .dramds = 34, - .dramodt = 240, .burst_ref_cnt = 1, .zqcsi = 0 }; -static struct drv_odt_lp_config lpddr3_drv_odt_default_config = { - .ddr3_speed_bin = DDR3_DEFAULT, - .pd_idle = 0, - .sr_idle = 0, - .sr_mc_gate_idle = 0, - .srpd_lite_idle = 0, - .standby_idle = 0, - - .ddr3_dll_dis_freq = 300, - .phy_dll_dis_freq = 125, - .odt_dis_freq = 666, - - .dram_side_drv = 40, - .dram_side_dq_odt = 120, - .dram_side_ca_odt = 120, - - .phy_side_ca_drv = 40, - .phy_side_ck_cs_drv = 40, - .phy_side_dq_drv = 40, - .phy_side_odt = 240, -}; - static struct rk3399_sdram_default_config lpddr4_default_config = { .bl = 16, .ap = 0, - .dramds = 40, - .dramodt = 240, .caodt = 240, .burst_ref_cnt = 1, .zqcsi = 0 }; -static struct drv_odt_lp_config lpddr4_drv_odt_default_config = { - .ddr3_speed_bin = DDR3_DEFAULT, - .pd_idle = 0, - .sr_idle = 0, - .sr_mc_gate_idle = 0, - .srpd_lite_idle = 0, - .standby_idle = 0, - - .ddr3_dll_dis_freq = 300, - .phy_dll_dis_freq = 125, - .odt_dis_freq = 933, - - .dram_side_drv = 60, - .dram_side_dq_odt = 40, - .dram_side_ca_odt = 40, - - .phy_side_ca_drv = 40, - .phy_side_ck_cs_drv = 80, - .phy_side_dq_drv = 80, - .phy_side_odt = 60, -}; - -uint32_t dcf_code[] = { -#include "dcf_code.inc" -}; - -#define DCF_START_ADDR (SRAM_BASE + 0x1400) -#define DCF_PARAM_ADDR (SRAM_BASE + 0x1000) - -/* DCF_PAMET */ -#define PARAM_DRAM_FREQ (0) -#define PARAM_DPLL_CON0 (4) -#define PARAM_DPLL_CON1 (8) -#define PARAM_DPLL_CON2 (0xc) -#define PARAM_DPLL_CON3 (0x10) -#define PARAM_DPLL_CON4 (0x14) -#define PARAM_DPLL_CON5 (0x18) -/* equal to fn<<4 */ -#define PARAM_FREQ_SELECT (0x1c) - static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config, uint8_t channel, uint8_t cs) { @@ -222,176 +123,79 @@ static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config, return (cs_cap / die); } -static void drv_odt_lp_cfg_init(uint32_t dram_type, - struct ddr_dts_config_timing *dts_timing, +static void get_dram_drv_odt_val(uint32_t dram_type, struct drv_odt_lp_config *drv_config) { - if ((dts_timing) && (dts_timing->available)) { - drv_config->ddr3_speed_bin = dts_timing->ddr3_speed_bin; - drv_config->pd_idle = dts_timing->pd_idle; - drv_config->sr_idle = dts_timing->sr_idle; - drv_config->sr_mc_gate_idle = dts_timing->sr_mc_gate_idle; - drv_config->srpd_lite_idle = dts_timing->srpd_lite_idle; - drv_config->standby_idle = dts_timing->standby_idle; - drv_config->ddr3_dll_dis_freq = dts_timing->ddr3_dll_dis_freq; - drv_config->phy_dll_dis_freq = dts_timing->phy_dll_dis_freq; - } + uint32_t tmp; + uint32_t mr1_val, mr3_val, mr11_val; switch (dram_type) { case DDR3: - if ((dts_timing) && (dts_timing->available)) { - drv_config->odt_dis_freq = - dts_timing->ddr3_odt_dis_freq; - drv_config->dram_side_drv = dts_timing->ddr3_drv; - drv_config->dram_side_dq_odt = dts_timing->ddr3_odt; - drv_config->phy_side_ca_drv = - dts_timing->phy_ddr3_ca_drv; - drv_config->phy_side_ck_cs_drv = - dts_timing->phy_ddr3_ca_drv; - drv_config->phy_side_dq_drv = - dts_timing->phy_ddr3_dq_drv; - drv_config->phy_side_odt = dts_timing->phy_ddr3_odt; - } else { - memcpy(drv_config, &ddr3_drv_odt_default_config, - sizeof(struct drv_odt_lp_config)); - } + mr1_val = (mmio_read_32(CTL_REG(0, 133)) >> 16) & 0xffff; + tmp = ((mr1_val >> 1) & 1) | ((mr1_val >> 4) & 1); + if (tmp) + drv_config->dram_side_drv = 34; + else + drv_config->dram_side_drv = 40; + tmp = ((mr1_val >> 2) & 1) | ((mr1_val >> 5) & 1) | + ((mr1_val >> 7) & 1); + if (tmp == 0) + drv_config->dram_side_dq_odt = 0; + else if (tmp == 1) + drv_config->dram_side_dq_odt = 60; + else if (tmp == 3) + drv_config->dram_side_dq_odt = 40; + else + drv_config->dram_side_dq_odt = 120; break; case LPDDR3: - if ((dts_timing) && (dts_timing->available)) { - drv_config->odt_dis_freq = - dts_timing->lpddr3_odt_dis_freq; - drv_config->dram_side_drv = dts_timing->lpddr3_drv; - drv_config->dram_side_dq_odt = dts_timing->lpddr3_odt; - drv_config->phy_side_ca_drv = - dts_timing->phy_lpddr3_ca_drv; - drv_config->phy_side_ck_cs_drv = - dts_timing->phy_lpddr3_ca_drv; - drv_config->phy_side_dq_drv = - dts_timing->phy_lpddr3_dq_drv; - drv_config->phy_side_odt = dts_timing->phy_lpddr3_odt; - - } else { - memcpy(drv_config, &lpddr3_drv_odt_default_config, - sizeof(struct drv_odt_lp_config)); - } + mr3_val = mmio_read_32(CTL_REG(0, 138)) & 0xf; + mr11_val = (mmio_read_32(CTL_REG(0, 139)) >> 24) & 0x3; + if (mr3_val == 0xb) + drv_config->dram_side_drv = 3448; + else if (mr3_val == 0xa) + drv_config->dram_side_drv = 4048; + else if (mr3_val == 0x9) + drv_config->dram_side_drv = 3440; + else if (mr3_val == 0x4) + drv_config->dram_side_drv = 60; + else if (mr3_val == 0x3) + drv_config->dram_side_drv = 48; + else if (mr3_val == 0x2) + drv_config->dram_side_drv = 40; + else + drv_config->dram_side_drv = 34; + + if (mr11_val == 1) + drv_config->dram_side_dq_odt = 60; + else if (mr11_val == 2) + drv_config->dram_side_dq_odt = 120; + else if (mr11_val == 0) + drv_config->dram_side_dq_odt = 0; + else + drv_config->dram_side_dq_odt = 240; break; case LPDDR4: default: - if ((dts_timing) && (dts_timing->available)) { - drv_config->odt_dis_freq = - dts_timing->lpddr4_odt_dis_freq; - drv_config->dram_side_drv = dts_timing->lpddr4_drv; - drv_config->dram_side_dq_odt = - dts_timing->lpddr4_dq_odt; - drv_config->dram_side_ca_odt = - dts_timing->lpddr4_ca_odt; - drv_config->phy_side_ca_drv = - dts_timing->phy_lpddr4_ca_drv; - drv_config->phy_side_ck_cs_drv = - dts_timing->phy_lpddr4_ck_cs_drv; - drv_config->phy_side_dq_drv = - dts_timing->phy_lpddr4_dq_drv; - drv_config->phy_side_odt = dts_timing->phy_lpddr4_odt; - } else { - memcpy(drv_config, &lpddr4_drv_odt_default_config, - sizeof(struct drv_odt_lp_config)); - } - break; - } - - switch (drv_config->phy_side_ca_drv) { - case 240: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_240; - break; - case 120: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_120; - break; - case 80: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_80; - break; - case 60: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_60; - break; - case 48: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_48; - break; - case 40: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_40; - break; - default: - drv_config->phy_side_ca_drv = PHY_DRV_ODT_34_3; - break; - }; + mr3_val = (mmio_read_32(CTL_REG(0, 138)) >> 3) & 0x7; + mr11_val = (mmio_read_32(CTL_REG(0, 139)) >> 24) & 0xff; - switch (drv_config->phy_side_ck_cs_drv) { - case 240: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_240; - break; - case 120: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_120; - break; - case 80: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_80; - break; - case 60: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_60; - break; - case 48: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_48; - break; - case 40: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_40; - break; - default: - drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_34_3; - break; - } + if ((mr3_val == 0) || (mr3_val == 7)) + drv_config->dram_side_drv = 40; + else + drv_config->dram_side_drv = 240 / mr3_val; - switch (drv_config->phy_side_dq_drv) { - case 240: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_240; - break; - case 120: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_120; - break; - case 80: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_80; - break; - case 60: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_60; - break; - case 48: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_48; - break; - case 40: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_40; - break; - default: - drv_config->phy_side_dq_drv = PHY_DRV_ODT_34_3; - break; - } + tmp = mr11_val & 0x7; + if ((tmp == 7) || (tmp == 0)) + drv_config->dram_side_dq_odt = 0; + else + drv_config->dram_side_dq_odt = 240 / tmp; - switch (drv_config->phy_side_odt) { - case 240: - drv_config->phy_side_odt = PHY_DRV_ODT_240; - break; - case 120: - drv_config->phy_side_odt = PHY_DRV_ODT_120; - break; - case 80: - drv_config->phy_side_odt = PHY_DRV_ODT_80; - break; - case 60: - drv_config->phy_side_odt = PHY_DRV_ODT_60; - break; - case 48: - drv_config->phy_side_odt = PHY_DRV_ODT_48; - break; - case 40: - drv_config->phy_side_odt = PHY_DRV_ODT_40; - break; - default: - drv_config->phy_side_odt = PHY_DRV_ODT_34_3; + tmp = (mr11_val >> 4) & 0x7; + if ((tmp == 7) || (tmp == 0)) + drv_config->dram_side_ca_odt = 0; + else + drv_config->dram_side_ca_odt = 240 / tmp; break; } } @@ -403,8 +207,7 @@ static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config, uint32_t i, j; for (i = 0; i < sdram_params->num_channels; i++) { - ptiming_config->dram_info[i].speed_rate = - drv_config->ddr3_speed_bin; + ptiming_config->dram_info[i].speed_rate = DDR3_DEFAULT; ptiming_config->dram_info[i].cs_cnt = sdram_params->ch[i].rank; for (j = 0; j < sdram_params->ch[i].rank; j++) { ptiming_config->dram_info[i].per_die_capability[j] = @@ -432,6 +235,7 @@ static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config, ptiming_config->dramds = drv_config->dram_side_drv; ptiming_config->dramodt = drv_config->dram_side_dq_odt; ptiming_config->caodt = drv_config->dram_side_ca_odt; + ptiming_config->odt = (mmio_read_32(PHY_REG(0, 5)) >> 16) & 0x1; } struct lat_adj_pair { @@ -928,7 +732,7 @@ static void gen_rk3399_ctl_params_f0(struct timing_related_config /* CTL_314 TDFI_WRCSLAT_F0:RW:8:8 */ tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); - if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) { + if (timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) { if (tmp1 == 0) tmp = 0; else if (tmp1 < 5) @@ -941,7 +745,7 @@ static void gen_rk3399_ctl_params_f0(struct timing_related_config mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 8, tmp << 8); /* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */ - if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) && + if ((timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) && (pdram_timing->cl >= 5)) tmp = pdram_timing->cl - 5; else @@ -1178,7 +982,7 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config /* CTL_314 TDFI_WRCSLAT_F1:RW:24:8 */ tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); - if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) { + if (timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) { if (tmp1 == 0) tmp = 0; else if (tmp1 < 5) @@ -1192,7 +996,7 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 24, tmp << 24); /* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */ - if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) && + if ((timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) && (pdram_timing->cl >= 5)) tmp = pdram_timing->cl - 5; else @@ -1201,6 +1005,33 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config } } +static void gen_rk3399_enable_training(uint32_t ch_cnt, uint32_t nmhz) +{ + uint32_t i, tmp; + + if (nmhz <= PHY_DLL_BYPASS_FREQ) + tmp = 0; + else + tmp = 1; + + for (i = 0; i < ch_cnt; i++) { + mmio_clrsetbits_32(CTL_REG(i, 305), 1 << 16, tmp << 16); + mmio_clrsetbits_32(CTL_REG(i, 71), 1, tmp); + mmio_clrsetbits_32(CTL_REG(i, 70), 1 << 8, 1 << 8); + } +} + +static void gen_rk3399_disable_training(uint32_t ch_cnt) +{ + uint32_t i; + + for (i = 0; i < ch_cnt; i++) { + mmio_clrbits_32(CTL_REG(i, 305), 1 << 16); + mmio_clrbits_32(CTL_REG(i, 71), 1); + mmio_clrbits_32(CTL_REG(i, 70), 1 << 8); + } +} + static void gen_rk3399_ctl_params(struct timing_related_config *timing_config, struct dram_timing_t *pdram_timing, uint32_t fn) @@ -1209,35 +1040,6 @@ static void gen_rk3399_ctl_params(struct timing_related_config *timing_config, gen_rk3399_ctl_params_f0(timing_config, pdram_timing); else gen_rk3399_ctl_params_f1(timing_config, pdram_timing); - -#if CTL_TRAINING - uint32_t i, tmp0, tmp1; - - tmp0 = tmp1 = 0; -#if EN_READ_GATE_TRAINING - tmp1 = 1; -#endif - -#if EN_CA_TRAINING - tmp0 |= (1 << 8); -#endif - -#if EN_WRITE_LEVELING - tmp0 |= (1 << 16); -#endif - -#if EN_READ_LEVELING - tmp0 |= (1 << 24); -#endif - for (i = 0; i < timing_config->ch_cnt; i++) { - if (tmp0 | tmp1) - mmio_setbits_32(CTL_REG(i, 305), 1 << 16); - if (tmp0) - mmio_setbits_32(CTL_REG(i, 70), tmp0); - if (tmp1) - mmio_setbits_32(CTL_REG(i, 71), tmp1); - } -#endif } static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config, @@ -1381,7 +1183,8 @@ static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config, mmio_clrsetbits_32(PI_REG(i, 148), 0xffff << 16, pdram_timing->mr[2] << 16); /* PI_156 PI_TFC_F0:RW:0:10 */ - mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff, pdram_timing->trfc); + mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff, + pdram_timing->tfc_long); /* PI_158 PI_TWR_F0:RW:24:6 */ mmio_clrsetbits_32(PI_REG(i, 158), 0x3f << 24, pdram_timing->twr << 24); @@ -1452,7 +1255,7 @@ static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config, mmio_clrsetbits_32(PI_REG(i, 44), 0x3f, PI_ADD_LATENCY); /* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */ mmio_clrsetbits_32(PI_REG(i, 44), 0x7f << 8, - pdram_timing->cl * 2); + (pdram_timing->cl * 2) << 8); /* PI_47 PI_TREF_F1:RW:16:16 */ mmio_clrsetbits_32(PI_REG(i, 47), 0xffff << 16, pdram_timing->trefi << 16); @@ -1561,7 +1364,7 @@ static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config, mmio_clrsetbits_32(PI_REG(i, 151), 0xffff, pdram_timing->mr[2]); /* PI_156 PI_TFC_F1:RW:16:10 */ mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff << 16, - pdram_timing->trfc << 16); + pdram_timing->tfc_long << 16); /* PI_162 PI_TWR_F1:RW:8:6 */ mmio_clrsetbits_32(PI_REG(i, 162), 0x3f << 8, pdram_timing->twr << 8); @@ -1605,32 +1408,6 @@ static void gen_rk3399_pi_params(struct timing_related_config *timing_config, gen_rk3399_pi_params_f0(timing_config, pdram_timing); else gen_rk3399_pi_params_f1(timing_config, pdram_timing); - -#if PI_TRAINING - uint32_t i; - - for (i = 0; i < timing_config->ch_cnt; i++) { -#if EN_READ_GATE_TRAINING - mmio_clrsetbits_32(PI_REG(i, 80), 3 << 24, 2 << 24); -#endif - -#if EN_CA_TRAINING - mmio_clrsetbits_32(PI_REG(i, 100), 3 << 8, 2 << 8); -#endif - -#if EN_WRITE_LEVELING - mmio_clrsetbits_32(PI_REG(i, 60), 3 << 8, 2 << 8); -#endif - -#if EN_READ_LEVELING - mmio_clrsetbits_32(PI_REG(i, 80), 3 << 16, 2 << 16); -#endif - -#if EN_WDQ_LEVELING - mmio_clrsetbits_32(PI_REG(i, 124), 3 << 16, 2 << 16); -#endif - } -#endif } static void gen_rk3399_set_odt(uint32_t odt_en) @@ -1652,57 +1429,92 @@ static void gen_rk3399_set_odt(uint32_t odt_en) } } -static void gen_rk3399_set_ds_odt(struct timing_related_config *timing_config, - struct drv_odt_lp_config *drv_config) +static void gen_rk3399_phy_dll_bypass(uint32_t mhz, uint32_t ch, + uint32_t index, uint32_t dram_type) { - uint32_t i, drv_odt_val; + uint32_t sw_master_mode = 0; + uint32_t rddqs_gate_delay, rddqs_latency, total_delay; + uint32_t i; - for (i = 0; i < timing_config->ch_cnt; i++) { - if (timing_config->dram_type == LPDDR4) - drv_odt_val = drv_config->phy_side_odt | - (PHY_DRV_ODT_Hi_Z << 4) | - (drv_config->phy_side_dq_drv << 8) | - (drv_config->phy_side_dq_drv << 12); - else if (timing_config->dram_type == LPDDR3) - drv_odt_val = PHY_DRV_ODT_Hi_Z | - (drv_config->phy_side_odt << 4) | - (drv_config->phy_side_dq_drv << 8) | - (drv_config->phy_side_dq_drv << 12); - else - drv_odt_val = drv_config->phy_side_odt | - (drv_config->phy_side_odt << 4) | - (drv_config->phy_side_dq_drv << 8) | - (drv_config->phy_side_dq_drv << 12); - - /* DQ drv odt set */ - mmio_clrsetbits_32(PHY_REG(i, 6), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 134), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 262), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 390), 0xffffff, drv_odt_val); - /* DQS drv odt set */ - mmio_clrsetbits_32(PHY_REG(i, 7), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 135), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 263), 0xffffff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 391), 0xffffff, drv_odt_val); - - gen_rk3399_set_odt(timing_config->odt); - - /* CA drv set */ - drv_odt_val = drv_config->phy_side_ca_drv | - (drv_config->phy_side_ca_drv << 4); - mmio_clrsetbits_32(PHY_REG(i, 544), 0xff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 672), 0xff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 800), 0xff, drv_odt_val); - - mmio_clrsetbits_32(PHY_REG(i, 928), 0xff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 937), 0xff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 935), 0xff, drv_odt_val); - - drv_odt_val = drv_config->phy_side_ck_cs_drv | - (drv_config->phy_side_ck_cs_drv << 4); - mmio_clrsetbits_32(PHY_REG(i, 929), 0xff, drv_odt_val); - mmio_clrsetbits_32(PHY_REG(i, 939), 0xff, drv_odt_val); + if (dram_type == DDR3) + total_delay = PI_PAD_DELAY_PS_VALUE; + else if (dram_type == LPDDR3) + total_delay = PI_PAD_DELAY_PS_VALUE + 2500; + else + total_delay = PI_PAD_DELAY_PS_VALUE + 1500; + /* total_delay + 0.55tck */ + total_delay += (55 * 10000)/mhz; + rddqs_latency = total_delay * mhz / 1000000; + total_delay -= rddqs_latency * 1000000 / mhz; + rddqs_gate_delay = total_delay * 0x200 * mhz / 1000000; + if (mhz <= PHY_DLL_BYPASS_FREQ) { + sw_master_mode = 0xc; + mmio_setbits_32(PHY_REG(ch, 514), 1); + mmio_setbits_32(PHY_REG(ch, 642), 1); + mmio_setbits_32(PHY_REG(ch, 770), 1); + + /* setting bypass mode slave delay */ + for (i = 0; i < 4; i++) { + /* wr dq delay = -180deg + (0x60 / 4) * 20ps */ + mmio_clrsetbits_32(PHY_REG(ch, 1 + 128 * i), 0x7ff << 8, + 0x4a0 << 8); + /* rd dqs/dq delay = (0x60 / 4) * 20ps */ + mmio_clrsetbits_32(PHY_REG(ch, 11 + 128 * i), 0x3ff, + 0xa0); + /* rd rddqs_gate delay */ + mmio_clrsetbits_32(PHY_REG(ch, 2 + 128 * i), 0x3ff, + rddqs_gate_delay); + mmio_clrsetbits_32(PHY_REG(ch, 78 + 128 * i), 0xf, + rddqs_latency); + } + for (i = 0; i < 3; i++) + /* adr delay */ + mmio_clrsetbits_32(PHY_REG(ch, 513 + 128 * i), + 0x7ff << 16, 0x80 << 16); + + if ((mmio_read_32(PHY_REG(ch, 86)) & 0xc00) == 0) { + /* + * old status is normal mode, + * and saving the wrdqs slave delay + */ + for (i = 0; i < 4; i++) { + /* save and clear wr dqs slave delay */ + wrdqs_delay_val[ch][index][i] = 0x3ff & + (mmio_read_32(PHY_REG(ch, 63 + i * 128)) + >> 16); + mmio_clrsetbits_32(PHY_REG(ch, 63 + i * 128), + 0x03ff << 16, 0 << 16); + /* + * in normal mode the cmd may delay 1cycle by + * wrlvl and in bypass mode making dqs also + * delay 1cycle. + */ + mmio_clrsetbits_32(PHY_REG(ch, 78 + i * 128), + 0x07 << 8, 0x1 << 8); + } + } + } else if (mmio_read_32(PHY_REG(ch, 86)) & 0xc00) { + /* old status is bypass mode and restore wrlvl resume */ + for (i = 0; i < 4; i++) { + mmio_clrsetbits_32(PHY_REG(ch, 63 + i * 128), + 0x03ff << 16, + (wrdqs_delay_val[ch][index][i] & + 0x3ff) << 16); + /* resume phy_write_path_lat_add */ + mmio_clrbits_32(PHY_REG(ch, 78 + i * 128), 0x07 << 8); + } } + + /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */ + mmio_clrsetbits_32(PHY_REG(ch, 86), 0xf << 8, sw_master_mode << 8); + mmio_clrsetbits_32(PHY_REG(ch, 214), 0xf << 8, sw_master_mode << 8); + mmio_clrsetbits_32(PHY_REG(ch, 342), 0xf << 8, sw_master_mode << 8); + mmio_clrsetbits_32(PHY_REG(ch, 470), 0xf << 8, sw_master_mode << 8); + + /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */ + mmio_clrsetbits_32(PHY_REG(ch, 547), 0xf << 16, sw_master_mode << 16); + mmio_clrsetbits_32(PHY_REG(ch, 675), 0xf << 16, sw_master_mode << 16); + mmio_clrsetbits_32(PHY_REG(ch, 803), 0xf << 16, sw_master_mode << 16); } static void gen_rk3399_phy_params(struct timing_related_config *timing_config, @@ -1745,15 +1557,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, /* DENALI_PHY_911 13bits offset_0 */ /* PHY_LP4_BOOT_PLL_CTRL */ /* DENALI_PHY_919 13bits offset_0 */ - if (pdram_timing->mhz <= 150) - tmp = 3; - else if (pdram_timing->mhz <= 300) - tmp = 2; - else if (pdram_timing->mhz <= 600) - tmp = 1; - else - tmp = 0; - tmp = (1 << 12) | (tmp << 9) | (2 << 7) | (1 << 1); + tmp = (1 << 12) | (2 << 7) | (1 << 1); mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff, tmp); mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff, tmp); @@ -1761,15 +1565,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, /* DENALI_PHY_911 13bits offset_16 */ /* PHY_LP4_BOOT_PLL_CTRL_CA */ /* DENALI_PHY_919 13bits offset_16 */ - if (pdram_timing->mhz <= 150) - tmp = 3; - else if (pdram_timing->mhz <= 300) - tmp = 2; - else if (pdram_timing->mhz <= 600) - tmp = 1; - else - tmp = 0; - tmp = (tmp << 9) | (2 << 7) | (1 << 5) | (1 << 1); + tmp = (2 << 7) | (1 << 5) | (1 << 1); mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff << 16, tmp << 16); mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff << 16, tmp << 16); @@ -1791,7 +1587,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, break; } mmio_clrsetbits_32(PHY_REG(i, 947), 0x7 << 8, tmp << 8); - mmio_setbits_32(PHY_REG(i, 927), (1 << 22)); if (timing_config->dram_type == DDR3) { mem_delay_ps = 0; @@ -1812,12 +1607,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, gate_delay_ps = delay_frac_ps + 1000 - (trpre_min_ps / 2); gate_delay_frac_ps = gate_delay_ps % 1000; tmp = gate_delay_frac_ps * 0x200 / 1000; - /* PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY */ - /* DENALI_PHY_2/130/258/386 10bits offset_0 */ - mmio_clrsetbits_32(PHY_REG(i, 2), 0x2ff, tmp); - mmio_clrsetbits_32(PHY_REG(i, 130), 0x2ff, tmp); - mmio_clrsetbits_32(PHY_REG(i, 258), 0x2ff, tmp); - mmio_clrsetbits_32(PHY_REG(i, 386), 0x2ff, tmp); /* PHY_RDDQS_GATE_SLAVE_DELAY */ /* DENALI_PHY_77/205/333/461 10bits offset_16 */ mmio_clrsetbits_32(PHY_REG(i, 77), 0x2ff << 16, tmp << 16); @@ -1832,12 +1621,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, mmio_clrsetbits_32(PHY_REG(i, 138), 0xf, tmp); mmio_clrsetbits_32(PHY_REG(i, 266), 0xf, tmp); mmio_clrsetbits_32(PHY_REG(i, 394), 0xf, tmp); - /* PHY_RDDQS_LATENCY_ADJUST */ - /* DENALI_PHY_78/206/334/462 4bits offset_0 */ - mmio_clrsetbits_32(PHY_REG(i, 78), 0xf, tmp); - mmio_clrsetbits_32(PHY_REG(i, 206), 0xf, tmp); - mmio_clrsetbits_32(PHY_REG(i, 334), 0xf, tmp); - mmio_clrsetbits_32(PHY_REG(i, 462), 0xf, tmp); /* PHY_GTLVL_LAT_ADJ_START */ /* DENALI_PHY_80/208/336/464 4bits offset_16 */ tmp = delay_frac_ps / 1000; @@ -1922,6 +1705,8 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config, mmio_setbits_32(PHY_REG(i, 340), 0x1 << 16); mmio_setbits_32(PHY_REG(i, 468), 0x1 << 16); } + gen_rk3399_phy_dll_bypass(pdram_timing->mhz, i, fn, + timing_config->dram_type); } } @@ -1944,22 +1729,6 @@ static int to_get_clk_index(unsigned int mhz) return i; } -uint32_t rkclk_prepare_pll_timing(unsigned int mhz) -{ - unsigned int refdiv, postdiv1, fbdiv, postdiv2; - int index; - - index = to_get_clk_index(mhz); - refdiv = dpll_rates_table[index].refdiv; - fbdiv = dpll_rates_table[index].fbdiv; - postdiv1 = dpll_rates_table[index].postdiv1; - postdiv2 = dpll_rates_table[index].postdiv2; - mmio_write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(fbdiv)); - mmio_write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON1, - POSTDIV2(postdiv2) | POSTDIV1(postdiv1) | REFDIV(refdiv)); - return (24 * fbdiv) / refdiv / postdiv1 / postdiv2; -} - uint32_t ddr_get_rate(void) { uint32_t refdiv, postdiv1, fbdiv, postdiv2; @@ -2051,90 +1820,21 @@ void resume_low_power(uint32_t low_power) } } -static void wait_dcf_done(void) -{ - while ((mmio_read_32(DCF_BASE + DCF_DCF_ISR) & (DCF_DONE)) == 0) - continue; -} - -void clr_dcf_irq(void) +static void dram_low_power_config(void) { - /* clear dcf irq status */ - mmio_write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE); -} - -static void enable_dcf(uint32_t dcf_addr) -{ - /* config DCF start addr */ - mmio_write_32(DCF_BASE + DCF_DCF_ADDR, dcf_addr); - /* wait dcf done */ - while (mmio_read_32(DCF_BASE + DCF_DCF_CTRL) & 1) - continue; - /* clear dcf irq status */ - mmio_write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE); - /* DCF start */ - mmio_setbits_32(DCF_BASE + DCF_DCF_CTRL, DCF_START); -} - -void dcf_code_init(void) -{ - memcpy((void *)DCF_START_ADDR, (void *)dcf_code, sizeof(dcf_code)); - /* set dcf master secure */ - mmio_write_32(SGRF_BASE + 0xe01c, ((0x3 << 0) << 16) | (0 << 0)); - mmio_write_32(DCF_BASE + DCF_DCF_TOSET, 0x80000000); -} - -static void dcf_start(uint32_t freq, uint32_t index) -{ - mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10), - (0x1 << (1 + 16)) | (1 << 1)); - mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(11), - (0x1 << (0 + 16)) | (1 << 0)); - mmio_write_32(DCF_PARAM_ADDR + PARAM_FREQ_SELECT, index << 4); - - mmio_write_32(DCF_PARAM_ADDR + PARAM_DRAM_FREQ, freq); - - rkclk_prepare_pll_timing(freq); - udelay(10); - mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10), - (0x1 << (1 + 16)) | (0 << 1)); - mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(11), - (0x1 << (0 + 16)) | (0 << 0)); - udelay(10); - enable_dcf(DCF_START_ADDR); -} - -static void dram_low_power_config(struct drv_odt_lp_config *lp_config) -{ - uint32_t tmp, tmp1, i; + uint32_t tmp, i; uint32_t ch_cnt = rk3399_dram_status.timing_config.ch_cnt; uint32_t dram_type = rk3399_dram_status.timing_config.dram_type; - uint32_t *low_power = &rk3399_dram_status.low_power_stat; - - if (dram_type == LPDDR4) - tmp = (lp_config->srpd_lite_idle << 16) | - lp_config->pd_idle; - else - tmp = lp_config->pd_idle; if (dram_type == DDR3) - tmp1 = (2 << 16) | (0x7 << 8) | 7; + tmp = (2 << 16) | (0x7 << 8); else - tmp1 = (3 << 16) | (0x7 << 8) | 7; + tmp = (3 << 16) | (0x7 << 8); - *low_power = 0; - - for (i = 0; i < ch_cnt; i++) { - mmio_write_32(CTL_REG(i, 102), tmp); - mmio_clrsetbits_32(CTL_REG(i, 103), 0xffff, - (lp_config->sr_mc_gate_idle << 8) | - lp_config->sr_idle); - mmio_clrsetbits_32(CTL_REG(i, 101), 0x70f0f, tmp1); - *low_power |= (7 << (8 * i)); - } + for (i = 0; i < ch_cnt; i++) + mmio_clrsetbits_32(CTL_REG(i, 101), 0x70f0f, tmp); /* standby idle */ - mmio_write_32(CIC_BASE + CIC_IDLE_TH, lp_config->standby_idle); mmio_write_32(CIC_BASE + CIC_CG_WAIT_TH, 0x640008); if (ch_cnt == 2) { @@ -2142,36 +1842,22 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config) (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) | ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); - if (lp_config->standby_idle) { - tmp = 0x002a002a; - *low_power |= (1 << 11); - } else - tmp = 0; - mmio_write_32(CIC_BASE + CIC_CTRL1, tmp); + mmio_write_32(CIC_BASE + CIC_CTRL1, 0x002a0028); } mmio_write_32(GRF_BASE + GRF_DDRC0_CON1, (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) | ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); - if (lp_config->standby_idle) { - tmp = 0x00150015; - *low_power |= (1 << 3); - } else - tmp = 0; - mmio_write_32(CIC_BASE + CIC_CTRL1, tmp); + mmio_write_32(CIC_BASE + CIC_CTRL1, 0x00150014); } - -static void dram_related_init(struct ddr_dts_config_timing *dts_timing) +void dram_dfs_init(void) { - uint32_t trefi0, trefi1; - uint32_t i; - - dcf_code_init(); + uint32_t trefi0, trefi1, boot_freq; /* get sdram config for os reg */ - drv_odt_lp_cfg_init(sdram_config.dramtype, dts_timing, - &rk3399_dram_status.drv_odt_lp_cfg); + get_dram_drv_odt_val(sdram_config.dramtype, + &rk3399_dram_status.drv_odt_lp_cfg); sdram_timing_cfg_init(&rk3399_dram_status.timing_config, &sdram_config, &rk3399_dram_status.drv_odt_lp_cfg); @@ -2187,30 +1873,106 @@ static void dram_related_init(struct ddr_dts_config_timing *dts_timing) rk3399_dram_status.index_freq[0] /= 2; rk3399_dram_status.index_freq[1] /= 2; } - rk3399_dram_status.index_freq[(rk3399_dram_status.current_index + 1) - & 0x1] = 0; + boot_freq = + rk3399_dram_status.index_freq[rk3399_dram_status.current_index]; + boot_freq = dpll_rates_table[to_get_clk_index(boot_freq)].mhz; + rk3399_dram_status.boot_freq = boot_freq; + rk3399_dram_status.index_freq[rk3399_dram_status.current_index] = + boot_freq; + rk3399_dram_status.index_freq[(rk3399_dram_status.current_index + 1) & + 0x1] = 0; + rk3399_dram_status.low_power_stat = 0; + /* + * following register decide if NOC stall the access request + * or return error when NOC being idled. when doing ddr frequency + * scaling in M0 or DCF, we need to make sure noc stall the access + * request, if return error cpu may data abort when ddr frequency + * changing. it don't need to set this register every times, + * so we init this register in function dram_dfs_init(). + */ + mmio_write_32(GRF_BASE + GRF_SOC_CON(0), 0xffffffff); + mmio_write_32(GRF_BASE + GRF_SOC_CON(1), 0xffffffff); + mmio_write_32(GRF_BASE + GRF_SOC_CON(2), 0xffffffff); + mmio_write_32(GRF_BASE + GRF_SOC_CON(3), 0xffffffff); + mmio_write_32(GRF_BASE + GRF_SOC_CON(4), 0x70007000); - /* disable all training by ctl and pi */ - for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) { - mmio_clrbits_32(CTL_REG(i, 70), (1 << 24) | - (1 << 16) | (1 << 8) | 1); - mmio_clrbits_32(CTL_REG(i, 71), 1); + /* Disable multicast */ + mmio_clrbits_32(PHY_REG(0, 896), 1); + mmio_clrbits_32(PHY_REG(1, 896), 1); + + dram_low_power_config(); +} + +/* + * arg0: bit0-7: sr_idle; bit8-15:sr_mc_gate_idle; bit16-31: standby idle + * arg1: bit0-11: pd_idle; bit 16-27: srpd_lite_idle + * arg2: bit0: if odt en + */ +uint32_t dram_set_odt_pd(uint32_t arg0, uint32_t arg1, uint32_t arg2) +{ + struct drv_odt_lp_config *lp_cfg = &rk3399_dram_status.drv_odt_lp_cfg; + uint32_t *low_power = &rk3399_dram_status.low_power_stat; + uint32_t dram_type, ch_count, pd_tmp, sr_tmp, i; + + dram_type = rk3399_dram_status.timing_config.dram_type; + ch_count = rk3399_dram_status.timing_config.ch_cnt; + + lp_cfg->sr_idle = arg0 & 0xff; + lp_cfg->sr_mc_gate_idle = (arg0 >> 8) & 0xff; + lp_cfg->standby_idle = (arg0 >> 16) & 0xffff; + lp_cfg->pd_idle = arg1 & 0xfff; + lp_cfg->srpd_lite_idle = (arg1 >> 16) & 0xfff; + + rk3399_dram_status.timing_config.odt = arg2 & 0x1; + + exit_low_power(); + + *low_power = 0; - mmio_clrbits_32(PI_REG(i, 60), 0x3 << 8); - mmio_clrbits_32(PI_REG(i, 80), (0x3 << 24) | (0x3 << 16)); - mmio_clrbits_32(PI_REG(i, 100), 0x3 << 8); - mmio_clrbits_32(PI_REG(i, 124), 0x3 << 16); + /* pd_idle en */ + if (lp_cfg->pd_idle) + *low_power |= ((1 << 0) | (1 << 8)); + /* sr_idle en srpd_lite_idle */ + if (lp_cfg->sr_idle | lp_cfg->srpd_lite_idle) + *low_power |= ((1 << 1) | (1 << 9)); + /* sr_mc_gate_idle */ + if (lp_cfg->sr_mc_gate_idle) + *low_power |= ((1 << 2) | (1 << 10)); + /* standbyidle */ + if (lp_cfg->standby_idle) { + if (rk3399_dram_status.timing_config.ch_cnt == 2) + *low_power |= ((1 << 3) | (1 << 11)); + else + *low_power |= (1 << 3); } - /* init drv odt */ - if (rk3399_dram_status.index_freq[rk3399_dram_status.current_index] < - rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq) - rk3399_dram_status.timing_config.odt = 0; - else - rk3399_dram_status.timing_config.odt = 1; - gen_rk3399_set_ds_odt(&rk3399_dram_status.timing_config, - &rk3399_dram_status.drv_odt_lp_cfg); - dram_low_power_config(&rk3399_dram_status.drv_odt_lp_cfg); + pd_tmp = arg1; + if (dram_type != LPDDR4) + pd_tmp = arg1 & 0xfff; + sr_tmp = arg0 & 0xffff; + for (i = 0; i < ch_count; i++) { + mmio_write_32(CTL_REG(i, 102), pd_tmp); + mmio_clrsetbits_32(CTL_REG(i, 103), 0xffff, sr_tmp); + } + mmio_write_32(CIC_BASE + CIC_IDLE_TH, (arg0 >> 16) & 0xffff); + + return 0; +} + +static void m0_configure_ddr(struct pll_div pll_div, uint32_t ddr_index) +{ + /* set PARAM to M0_FUNC_DRAM */ + mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_DRAM); + + mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(pll_div.fbdiv)); + mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON1, + POSTDIV2(pll_div.postdiv2) | POSTDIV1(pll_div.postdiv1) | + REFDIV(pll_div.refdiv)); + + mmio_write_32(M0_PARAM_ADDR + PARAM_DRAM_FREQ, pll_div.mhz); + + mmio_write_32(M0_PARAM_ADDR + PARAM_FREQ_SELECT, ddr_index << 4); + dmbst(); } static uint32_t prepare_ddr_timing(uint32_t mhz) @@ -2220,20 +1982,15 @@ static uint32_t prepare_ddr_timing(uint32_t mhz) rk3399_dram_status.timing_config.freq = mhz; - if (mhz < rk3399_dram_status.drv_odt_lp_cfg.ddr3_dll_dis_freq) + if (mhz < 300) rk3399_dram_status.timing_config.dllbp = 1; else rk3399_dram_status.timing_config.dllbp = 0; - if (mhz < rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq) { - rk3399_dram_status.timing_config.odt = 0; - } else { - rk3399_dram_status.timing_config.odt = 1; + + if (rk3399_dram_status.timing_config.odt == 1) gen_rk3399_set_odt(1); - } index = (rk3399_dram_status.current_index + 1) & 0x1; - if (rk3399_dram_status.index_freq[index] == mhz) - goto out; /* * checking if having available gate traiing timing for @@ -2249,8 +2006,6 @@ static uint32_t prepare_ddr_timing(uint32_t mhz) &dram_timing, index); rk3399_dram_status.index_freq[index] = mhz; - -out: return index; } @@ -2271,33 +2026,39 @@ void print_dram_status_info(void) uint32_t ddr_set_rate(uint32_t hz) { - uint32_t low_power, index; + uint32_t low_power, index, ddr_index; uint32_t mhz = hz / (1000 * 1000); if (mhz == rk3399_dram_status.index_freq[rk3399_dram_status.current_index]) - goto out; + return mhz; index = to_get_clk_index(mhz); mhz = dpll_rates_table[index].mhz; - low_power = exit_low_power(); - index = prepare_ddr_timing(mhz); - if (index > 1) + ddr_index = prepare_ddr_timing(mhz); + gen_rk3399_enable_training(rk3399_dram_status.timing_config.ch_cnt, + mhz); + if (ddr_index > 1) goto out; - dcf_start(mhz, index); - wait_dcf_done(); + /* + * Make sure the clock is enabled. The M0 clocks should be on all of the + * time during S0. + */ + m0_configure_ddr(dpll_rates_table[index], ddr_index); + m0_start(); + m0_wait_done(); + m0_stop(); + if (rk3399_dram_status.timing_config.odt == 0) gen_rk3399_set_odt(0); - rk3399_dram_status.current_index = index; - - if (mhz < dts_parameter.auto_pd_dis_freq) - low_power |= rk3399_dram_status.low_power_stat; - + rk3399_dram_status.current_index = ddr_index; + low_power = rk3399_dram_status.low_power_stat; resume_low_power(low_power); out: + gen_rk3399_disable_training(rk3399_dram_status.timing_config.ch_cnt); return mhz; } @@ -2311,29 +2072,56 @@ uint32_t ddr_round_rate(uint32_t hz) return dpll_rates_table[index].mhz * 1000 * 1000; } -uint32_t dts_timing_receive(uint32_t timing, uint32_t index) +void ddr_prepare_for_sys_suspend(void) { - uint32_t *p = (uint32_t *) &dts_parameter; - static uint32_t receive_nums; - - if (index < (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) { - p[index] = (uint32_t)timing; - receive_nums++; - } else { - dts_parameter.available = 0; - return -1; - } + uint32_t mhz = + rk3399_dram_status.index_freq[rk3399_dram_status.current_index]; - /* receive all parameter */ - if (receive_nums == (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) { - dts_parameter.available = 1; - receive_nums = 0; - } + /* + * If we're not currently at the boot (assumed highest) frequency, we + * need to change frequencies to configure out current index. + */ + rk3399_suspend_status.freq = mhz; + exit_low_power(); + rk3399_suspend_status.low_power_stat = + rk3399_dram_status.low_power_stat; + rk3399_suspend_status.odt = rk3399_dram_status.timing_config.odt; + rk3399_dram_status.low_power_stat = 0; + rk3399_dram_status.timing_config.odt = 1; + if (mhz != rk3399_dram_status.boot_freq) + ddr_set_rate(rk3399_dram_status.boot_freq * 1000 * 1000); - return index; + /* + * This will configure the other index to be the same frequency as the + * current one. We retrain both indices on resume, so both have to be + * setup for the same frequency. + */ + prepare_ddr_timing(rk3399_dram_status.boot_freq); } -void ddr_dfs_init(void) +void ddr_prepare_for_sys_resume(void) { - dram_related_init(&dts_parameter); + /* Disable multicast */ + mmio_clrbits_32(PHY_REG(0, 896), 1); + mmio_clrbits_32(PHY_REG(1, 896), 1); + + /* The suspend code changes the current index, so reset it now. */ + rk3399_dram_status.current_index = + (mmio_read_32(CTL_REG(0, 111)) >> 16) & 0x3; + rk3399_dram_status.low_power_stat = + rk3399_suspend_status.low_power_stat; + rk3399_dram_status.timing_config.odt = rk3399_suspend_status.odt; + + /* + * Set the saved frequency from suspend if it's different than the + * current frequency. + */ + if (rk3399_suspend_status.freq != + rk3399_dram_status.index_freq[rk3399_dram_status.current_index]) { + ddr_set_rate(rk3399_suspend_status.freq * 1000 * 1000); + return; + } + + gen_rk3399_set_odt(rk3399_dram_status.timing_config.odt); + resume_low_power(rk3399_dram_status.low_power_stat); } diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.h b/plat/rockchip/rk3399/drivers/dram/dfs.h index 1da09032d3..3204ae74c8 100644 --- a/plat/rockchip/rk3399/drivers/dram/dfs.h +++ b/plat/rockchip/rk3399/drivers/dram/dfs.h @@ -48,65 +48,25 @@ struct rk3399_sdram_default_config { unsigned char zqcsi; }; -struct ddr_dts_config_timing { - unsigned int ddr3_speed_bin; - unsigned int pd_idle; - unsigned int sr_idle; - unsigned int sr_mc_gate_idle; - unsigned int srpd_lite_idle; - unsigned int standby_idle; - unsigned int auto_pd_dis_freq; - unsigned int ddr3_dll_dis_freq; - unsigned int phy_dll_dis_freq; - unsigned int ddr3_odt_dis_freq; - unsigned int ddr3_drv; - unsigned int ddr3_odt; - unsigned int phy_ddr3_ca_drv; - unsigned int phy_ddr3_dq_drv; - unsigned int phy_ddr3_odt; - unsigned int lpddr3_odt_dis_freq; - unsigned int lpddr3_drv; - unsigned int lpddr3_odt; - unsigned int phy_lpddr3_ca_drv; - unsigned int phy_lpddr3_dq_drv; - unsigned int phy_lpddr3_odt; - unsigned int lpddr4_odt_dis_freq; - unsigned int lpddr4_drv; - unsigned int lpddr4_dq_odt; - unsigned int lpddr4_ca_odt; - unsigned int phy_lpddr4_ca_drv; - unsigned int phy_lpddr4_ck_cs_drv; - unsigned int phy_lpddr4_dq_drv; - unsigned int phy_lpddr4_odt; - uint32_t available; -}; - struct drv_odt_lp_config { - uint32_t ddr3_speed_bin; uint32_t pd_idle; uint32_t sr_idle; uint32_t sr_mc_gate_idle; uint32_t srpd_lite_idle; uint32_t standby_idle; - - uint32_t ddr3_dll_dis_freq;/* for ddr3 only */ - uint32_t phy_dll_dis_freq; - uint32_t odt_dis_freq; + uint32_t odt_en; uint32_t dram_side_drv; uint32_t dram_side_dq_odt; uint32_t dram_side_ca_odt; - - uint32_t phy_side_ca_drv; - uint32_t phy_side_ck_cs_drv; - uint32_t phy_side_dq_drv; - uint32_t phy_side_odt; }; -void ddr_dfs_init(void); uint32_t ddr_set_rate(uint32_t hz); uint32_t ddr_round_rate(uint32_t hz); uint32_t ddr_get_rate(void); -void clr_dcf_irq(void); -uint32_t dts_timing_receive(uint32_t timing, uint32_t index); +uint32_t dram_set_odt_pd(uint32_t arg0, uint32_t arg1, uint32_t arg2); +void dram_dfs_init(void); +void ddr_prepare_for_sys_suspend(void); +void ddr_prepare_for_sys_resume(void); + #endif diff --git a/plat/rockchip/rk3399/drivers/dram/dram.c b/plat/rockchip/rk3399/drivers/dram/dram.c index 5f6f0fc3e4..1dfb3e5a6e 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.c +++ b/plat/rockchip/rk3399/drivers/dram/dram.c @@ -30,6 +30,7 @@ #include <dram.h> #include <plat_private.h> +#include <secure.h> #include <soc.h> #include <rk3399_def.h> diff --git a/plat/rockchip/rk3399/drivers/dram/dram.h b/plat/rockchip/rk3399/drivers/dram/dram.h index 44dfbbdcae..571d51afe1 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.h +++ b/plat/rockchip/rk3399/drivers/dram/dram.h @@ -30,111 +30,11 @@ #ifndef __SOC_ROCKCHIP_RK3399_DRAM_H__ #define __SOC_ROCKCHIP_RK3399_DRAM_H__ + +#include <dram_regs.h> #include <plat_private.h> #include <stdint.h> -#define CTL_BASE(ch) (0xffa80000 + (ch) * 0x8000) -#define CTL_REG(ch, n) (CTL_BASE(ch) + (n) * 0x4) - -#define PI_OFFSET 0x800 -#define PI_BASE(ch) (CTL_BASE(ch) + PI_OFFSET) -#define PI_REG(ch, n) (PI_BASE(ch) + (n) * 0x4) - -#define PHY_OFFSET 0x2000 -#define PHY_BASE(ch) (CTL_BASE(ch) + PHY_OFFSET) -#define PHY_REG(ch, n) (PHY_BASE(ch) + (n) * 0x4) - -#define MSCH_BASE(ch) (0xffa84000 + (ch) * 0x8000) -#define MSCH_ID_COREID 0x0 -#define MSCH_ID_REVISIONID 0x4 -#define MSCH_DEVICECONF 0x8 -#define MSCH_DEVICESIZE 0xc -#define MSCH_DDRTIMINGA0 0x10 -#define MSCH_DDRTIMINGB0 0x14 -#define MSCH_DDRTIMINGC0 0x18 -#define MSCH_DEVTODEV0 0x1c -#define MSCH_DDRMODE 0x110 -#define MSCH_AGINGX0 0x1000 - -#define CIC_CTRL0 0x0 -#define CIC_CTRL1 0x4 -#define CIC_IDLE_TH 0x8 -#define CIC_CG_WAIT_TH 0xc -#define CIC_STATUS0 0x10 -#define CIC_STATUS1 0x14 -#define CIC_CTRL2 0x18 -#define CIC_CTRL3 0x1c -#define CIC_CTRL4 0x20 - -/* DENALI_CTL_00 */ -#define START 1 - -/* DENALI_CTL_68 */ -#define PWRUP_SREFRESH_EXIT (1 << 16) - -/* DENALI_CTL_274 */ -#define MEM_RST_VALID 1 - -#define PHY_DRV_ODT_Hi_Z 0x0 -#define PHY_DRV_ODT_240 0x1 -#define PHY_DRV_ODT_120 0x8 -#define PHY_DRV_ODT_80 0x9 -#define PHY_DRV_ODT_60 0xc -#define PHY_DRV_ODT_48 0xd -#define PHY_DRV_ODT_40 0xe -#define PHY_DRV_ODT_34_3 0xf - -/* - * 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_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_DEC_CHINFO(n, ch) (((n) >> (28 + (ch))) & 0x1) -#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 + (ch) * 16)) & 0x1)) -#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << (9 + (ch) * 16)) -#define SYS_REG_DEC_COL(n, ch) (9 + (((n) >> (9 + (ch) * 16)) & 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 + (ch) * 16)) & 0x1)) -#define SYS_REG_ENC_CS0_ROW(n, ch) (((n) - 13) << (6 + (ch) * 16)) -#define SYS_REG_DEC_CS0_ROW(n, ch) (13 + (((n) >> (6 + (ch) * 16)) & 0x3)) -#define SYS_REG_ENC_CS1_ROW(n, ch) (((n) - 13) << (4 + (ch) * 16)) -#define SYS_REG_DEC_CS1_ROW(n, ch) (13 + (((n) >> (4 + (ch) * 16)) & 0x3)) -#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << (2 + (ch) * 16)) -#define SYS_REG_DEC_BW(n, ch) (2 >> (((n) >> (2 + (ch) * 16)) & 0x3)) -#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + (ch) * 16)) -#define SYS_REG_DEC_DBW(n, ch) (2 >> (((n) >> (0 + (ch) * 16)) & 0x3)) -#define DDR_STRIDE(n) mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(4), \ - (0x1f<<(10+16))|((n)<<10)) - -#define CTL_REG_NUM 332 -#define PHY_REG_NUM 959 -#define PI_REG_NUM 200 - enum { DDR3 = 3, LPDDR2 = 5, @@ -259,6 +159,7 @@ struct rk3399_sdram_params { struct rk3399_ddr_pctl_regs pctl_regs; struct rk3399_ddr_pi_regs pi_regs; struct rk3399_ddr_publ_regs phy_regs; + uint32_t rx_cal_dqs[2][4]; }; extern __sramdata struct rk3399_sdram_params sdram_config; diff --git a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c index 3f6ab2f2c1..6288de4339 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c +++ b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c @@ -267,21 +267,24 @@ static void ddr3_get_parameter(struct timing_related_config *timing_config, break; } - switch (timing_config->dramodt) { - case 60: - pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_60; - break; - case 40: - pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_40; - break; - case 120: - pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_120; - break; - case 0: - default: + if (timing_config->odt) + switch (timing_config->dramodt) { + case 60: + pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_60; + break; + case 40: + pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_40; + break; + case 120: + pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_120; + break; + case 0: + default: + pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_DIS; + break; + } + else pdram_timing->mr[1] = tmp | DDR3_RTT_NOM_DIS; - break; - } pdram_timing->mr[2] = DDR3_MR2_CWL(pdram_timing->cwl); pdram_timing->mr[3] = 0; @@ -664,6 +667,9 @@ static void lpddr2_get_parameter(struct timing_related_config *timing_config, #define LPDDR3_TADR (20) /* ns */ #define LPDDR3_TMRZ (3) /* ns */ +/* FSP */ +#define LPDDR3_TFC_LONG (250) /* ns */ + /* * Description: depend on input parameter "timing_config", * and calculate all lpddr3 @@ -751,18 +757,21 @@ static void lpddr3_get_parameter(struct timing_related_config *timing_config, break; } pdram_timing->mr[0] = 0; - switch (timing_config->dramodt) { - case 60: - pdram_timing->mr11 = LPDDR3_ODT_60; - break; - case 120: - pdram_timing->mr11 = LPDDR3_ODT_120; - break; - case 240: - default: - pdram_timing->mr11 = LPDDR3_ODT_240; - break; - } + if (timing_config->odt) + switch (timing_config->dramodt) { + case 60: + pdram_timing->mr11 = LPDDR3_ODT_60; + break; + case 120: + pdram_timing->mr11 = LPDDR3_ODT_120; + break; + case 240: + default: + pdram_timing->mr11 = LPDDR3_ODT_240; + break; + } + else + pdram_timing->mr11 = LPDDR3_ODT_DIS; pdram_timing->tinit1 = (LPDDR3_TINIT1 * nmhz + 999) / 1000; pdram_timing->tinit2 = LPDDR3_TINIT2; @@ -874,6 +883,9 @@ static void lpddr3_get_parameter(struct timing_related_config *timing_config, pdram_timing->tadr = (LPDDR3_TADR * nmhz + 999) / 1000; pdram_timing->tmrz = (LPDDR3_TMRZ * nmhz + 999) / 1000; pdram_timing->tcacd = pdram_timing->tadr + 2; + + /* FSP */ + pdram_timing->tfc_long = (LPDDR3_TFC_LONG * nmhz + 999) / 1000; } #define LPDDR4_TINIT1 (200000) /* 200us */ @@ -1113,47 +1125,52 @@ static void lpddr4_get_parameter(struct timing_related_config *timing_config, break; } pdram_timing->mr[0] = 0; - switch (timing_config->dramodt) { - case 240: - tmp = LPDDR4_DQODT_240; - break; - case 120: - tmp = LPDDR4_DQODT_120; - break; - case 80: - tmp = LPDDR4_DQODT_80; - break; - case 60: - tmp = LPDDR4_DQODT_60; - break; - case 48: - tmp = LPDDR4_DQODT_48; - break; - case 40: - default: - tmp = LPDDR4_DQODT_40; - break; - } - switch (timing_config->caodt) { - case 240: - pdram_timing->mr11 = LPDDR4_CAODT_240 | tmp; - break; - case 120: - pdram_timing->mr11 = LPDDR4_CAODT_120 | tmp; - break; - case 80: - pdram_timing->mr11 = LPDDR4_CAODT_80 | tmp; - break; - case 60: - pdram_timing->mr11 = LPDDR4_CAODT_60 | tmp; - break; - case 48: - pdram_timing->mr11 = LPDDR4_CAODT_48 | tmp; - break; - case 40: - default: - pdram_timing->mr11 = LPDDR4_CAODT_40 | tmp; - break; + if (timing_config->odt) { + switch (timing_config->dramodt) { + case 240: + tmp = LPDDR4_DQODT_240; + break; + case 120: + tmp = LPDDR4_DQODT_120; + break; + case 80: + tmp = LPDDR4_DQODT_80; + break; + case 60: + tmp = LPDDR4_DQODT_60; + break; + case 48: + tmp = LPDDR4_DQODT_48; + break; + case 40: + default: + tmp = LPDDR4_DQODT_40; + break; + } + + switch (timing_config->caodt) { + case 240: + pdram_timing->mr11 = LPDDR4_CAODT_240 | tmp; + break; + case 120: + pdram_timing->mr11 = LPDDR4_CAODT_120 | tmp; + break; + case 80: + pdram_timing->mr11 = LPDDR4_CAODT_80 | tmp; + break; + case 60: + pdram_timing->mr11 = LPDDR4_CAODT_60 | tmp; + break; + case 48: + pdram_timing->mr11 = LPDDR4_CAODT_48 | tmp; + break; + case 40: + default: + pdram_timing->mr11 = LPDDR4_CAODT_40 | tmp; + break; + } + } else { + pdram_timing->mr11 = LPDDR4_CAODT_DIS | tmp; } pdram_timing->tinit1 = (LPDDR4_TINIT1 * nmhz + 999) / 1000; diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index f408d676c6..42cbf98799 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -34,6 +34,7 @@ #include <dram.h> #include <pmu_regs.h> #include <rk3399_def.h> +#include <secure.h> #include <soc.h> #include <suspend.h> @@ -571,14 +572,15 @@ static __sramfunc void pctl_cfg(uint32_t ch, sram_regcpy(PHY_REG(ch, 768), (uintptr_t)¶ms_phy[768], 38); } -static __sramfunc int dram_switch_to_phy_index1( +static __sramfunc int dram_switch_to_next_index( struct rk3399_sdram_params *sdram_params) { uint32_t ch, ch_count; + uint32_t fn = ((mmio_read_32(CTL_REG(0, 111)) >> 16) + 1) & 0x1; mmio_write_32(CIC_BASE + CIC_CTRL0, (((0x3 << 4) | (1 << 2) | 1) << 16) | - (1 << 4) | (1 << 2) | 1); + (fn << 4) | (1 << 2) | 1); while (!(mmio_read_32(CIC_BASE + CIC_STATUS0) & (1 << 2))) ; @@ -591,7 +593,7 @@ static __sramfunc int dram_switch_to_phy_index1( /* LPDDR4 f2 cann't do training, all training will fail */ for (ch = 0; ch < ch_count; ch++) { mmio_clrsetbits_32(PHY_REG(ch, 896), (0x3 << 8) | 1, - 1 << 8); + fn << 8); /* data_training failed */ if (data_training(ch, sdram_params, PI_FULL_TRAINING)) @@ -609,6 +611,7 @@ static __sramfunc int pctl_start(uint32_t channel_mask, struct rk3399_sdram_params *sdram_params) { uint32_t count; + uint32_t byte; mmio_setbits_32(CTL_REG(0, 68), PWRUP_SREFRESH_EXIT); mmio_setbits_32(CTL_REG(1, 68), PWRUP_SREFRESH_EXIT); @@ -640,6 +643,12 @@ static __sramfunc int pctl_start(uint32_t channel_mask, } mmio_clrbits_32(CTL_REG(0, 68), PWRUP_SREFRESH_EXIT); + + /* Restore the PHY_RX_CAL_DQS value */ + for (byte = 0; byte < 4; byte++) + mmio_clrsetbits_32(PHY_REG(0, 57 + 128 * byte), + 0xfff << 16, + sdram_params->rx_cal_dqs[0][byte]); } if (channel_mask & (1 << 1)) { count = 0; @@ -653,6 +662,12 @@ static __sramfunc int pctl_start(uint32_t channel_mask, } mmio_clrbits_32(CTL_REG(1, 68), PWRUP_SREFRESH_EXIT); + + /* Restore the PHY_RX_CAL_DQS value */ + for (byte = 0; byte < 4; byte++) + mmio_clrsetbits_32(PHY_REG(1, 57 + 128 * byte), + 0xfff << 16, + sdram_params->rx_cal_dqs[1][byte]); } return 0; @@ -665,7 +680,7 @@ void dmc_save(void) uint32_t *params_pi; uint32_t *params_phy; uint32_t refdiv, postdiv2, postdiv1, fbdiv; - uint32_t tmp; + uint32_t tmp, ch, byte; params_ctl = sdram_params->pctl_regs.denali_ctl; params_pi = sdram_params->pi_regs.denali_pi; @@ -705,6 +720,12 @@ void dmc_save(void) sram_regcpy((uintptr_t)¶ms_phy[768], PHY_REG(0, 768), 38); sram_regcpy((uintptr_t)¶ms_phy[896], PHY_REG(0, 896), 63); + for (ch = 0; ch < sdram_params->num_channels; ch++) { + for (byte = 0; byte < 4; byte++) + sdram_params->rx_cal_dqs[ch][byte] = (0xfff << 16) & + mmio_read_32(PHY_REG(ch, 57 + byte * 128)); + } + /* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */ params_phy[957] &= ~(0x3 << 24); params_phy[957] |= 1 << 24; @@ -754,5 +775,5 @@ retry: dram_all_config(sdram_params); /* Switch to index 1 and prepare for DDR frequency switch. */ - dram_switch_to_phy_index1(sdram_params); + dram_switch_to_next_index(sdram_params); } |