1*613038bcSCaesar Wang /* 2*613038bcSCaesar Wang * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*613038bcSCaesar Wang * 4*613038bcSCaesar Wang * Redistribution and use in source and binary forms, with or without 5*613038bcSCaesar Wang * modification, are permitted provided that the following conditions are met: 6*613038bcSCaesar Wang * 7*613038bcSCaesar Wang * Redistributions of source code must retain the above copyright notice, this 8*613038bcSCaesar Wang * list of conditions and the following disclaimer. 9*613038bcSCaesar Wang * 10*613038bcSCaesar Wang * Redistributions in binary form must reproduce the above copyright notice, 11*613038bcSCaesar Wang * this list of conditions and the following disclaimer in the documentation 12*613038bcSCaesar Wang * and/or other materials provided with the distribution. 13*613038bcSCaesar Wang * 14*613038bcSCaesar Wang * Neither the name of ARM nor the names of its contributors may be used 15*613038bcSCaesar Wang * to endorse or promote products derived from this software without specific 16*613038bcSCaesar Wang * prior written permission. 17*613038bcSCaesar Wang * 18*613038bcSCaesar Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*613038bcSCaesar Wang * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*613038bcSCaesar Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*613038bcSCaesar Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*613038bcSCaesar Wang * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*613038bcSCaesar Wang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*613038bcSCaesar Wang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*613038bcSCaesar Wang * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*613038bcSCaesar Wang * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*613038bcSCaesar Wang * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*613038bcSCaesar Wang * POSSIBILITY OF SUCH DAMAGE. 29*613038bcSCaesar Wang */ 30*613038bcSCaesar Wang 31*613038bcSCaesar Wang #include <debug.h> 32*613038bcSCaesar Wang #include <mmio.h> 33*613038bcSCaesar Wang #include <plat_private.h> 34*613038bcSCaesar Wang #include "dfs.h" 35*613038bcSCaesar Wang #include "dram.h" 36*613038bcSCaesar Wang #include "dram_spec_timing.h" 37*613038bcSCaesar Wang #include "string.h" 38*613038bcSCaesar Wang #include "soc.h" 39*613038bcSCaesar Wang #include "pmu.h" 40*613038bcSCaesar Wang 41*613038bcSCaesar Wang #include <delay_timer.h> 42*613038bcSCaesar Wang 43*613038bcSCaesar Wang #define CTL_TRAINING (1) 44*613038bcSCaesar Wang #define PI_TRAINING (!CTL_TRAINING) 45*613038bcSCaesar Wang 46*613038bcSCaesar Wang #define EN_READ_GATE_TRAINING (1) 47*613038bcSCaesar Wang #define EN_CA_TRAINING (0) 48*613038bcSCaesar Wang #define EN_WRITE_LEVELING (0) 49*613038bcSCaesar Wang #define EN_READ_LEVELING (0) 50*613038bcSCaesar Wang #define EN_WDQ_LEVELING (0) 51*613038bcSCaesar Wang 52*613038bcSCaesar Wang #define ENPER_CS_TRAINING_FREQ (933) 53*613038bcSCaesar Wang 54*613038bcSCaesar Wang struct pll_div { 55*613038bcSCaesar Wang unsigned int mhz; 56*613038bcSCaesar Wang unsigned int refdiv; 57*613038bcSCaesar Wang unsigned int fbdiv; 58*613038bcSCaesar Wang unsigned int postdiv1; 59*613038bcSCaesar Wang unsigned int postdiv2; 60*613038bcSCaesar Wang unsigned int frac; 61*613038bcSCaesar Wang unsigned int freq; 62*613038bcSCaesar Wang }; 63*613038bcSCaesar Wang 64*613038bcSCaesar Wang static const struct pll_div dpll_rates_table[] = { 65*613038bcSCaesar Wang 66*613038bcSCaesar Wang /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */ 67*613038bcSCaesar Wang {.mhz = 933, .refdiv = 3, .fbdiv = 350, .postdiv1 = 3, .postdiv2 = 1}, 68*613038bcSCaesar Wang {.mhz = 800, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1}, 69*613038bcSCaesar Wang {.mhz = 732, .refdiv = 1, .fbdiv = 61, .postdiv1 = 2, .postdiv2 = 1}, 70*613038bcSCaesar Wang {.mhz = 666, .refdiv = 1, .fbdiv = 111, .postdiv1 = 4, .postdiv2 = 1}, 71*613038bcSCaesar Wang {.mhz = 600, .refdiv = 1, .fbdiv = 50, .postdiv1 = 2, .postdiv2 = 1}, 72*613038bcSCaesar Wang {.mhz = 528, .refdiv = 1, .fbdiv = 66, .postdiv1 = 3, .postdiv2 = 1}, 73*613038bcSCaesar Wang {.mhz = 400, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1}, 74*613038bcSCaesar Wang {.mhz = 300, .refdiv = 1, .fbdiv = 50, .postdiv1 = 4, .postdiv2 = 1}, 75*613038bcSCaesar Wang {.mhz = 200, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 2}, 76*613038bcSCaesar Wang }; 77*613038bcSCaesar Wang 78*613038bcSCaesar Wang static struct rk3399_ddr_pctl_regs *const rk3399_ddr_pctl[2] = { 79*613038bcSCaesar Wang (void *)DDRC0_BASE, (void *)DDRC1_BASE 80*613038bcSCaesar Wang }; 81*613038bcSCaesar Wang 82*613038bcSCaesar Wang static struct rk3399_ddr_pi_regs *const rk3399_ddr_pi[2] = { 83*613038bcSCaesar Wang (void *)DDRC0_PI_BASE, (void *)DDRC1_PI_BASE 84*613038bcSCaesar Wang }; 85*613038bcSCaesar Wang 86*613038bcSCaesar Wang static struct rk3399_ddr_publ_regs *const rk3399_ddr_publ[2] = { 87*613038bcSCaesar Wang (void *)DDRC0_PHY_BASE, (void *)DDRC1_PHY_BASE 88*613038bcSCaesar Wang }; 89*613038bcSCaesar Wang 90*613038bcSCaesar Wang struct rk3399_dram_status { 91*613038bcSCaesar Wang uint32_t current_index; 92*613038bcSCaesar Wang uint32_t index_freq[2]; 93*613038bcSCaesar Wang uint32_t low_power_stat; 94*613038bcSCaesar Wang struct timing_related_config timing_config; 95*613038bcSCaesar Wang struct drv_odt_lp_config drv_odt_lp_cfg; 96*613038bcSCaesar Wang }; 97*613038bcSCaesar Wang 98*613038bcSCaesar Wang static struct rk3399_dram_status rk3399_dram_status; 99*613038bcSCaesar Wang static struct ddr_dts_config_timing dts_parameter = { 100*613038bcSCaesar Wang .available = 0 101*613038bcSCaesar Wang }; 102*613038bcSCaesar Wang 103*613038bcSCaesar Wang static struct rk3399_sdram_default_config ddr3_default_config = { 104*613038bcSCaesar Wang .bl = 8, 105*613038bcSCaesar Wang .ap = 0, 106*613038bcSCaesar Wang .dramds = 40, 107*613038bcSCaesar Wang .dramodt = 120, 108*613038bcSCaesar Wang .burst_ref_cnt = 1, 109*613038bcSCaesar Wang .zqcsi = 0 110*613038bcSCaesar Wang }; 111*613038bcSCaesar Wang 112*613038bcSCaesar Wang static struct drv_odt_lp_config ddr3_drv_odt_default_config = { 113*613038bcSCaesar Wang .ddr3_speed_bin = DDR3_DEFAULT, 114*613038bcSCaesar Wang .pd_idle = 0, 115*613038bcSCaesar Wang .sr_idle = 0, 116*613038bcSCaesar Wang .sr_mc_gate_idle = 0, 117*613038bcSCaesar Wang .srpd_lite_idle = 0, 118*613038bcSCaesar Wang .standby_idle = 0, 119*613038bcSCaesar Wang 120*613038bcSCaesar Wang .ddr3_dll_dis_freq = 300, 121*613038bcSCaesar Wang .phy_dll_dis_freq = 125, 122*613038bcSCaesar Wang .odt_dis_freq = 933, 123*613038bcSCaesar Wang 124*613038bcSCaesar Wang .dram_side_drv = 40, 125*613038bcSCaesar Wang .dram_side_dq_odt = 120, 126*613038bcSCaesar Wang .dram_side_ca_odt = 120, 127*613038bcSCaesar Wang 128*613038bcSCaesar Wang .phy_side_ca_drv = 40, 129*613038bcSCaesar Wang .phy_side_ck_cs_drv = 40, 130*613038bcSCaesar Wang .phy_side_dq_drv = 40, 131*613038bcSCaesar Wang .phy_side_odt = 240, 132*613038bcSCaesar Wang }; 133*613038bcSCaesar Wang 134*613038bcSCaesar Wang static struct rk3399_sdram_default_config lpddr3_default_config = { 135*613038bcSCaesar Wang .bl = 8, 136*613038bcSCaesar Wang .ap = 0, 137*613038bcSCaesar Wang .dramds = 34, 138*613038bcSCaesar Wang .dramodt = 240, 139*613038bcSCaesar Wang .burst_ref_cnt = 1, 140*613038bcSCaesar Wang .zqcsi = 0 141*613038bcSCaesar Wang }; 142*613038bcSCaesar Wang 143*613038bcSCaesar Wang static struct drv_odt_lp_config lpddr3_drv_odt_default_config = { 144*613038bcSCaesar Wang .ddr3_speed_bin = DDR3_DEFAULT, 145*613038bcSCaesar Wang .pd_idle = 0, 146*613038bcSCaesar Wang .sr_idle = 0, 147*613038bcSCaesar Wang .sr_mc_gate_idle = 0, 148*613038bcSCaesar Wang .srpd_lite_idle = 0, 149*613038bcSCaesar Wang .standby_idle = 0, 150*613038bcSCaesar Wang 151*613038bcSCaesar Wang .ddr3_dll_dis_freq = 300, 152*613038bcSCaesar Wang .phy_dll_dis_freq = 125, 153*613038bcSCaesar Wang .odt_dis_freq = 666, 154*613038bcSCaesar Wang 155*613038bcSCaesar Wang .dram_side_drv = 40, 156*613038bcSCaesar Wang .dram_side_dq_odt = 120, 157*613038bcSCaesar Wang .dram_side_ca_odt = 120, 158*613038bcSCaesar Wang 159*613038bcSCaesar Wang .phy_side_ca_drv = 40, 160*613038bcSCaesar Wang .phy_side_ck_cs_drv = 40, 161*613038bcSCaesar Wang .phy_side_dq_drv = 40, 162*613038bcSCaesar Wang .phy_side_odt = 240, 163*613038bcSCaesar Wang }; 164*613038bcSCaesar Wang 165*613038bcSCaesar Wang static struct rk3399_sdram_default_config lpddr4_default_config = { 166*613038bcSCaesar Wang .bl = 16, 167*613038bcSCaesar Wang .ap = 0, 168*613038bcSCaesar Wang .dramds = 40, 169*613038bcSCaesar Wang .dramodt = 240, 170*613038bcSCaesar Wang .caodt = 240, 171*613038bcSCaesar Wang .burst_ref_cnt = 1, 172*613038bcSCaesar Wang .zqcsi = 0 173*613038bcSCaesar Wang }; 174*613038bcSCaesar Wang 175*613038bcSCaesar Wang static struct drv_odt_lp_config lpddr4_drv_odt_default_config = { 176*613038bcSCaesar Wang .ddr3_speed_bin = DDR3_DEFAULT, 177*613038bcSCaesar Wang .pd_idle = 0, 178*613038bcSCaesar Wang .sr_idle = 0, 179*613038bcSCaesar Wang .sr_mc_gate_idle = 0, 180*613038bcSCaesar Wang .srpd_lite_idle = 0, 181*613038bcSCaesar Wang .standby_idle = 0, 182*613038bcSCaesar Wang 183*613038bcSCaesar Wang .ddr3_dll_dis_freq = 300, 184*613038bcSCaesar Wang .phy_dll_dis_freq = 125, 185*613038bcSCaesar Wang .odt_dis_freq = 933, 186*613038bcSCaesar Wang 187*613038bcSCaesar Wang .dram_side_drv = 60, 188*613038bcSCaesar Wang .dram_side_dq_odt = 40, 189*613038bcSCaesar Wang .dram_side_ca_odt = 40, 190*613038bcSCaesar Wang 191*613038bcSCaesar Wang .phy_side_ca_drv = 40, 192*613038bcSCaesar Wang .phy_side_ck_cs_drv = 80, 193*613038bcSCaesar Wang .phy_side_dq_drv = 80, 194*613038bcSCaesar Wang .phy_side_odt = 60, 195*613038bcSCaesar Wang }; 196*613038bcSCaesar Wang 197*613038bcSCaesar Wang uint32_t dcf_code[] = { 198*613038bcSCaesar Wang #include "dcf_code.inc" 199*613038bcSCaesar Wang }; 200*613038bcSCaesar Wang 201*613038bcSCaesar Wang 202*613038bcSCaesar Wang #define write_32(addr, value)\ 203*613038bcSCaesar Wang mmio_write_32((uintptr_t)(addr), (uint32_t)(value)) 204*613038bcSCaesar Wang 205*613038bcSCaesar Wang #define read_32(addr) \ 206*613038bcSCaesar Wang mmio_read_32((uintptr_t)(addr)) 207*613038bcSCaesar Wang #define clrbits_32(addr, clear)\ 208*613038bcSCaesar Wang mmio_clrbits_32((uintptr_t)(addr), (uint32_t)(clear)) 209*613038bcSCaesar Wang #define setbits_32(addr, set)\ 210*613038bcSCaesar Wang mmio_setbits_32((uintptr_t)(addr), (uint32_t)(set)) 211*613038bcSCaesar Wang #define clrsetbits_32(addr, clear, set)\ 212*613038bcSCaesar Wang mmio_clrsetbits_32((uintptr_t)(addr), (uint32_t)(clear),\ 213*613038bcSCaesar Wang (uint32_t)(set)) 214*613038bcSCaesar Wang 215*613038bcSCaesar Wang #define DCF_START_ADDR (SRAM_BASE + 0x1400) 216*613038bcSCaesar Wang #define DCF_PARAM_ADDR (SRAM_BASE + 0x1000) 217*613038bcSCaesar Wang 218*613038bcSCaesar Wang /* DCF_PAMET */ 219*613038bcSCaesar Wang #define PARAM_DRAM_FREQ (0) 220*613038bcSCaesar Wang #define PARAM_DPLL_CON0 (4) 221*613038bcSCaesar Wang #define PARAM_DPLL_CON1 (8) 222*613038bcSCaesar Wang #define PARAM_DPLL_CON2 (0xc) 223*613038bcSCaesar Wang #define PARAM_DPLL_CON3 (0x10) 224*613038bcSCaesar Wang #define PARAM_DPLL_CON4 (0x14) 225*613038bcSCaesar Wang #define PARAM_DPLL_CON5 (0x18) 226*613038bcSCaesar Wang /* equal to fn<<4 */ 227*613038bcSCaesar Wang #define PARAM_FREQ_SELECT (0x1c) 228*613038bcSCaesar Wang 229*613038bcSCaesar Wang static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config, 230*613038bcSCaesar Wang uint8_t channel, uint8_t cs) 231*613038bcSCaesar Wang { 232*613038bcSCaesar Wang struct rk3399_sdram_channel *ch = &sdram_config->ch[channel]; 233*613038bcSCaesar Wang uint32_t bandwidth; 234*613038bcSCaesar Wang uint32_t die_bandwidth; 235*613038bcSCaesar Wang uint32_t die; 236*613038bcSCaesar Wang uint32_t cs_cap; 237*613038bcSCaesar Wang uint32_t row; 238*613038bcSCaesar Wang 239*613038bcSCaesar Wang row = cs == 0 ? ch->cs0_row : ch->cs1_row; 240*613038bcSCaesar Wang bandwidth = 8 * (1 << ch->bw); 241*613038bcSCaesar Wang die_bandwidth = 8 * (1 << ch->dbw); 242*613038bcSCaesar Wang die = bandwidth / die_bandwidth; 243*613038bcSCaesar Wang cs_cap = (1 << (row + ((1 << ch->bk) / 4 + 1) + ch->col + 244*613038bcSCaesar Wang (bandwidth / 16))); 245*613038bcSCaesar Wang if (ch->row_3_4) 246*613038bcSCaesar Wang cs_cap = cs_cap * 3 / 4; 247*613038bcSCaesar Wang 248*613038bcSCaesar Wang return (cs_cap / die); 249*613038bcSCaesar Wang } 250*613038bcSCaesar Wang 251*613038bcSCaesar Wang static void drv_odt_lp_cfg_init(uint32_t dram_type, 252*613038bcSCaesar Wang struct ddr_dts_config_timing *dts_timing, 253*613038bcSCaesar Wang struct drv_odt_lp_config *drv_config) 254*613038bcSCaesar Wang { 255*613038bcSCaesar Wang if ((dts_timing) && (dts_timing->available)) { 256*613038bcSCaesar Wang drv_config->ddr3_speed_bin = dts_timing->ddr3_speed_bin; 257*613038bcSCaesar Wang drv_config->pd_idle = dts_timing->pd_idle; 258*613038bcSCaesar Wang drv_config->sr_idle = dts_timing->sr_idle; 259*613038bcSCaesar Wang drv_config->sr_mc_gate_idle = dts_timing->sr_mc_gate_idle; 260*613038bcSCaesar Wang drv_config->srpd_lite_idle = dts_timing->srpd_lite_idle; 261*613038bcSCaesar Wang drv_config->standby_idle = dts_timing->standby_idle; 262*613038bcSCaesar Wang drv_config->ddr3_dll_dis_freq = dts_timing->ddr3_dll_dis_freq; 263*613038bcSCaesar Wang drv_config->phy_dll_dis_freq = dts_timing->phy_dll_dis_freq; 264*613038bcSCaesar Wang } 265*613038bcSCaesar Wang 266*613038bcSCaesar Wang switch (dram_type) { 267*613038bcSCaesar Wang case DDR3: 268*613038bcSCaesar Wang if ((dts_timing) && (dts_timing->available)) { 269*613038bcSCaesar Wang drv_config->odt_dis_freq = 270*613038bcSCaesar Wang dts_timing->ddr3_odt_dis_freq; 271*613038bcSCaesar Wang drv_config->dram_side_drv = dts_timing->ddr3_drv; 272*613038bcSCaesar Wang drv_config->dram_side_dq_odt = dts_timing->ddr3_odt; 273*613038bcSCaesar Wang drv_config->phy_side_ca_drv = 274*613038bcSCaesar Wang dts_timing->phy_ddr3_ca_drv; 275*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = 276*613038bcSCaesar Wang dts_timing->phy_ddr3_ca_drv; 277*613038bcSCaesar Wang drv_config->phy_side_dq_drv = 278*613038bcSCaesar Wang dts_timing->phy_ddr3_dq_drv; 279*613038bcSCaesar Wang drv_config->phy_side_odt = dts_timing->phy_ddr3_odt; 280*613038bcSCaesar Wang } else { 281*613038bcSCaesar Wang memcpy(drv_config, &ddr3_drv_odt_default_config, 282*613038bcSCaesar Wang sizeof(struct drv_odt_lp_config)); 283*613038bcSCaesar Wang } 284*613038bcSCaesar Wang break; 285*613038bcSCaesar Wang case LPDDR3: 286*613038bcSCaesar Wang if ((dts_timing) && (dts_timing->available)) { 287*613038bcSCaesar Wang drv_config->odt_dis_freq = 288*613038bcSCaesar Wang dts_timing->lpddr3_odt_dis_freq; 289*613038bcSCaesar Wang drv_config->dram_side_drv = dts_timing->lpddr3_drv; 290*613038bcSCaesar Wang drv_config->dram_side_dq_odt = dts_timing->lpddr3_odt; 291*613038bcSCaesar Wang drv_config->phy_side_ca_drv = 292*613038bcSCaesar Wang dts_timing->phy_lpddr3_ca_drv; 293*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = 294*613038bcSCaesar Wang dts_timing->phy_lpddr3_ca_drv; 295*613038bcSCaesar Wang drv_config->phy_side_dq_drv = 296*613038bcSCaesar Wang dts_timing->phy_lpddr3_dq_drv; 297*613038bcSCaesar Wang drv_config->phy_side_odt = dts_timing->phy_lpddr3_odt; 298*613038bcSCaesar Wang 299*613038bcSCaesar Wang } else { 300*613038bcSCaesar Wang memcpy(drv_config, &lpddr3_drv_odt_default_config, 301*613038bcSCaesar Wang sizeof(struct drv_odt_lp_config)); 302*613038bcSCaesar Wang } 303*613038bcSCaesar Wang break; 304*613038bcSCaesar Wang case LPDDR4: 305*613038bcSCaesar Wang default: 306*613038bcSCaesar Wang if ((dts_timing) && (dts_timing->available)) { 307*613038bcSCaesar Wang drv_config->odt_dis_freq = 308*613038bcSCaesar Wang dts_timing->lpddr4_odt_dis_freq; 309*613038bcSCaesar Wang drv_config->dram_side_drv = dts_timing->lpddr4_drv; 310*613038bcSCaesar Wang drv_config->dram_side_dq_odt = 311*613038bcSCaesar Wang dts_timing->lpddr4_dq_odt; 312*613038bcSCaesar Wang drv_config->dram_side_ca_odt = 313*613038bcSCaesar Wang dts_timing->lpddr4_ca_odt; 314*613038bcSCaesar Wang drv_config->phy_side_ca_drv = 315*613038bcSCaesar Wang dts_timing->phy_lpddr4_ca_drv; 316*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = 317*613038bcSCaesar Wang dts_timing->phy_lpddr4_ck_cs_drv; 318*613038bcSCaesar Wang drv_config->phy_side_dq_drv = 319*613038bcSCaesar Wang dts_timing->phy_lpddr4_dq_drv; 320*613038bcSCaesar Wang drv_config->phy_side_odt = dts_timing->phy_lpddr4_odt; 321*613038bcSCaesar Wang } else { 322*613038bcSCaesar Wang memcpy(drv_config, &lpddr4_drv_odt_default_config, 323*613038bcSCaesar Wang sizeof(struct drv_odt_lp_config)); 324*613038bcSCaesar Wang } 325*613038bcSCaesar Wang break; 326*613038bcSCaesar Wang } 327*613038bcSCaesar Wang 328*613038bcSCaesar Wang switch (drv_config->phy_side_ca_drv) { 329*613038bcSCaesar Wang case 240: 330*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_240; 331*613038bcSCaesar Wang break; 332*613038bcSCaesar Wang case 120: 333*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_120; 334*613038bcSCaesar Wang break; 335*613038bcSCaesar Wang case 80: 336*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_80; 337*613038bcSCaesar Wang break; 338*613038bcSCaesar Wang case 60: 339*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_60; 340*613038bcSCaesar Wang break; 341*613038bcSCaesar Wang case 48: 342*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_48; 343*613038bcSCaesar Wang break; 344*613038bcSCaesar Wang case 40: 345*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_40; 346*613038bcSCaesar Wang break; 347*613038bcSCaesar Wang default: 348*613038bcSCaesar Wang drv_config->phy_side_ca_drv = PHY_DRV_ODT_34_3; 349*613038bcSCaesar Wang break; 350*613038bcSCaesar Wang }; 351*613038bcSCaesar Wang 352*613038bcSCaesar Wang switch (drv_config->phy_side_ck_cs_drv) { 353*613038bcSCaesar Wang case 240: 354*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_240; 355*613038bcSCaesar Wang break; 356*613038bcSCaesar Wang case 120: 357*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_120; 358*613038bcSCaesar Wang break; 359*613038bcSCaesar Wang case 80: 360*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_80; 361*613038bcSCaesar Wang break; 362*613038bcSCaesar Wang case 60: 363*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_60; 364*613038bcSCaesar Wang break; 365*613038bcSCaesar Wang case 48: 366*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_48; 367*613038bcSCaesar Wang break; 368*613038bcSCaesar Wang case 40: 369*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_40; 370*613038bcSCaesar Wang break; 371*613038bcSCaesar Wang default: 372*613038bcSCaesar Wang drv_config->phy_side_ck_cs_drv = PHY_DRV_ODT_34_3; 373*613038bcSCaesar Wang break; 374*613038bcSCaesar Wang } 375*613038bcSCaesar Wang 376*613038bcSCaesar Wang switch (drv_config->phy_side_dq_drv) { 377*613038bcSCaesar Wang case 240: 378*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_240; 379*613038bcSCaesar Wang break; 380*613038bcSCaesar Wang case 120: 381*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_120; 382*613038bcSCaesar Wang break; 383*613038bcSCaesar Wang case 80: 384*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_80; 385*613038bcSCaesar Wang break; 386*613038bcSCaesar Wang case 60: 387*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_60; 388*613038bcSCaesar Wang break; 389*613038bcSCaesar Wang case 48: 390*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_48; 391*613038bcSCaesar Wang break; 392*613038bcSCaesar Wang case 40: 393*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_40; 394*613038bcSCaesar Wang break; 395*613038bcSCaesar Wang default: 396*613038bcSCaesar Wang drv_config->phy_side_dq_drv = PHY_DRV_ODT_34_3; 397*613038bcSCaesar Wang break; 398*613038bcSCaesar Wang } 399*613038bcSCaesar Wang 400*613038bcSCaesar Wang switch (drv_config->phy_side_odt) { 401*613038bcSCaesar Wang case 240: 402*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_240; 403*613038bcSCaesar Wang break; 404*613038bcSCaesar Wang case 120: 405*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_120; 406*613038bcSCaesar Wang break; 407*613038bcSCaesar Wang case 80: 408*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_80; 409*613038bcSCaesar Wang break; 410*613038bcSCaesar Wang case 60: 411*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_60; 412*613038bcSCaesar Wang break; 413*613038bcSCaesar Wang case 48: 414*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_48; 415*613038bcSCaesar Wang break; 416*613038bcSCaesar Wang case 40: 417*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_40; 418*613038bcSCaesar Wang break; 419*613038bcSCaesar Wang default: 420*613038bcSCaesar Wang drv_config->phy_side_odt = PHY_DRV_ODT_34_3; 421*613038bcSCaesar Wang break; 422*613038bcSCaesar Wang } 423*613038bcSCaesar Wang } 424*613038bcSCaesar Wang 425*613038bcSCaesar Wang static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config, 426*613038bcSCaesar Wang struct rk3399_sdram_params *sdram_params, 427*613038bcSCaesar Wang struct drv_odt_lp_config *drv_config) 428*613038bcSCaesar Wang { 429*613038bcSCaesar Wang uint32_t i, j; 430*613038bcSCaesar Wang 431*613038bcSCaesar Wang for (i = 0; i < sdram_params->num_channels; i++) { 432*613038bcSCaesar Wang ptiming_config->dram_info[i].speed_rate = 433*613038bcSCaesar Wang drv_config->ddr3_speed_bin; 434*613038bcSCaesar Wang ptiming_config->dram_info[i].cs_cnt = sdram_params->ch[i].rank; 435*613038bcSCaesar Wang for (j = 0; j < sdram_params->ch[i].rank; j++) { 436*613038bcSCaesar Wang ptiming_config->dram_info[i].per_die_capability[j] = 437*613038bcSCaesar Wang get_cs_die_capability(sdram_params, i, j); 438*613038bcSCaesar Wang } 439*613038bcSCaesar Wang } 440*613038bcSCaesar Wang ptiming_config->dram_type = sdram_params->dramtype; 441*613038bcSCaesar Wang ptiming_config->ch_cnt = sdram_params->num_channels; 442*613038bcSCaesar Wang switch (sdram_params->dramtype) { 443*613038bcSCaesar Wang case DDR3: 444*613038bcSCaesar Wang ptiming_config->bl = ddr3_default_config.bl; 445*613038bcSCaesar Wang ptiming_config->ap = ddr3_default_config.ap; 446*613038bcSCaesar Wang break; 447*613038bcSCaesar Wang case LPDDR3: 448*613038bcSCaesar Wang ptiming_config->bl = lpddr3_default_config.bl; 449*613038bcSCaesar Wang ptiming_config->ap = lpddr3_default_config.ap; 450*613038bcSCaesar Wang break; 451*613038bcSCaesar Wang case LPDDR4: 452*613038bcSCaesar Wang ptiming_config->bl = lpddr4_default_config.bl; 453*613038bcSCaesar Wang ptiming_config->ap = lpddr4_default_config.ap; 454*613038bcSCaesar Wang ptiming_config->rdbi = 0; 455*613038bcSCaesar Wang ptiming_config->wdbi = 0; 456*613038bcSCaesar Wang break; 457*613038bcSCaesar Wang } 458*613038bcSCaesar Wang ptiming_config->dramds = drv_config->dram_side_drv; 459*613038bcSCaesar Wang ptiming_config->dramodt = drv_config->dram_side_dq_odt; 460*613038bcSCaesar Wang ptiming_config->caodt = drv_config->dram_side_ca_odt; 461*613038bcSCaesar Wang } 462*613038bcSCaesar Wang 463*613038bcSCaesar Wang struct lat_adj_pair { 464*613038bcSCaesar Wang uint32_t cl; 465*613038bcSCaesar Wang uint32_t rdlat_adj; 466*613038bcSCaesar Wang uint32_t cwl; 467*613038bcSCaesar Wang uint32_t wrlat_adj; 468*613038bcSCaesar Wang }; 469*613038bcSCaesar Wang 470*613038bcSCaesar Wang const struct lat_adj_pair ddr3_lat_adj[] = { 471*613038bcSCaesar Wang {6, 5, 5, 4}, 472*613038bcSCaesar Wang {8, 7, 6, 5}, 473*613038bcSCaesar Wang {10, 9, 7, 6}, 474*613038bcSCaesar Wang {11, 9, 8, 7}, 475*613038bcSCaesar Wang {13, 0xb, 9, 8}, 476*613038bcSCaesar Wang {14, 0xb, 0xa, 9} 477*613038bcSCaesar Wang }; 478*613038bcSCaesar Wang 479*613038bcSCaesar Wang const struct lat_adj_pair lpddr3_lat_adj[] = { 480*613038bcSCaesar Wang {3, 2, 1, 0}, 481*613038bcSCaesar Wang {6, 5, 3, 2}, 482*613038bcSCaesar Wang {8, 7, 4, 3}, 483*613038bcSCaesar Wang {9, 8, 5, 4}, 484*613038bcSCaesar Wang {10, 9, 6, 5}, 485*613038bcSCaesar Wang {11, 9, 6, 5}, 486*613038bcSCaesar Wang {12, 0xa, 6, 5}, 487*613038bcSCaesar Wang {14, 0xc, 8, 7}, 488*613038bcSCaesar Wang {16, 0xd, 8, 7} 489*613038bcSCaesar Wang }; 490*613038bcSCaesar Wang 491*613038bcSCaesar Wang const struct lat_adj_pair lpddr4_lat_adj[] = { 492*613038bcSCaesar Wang {6, 5, 4, 2}, 493*613038bcSCaesar Wang {10, 9, 6, 4}, 494*613038bcSCaesar Wang {14, 0xc, 8, 6}, 495*613038bcSCaesar Wang {20, 0x11, 0xa, 8}, 496*613038bcSCaesar Wang {24, 0x15, 0xc, 0xa}, 497*613038bcSCaesar Wang {28, 0x18, 0xe, 0xc}, 498*613038bcSCaesar Wang {32, 0x1b, 0x10, 0xe}, 499*613038bcSCaesar Wang {36, 0x1e, 0x12, 0x10} 500*613038bcSCaesar Wang }; 501*613038bcSCaesar Wang 502*613038bcSCaesar Wang static uint32_t get_rdlat_adj(uint32_t dram_type, uint32_t cl) 503*613038bcSCaesar Wang { 504*613038bcSCaesar Wang const struct lat_adj_pair *p; 505*613038bcSCaesar Wang uint32_t cnt; 506*613038bcSCaesar Wang uint32_t i; 507*613038bcSCaesar Wang 508*613038bcSCaesar Wang if (dram_type == DDR3) { 509*613038bcSCaesar Wang p = ddr3_lat_adj; 510*613038bcSCaesar Wang cnt = ARRAY_SIZE(ddr3_lat_adj); 511*613038bcSCaesar Wang } else if (dram_type == LPDDR3) { 512*613038bcSCaesar Wang p = lpddr3_lat_adj; 513*613038bcSCaesar Wang cnt = ARRAY_SIZE(lpddr3_lat_adj); 514*613038bcSCaesar Wang } else { 515*613038bcSCaesar Wang p = lpddr4_lat_adj; 516*613038bcSCaesar Wang cnt = ARRAY_SIZE(lpddr4_lat_adj); 517*613038bcSCaesar Wang } 518*613038bcSCaesar Wang 519*613038bcSCaesar Wang for (i = 0; i < cnt; i++) { 520*613038bcSCaesar Wang if (cl == p[i].cl) 521*613038bcSCaesar Wang return p[i].rdlat_adj; 522*613038bcSCaesar Wang } 523*613038bcSCaesar Wang /* fail */ 524*613038bcSCaesar Wang return 0xff; 525*613038bcSCaesar Wang } 526*613038bcSCaesar Wang 527*613038bcSCaesar Wang static uint32_t get_wrlat_adj(uint32_t dram_type, uint32_t cwl) 528*613038bcSCaesar Wang { 529*613038bcSCaesar Wang const struct lat_adj_pair *p; 530*613038bcSCaesar Wang uint32_t cnt; 531*613038bcSCaesar Wang uint32_t i; 532*613038bcSCaesar Wang 533*613038bcSCaesar Wang if (dram_type == DDR3) { 534*613038bcSCaesar Wang p = ddr3_lat_adj; 535*613038bcSCaesar Wang cnt = ARRAY_SIZE(ddr3_lat_adj); 536*613038bcSCaesar Wang } else if (dram_type == LPDDR3) { 537*613038bcSCaesar Wang p = lpddr3_lat_adj; 538*613038bcSCaesar Wang cnt = ARRAY_SIZE(lpddr3_lat_adj); 539*613038bcSCaesar Wang } else { 540*613038bcSCaesar Wang p = lpddr4_lat_adj; 541*613038bcSCaesar Wang cnt = ARRAY_SIZE(lpddr4_lat_adj); 542*613038bcSCaesar Wang } 543*613038bcSCaesar Wang 544*613038bcSCaesar Wang for (i = 0; i < cnt; i++) { 545*613038bcSCaesar Wang if (cwl == p[i].cwl) 546*613038bcSCaesar Wang return p[i].wrlat_adj; 547*613038bcSCaesar Wang } 548*613038bcSCaesar Wang /* fail */ 549*613038bcSCaesar Wang return 0xff; 550*613038bcSCaesar Wang } 551*613038bcSCaesar Wang 552*613038bcSCaesar Wang #define PI_REGS_DIMM_SUPPORT (0) 553*613038bcSCaesar Wang #define PI_ADD_LATENCY (0) 554*613038bcSCaesar Wang #define PI_DOUBLEFREEK (1) 555*613038bcSCaesar Wang 556*613038bcSCaesar Wang #define PI_PAD_DELAY_PS_VALUE (1000) 557*613038bcSCaesar Wang #define PI_IE_ENABLE_VALUE (3000) 558*613038bcSCaesar Wang #define PI_TSEL_ENABLE_VALUE (700) 559*613038bcSCaesar Wang 560*613038bcSCaesar Wang static uint32_t get_pi_rdlat_adj(struct dram_timing_t *pdram_timing) 561*613038bcSCaesar Wang { 562*613038bcSCaesar Wang /*[DLLSUBTYPE2] == "STD_DENALI_HS" */ 563*613038bcSCaesar Wang uint32_t rdlat, delay_adder, ie_enable, hs_offset, tsel_adder, 564*613038bcSCaesar Wang extra_adder, tsel_enable; 565*613038bcSCaesar Wang 566*613038bcSCaesar Wang ie_enable = PI_IE_ENABLE_VALUE; 567*613038bcSCaesar Wang tsel_enable = PI_TSEL_ENABLE_VALUE; 568*613038bcSCaesar Wang 569*613038bcSCaesar Wang rdlat = pdram_timing->cl + PI_ADD_LATENCY; 570*613038bcSCaesar Wang delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 571*613038bcSCaesar Wang if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 572*613038bcSCaesar Wang delay_adder++; 573*613038bcSCaesar Wang hs_offset = 0; 574*613038bcSCaesar Wang tsel_adder = 0; 575*613038bcSCaesar Wang extra_adder = 0; 576*613038bcSCaesar Wang /* rdlat = rdlat - (PREAMBLE_SUPPORT & 0x1); */ 577*613038bcSCaesar Wang tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz); 578*613038bcSCaesar Wang if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0) 579*613038bcSCaesar Wang tsel_adder++; 580*613038bcSCaesar Wang delay_adder = delay_adder - 1; 581*613038bcSCaesar Wang if (tsel_adder > delay_adder) 582*613038bcSCaesar Wang extra_adder = tsel_adder - delay_adder; 583*613038bcSCaesar Wang else 584*613038bcSCaesar Wang extra_adder = 0; 585*613038bcSCaesar Wang if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 586*613038bcSCaesar Wang hs_offset = 2; 587*613038bcSCaesar Wang else 588*613038bcSCaesar Wang hs_offset = 1; 589*613038bcSCaesar Wang 590*613038bcSCaesar Wang if (delay_adder > (rdlat - 1 - hs_offset)) { 591*613038bcSCaesar Wang rdlat = rdlat - tsel_adder; 592*613038bcSCaesar Wang } else { 593*613038bcSCaesar Wang if ((rdlat - delay_adder) < 2) 594*613038bcSCaesar Wang rdlat = 2; 595*613038bcSCaesar Wang else 596*613038bcSCaesar Wang rdlat = rdlat - delay_adder - extra_adder; 597*613038bcSCaesar Wang } 598*613038bcSCaesar Wang 599*613038bcSCaesar Wang return rdlat; 600*613038bcSCaesar Wang } 601*613038bcSCaesar Wang 602*613038bcSCaesar Wang static uint32_t get_pi_wrlat(struct dram_timing_t *pdram_timing, 603*613038bcSCaesar Wang struct timing_related_config *timing_config) 604*613038bcSCaesar Wang { 605*613038bcSCaesar Wang uint32_t tmp; 606*613038bcSCaesar Wang 607*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) { 608*613038bcSCaesar Wang tmp = pdram_timing->cl; 609*613038bcSCaesar Wang if (tmp >= 14) 610*613038bcSCaesar Wang tmp = 8; 611*613038bcSCaesar Wang else if (tmp >= 10) 612*613038bcSCaesar Wang tmp = 6; 613*613038bcSCaesar Wang else if (tmp == 9) 614*613038bcSCaesar Wang tmp = 5; 615*613038bcSCaesar Wang else if (tmp == 8) 616*613038bcSCaesar Wang tmp = 4; 617*613038bcSCaesar Wang else if (tmp == 6) 618*613038bcSCaesar Wang tmp = 3; 619*613038bcSCaesar Wang else 620*613038bcSCaesar Wang tmp = 1; 621*613038bcSCaesar Wang } else { 622*613038bcSCaesar Wang tmp = 1; 623*613038bcSCaesar Wang } 624*613038bcSCaesar Wang 625*613038bcSCaesar Wang return tmp; 626*613038bcSCaesar Wang } 627*613038bcSCaesar Wang 628*613038bcSCaesar Wang static uint32_t get_pi_wrlat_adj(struct dram_timing_t *pdram_timing, 629*613038bcSCaesar Wang struct timing_related_config *timing_config) 630*613038bcSCaesar Wang { 631*613038bcSCaesar Wang return get_pi_wrlat(pdram_timing, timing_config) + PI_ADD_LATENCY - 1; 632*613038bcSCaesar Wang } 633*613038bcSCaesar Wang 634*613038bcSCaesar Wang static uint32_t get_pi_tdfi_phy_rdlat(struct dram_timing_t *pdram_timing, 635*613038bcSCaesar Wang struct timing_related_config *timing_config) 636*613038bcSCaesar Wang { 637*613038bcSCaesar Wang /* [DLLSUBTYPE2] == "STD_DENALI_HS" */ 638*613038bcSCaesar Wang uint32_t cas_lat, delay_adder, ie_enable, hs_offset, ie_delay_adder; 639*613038bcSCaesar Wang uint32_t mem_delay_ps, round_trip_ps; 640*613038bcSCaesar Wang uint32_t phy_internal_delay, lpddr_adder, dfi_adder, rdlat_delay; 641*613038bcSCaesar Wang 642*613038bcSCaesar Wang ie_enable = PI_IE_ENABLE_VALUE; 643*613038bcSCaesar Wang 644*613038bcSCaesar Wang delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 645*613038bcSCaesar Wang if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 646*613038bcSCaesar Wang delay_adder++; 647*613038bcSCaesar Wang delay_adder = delay_adder - 1; 648*613038bcSCaesar Wang if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 649*613038bcSCaesar Wang hs_offset = 2; 650*613038bcSCaesar Wang else 651*613038bcSCaesar Wang hs_offset = 1; 652*613038bcSCaesar Wang 653*613038bcSCaesar Wang cas_lat = pdram_timing->cl + PI_ADD_LATENCY; 654*613038bcSCaesar Wang 655*613038bcSCaesar Wang if (delay_adder > (cas_lat - 1 - hs_offset)) { 656*613038bcSCaesar Wang ie_delay_adder = 0; 657*613038bcSCaesar Wang } else { 658*613038bcSCaesar Wang ie_delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 659*613038bcSCaesar Wang if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 660*613038bcSCaesar Wang ie_delay_adder++; 661*613038bcSCaesar Wang } 662*613038bcSCaesar Wang 663*613038bcSCaesar Wang if (timing_config->dram_type == DDR3) { 664*613038bcSCaesar Wang mem_delay_ps = 0; 665*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR4) { 666*613038bcSCaesar Wang mem_delay_ps = 3600; 667*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR3) { 668*613038bcSCaesar Wang mem_delay_ps = 5500; 669*613038bcSCaesar Wang } else { 670*613038bcSCaesar Wang printf("get_pi_tdfi_phy_rdlat:dramtype unsupport\n"); 671*613038bcSCaesar Wang return 0; 672*613038bcSCaesar Wang } 673*613038bcSCaesar Wang round_trip_ps = 1100 + 500 + mem_delay_ps + 500 + 600; 674*613038bcSCaesar Wang delay_adder = round_trip_ps / (1000000 / pdram_timing->mhz); 675*613038bcSCaesar Wang if ((round_trip_ps % (1000000 / pdram_timing->mhz)) != 0) 676*613038bcSCaesar Wang delay_adder++; 677*613038bcSCaesar Wang 678*613038bcSCaesar Wang phy_internal_delay = 5 + 2 + 4; 679*613038bcSCaesar Wang lpddr_adder = mem_delay_ps / (1000000 / pdram_timing->mhz); 680*613038bcSCaesar Wang if ((mem_delay_ps % (1000000 / pdram_timing->mhz)) != 0) 681*613038bcSCaesar Wang lpddr_adder++; 682*613038bcSCaesar Wang dfi_adder = 0; 683*613038bcSCaesar Wang phy_internal_delay = phy_internal_delay + 2; 684*613038bcSCaesar Wang rdlat_delay = delay_adder + phy_internal_delay + 685*613038bcSCaesar Wang ie_delay_adder + lpddr_adder + dfi_adder; 686*613038bcSCaesar Wang 687*613038bcSCaesar Wang rdlat_delay = rdlat_delay + 2; 688*613038bcSCaesar Wang return rdlat_delay; 689*613038bcSCaesar Wang } 690*613038bcSCaesar Wang 691*613038bcSCaesar Wang static uint32_t get_pi_todtoff_min(struct dram_timing_t *pdram_timing, 692*613038bcSCaesar Wang struct timing_related_config *timing_config) 693*613038bcSCaesar Wang { 694*613038bcSCaesar Wang uint32_t tmp, todtoff_min_ps; 695*613038bcSCaesar Wang 696*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) 697*613038bcSCaesar Wang todtoff_min_ps = 2500; 698*613038bcSCaesar Wang else if (timing_config->dram_type == LPDDR4) 699*613038bcSCaesar Wang todtoff_min_ps = 1500; 700*613038bcSCaesar Wang else 701*613038bcSCaesar Wang todtoff_min_ps = 0; 702*613038bcSCaesar Wang /* todtoff_min */ 703*613038bcSCaesar Wang tmp = todtoff_min_ps / (1000000 / pdram_timing->mhz); 704*613038bcSCaesar Wang if ((todtoff_min_ps % (1000000 / pdram_timing->mhz)) != 0) 705*613038bcSCaesar Wang tmp++; 706*613038bcSCaesar Wang return tmp; 707*613038bcSCaesar Wang } 708*613038bcSCaesar Wang 709*613038bcSCaesar Wang static uint32_t get_pi_todtoff_max(struct dram_timing_t *pdram_timing, 710*613038bcSCaesar Wang struct timing_related_config *timing_config) 711*613038bcSCaesar Wang { 712*613038bcSCaesar Wang uint32_t tmp, todtoff_max_ps; 713*613038bcSCaesar Wang 714*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR4) 715*613038bcSCaesar Wang || (timing_config->dram_type == LPDDR3)) 716*613038bcSCaesar Wang todtoff_max_ps = 3500; 717*613038bcSCaesar Wang else 718*613038bcSCaesar Wang todtoff_max_ps = 0; 719*613038bcSCaesar Wang 720*613038bcSCaesar Wang /* todtoff_max */ 721*613038bcSCaesar Wang tmp = todtoff_max_ps / (1000000 / pdram_timing->mhz); 722*613038bcSCaesar Wang if ((todtoff_max_ps % (1000000 / pdram_timing->mhz)) != 0) 723*613038bcSCaesar Wang tmp++; 724*613038bcSCaesar Wang return tmp; 725*613038bcSCaesar Wang } 726*613038bcSCaesar Wang 727*613038bcSCaesar Wang static void gen_rk3399_ctl_params_f0(struct timing_related_config 728*613038bcSCaesar Wang *timing_config, 729*613038bcSCaesar Wang struct dram_timing_t *pdram_timing) 730*613038bcSCaesar Wang { 731*613038bcSCaesar Wang uint32_t i; 732*613038bcSCaesar Wang uint32_t tmp, tmp1; 733*613038bcSCaesar Wang 734*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 735*613038bcSCaesar Wang if (timing_config->dram_type == DDR3) { 736*613038bcSCaesar Wang tmp = ((700000 + 10) * timing_config->freq + 737*613038bcSCaesar Wang 999) / 1000; 738*613038bcSCaesar Wang tmp += pdram_timing->txsnr + (pdram_timing->tmrd * 3) + 739*613038bcSCaesar Wang pdram_timing->tmod + pdram_timing->tzqinit; 740*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[5], tmp); 741*613038bcSCaesar Wang 742*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[22], 743*613038bcSCaesar Wang 0xffff, pdram_timing->tdllk); 744*613038bcSCaesar Wang 745*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[32], 746*613038bcSCaesar Wang (pdram_timing->tmod << 8) | 747*613038bcSCaesar Wang pdram_timing->tmrd); 748*613038bcSCaesar Wang 749*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[59], 750*613038bcSCaesar Wang 0xffff << 16, 751*613038bcSCaesar Wang (pdram_timing->txsr - 752*613038bcSCaesar Wang pdram_timing->trcd) << 16); 753*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR4) { 754*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[5], 755*613038bcSCaesar Wang pdram_timing->tinit1 + pdram_timing->tinit3); 756*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[32], 757*613038bcSCaesar Wang (pdram_timing->tmrd << 8) | 758*613038bcSCaesar Wang pdram_timing->tmrd); 759*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[59], 760*613038bcSCaesar Wang 0xffff << 16, pdram_timing->txsr << 16); 761*613038bcSCaesar Wang } else { 762*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[5], 763*613038bcSCaesar Wang pdram_timing->tinit1); 764*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[7], 765*613038bcSCaesar Wang pdram_timing->tinit4); 766*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[32], 767*613038bcSCaesar Wang (pdram_timing->tmrd << 8) | 768*613038bcSCaesar Wang pdram_timing->tmrd); 769*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[59], 770*613038bcSCaesar Wang 0xffff << 16, pdram_timing->txsr << 16); 771*613038bcSCaesar Wang } 772*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[6], 773*613038bcSCaesar Wang pdram_timing->tinit3); 774*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[8], 775*613038bcSCaesar Wang pdram_timing->tinit5); 776*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[23], (0x7f << 16), 777*613038bcSCaesar Wang ((pdram_timing->cl * 2) << 16)); 778*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[23], (0x1f << 24), 779*613038bcSCaesar Wang (pdram_timing->cwl << 24)); 780*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[24], 0x3f, 781*613038bcSCaesar Wang pdram_timing->al); 782*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[26], 0xffff << 16, 783*613038bcSCaesar Wang (pdram_timing->trc << 24) | 784*613038bcSCaesar Wang (pdram_timing->trrd << 16)); 785*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[27], 786*613038bcSCaesar Wang (pdram_timing->tfaw << 24) | 787*613038bcSCaesar Wang (pdram_timing->trppb << 16) | 788*613038bcSCaesar Wang (pdram_timing->twtr << 8) | pdram_timing->tras_min); 789*613038bcSCaesar Wang 790*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[31], 0xff << 24, 791*613038bcSCaesar Wang max(4, pdram_timing->trtp) << 24); 792*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[33], 793*613038bcSCaesar Wang (pdram_timing->tcke << 24) | pdram_timing->tras_max); 794*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[34], 0xff, 795*613038bcSCaesar Wang max(1, pdram_timing->tckesr)); 796*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[39], 797*613038bcSCaesar Wang (0x3f << 16) | (0xff << 8), 798*613038bcSCaesar Wang (pdram_timing->twr << 16) | 799*613038bcSCaesar Wang (pdram_timing->trcd << 8)); 800*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[42], 0x1f << 16, 801*613038bcSCaesar Wang pdram_timing->tmrz << 16); 802*613038bcSCaesar Wang tmp = pdram_timing->tdal ? pdram_timing->tdal : 803*613038bcSCaesar Wang (pdram_timing->twr + pdram_timing->trp); 804*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[44], 0xff, tmp); 805*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[45], 0xff, 806*613038bcSCaesar Wang pdram_timing->trp); 807*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[48], 808*613038bcSCaesar Wang ((pdram_timing->trefi - 8) << 16) | 809*613038bcSCaesar Wang pdram_timing->trfc); 810*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[52], 0xffff, 811*613038bcSCaesar Wang pdram_timing->txp); 812*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[53], 0xffff << 16, 813*613038bcSCaesar Wang pdram_timing->txpdll << 16); 814*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[55], 0xf << 24, 815*613038bcSCaesar Wang pdram_timing->tcscke << 24); 816*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[55], 0xff, 817*613038bcSCaesar Wang pdram_timing->tmrri); 818*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[56], 819*613038bcSCaesar Wang (pdram_timing->tzqcke << 24) | 820*613038bcSCaesar Wang (pdram_timing->tmrwckel << 16) | 821*613038bcSCaesar Wang (pdram_timing->tckehcs << 8) | pdram_timing->tckelcs); 822*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[60], 0xffff, 823*613038bcSCaesar Wang pdram_timing->txsnr); 824*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[62], 0xffff << 16, 825*613038bcSCaesar Wang (pdram_timing->tckehcmd << 24) | 826*613038bcSCaesar Wang (pdram_timing->tckelcmd << 16)); 827*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[63], 828*613038bcSCaesar Wang (pdram_timing->tckelpd << 24) | 829*613038bcSCaesar Wang (pdram_timing->tescke << 16) | 830*613038bcSCaesar Wang (pdram_timing->tsr << 8) | pdram_timing->tckckel); 831*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[64], 0xfff, 832*613038bcSCaesar Wang (pdram_timing->tcmdcke << 8) | 833*613038bcSCaesar Wang pdram_timing->tcsckeh); 834*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[92], 835*613038bcSCaesar Wang (0xffff << 8), 836*613038bcSCaesar Wang (pdram_timing->tcksrx << 16) | 837*613038bcSCaesar Wang (pdram_timing->tcksre << 8)); 838*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[108], (0x1 << 24), 839*613038bcSCaesar Wang (timing_config->dllbp << 24)); 840*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[122], 841*613038bcSCaesar Wang (0x3FF << 16), 842*613038bcSCaesar Wang (pdram_timing->tvrcg_enable << 16)); 843*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[123], 844*613038bcSCaesar Wang (pdram_timing->tfc_long << 16) | 845*613038bcSCaesar Wang pdram_timing->tvrcg_disable); 846*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[124], 847*613038bcSCaesar Wang (pdram_timing->tvref_long << 16) | 848*613038bcSCaesar Wang (pdram_timing->tckfspx << 8) | 849*613038bcSCaesar Wang pdram_timing->tckfspe); 850*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[133], 851*613038bcSCaesar Wang (pdram_timing->mr[1] << 16) | pdram_timing->mr[0]); 852*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[134], 0xffff, 853*613038bcSCaesar Wang pdram_timing->mr[2]); 854*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[138], 0xffff, 855*613038bcSCaesar Wang pdram_timing->mr[3]); 856*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[139], 0xff << 24, 857*613038bcSCaesar Wang pdram_timing->mr11 << 24); 858*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[147], 859*613038bcSCaesar Wang (pdram_timing->mr[1] << 16) | pdram_timing->mr[0]); 860*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[148], 0xffff, 861*613038bcSCaesar Wang pdram_timing->mr[2]); 862*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[152], 0xffff, 863*613038bcSCaesar Wang pdram_timing->mr[3]); 864*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[153], 0xff << 24, 865*613038bcSCaesar Wang pdram_timing->mr11 << 24); 866*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR4) { 867*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[140], 868*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr12 << 16); 869*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[142], 870*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr14 << 16); 871*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[145], 872*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr22 << 16); 873*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[154], 874*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr12 << 16); 875*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[156], 876*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr14 << 16); 877*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[159], 878*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr22 << 16); 879*613038bcSCaesar Wang } 880*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[179], 0xfff << 8, 881*613038bcSCaesar Wang pdram_timing->tzqinit << 8); 882*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[180], 883*613038bcSCaesar Wang (pdram_timing->tzqcs << 16) | 884*613038bcSCaesar Wang (pdram_timing->tzqinit / 2)); 885*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[181], 886*613038bcSCaesar Wang (pdram_timing->tzqlat << 16) | pdram_timing->tzqcal); 887*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[212], 0xff << 8, 888*613038bcSCaesar Wang pdram_timing->todton << 8); 889*613038bcSCaesar Wang 890*613038bcSCaesar Wang if (timing_config->odt) { 891*613038bcSCaesar Wang setbits_32(&rk3399_ddr_pctl[i]->denali_ctl[213], 892*613038bcSCaesar Wang 1 << 16); 893*613038bcSCaesar Wang if (timing_config->freq < 400) 894*613038bcSCaesar Wang tmp = 4 << 24; 895*613038bcSCaesar Wang else 896*613038bcSCaesar Wang tmp = 8 << 24; 897*613038bcSCaesar Wang } else { 898*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pctl[i]->denali_ctl[213], 899*613038bcSCaesar Wang 1 << 16); 900*613038bcSCaesar Wang tmp = 2 << 24; 901*613038bcSCaesar Wang } 902*613038bcSCaesar Wang 903*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[216], 904*613038bcSCaesar Wang 0x1f << 24, tmp); 905*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[221], 906*613038bcSCaesar Wang (0x3 << 16) | (0xf << 8), 907*613038bcSCaesar Wang (pdram_timing->tdqsck << 16) | 908*613038bcSCaesar Wang (pdram_timing->tdqsck_max << 8)); 909*613038bcSCaesar Wang tmp = 910*613038bcSCaesar Wang (get_wrlat_adj(timing_config->dram_type, pdram_timing->cwl) 911*613038bcSCaesar Wang << 8) | get_rdlat_adj(timing_config->dram_type, 912*613038bcSCaesar Wang pdram_timing->cl); 913*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[284], 0xffff, 914*613038bcSCaesar Wang tmp); 915*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[82], 0xffff << 16, 916*613038bcSCaesar Wang (4 * pdram_timing->trefi) << 16); 917*613038bcSCaesar Wang 918*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[83], 0xffff, 919*613038bcSCaesar Wang (2 * pdram_timing->trefi) & 0xffff); 920*613038bcSCaesar Wang 921*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 922*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 923*613038bcSCaesar Wang tmp = get_pi_wrlat(pdram_timing, timing_config); 924*613038bcSCaesar Wang tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 925*613038bcSCaesar Wang tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 926*613038bcSCaesar Wang } else { 927*613038bcSCaesar Wang tmp = 0; 928*613038bcSCaesar Wang } 929*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[214], 0x3f << 16, 930*613038bcSCaesar Wang (tmp & 0x3f) << 16); 931*613038bcSCaesar Wang 932*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 933*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 934*613038bcSCaesar Wang /* min_rl_preamble= cl+TDQSCK_MIN-1 */ 935*613038bcSCaesar Wang tmp = pdram_timing->cl + 936*613038bcSCaesar Wang get_pi_todtoff_min(pdram_timing, timing_config) - 1; 937*613038bcSCaesar Wang /* todtoff_max */ 938*613038bcSCaesar Wang tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 939*613038bcSCaesar Wang tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 940*613038bcSCaesar Wang } else { 941*613038bcSCaesar Wang tmp = pdram_timing->cl - pdram_timing->cwl; 942*613038bcSCaesar Wang } 943*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[215], 0x3f << 8, 944*613038bcSCaesar Wang (tmp & 0x3f) << 8); 945*613038bcSCaesar Wang 946*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[275], 0xff << 16, 947*613038bcSCaesar Wang (get_pi_tdfi_phy_rdlat 948*613038bcSCaesar Wang (pdram_timing, timing_config) 949*613038bcSCaesar Wang & 0xff) << 16); 950*613038bcSCaesar Wang 951*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[277], 0xffff, 952*613038bcSCaesar Wang (2 * pdram_timing->trefi) & 0xffff); 953*613038bcSCaesar Wang 954*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[282], 0xffff, 955*613038bcSCaesar Wang (2 * pdram_timing->trefi) & 0xffff); 956*613038bcSCaesar Wang 957*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[283], 958*613038bcSCaesar Wang 20 * pdram_timing->trefi); 959*613038bcSCaesar Wang 960*613038bcSCaesar Wang /* CTL_308 TDFI_CALVL_CAPTURE_F0:RW:16:10 */ 961*613038bcSCaesar Wang tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 962*613038bcSCaesar Wang if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 963*613038bcSCaesar Wang tmp1++; 964*613038bcSCaesar Wang tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 965*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[308], 0x3ff << 16, 966*613038bcSCaesar Wang tmp << 16); 967*613038bcSCaesar Wang 968*613038bcSCaesar Wang /* CTL_308 TDFI_CALVL_CC_F0:RW:0:10 */ 969*613038bcSCaesar Wang tmp = tmp + 18; 970*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[308], 0x3ff, 971*613038bcSCaesar Wang tmp); 972*613038bcSCaesar Wang 973*613038bcSCaesar Wang /* CTL_314 TDFI_WRCSLAT_F0:RW:8:8 */ 974*613038bcSCaesar Wang tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); 975*613038bcSCaesar Wang if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) { 976*613038bcSCaesar Wang if (tmp1 < 5) { 977*613038bcSCaesar Wang if (tmp1 == 0) 978*613038bcSCaesar Wang tmp = 0; 979*613038bcSCaesar Wang else 980*613038bcSCaesar Wang tmp = tmp1 - 1; 981*613038bcSCaesar Wang } else { 982*613038bcSCaesar Wang tmp = tmp1 - 5; 983*613038bcSCaesar Wang } 984*613038bcSCaesar Wang } else { 985*613038bcSCaesar Wang tmp = tmp1 - 2; 986*613038bcSCaesar Wang } 987*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[314], 0xff << 8, 988*613038bcSCaesar Wang tmp << 8); 989*613038bcSCaesar Wang 990*613038bcSCaesar Wang /* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */ 991*613038bcSCaesar Wang if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) && 992*613038bcSCaesar Wang (pdram_timing->cl >= 5)) 993*613038bcSCaesar Wang tmp = pdram_timing->cl - 5; 994*613038bcSCaesar Wang else 995*613038bcSCaesar Wang tmp = pdram_timing->cl - 2; 996*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[314], 0xff, 997*613038bcSCaesar Wang tmp); 998*613038bcSCaesar Wang } 999*613038bcSCaesar Wang } 1000*613038bcSCaesar Wang 1001*613038bcSCaesar Wang static void gen_rk3399_ctl_params_f1(struct timing_related_config 1002*613038bcSCaesar Wang *timing_config, 1003*613038bcSCaesar Wang struct dram_timing_t *pdram_timing) 1004*613038bcSCaesar Wang { 1005*613038bcSCaesar Wang uint32_t i; 1006*613038bcSCaesar Wang uint32_t tmp, tmp1; 1007*613038bcSCaesar Wang 1008*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1009*613038bcSCaesar Wang if (timing_config->dram_type == DDR3) { 1010*613038bcSCaesar Wang tmp = 1011*613038bcSCaesar Wang ((700000 + 10) * timing_config->freq + 1012*613038bcSCaesar Wang 999) / 1000; 1013*613038bcSCaesar Wang tmp += 1014*613038bcSCaesar Wang pdram_timing->txsnr + (pdram_timing->tmrd * 3) + 1015*613038bcSCaesar Wang pdram_timing->tmod + pdram_timing->tzqinit; 1016*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[9], tmp); 1017*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[22], 1018*613038bcSCaesar Wang 0xffff << 16, pdram_timing->tdllk << 16); 1019*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[34], 1020*613038bcSCaesar Wang 0xffffff00, 1021*613038bcSCaesar Wang (pdram_timing->tmod << 24) | 1022*613038bcSCaesar Wang (pdram_timing->tmrd << 16) | 1023*613038bcSCaesar Wang (pdram_timing->trtp << 8)); 1024*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[60], 1025*613038bcSCaesar Wang 0xffff << 16, 1026*613038bcSCaesar Wang (pdram_timing->txsr - 1027*613038bcSCaesar Wang pdram_timing->trcd) << 16); 1028*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR4) { 1029*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[9], 1030*613038bcSCaesar Wang pdram_timing->tinit1 + pdram_timing->tinit3); 1031*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[34], 1032*613038bcSCaesar Wang 0xffffff00, 1033*613038bcSCaesar Wang (pdram_timing->tmrd << 24) | 1034*613038bcSCaesar Wang (pdram_timing->tmrd << 16) | 1035*613038bcSCaesar Wang (pdram_timing->trtp << 8)); 1036*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[60], 1037*613038bcSCaesar Wang 0xffff << 16, pdram_timing->txsr << 16); 1038*613038bcSCaesar Wang } else { 1039*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[9], 1040*613038bcSCaesar Wang pdram_timing->tinit1); 1041*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[11], 1042*613038bcSCaesar Wang pdram_timing->tinit4); 1043*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[34], 1044*613038bcSCaesar Wang 0xffffff00, 1045*613038bcSCaesar Wang (pdram_timing->tmrd << 24) | 1046*613038bcSCaesar Wang (pdram_timing->tmrd << 16) | 1047*613038bcSCaesar Wang (pdram_timing->trtp << 8)); 1048*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[60], 1049*613038bcSCaesar Wang 0xffff << 16, pdram_timing->txsr << 16); 1050*613038bcSCaesar Wang } 1051*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[10], 1052*613038bcSCaesar Wang pdram_timing->tinit3); 1053*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[12], 1054*613038bcSCaesar Wang pdram_timing->tinit5); 1055*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[24], (0x7f << 8), 1056*613038bcSCaesar Wang ((pdram_timing->cl * 2) << 8)); 1057*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[24], (0x1f << 16), 1058*613038bcSCaesar Wang (pdram_timing->cwl << 16)); 1059*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[24], 0x3f << 24, 1060*613038bcSCaesar Wang pdram_timing->al << 24); 1061*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[28], 0xffffff00, 1062*613038bcSCaesar Wang (pdram_timing->tras_min << 24) | 1063*613038bcSCaesar Wang (pdram_timing->trc << 16) | 1064*613038bcSCaesar Wang (pdram_timing->trrd << 8)); 1065*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[29], 0xffffff, 1066*613038bcSCaesar Wang (pdram_timing->tfaw << 16) | 1067*613038bcSCaesar Wang (pdram_timing->trppb << 8) | pdram_timing->twtr); 1068*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[35], 1069*613038bcSCaesar Wang (pdram_timing->tcke << 24) | pdram_timing->tras_max); 1070*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[36], 0xff, 1071*613038bcSCaesar Wang max(1, pdram_timing->tckesr)); 1072*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[39], 1073*613038bcSCaesar Wang (0xff << 24), (pdram_timing->trcd << 24)); 1074*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[40], 1075*613038bcSCaesar Wang 0x3f, pdram_timing->twr); 1076*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[42], 0x1f << 24, 1077*613038bcSCaesar Wang pdram_timing->tmrz << 24); 1078*613038bcSCaesar Wang tmp = pdram_timing->tdal ? pdram_timing->tdal : 1079*613038bcSCaesar Wang (pdram_timing->twr + pdram_timing->trp); 1080*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[44], 0xff << 8, 1081*613038bcSCaesar Wang tmp << 8); 1082*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[45], 0xff << 8, 1083*613038bcSCaesar Wang pdram_timing->trp << 8); 1084*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[49], 1085*613038bcSCaesar Wang ((pdram_timing->trefi - 8) << 16) | 1086*613038bcSCaesar Wang pdram_timing->trfc); 1087*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[52], 0xffff << 16, 1088*613038bcSCaesar Wang pdram_timing->txp << 16); 1089*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[54], 0xffff, 1090*613038bcSCaesar Wang pdram_timing->txpdll); 1091*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[55], 0xff << 8, 1092*613038bcSCaesar Wang pdram_timing->tmrri << 8); 1093*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[57], 1094*613038bcSCaesar Wang (pdram_timing->tmrwckel << 24) | 1095*613038bcSCaesar Wang (pdram_timing->tckehcs << 16) | 1096*613038bcSCaesar Wang (pdram_timing->tckelcs << 8) | pdram_timing->tcscke); 1097*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[58], 0xf, 1098*613038bcSCaesar Wang pdram_timing->tzqcke); 1099*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[61], 0xffff, 1100*613038bcSCaesar Wang pdram_timing->txsnr); 1101*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[64], 0xffff << 16, 1102*613038bcSCaesar Wang (pdram_timing->tckehcmd << 24) | 1103*613038bcSCaesar Wang (pdram_timing->tckelcmd << 16)); 1104*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[65], 1105*613038bcSCaesar Wang (pdram_timing->tckelpd << 24) | 1106*613038bcSCaesar Wang (pdram_timing->tescke << 16) | 1107*613038bcSCaesar Wang (pdram_timing->tsr << 8) | pdram_timing->tckckel); 1108*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[66], 0xfff, 1109*613038bcSCaesar Wang (pdram_timing->tcmdcke << 8) | 1110*613038bcSCaesar Wang pdram_timing->tcsckeh); 1111*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[92], (0xff << 24), 1112*613038bcSCaesar Wang (pdram_timing->tcksre << 24)); 1113*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[93], 0xff, 1114*613038bcSCaesar Wang pdram_timing->tcksrx); 1115*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[108], (0x1 << 25), 1116*613038bcSCaesar Wang (timing_config->dllbp << 25)); 1117*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[125], 1118*613038bcSCaesar Wang (pdram_timing->tvrcg_disable << 16) | 1119*613038bcSCaesar Wang pdram_timing->tvrcg_enable); 1120*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[126], 1121*613038bcSCaesar Wang (pdram_timing->tckfspx << 24) | 1122*613038bcSCaesar Wang (pdram_timing->tckfspe << 16) | 1123*613038bcSCaesar Wang pdram_timing->tfc_long); 1124*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[127], 0xffff, 1125*613038bcSCaesar Wang pdram_timing->tvref_long); 1126*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[134], 1127*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr[0] << 16); 1128*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[135], 1129*613038bcSCaesar Wang (pdram_timing->mr[2] << 16) | pdram_timing->mr[1]); 1130*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[138], 1131*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr[3] << 16); 1132*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[140], 0xff, 1133*613038bcSCaesar Wang pdram_timing->mr11); 1134*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[148], 1135*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr[0] << 16); 1136*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[149], 1137*613038bcSCaesar Wang (pdram_timing->mr[2] << 16) | pdram_timing->mr[1]); 1138*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[152], 1139*613038bcSCaesar Wang 0xffff << 16, pdram_timing->mr[3] << 16); 1140*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[154], 0xff, 1141*613038bcSCaesar Wang pdram_timing->mr11); 1142*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR4) { 1143*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[141], 1144*613038bcSCaesar Wang 0xffff, pdram_timing->mr12); 1145*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[143], 1146*613038bcSCaesar Wang 0xffff, pdram_timing->mr14); 1147*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[146], 1148*613038bcSCaesar Wang 0xffff, pdram_timing->mr22); 1149*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[155], 1150*613038bcSCaesar Wang 0xffff, pdram_timing->mr12); 1151*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[157], 1152*613038bcSCaesar Wang 0xffff, pdram_timing->mr14); 1153*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[160], 1154*613038bcSCaesar Wang 0xffff, pdram_timing->mr22); 1155*613038bcSCaesar Wang } 1156*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[182], 1157*613038bcSCaesar Wang ((pdram_timing->tzqinit / 2) << 16) | 1158*613038bcSCaesar Wang pdram_timing->tzqinit); 1159*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[183], 1160*613038bcSCaesar Wang (pdram_timing->tzqcal << 16) | pdram_timing->tzqcs); 1161*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[184], 0x3f, 1162*613038bcSCaesar Wang pdram_timing->tzqlat); 1163*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[188], 0xfff, 1164*613038bcSCaesar Wang pdram_timing->tzqreset); 1165*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[212], 0xff << 16, 1166*613038bcSCaesar Wang pdram_timing->todton << 16); 1167*613038bcSCaesar Wang 1168*613038bcSCaesar Wang if (timing_config->odt) { 1169*613038bcSCaesar Wang setbits_32(&rk3399_ddr_pctl[i]->denali_ctl[213], 1170*613038bcSCaesar Wang (1 << 24)); 1171*613038bcSCaesar Wang if (timing_config->freq < 400) 1172*613038bcSCaesar Wang tmp = 4 << 24; 1173*613038bcSCaesar Wang else 1174*613038bcSCaesar Wang tmp = 8 << 24; 1175*613038bcSCaesar Wang } else { 1176*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pctl[i]->denali_ctl[213], 1177*613038bcSCaesar Wang (1 << 24)); 1178*613038bcSCaesar Wang tmp = 2 << 24; 1179*613038bcSCaesar Wang } 1180*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[217], 0x1f << 24, 1181*613038bcSCaesar Wang tmp); 1182*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[221], 0xf << 24, 1183*613038bcSCaesar Wang (pdram_timing->tdqsck_max << 24)); 1184*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[222], 0x3, 1185*613038bcSCaesar Wang pdram_timing->tdqsck); 1186*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[291], 0xffff, 1187*613038bcSCaesar Wang (get_wrlat_adj(timing_config->dram_type, 1188*613038bcSCaesar Wang pdram_timing->cwl) << 8) | 1189*613038bcSCaesar Wang get_rdlat_adj(timing_config->dram_type, 1190*613038bcSCaesar Wang pdram_timing->cl)); 1191*613038bcSCaesar Wang 1192*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[84], 0xffff, 1193*613038bcSCaesar Wang (4 * pdram_timing->trefi) & 0xffff); 1194*613038bcSCaesar Wang 1195*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[84], 0xffff << 16, 1196*613038bcSCaesar Wang ((2 * pdram_timing->trefi) & 0xffff) << 16); 1197*613038bcSCaesar Wang 1198*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 1199*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 1200*613038bcSCaesar Wang tmp = get_pi_wrlat(pdram_timing, timing_config); 1201*613038bcSCaesar Wang tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 1202*613038bcSCaesar Wang tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 1203*613038bcSCaesar Wang } else { 1204*613038bcSCaesar Wang tmp = 0; 1205*613038bcSCaesar Wang } 1206*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[214], 0x3f << 24, 1207*613038bcSCaesar Wang (tmp & 0x3f) << 24); 1208*613038bcSCaesar Wang 1209*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 1210*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 1211*613038bcSCaesar Wang /* min_rl_preamble= cl+TDQSCK_MIN-1 */ 1212*613038bcSCaesar Wang tmp = pdram_timing->cl + 1213*613038bcSCaesar Wang get_pi_todtoff_min(pdram_timing, timing_config) - 1; 1214*613038bcSCaesar Wang /* todtoff_max */ 1215*613038bcSCaesar Wang tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 1216*613038bcSCaesar Wang tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 1217*613038bcSCaesar Wang } else { 1218*613038bcSCaesar Wang tmp = pdram_timing->cl - pdram_timing->cwl; 1219*613038bcSCaesar Wang } 1220*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[215], 0x3f << 16, 1221*613038bcSCaesar Wang (tmp & 0x3f) << 16); 1222*613038bcSCaesar Wang 1223*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[275], 0xff << 24, 1224*613038bcSCaesar Wang (get_pi_tdfi_phy_rdlat 1225*613038bcSCaesar Wang (pdram_timing, timing_config) 1226*613038bcSCaesar Wang & 0xff) << 24); 1227*613038bcSCaesar Wang 1228*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[284], 1229*613038bcSCaesar Wang 0xffff << 16, 1230*613038bcSCaesar Wang ((2 * pdram_timing->trefi) & 0xffff) << 16); 1231*613038bcSCaesar Wang 1232*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[289], 0xffff, 1233*613038bcSCaesar Wang (2 * pdram_timing->trefi) & 0xffff); 1234*613038bcSCaesar Wang 1235*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[290], 1236*613038bcSCaesar Wang 20 * pdram_timing->trefi); 1237*613038bcSCaesar Wang 1238*613038bcSCaesar Wang /* CTL_309 TDFI_CALVL_CAPTURE_F1:RW:16:10 */ 1239*613038bcSCaesar Wang tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 1240*613038bcSCaesar Wang if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 1241*613038bcSCaesar Wang tmp1++; 1242*613038bcSCaesar Wang tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 1243*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[309], 0x3ff << 16, 1244*613038bcSCaesar Wang tmp << 16); 1245*613038bcSCaesar Wang 1246*613038bcSCaesar Wang /* CTL_309 TDFI_CALVL_CC_F1:RW:0:10 */ 1247*613038bcSCaesar Wang tmp = tmp + 18; 1248*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[309], 0x3ff, 1249*613038bcSCaesar Wang tmp); 1250*613038bcSCaesar Wang 1251*613038bcSCaesar Wang /* CTL_314 TDFI_WRCSLAT_F1:RW:24:8 */ 1252*613038bcSCaesar Wang tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); 1253*613038bcSCaesar Wang if (timing_config->freq <= ENPER_CS_TRAINING_FREQ) { 1254*613038bcSCaesar Wang if (tmp1 < 5) { 1255*613038bcSCaesar Wang if (tmp1 == 0) 1256*613038bcSCaesar Wang tmp = 0; 1257*613038bcSCaesar Wang else 1258*613038bcSCaesar Wang tmp = tmp1 - 1; 1259*613038bcSCaesar Wang } else { 1260*613038bcSCaesar Wang tmp = tmp1 - 5; 1261*613038bcSCaesar Wang } 1262*613038bcSCaesar Wang } else { 1263*613038bcSCaesar Wang tmp = tmp1 - 2; 1264*613038bcSCaesar Wang } 1265*613038bcSCaesar Wang 1266*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[314], 0xff << 24, 1267*613038bcSCaesar Wang tmp << 24); 1268*613038bcSCaesar Wang 1269*613038bcSCaesar Wang /* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */ 1270*613038bcSCaesar Wang if ((timing_config->freq <= ENPER_CS_TRAINING_FREQ) && 1271*613038bcSCaesar Wang (pdram_timing->cl >= 5)) 1272*613038bcSCaesar Wang tmp = pdram_timing->cl - 5; 1273*613038bcSCaesar Wang else 1274*613038bcSCaesar Wang tmp = pdram_timing->cl - 2; 1275*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[314], 0xff << 16, 1276*613038bcSCaesar Wang tmp << 16); 1277*613038bcSCaesar Wang } 1278*613038bcSCaesar Wang } 1279*613038bcSCaesar Wang 1280*613038bcSCaesar Wang static void gen_rk3399_ctl_params(struct timing_related_config *timing_config, 1281*613038bcSCaesar Wang struct dram_timing_t *pdram_timing, 1282*613038bcSCaesar Wang uint32_t fn) 1283*613038bcSCaesar Wang { 1284*613038bcSCaesar Wang if (fn == 0) 1285*613038bcSCaesar Wang gen_rk3399_ctl_params_f0(timing_config, pdram_timing); 1286*613038bcSCaesar Wang else 1287*613038bcSCaesar Wang gen_rk3399_ctl_params_f1(timing_config, pdram_timing); 1288*613038bcSCaesar Wang 1289*613038bcSCaesar Wang #if CTL_TRAINING 1290*613038bcSCaesar Wang uint32_t i, tmp0, tmp1; 1291*613038bcSCaesar Wang 1292*613038bcSCaesar Wang tmp0 = tmp1 = 0; 1293*613038bcSCaesar Wang #if EN_READ_GATE_TRAINING 1294*613038bcSCaesar Wang tmp1 = 1; 1295*613038bcSCaesar Wang #endif 1296*613038bcSCaesar Wang 1297*613038bcSCaesar Wang #if EN_CA_TRAINING 1298*613038bcSCaesar Wang tmp0 |= (1 << 8); 1299*613038bcSCaesar Wang #endif 1300*613038bcSCaesar Wang 1301*613038bcSCaesar Wang #if EN_WRITE_LEVELING 1302*613038bcSCaesar Wang tmp0 |= (1 << 16); 1303*613038bcSCaesar Wang #endif 1304*613038bcSCaesar Wang 1305*613038bcSCaesar Wang #if EN_READ_LEVELING 1306*613038bcSCaesar Wang tmp0 |= (1 << 24); 1307*613038bcSCaesar Wang #endif 1308*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1309*613038bcSCaesar Wang if (tmp0 | tmp1) 1310*613038bcSCaesar Wang setbits_32(&rk3399_ddr_pctl[i]->denali_ctl[305], 1311*613038bcSCaesar Wang 1 << 16); 1312*613038bcSCaesar Wang if (tmp0) 1313*613038bcSCaesar Wang setbits_32(&rk3399_ddr_pctl[i]->denali_ctl[70], tmp0); 1314*613038bcSCaesar Wang if (tmp1) 1315*613038bcSCaesar Wang setbits_32(&rk3399_ddr_pctl[i]->denali_ctl[71], tmp1); 1316*613038bcSCaesar Wang } 1317*613038bcSCaesar Wang #endif 1318*613038bcSCaesar Wang } 1319*613038bcSCaesar Wang 1320*613038bcSCaesar Wang static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config, 1321*613038bcSCaesar Wang struct dram_timing_t *pdram_timing) 1322*613038bcSCaesar Wang { 1323*613038bcSCaesar Wang uint32_t tmp, tmp1, tmp2; 1324*613038bcSCaesar Wang uint32_t i; 1325*613038bcSCaesar Wang 1326*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1327*613038bcSCaesar Wang /* PI_02 PI_TDFI_PHYMSTR_MAX_F0:RW:0:32 */ 1328*613038bcSCaesar Wang tmp = 4 * pdram_timing->trefi; 1329*613038bcSCaesar Wang write_32(&rk3399_ddr_pi[i]->denali_pi[2], tmp); 1330*613038bcSCaesar Wang /* PI_03 PI_TDFI_PHYMSTR_RESP_F0:RW:0:16 */ 1331*613038bcSCaesar Wang tmp = 2 * pdram_timing->trefi; 1332*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[3], 0xffff, tmp); 1333*613038bcSCaesar Wang /* PI_07 PI_TDFI_PHYUPD_RESP_F0:RW:16:16 */ 1334*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[7], 0xffff << 16, 1335*613038bcSCaesar Wang tmp << 16); 1336*613038bcSCaesar Wang 1337*613038bcSCaesar Wang /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F0:RW:0:8 */ 1338*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR4) 1339*613038bcSCaesar Wang tmp = 2; 1340*613038bcSCaesar Wang else 1341*613038bcSCaesar Wang tmp = 0; 1342*613038bcSCaesar Wang tmp = (pdram_timing->bl / 2) + 4 + 1343*613038bcSCaesar Wang (get_pi_rdlat_adj(pdram_timing) - 2) + tmp + 1344*613038bcSCaesar Wang get_pi_tdfi_phy_rdlat(pdram_timing, timing_config); 1345*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[42], 0xff, tmp); 1346*613038bcSCaesar Wang /* PI_43 PI_WRLAT_F0:RW:0:5 */ 1347*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) { 1348*613038bcSCaesar Wang tmp = get_pi_wrlat(pdram_timing, timing_config); 1349*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[43], 0x1f, 1350*613038bcSCaesar Wang tmp); 1351*613038bcSCaesar Wang } 1352*613038bcSCaesar Wang /* PI_43 PI_ADDITIVE_LAT_F0:RW:8:6 */ 1353*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[43], 0x3f << 8, 1354*613038bcSCaesar Wang PI_ADD_LATENCY << 8); 1355*613038bcSCaesar Wang 1356*613038bcSCaesar Wang /* PI_43 PI_CASLAT_LIN_F0:RW:16:7 */ 1357*613038bcSCaesar Wang tmp = pdram_timing->cl * 2; 1358*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[43], 0x7f << 16, 1359*613038bcSCaesar Wang tmp << 16); 1360*613038bcSCaesar Wang /* PI_46 PI_TREF_F0:RW:16:16 */ 1361*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[46], 0xffff << 16, 1362*613038bcSCaesar Wang pdram_timing->trefi << 16); 1363*613038bcSCaesar Wang /* PI_46 PI_TRFC_F0:RW:0:10 */ 1364*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[46], 0x3ff, 1365*613038bcSCaesar Wang pdram_timing->trfc); 1366*613038bcSCaesar Wang /* PI_66 PI_TODTL_2CMD_F0:RW:24:8 */ 1367*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) { 1368*613038bcSCaesar Wang tmp = get_pi_todtoff_max(pdram_timing, timing_config); 1369*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[66], 1370*613038bcSCaesar Wang 0xff << 24, tmp << 24); 1371*613038bcSCaesar Wang } 1372*613038bcSCaesar Wang /* PI_72 PI_WR_TO_ODTH_F0:RW:16:6 */ 1373*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 1374*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 1375*613038bcSCaesar Wang tmp1 = get_pi_wrlat(pdram_timing, timing_config); 1376*613038bcSCaesar Wang tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1377*613038bcSCaesar Wang if (tmp1 > tmp2) 1378*613038bcSCaesar Wang tmp = tmp1 - tmp2; 1379*613038bcSCaesar Wang else 1380*613038bcSCaesar Wang tmp = 0; 1381*613038bcSCaesar Wang } else if (timing_config->dram_type == DDR3) { 1382*613038bcSCaesar Wang tmp = 0; 1383*613038bcSCaesar Wang } 1384*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[72], 0x3f << 16, 1385*613038bcSCaesar Wang tmp << 16); 1386*613038bcSCaesar Wang /* PI_73 PI_RD_TO_ODTH_F0:RW:8:6 */ 1387*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) || 1388*613038bcSCaesar Wang (timing_config->dram_type == LPDDR4)) { 1389*613038bcSCaesar Wang /* min_rl_preamble= cl+TDQSCK_MIN-1 */ 1390*613038bcSCaesar Wang tmp1 = pdram_timing->cl + 1391*613038bcSCaesar Wang get_pi_todtoff_min(pdram_timing, timing_config) - 1; 1392*613038bcSCaesar Wang /* todtoff_max */ 1393*613038bcSCaesar Wang tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1394*613038bcSCaesar Wang if (tmp1 > tmp2) 1395*613038bcSCaesar Wang tmp = tmp1 - tmp2; 1396*613038bcSCaesar Wang else 1397*613038bcSCaesar Wang tmp = 0; 1398*613038bcSCaesar Wang } else if (timing_config->dram_type == DDR3) { 1399*613038bcSCaesar Wang tmp = pdram_timing->cl - pdram_timing->cwl; 1400*613038bcSCaesar Wang } 1401*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[73], 0x3f << 8, 1402*613038bcSCaesar Wang tmp << 8); 1403*613038bcSCaesar Wang /* PI_89 PI_RDLAT_ADJ_F0:RW:16:8 */ 1404*613038bcSCaesar Wang tmp = get_pi_rdlat_adj(pdram_timing); 1405*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[89], 0xff << 16, 1406*613038bcSCaesar Wang tmp << 16); 1407*613038bcSCaesar Wang /* PI_90 PI_WRLAT_ADJ_F0:RW:16:8 */ 1408*613038bcSCaesar Wang tmp = get_pi_wrlat_adj(pdram_timing, timing_config); 1409*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[90], 0xff << 16, 1410*613038bcSCaesar Wang tmp << 16); 1411*613038bcSCaesar Wang /* PI_91 PI_TDFI_WRCSLAT_F0:RW:16:8 */ 1412*613038bcSCaesar Wang tmp1 = tmp; 1413*613038bcSCaesar Wang if (tmp1 < 5) { 1414*613038bcSCaesar Wang if (tmp1 == 0) 1415*613038bcSCaesar Wang tmp = 0; 1416*613038bcSCaesar Wang else 1417*613038bcSCaesar Wang tmp = tmp1 - 1; 1418*613038bcSCaesar Wang } else { 1419*613038bcSCaesar Wang tmp = tmp1 - 5; 1420*613038bcSCaesar Wang } 1421*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[91], 0xff << 16, 1422*613038bcSCaesar Wang tmp << 16); 1423*613038bcSCaesar Wang /* PI_95 PI_TDFI_CALVL_CAPTURE_F0:RW:16:10 */ 1424*613038bcSCaesar Wang tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 1425*613038bcSCaesar Wang if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 1426*613038bcSCaesar Wang tmp1++; 1427*613038bcSCaesar Wang tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 1428*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[95], 0x3ff << 16, 1429*613038bcSCaesar Wang tmp << 16); 1430*613038bcSCaesar Wang /* PI_95 PI_TDFI_CALVL_CC_F0:RW:0:10 */ 1431*613038bcSCaesar Wang tmp = tmp + 18; 1432*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[95], 0x3ff, tmp); 1433*613038bcSCaesar Wang /* PI_102 PI_TMRZ_F0:RW:8:5 */ 1434*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[102], 0x1f << 8, 1435*613038bcSCaesar Wang pdram_timing->tmrz << 8); 1436*613038bcSCaesar Wang /* PI_111 PI_TDFI_CALVL_STROBE_F0:RW:8:4 */ 1437*613038bcSCaesar Wang tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz); 1438*613038bcSCaesar Wang if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0) 1439*613038bcSCaesar Wang tmp1++; 1440*613038bcSCaesar Wang /* pi_tdfi_calvl_strobe=tds_train+5 */ 1441*613038bcSCaesar Wang tmp = tmp1 + 5; 1442*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[111], 0xf << 8, 1443*613038bcSCaesar Wang tmp << 8); 1444*613038bcSCaesar Wang /* PI_116 PI_TCKEHDQS_F0:RW:16:6 */ 1445*613038bcSCaesar Wang tmp = 10000 / (1000000 / pdram_timing->mhz); 1446*613038bcSCaesar Wang if ((10000 % (1000000 / pdram_timing->mhz)) != 0) 1447*613038bcSCaesar Wang tmp++; 1448*613038bcSCaesar Wang if (pdram_timing->mhz <= 100) 1449*613038bcSCaesar Wang tmp = tmp + 1; 1450*613038bcSCaesar Wang else 1451*613038bcSCaesar Wang tmp = tmp + 8; 1452*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[116], 0x3f << 16, 1453*613038bcSCaesar Wang tmp << 16); 1454*613038bcSCaesar Wang /* PI_125 PI_MR1_DATA_F0_0:RW+:8:16 */ 1455*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[125], 0xffff << 8, 1456*613038bcSCaesar Wang pdram_timing->mr[1] << 8); 1457*613038bcSCaesar Wang /* PI_133 PI_MR1_DATA_F0_1:RW+:0:16 */ 1458*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[133], 0xffff, 1459*613038bcSCaesar Wang pdram_timing->mr[1]); 1460*613038bcSCaesar Wang /* PI_140 PI_MR1_DATA_F0_2:RW+:16:16 */ 1461*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[140], 0xffff << 16, 1462*613038bcSCaesar Wang pdram_timing->mr[1] << 16); 1463*613038bcSCaesar Wang /* PI_148 PI_MR1_DATA_F0_3:RW+:0:16 */ 1464*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[148], 0xffff, 1465*613038bcSCaesar Wang pdram_timing->mr[1]); 1466*613038bcSCaesar Wang /* PI_126 PI_MR2_DATA_F0_0:RW+:0:16 */ 1467*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[126], 0xffff, 1468*613038bcSCaesar Wang pdram_timing->mr[2]); 1469*613038bcSCaesar Wang /* PI_133 PI_MR2_DATA_F0_1:RW+:16:16 */ 1470*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[133], 0xffff << 16, 1471*613038bcSCaesar Wang pdram_timing->mr[2] << 16); 1472*613038bcSCaesar Wang /* PI_141 PI_MR2_DATA_F0_2:RW+:0:16 */ 1473*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[141], 0xffff, 1474*613038bcSCaesar Wang pdram_timing->mr[2]); 1475*613038bcSCaesar Wang /* PI_148 PI_MR2_DATA_F0_3:RW+:16:16 */ 1476*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[148], 0xffff << 16, 1477*613038bcSCaesar Wang pdram_timing->mr[2] << 16); 1478*613038bcSCaesar Wang /* PI_156 PI_TFC_F0:RW:0:10 */ 1479*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[156], 0x3ff, 1480*613038bcSCaesar Wang pdram_timing->trfc); 1481*613038bcSCaesar Wang /* PI_158 PI_TWR_F0:RW:24:6 */ 1482*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[158], 0x3f << 24, 1483*613038bcSCaesar Wang pdram_timing->twr << 24); 1484*613038bcSCaesar Wang /* PI_158 PI_TWTR_F0:RW:16:6 */ 1485*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[158], 0x3f << 16, 1486*613038bcSCaesar Wang pdram_timing->twtr << 16); 1487*613038bcSCaesar Wang /* PI_158 PI_TRCD_F0:RW:8:8 */ 1488*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[158], 0xff << 8, 1489*613038bcSCaesar Wang pdram_timing->trcd << 8); 1490*613038bcSCaesar Wang /* PI_158 PI_TRP_F0:RW:0:8 */ 1491*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[158], 0xff, 1492*613038bcSCaesar Wang pdram_timing->trp); 1493*613038bcSCaesar Wang /* PI_157 PI_TRTP_F0:RW:24:8 */ 1494*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[157], 0xff << 24, 1495*613038bcSCaesar Wang pdram_timing->trtp << 24); 1496*613038bcSCaesar Wang /* PI_159 PI_TRAS_MIN_F0:RW:24:8 */ 1497*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[159], 0xff << 24, 1498*613038bcSCaesar Wang pdram_timing->tras_min << 24); 1499*613038bcSCaesar Wang /* PI_159 PI_TRAS_MAX_F0:RW:0:17 */ 1500*613038bcSCaesar Wang tmp = pdram_timing->tras_max * 99 / 100; 1501*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[159], 0x1ffff, tmp); 1502*613038bcSCaesar Wang /* PI_160 PI_TMRD_F0:RW:16:6 */ 1503*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[160], 0x3f << 16, 1504*613038bcSCaesar Wang pdram_timing->tmrd << 16); 1505*613038bcSCaesar Wang /*PI_160 PI_TDQSCK_MAX_F0:RW:0:4 */ 1506*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[160], 0xf, 1507*613038bcSCaesar Wang pdram_timing->tdqsck_max); 1508*613038bcSCaesar Wang /* PI_187 PI_TDFI_CTRLUPD_MAX_F0:RW:8:16 */ 1509*613038bcSCaesar Wang tmp = 2 * pdram_timing->trefi; 1510*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[187], 0xffff << 8, 1511*613038bcSCaesar Wang tmp << 8); 1512*613038bcSCaesar Wang /* PI_188 PI_TDFI_CTRLUPD_INTERVAL_F0:RW:0:32 */ 1513*613038bcSCaesar Wang tmp = 20 * pdram_timing->trefi; 1514*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[188], 0xffffffff, 1515*613038bcSCaesar Wang tmp); 1516*613038bcSCaesar Wang } 1517*613038bcSCaesar Wang } 1518*613038bcSCaesar Wang 1519*613038bcSCaesar Wang static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config, 1520*613038bcSCaesar Wang struct dram_timing_t *pdram_timing) 1521*613038bcSCaesar Wang { 1522*613038bcSCaesar Wang uint32_t tmp, tmp1, tmp2; 1523*613038bcSCaesar Wang uint32_t i; 1524*613038bcSCaesar Wang 1525*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1526*613038bcSCaesar Wang /* PI_04 PI_TDFI_PHYMSTR_MAX_F1:RW:0:32 */ 1527*613038bcSCaesar Wang tmp = 4 * pdram_timing->trefi; 1528*613038bcSCaesar Wang write_32(&rk3399_ddr_pi[i]->denali_pi[4], tmp); 1529*613038bcSCaesar Wang /* PI_05 PI_TDFI_PHYMSTR_RESP_F1:RW:0:16 */ 1530*613038bcSCaesar Wang tmp = 2 * pdram_timing->trefi; 1531*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[5], 0xffff, tmp); 1532*613038bcSCaesar Wang /* PI_12 PI_TDFI_PHYUPD_RESP_F1:RW:0:16 */ 1533*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[12], 0xffff, tmp); 1534*613038bcSCaesar Wang 1535*613038bcSCaesar Wang /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F1:RW:8:8 */ 1536*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR4) 1537*613038bcSCaesar Wang tmp = 2; 1538*613038bcSCaesar Wang else 1539*613038bcSCaesar Wang tmp = 0; 1540*613038bcSCaesar Wang tmp = (pdram_timing->bl / 2) + 4 + 1541*613038bcSCaesar Wang (get_pi_rdlat_adj(pdram_timing) - 2) + tmp + 1542*613038bcSCaesar Wang get_pi_tdfi_phy_rdlat(pdram_timing, timing_config); 1543*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[42], 0xff << 8, 1544*613038bcSCaesar Wang tmp << 8); 1545*613038bcSCaesar Wang /* PI_43 PI_WRLAT_F1:RW:24:5 */ 1546*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) { 1547*613038bcSCaesar Wang tmp = get_pi_wrlat(pdram_timing, timing_config); 1548*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[43], 1549*613038bcSCaesar Wang 0x1f << 24, tmp << 24); 1550*613038bcSCaesar Wang } 1551*613038bcSCaesar Wang /* PI_44 PI_ADDITIVE_LAT_F1:RW:0:6 */ 1552*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[44], 0x3f, 1553*613038bcSCaesar Wang PI_ADD_LATENCY); 1554*613038bcSCaesar Wang /* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */ 1555*613038bcSCaesar Wang tmp = pdram_timing->cl * 2; 1556*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[44], 0x7f << 8, 1557*613038bcSCaesar Wang tmp << 8); 1558*613038bcSCaesar Wang /* PI_47 PI_TREF_F1:RW:16:16 */ 1559*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[47], 0xffff << 16, 1560*613038bcSCaesar Wang pdram_timing->trefi << 16); 1561*613038bcSCaesar Wang /* PI_47 PI_TRFC_F1:RW:0:10 */ 1562*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[47], 0x3ff, 1563*613038bcSCaesar Wang pdram_timing->trfc); 1564*613038bcSCaesar Wang /* PI_67 PI_TODTL_2CMD_F1:RW:8:8 */ 1565*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR3) { 1566*613038bcSCaesar Wang tmp = get_pi_todtoff_max(pdram_timing, timing_config); 1567*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[67], 1568*613038bcSCaesar Wang 0xff << 8, tmp << 8); 1569*613038bcSCaesar Wang } 1570*613038bcSCaesar Wang /* PI_72 PI_WR_TO_ODTH_F1:RW:24:6 */ 1571*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) 1572*613038bcSCaesar Wang || (timing_config->dram_type == LPDDR4)) { 1573*613038bcSCaesar Wang tmp1 = get_pi_wrlat(pdram_timing, timing_config); 1574*613038bcSCaesar Wang tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1575*613038bcSCaesar Wang if (tmp1 > tmp2) 1576*613038bcSCaesar Wang tmp = tmp1 - tmp2; 1577*613038bcSCaesar Wang else 1578*613038bcSCaesar Wang tmp = 0; 1579*613038bcSCaesar Wang } else if (timing_config->dram_type == DDR3) { 1580*613038bcSCaesar Wang tmp = 0; 1581*613038bcSCaesar Wang } 1582*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[72], 0x3f << 24, 1583*613038bcSCaesar Wang tmp << 24); 1584*613038bcSCaesar Wang /* PI_73 PI_RD_TO_ODTH_F1:RW:16:6 */ 1585*613038bcSCaesar Wang if ((timing_config->dram_type == LPDDR3) 1586*613038bcSCaesar Wang || (timing_config->dram_type == LPDDR4)) { 1587*613038bcSCaesar Wang /* min_rl_preamble= cl+TDQSCK_MIN-1 */ 1588*613038bcSCaesar Wang tmp1 = 1589*613038bcSCaesar Wang pdram_timing->cl + get_pi_todtoff_min(pdram_timing, 1590*613038bcSCaesar Wang timing_config) 1591*613038bcSCaesar Wang - 1; 1592*613038bcSCaesar Wang /* todtoff_max */ 1593*613038bcSCaesar Wang tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1594*613038bcSCaesar Wang if (tmp1 > tmp2) 1595*613038bcSCaesar Wang tmp = tmp1 - tmp2; 1596*613038bcSCaesar Wang else 1597*613038bcSCaesar Wang tmp = 0; 1598*613038bcSCaesar Wang } else if (timing_config->dram_type == DDR3) { 1599*613038bcSCaesar Wang tmp = pdram_timing->cl - pdram_timing->cwl; 1600*613038bcSCaesar Wang } 1601*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[73], 0x3f << 16, 1602*613038bcSCaesar Wang tmp << 16); 1603*613038bcSCaesar Wang /*P I_89 PI_RDLAT_ADJ_F1:RW:24:8 */ 1604*613038bcSCaesar Wang tmp = get_pi_rdlat_adj(pdram_timing); 1605*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[89], 0xff << 24, 1606*613038bcSCaesar Wang tmp << 24); 1607*613038bcSCaesar Wang /* PI_90 PI_WRLAT_ADJ_F1:RW:24:8 */ 1608*613038bcSCaesar Wang tmp = get_pi_wrlat_adj(pdram_timing, timing_config); 1609*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[90], 0xff << 24, 1610*613038bcSCaesar Wang tmp << 24); 1611*613038bcSCaesar Wang /* PI_91 PI_TDFI_WRCSLAT_F1:RW:24:8 */ 1612*613038bcSCaesar Wang tmp1 = tmp; 1613*613038bcSCaesar Wang if (tmp1 < 5) { 1614*613038bcSCaesar Wang if (tmp1 == 0) 1615*613038bcSCaesar Wang tmp = 0; 1616*613038bcSCaesar Wang else 1617*613038bcSCaesar Wang tmp = tmp1 - 1; 1618*613038bcSCaesar Wang } else { 1619*613038bcSCaesar Wang tmp = tmp1 - 5; 1620*613038bcSCaesar Wang } 1621*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[91], 0xff << 24, 1622*613038bcSCaesar Wang tmp << 24); 1623*613038bcSCaesar Wang /*PI_96 PI_TDFI_CALVL_CAPTURE_F1:RW:16:10 */ 1624*613038bcSCaesar Wang /* tadr=20ns */ 1625*613038bcSCaesar Wang tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 1626*613038bcSCaesar Wang if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 1627*613038bcSCaesar Wang tmp1++; 1628*613038bcSCaesar Wang tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 1629*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[96], 0x3ff << 16, 1630*613038bcSCaesar Wang tmp << 16); 1631*613038bcSCaesar Wang /* PI_96 PI_TDFI_CALVL_CC_F1:RW:0:10 */ 1632*613038bcSCaesar Wang tmp = tmp + 18; 1633*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[96], 0x3ff, tmp); 1634*613038bcSCaesar Wang /*PI_103 PI_TMRZ_F1:RW:0:5 */ 1635*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[103], 0x1f, 1636*613038bcSCaesar Wang pdram_timing->tmrz); 1637*613038bcSCaesar Wang /*PI_111 PI_TDFI_CALVL_STROBE_F1:RW:16:4 */ 1638*613038bcSCaesar Wang /* tds_train=ceil(2/ns) */ 1639*613038bcSCaesar Wang tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz); 1640*613038bcSCaesar Wang if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0) 1641*613038bcSCaesar Wang tmp1++; 1642*613038bcSCaesar Wang /* pi_tdfi_calvl_strobe=tds_train+5 */ 1643*613038bcSCaesar Wang tmp = tmp1 + 5; 1644*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[111], 0xf << 16, 1645*613038bcSCaesar Wang tmp << 16); 1646*613038bcSCaesar Wang /* PI_116 PI_TCKEHDQS_F1:RW:24:6 */ 1647*613038bcSCaesar Wang tmp = 10000 / (1000000 / pdram_timing->mhz); 1648*613038bcSCaesar Wang if ((10000 % (1000000 / pdram_timing->mhz)) != 0) 1649*613038bcSCaesar Wang tmp++; 1650*613038bcSCaesar Wang if (pdram_timing->mhz <= 100) 1651*613038bcSCaesar Wang tmp = tmp + 1; 1652*613038bcSCaesar Wang else 1653*613038bcSCaesar Wang tmp = tmp + 8; 1654*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[116], 0x3f << 24, 1655*613038bcSCaesar Wang tmp << 24); 1656*613038bcSCaesar Wang /* PI_128 PI_MR1_DATA_F1_0:RW+:0:16 */ 1657*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[128], 0xffff, 1658*613038bcSCaesar Wang pdram_timing->mr[1]); 1659*613038bcSCaesar Wang /* PI_135 PI_MR1_DATA_F1_1:RW+:8:16 */ 1660*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[135], 0xffff << 8, 1661*613038bcSCaesar Wang pdram_timing->mr[1] << 8); 1662*613038bcSCaesar Wang /* PI_143 PI_MR1_DATA_F1_2:RW+:0:16 */ 1663*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[143], 0xffff, 1664*613038bcSCaesar Wang pdram_timing->mr[1]); 1665*613038bcSCaesar Wang /* PI_150 PI_MR1_DATA_F1_3:RW+:8:16 */ 1666*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[150], 0xffff << 8, 1667*613038bcSCaesar Wang pdram_timing->mr[1] << 8); 1668*613038bcSCaesar Wang /* PI_128 PI_MR2_DATA_F1_0:RW+:16:16 */ 1669*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[128], 0xffff << 16, 1670*613038bcSCaesar Wang pdram_timing->mr[2] << 16); 1671*613038bcSCaesar Wang /* PI_136 PI_MR2_DATA_F1_1:RW+:0:16 */ 1672*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[136], 0xffff, 1673*613038bcSCaesar Wang pdram_timing->mr[2]); 1674*613038bcSCaesar Wang /* PI_143 PI_MR2_DATA_F1_2:RW+:16:16 */ 1675*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[143], 0xffff << 16, 1676*613038bcSCaesar Wang pdram_timing->mr[2] << 16); 1677*613038bcSCaesar Wang /* PI_151 PI_MR2_DATA_F1_3:RW+:0:16 */ 1678*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[151], 0xffff, 1679*613038bcSCaesar Wang pdram_timing->mr[2]); 1680*613038bcSCaesar Wang /* PI_156 PI_TFC_F1:RW:16:10 */ 1681*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[156], 0x3ff << 16, 1682*613038bcSCaesar Wang pdram_timing->trfc << 16); 1683*613038bcSCaesar Wang /* PI_162 PI_TWR_F1:RW:8:6 */ 1684*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[162], 0x3f << 8, 1685*613038bcSCaesar Wang pdram_timing->twr << 8); 1686*613038bcSCaesar Wang /* PI_162 PI_TWTR_F1:RW:0:6 */ 1687*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[162], 0x3f, 1688*613038bcSCaesar Wang pdram_timing->twtr); 1689*613038bcSCaesar Wang /* PI_161 PI_TRCD_F1:RW:24:8 */ 1690*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[161], 0xff << 24, 1691*613038bcSCaesar Wang pdram_timing->trcd << 24); 1692*613038bcSCaesar Wang /* PI_161 PI_TRP_F1:RW:16:8 */ 1693*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[161], 0xff << 16, 1694*613038bcSCaesar Wang pdram_timing->trp << 16); 1695*613038bcSCaesar Wang /* PI_161 PI_TRTP_F1:RW:8:8 */ 1696*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[161], 0xff << 8, 1697*613038bcSCaesar Wang pdram_timing->trtp << 8); 1698*613038bcSCaesar Wang /* PI_163 PI_TRAS_MIN_F1:RW:24:8 */ 1699*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[163], 0xff << 24, 1700*613038bcSCaesar Wang pdram_timing->tras_min << 24); 1701*613038bcSCaesar Wang /* PI_163 PI_TRAS_MAX_F1:RW:0:17 */ 1702*613038bcSCaesar Wang tmp = pdram_timing->tras_max * 99 / 100; 1703*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[163], 0x1ffff, tmp); 1704*613038bcSCaesar Wang /* PI_164 PI_TMRD_F1:RW:16:6 */ 1705*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[164], 0x3f << 16, 1706*613038bcSCaesar Wang pdram_timing->tmrd << 16); 1707*613038bcSCaesar Wang /* PI_164 PI_TDQSCK_MAX_F1:RW:0:4 */ 1708*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[164], 0xf, 1709*613038bcSCaesar Wang pdram_timing->tdqsck_max); 1710*613038bcSCaesar Wang /* PI_189 PI_TDFI_CTRLUPD_MAX_F1:RW:0:16 */ 1711*613038bcSCaesar Wang tmp = 2 * pdram_timing->trefi; 1712*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[189], 0xffff, tmp); 1713*613038bcSCaesar Wang /* PI_190 PI_TDFI_CTRLUPD_INTERVAL_F1:RW:0:32 */ 1714*613038bcSCaesar Wang tmp = 20 * pdram_timing->trefi; 1715*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[190], 0xffffffff, 1716*613038bcSCaesar Wang tmp); 1717*613038bcSCaesar Wang } 1718*613038bcSCaesar Wang } 1719*613038bcSCaesar Wang 1720*613038bcSCaesar Wang static void gen_rk3399_pi_params(struct timing_related_config *timing_config, 1721*613038bcSCaesar Wang struct dram_timing_t *pdram_timing, 1722*613038bcSCaesar Wang uint32_t fn) 1723*613038bcSCaesar Wang { 1724*613038bcSCaesar Wang if (fn == 0) 1725*613038bcSCaesar Wang gen_rk3399_pi_params_f0(timing_config, pdram_timing); 1726*613038bcSCaesar Wang else 1727*613038bcSCaesar Wang gen_rk3399_pi_params_f1(timing_config, pdram_timing); 1728*613038bcSCaesar Wang 1729*613038bcSCaesar Wang #if PI_TRAINING 1730*613038bcSCaesar Wang uint32_t i; 1731*613038bcSCaesar Wang 1732*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1733*613038bcSCaesar Wang #if EN_READ_GATE_TRAINING 1734*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[80], 3 << 24, 1735*613038bcSCaesar Wang 2 << 24); 1736*613038bcSCaesar Wang #endif 1737*613038bcSCaesar Wang 1738*613038bcSCaesar Wang #if EN_CA_TRAINING 1739*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[100], 3 << 8, 1740*613038bcSCaesar Wang 2 << 8); 1741*613038bcSCaesar Wang #endif 1742*613038bcSCaesar Wang 1743*613038bcSCaesar Wang #if EN_WRITE_LEVELING 1744*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[60], 3 << 8, 1745*613038bcSCaesar Wang 2 << 8); 1746*613038bcSCaesar Wang #endif 1747*613038bcSCaesar Wang 1748*613038bcSCaesar Wang #if EN_READ_LEVELING 1749*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[80], 3 << 16, 1750*613038bcSCaesar Wang 2 << 16); 1751*613038bcSCaesar Wang #endif 1752*613038bcSCaesar Wang 1753*613038bcSCaesar Wang #if EN_WDQ_LEVELING 1754*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pi[i]->denali_pi[124], 3 << 16, 1755*613038bcSCaesar Wang 2 << 16); 1756*613038bcSCaesar Wang #endif 1757*613038bcSCaesar Wang } 1758*613038bcSCaesar Wang #endif 1759*613038bcSCaesar Wang } 1760*613038bcSCaesar Wang 1761*613038bcSCaesar Wang static void gen_rk3399_set_odt(uint32_t odt_en) 1762*613038bcSCaesar Wang { 1763*613038bcSCaesar Wang uint32_t drv_odt_val; 1764*613038bcSCaesar Wang uint32_t i; 1765*613038bcSCaesar Wang 1766*613038bcSCaesar Wang for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) { 1767*613038bcSCaesar Wang drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 16; 1768*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[5], 1769*613038bcSCaesar Wang 0x7 << 16, drv_odt_val); 1770*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[133], 1771*613038bcSCaesar Wang 0x7 << 16, drv_odt_val); 1772*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[261], 1773*613038bcSCaesar Wang 0x7 << 16, drv_odt_val); 1774*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[389], 1775*613038bcSCaesar Wang 0x7 << 16, drv_odt_val); 1776*613038bcSCaesar Wang drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 24; 1777*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[6], 1778*613038bcSCaesar Wang 0x7 << 24, drv_odt_val); 1779*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[134], 1780*613038bcSCaesar Wang 0x7 << 24, drv_odt_val); 1781*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[262], 1782*613038bcSCaesar Wang 0x7 << 24, drv_odt_val); 1783*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[390], 1784*613038bcSCaesar Wang 0x7 << 24, drv_odt_val); 1785*613038bcSCaesar Wang } 1786*613038bcSCaesar Wang } 1787*613038bcSCaesar Wang 1788*613038bcSCaesar Wang static void gen_rk3399_set_ds_odt(struct timing_related_config *timing_config, 1789*613038bcSCaesar Wang struct drv_odt_lp_config *drv_config) 1790*613038bcSCaesar Wang { 1791*613038bcSCaesar Wang uint32_t i, drv_odt_val; 1792*613038bcSCaesar Wang 1793*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1794*613038bcSCaesar Wang if (timing_config->dram_type == LPDDR4) 1795*613038bcSCaesar Wang drv_odt_val = drv_config->phy_side_odt | 1796*613038bcSCaesar Wang (PHY_DRV_ODT_Hi_Z << 4) | 1797*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 8) | 1798*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 12); 1799*613038bcSCaesar Wang else if (timing_config->dram_type == LPDDR3) 1800*613038bcSCaesar Wang drv_odt_val = PHY_DRV_ODT_Hi_Z | 1801*613038bcSCaesar Wang (drv_config->phy_side_odt << 4) | 1802*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 8) | 1803*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 12); 1804*613038bcSCaesar Wang else 1805*613038bcSCaesar Wang drv_odt_val = drv_config->phy_side_odt | 1806*613038bcSCaesar Wang (drv_config->phy_side_odt << 4) | 1807*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 8) | 1808*613038bcSCaesar Wang (drv_config->phy_side_dq_drv << 12); 1809*613038bcSCaesar Wang 1810*613038bcSCaesar Wang /* DQ drv odt set */ 1811*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[6], 0xffffff, 1812*613038bcSCaesar Wang drv_odt_val); 1813*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[134], 0xffffff, 1814*613038bcSCaesar Wang drv_odt_val); 1815*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[262], 0xffffff, 1816*613038bcSCaesar Wang drv_odt_val); 1817*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[390], 0xffffff, 1818*613038bcSCaesar Wang drv_odt_val); 1819*613038bcSCaesar Wang /* DQS drv odt set */ 1820*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[7], 0xffffff, 1821*613038bcSCaesar Wang drv_odt_val); 1822*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[135], 0xffffff, 1823*613038bcSCaesar Wang drv_odt_val); 1824*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[263], 0xffffff, 1825*613038bcSCaesar Wang drv_odt_val); 1826*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[391], 0xffffff, 1827*613038bcSCaesar Wang drv_odt_val); 1828*613038bcSCaesar Wang 1829*613038bcSCaesar Wang gen_rk3399_set_odt(timing_config->odt); 1830*613038bcSCaesar Wang 1831*613038bcSCaesar Wang /* CA drv set */ 1832*613038bcSCaesar Wang drv_odt_val = drv_config->phy_side_ca_drv | 1833*613038bcSCaesar Wang (drv_config->phy_side_ca_drv << 4); 1834*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[544], 0xff, 1835*613038bcSCaesar Wang drv_odt_val); 1836*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[672], 0xff, 1837*613038bcSCaesar Wang drv_odt_val); 1838*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[800], 0xff, 1839*613038bcSCaesar Wang drv_odt_val); 1840*613038bcSCaesar Wang 1841*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[928], 0xff, 1842*613038bcSCaesar Wang drv_odt_val); 1843*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[937], 0xff, 1844*613038bcSCaesar Wang drv_odt_val); 1845*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[935], 0xff, 1846*613038bcSCaesar Wang drv_odt_val); 1847*613038bcSCaesar Wang 1848*613038bcSCaesar Wang drv_odt_val = drv_config->phy_side_ck_cs_drv | 1849*613038bcSCaesar Wang (drv_config->phy_side_ck_cs_drv << 4); 1850*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[929], 0xff, 1851*613038bcSCaesar Wang drv_odt_val); 1852*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[939], 0xff, 1853*613038bcSCaesar Wang drv_odt_val); 1854*613038bcSCaesar Wang } 1855*613038bcSCaesar Wang } 1856*613038bcSCaesar Wang 1857*613038bcSCaesar Wang static void gen_rk3399_phy_params(struct timing_related_config *timing_config, 1858*613038bcSCaesar Wang struct drv_odt_lp_config *drv_config, 1859*613038bcSCaesar Wang struct dram_timing_t *pdram_timing, 1860*613038bcSCaesar Wang uint32_t fn) 1861*613038bcSCaesar Wang { 1862*613038bcSCaesar Wang uint32_t tmp, i, div, j; 1863*613038bcSCaesar Wang uint32_t mem_delay_ps, pad_delay_ps, total_delay_ps, delay_frac_ps; 1864*613038bcSCaesar Wang uint32_t trpre_min_ps, gate_delay_ps, gate_delay_frac_ps; 1865*613038bcSCaesar Wang uint32_t ie_enable, tsel_enable, cas_lat, rddata_en_ie_dly, tsel_adder; 1866*613038bcSCaesar Wang uint32_t extra_adder, delta, hs_offset; 1867*613038bcSCaesar Wang 1868*613038bcSCaesar Wang for (i = 0; i < timing_config->ch_cnt; i++) { 1869*613038bcSCaesar Wang 1870*613038bcSCaesar Wang pad_delay_ps = PI_PAD_DELAY_PS_VALUE; 1871*613038bcSCaesar Wang ie_enable = PI_IE_ENABLE_VALUE; 1872*613038bcSCaesar Wang tsel_enable = PI_TSEL_ENABLE_VALUE; 1873*613038bcSCaesar Wang 1874*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[896], 1875*613038bcSCaesar Wang (0x3 << 8) | 1, fn << 8); 1876*613038bcSCaesar Wang 1877*613038bcSCaesar Wang /* PHY_LOW_FREQ_SEL */ 1878*613038bcSCaesar Wang /* DENALI_PHY_913 1bit offset_0 */ 1879*613038bcSCaesar Wang if (timing_config->freq > 400) 1880*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_publ[i]->denali_phy[913], 1); 1881*613038bcSCaesar Wang else 1882*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[913], 1); 1883*613038bcSCaesar Wang 1884*613038bcSCaesar Wang /* PHY_RPTR_UPDATE_x */ 1885*613038bcSCaesar Wang /* DENALI_PHY_87/215/343/471 4bit offset_16 */ 1886*613038bcSCaesar Wang tmp = 2500 / (1000000 / pdram_timing->mhz) + 3; 1887*613038bcSCaesar Wang if ((2500 % (1000000 / pdram_timing->mhz)) != 0) 1888*613038bcSCaesar Wang tmp++; 1889*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[87], 0xf << 16, 1890*613038bcSCaesar Wang tmp << 16); 1891*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[215], 0xf << 16, 1892*613038bcSCaesar Wang tmp << 16); 1893*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[343], 0xf << 16, 1894*613038bcSCaesar Wang tmp << 16); 1895*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[471], 0xf << 16, 1896*613038bcSCaesar Wang tmp << 16); 1897*613038bcSCaesar Wang 1898*613038bcSCaesar Wang /* PHY_PLL_CTRL */ 1899*613038bcSCaesar Wang /* DENALI_PHY_911 13bits offset_0 */ 1900*613038bcSCaesar Wang /* PHY_LP4_BOOT_PLL_CTRL */ 1901*613038bcSCaesar Wang /* DENALI_PHY_919 13bits offset_0 */ 1902*613038bcSCaesar Wang if (pdram_timing->mhz <= 150) 1903*613038bcSCaesar Wang tmp = 3; 1904*613038bcSCaesar Wang else if (pdram_timing->mhz <= 300) 1905*613038bcSCaesar Wang tmp = 2; 1906*613038bcSCaesar Wang else if (pdram_timing->mhz <= 600) 1907*613038bcSCaesar Wang tmp = 1; 1908*613038bcSCaesar Wang else 1909*613038bcSCaesar Wang tmp = 0; 1910*613038bcSCaesar Wang tmp = (1 << 12) | (tmp << 9) | (2 << 7) | (1 << 1); 1911*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[911], 0x1fff, 1912*613038bcSCaesar Wang tmp); 1913*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[919], 0x1fff, 1914*613038bcSCaesar Wang tmp); 1915*613038bcSCaesar Wang 1916*613038bcSCaesar Wang /* PHY_PLL_CTRL_CA */ 1917*613038bcSCaesar Wang /* DENALI_PHY_911 13bits offset_16 */ 1918*613038bcSCaesar Wang /* PHY_LP4_BOOT_PLL_CTRL_CA */ 1919*613038bcSCaesar Wang /* DENALI_PHY_919 13bits offset_16 */ 1920*613038bcSCaesar Wang if (pdram_timing->mhz <= 150) 1921*613038bcSCaesar Wang tmp = 3; 1922*613038bcSCaesar Wang else if (pdram_timing->mhz <= 300) 1923*613038bcSCaesar Wang tmp = 2; 1924*613038bcSCaesar Wang else if (pdram_timing->mhz <= 600) 1925*613038bcSCaesar Wang tmp = 1; 1926*613038bcSCaesar Wang else 1927*613038bcSCaesar Wang tmp = 0; 1928*613038bcSCaesar Wang tmp = (tmp << 9) | (2 << 7) | (1 << 5) | (1 << 1); 1929*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[911], 1930*613038bcSCaesar Wang 0x1fff << 16, tmp << 16); 1931*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[919], 1932*613038bcSCaesar Wang 0x1fff << 16, tmp << 16); 1933*613038bcSCaesar Wang 1934*613038bcSCaesar Wang /* PHY_TCKSRE_WAIT */ 1935*613038bcSCaesar Wang /* DENALI_PHY_922 4bits offset_24 */ 1936*613038bcSCaesar Wang if (pdram_timing->mhz <= 400) 1937*613038bcSCaesar Wang tmp = 1; 1938*613038bcSCaesar Wang else if (pdram_timing->mhz <= 800) 1939*613038bcSCaesar Wang tmp = 3; 1940*613038bcSCaesar Wang else if (pdram_timing->mhz <= 1000) 1941*613038bcSCaesar Wang tmp = 4; 1942*613038bcSCaesar Wang else 1943*613038bcSCaesar Wang tmp = 5; 1944*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[922], 0xf << 24, 1945*613038bcSCaesar Wang tmp << 24); 1946*613038bcSCaesar Wang /* PHY_CAL_CLK_SELECT_0:RW8:3 */ 1947*613038bcSCaesar Wang div = pdram_timing->mhz / (2 * 20); 1948*613038bcSCaesar Wang for (j = 2, tmp = 1; j <= 128; j <<= 1, tmp++) { 1949*613038bcSCaesar Wang if (div < j) 1950*613038bcSCaesar Wang break; 1951*613038bcSCaesar Wang } 1952*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[947], 0x7 << 8, 1953*613038bcSCaesar Wang tmp << 8); 1954*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[927], (1 << 22)); 1955*613038bcSCaesar Wang 1956*613038bcSCaesar Wang if (timing_config->dram_type == DDR3) { 1957*613038bcSCaesar Wang mem_delay_ps = 0; 1958*613038bcSCaesar Wang trpre_min_ps = 1000; 1959*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR4) { 1960*613038bcSCaesar Wang mem_delay_ps = 1500; 1961*613038bcSCaesar Wang trpre_min_ps = 900; 1962*613038bcSCaesar Wang } else if (timing_config->dram_type == LPDDR3) { 1963*613038bcSCaesar Wang mem_delay_ps = 2500; 1964*613038bcSCaesar Wang trpre_min_ps = 900; 1965*613038bcSCaesar Wang } else { 1966*613038bcSCaesar Wang ERROR("gen_rk3399_phy_params:dramtype unsupport\n"); 1967*613038bcSCaesar Wang return; 1968*613038bcSCaesar Wang } 1969*613038bcSCaesar Wang total_delay_ps = mem_delay_ps + pad_delay_ps; 1970*613038bcSCaesar Wang delay_frac_ps = 1971*613038bcSCaesar Wang 1000 * total_delay_ps / (1000000 / pdram_timing->mhz); 1972*613038bcSCaesar Wang gate_delay_ps = delay_frac_ps + 1000 - (trpre_min_ps / 2); 1973*613038bcSCaesar Wang gate_delay_frac_ps = 1974*613038bcSCaesar Wang gate_delay_ps - gate_delay_ps / 1000 * 1000; 1975*613038bcSCaesar Wang tmp = gate_delay_frac_ps * 0x200 / 1000; 1976*613038bcSCaesar Wang /* PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY */ 1977*613038bcSCaesar Wang /* DENALI_PHY_2/130/258/386 10bits offset_0 */ 1978*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[2], 0x2ff, tmp); 1979*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[130], 0x2ff, tmp); 1980*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[258], 0x2ff, tmp); 1981*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[386], 0x2ff, tmp); 1982*613038bcSCaesar Wang /* PHY_RDDQS_GATE_SLAVE_DELAY */ 1983*613038bcSCaesar Wang /* DENALI_PHY_77/205/333/461 10bits offset_16 */ 1984*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[77], 0x2ff << 16, 1985*613038bcSCaesar Wang tmp << 16); 1986*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[205], 0x2ff << 16, 1987*613038bcSCaesar Wang tmp << 16); 1988*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[333], 0x2ff << 16, 1989*613038bcSCaesar Wang tmp << 16); 1990*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[461], 0x2ff << 16, 1991*613038bcSCaesar Wang tmp << 16); 1992*613038bcSCaesar Wang 1993*613038bcSCaesar Wang tmp = gate_delay_ps / 1000; 1994*613038bcSCaesar Wang /* PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST */ 1995*613038bcSCaesar Wang /* DENALI_PHY_10/138/266/394 4bit offset_0 */ 1996*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[10], 0xf, tmp); 1997*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[138], 0xf, tmp); 1998*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[266], 0xf, tmp); 1999*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[394], 0xf, tmp); 2000*613038bcSCaesar Wang /* PHY_RDDQS_LATENCY_ADJUST */ 2001*613038bcSCaesar Wang /* DENALI_PHY_78/206/334/462 4bits offset_0 */ 2002*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[78], 0xf, tmp); 2003*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[206], 0xf, tmp); 2004*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[334], 0xf, tmp); 2005*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[462], 0xf, tmp); 2006*613038bcSCaesar Wang /* PHY_GTLVL_LAT_ADJ_START */ 2007*613038bcSCaesar Wang /* DENALI_PHY_80/208/336/464 4bits offset_16 */ 2008*613038bcSCaesar Wang tmp = delay_frac_ps / 1000; 2009*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[80], 0xf << 16, 2010*613038bcSCaesar Wang tmp << 16); 2011*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[208], 0xf << 16, 2012*613038bcSCaesar Wang tmp << 16); 2013*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[336], 0xf << 16, 2014*613038bcSCaesar Wang tmp << 16); 2015*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[464], 0xf << 16, 2016*613038bcSCaesar Wang tmp << 16); 2017*613038bcSCaesar Wang 2018*613038bcSCaesar Wang cas_lat = pdram_timing->cl + PI_ADD_LATENCY; 2019*613038bcSCaesar Wang rddata_en_ie_dly = ie_enable / (1000000 / pdram_timing->mhz); 2020*613038bcSCaesar Wang if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 2021*613038bcSCaesar Wang rddata_en_ie_dly++; 2022*613038bcSCaesar Wang rddata_en_ie_dly = rddata_en_ie_dly - 1; 2023*613038bcSCaesar Wang tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz); 2024*613038bcSCaesar Wang if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0) 2025*613038bcSCaesar Wang tsel_adder++; 2026*613038bcSCaesar Wang if (rddata_en_ie_dly > tsel_adder) 2027*613038bcSCaesar Wang extra_adder = rddata_en_ie_dly - tsel_adder; 2028*613038bcSCaesar Wang else 2029*613038bcSCaesar Wang extra_adder = 0; 2030*613038bcSCaesar Wang delta = cas_lat - rddata_en_ie_dly; 2031*613038bcSCaesar Wang if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 2032*613038bcSCaesar Wang hs_offset = 2; 2033*613038bcSCaesar Wang else 2034*613038bcSCaesar Wang hs_offset = 1; 2035*613038bcSCaesar Wang if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset)) { 2036*613038bcSCaesar Wang tmp = 0; 2037*613038bcSCaesar Wang } else { 2038*613038bcSCaesar Wang if ((delta == 2) || (delta == 1)) 2039*613038bcSCaesar Wang tmp = rddata_en_ie_dly - 0 - extra_adder; 2040*613038bcSCaesar Wang else 2041*613038bcSCaesar Wang tmp = extra_adder; 2042*613038bcSCaesar Wang } 2043*613038bcSCaesar Wang /* PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY */ 2044*613038bcSCaesar Wang /* DENALI_PHY_9/137/265/393 4bit offset_16 */ 2045*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[9], 0xf << 16, 2046*613038bcSCaesar Wang tmp << 16); 2047*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[137], 0xf << 16, 2048*613038bcSCaesar Wang tmp << 16); 2049*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[265], 0xf << 16, 2050*613038bcSCaesar Wang tmp << 16); 2051*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[393], 0xf << 16, 2052*613038bcSCaesar Wang tmp << 16); 2053*613038bcSCaesar Wang /* PHY_RDDATA_EN_TSEL_DLY */ 2054*613038bcSCaesar Wang /* DENALI_PHY_86/214/342/470 4bit offset_0 */ 2055*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[86], 0xf, tmp); 2056*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[214], 0xf, tmp); 2057*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[342], 0xf, tmp); 2058*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[470], 0xf, tmp); 2059*613038bcSCaesar Wang 2060*613038bcSCaesar Wang if (tsel_adder > rddata_en_ie_dly) 2061*613038bcSCaesar Wang extra_adder = tsel_adder - rddata_en_ie_dly; 2062*613038bcSCaesar Wang else 2063*613038bcSCaesar Wang extra_adder = 0; 2064*613038bcSCaesar Wang if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset)) 2065*613038bcSCaesar Wang tmp = tsel_adder; 2066*613038bcSCaesar Wang else 2067*613038bcSCaesar Wang tmp = rddata_en_ie_dly - 0 + extra_adder; 2068*613038bcSCaesar Wang /* PHY_LP4_BOOT_RDDATA_EN_DLY */ 2069*613038bcSCaesar Wang /* DENALI_PHY_9/137/265/393 4bit offset_8 */ 2070*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[9], 0xf << 8, 2071*613038bcSCaesar Wang tmp << 8); 2072*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[137], 0xf << 8, 2073*613038bcSCaesar Wang tmp << 8); 2074*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[265], 0xf << 8, 2075*613038bcSCaesar Wang tmp << 8); 2076*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[393], 0xf << 8, 2077*613038bcSCaesar Wang tmp << 8); 2078*613038bcSCaesar Wang /* PHY_RDDATA_EN_DLY */ 2079*613038bcSCaesar Wang /* DENALI_PHY_85/213/341/469 4bit offset_24 */ 2080*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[85], 0xf << 24, 2081*613038bcSCaesar Wang tmp << 24); 2082*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[213], 0xf << 24, 2083*613038bcSCaesar Wang tmp << 24); 2084*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[341], 0xf << 24, 2085*613038bcSCaesar Wang tmp << 24); 2086*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_publ[i]->denali_phy[469], 0xf << 24, 2087*613038bcSCaesar Wang tmp << 24); 2088*613038bcSCaesar Wang 2089*613038bcSCaesar Wang if (pdram_timing->mhz <= ENPER_CS_TRAINING_FREQ) { 2090*613038bcSCaesar Wang 2091*613038bcSCaesar Wang /* 2092*613038bcSCaesar Wang * Note:Per-CS Training is not compatible at speeds 2093*613038bcSCaesar Wang * under 533 MHz. If the PHY is running at a speed 2094*613038bcSCaesar Wang * less than 533MHz, all phy_per_cs_training_en_X 2095*613038bcSCaesar Wang * parameters must be cleared to 0. 2096*613038bcSCaesar Wang */ 2097*613038bcSCaesar Wang 2098*613038bcSCaesar Wang /*DENALI_PHY_84/212/340/468 1bit offset_16 */ 2099*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_publ[i]->denali_phy[84], 2100*613038bcSCaesar Wang 0x1 << 16); 2101*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_publ[i]->denali_phy[212], 2102*613038bcSCaesar Wang 0x1 << 16); 2103*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_publ[i]->denali_phy[340], 2104*613038bcSCaesar Wang 0x1 << 16); 2105*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_publ[i]->denali_phy[468], 2106*613038bcSCaesar Wang 0x1 << 16); 2107*613038bcSCaesar Wang } else { 2108*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[84], 2109*613038bcSCaesar Wang 0x1 << 16); 2110*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[212], 2111*613038bcSCaesar Wang 0x1 << 16); 2112*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[340], 2113*613038bcSCaesar Wang 0x1 << 16); 2114*613038bcSCaesar Wang setbits_32(&rk3399_ddr_publ[i]->denali_phy[468], 2115*613038bcSCaesar Wang 0x1 << 16); 2116*613038bcSCaesar Wang } 2117*613038bcSCaesar Wang } 2118*613038bcSCaesar Wang } 2119*613038bcSCaesar Wang 2120*613038bcSCaesar Wang static int to_get_clk_index(unsigned int mhz) 2121*613038bcSCaesar Wang { 2122*613038bcSCaesar Wang int pll_cnt, i; 2123*613038bcSCaesar Wang 2124*613038bcSCaesar Wang pll_cnt = ARRAY_SIZE(dpll_rates_table); 2125*613038bcSCaesar Wang 2126*613038bcSCaesar Wang /* Assumming rate_table is in descending order */ 2127*613038bcSCaesar Wang for (i = 0; i < pll_cnt; i++) { 2128*613038bcSCaesar Wang if (mhz >= dpll_rates_table[i].mhz) 2129*613038bcSCaesar Wang break; 2130*613038bcSCaesar Wang } 2131*613038bcSCaesar Wang 2132*613038bcSCaesar Wang /* if mhz lower than lowest frequency in table, use lowest frequency */ 2133*613038bcSCaesar Wang if (i == pll_cnt) 2134*613038bcSCaesar Wang i = pll_cnt - 1; 2135*613038bcSCaesar Wang 2136*613038bcSCaesar Wang return i; 2137*613038bcSCaesar Wang } 2138*613038bcSCaesar Wang 2139*613038bcSCaesar Wang uint32_t rkclk_prepare_pll_timing(unsigned int mhz) 2140*613038bcSCaesar Wang { 2141*613038bcSCaesar Wang unsigned int refdiv, postdiv1, fbdiv, postdiv2; 2142*613038bcSCaesar Wang int index; 2143*613038bcSCaesar Wang 2144*613038bcSCaesar Wang index = to_get_clk_index(mhz); 2145*613038bcSCaesar Wang refdiv = dpll_rates_table[index].refdiv; 2146*613038bcSCaesar Wang fbdiv = dpll_rates_table[index].fbdiv; 2147*613038bcSCaesar Wang postdiv1 = dpll_rates_table[index].postdiv1; 2148*613038bcSCaesar Wang postdiv2 = dpll_rates_table[index].postdiv2; 2149*613038bcSCaesar Wang write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(fbdiv)); 2150*613038bcSCaesar Wang write_32(DCF_PARAM_ADDR + PARAM_DPLL_CON1, POSTDIV2(postdiv2) | 2151*613038bcSCaesar Wang POSTDIV1(postdiv1) | REFDIV(refdiv)); 2152*613038bcSCaesar Wang return (24 * fbdiv) / refdiv / postdiv1 / postdiv2; 2153*613038bcSCaesar Wang } 2154*613038bcSCaesar Wang 2155*613038bcSCaesar Wang uint32_t ddr_get_rate(void) 2156*613038bcSCaesar Wang { 2157*613038bcSCaesar Wang uint32_t refdiv, postdiv1, fbdiv, postdiv2; 2158*613038bcSCaesar Wang 2159*613038bcSCaesar Wang refdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) & 0x3f; 2160*613038bcSCaesar Wang fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff; 2161*613038bcSCaesar Wang postdiv1 = 2162*613038bcSCaesar Wang (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 8) & 0x7; 2163*613038bcSCaesar Wang postdiv2 = 2164*613038bcSCaesar Wang (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 12) & 0x7; 2165*613038bcSCaesar Wang 2166*613038bcSCaesar Wang return (24 / refdiv * fbdiv / postdiv1 / postdiv2) * 1000 * 1000; 2167*613038bcSCaesar Wang } 2168*613038bcSCaesar Wang 2169*613038bcSCaesar Wang /* 2170*613038bcSCaesar Wang * return: bit12: channel 1, external self-refresh 2171*613038bcSCaesar Wang * bit11: channel 1, stdby_mode 2172*613038bcSCaesar Wang * bit10: channel 1, self-refresh with controller and memory clock gate 2173*613038bcSCaesar Wang * bit9: channel 1, self-refresh 2174*613038bcSCaesar Wang * bit8: channel 1, power-down 2175*613038bcSCaesar Wang * 2176*613038bcSCaesar Wang * bit4: channel 1, external self-refresh 2177*613038bcSCaesar Wang * bit3: channel 0, stdby_mode 2178*613038bcSCaesar Wang * bit2: channel 0, self-refresh with controller and memory clock gate 2179*613038bcSCaesar Wang * bit1: channel 0, self-refresh 2180*613038bcSCaesar Wang * bit0: channel 0, power-down 2181*613038bcSCaesar Wang */ 2182*613038bcSCaesar Wang uint32_t exit_low_power(void) 2183*613038bcSCaesar Wang { 2184*613038bcSCaesar Wang struct rk3399_ddr_pctl_regs *ddr_pctl_regs; 2185*613038bcSCaesar Wang uint32_t low_power = 0; 2186*613038bcSCaesar Wang uint32_t channel_mask; 2187*613038bcSCaesar Wang uint32_t channel; 2188*613038bcSCaesar Wang uint32_t tmp; 2189*613038bcSCaesar Wang 2190*613038bcSCaesar Wang channel_mask = (read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) & 0x3; 2191*613038bcSCaesar Wang for (channel = 0; channel < 2; channel++) { 2192*613038bcSCaesar Wang ddr_pctl_regs = rk3399_ddr_pctl[channel]; 2193*613038bcSCaesar Wang if (!(channel_mask & (1 << channel))) 2194*613038bcSCaesar Wang continue; 2195*613038bcSCaesar Wang 2196*613038bcSCaesar Wang /* exit stdby mode */ 2197*613038bcSCaesar Wang write_32(CIC_BASE + CIC_CTRL1, 2198*613038bcSCaesar Wang (1 << (channel + 16)) | (0 << channel)); 2199*613038bcSCaesar Wang /* exit external self-refresh */ 2200*613038bcSCaesar Wang tmp = channel ? 12 : 8; 2201*613038bcSCaesar Wang low_power |= ((read_32(PMU_BASE + PMU_SFT_CON) >> tmp) & 0x1) 2202*613038bcSCaesar Wang << (4 + 8 * channel); 2203*613038bcSCaesar Wang clrbits_32(PMU_BASE + PMU_SFT_CON, 1 << tmp); 2204*613038bcSCaesar Wang while (!(read_32(PMU_BASE + PMU_DDR_SREF_ST) & 2205*613038bcSCaesar Wang (1 << channel))) 2206*613038bcSCaesar Wang ; 2207*613038bcSCaesar Wang /* exit auto low-power */ 2208*613038bcSCaesar Wang clrbits_32(&ddr_pctl_regs->denali_ctl[101], 0x7); 2209*613038bcSCaesar Wang /* lp_cmd to exit */ 2210*613038bcSCaesar Wang if (((read_32(&ddr_pctl_regs->denali_ctl[100]) >> 24) & 2211*613038bcSCaesar Wang 0x7f) != 0x40) { 2212*613038bcSCaesar Wang while (read_32(&ddr_pctl_regs->denali_ctl[200]) & 0x1) 2213*613038bcSCaesar Wang ; 2214*613038bcSCaesar Wang clrsetbits_32(&ddr_pctl_regs->denali_ctl[93], 2215*613038bcSCaesar Wang 0xff << 24, 0x69 << 24); 2216*613038bcSCaesar Wang while (((read_32(&ddr_pctl_regs->denali_ctl[100]) >> 2217*613038bcSCaesar Wang 24) & 0x7f) != 0x40) 2218*613038bcSCaesar Wang ; 2219*613038bcSCaesar Wang } 2220*613038bcSCaesar Wang } 2221*613038bcSCaesar Wang return low_power; 2222*613038bcSCaesar Wang } 2223*613038bcSCaesar Wang 2224*613038bcSCaesar Wang void resume_low_power(uint32_t low_power) 2225*613038bcSCaesar Wang { 2226*613038bcSCaesar Wang struct rk3399_ddr_pctl_regs *ddr_pctl_regs; 2227*613038bcSCaesar Wang uint32_t channel_mask; 2228*613038bcSCaesar Wang uint32_t channel; 2229*613038bcSCaesar Wang uint32_t tmp; 2230*613038bcSCaesar Wang uint32_t val; 2231*613038bcSCaesar Wang 2232*613038bcSCaesar Wang channel_mask = (read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) & 0x3; 2233*613038bcSCaesar Wang for (channel = 0; channel < 2; channel++) { 2234*613038bcSCaesar Wang ddr_pctl_regs = rk3399_ddr_pctl[channel]; 2235*613038bcSCaesar Wang if (!(channel_mask & (1 << channel))) 2236*613038bcSCaesar Wang continue; 2237*613038bcSCaesar Wang 2238*613038bcSCaesar Wang /* resume external self-refresh */ 2239*613038bcSCaesar Wang tmp = channel ? 12 : 8; 2240*613038bcSCaesar Wang val = (low_power >> (4 + 8 * channel)) & 0x1; 2241*613038bcSCaesar Wang setbits_32(PMU_BASE + PMU_SFT_CON, val << tmp); 2242*613038bcSCaesar Wang /* resume auto low-power */ 2243*613038bcSCaesar Wang val = (low_power >> (8 * channel)) & 0x7; 2244*613038bcSCaesar Wang setbits_32(&ddr_pctl_regs->denali_ctl[101], val); 2245*613038bcSCaesar Wang /* resume stdby mode */ 2246*613038bcSCaesar Wang val = (low_power >> (3 + 8 * channel)) & 0x1; 2247*613038bcSCaesar Wang write_32(CIC_BASE + CIC_CTRL1, 2248*613038bcSCaesar Wang (1 << (channel + 16)) | (val << channel)); 2249*613038bcSCaesar Wang } 2250*613038bcSCaesar Wang } 2251*613038bcSCaesar Wang 2252*613038bcSCaesar Wang static void wait_dcf_done(void) 2253*613038bcSCaesar Wang { 2254*613038bcSCaesar Wang while ((read_32(DCF_BASE + DCF_DCF_ISR) & (DCF_DONE)) == 0) 2255*613038bcSCaesar Wang continue; 2256*613038bcSCaesar Wang } 2257*613038bcSCaesar Wang 2258*613038bcSCaesar Wang void clr_dcf_irq(void) 2259*613038bcSCaesar Wang { 2260*613038bcSCaesar Wang /* clear dcf irq status */ 2261*613038bcSCaesar Wang mmio_write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE); 2262*613038bcSCaesar Wang } 2263*613038bcSCaesar Wang 2264*613038bcSCaesar Wang static void enable_dcf(uint32_t dcf_addr) 2265*613038bcSCaesar Wang { 2266*613038bcSCaesar Wang /* config DCF start addr */ 2267*613038bcSCaesar Wang write_32(DCF_BASE + DCF_DCF_ADDR, dcf_addr); 2268*613038bcSCaesar Wang /* wait dcf done */ 2269*613038bcSCaesar Wang while (read_32(DCF_BASE + DCF_DCF_CTRL) & 1) 2270*613038bcSCaesar Wang continue; 2271*613038bcSCaesar Wang /* clear dcf irq status */ 2272*613038bcSCaesar Wang write_32(DCF_BASE + DCF_DCF_ISR, DCF_TIMEOUT | DCF_ERR | DCF_DONE); 2273*613038bcSCaesar Wang /* DCF start */ 2274*613038bcSCaesar Wang setbits_32(DCF_BASE + DCF_DCF_CTRL, DCF_START); 2275*613038bcSCaesar Wang } 2276*613038bcSCaesar Wang 2277*613038bcSCaesar Wang void dcf_code_init(void) 2278*613038bcSCaesar Wang { 2279*613038bcSCaesar Wang memcpy((void *)DCF_START_ADDR, (void *)dcf_code, sizeof(dcf_code)); 2280*613038bcSCaesar Wang /* set dcf master secure */ 2281*613038bcSCaesar Wang write_32(SGRF_BASE + 0xe01c, ((0x3 << 0) << 16) | (0 << 0)); 2282*613038bcSCaesar Wang write_32(DCF_BASE + DCF_DCF_TOSET, 0x80000000); 2283*613038bcSCaesar Wang } 2284*613038bcSCaesar Wang 2285*613038bcSCaesar Wang static void dcf_start(uint32_t freq, uint32_t index) 2286*613038bcSCaesar Wang { 2287*613038bcSCaesar Wang write_32(CRU_BASE + CRU_SOFTRST_CON(10), (0x1 << (1 + 16)) | (1 << 1)); 2288*613038bcSCaesar Wang write_32(CRU_BASE + CRU_SOFTRST_CON(11), (0x1 << (0 + 16)) | (1 << 0)); 2289*613038bcSCaesar Wang write_32(DCF_PARAM_ADDR + PARAM_FREQ_SELECT, index << 4); 2290*613038bcSCaesar Wang 2291*613038bcSCaesar Wang write_32(DCF_PARAM_ADDR + PARAM_DRAM_FREQ, freq); 2292*613038bcSCaesar Wang 2293*613038bcSCaesar Wang rkclk_prepare_pll_timing(freq); 2294*613038bcSCaesar Wang udelay(10); 2295*613038bcSCaesar Wang write_32(CRU_BASE + CRU_SOFTRST_CON(10), (0x1 << (1 + 16)) | (0 << 1)); 2296*613038bcSCaesar Wang write_32(CRU_BASE + CRU_SOFTRST_CON(11), (0x1 << (0 + 16)) | (0 << 0)); 2297*613038bcSCaesar Wang udelay(10); 2298*613038bcSCaesar Wang enable_dcf(DCF_START_ADDR); 2299*613038bcSCaesar Wang } 2300*613038bcSCaesar Wang 2301*613038bcSCaesar Wang static void dram_low_power_config(struct drv_odt_lp_config *lp_config) 2302*613038bcSCaesar Wang { 2303*613038bcSCaesar Wang uint32_t tmp, tmp1, i; 2304*613038bcSCaesar Wang uint32_t ch_cnt = rk3399_dram_status.timing_config.ch_cnt; 2305*613038bcSCaesar Wang uint32_t dram_type = rk3399_dram_status.timing_config.dram_type; 2306*613038bcSCaesar Wang uint32_t *low_power = &rk3399_dram_status.low_power_stat; 2307*613038bcSCaesar Wang 2308*613038bcSCaesar Wang if (dram_type == LPDDR4) 2309*613038bcSCaesar Wang tmp = (lp_config->srpd_lite_idle << 16) | 2310*613038bcSCaesar Wang lp_config->pd_idle; 2311*613038bcSCaesar Wang else 2312*613038bcSCaesar Wang tmp = lp_config->pd_idle; 2313*613038bcSCaesar Wang 2314*613038bcSCaesar Wang if (dram_type == DDR3) 2315*613038bcSCaesar Wang tmp1 = (2 << 16) | (0x7 << 8) | 7; 2316*613038bcSCaesar Wang else 2317*613038bcSCaesar Wang tmp1 = (3 << 16) | (0x7 << 8) | 7; 2318*613038bcSCaesar Wang 2319*613038bcSCaesar Wang *low_power = 0; 2320*613038bcSCaesar Wang 2321*613038bcSCaesar Wang for (i = 0; i < ch_cnt; i++) { 2322*613038bcSCaesar Wang write_32(&rk3399_ddr_pctl[i]->denali_ctl[102], tmp); 2323*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[103], 0xffff, 2324*613038bcSCaesar Wang (lp_config->sr_mc_gate_idle << 8) | 2325*613038bcSCaesar Wang lp_config->sr_idle); 2326*613038bcSCaesar Wang clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[101], 2327*613038bcSCaesar Wang 0x70f0f, tmp1); 2328*613038bcSCaesar Wang *low_power |= (7 << (8 * i)); 2329*613038bcSCaesar Wang } 2330*613038bcSCaesar Wang 2331*613038bcSCaesar Wang /* standby idle */ 2332*613038bcSCaesar Wang write_32(CIC_BASE + CIC_IDLE_TH, lp_config->standby_idle); 2333*613038bcSCaesar Wang write_32(CIC_BASE + CIC_CG_WAIT_TH, 0x640008); 2334*613038bcSCaesar Wang 2335*613038bcSCaesar Wang if (ch_cnt == 2) { 2336*613038bcSCaesar Wang write_32(GRF_BASE + GRF_DDRC1_CON1, 2337*613038bcSCaesar Wang (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) | 2338*613038bcSCaesar Wang ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); 2339*613038bcSCaesar Wang if (lp_config->standby_idle) { 2340*613038bcSCaesar Wang tmp = 0x002a002a; 2341*613038bcSCaesar Wang *low_power |= (1 << 11); 2342*613038bcSCaesar Wang } else { 2343*613038bcSCaesar Wang tmp = 0; 2344*613038bcSCaesar Wang } 2345*613038bcSCaesar Wang write_32(CIC_BASE + CIC_CTRL1, tmp); 2346*613038bcSCaesar Wang } 2347*613038bcSCaesar Wang 2348*613038bcSCaesar Wang write_32(GRF_BASE + GRF_DDRC0_CON1, 2349*613038bcSCaesar Wang (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) | 2350*613038bcSCaesar Wang ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); 2351*613038bcSCaesar Wang if (lp_config->standby_idle) { 2352*613038bcSCaesar Wang tmp = 0x00150015; 2353*613038bcSCaesar Wang *low_power |= (1 << 3); 2354*613038bcSCaesar Wang } else { 2355*613038bcSCaesar Wang tmp = 0; 2356*613038bcSCaesar Wang } 2357*613038bcSCaesar Wang write_32(CIC_BASE + CIC_CTRL1, tmp); 2358*613038bcSCaesar Wang } 2359*613038bcSCaesar Wang 2360*613038bcSCaesar Wang 2361*613038bcSCaesar Wang static void dram_related_init(struct ddr_dts_config_timing *dts_timing) 2362*613038bcSCaesar Wang { 2363*613038bcSCaesar Wang uint32_t trefi0, trefi1; 2364*613038bcSCaesar Wang uint32_t i; 2365*613038bcSCaesar Wang 2366*613038bcSCaesar Wang dcf_code_init(); 2367*613038bcSCaesar Wang 2368*613038bcSCaesar Wang /* get sdram config for os reg */ 2369*613038bcSCaesar Wang drv_odt_lp_cfg_init(sdram_config.dramtype, dts_timing, 2370*613038bcSCaesar Wang &rk3399_dram_status.drv_odt_lp_cfg); 2371*613038bcSCaesar Wang sdram_timing_cfg_init(&rk3399_dram_status.timing_config, 2372*613038bcSCaesar Wang &sdram_config, 2373*613038bcSCaesar Wang &rk3399_dram_status.drv_odt_lp_cfg); 2374*613038bcSCaesar Wang 2375*613038bcSCaesar Wang trefi0 = ((read_32(&rk3399_ddr_pctl[0]->denali_ctl[48]) >> 2376*613038bcSCaesar Wang 16) & 0xffff) + 8; 2377*613038bcSCaesar Wang trefi1 = ((read_32(&rk3399_ddr_pctl[0]->denali_ctl[49]) >> 2378*613038bcSCaesar Wang 16) & 0xffff) + 8; 2379*613038bcSCaesar Wang 2380*613038bcSCaesar Wang rk3399_dram_status.index_freq[0] = trefi0 * 10 / 39; 2381*613038bcSCaesar Wang rk3399_dram_status.index_freq[1] = trefi1 * 10 / 39; 2382*613038bcSCaesar Wang rk3399_dram_status.current_index = 2383*613038bcSCaesar Wang (read_32(&rk3399_ddr_pctl[0]->denali_ctl[111]) 2384*613038bcSCaesar Wang >> 16) & 0x3; 2385*613038bcSCaesar Wang if (rk3399_dram_status.timing_config.dram_type == DDR3) { 2386*613038bcSCaesar Wang rk3399_dram_status.index_freq[0] /= 2; 2387*613038bcSCaesar Wang rk3399_dram_status.index_freq[1] /= 2; 2388*613038bcSCaesar Wang } 2389*613038bcSCaesar Wang rk3399_dram_status.index_freq[(rk3399_dram_status.current_index + 1) 2390*613038bcSCaesar Wang & 0x1] = 0; 2391*613038bcSCaesar Wang 2392*613038bcSCaesar Wang /* disable all training by ctl and pi */ 2393*613038bcSCaesar Wang for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) { 2394*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pctl[i]->denali_ctl[70], (1 << 24) | 2395*613038bcSCaesar Wang (1 << 16) | (1 << 8) | 1); 2396*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pctl[i]->denali_ctl[71], 1); 2397*613038bcSCaesar Wang 2398*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pi[i]->denali_pi[60], 0x3 << 8); 2399*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pi[i]->denali_pi[80], (0x3 << 24) | 2400*613038bcSCaesar Wang (0x3 << 16)); 2401*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pi[i]->denali_pi[100], 0x3 << 8); 2402*613038bcSCaesar Wang clrbits_32(&rk3399_ddr_pi[i]->denali_pi[124], 0x3 << 16); 2403*613038bcSCaesar Wang } 2404*613038bcSCaesar Wang 2405*613038bcSCaesar Wang /* init drv odt */ 2406*613038bcSCaesar Wang if (rk3399_dram_status.index_freq[rk3399_dram_status.current_index] < 2407*613038bcSCaesar Wang rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq) 2408*613038bcSCaesar Wang rk3399_dram_status.timing_config.odt = 0; 2409*613038bcSCaesar Wang else 2410*613038bcSCaesar Wang rk3399_dram_status.timing_config.odt = 1; 2411*613038bcSCaesar Wang gen_rk3399_set_ds_odt(&rk3399_dram_status.timing_config, 2412*613038bcSCaesar Wang &rk3399_dram_status.drv_odt_lp_cfg); 2413*613038bcSCaesar Wang dram_low_power_config(&rk3399_dram_status.drv_odt_lp_cfg); 2414*613038bcSCaesar Wang } 2415*613038bcSCaesar Wang 2416*613038bcSCaesar Wang static uint32_t prepare_ddr_timing(uint32_t mhz) 2417*613038bcSCaesar Wang { 2418*613038bcSCaesar Wang uint32_t index; 2419*613038bcSCaesar Wang struct dram_timing_t dram_timing; 2420*613038bcSCaesar Wang 2421*613038bcSCaesar Wang rk3399_dram_status.timing_config.freq = mhz; 2422*613038bcSCaesar Wang 2423*613038bcSCaesar Wang if (mhz < rk3399_dram_status.drv_odt_lp_cfg.ddr3_dll_dis_freq) 2424*613038bcSCaesar Wang rk3399_dram_status.timing_config.dllbp = 1; 2425*613038bcSCaesar Wang else 2426*613038bcSCaesar Wang rk3399_dram_status.timing_config.dllbp = 0; 2427*613038bcSCaesar Wang if (mhz < rk3399_dram_status.drv_odt_lp_cfg.odt_dis_freq) { 2428*613038bcSCaesar Wang rk3399_dram_status.timing_config.odt = 0; 2429*613038bcSCaesar Wang } else { 2430*613038bcSCaesar Wang rk3399_dram_status.timing_config.odt = 1; 2431*613038bcSCaesar Wang gen_rk3399_set_odt(1); 2432*613038bcSCaesar Wang } 2433*613038bcSCaesar Wang 2434*613038bcSCaesar Wang index = (rk3399_dram_status.current_index + 1) & 0x1; 2435*613038bcSCaesar Wang if (rk3399_dram_status.index_freq[index] == mhz) 2436*613038bcSCaesar Wang goto out; 2437*613038bcSCaesar Wang 2438*613038bcSCaesar Wang /* 2439*613038bcSCaesar Wang * checking if having available gate traiing timing for 2440*613038bcSCaesar Wang * target freq. 2441*613038bcSCaesar Wang */ 2442*613038bcSCaesar Wang dram_get_parameter(&rk3399_dram_status.timing_config, &dram_timing); 2443*613038bcSCaesar Wang gen_rk3399_ctl_params(&rk3399_dram_status.timing_config, 2444*613038bcSCaesar Wang &dram_timing, index); 2445*613038bcSCaesar Wang gen_rk3399_pi_params(&rk3399_dram_status.timing_config, 2446*613038bcSCaesar Wang &dram_timing, index); 2447*613038bcSCaesar Wang gen_rk3399_phy_params(&rk3399_dram_status.timing_config, 2448*613038bcSCaesar Wang &rk3399_dram_status.drv_odt_lp_cfg, 2449*613038bcSCaesar Wang &dram_timing, index); 2450*613038bcSCaesar Wang rk3399_dram_status.index_freq[index] = mhz; 2451*613038bcSCaesar Wang 2452*613038bcSCaesar Wang 2453*613038bcSCaesar Wang out: 2454*613038bcSCaesar Wang return index; 2455*613038bcSCaesar Wang } 2456*613038bcSCaesar Wang 2457*613038bcSCaesar Wang void print_dram_status_info(void) 2458*613038bcSCaesar Wang { 2459*613038bcSCaesar Wang uint32_t *p; 2460*613038bcSCaesar Wang uint32_t i; 2461*613038bcSCaesar Wang 2462*613038bcSCaesar Wang p = (uint32_t *) &rk3399_dram_status.timing_config; 2463*613038bcSCaesar Wang INFO("rk3399_dram_status.timing_config:\n"); 2464*613038bcSCaesar Wang for (i = 0; i < sizeof(struct timing_related_config) / 4; i++) 2465*613038bcSCaesar Wang tf_printf("%u\n", p[i]); 2466*613038bcSCaesar Wang p = (uint32_t *) &rk3399_dram_status.drv_odt_lp_cfg; 2467*613038bcSCaesar Wang INFO("rk3399_dram_status.drv_odt_lp_cfg:\n"); 2468*613038bcSCaesar Wang for (i = 0; i < sizeof(struct drv_odt_lp_config) / 4; i++) 2469*613038bcSCaesar Wang tf_printf("%u\n", p[i]); 2470*613038bcSCaesar Wang } 2471*613038bcSCaesar Wang 2472*613038bcSCaesar Wang uint32_t ddr_set_rate(uint32_t hz) 2473*613038bcSCaesar Wang { 2474*613038bcSCaesar Wang uint32_t low_power, index; 2475*613038bcSCaesar Wang uint32_t mhz = hz / (1000 * 1000); 2476*613038bcSCaesar Wang 2477*613038bcSCaesar Wang if (mhz == 2478*613038bcSCaesar Wang rk3399_dram_status.index_freq[rk3399_dram_status.current_index]) 2479*613038bcSCaesar Wang goto out; 2480*613038bcSCaesar Wang 2481*613038bcSCaesar Wang index = to_get_clk_index(mhz); 2482*613038bcSCaesar Wang mhz = dpll_rates_table[index].mhz; 2483*613038bcSCaesar Wang 2484*613038bcSCaesar Wang low_power = exit_low_power(); 2485*613038bcSCaesar Wang index = prepare_ddr_timing(mhz); 2486*613038bcSCaesar Wang if (index > 1) 2487*613038bcSCaesar Wang goto out; 2488*613038bcSCaesar Wang 2489*613038bcSCaesar Wang dcf_start(mhz, index); 2490*613038bcSCaesar Wang wait_dcf_done(); 2491*613038bcSCaesar Wang if (rk3399_dram_status.timing_config.odt == 0) 2492*613038bcSCaesar Wang gen_rk3399_set_odt(0); 2493*613038bcSCaesar Wang 2494*613038bcSCaesar Wang rk3399_dram_status.current_index = index; 2495*613038bcSCaesar Wang 2496*613038bcSCaesar Wang if (mhz < dts_parameter.auto_pd_dis_freq) 2497*613038bcSCaesar Wang low_power |= rk3399_dram_status.low_power_stat; 2498*613038bcSCaesar Wang 2499*613038bcSCaesar Wang resume_low_power(low_power); 2500*613038bcSCaesar Wang out: 2501*613038bcSCaesar Wang return mhz; 2502*613038bcSCaesar Wang } 2503*613038bcSCaesar Wang 2504*613038bcSCaesar Wang uint32_t ddr_round_rate(uint32_t hz) 2505*613038bcSCaesar Wang { 2506*613038bcSCaesar Wang int index; 2507*613038bcSCaesar Wang uint32_t mhz = hz / (1000 * 1000); 2508*613038bcSCaesar Wang 2509*613038bcSCaesar Wang index = to_get_clk_index(mhz); 2510*613038bcSCaesar Wang 2511*613038bcSCaesar Wang return dpll_rates_table[index].mhz * 1000 * 1000; 2512*613038bcSCaesar Wang } 2513*613038bcSCaesar Wang 2514*613038bcSCaesar Wang uint32_t dts_timing_receive(uint32_t timing, uint32_t index) 2515*613038bcSCaesar Wang { 2516*613038bcSCaesar Wang uint32_t *p = (uint32_t *) &dts_parameter; 2517*613038bcSCaesar Wang static uint32_t receive_nums; 2518*613038bcSCaesar Wang 2519*613038bcSCaesar Wang if (index < (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) { 2520*613038bcSCaesar Wang p[index] = (uint32_t)timing; 2521*613038bcSCaesar Wang receive_nums++; 2522*613038bcSCaesar Wang } else { 2523*613038bcSCaesar Wang dts_parameter.available = 0; 2524*613038bcSCaesar Wang return -1; 2525*613038bcSCaesar Wang } 2526*613038bcSCaesar Wang 2527*613038bcSCaesar Wang /* receive all parameter */ 2528*613038bcSCaesar Wang if (receive_nums == (sizeof(dts_parameter) / sizeof(uint32_t) - 1)) { 2529*613038bcSCaesar Wang dts_parameter.available = 1; 2530*613038bcSCaesar Wang receive_nums = 0; 2531*613038bcSCaesar Wang } 2532*613038bcSCaesar Wang 2533*613038bcSCaesar Wang return index; 2534*613038bcSCaesar Wang } 2535*613038bcSCaesar Wang 2536*613038bcSCaesar Wang void ddr_dfs_init(void) 2537*613038bcSCaesar Wang { 2538*613038bcSCaesar Wang dram_related_init(&dts_parameter); 2539*613038bcSCaesar Wang } 2540