1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <arch_helpers.h> 8*91f16700Schasinglulu #include <common/debug.h> 9*91f16700Schasinglulu #include <drivers/delay_timer.h> 10*91f16700Schasinglulu #include <lib/mmio.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <m0_ctl.h> 13*91f16700Schasinglulu #include <plat_private.h> 14*91f16700Schasinglulu #include "dfs.h" 15*91f16700Schasinglulu #include "dram.h" 16*91f16700Schasinglulu #include "dram_spec_timing.h" 17*91f16700Schasinglulu #include "pmu.h" 18*91f16700Schasinglulu #include "soc.h" 19*91f16700Schasinglulu #include "string.h" 20*91f16700Schasinglulu 21*91f16700Schasinglulu #define ENPER_CS_TRAINING_FREQ (666) 22*91f16700Schasinglulu #define TDFI_LAT_THRESHOLD_FREQ (928) 23*91f16700Schasinglulu #define PHY_DLL_BYPASS_FREQ (260) 24*91f16700Schasinglulu 25*91f16700Schasinglulu static const struct pll_div dpll_rates_table[] = { 26*91f16700Schasinglulu 27*91f16700Schasinglulu /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */ 28*91f16700Schasinglulu {.mhz = 928, .refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1}, 29*91f16700Schasinglulu {.mhz = 800, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1}, 30*91f16700Schasinglulu {.mhz = 732, .refdiv = 1, .fbdiv = 61, .postdiv1 = 2, .postdiv2 = 1}, 31*91f16700Schasinglulu {.mhz = 666, .refdiv = 1, .fbdiv = 111, .postdiv1 = 4, .postdiv2 = 1}, 32*91f16700Schasinglulu {.mhz = 600, .refdiv = 1, .fbdiv = 50, .postdiv1 = 2, .postdiv2 = 1}, 33*91f16700Schasinglulu {.mhz = 528, .refdiv = 1, .fbdiv = 66, .postdiv1 = 3, .postdiv2 = 1}, 34*91f16700Schasinglulu {.mhz = 400, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1}, 35*91f16700Schasinglulu {.mhz = 300, .refdiv = 1, .fbdiv = 50, .postdiv1 = 4, .postdiv2 = 1}, 36*91f16700Schasinglulu {.mhz = 200, .refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 2}, 37*91f16700Schasinglulu }; 38*91f16700Schasinglulu 39*91f16700Schasinglulu struct rk3399_dram_status { 40*91f16700Schasinglulu uint32_t current_index; 41*91f16700Schasinglulu uint32_t index_freq[2]; 42*91f16700Schasinglulu uint32_t boot_freq; 43*91f16700Schasinglulu uint32_t low_power_stat; 44*91f16700Schasinglulu struct timing_related_config timing_config; 45*91f16700Schasinglulu struct drv_odt_lp_config drv_odt_lp_cfg; 46*91f16700Schasinglulu }; 47*91f16700Schasinglulu 48*91f16700Schasinglulu struct rk3399_saved_status { 49*91f16700Schasinglulu uint32_t freq; 50*91f16700Schasinglulu uint32_t low_power_stat; 51*91f16700Schasinglulu uint32_t odt; 52*91f16700Schasinglulu }; 53*91f16700Schasinglulu 54*91f16700Schasinglulu static struct rk3399_dram_status rk3399_dram_status; 55*91f16700Schasinglulu static struct rk3399_saved_status rk3399_suspend_status; 56*91f16700Schasinglulu static uint32_t wrdqs_delay_val[2][2][4]; 57*91f16700Schasinglulu static uint32_t rddqs_delay_ps; 58*91f16700Schasinglulu 59*91f16700Schasinglulu static struct rk3399_sdram_default_config ddr3_default_config = { 60*91f16700Schasinglulu .bl = 8, 61*91f16700Schasinglulu .ap = 0, 62*91f16700Schasinglulu .burst_ref_cnt = 1, 63*91f16700Schasinglulu .zqcsi = 0 64*91f16700Schasinglulu }; 65*91f16700Schasinglulu 66*91f16700Schasinglulu static struct rk3399_sdram_default_config lpddr3_default_config = { 67*91f16700Schasinglulu .bl = 8, 68*91f16700Schasinglulu .ap = 0, 69*91f16700Schasinglulu .burst_ref_cnt = 1, 70*91f16700Schasinglulu .zqcsi = 0 71*91f16700Schasinglulu }; 72*91f16700Schasinglulu 73*91f16700Schasinglulu static struct rk3399_sdram_default_config lpddr4_default_config = { 74*91f16700Schasinglulu .bl = 16, 75*91f16700Schasinglulu .ap = 0, 76*91f16700Schasinglulu .caodt = 240, 77*91f16700Schasinglulu .burst_ref_cnt = 1, 78*91f16700Schasinglulu .zqcsi = 0 79*91f16700Schasinglulu }; 80*91f16700Schasinglulu 81*91f16700Schasinglulu static uint32_t get_cs_die_capability(struct rk3399_sdram_params *ram_config, 82*91f16700Schasinglulu uint8_t channel, uint8_t cs) 83*91f16700Schasinglulu { 84*91f16700Schasinglulu struct rk3399_sdram_channel *ch = &ram_config->ch[channel]; 85*91f16700Schasinglulu uint32_t bandwidth; 86*91f16700Schasinglulu uint32_t die_bandwidth; 87*91f16700Schasinglulu uint32_t die; 88*91f16700Schasinglulu uint32_t cs_cap; 89*91f16700Schasinglulu uint32_t row; 90*91f16700Schasinglulu 91*91f16700Schasinglulu row = cs == 0 ? ch->cs0_row : ch->cs1_row; 92*91f16700Schasinglulu bandwidth = 8 * (1 << ch->bw); 93*91f16700Schasinglulu die_bandwidth = 8 * (1 << ch->dbw); 94*91f16700Schasinglulu die = bandwidth / die_bandwidth; 95*91f16700Schasinglulu cs_cap = (1 << (row + ((1 << ch->bk) / 4 + 1) + ch->col + 96*91f16700Schasinglulu (bandwidth / 16))); 97*91f16700Schasinglulu if (ch->row_3_4) 98*91f16700Schasinglulu cs_cap = cs_cap * 3 / 4; 99*91f16700Schasinglulu 100*91f16700Schasinglulu return (cs_cap / die); 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu static void get_dram_drv_odt_val(uint32_t dram_type, 104*91f16700Schasinglulu struct drv_odt_lp_config *drv_config) 105*91f16700Schasinglulu { 106*91f16700Schasinglulu uint32_t tmp; 107*91f16700Schasinglulu uint32_t mr1_val, mr3_val, mr11_val; 108*91f16700Schasinglulu 109*91f16700Schasinglulu switch (dram_type) { 110*91f16700Schasinglulu case DDR3: 111*91f16700Schasinglulu mr1_val = (mmio_read_32(CTL_REG(0, 133)) >> 16) & 0xffff; 112*91f16700Schasinglulu tmp = ((mr1_val >> 1) & 1) | ((mr1_val >> 4) & 1); 113*91f16700Schasinglulu if (tmp) 114*91f16700Schasinglulu drv_config->dram_side_drv = 34; 115*91f16700Schasinglulu else 116*91f16700Schasinglulu drv_config->dram_side_drv = 40; 117*91f16700Schasinglulu tmp = ((mr1_val >> 2) & 1) | ((mr1_val >> 5) & 1) | 118*91f16700Schasinglulu ((mr1_val >> 7) & 1); 119*91f16700Schasinglulu if (tmp == 0) 120*91f16700Schasinglulu drv_config->dram_side_dq_odt = 0; 121*91f16700Schasinglulu else if (tmp == 1) 122*91f16700Schasinglulu drv_config->dram_side_dq_odt = 60; 123*91f16700Schasinglulu else if (tmp == 3) 124*91f16700Schasinglulu drv_config->dram_side_dq_odt = 40; 125*91f16700Schasinglulu else 126*91f16700Schasinglulu drv_config->dram_side_dq_odt = 120; 127*91f16700Schasinglulu break; 128*91f16700Schasinglulu case LPDDR3: 129*91f16700Schasinglulu mr3_val = mmio_read_32(CTL_REG(0, 138)) & 0xf; 130*91f16700Schasinglulu mr11_val = (mmio_read_32(CTL_REG(0, 139)) >> 24) & 0x3; 131*91f16700Schasinglulu if (mr3_val == 0xb) 132*91f16700Schasinglulu drv_config->dram_side_drv = 3448; 133*91f16700Schasinglulu else if (mr3_val == 0xa) 134*91f16700Schasinglulu drv_config->dram_side_drv = 4048; 135*91f16700Schasinglulu else if (mr3_val == 0x9) 136*91f16700Schasinglulu drv_config->dram_side_drv = 3440; 137*91f16700Schasinglulu else if (mr3_val == 0x4) 138*91f16700Schasinglulu drv_config->dram_side_drv = 60; 139*91f16700Schasinglulu else if (mr3_val == 0x3) 140*91f16700Schasinglulu drv_config->dram_side_drv = 48; 141*91f16700Schasinglulu else if (mr3_val == 0x2) 142*91f16700Schasinglulu drv_config->dram_side_drv = 40; 143*91f16700Schasinglulu else 144*91f16700Schasinglulu drv_config->dram_side_drv = 34; 145*91f16700Schasinglulu 146*91f16700Schasinglulu if (mr11_val == 1) 147*91f16700Schasinglulu drv_config->dram_side_dq_odt = 60; 148*91f16700Schasinglulu else if (mr11_val == 2) 149*91f16700Schasinglulu drv_config->dram_side_dq_odt = 120; 150*91f16700Schasinglulu else if (mr11_val == 0) 151*91f16700Schasinglulu drv_config->dram_side_dq_odt = 0; 152*91f16700Schasinglulu else 153*91f16700Schasinglulu drv_config->dram_side_dq_odt = 240; 154*91f16700Schasinglulu break; 155*91f16700Schasinglulu case LPDDR4: 156*91f16700Schasinglulu default: 157*91f16700Schasinglulu mr3_val = (mmio_read_32(CTL_REG(0, 138)) >> 3) & 0x7; 158*91f16700Schasinglulu mr11_val = (mmio_read_32(CTL_REG(0, 139)) >> 24) & 0xff; 159*91f16700Schasinglulu 160*91f16700Schasinglulu if ((mr3_val == 0) || (mr3_val == 7)) 161*91f16700Schasinglulu drv_config->dram_side_drv = 40; 162*91f16700Schasinglulu else 163*91f16700Schasinglulu drv_config->dram_side_drv = 240 / mr3_val; 164*91f16700Schasinglulu 165*91f16700Schasinglulu tmp = mr11_val & 0x7; 166*91f16700Schasinglulu if ((tmp == 7) || (tmp == 0)) 167*91f16700Schasinglulu drv_config->dram_side_dq_odt = 0; 168*91f16700Schasinglulu else 169*91f16700Schasinglulu drv_config->dram_side_dq_odt = 240 / tmp; 170*91f16700Schasinglulu 171*91f16700Schasinglulu tmp = (mr11_val >> 4) & 0x7; 172*91f16700Schasinglulu if ((tmp == 7) || (tmp == 0)) 173*91f16700Schasinglulu drv_config->dram_side_ca_odt = 0; 174*91f16700Schasinglulu else 175*91f16700Schasinglulu drv_config->dram_side_ca_odt = 240 / tmp; 176*91f16700Schasinglulu break; 177*91f16700Schasinglulu } 178*91f16700Schasinglulu } 179*91f16700Schasinglulu 180*91f16700Schasinglulu static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config, 181*91f16700Schasinglulu struct rk3399_sdram_params *sdram_params, 182*91f16700Schasinglulu struct drv_odt_lp_config *drv_config) 183*91f16700Schasinglulu { 184*91f16700Schasinglulu uint32_t i, j; 185*91f16700Schasinglulu 186*91f16700Schasinglulu for (i = 0; i < sdram_params->num_channels; i++) { 187*91f16700Schasinglulu ptiming_config->dram_info[i].speed_rate = DDR3_DEFAULT; 188*91f16700Schasinglulu ptiming_config->dram_info[i].cs_cnt = sdram_params->ch[i].rank; 189*91f16700Schasinglulu for (j = 0; j < sdram_params->ch[i].rank; j++) { 190*91f16700Schasinglulu ptiming_config->dram_info[i].per_die_capability[j] = 191*91f16700Schasinglulu get_cs_die_capability(sdram_params, i, j); 192*91f16700Schasinglulu } 193*91f16700Schasinglulu } 194*91f16700Schasinglulu ptiming_config->dram_type = sdram_params->dramtype; 195*91f16700Schasinglulu ptiming_config->ch_cnt = sdram_params->num_channels; 196*91f16700Schasinglulu switch (sdram_params->dramtype) { 197*91f16700Schasinglulu case DDR3: 198*91f16700Schasinglulu ptiming_config->bl = ddr3_default_config.bl; 199*91f16700Schasinglulu ptiming_config->ap = ddr3_default_config.ap; 200*91f16700Schasinglulu break; 201*91f16700Schasinglulu case LPDDR3: 202*91f16700Schasinglulu ptiming_config->bl = lpddr3_default_config.bl; 203*91f16700Schasinglulu ptiming_config->ap = lpddr3_default_config.ap; 204*91f16700Schasinglulu break; 205*91f16700Schasinglulu case LPDDR4: 206*91f16700Schasinglulu ptiming_config->bl = lpddr4_default_config.bl; 207*91f16700Schasinglulu ptiming_config->ap = lpddr4_default_config.ap; 208*91f16700Schasinglulu ptiming_config->rdbi = 0; 209*91f16700Schasinglulu ptiming_config->wdbi = 0; 210*91f16700Schasinglulu break; 211*91f16700Schasinglulu default: 212*91f16700Schasinglulu /* Do nothing in default case */ 213*91f16700Schasinglulu break; 214*91f16700Schasinglulu } 215*91f16700Schasinglulu ptiming_config->dramds = drv_config->dram_side_drv; 216*91f16700Schasinglulu ptiming_config->dramodt = drv_config->dram_side_dq_odt; 217*91f16700Schasinglulu ptiming_config->caodt = drv_config->dram_side_ca_odt; 218*91f16700Schasinglulu ptiming_config->odt = (mmio_read_32(PHY_REG(0, 5)) >> 16) & 0x1; 219*91f16700Schasinglulu } 220*91f16700Schasinglulu 221*91f16700Schasinglulu struct lat_adj_pair { 222*91f16700Schasinglulu uint32_t cl; 223*91f16700Schasinglulu uint32_t rdlat_adj; 224*91f16700Schasinglulu uint32_t cwl; 225*91f16700Schasinglulu uint32_t wrlat_adj; 226*91f16700Schasinglulu }; 227*91f16700Schasinglulu 228*91f16700Schasinglulu const struct lat_adj_pair ddr3_lat_adj[] = { 229*91f16700Schasinglulu {6, 5, 5, 4}, 230*91f16700Schasinglulu {8, 7, 6, 5}, 231*91f16700Schasinglulu {10, 9, 7, 6}, 232*91f16700Schasinglulu {11, 9, 8, 7}, 233*91f16700Schasinglulu {13, 0xb, 9, 8}, 234*91f16700Schasinglulu {14, 0xb, 0xa, 9} 235*91f16700Schasinglulu }; 236*91f16700Schasinglulu 237*91f16700Schasinglulu const struct lat_adj_pair lpddr3_lat_adj[] = { 238*91f16700Schasinglulu {3, 2, 1, 0}, 239*91f16700Schasinglulu {6, 5, 3, 2}, 240*91f16700Schasinglulu {8, 7, 4, 3}, 241*91f16700Schasinglulu {9, 8, 5, 4}, 242*91f16700Schasinglulu {10, 9, 6, 5}, 243*91f16700Schasinglulu {11, 9, 6, 5}, 244*91f16700Schasinglulu {12, 0xa, 6, 5}, 245*91f16700Schasinglulu {14, 0xc, 8, 7}, 246*91f16700Schasinglulu {16, 0xd, 8, 7} 247*91f16700Schasinglulu }; 248*91f16700Schasinglulu 249*91f16700Schasinglulu const struct lat_adj_pair lpddr4_lat_adj[] = { 250*91f16700Schasinglulu {6, 5, 4, 2}, 251*91f16700Schasinglulu {10, 9, 6, 4}, 252*91f16700Schasinglulu {14, 0xc, 8, 6}, 253*91f16700Schasinglulu {20, 0x11, 0xa, 8}, 254*91f16700Schasinglulu {24, 0x15, 0xc, 0xa}, 255*91f16700Schasinglulu {28, 0x18, 0xe, 0xc}, 256*91f16700Schasinglulu {32, 0x1b, 0x10, 0xe}, 257*91f16700Schasinglulu {36, 0x1e, 0x12, 0x10} 258*91f16700Schasinglulu }; 259*91f16700Schasinglulu 260*91f16700Schasinglulu static uint32_t get_rdlat_adj(uint32_t dram_type, uint32_t cl) 261*91f16700Schasinglulu { 262*91f16700Schasinglulu const struct lat_adj_pair *p; 263*91f16700Schasinglulu uint32_t cnt; 264*91f16700Schasinglulu uint32_t i; 265*91f16700Schasinglulu 266*91f16700Schasinglulu if (dram_type == DDR3) { 267*91f16700Schasinglulu p = ddr3_lat_adj; 268*91f16700Schasinglulu cnt = ARRAY_SIZE(ddr3_lat_adj); 269*91f16700Schasinglulu } else if (dram_type == LPDDR3) { 270*91f16700Schasinglulu p = lpddr3_lat_adj; 271*91f16700Schasinglulu cnt = ARRAY_SIZE(lpddr3_lat_adj); 272*91f16700Schasinglulu } else { 273*91f16700Schasinglulu p = lpddr4_lat_adj; 274*91f16700Schasinglulu cnt = ARRAY_SIZE(lpddr4_lat_adj); 275*91f16700Schasinglulu } 276*91f16700Schasinglulu 277*91f16700Schasinglulu for (i = 0; i < cnt; i++) { 278*91f16700Schasinglulu if (cl == p[i].cl) 279*91f16700Schasinglulu return p[i].rdlat_adj; 280*91f16700Schasinglulu } 281*91f16700Schasinglulu /* fail */ 282*91f16700Schasinglulu return 0xff; 283*91f16700Schasinglulu } 284*91f16700Schasinglulu 285*91f16700Schasinglulu static uint32_t get_wrlat_adj(uint32_t dram_type, uint32_t cwl) 286*91f16700Schasinglulu { 287*91f16700Schasinglulu const struct lat_adj_pair *p; 288*91f16700Schasinglulu uint32_t cnt; 289*91f16700Schasinglulu uint32_t i; 290*91f16700Schasinglulu 291*91f16700Schasinglulu if (dram_type == DDR3) { 292*91f16700Schasinglulu p = ddr3_lat_adj; 293*91f16700Schasinglulu cnt = ARRAY_SIZE(ddr3_lat_adj); 294*91f16700Schasinglulu } else if (dram_type == LPDDR3) { 295*91f16700Schasinglulu p = lpddr3_lat_adj; 296*91f16700Schasinglulu cnt = ARRAY_SIZE(lpddr3_lat_adj); 297*91f16700Schasinglulu } else { 298*91f16700Schasinglulu p = lpddr4_lat_adj; 299*91f16700Schasinglulu cnt = ARRAY_SIZE(lpddr4_lat_adj); 300*91f16700Schasinglulu } 301*91f16700Schasinglulu 302*91f16700Schasinglulu for (i = 0; i < cnt; i++) { 303*91f16700Schasinglulu if (cwl == p[i].cwl) 304*91f16700Schasinglulu return p[i].wrlat_adj; 305*91f16700Schasinglulu } 306*91f16700Schasinglulu /* fail */ 307*91f16700Schasinglulu return 0xff; 308*91f16700Schasinglulu } 309*91f16700Schasinglulu 310*91f16700Schasinglulu #define PI_REGS_DIMM_SUPPORT (0) 311*91f16700Schasinglulu #define PI_ADD_LATENCY (0) 312*91f16700Schasinglulu #define PI_DOUBLEFREEK (1) 313*91f16700Schasinglulu 314*91f16700Schasinglulu #define PI_PAD_DELAY_PS_VALUE (1000) 315*91f16700Schasinglulu #define PI_IE_ENABLE_VALUE (3000) 316*91f16700Schasinglulu #define PI_TSEL_ENABLE_VALUE (700) 317*91f16700Schasinglulu 318*91f16700Schasinglulu static uint32_t get_pi_rdlat_adj(struct dram_timing_t *pdram_timing) 319*91f16700Schasinglulu { 320*91f16700Schasinglulu /*[DLLSUBTYPE2] == "STD_DENALI_HS" */ 321*91f16700Schasinglulu uint32_t rdlat, delay_adder, ie_enable, hs_offset, tsel_adder, 322*91f16700Schasinglulu extra_adder, tsel_enable; 323*91f16700Schasinglulu 324*91f16700Schasinglulu ie_enable = PI_IE_ENABLE_VALUE; 325*91f16700Schasinglulu tsel_enable = PI_TSEL_ENABLE_VALUE; 326*91f16700Schasinglulu 327*91f16700Schasinglulu rdlat = pdram_timing->cl + PI_ADD_LATENCY; 328*91f16700Schasinglulu delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 329*91f16700Schasinglulu if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 330*91f16700Schasinglulu delay_adder++; 331*91f16700Schasinglulu hs_offset = 0; 332*91f16700Schasinglulu tsel_adder = 0; 333*91f16700Schasinglulu extra_adder = 0; 334*91f16700Schasinglulu /* rdlat = rdlat - (PREAMBLE_SUPPORT & 0x1); */ 335*91f16700Schasinglulu tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz); 336*91f16700Schasinglulu if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0) 337*91f16700Schasinglulu tsel_adder++; 338*91f16700Schasinglulu delay_adder = delay_adder - 1; 339*91f16700Schasinglulu if (tsel_adder > delay_adder) 340*91f16700Schasinglulu extra_adder = tsel_adder - delay_adder; 341*91f16700Schasinglulu else 342*91f16700Schasinglulu extra_adder = 0; 343*91f16700Schasinglulu if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 344*91f16700Schasinglulu hs_offset = 2; 345*91f16700Schasinglulu else 346*91f16700Schasinglulu hs_offset = 1; 347*91f16700Schasinglulu 348*91f16700Schasinglulu if (delay_adder > (rdlat - 1 - hs_offset)) { 349*91f16700Schasinglulu rdlat = rdlat - tsel_adder; 350*91f16700Schasinglulu } else { 351*91f16700Schasinglulu if ((rdlat - delay_adder) < 2) 352*91f16700Schasinglulu rdlat = 2; 353*91f16700Schasinglulu else 354*91f16700Schasinglulu rdlat = rdlat - delay_adder - extra_adder; 355*91f16700Schasinglulu } 356*91f16700Schasinglulu 357*91f16700Schasinglulu return rdlat; 358*91f16700Schasinglulu } 359*91f16700Schasinglulu 360*91f16700Schasinglulu static uint32_t get_pi_wrlat(struct dram_timing_t *pdram_timing, 361*91f16700Schasinglulu struct timing_related_config *timing_config) 362*91f16700Schasinglulu { 363*91f16700Schasinglulu uint32_t tmp; 364*91f16700Schasinglulu 365*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) { 366*91f16700Schasinglulu tmp = pdram_timing->cl; 367*91f16700Schasinglulu if (tmp >= 14) 368*91f16700Schasinglulu tmp = 8; 369*91f16700Schasinglulu else if (tmp >= 10) 370*91f16700Schasinglulu tmp = 6; 371*91f16700Schasinglulu else if (tmp == 9) 372*91f16700Schasinglulu tmp = 5; 373*91f16700Schasinglulu else if (tmp == 8) 374*91f16700Schasinglulu tmp = 4; 375*91f16700Schasinglulu else if (tmp == 6) 376*91f16700Schasinglulu tmp = 3; 377*91f16700Schasinglulu else 378*91f16700Schasinglulu tmp = 1; 379*91f16700Schasinglulu } else { 380*91f16700Schasinglulu tmp = 1; 381*91f16700Schasinglulu } 382*91f16700Schasinglulu 383*91f16700Schasinglulu return tmp; 384*91f16700Schasinglulu } 385*91f16700Schasinglulu 386*91f16700Schasinglulu static uint32_t get_pi_wrlat_adj(struct dram_timing_t *pdram_timing, 387*91f16700Schasinglulu struct timing_related_config *timing_config) 388*91f16700Schasinglulu { 389*91f16700Schasinglulu return get_pi_wrlat(pdram_timing, timing_config) + PI_ADD_LATENCY - 1; 390*91f16700Schasinglulu } 391*91f16700Schasinglulu 392*91f16700Schasinglulu static uint32_t get_pi_tdfi_phy_rdlat(struct dram_timing_t *pdram_timing, 393*91f16700Schasinglulu struct timing_related_config *timing_config) 394*91f16700Schasinglulu { 395*91f16700Schasinglulu /* [DLLSUBTYPE2] == "STD_DENALI_HS" */ 396*91f16700Schasinglulu uint32_t cas_lat, delay_adder, ie_enable, hs_offset, ie_delay_adder; 397*91f16700Schasinglulu uint32_t mem_delay_ps, round_trip_ps; 398*91f16700Schasinglulu uint32_t phy_internal_delay, lpddr_adder, dfi_adder, rdlat_delay; 399*91f16700Schasinglulu 400*91f16700Schasinglulu ie_enable = PI_IE_ENABLE_VALUE; 401*91f16700Schasinglulu 402*91f16700Schasinglulu delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 403*91f16700Schasinglulu if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 404*91f16700Schasinglulu delay_adder++; 405*91f16700Schasinglulu delay_adder = delay_adder - 1; 406*91f16700Schasinglulu if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 407*91f16700Schasinglulu hs_offset = 2; 408*91f16700Schasinglulu else 409*91f16700Schasinglulu hs_offset = 1; 410*91f16700Schasinglulu 411*91f16700Schasinglulu cas_lat = pdram_timing->cl + PI_ADD_LATENCY; 412*91f16700Schasinglulu 413*91f16700Schasinglulu if (delay_adder > (cas_lat - 1 - hs_offset)) { 414*91f16700Schasinglulu ie_delay_adder = 0; 415*91f16700Schasinglulu } else { 416*91f16700Schasinglulu ie_delay_adder = ie_enable / (1000000 / pdram_timing->mhz); 417*91f16700Schasinglulu if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 418*91f16700Schasinglulu ie_delay_adder++; 419*91f16700Schasinglulu } 420*91f16700Schasinglulu 421*91f16700Schasinglulu if (timing_config->dram_type == DDR3) { 422*91f16700Schasinglulu mem_delay_ps = 0; 423*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR4) { 424*91f16700Schasinglulu mem_delay_ps = 3600; 425*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR3) { 426*91f16700Schasinglulu mem_delay_ps = 5500; 427*91f16700Schasinglulu } else { 428*91f16700Schasinglulu NOTICE("get_pi_tdfi_phy_rdlat:dramtype unsupport\n"); 429*91f16700Schasinglulu return 0; 430*91f16700Schasinglulu } 431*91f16700Schasinglulu round_trip_ps = 1100 + 500 + mem_delay_ps + 500 + 600; 432*91f16700Schasinglulu delay_adder = round_trip_ps / (1000000 / pdram_timing->mhz); 433*91f16700Schasinglulu if ((round_trip_ps % (1000000 / pdram_timing->mhz)) != 0) 434*91f16700Schasinglulu delay_adder++; 435*91f16700Schasinglulu 436*91f16700Schasinglulu phy_internal_delay = 5 + 2 + 4; 437*91f16700Schasinglulu lpddr_adder = mem_delay_ps / (1000000 / pdram_timing->mhz); 438*91f16700Schasinglulu if ((mem_delay_ps % (1000000 / pdram_timing->mhz)) != 0) 439*91f16700Schasinglulu lpddr_adder++; 440*91f16700Schasinglulu dfi_adder = 0; 441*91f16700Schasinglulu phy_internal_delay = phy_internal_delay + 2; 442*91f16700Schasinglulu rdlat_delay = delay_adder + phy_internal_delay + 443*91f16700Schasinglulu ie_delay_adder + lpddr_adder + dfi_adder; 444*91f16700Schasinglulu 445*91f16700Schasinglulu rdlat_delay = rdlat_delay + 2; 446*91f16700Schasinglulu return rdlat_delay; 447*91f16700Schasinglulu } 448*91f16700Schasinglulu 449*91f16700Schasinglulu static uint32_t get_pi_todtoff_min(struct dram_timing_t *pdram_timing, 450*91f16700Schasinglulu struct timing_related_config *timing_config) 451*91f16700Schasinglulu { 452*91f16700Schasinglulu uint32_t tmp, todtoff_min_ps; 453*91f16700Schasinglulu 454*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) 455*91f16700Schasinglulu todtoff_min_ps = 2500; 456*91f16700Schasinglulu else if (timing_config->dram_type == LPDDR4) 457*91f16700Schasinglulu todtoff_min_ps = 1500; 458*91f16700Schasinglulu else 459*91f16700Schasinglulu todtoff_min_ps = 0; 460*91f16700Schasinglulu /* todtoff_min */ 461*91f16700Schasinglulu tmp = todtoff_min_ps / (1000000 / pdram_timing->mhz); 462*91f16700Schasinglulu if ((todtoff_min_ps % (1000000 / pdram_timing->mhz)) != 0) 463*91f16700Schasinglulu tmp++; 464*91f16700Schasinglulu return tmp; 465*91f16700Schasinglulu } 466*91f16700Schasinglulu 467*91f16700Schasinglulu static uint32_t get_pi_todtoff_max(struct dram_timing_t *pdram_timing, 468*91f16700Schasinglulu struct timing_related_config *timing_config) 469*91f16700Schasinglulu { 470*91f16700Schasinglulu uint32_t tmp, todtoff_max_ps; 471*91f16700Schasinglulu 472*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR4) 473*91f16700Schasinglulu || (timing_config->dram_type == LPDDR3)) 474*91f16700Schasinglulu todtoff_max_ps = 3500; 475*91f16700Schasinglulu else 476*91f16700Schasinglulu todtoff_max_ps = 0; 477*91f16700Schasinglulu 478*91f16700Schasinglulu /* todtoff_max */ 479*91f16700Schasinglulu tmp = todtoff_max_ps / (1000000 / pdram_timing->mhz); 480*91f16700Schasinglulu if ((todtoff_max_ps % (1000000 / pdram_timing->mhz)) != 0) 481*91f16700Schasinglulu tmp++; 482*91f16700Schasinglulu return tmp; 483*91f16700Schasinglulu } 484*91f16700Schasinglulu 485*91f16700Schasinglulu static void gen_rk3399_ctl_params_f0(struct timing_related_config 486*91f16700Schasinglulu *timing_config, 487*91f16700Schasinglulu struct dram_timing_t *pdram_timing) 488*91f16700Schasinglulu { 489*91f16700Schasinglulu uint32_t i; 490*91f16700Schasinglulu uint32_t tmp, tmp1; 491*91f16700Schasinglulu 492*91f16700Schasinglulu for (i = 0; i < timing_config->ch_cnt; i++) { 493*91f16700Schasinglulu if (timing_config->dram_type == DDR3) { 494*91f16700Schasinglulu tmp = ((700000 + 10) * timing_config->freq + 495*91f16700Schasinglulu 999) / 1000; 496*91f16700Schasinglulu tmp += pdram_timing->txsnr + (pdram_timing->tmrd * 3) + 497*91f16700Schasinglulu pdram_timing->tmod + pdram_timing->tzqinit; 498*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 5), tmp); 499*91f16700Schasinglulu 500*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 22), 0xffff, 501*91f16700Schasinglulu pdram_timing->tdllk); 502*91f16700Schasinglulu 503*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 32), 504*91f16700Schasinglulu (pdram_timing->tmod << 8) | 505*91f16700Schasinglulu pdram_timing->tmrd); 506*91f16700Schasinglulu 507*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 59), 0xffffu << 16, 508*91f16700Schasinglulu (pdram_timing->txsr - 509*91f16700Schasinglulu pdram_timing->trcd) << 16); 510*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR4) { 511*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 5), pdram_timing->tinit1 + 512*91f16700Schasinglulu pdram_timing->tinit3); 513*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 32), 514*91f16700Schasinglulu (pdram_timing->tmrd << 8) | 515*91f16700Schasinglulu pdram_timing->tmrd); 516*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 59), 0xffffu << 16, 517*91f16700Schasinglulu pdram_timing->txsr << 16); 518*91f16700Schasinglulu } else { 519*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 5), pdram_timing->tinit1); 520*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 7), pdram_timing->tinit4); 521*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 32), 522*91f16700Schasinglulu (pdram_timing->tmrd << 8) | 523*91f16700Schasinglulu pdram_timing->tmrd); 524*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 59), 0xffffu << 16, 525*91f16700Schasinglulu pdram_timing->txsr << 16); 526*91f16700Schasinglulu } 527*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 6), pdram_timing->tinit3); 528*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 8), pdram_timing->tinit5); 529*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 23), (0x7f << 16), 530*91f16700Schasinglulu ((pdram_timing->cl * 2) << 16)); 531*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 23), (0x1f << 24), 532*91f16700Schasinglulu (pdram_timing->cwl << 24)); 533*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 24), 0x3f, pdram_timing->al); 534*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 26), 0xffffu << 16, 535*91f16700Schasinglulu (pdram_timing->trc << 24) | 536*91f16700Schasinglulu (pdram_timing->trrd << 16)); 537*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 27), 538*91f16700Schasinglulu (pdram_timing->tfaw << 24) | 539*91f16700Schasinglulu (pdram_timing->trppb << 16) | 540*91f16700Schasinglulu (pdram_timing->twtr << 8) | 541*91f16700Schasinglulu pdram_timing->tras_min); 542*91f16700Schasinglulu 543*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 31), 0xffu << 24, 544*91f16700Schasinglulu max(4, pdram_timing->trtp) << 24); 545*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 33), (pdram_timing->tcke << 24) | 546*91f16700Schasinglulu pdram_timing->tras_max); 547*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 34), 0xff, 548*91f16700Schasinglulu max(1, pdram_timing->tckesr)); 549*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 39), 550*91f16700Schasinglulu (0x3f << 16) | (0xff << 8), 551*91f16700Schasinglulu (pdram_timing->twr << 16) | 552*91f16700Schasinglulu (pdram_timing->trcd << 8)); 553*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 42), 0x1f << 16, 554*91f16700Schasinglulu pdram_timing->tmrz << 16); 555*91f16700Schasinglulu tmp = pdram_timing->tdal ? pdram_timing->tdal : 556*91f16700Schasinglulu (pdram_timing->twr + pdram_timing->trp); 557*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 44), 0xff, tmp); 558*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 45), 0xff, pdram_timing->trp); 559*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 48), 560*91f16700Schasinglulu ((pdram_timing->trefi - 8) << 16) | 561*91f16700Schasinglulu pdram_timing->trfc); 562*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 52), 0xffff, pdram_timing->txp); 563*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 53), 0xffffu << 16, 564*91f16700Schasinglulu pdram_timing->txpdll << 16); 565*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 55), 0xf << 24, 566*91f16700Schasinglulu pdram_timing->tcscke << 24); 567*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 55), 0xff, pdram_timing->tmrri); 568*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 56), 569*91f16700Schasinglulu (pdram_timing->tzqcke << 24) | 570*91f16700Schasinglulu (pdram_timing->tmrwckel << 16) | 571*91f16700Schasinglulu (pdram_timing->tckehcs << 8) | 572*91f16700Schasinglulu pdram_timing->tckelcs); 573*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 60), 0xffff, pdram_timing->txsnr); 574*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 62), 0xffffu << 16, 575*91f16700Schasinglulu (pdram_timing->tckehcmd << 24) | 576*91f16700Schasinglulu (pdram_timing->tckelcmd << 16)); 577*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 63), 578*91f16700Schasinglulu (pdram_timing->tckelpd << 24) | 579*91f16700Schasinglulu (pdram_timing->tescke << 16) | 580*91f16700Schasinglulu (pdram_timing->tsr << 8) | 581*91f16700Schasinglulu pdram_timing->tckckel); 582*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 64), 0xfff, 583*91f16700Schasinglulu (pdram_timing->tcmdcke << 8) | 584*91f16700Schasinglulu pdram_timing->tcsckeh); 585*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 92), 0xffff << 8, 586*91f16700Schasinglulu (pdram_timing->tcksrx << 16) | 587*91f16700Schasinglulu (pdram_timing->tcksre << 8)); 588*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 108), 0x1 << 24, 589*91f16700Schasinglulu (timing_config->dllbp << 24)); 590*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 122), 0x3ff << 16, 591*91f16700Schasinglulu (pdram_timing->tvrcg_enable << 16)); 592*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 123), (pdram_timing->tfc_long << 16) | 593*91f16700Schasinglulu pdram_timing->tvrcg_disable); 594*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 124), 595*91f16700Schasinglulu (pdram_timing->tvref_long << 16) | 596*91f16700Schasinglulu (pdram_timing->tckfspx << 8) | 597*91f16700Schasinglulu pdram_timing->tckfspe); 598*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 133), (pdram_timing->mr[1] << 16) | 599*91f16700Schasinglulu pdram_timing->mr[0]); 600*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 134), 0xffff, 601*91f16700Schasinglulu pdram_timing->mr[2]); 602*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 138), 0xffff, 603*91f16700Schasinglulu pdram_timing->mr[3]); 604*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 139), 0xffu << 24, 605*91f16700Schasinglulu pdram_timing->mr11 << 24); 606*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 147), 607*91f16700Schasinglulu (pdram_timing->mr[1] << 16) | 608*91f16700Schasinglulu pdram_timing->mr[0]); 609*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 148), 0xffff, 610*91f16700Schasinglulu pdram_timing->mr[2]); 611*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 152), 0xffff, 612*91f16700Schasinglulu pdram_timing->mr[3]); 613*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 153), 0xffu << 24, 614*91f16700Schasinglulu pdram_timing->mr11 << 24); 615*91f16700Schasinglulu if (timing_config->dram_type == LPDDR4) { 616*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 140), 0xffffu << 16, 617*91f16700Schasinglulu pdram_timing->mr12 << 16); 618*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 142), 0xffffu << 16, 619*91f16700Schasinglulu pdram_timing->mr14 << 16); 620*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 145), 0xffffu << 16, 621*91f16700Schasinglulu pdram_timing->mr22 << 16); 622*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 154), 0xffffu << 16, 623*91f16700Schasinglulu pdram_timing->mr12 << 16); 624*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 156), 0xffffu << 16, 625*91f16700Schasinglulu pdram_timing->mr14 << 16); 626*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 159), 0xffffu << 16, 627*91f16700Schasinglulu pdram_timing->mr22 << 16); 628*91f16700Schasinglulu } 629*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 179), 0xfff << 8, 630*91f16700Schasinglulu pdram_timing->tzqinit << 8); 631*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 180), (pdram_timing->tzqcs << 16) | 632*91f16700Schasinglulu (pdram_timing->tzqinit / 2)); 633*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 181), (pdram_timing->tzqlat << 16) | 634*91f16700Schasinglulu pdram_timing->tzqcal); 635*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 212), 0xff << 8, 636*91f16700Schasinglulu pdram_timing->todton << 8); 637*91f16700Schasinglulu 638*91f16700Schasinglulu if (timing_config->odt) { 639*91f16700Schasinglulu mmio_setbits_32(CTL_REG(i, 213), 1 << 16); 640*91f16700Schasinglulu if (timing_config->freq < 400) 641*91f16700Schasinglulu tmp = 4 << 24; 642*91f16700Schasinglulu else 643*91f16700Schasinglulu tmp = 8 << 24; 644*91f16700Schasinglulu } else { 645*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 213), 1 << 16); 646*91f16700Schasinglulu tmp = 2 << 24; 647*91f16700Schasinglulu } 648*91f16700Schasinglulu 649*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 216), 0x1f << 24, tmp); 650*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 221), (0x3 << 16) | (0xf << 8), 651*91f16700Schasinglulu (pdram_timing->tdqsck << 16) | 652*91f16700Schasinglulu (pdram_timing->tdqsck_max << 8)); 653*91f16700Schasinglulu tmp = 654*91f16700Schasinglulu (get_wrlat_adj(timing_config->dram_type, pdram_timing->cwl) 655*91f16700Schasinglulu << 8) | get_rdlat_adj(timing_config->dram_type, 656*91f16700Schasinglulu pdram_timing->cl); 657*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 284), 0xffff, tmp); 658*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 82), 0xffffu << 16, 659*91f16700Schasinglulu (4 * pdram_timing->trefi) << 16); 660*91f16700Schasinglulu 661*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 83), 0xffff, 662*91f16700Schasinglulu (2 * pdram_timing->trefi) & 0xffff); 663*91f16700Schasinglulu 664*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 665*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 666*91f16700Schasinglulu tmp = get_pi_wrlat(pdram_timing, timing_config); 667*91f16700Schasinglulu tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 668*91f16700Schasinglulu tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 669*91f16700Schasinglulu } else { 670*91f16700Schasinglulu tmp = 0; 671*91f16700Schasinglulu } 672*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 214), 0x3f << 16, 673*91f16700Schasinglulu (tmp & 0x3f) << 16); 674*91f16700Schasinglulu 675*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 676*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 677*91f16700Schasinglulu /* min_rl_preamble = cl+TDQSCK_MIN -1 */ 678*91f16700Schasinglulu tmp = pdram_timing->cl + 679*91f16700Schasinglulu get_pi_todtoff_min(pdram_timing, timing_config) - 1; 680*91f16700Schasinglulu /* todtoff_max */ 681*91f16700Schasinglulu tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 682*91f16700Schasinglulu tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 683*91f16700Schasinglulu } else { 684*91f16700Schasinglulu tmp = pdram_timing->cl - pdram_timing->cwl; 685*91f16700Schasinglulu } 686*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 215), 0x3f << 8, 687*91f16700Schasinglulu (tmp & 0x3f) << 8); 688*91f16700Schasinglulu 689*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 275), 0xff << 16, 690*91f16700Schasinglulu (get_pi_tdfi_phy_rdlat(pdram_timing, 691*91f16700Schasinglulu timing_config) & 692*91f16700Schasinglulu 0xff) << 16); 693*91f16700Schasinglulu 694*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 277), 0xffff, 695*91f16700Schasinglulu (2 * pdram_timing->trefi) & 0xffff); 696*91f16700Schasinglulu 697*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 282), 0xffff, 698*91f16700Schasinglulu (2 * pdram_timing->trefi) & 0xffff); 699*91f16700Schasinglulu 700*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 283), 20 * pdram_timing->trefi); 701*91f16700Schasinglulu 702*91f16700Schasinglulu /* CTL_308 TDFI_CALVL_CAPTURE_F0:RW:16:10 */ 703*91f16700Schasinglulu tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 704*91f16700Schasinglulu if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 705*91f16700Schasinglulu tmp1++; 706*91f16700Schasinglulu tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 707*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 308), 0x3ff << 16, tmp << 16); 708*91f16700Schasinglulu 709*91f16700Schasinglulu /* CTL_308 TDFI_CALVL_CC_F0:RW:0:10 */ 710*91f16700Schasinglulu tmp = tmp + 18; 711*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 308), 0x3ff, tmp); 712*91f16700Schasinglulu 713*91f16700Schasinglulu /* CTL_314 TDFI_WRCSLAT_F0:RW:8:8 */ 714*91f16700Schasinglulu tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); 715*91f16700Schasinglulu if (timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) { 716*91f16700Schasinglulu if (tmp1 == 0) 717*91f16700Schasinglulu tmp = 0; 718*91f16700Schasinglulu else if (tmp1 < 5) 719*91f16700Schasinglulu tmp = tmp1 - 1; 720*91f16700Schasinglulu else 721*91f16700Schasinglulu tmp = tmp1 - 5; 722*91f16700Schasinglulu } else { 723*91f16700Schasinglulu tmp = tmp1 - 2; 724*91f16700Schasinglulu } 725*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 8, tmp << 8); 726*91f16700Schasinglulu 727*91f16700Schasinglulu /* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */ 728*91f16700Schasinglulu if ((timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) && 729*91f16700Schasinglulu (pdram_timing->cl >= 5)) 730*91f16700Schasinglulu tmp = pdram_timing->cl - 5; 731*91f16700Schasinglulu else 732*91f16700Schasinglulu tmp = pdram_timing->cl - 2; 733*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 314), 0xff, tmp); 734*91f16700Schasinglulu } 735*91f16700Schasinglulu } 736*91f16700Schasinglulu 737*91f16700Schasinglulu static void gen_rk3399_ctl_params_f1(struct timing_related_config 738*91f16700Schasinglulu *timing_config, 739*91f16700Schasinglulu struct dram_timing_t *pdram_timing) 740*91f16700Schasinglulu { 741*91f16700Schasinglulu uint32_t i; 742*91f16700Schasinglulu uint32_t tmp, tmp1; 743*91f16700Schasinglulu 744*91f16700Schasinglulu for (i = 0; i < timing_config->ch_cnt; i++) { 745*91f16700Schasinglulu if (timing_config->dram_type == DDR3) { 746*91f16700Schasinglulu tmp = 747*91f16700Schasinglulu ((700000 + 10) * timing_config->freq + 999) / 1000; 748*91f16700Schasinglulu tmp += pdram_timing->txsnr + (pdram_timing->tmrd * 3) + 749*91f16700Schasinglulu pdram_timing->tmod + pdram_timing->tzqinit; 750*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 9), tmp); 751*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 22), 0xffffu << 16, 752*91f16700Schasinglulu pdram_timing->tdllk << 16); 753*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00, 754*91f16700Schasinglulu (pdram_timing->tmod << 24) | 755*91f16700Schasinglulu (pdram_timing->tmrd << 16) | 756*91f16700Schasinglulu (pdram_timing->trtp << 8)); 757*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 60), 0xffffu << 16, 758*91f16700Schasinglulu (pdram_timing->txsr - 759*91f16700Schasinglulu pdram_timing->trcd) << 16); 760*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR4) { 761*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 9), pdram_timing->tinit1 + 762*91f16700Schasinglulu pdram_timing->tinit3); 763*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00, 764*91f16700Schasinglulu (pdram_timing->tmrd << 24) | 765*91f16700Schasinglulu (pdram_timing->tmrd << 16) | 766*91f16700Schasinglulu (pdram_timing->trtp << 8)); 767*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 60), 0xffffu << 16, 768*91f16700Schasinglulu pdram_timing->txsr << 16); 769*91f16700Schasinglulu } else { 770*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 9), pdram_timing->tinit1); 771*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 11), pdram_timing->tinit4); 772*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 34), 0xffffff00, 773*91f16700Schasinglulu (pdram_timing->tmrd << 24) | 774*91f16700Schasinglulu (pdram_timing->tmrd << 16) | 775*91f16700Schasinglulu (pdram_timing->trtp << 8)); 776*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 60), 0xffffu << 16, 777*91f16700Schasinglulu pdram_timing->txsr << 16); 778*91f16700Schasinglulu } 779*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 10), pdram_timing->tinit3); 780*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 12), pdram_timing->tinit5); 781*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 24), (0x7f << 8), 782*91f16700Schasinglulu ((pdram_timing->cl * 2) << 8)); 783*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 24), (0x1f << 16), 784*91f16700Schasinglulu (pdram_timing->cwl << 16)); 785*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 24), 0x3f << 24, 786*91f16700Schasinglulu pdram_timing->al << 24); 787*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 28), 0xffffff00, 788*91f16700Schasinglulu (pdram_timing->tras_min << 24) | 789*91f16700Schasinglulu (pdram_timing->trc << 16) | 790*91f16700Schasinglulu (pdram_timing->trrd << 8)); 791*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 29), 0xffffff, 792*91f16700Schasinglulu (pdram_timing->tfaw << 16) | 793*91f16700Schasinglulu (pdram_timing->trppb << 8) | 794*91f16700Schasinglulu pdram_timing->twtr); 795*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 35), (pdram_timing->tcke << 24) | 796*91f16700Schasinglulu pdram_timing->tras_max); 797*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 36), 0xff, 798*91f16700Schasinglulu max(1, pdram_timing->tckesr)); 799*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 39), (0xffu << 24), 800*91f16700Schasinglulu (pdram_timing->trcd << 24)); 801*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 40), 0x3f, pdram_timing->twr); 802*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 42), 0x1f << 24, 803*91f16700Schasinglulu pdram_timing->tmrz << 24); 804*91f16700Schasinglulu tmp = pdram_timing->tdal ? pdram_timing->tdal : 805*91f16700Schasinglulu (pdram_timing->twr + pdram_timing->trp); 806*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 44), 0xff << 8, tmp << 8); 807*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 45), 0xff << 8, 808*91f16700Schasinglulu pdram_timing->trp << 8); 809*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 49), 810*91f16700Schasinglulu ((pdram_timing->trefi - 8) << 16) | 811*91f16700Schasinglulu pdram_timing->trfc); 812*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 52), 0xffffu << 16, 813*91f16700Schasinglulu pdram_timing->txp << 16); 814*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 54), 0xffff, 815*91f16700Schasinglulu pdram_timing->txpdll); 816*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 55), 0xff << 8, 817*91f16700Schasinglulu pdram_timing->tmrri << 8); 818*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 57), (pdram_timing->tmrwckel << 24) | 819*91f16700Schasinglulu (pdram_timing->tckehcs << 16) | 820*91f16700Schasinglulu (pdram_timing->tckelcs << 8) | 821*91f16700Schasinglulu pdram_timing->tcscke); 822*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 58), 0xf, pdram_timing->tzqcke); 823*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 61), 0xffff, pdram_timing->txsnr); 824*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 64), 0xffffu << 16, 825*91f16700Schasinglulu (pdram_timing->tckehcmd << 24) | 826*91f16700Schasinglulu (pdram_timing->tckelcmd << 16)); 827*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 65), (pdram_timing->tckelpd << 24) | 828*91f16700Schasinglulu (pdram_timing->tescke << 16) | 829*91f16700Schasinglulu (pdram_timing->tsr << 8) | 830*91f16700Schasinglulu pdram_timing->tckckel); 831*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 66), 0xfff, 832*91f16700Schasinglulu (pdram_timing->tcmdcke << 8) | 833*91f16700Schasinglulu pdram_timing->tcsckeh); 834*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 92), (0xffu << 24), 835*91f16700Schasinglulu (pdram_timing->tcksre << 24)); 836*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 93), 0xff, 837*91f16700Schasinglulu pdram_timing->tcksrx); 838*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 108), (0x1 << 25), 839*91f16700Schasinglulu (timing_config->dllbp << 25)); 840*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 125), 841*91f16700Schasinglulu (pdram_timing->tvrcg_disable << 16) | 842*91f16700Schasinglulu pdram_timing->tvrcg_enable); 843*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 126), (pdram_timing->tckfspx << 24) | 844*91f16700Schasinglulu (pdram_timing->tckfspe << 16) | 845*91f16700Schasinglulu pdram_timing->tfc_long); 846*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 127), 0xffff, 847*91f16700Schasinglulu pdram_timing->tvref_long); 848*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 134), 0xffffu << 16, 849*91f16700Schasinglulu pdram_timing->mr[0] << 16); 850*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 135), (pdram_timing->mr[2] << 16) | 851*91f16700Schasinglulu pdram_timing->mr[1]); 852*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 138), 0xffffu << 16, 853*91f16700Schasinglulu pdram_timing->mr[3] << 16); 854*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 140), 0xff, pdram_timing->mr11); 855*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 148), 0xffffu << 16, 856*91f16700Schasinglulu pdram_timing->mr[0] << 16); 857*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 149), (pdram_timing->mr[2] << 16) | 858*91f16700Schasinglulu pdram_timing->mr[1]); 859*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 152), 0xffffu << 16, 860*91f16700Schasinglulu pdram_timing->mr[3] << 16); 861*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 154), 0xff, pdram_timing->mr11); 862*91f16700Schasinglulu if (timing_config->dram_type == LPDDR4) { 863*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 141), 0xffff, 864*91f16700Schasinglulu pdram_timing->mr12); 865*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 143), 0xffff, 866*91f16700Schasinglulu pdram_timing->mr14); 867*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 146), 0xffff, 868*91f16700Schasinglulu pdram_timing->mr22); 869*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 155), 0xffff, 870*91f16700Schasinglulu pdram_timing->mr12); 871*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 157), 0xffff, 872*91f16700Schasinglulu pdram_timing->mr14); 873*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 160), 0xffff, 874*91f16700Schasinglulu pdram_timing->mr22); 875*91f16700Schasinglulu } 876*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 182), 877*91f16700Schasinglulu ((pdram_timing->tzqinit / 2) << 16) | 878*91f16700Schasinglulu pdram_timing->tzqinit); 879*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 183), (pdram_timing->tzqcal << 16) | 880*91f16700Schasinglulu pdram_timing->tzqcs); 881*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 184), 0x3f, pdram_timing->tzqlat); 882*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 188), 0xfff, 883*91f16700Schasinglulu pdram_timing->tzqreset); 884*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 212), 0xff << 16, 885*91f16700Schasinglulu pdram_timing->todton << 16); 886*91f16700Schasinglulu 887*91f16700Schasinglulu if (timing_config->odt) { 888*91f16700Schasinglulu mmio_setbits_32(CTL_REG(i, 213), (1 << 24)); 889*91f16700Schasinglulu if (timing_config->freq < 400) 890*91f16700Schasinglulu tmp = 4 << 24; 891*91f16700Schasinglulu else 892*91f16700Schasinglulu tmp = 8 << 24; 893*91f16700Schasinglulu } else { 894*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 213), (1 << 24)); 895*91f16700Schasinglulu tmp = 2 << 24; 896*91f16700Schasinglulu } 897*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 217), 0x1f << 24, tmp); 898*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 221), 0xf << 24, 899*91f16700Schasinglulu (pdram_timing->tdqsck_max << 24)); 900*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 222), 0x3, pdram_timing->tdqsck); 901*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 291), 0xffff, 902*91f16700Schasinglulu (get_wrlat_adj(timing_config->dram_type, 903*91f16700Schasinglulu pdram_timing->cwl) << 8) | 904*91f16700Schasinglulu get_rdlat_adj(timing_config->dram_type, 905*91f16700Schasinglulu pdram_timing->cl)); 906*91f16700Schasinglulu 907*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 84), 0xffff, 908*91f16700Schasinglulu (4 * pdram_timing->trefi) & 0xffff); 909*91f16700Schasinglulu 910*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 84), 0xffffu << 16, 911*91f16700Schasinglulu ((2 * pdram_timing->trefi) & 0xffff) << 16); 912*91f16700Schasinglulu 913*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 914*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 915*91f16700Schasinglulu tmp = get_pi_wrlat(pdram_timing, timing_config); 916*91f16700Schasinglulu tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 917*91f16700Schasinglulu tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 918*91f16700Schasinglulu } else { 919*91f16700Schasinglulu tmp = 0; 920*91f16700Schasinglulu } 921*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 214), 0x3f << 24, 922*91f16700Schasinglulu (tmp & 0x3f) << 24); 923*91f16700Schasinglulu 924*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 925*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 926*91f16700Schasinglulu /* min_rl_preamble = cl + TDQSCK_MIN - 1 */ 927*91f16700Schasinglulu tmp = pdram_timing->cl + 928*91f16700Schasinglulu get_pi_todtoff_min(pdram_timing, timing_config); 929*91f16700Schasinglulu tmp--; 930*91f16700Schasinglulu /* todtoff_max */ 931*91f16700Schasinglulu tmp1 = get_pi_todtoff_max(pdram_timing, timing_config); 932*91f16700Schasinglulu tmp = (tmp > tmp1) ? (tmp - tmp1) : 0; 933*91f16700Schasinglulu } else { 934*91f16700Schasinglulu tmp = pdram_timing->cl - pdram_timing->cwl; 935*91f16700Schasinglulu } 936*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 215), 0x3f << 16, 937*91f16700Schasinglulu (tmp & 0x3f) << 16); 938*91f16700Schasinglulu 939*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 275), 0xffu << 24, 940*91f16700Schasinglulu (get_pi_tdfi_phy_rdlat(pdram_timing, 941*91f16700Schasinglulu timing_config) & 942*91f16700Schasinglulu 0xff) << 24); 943*91f16700Schasinglulu 944*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 284), 0xffffu << 16, 945*91f16700Schasinglulu ((2 * pdram_timing->trefi) & 0xffff) << 16); 946*91f16700Schasinglulu 947*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 289), 0xffff, 948*91f16700Schasinglulu (2 * pdram_timing->trefi) & 0xffff); 949*91f16700Schasinglulu 950*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 290), 20 * pdram_timing->trefi); 951*91f16700Schasinglulu 952*91f16700Schasinglulu /* CTL_309 TDFI_CALVL_CAPTURE_F1:RW:16:10 */ 953*91f16700Schasinglulu tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 954*91f16700Schasinglulu if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 955*91f16700Schasinglulu tmp1++; 956*91f16700Schasinglulu tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 957*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 309), 0x3ff << 16, tmp << 16); 958*91f16700Schasinglulu 959*91f16700Schasinglulu /* CTL_309 TDFI_CALVL_CC_F1:RW:0:10 */ 960*91f16700Schasinglulu tmp = tmp + 18; 961*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 309), 0x3ff, tmp); 962*91f16700Schasinglulu 963*91f16700Schasinglulu /* CTL_314 TDFI_WRCSLAT_F1:RW:24:8 */ 964*91f16700Schasinglulu tmp1 = get_pi_wrlat_adj(pdram_timing, timing_config); 965*91f16700Schasinglulu if (timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) { 966*91f16700Schasinglulu if (tmp1 == 0) 967*91f16700Schasinglulu tmp = 0; 968*91f16700Schasinglulu else if (tmp1 < 5) 969*91f16700Schasinglulu tmp = tmp1 - 1; 970*91f16700Schasinglulu else 971*91f16700Schasinglulu tmp = tmp1 - 5; 972*91f16700Schasinglulu } else { 973*91f16700Schasinglulu tmp = tmp1 - 2; 974*91f16700Schasinglulu } 975*91f16700Schasinglulu 976*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 314), 0xffu << 24, tmp << 24); 977*91f16700Schasinglulu 978*91f16700Schasinglulu /* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */ 979*91f16700Schasinglulu if ((timing_config->freq <= TDFI_LAT_THRESHOLD_FREQ) && 980*91f16700Schasinglulu (pdram_timing->cl >= 5)) 981*91f16700Schasinglulu tmp = pdram_timing->cl - 5; 982*91f16700Schasinglulu else 983*91f16700Schasinglulu tmp = pdram_timing->cl - 2; 984*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 314), 0xff << 16, tmp << 16); 985*91f16700Schasinglulu } 986*91f16700Schasinglulu } 987*91f16700Schasinglulu 988*91f16700Schasinglulu static void gen_rk3399_enable_training(uint32_t ch_cnt, uint32_t nmhz) 989*91f16700Schasinglulu { 990*91f16700Schasinglulu uint32_t i, tmp; 991*91f16700Schasinglulu 992*91f16700Schasinglulu if (nmhz <= PHY_DLL_BYPASS_FREQ) 993*91f16700Schasinglulu tmp = 0; 994*91f16700Schasinglulu else 995*91f16700Schasinglulu tmp = 1; 996*91f16700Schasinglulu 997*91f16700Schasinglulu for (i = 0; i < ch_cnt; i++) { 998*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 305), 1 << 16, tmp << 16); 999*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 71), 1, tmp); 1000*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 70), 1 << 8, 1 << 8); 1001*91f16700Schasinglulu } 1002*91f16700Schasinglulu } 1003*91f16700Schasinglulu 1004*91f16700Schasinglulu static void gen_rk3399_disable_training(uint32_t ch_cnt) 1005*91f16700Schasinglulu { 1006*91f16700Schasinglulu uint32_t i; 1007*91f16700Schasinglulu 1008*91f16700Schasinglulu for (i = 0; i < ch_cnt; i++) { 1009*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 305), 1 << 16); 1010*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 71), 1); 1011*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 70), 1 << 8); 1012*91f16700Schasinglulu } 1013*91f16700Schasinglulu } 1014*91f16700Schasinglulu 1015*91f16700Schasinglulu static void gen_rk3399_ctl_params(struct timing_related_config *timing_config, 1016*91f16700Schasinglulu struct dram_timing_t *pdram_timing, 1017*91f16700Schasinglulu uint32_t fn) 1018*91f16700Schasinglulu { 1019*91f16700Schasinglulu if (fn == 0) 1020*91f16700Schasinglulu gen_rk3399_ctl_params_f0(timing_config, pdram_timing); 1021*91f16700Schasinglulu else 1022*91f16700Schasinglulu gen_rk3399_ctl_params_f1(timing_config, pdram_timing); 1023*91f16700Schasinglulu } 1024*91f16700Schasinglulu 1025*91f16700Schasinglulu static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config, 1026*91f16700Schasinglulu struct dram_timing_t *pdram_timing) 1027*91f16700Schasinglulu { 1028*91f16700Schasinglulu uint32_t tmp, tmp1, tmp2; 1029*91f16700Schasinglulu uint32_t i; 1030*91f16700Schasinglulu 1031*91f16700Schasinglulu for (i = 0; i < timing_config->ch_cnt; i++) { 1032*91f16700Schasinglulu /* PI_02 PI_TDFI_PHYMSTR_MAX_F0:RW:0:32 */ 1033*91f16700Schasinglulu tmp = 4 * pdram_timing->trefi; 1034*91f16700Schasinglulu mmio_write_32(PI_REG(i, 2), tmp); 1035*91f16700Schasinglulu /* PI_03 PI_TDFI_PHYMSTR_RESP_F0:RW:0:16 */ 1036*91f16700Schasinglulu tmp = 2 * pdram_timing->trefi; 1037*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 3), 0xffff, tmp); 1038*91f16700Schasinglulu /* PI_07 PI_TDFI_PHYUPD_RESP_F0:RW:16:16 */ 1039*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 7), 0xffffu << 16, tmp << 16); 1040*91f16700Schasinglulu 1041*91f16700Schasinglulu /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F0:RW:0:8 */ 1042*91f16700Schasinglulu if (timing_config->dram_type == LPDDR4) 1043*91f16700Schasinglulu tmp = 2; 1044*91f16700Schasinglulu else 1045*91f16700Schasinglulu tmp = 0; 1046*91f16700Schasinglulu tmp = (pdram_timing->bl / 2) + 4 + 1047*91f16700Schasinglulu (get_pi_rdlat_adj(pdram_timing) - 2) + tmp + 1048*91f16700Schasinglulu get_pi_tdfi_phy_rdlat(pdram_timing, timing_config); 1049*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 42), 0xff, tmp); 1050*91f16700Schasinglulu /* PI_43 PI_WRLAT_F0:RW:0:5 */ 1051*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) { 1052*91f16700Schasinglulu tmp = get_pi_wrlat(pdram_timing, timing_config); 1053*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 43), 0x1f, tmp); 1054*91f16700Schasinglulu } 1055*91f16700Schasinglulu /* PI_43 PI_ADDITIVE_LAT_F0:RW:8:6 */ 1056*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 43), 0x3f << 8, 1057*91f16700Schasinglulu PI_ADD_LATENCY << 8); 1058*91f16700Schasinglulu 1059*91f16700Schasinglulu /* PI_43 PI_CASLAT_LIN_F0:RW:16:7 */ 1060*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 43), 0x7f << 16, 1061*91f16700Schasinglulu (pdram_timing->cl * 2) << 16); 1062*91f16700Schasinglulu /* PI_46 PI_TREF_F0:RW:16:16 */ 1063*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 46), 0xffffu << 16, 1064*91f16700Schasinglulu pdram_timing->trefi << 16); 1065*91f16700Schasinglulu /* PI_46 PI_TRFC_F0:RW:0:10 */ 1066*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 46), 0x3ff, pdram_timing->trfc); 1067*91f16700Schasinglulu /* PI_66 PI_TODTL_2CMD_F0:RW:24:8 */ 1068*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) { 1069*91f16700Schasinglulu tmp = get_pi_todtoff_max(pdram_timing, timing_config); 1070*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 66), 0xffu << 24, 1071*91f16700Schasinglulu tmp << 24); 1072*91f16700Schasinglulu } 1073*91f16700Schasinglulu /* PI_72 PI_WR_TO_ODTH_F0:RW:16:6 */ 1074*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 1075*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 1076*91f16700Schasinglulu tmp1 = get_pi_wrlat(pdram_timing, timing_config); 1077*91f16700Schasinglulu tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1078*91f16700Schasinglulu if (tmp1 > tmp2) 1079*91f16700Schasinglulu tmp = tmp1 - tmp2; 1080*91f16700Schasinglulu else 1081*91f16700Schasinglulu tmp = 0; 1082*91f16700Schasinglulu } else if (timing_config->dram_type == DDR3) { 1083*91f16700Schasinglulu tmp = 0; 1084*91f16700Schasinglulu } 1085*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 72), 0x3f << 16, tmp << 16); 1086*91f16700Schasinglulu /* PI_73 PI_RD_TO_ODTH_F0:RW:8:6 */ 1087*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 1088*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 1089*91f16700Schasinglulu /* min_rl_preamble = cl + TDQSCK_MIN - 1 */ 1090*91f16700Schasinglulu tmp1 = pdram_timing->cl; 1091*91f16700Schasinglulu tmp1 += get_pi_todtoff_min(pdram_timing, timing_config); 1092*91f16700Schasinglulu tmp1--; 1093*91f16700Schasinglulu /* todtoff_max */ 1094*91f16700Schasinglulu tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1095*91f16700Schasinglulu if (tmp1 > tmp2) 1096*91f16700Schasinglulu tmp = tmp1 - tmp2; 1097*91f16700Schasinglulu else 1098*91f16700Schasinglulu tmp = 0; 1099*91f16700Schasinglulu } else if (timing_config->dram_type == DDR3) { 1100*91f16700Schasinglulu tmp = pdram_timing->cl - pdram_timing->cwl; 1101*91f16700Schasinglulu } 1102*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 73), 0x3f << 8, tmp << 8); 1103*91f16700Schasinglulu /* PI_89 PI_RDLAT_ADJ_F0:RW:16:8 */ 1104*91f16700Schasinglulu tmp = get_pi_rdlat_adj(pdram_timing); 1105*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 89), 0xff << 16, tmp << 16); 1106*91f16700Schasinglulu /* PI_90 PI_WRLAT_ADJ_F0:RW:16:8 */ 1107*91f16700Schasinglulu tmp = get_pi_wrlat_adj(pdram_timing, timing_config); 1108*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 90), 0xff << 16, tmp << 16); 1109*91f16700Schasinglulu /* PI_91 PI_TDFI_WRCSLAT_F0:RW:16:8 */ 1110*91f16700Schasinglulu tmp1 = tmp; 1111*91f16700Schasinglulu if (tmp1 == 0) 1112*91f16700Schasinglulu tmp = 0; 1113*91f16700Schasinglulu else if (tmp1 < 5) 1114*91f16700Schasinglulu tmp = tmp1 - 1; 1115*91f16700Schasinglulu else 1116*91f16700Schasinglulu tmp = tmp1 - 5; 1117*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 91), 0xff << 16, tmp << 16); 1118*91f16700Schasinglulu /* PI_95 PI_TDFI_CALVL_CAPTURE_F0:RW:16:10 */ 1119*91f16700Schasinglulu tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 1120*91f16700Schasinglulu if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 1121*91f16700Schasinglulu tmp1++; 1122*91f16700Schasinglulu tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 1123*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 95), 0x3ff << 16, tmp << 16); 1124*91f16700Schasinglulu /* PI_95 PI_TDFI_CALVL_CC_F0:RW:0:10 */ 1125*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 95), 0x3ff, tmp + 18); 1126*91f16700Schasinglulu /* PI_102 PI_TMRZ_F0:RW:8:5 */ 1127*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 102), 0x1f << 8, 1128*91f16700Schasinglulu pdram_timing->tmrz << 8); 1129*91f16700Schasinglulu /* PI_111 PI_TDFI_CALVL_STROBE_F0:RW:8:4 */ 1130*91f16700Schasinglulu tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz); 1131*91f16700Schasinglulu if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0) 1132*91f16700Schasinglulu tmp1++; 1133*91f16700Schasinglulu /* pi_tdfi_calvl_strobe=tds_train+5 */ 1134*91f16700Schasinglulu tmp = tmp1 + 5; 1135*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 111), 0xf << 8, tmp << 8); 1136*91f16700Schasinglulu /* PI_116 PI_TCKEHDQS_F0:RW:16:6 */ 1137*91f16700Schasinglulu tmp = 10000 / (1000000 / pdram_timing->mhz); 1138*91f16700Schasinglulu if ((10000 % (1000000 / pdram_timing->mhz)) != 0) 1139*91f16700Schasinglulu tmp++; 1140*91f16700Schasinglulu if (pdram_timing->mhz <= 100) 1141*91f16700Schasinglulu tmp = tmp + 1; 1142*91f16700Schasinglulu else 1143*91f16700Schasinglulu tmp = tmp + 8; 1144*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 116), 0x3f << 16, tmp << 16); 1145*91f16700Schasinglulu /* PI_125 PI_MR1_DATA_F0_0:RW+:8:16 */ 1146*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 125), 0xffff << 8, 1147*91f16700Schasinglulu pdram_timing->mr[1] << 8); 1148*91f16700Schasinglulu /* PI_133 PI_MR1_DATA_F0_1:RW+:0:16 */ 1149*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 133), 0xffff, pdram_timing->mr[1]); 1150*91f16700Schasinglulu /* PI_140 PI_MR1_DATA_F0_2:RW+:16:16 */ 1151*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 140), 0xffffu << 16, 1152*91f16700Schasinglulu pdram_timing->mr[1] << 16); 1153*91f16700Schasinglulu /* PI_148 PI_MR1_DATA_F0_3:RW+:0:16 */ 1154*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 148), 0xffff, pdram_timing->mr[1]); 1155*91f16700Schasinglulu /* PI_126 PI_MR2_DATA_F0_0:RW+:0:16 */ 1156*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 126), 0xffff, pdram_timing->mr[2]); 1157*91f16700Schasinglulu /* PI_133 PI_MR2_DATA_F0_1:RW+:16:16 */ 1158*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 133), 0xffffu << 16, 1159*91f16700Schasinglulu pdram_timing->mr[2] << 16); 1160*91f16700Schasinglulu /* PI_141 PI_MR2_DATA_F0_2:RW+:0:16 */ 1161*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 141), 0xffff, pdram_timing->mr[2]); 1162*91f16700Schasinglulu /* PI_148 PI_MR2_DATA_F0_3:RW+:16:16 */ 1163*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 148), 0xffffu << 16, 1164*91f16700Schasinglulu pdram_timing->mr[2] << 16); 1165*91f16700Schasinglulu /* PI_156 PI_TFC_F0:RW:0:10 */ 1166*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff, 1167*91f16700Schasinglulu pdram_timing->tfc_long); 1168*91f16700Schasinglulu /* PI_158 PI_TWR_F0:RW:24:6 */ 1169*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 158), 0x3f << 24, 1170*91f16700Schasinglulu pdram_timing->twr << 24); 1171*91f16700Schasinglulu /* PI_158 PI_TWTR_F0:RW:16:6 */ 1172*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 158), 0x3f << 16, 1173*91f16700Schasinglulu pdram_timing->twtr << 16); 1174*91f16700Schasinglulu /* PI_158 PI_TRCD_F0:RW:8:8 */ 1175*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 158), 0xff << 8, 1176*91f16700Schasinglulu pdram_timing->trcd << 8); 1177*91f16700Schasinglulu /* PI_158 PI_TRP_F0:RW:0:8 */ 1178*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 158), 0xff, pdram_timing->trp); 1179*91f16700Schasinglulu /* PI_157 PI_TRTP_F0:RW:24:8 */ 1180*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 157), 0xffu << 24, 1181*91f16700Schasinglulu pdram_timing->trtp << 24); 1182*91f16700Schasinglulu /* PI_159 PI_TRAS_MIN_F0:RW:24:8 */ 1183*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 159), 0xffu << 24, 1184*91f16700Schasinglulu pdram_timing->tras_min << 24); 1185*91f16700Schasinglulu /* PI_159 PI_TRAS_MAX_F0:RW:0:17 */ 1186*91f16700Schasinglulu tmp = pdram_timing->tras_max * 99 / 100; 1187*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 159), 0x1ffff, tmp); 1188*91f16700Schasinglulu /* PI_160 PI_TMRD_F0:RW:16:6 */ 1189*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 160), 0x3f << 16, 1190*91f16700Schasinglulu pdram_timing->tmrd << 16); 1191*91f16700Schasinglulu /*PI_160 PI_TDQSCK_MAX_F0:RW:0:4 */ 1192*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 160), 0xf, 1193*91f16700Schasinglulu pdram_timing->tdqsck_max); 1194*91f16700Schasinglulu /* PI_187 PI_TDFI_CTRLUPD_MAX_F0:RW:8:16 */ 1195*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 187), 0xffff << 8, 1196*91f16700Schasinglulu (2 * pdram_timing->trefi) << 8); 1197*91f16700Schasinglulu /* PI_188 PI_TDFI_CTRLUPD_INTERVAL_F0:RW:0:32 */ 1198*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 188), 0xffffffff, 1199*91f16700Schasinglulu 20 * pdram_timing->trefi); 1200*91f16700Schasinglulu } 1201*91f16700Schasinglulu } 1202*91f16700Schasinglulu 1203*91f16700Schasinglulu static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config, 1204*91f16700Schasinglulu struct dram_timing_t *pdram_timing) 1205*91f16700Schasinglulu { 1206*91f16700Schasinglulu uint32_t tmp, tmp1, tmp2; 1207*91f16700Schasinglulu uint32_t i; 1208*91f16700Schasinglulu 1209*91f16700Schasinglulu for (i = 0; i < timing_config->ch_cnt; i++) { 1210*91f16700Schasinglulu /* PI_04 PI_TDFI_PHYMSTR_MAX_F1:RW:0:32 */ 1211*91f16700Schasinglulu tmp = 4 * pdram_timing->trefi; 1212*91f16700Schasinglulu mmio_write_32(PI_REG(i, 4), tmp); 1213*91f16700Schasinglulu /* PI_05 PI_TDFI_PHYMSTR_RESP_F1:RW:0:16 */ 1214*91f16700Schasinglulu tmp = 2 * pdram_timing->trefi; 1215*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 5), 0xffff, tmp); 1216*91f16700Schasinglulu /* PI_12 PI_TDFI_PHYUPD_RESP_F1:RW:0:16 */ 1217*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 12), 0xffff, tmp); 1218*91f16700Schasinglulu 1219*91f16700Schasinglulu /* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F1:RW:8:8 */ 1220*91f16700Schasinglulu if (timing_config->dram_type == LPDDR4) 1221*91f16700Schasinglulu tmp = 2; 1222*91f16700Schasinglulu else 1223*91f16700Schasinglulu tmp = 0; 1224*91f16700Schasinglulu tmp = (pdram_timing->bl / 2) + 4 + 1225*91f16700Schasinglulu (get_pi_rdlat_adj(pdram_timing) - 2) + tmp + 1226*91f16700Schasinglulu get_pi_tdfi_phy_rdlat(pdram_timing, timing_config); 1227*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 42), 0xff << 8, tmp << 8); 1228*91f16700Schasinglulu /* PI_43 PI_WRLAT_F1:RW:24:5 */ 1229*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) { 1230*91f16700Schasinglulu tmp = get_pi_wrlat(pdram_timing, timing_config); 1231*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 43), 0x1f << 24, 1232*91f16700Schasinglulu tmp << 24); 1233*91f16700Schasinglulu } 1234*91f16700Schasinglulu /* PI_44 PI_ADDITIVE_LAT_F1:RW:0:6 */ 1235*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 44), 0x3f, PI_ADD_LATENCY); 1236*91f16700Schasinglulu /* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */ 1237*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 44), 0x7f << 8, 1238*91f16700Schasinglulu (pdram_timing->cl * 2) << 8); 1239*91f16700Schasinglulu /* PI_47 PI_TREF_F1:RW:16:16 */ 1240*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 47), 0xffffu << 16, 1241*91f16700Schasinglulu pdram_timing->trefi << 16); 1242*91f16700Schasinglulu /* PI_47 PI_TRFC_F1:RW:0:10 */ 1243*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 47), 0x3ff, pdram_timing->trfc); 1244*91f16700Schasinglulu /* PI_67 PI_TODTL_2CMD_F1:RW:8:8 */ 1245*91f16700Schasinglulu if (timing_config->dram_type == LPDDR3) { 1246*91f16700Schasinglulu tmp = get_pi_todtoff_max(pdram_timing, timing_config); 1247*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 67), 0xff << 8, tmp << 8); 1248*91f16700Schasinglulu } 1249*91f16700Schasinglulu /* PI_72 PI_WR_TO_ODTH_F1:RW:24:6 */ 1250*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 1251*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 1252*91f16700Schasinglulu tmp1 = get_pi_wrlat(pdram_timing, timing_config); 1253*91f16700Schasinglulu tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1254*91f16700Schasinglulu if (tmp1 > tmp2) 1255*91f16700Schasinglulu tmp = tmp1 - tmp2; 1256*91f16700Schasinglulu else 1257*91f16700Schasinglulu tmp = 0; 1258*91f16700Schasinglulu } else if (timing_config->dram_type == DDR3) { 1259*91f16700Schasinglulu tmp = 0; 1260*91f16700Schasinglulu } 1261*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 72), 0x3f << 24, tmp << 24); 1262*91f16700Schasinglulu /* PI_73 PI_RD_TO_ODTH_F1:RW:16:6 */ 1263*91f16700Schasinglulu if ((timing_config->dram_type == LPDDR3) || 1264*91f16700Schasinglulu (timing_config->dram_type == LPDDR4)) { 1265*91f16700Schasinglulu /* min_rl_preamble = cl + TDQSCK_MIN - 1 */ 1266*91f16700Schasinglulu tmp1 = pdram_timing->cl + 1267*91f16700Schasinglulu get_pi_todtoff_min(pdram_timing, timing_config); 1268*91f16700Schasinglulu tmp1--; 1269*91f16700Schasinglulu /* todtoff_max */ 1270*91f16700Schasinglulu tmp2 = get_pi_todtoff_max(pdram_timing, timing_config); 1271*91f16700Schasinglulu if (tmp1 > tmp2) 1272*91f16700Schasinglulu tmp = tmp1 - tmp2; 1273*91f16700Schasinglulu else 1274*91f16700Schasinglulu tmp = 0; 1275*91f16700Schasinglulu } else if (timing_config->dram_type == DDR3) 1276*91f16700Schasinglulu tmp = pdram_timing->cl - pdram_timing->cwl; 1277*91f16700Schasinglulu 1278*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 73), 0x3f << 16, tmp << 16); 1279*91f16700Schasinglulu /*P I_89 PI_RDLAT_ADJ_F1:RW:24:8 */ 1280*91f16700Schasinglulu tmp = get_pi_rdlat_adj(pdram_timing); 1281*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 89), 0xffu << 24, tmp << 24); 1282*91f16700Schasinglulu /* PI_90 PI_WRLAT_ADJ_F1:RW:24:8 */ 1283*91f16700Schasinglulu tmp = get_pi_wrlat_adj(pdram_timing, timing_config); 1284*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 90), 0xffu << 24, tmp << 24); 1285*91f16700Schasinglulu /* PI_91 PI_TDFI_WRCSLAT_F1:RW:24:8 */ 1286*91f16700Schasinglulu tmp1 = tmp; 1287*91f16700Schasinglulu if (tmp1 == 0) 1288*91f16700Schasinglulu tmp = 0; 1289*91f16700Schasinglulu else if (tmp1 < 5) 1290*91f16700Schasinglulu tmp = tmp1 - 1; 1291*91f16700Schasinglulu else 1292*91f16700Schasinglulu tmp = tmp1 - 5; 1293*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 91), 0xffu << 24, tmp << 24); 1294*91f16700Schasinglulu /*PI_96 PI_TDFI_CALVL_CAPTURE_F1:RW:16:10 */ 1295*91f16700Schasinglulu /* tadr=20ns */ 1296*91f16700Schasinglulu tmp1 = 20000 / (1000000 / pdram_timing->mhz) + 1; 1297*91f16700Schasinglulu if ((20000 % (1000000 / pdram_timing->mhz)) != 0) 1298*91f16700Schasinglulu tmp1++; 1299*91f16700Schasinglulu tmp = (tmp1 >> 1) + (tmp1 % 2) + 5; 1300*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 96), 0x3ff << 16, tmp << 16); 1301*91f16700Schasinglulu /* PI_96 PI_TDFI_CALVL_CC_F1:RW:0:10 */ 1302*91f16700Schasinglulu tmp = tmp + 18; 1303*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 96), 0x3ff, tmp); 1304*91f16700Schasinglulu /*PI_103 PI_TMRZ_F1:RW:0:5 */ 1305*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 103), 0x1f, pdram_timing->tmrz); 1306*91f16700Schasinglulu /*PI_111 PI_TDFI_CALVL_STROBE_F1:RW:16:4 */ 1307*91f16700Schasinglulu /* tds_train=ceil(2/ns) */ 1308*91f16700Schasinglulu tmp1 = 2 * 1000 / (1000000 / pdram_timing->mhz); 1309*91f16700Schasinglulu if ((2 * 1000 % (1000000 / pdram_timing->mhz)) != 0) 1310*91f16700Schasinglulu tmp1++; 1311*91f16700Schasinglulu /* pi_tdfi_calvl_strobe=tds_train+5 */ 1312*91f16700Schasinglulu tmp = tmp1 + 5; 1313*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 111), 0xf << 16, 1314*91f16700Schasinglulu tmp << 16); 1315*91f16700Schasinglulu /* PI_116 PI_TCKEHDQS_F1:RW:24:6 */ 1316*91f16700Schasinglulu tmp = 10000 / (1000000 / pdram_timing->mhz); 1317*91f16700Schasinglulu if ((10000 % (1000000 / pdram_timing->mhz)) != 0) 1318*91f16700Schasinglulu tmp++; 1319*91f16700Schasinglulu if (pdram_timing->mhz <= 100) 1320*91f16700Schasinglulu tmp = tmp + 1; 1321*91f16700Schasinglulu else 1322*91f16700Schasinglulu tmp = tmp + 8; 1323*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 116), 0x3f << 24, 1324*91f16700Schasinglulu tmp << 24); 1325*91f16700Schasinglulu /* PI_128 PI_MR1_DATA_F1_0:RW+:0:16 */ 1326*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 128), 0xffff, pdram_timing->mr[1]); 1327*91f16700Schasinglulu /* PI_135 PI_MR1_DATA_F1_1:RW+:8:16 */ 1328*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 135), 0xffff << 8, 1329*91f16700Schasinglulu pdram_timing->mr[1] << 8); 1330*91f16700Schasinglulu /* PI_143 PI_MR1_DATA_F1_2:RW+:0:16 */ 1331*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 143), 0xffff, pdram_timing->mr[1]); 1332*91f16700Schasinglulu /* PI_150 PI_MR1_DATA_F1_3:RW+:8:16 */ 1333*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 150), 0xffff << 8, 1334*91f16700Schasinglulu pdram_timing->mr[1] << 8); 1335*91f16700Schasinglulu /* PI_128 PI_MR2_DATA_F1_0:RW+:16:16 */ 1336*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 128), 0xffffu << 16, 1337*91f16700Schasinglulu pdram_timing->mr[2] << 16); 1338*91f16700Schasinglulu /* PI_136 PI_MR2_DATA_F1_1:RW+:0:16 */ 1339*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 136), 0xffff, pdram_timing->mr[2]); 1340*91f16700Schasinglulu /* PI_143 PI_MR2_DATA_F1_2:RW+:16:16 */ 1341*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 143), 0xffffu << 16, 1342*91f16700Schasinglulu pdram_timing->mr[2] << 16); 1343*91f16700Schasinglulu /* PI_151 PI_MR2_DATA_F1_3:RW+:0:16 */ 1344*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 151), 0xffff, pdram_timing->mr[2]); 1345*91f16700Schasinglulu /* PI_156 PI_TFC_F1:RW:16:10 */ 1346*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 156), 0x3ff << 16, 1347*91f16700Schasinglulu pdram_timing->tfc_long << 16); 1348*91f16700Schasinglulu /* PI_162 PI_TWR_F1:RW:8:6 */ 1349*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 162), 0x3f << 8, 1350*91f16700Schasinglulu pdram_timing->twr << 8); 1351*91f16700Schasinglulu /* PI_162 PI_TWTR_F1:RW:0:6 */ 1352*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 162), 0x3f, pdram_timing->twtr); 1353*91f16700Schasinglulu /* PI_161 PI_TRCD_F1:RW:24:8 */ 1354*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 161), 0xffu << 24, 1355*91f16700Schasinglulu pdram_timing->trcd << 24); 1356*91f16700Schasinglulu /* PI_161 PI_TRP_F1:RW:16:8 */ 1357*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 161), 0xff << 16, 1358*91f16700Schasinglulu pdram_timing->trp << 16); 1359*91f16700Schasinglulu /* PI_161 PI_TRTP_F1:RW:8:8 */ 1360*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 161), 0xff << 8, 1361*91f16700Schasinglulu pdram_timing->trtp << 8); 1362*91f16700Schasinglulu /* PI_163 PI_TRAS_MIN_F1:RW:24:8 */ 1363*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 163), 0xffu << 24, 1364*91f16700Schasinglulu pdram_timing->tras_min << 24); 1365*91f16700Schasinglulu /* PI_163 PI_TRAS_MAX_F1:RW:0:17 */ 1366*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 163), 0x1ffff, 1367*91f16700Schasinglulu pdram_timing->tras_max * 99 / 100); 1368*91f16700Schasinglulu /* PI_164 PI_TMRD_F1:RW:16:6 */ 1369*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 164), 0x3f << 16, 1370*91f16700Schasinglulu pdram_timing->tmrd << 16); 1371*91f16700Schasinglulu /* PI_164 PI_TDQSCK_MAX_F1:RW:0:4 */ 1372*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 164), 0xf, 1373*91f16700Schasinglulu pdram_timing->tdqsck_max); 1374*91f16700Schasinglulu /* PI_189 PI_TDFI_CTRLUPD_MAX_F1:RW:0:16 */ 1375*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 189), 0xffff, 1376*91f16700Schasinglulu 2 * pdram_timing->trefi); 1377*91f16700Schasinglulu /* PI_190 PI_TDFI_CTRLUPD_INTERVAL_F1:RW:0:32 */ 1378*91f16700Schasinglulu mmio_clrsetbits_32(PI_REG(i, 190), 0xffffffff, 1379*91f16700Schasinglulu 20 * pdram_timing->trefi); 1380*91f16700Schasinglulu } 1381*91f16700Schasinglulu } 1382*91f16700Schasinglulu 1383*91f16700Schasinglulu static void gen_rk3399_pi_params(struct timing_related_config *timing_config, 1384*91f16700Schasinglulu struct dram_timing_t *pdram_timing, 1385*91f16700Schasinglulu uint32_t fn) 1386*91f16700Schasinglulu { 1387*91f16700Schasinglulu if (fn == 0) 1388*91f16700Schasinglulu gen_rk3399_pi_params_f0(timing_config, pdram_timing); 1389*91f16700Schasinglulu else 1390*91f16700Schasinglulu gen_rk3399_pi_params_f1(timing_config, pdram_timing); 1391*91f16700Schasinglulu } 1392*91f16700Schasinglulu 1393*91f16700Schasinglulu static void gen_rk3399_set_odt(uint32_t odt_en) 1394*91f16700Schasinglulu { 1395*91f16700Schasinglulu uint32_t drv_odt_val; 1396*91f16700Schasinglulu uint32_t i; 1397*91f16700Schasinglulu 1398*91f16700Schasinglulu for (i = 0; i < rk3399_dram_status.timing_config.ch_cnt; i++) { 1399*91f16700Schasinglulu drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 16; 1400*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 5), 0x7 << 16, drv_odt_val); 1401*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 133), 0x7 << 16, drv_odt_val); 1402*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 261), 0x7 << 16, drv_odt_val); 1403*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 389), 0x7 << 16, drv_odt_val); 1404*91f16700Schasinglulu drv_odt_val = (odt_en | (0 << 1) | (0 << 2)) << 24; 1405*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 6), 0x7 << 24, drv_odt_val); 1406*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 134), 0x7 << 24, drv_odt_val); 1407*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 262), 0x7 << 24, drv_odt_val); 1408*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 390), 0x7 << 24, drv_odt_val); 1409*91f16700Schasinglulu } 1410*91f16700Schasinglulu } 1411*91f16700Schasinglulu 1412*91f16700Schasinglulu static void gen_rk3399_phy_dll_bypass(uint32_t mhz, uint32_t ch, 1413*91f16700Schasinglulu uint32_t index, uint32_t dram_type) 1414*91f16700Schasinglulu { 1415*91f16700Schasinglulu uint32_t sw_master_mode = 0; 1416*91f16700Schasinglulu uint32_t rddqs_gate_delay, rddqs_latency, total_delay; 1417*91f16700Schasinglulu uint32_t i; 1418*91f16700Schasinglulu 1419*91f16700Schasinglulu if (dram_type == DDR3) 1420*91f16700Schasinglulu total_delay = PI_PAD_DELAY_PS_VALUE; 1421*91f16700Schasinglulu else if (dram_type == LPDDR3) 1422*91f16700Schasinglulu total_delay = PI_PAD_DELAY_PS_VALUE + 2500; 1423*91f16700Schasinglulu else 1424*91f16700Schasinglulu total_delay = PI_PAD_DELAY_PS_VALUE + 1500; 1425*91f16700Schasinglulu /* total_delay + 0.55tck */ 1426*91f16700Schasinglulu total_delay += (55 * 10000)/mhz; 1427*91f16700Schasinglulu rddqs_latency = total_delay * mhz / 1000000; 1428*91f16700Schasinglulu total_delay -= rddqs_latency * 1000000 / mhz; 1429*91f16700Schasinglulu rddqs_gate_delay = total_delay * 0x200 * mhz / 1000000; 1430*91f16700Schasinglulu if (mhz <= PHY_DLL_BYPASS_FREQ) { 1431*91f16700Schasinglulu sw_master_mode = 0xc; 1432*91f16700Schasinglulu mmio_setbits_32(PHY_REG(ch, 514), 1); 1433*91f16700Schasinglulu mmio_setbits_32(PHY_REG(ch, 642), 1); 1434*91f16700Schasinglulu mmio_setbits_32(PHY_REG(ch, 770), 1); 1435*91f16700Schasinglulu 1436*91f16700Schasinglulu /* setting bypass mode slave delay */ 1437*91f16700Schasinglulu for (i = 0; i < 4; i++) { 1438*91f16700Schasinglulu /* wr dq delay = -180deg + (0x60 / 4) * 20ps */ 1439*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 1 + 128 * i), 0x7ff << 8, 1440*91f16700Schasinglulu 0x4a0 << 8); 1441*91f16700Schasinglulu /* rd dqs/dq delay = (0x60 / 4) * 20ps */ 1442*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 11 + 128 * i), 0x3ff, 1443*91f16700Schasinglulu 0xa0); 1444*91f16700Schasinglulu /* rd rddqs_gate delay */ 1445*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 2 + 128 * i), 0x3ff, 1446*91f16700Schasinglulu rddqs_gate_delay); 1447*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 78 + 128 * i), 0xf, 1448*91f16700Schasinglulu rddqs_latency); 1449*91f16700Schasinglulu } 1450*91f16700Schasinglulu for (i = 0; i < 3; i++) 1451*91f16700Schasinglulu /* adr delay */ 1452*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 513 + 128 * i), 1453*91f16700Schasinglulu 0x7ff << 16, 0x80 << 16); 1454*91f16700Schasinglulu 1455*91f16700Schasinglulu if ((mmio_read_32(PHY_REG(ch, 86)) & 0xc00) == 0) { 1456*91f16700Schasinglulu /* 1457*91f16700Schasinglulu * old status is normal mode, 1458*91f16700Schasinglulu * and saving the wrdqs slave delay 1459*91f16700Schasinglulu */ 1460*91f16700Schasinglulu for (i = 0; i < 4; i++) { 1461*91f16700Schasinglulu /* save and clear wr dqs slave delay */ 1462*91f16700Schasinglulu wrdqs_delay_val[ch][index][i] = 0x3ff & 1463*91f16700Schasinglulu (mmio_read_32(PHY_REG(ch, 63 + i * 128)) 1464*91f16700Schasinglulu >> 16); 1465*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 63 + i * 128), 1466*91f16700Schasinglulu 0x03ff << 16, 0 << 16); 1467*91f16700Schasinglulu /* 1468*91f16700Schasinglulu * in normal mode the cmd may delay 1cycle by 1469*91f16700Schasinglulu * wrlvl and in bypass mode making dqs also 1470*91f16700Schasinglulu * delay 1cycle. 1471*91f16700Schasinglulu */ 1472*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 78 + i * 128), 1473*91f16700Schasinglulu 0x07 << 8, 0x1 << 8); 1474*91f16700Schasinglulu } 1475*91f16700Schasinglulu } 1476*91f16700Schasinglulu } else if (mmio_read_32(PHY_REG(ch, 86)) & 0xc00) { 1477*91f16700Schasinglulu /* old status is bypass mode and restore wrlvl resume */ 1478*91f16700Schasinglulu for (i = 0; i < 4; i++) { 1479*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 63 + i * 128), 1480*91f16700Schasinglulu 0x03ff << 16, 1481*91f16700Schasinglulu (wrdqs_delay_val[ch][index][i] & 1482*91f16700Schasinglulu 0x3ff) << 16); 1483*91f16700Schasinglulu /* resume phy_write_path_lat_add */ 1484*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(ch, 78 + i * 128), 0x07 << 8); 1485*91f16700Schasinglulu } 1486*91f16700Schasinglulu } 1487*91f16700Schasinglulu 1488*91f16700Schasinglulu /* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */ 1489*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 86), 0xf << 8, sw_master_mode << 8); 1490*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 214), 0xf << 8, sw_master_mode << 8); 1491*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 342), 0xf << 8, sw_master_mode << 8); 1492*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 470), 0xf << 8, sw_master_mode << 8); 1493*91f16700Schasinglulu 1494*91f16700Schasinglulu /* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */ 1495*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 547), 0xf << 16, sw_master_mode << 16); 1496*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 675), 0xf << 16, sw_master_mode << 16); 1497*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(ch, 803), 0xf << 16, sw_master_mode << 16); 1498*91f16700Schasinglulu } 1499*91f16700Schasinglulu 1500*91f16700Schasinglulu static void gen_rk3399_phy_params(struct timing_related_config *timing_config, 1501*91f16700Schasinglulu struct drv_odt_lp_config *drv_config, 1502*91f16700Schasinglulu struct dram_timing_t *pdram_timing, 1503*91f16700Schasinglulu uint32_t fn) 1504*91f16700Schasinglulu { 1505*91f16700Schasinglulu uint32_t tmp, i, div, j; 1506*91f16700Schasinglulu uint32_t mem_delay_ps, pad_delay_ps, total_delay_ps, delay_frac_ps; 1507*91f16700Schasinglulu uint32_t trpre_min_ps, gate_delay_ps, gate_delay_frac_ps; 1508*91f16700Schasinglulu uint32_t ie_enable, tsel_enable, cas_lat, rddata_en_ie_dly, tsel_adder; 1509*91f16700Schasinglulu uint32_t extra_adder, delta, hs_offset; 1510*91f16700Schasinglulu 1511*91f16700Schasinglulu for (i = 0; i < timing_config->ch_cnt; i++) { 1512*91f16700Schasinglulu 1513*91f16700Schasinglulu pad_delay_ps = PI_PAD_DELAY_PS_VALUE; 1514*91f16700Schasinglulu ie_enable = PI_IE_ENABLE_VALUE; 1515*91f16700Schasinglulu tsel_enable = PI_TSEL_ENABLE_VALUE; 1516*91f16700Schasinglulu 1517*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 896), (0x3 << 8) | 1, fn << 8); 1518*91f16700Schasinglulu 1519*91f16700Schasinglulu /* PHY_LOW_FREQ_SEL */ 1520*91f16700Schasinglulu /* DENALI_PHY_913 1bit offset_0 */ 1521*91f16700Schasinglulu if (timing_config->freq > 400) 1522*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(i, 913), 1); 1523*91f16700Schasinglulu else 1524*91f16700Schasinglulu mmio_setbits_32(PHY_REG(i, 913), 1); 1525*91f16700Schasinglulu 1526*91f16700Schasinglulu /* PHY_RPTR_UPDATE_x */ 1527*91f16700Schasinglulu /* DENALI_PHY_87/215/343/471 4bit offset_16 */ 1528*91f16700Schasinglulu tmp = 2500 / (1000000 / pdram_timing->mhz) + 3; 1529*91f16700Schasinglulu if ((2500 % (1000000 / pdram_timing->mhz)) != 0) 1530*91f16700Schasinglulu tmp++; 1531*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 87), 0xf << 16, tmp << 16); 1532*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 215), 0xf << 16, tmp << 16); 1533*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 343), 0xf << 16, tmp << 16); 1534*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 471), 0xf << 16, tmp << 16); 1535*91f16700Schasinglulu 1536*91f16700Schasinglulu /* PHY_PLL_CTRL */ 1537*91f16700Schasinglulu /* DENALI_PHY_911 13bits offset_0 */ 1538*91f16700Schasinglulu /* PHY_LP4_BOOT_PLL_CTRL */ 1539*91f16700Schasinglulu /* DENALI_PHY_919 13bits offset_0 */ 1540*91f16700Schasinglulu tmp = (1 << 12) | (2 << 7) | (1 << 1); 1541*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff, tmp); 1542*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff, tmp); 1543*91f16700Schasinglulu 1544*91f16700Schasinglulu /* PHY_PLL_CTRL_CA */ 1545*91f16700Schasinglulu /* DENALI_PHY_911 13bits offset_16 */ 1546*91f16700Schasinglulu /* PHY_LP4_BOOT_PLL_CTRL_CA */ 1547*91f16700Schasinglulu /* DENALI_PHY_919 13bits offset_16 */ 1548*91f16700Schasinglulu tmp = (2 << 7) | (1 << 5) | (1 << 1); 1549*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 911), 0x1fff << 16, tmp << 16); 1550*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 919), 0x1fff << 16, tmp << 16); 1551*91f16700Schasinglulu 1552*91f16700Schasinglulu /* PHY_TCKSRE_WAIT */ 1553*91f16700Schasinglulu /* DENALI_PHY_922 4bits offset_24 */ 1554*91f16700Schasinglulu if (pdram_timing->mhz <= 400) 1555*91f16700Schasinglulu tmp = 1; 1556*91f16700Schasinglulu else if (pdram_timing->mhz <= 800) 1557*91f16700Schasinglulu tmp = 3; 1558*91f16700Schasinglulu else if (pdram_timing->mhz <= 1000) 1559*91f16700Schasinglulu tmp = 4; 1560*91f16700Schasinglulu else 1561*91f16700Schasinglulu tmp = 5; 1562*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 922), 0xf << 24, tmp << 24); 1563*91f16700Schasinglulu /* PHY_CAL_CLK_SELECT_0:RW8:3 */ 1564*91f16700Schasinglulu div = pdram_timing->mhz / (2 * 20); 1565*91f16700Schasinglulu for (j = 2, tmp = 1; j <= 128; j <<= 1, tmp++) { 1566*91f16700Schasinglulu if (div < j) 1567*91f16700Schasinglulu break; 1568*91f16700Schasinglulu } 1569*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 947), 0x7 << 8, tmp << 8); 1570*91f16700Schasinglulu 1571*91f16700Schasinglulu if (timing_config->dram_type == DDR3) { 1572*91f16700Schasinglulu mem_delay_ps = 0; 1573*91f16700Schasinglulu trpre_min_ps = 1000; 1574*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR4) { 1575*91f16700Schasinglulu mem_delay_ps = 1500; 1576*91f16700Schasinglulu trpre_min_ps = 900; 1577*91f16700Schasinglulu } else if (timing_config->dram_type == LPDDR3) { 1578*91f16700Schasinglulu mem_delay_ps = 2500; 1579*91f16700Schasinglulu trpre_min_ps = 900; 1580*91f16700Schasinglulu } else { 1581*91f16700Schasinglulu ERROR("gen_rk3399_phy_params:dramtype unsupport\n"); 1582*91f16700Schasinglulu return; 1583*91f16700Schasinglulu } 1584*91f16700Schasinglulu total_delay_ps = mem_delay_ps + pad_delay_ps; 1585*91f16700Schasinglulu delay_frac_ps = 1000 * total_delay_ps / 1586*91f16700Schasinglulu (1000000 / pdram_timing->mhz); 1587*91f16700Schasinglulu gate_delay_ps = delay_frac_ps + 1000 - (trpre_min_ps / 2); 1588*91f16700Schasinglulu gate_delay_frac_ps = gate_delay_ps % 1000; 1589*91f16700Schasinglulu tmp = gate_delay_frac_ps * 0x200 / 1000; 1590*91f16700Schasinglulu /* PHY_RDDQS_GATE_SLAVE_DELAY */ 1591*91f16700Schasinglulu /* DENALI_PHY_77/205/333/461 10bits offset_16 */ 1592*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 77), 0x2ff << 16, tmp << 16); 1593*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 205), 0x2ff << 16, tmp << 16); 1594*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 333), 0x2ff << 16, tmp << 16); 1595*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 461), 0x2ff << 16, tmp << 16); 1596*91f16700Schasinglulu 1597*91f16700Schasinglulu tmp = gate_delay_ps / 1000; 1598*91f16700Schasinglulu /* PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST */ 1599*91f16700Schasinglulu /* DENALI_PHY_10/138/266/394 4bit offset_0 */ 1600*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 10), 0xf, tmp); 1601*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 138), 0xf, tmp); 1602*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 266), 0xf, tmp); 1603*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 394), 0xf, tmp); 1604*91f16700Schasinglulu /* PHY_GTLVL_LAT_ADJ_START */ 1605*91f16700Schasinglulu /* DENALI_PHY_80/208/336/464 4bits offset_16 */ 1606*91f16700Schasinglulu tmp = rddqs_delay_ps / (1000000 / pdram_timing->mhz) + 2; 1607*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 80), 0xf << 16, tmp << 16); 1608*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 208), 0xf << 16, tmp << 16); 1609*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 336), 0xf << 16, tmp << 16); 1610*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 464), 0xf << 16, tmp << 16); 1611*91f16700Schasinglulu 1612*91f16700Schasinglulu cas_lat = pdram_timing->cl + PI_ADD_LATENCY; 1613*91f16700Schasinglulu rddata_en_ie_dly = ie_enable / (1000000 / pdram_timing->mhz); 1614*91f16700Schasinglulu if ((ie_enable % (1000000 / pdram_timing->mhz)) != 0) 1615*91f16700Schasinglulu rddata_en_ie_dly++; 1616*91f16700Schasinglulu rddata_en_ie_dly = rddata_en_ie_dly - 1; 1617*91f16700Schasinglulu tsel_adder = tsel_enable / (1000000 / pdram_timing->mhz); 1618*91f16700Schasinglulu if ((tsel_enable % (1000000 / pdram_timing->mhz)) != 0) 1619*91f16700Schasinglulu tsel_adder++; 1620*91f16700Schasinglulu if (rddata_en_ie_dly > tsel_adder) 1621*91f16700Schasinglulu extra_adder = rddata_en_ie_dly - tsel_adder; 1622*91f16700Schasinglulu else 1623*91f16700Schasinglulu extra_adder = 0; 1624*91f16700Schasinglulu delta = cas_lat - rddata_en_ie_dly; 1625*91f16700Schasinglulu if (PI_REGS_DIMM_SUPPORT && PI_DOUBLEFREEK) 1626*91f16700Schasinglulu hs_offset = 2; 1627*91f16700Schasinglulu else 1628*91f16700Schasinglulu hs_offset = 1; 1629*91f16700Schasinglulu if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset)) 1630*91f16700Schasinglulu tmp = 0; 1631*91f16700Schasinglulu else if ((delta == 2) || (delta == 1)) 1632*91f16700Schasinglulu tmp = rddata_en_ie_dly - 0 - extra_adder; 1633*91f16700Schasinglulu else 1634*91f16700Schasinglulu tmp = extra_adder; 1635*91f16700Schasinglulu /* PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY */ 1636*91f16700Schasinglulu /* DENALI_PHY_9/137/265/393 4bit offset_16 */ 1637*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 9), 0xf << 16, tmp << 16); 1638*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 137), 0xf << 16, tmp << 16); 1639*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 265), 0xf << 16, tmp << 16); 1640*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 393), 0xf << 16, tmp << 16); 1641*91f16700Schasinglulu /* PHY_RDDATA_EN_TSEL_DLY */ 1642*91f16700Schasinglulu /* DENALI_PHY_86/214/342/470 4bit offset_0 */ 1643*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 86), 0xf, tmp); 1644*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 214), 0xf, tmp); 1645*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 342), 0xf, tmp); 1646*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 470), 0xf, tmp); 1647*91f16700Schasinglulu 1648*91f16700Schasinglulu if (tsel_adder > rddata_en_ie_dly) 1649*91f16700Schasinglulu extra_adder = tsel_adder - rddata_en_ie_dly; 1650*91f16700Schasinglulu else 1651*91f16700Schasinglulu extra_adder = 0; 1652*91f16700Schasinglulu if (rddata_en_ie_dly > (cas_lat - 1 - hs_offset)) 1653*91f16700Schasinglulu tmp = tsel_adder; 1654*91f16700Schasinglulu else 1655*91f16700Schasinglulu tmp = rddata_en_ie_dly - 0 + extra_adder; 1656*91f16700Schasinglulu /* PHY_LP4_BOOT_RDDATA_EN_DLY */ 1657*91f16700Schasinglulu /* DENALI_PHY_9/137/265/393 4bit offset_8 */ 1658*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 9), 0xf << 8, tmp << 8); 1659*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 137), 0xf << 8, tmp << 8); 1660*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 265), 0xf << 8, tmp << 8); 1661*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 393), 0xf << 8, tmp << 8); 1662*91f16700Schasinglulu /* PHY_RDDATA_EN_DLY */ 1663*91f16700Schasinglulu /* DENALI_PHY_85/213/341/469 4bit offset_24 */ 1664*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 85), 0xf << 24, tmp << 24); 1665*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 213), 0xf << 24, tmp << 24); 1666*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 341), 0xf << 24, tmp << 24); 1667*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(i, 469), 0xf << 24, tmp << 24); 1668*91f16700Schasinglulu 1669*91f16700Schasinglulu if (pdram_timing->mhz <= ENPER_CS_TRAINING_FREQ) { 1670*91f16700Schasinglulu /* 1671*91f16700Schasinglulu * Note:Per-CS Training is not compatible at speeds 1672*91f16700Schasinglulu * under 533 MHz. If the PHY is running at a speed 1673*91f16700Schasinglulu * less than 533MHz, all phy_per_cs_training_en_X 1674*91f16700Schasinglulu * parameters must be cleared to 0. 1675*91f16700Schasinglulu */ 1676*91f16700Schasinglulu 1677*91f16700Schasinglulu /*DENALI_PHY_84/212/340/468 1bit offset_16 */ 1678*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(i, 84), 0x1 << 16); 1679*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(i, 212), 0x1 << 16); 1680*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(i, 340), 0x1 << 16); 1681*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(i, 468), 0x1 << 16); 1682*91f16700Schasinglulu } else { 1683*91f16700Schasinglulu mmio_setbits_32(PHY_REG(i, 84), 0x1 << 16); 1684*91f16700Schasinglulu mmio_setbits_32(PHY_REG(i, 212), 0x1 << 16); 1685*91f16700Schasinglulu mmio_setbits_32(PHY_REG(i, 340), 0x1 << 16); 1686*91f16700Schasinglulu mmio_setbits_32(PHY_REG(i, 468), 0x1 << 16); 1687*91f16700Schasinglulu } 1688*91f16700Schasinglulu gen_rk3399_phy_dll_bypass(pdram_timing->mhz, i, fn, 1689*91f16700Schasinglulu timing_config->dram_type); 1690*91f16700Schasinglulu } 1691*91f16700Schasinglulu } 1692*91f16700Schasinglulu 1693*91f16700Schasinglulu static int to_get_clk_index(unsigned int mhz) 1694*91f16700Schasinglulu { 1695*91f16700Schasinglulu int pll_cnt, i; 1696*91f16700Schasinglulu 1697*91f16700Schasinglulu pll_cnt = ARRAY_SIZE(dpll_rates_table); 1698*91f16700Schasinglulu 1699*91f16700Schasinglulu /* Assuming rate_table is in descending order */ 1700*91f16700Schasinglulu for (i = 0; i < pll_cnt; i++) { 1701*91f16700Schasinglulu if (mhz >= dpll_rates_table[i].mhz) 1702*91f16700Schasinglulu break; 1703*91f16700Schasinglulu } 1704*91f16700Schasinglulu 1705*91f16700Schasinglulu /* if mhz lower than lowest frequency in table, use lowest frequency */ 1706*91f16700Schasinglulu if (i == pll_cnt) 1707*91f16700Schasinglulu i = pll_cnt - 1; 1708*91f16700Schasinglulu 1709*91f16700Schasinglulu return i; 1710*91f16700Schasinglulu } 1711*91f16700Schasinglulu 1712*91f16700Schasinglulu uint32_t ddr_get_rate(void) 1713*91f16700Schasinglulu { 1714*91f16700Schasinglulu uint32_t refdiv, postdiv1, fbdiv, postdiv2; 1715*91f16700Schasinglulu 1716*91f16700Schasinglulu refdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) & 0x3f; 1717*91f16700Schasinglulu fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff; 1718*91f16700Schasinglulu postdiv1 = 1719*91f16700Schasinglulu (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 8) & 0x7; 1720*91f16700Schasinglulu postdiv2 = 1721*91f16700Schasinglulu (mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1)) >> 12) & 0x7; 1722*91f16700Schasinglulu 1723*91f16700Schasinglulu return (24 / refdiv * fbdiv / postdiv1 / postdiv2) * 1000 * 1000; 1724*91f16700Schasinglulu } 1725*91f16700Schasinglulu 1726*91f16700Schasinglulu /* 1727*91f16700Schasinglulu * return: bit12: channel 1, external self-refresh 1728*91f16700Schasinglulu * bit11: channel 1, stdby_mode 1729*91f16700Schasinglulu * bit10: channel 1, self-refresh with controller and memory clock gate 1730*91f16700Schasinglulu * bit9: channel 1, self-refresh 1731*91f16700Schasinglulu * bit8: channel 1, power-down 1732*91f16700Schasinglulu * 1733*91f16700Schasinglulu * bit4: channel 1, external self-refresh 1734*91f16700Schasinglulu * bit3: channel 0, stdby_mode 1735*91f16700Schasinglulu * bit2: channel 0, self-refresh with controller and memory clock gate 1736*91f16700Schasinglulu * bit1: channel 0, self-refresh 1737*91f16700Schasinglulu * bit0: channel 0, power-down 1738*91f16700Schasinglulu */ 1739*91f16700Schasinglulu uint32_t exit_low_power(void) 1740*91f16700Schasinglulu { 1741*91f16700Schasinglulu uint32_t low_power = 0; 1742*91f16700Schasinglulu uint32_t channel_mask; 1743*91f16700Schasinglulu uint32_t tmp, i; 1744*91f16700Schasinglulu 1745*91f16700Schasinglulu channel_mask = (mmio_read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) & 1746*91f16700Schasinglulu 0x3; 1747*91f16700Schasinglulu for (i = 0; i < 2; i++) { 1748*91f16700Schasinglulu if (!(channel_mask & (1 << i))) 1749*91f16700Schasinglulu continue; 1750*91f16700Schasinglulu 1751*91f16700Schasinglulu /* exit stdby mode */ 1752*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_CTRL1, 1753*91f16700Schasinglulu (1 << (i + 16)) | (0 << i)); 1754*91f16700Schasinglulu /* exit external self-refresh */ 1755*91f16700Schasinglulu tmp = i ? 12 : 8; 1756*91f16700Schasinglulu low_power |= ((mmio_read_32(PMU_BASE + PMU_SFT_CON) >> tmp) & 1757*91f16700Schasinglulu 0x1) << (4 + 8 * i); 1758*91f16700Schasinglulu mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 1 << tmp); 1759*91f16700Schasinglulu while (!(mmio_read_32(PMU_BASE + PMU_DDR_SREF_ST) & (1 << i))) 1760*91f16700Schasinglulu ; 1761*91f16700Schasinglulu /* exit auto low-power */ 1762*91f16700Schasinglulu mmio_clrbits_32(CTL_REG(i, 101), 0x7); 1763*91f16700Schasinglulu /* lp_cmd to exit */ 1764*91f16700Schasinglulu if (((mmio_read_32(CTL_REG(i, 100)) >> 24) & 0x7f) != 1765*91f16700Schasinglulu 0x40) { 1766*91f16700Schasinglulu while (mmio_read_32(CTL_REG(i, 200)) & 0x1) 1767*91f16700Schasinglulu ; 1768*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 93), 0xffu << 24, 1769*91f16700Schasinglulu 0x69 << 24); 1770*91f16700Schasinglulu while (((mmio_read_32(CTL_REG(i, 100)) >> 24) & 0x7f) != 1771*91f16700Schasinglulu 0x40) 1772*91f16700Schasinglulu ; 1773*91f16700Schasinglulu } 1774*91f16700Schasinglulu } 1775*91f16700Schasinglulu return low_power; 1776*91f16700Schasinglulu } 1777*91f16700Schasinglulu 1778*91f16700Schasinglulu void resume_low_power(uint32_t low_power) 1779*91f16700Schasinglulu { 1780*91f16700Schasinglulu uint32_t channel_mask; 1781*91f16700Schasinglulu uint32_t tmp, i, val; 1782*91f16700Schasinglulu 1783*91f16700Schasinglulu channel_mask = (mmio_read_32(PMUGRF_BASE + PMUGRF_OSREG(2)) >> 28) & 1784*91f16700Schasinglulu 0x3; 1785*91f16700Schasinglulu for (i = 0; i < 2; i++) { 1786*91f16700Schasinglulu if (!(channel_mask & (1 << i))) 1787*91f16700Schasinglulu continue; 1788*91f16700Schasinglulu 1789*91f16700Schasinglulu /* resume external self-refresh */ 1790*91f16700Schasinglulu tmp = i ? 12 : 8; 1791*91f16700Schasinglulu val = (low_power >> (4 + 8 * i)) & 0x1; 1792*91f16700Schasinglulu mmio_setbits_32(PMU_BASE + PMU_SFT_CON, val << tmp); 1793*91f16700Schasinglulu /* resume auto low-power */ 1794*91f16700Schasinglulu val = (low_power >> (8 * i)) & 0x7; 1795*91f16700Schasinglulu mmio_setbits_32(CTL_REG(i, 101), val); 1796*91f16700Schasinglulu /* resume stdby mode */ 1797*91f16700Schasinglulu val = (low_power >> (3 + 8 * i)) & 0x1; 1798*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_CTRL1, 1799*91f16700Schasinglulu (1 << (i + 16)) | (val << i)); 1800*91f16700Schasinglulu } 1801*91f16700Schasinglulu } 1802*91f16700Schasinglulu 1803*91f16700Schasinglulu static void dram_low_power_config(void) 1804*91f16700Schasinglulu { 1805*91f16700Schasinglulu uint32_t tmp, i; 1806*91f16700Schasinglulu uint32_t ch_cnt = rk3399_dram_status.timing_config.ch_cnt; 1807*91f16700Schasinglulu uint32_t dram_type = rk3399_dram_status.timing_config.dram_type; 1808*91f16700Schasinglulu 1809*91f16700Schasinglulu if (dram_type == DDR3) 1810*91f16700Schasinglulu tmp = (2 << 16) | (0x7 << 8); 1811*91f16700Schasinglulu else 1812*91f16700Schasinglulu tmp = (3 << 16) | (0x7 << 8); 1813*91f16700Schasinglulu 1814*91f16700Schasinglulu for (i = 0; i < ch_cnt; i++) 1815*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 101), 0x70f0f, tmp); 1816*91f16700Schasinglulu 1817*91f16700Schasinglulu /* standby idle */ 1818*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_CG_WAIT_TH, 0x640008); 1819*91f16700Schasinglulu 1820*91f16700Schasinglulu if (ch_cnt == 2) { 1821*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_DDRC1_CON1, 1822*91f16700Schasinglulu (((0x1<<4) | (0x1<<5) | (0x1<<6) | 1823*91f16700Schasinglulu (0x1<<7)) << 16) | 1824*91f16700Schasinglulu ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); 1825*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_CTRL1, 0x002a0028); 1826*91f16700Schasinglulu } 1827*91f16700Schasinglulu 1828*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_DDRC0_CON1, 1829*91f16700Schasinglulu (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) | 1830*91f16700Schasinglulu ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7))); 1831*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_CTRL1, 0x00150014); 1832*91f16700Schasinglulu } 1833*91f16700Schasinglulu 1834*91f16700Schasinglulu void dram_dfs_init(void) 1835*91f16700Schasinglulu { 1836*91f16700Schasinglulu uint32_t trefi0, trefi1, boot_freq; 1837*91f16700Schasinglulu uint32_t rddqs_adjust, rddqs_slave; 1838*91f16700Schasinglulu 1839*91f16700Schasinglulu /* get sdram config for os reg */ 1840*91f16700Schasinglulu get_dram_drv_odt_val(sdram_config.dramtype, 1841*91f16700Schasinglulu &rk3399_dram_status.drv_odt_lp_cfg); 1842*91f16700Schasinglulu sdram_timing_cfg_init(&rk3399_dram_status.timing_config, 1843*91f16700Schasinglulu &sdram_config, 1844*91f16700Schasinglulu &rk3399_dram_status.drv_odt_lp_cfg); 1845*91f16700Schasinglulu 1846*91f16700Schasinglulu trefi0 = ((mmio_read_32(CTL_REG(0, 48)) >> 16) & 0xffff) + 8; 1847*91f16700Schasinglulu trefi1 = ((mmio_read_32(CTL_REG(0, 49)) >> 16) & 0xffff) + 8; 1848*91f16700Schasinglulu 1849*91f16700Schasinglulu rk3399_dram_status.index_freq[0] = trefi0 * 10 / 39; 1850*91f16700Schasinglulu rk3399_dram_status.index_freq[1] = trefi1 * 10 / 39; 1851*91f16700Schasinglulu rk3399_dram_status.current_index = 1852*91f16700Schasinglulu (mmio_read_32(CTL_REG(0, 111)) >> 16) & 0x3; 1853*91f16700Schasinglulu if (rk3399_dram_status.timing_config.dram_type == DDR3) { 1854*91f16700Schasinglulu rk3399_dram_status.index_freq[0] /= 2; 1855*91f16700Schasinglulu rk3399_dram_status.index_freq[1] /= 2; 1856*91f16700Schasinglulu } 1857*91f16700Schasinglulu boot_freq = 1858*91f16700Schasinglulu rk3399_dram_status.index_freq[rk3399_dram_status.current_index]; 1859*91f16700Schasinglulu boot_freq = dpll_rates_table[to_get_clk_index(boot_freq)].mhz; 1860*91f16700Schasinglulu rk3399_dram_status.boot_freq = boot_freq; 1861*91f16700Schasinglulu rk3399_dram_status.index_freq[rk3399_dram_status.current_index] = 1862*91f16700Schasinglulu boot_freq; 1863*91f16700Schasinglulu rk3399_dram_status.index_freq[(rk3399_dram_status.current_index + 1) & 1864*91f16700Schasinglulu 0x1] = 0; 1865*91f16700Schasinglulu rk3399_dram_status.low_power_stat = 0; 1866*91f16700Schasinglulu /* 1867*91f16700Schasinglulu * following register decide if NOC stall the access request 1868*91f16700Schasinglulu * or return error when NOC being idled. when doing ddr frequency 1869*91f16700Schasinglulu * scaling in M0 or DCF, we need to make sure noc stall the access 1870*91f16700Schasinglulu * request, if return error cpu may data abort when ddr frequency 1871*91f16700Schasinglulu * changing. it don't need to set this register every times, 1872*91f16700Schasinglulu * so we init this register in function dram_dfs_init(). 1873*91f16700Schasinglulu */ 1874*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_SOC_CON(0), 0xffffffff); 1875*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_SOC_CON(1), 0xffffffff); 1876*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_SOC_CON(2), 0xffffffff); 1877*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_SOC_CON(3), 0xffffffff); 1878*91f16700Schasinglulu mmio_write_32(GRF_BASE + GRF_SOC_CON(4), 0x70007000); 1879*91f16700Schasinglulu 1880*91f16700Schasinglulu /* Disable multicast */ 1881*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(0, 896), 1); 1882*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(1, 896), 1); 1883*91f16700Schasinglulu dram_low_power_config(); 1884*91f16700Schasinglulu 1885*91f16700Schasinglulu /* 1886*91f16700Schasinglulu * If boot_freq isn't in the bypass mode, it can get the 1887*91f16700Schasinglulu * rddqs_delay_ps from the result of gate training 1888*91f16700Schasinglulu */ 1889*91f16700Schasinglulu if (((mmio_read_32(PHY_REG(0, 86)) >> 8) & 0xf) != 0xc) { 1890*91f16700Schasinglulu 1891*91f16700Schasinglulu /* 1892*91f16700Schasinglulu * Select PHY's frequency set to current_index 1893*91f16700Schasinglulu * index for get the result of gate Training 1894*91f16700Schasinglulu * from registers 1895*91f16700Schasinglulu */ 1896*91f16700Schasinglulu mmio_clrsetbits_32(PHY_REG(0, 896), 0x3 << 8, 1897*91f16700Schasinglulu rk3399_dram_status.current_index << 8); 1898*91f16700Schasinglulu rddqs_slave = (mmio_read_32(PHY_REG(0, 77)) >> 16) & 0x3ff; 1899*91f16700Schasinglulu rddqs_slave = rddqs_slave * 1000000 / boot_freq / 512; 1900*91f16700Schasinglulu 1901*91f16700Schasinglulu rddqs_adjust = mmio_read_32(PHY_REG(0, 78)) & 0xf; 1902*91f16700Schasinglulu rddqs_adjust = rddqs_adjust * 1000000 / boot_freq; 1903*91f16700Schasinglulu rddqs_delay_ps = rddqs_slave + rddqs_adjust - 1904*91f16700Schasinglulu (1000000 / boot_freq / 2); 1905*91f16700Schasinglulu } else { 1906*91f16700Schasinglulu rddqs_delay_ps = 3500; 1907*91f16700Schasinglulu } 1908*91f16700Schasinglulu } 1909*91f16700Schasinglulu 1910*91f16700Schasinglulu /* 1911*91f16700Schasinglulu * arg0: bit0-7: sr_idle; bit8-15:sr_mc_gate_idle; bit16-31: standby idle 1912*91f16700Schasinglulu * arg1: bit0-11: pd_idle; bit 16-27: srpd_lite_idle 1913*91f16700Schasinglulu * arg2: bit0: if odt en 1914*91f16700Schasinglulu */ 1915*91f16700Schasinglulu uint32_t dram_set_odt_pd(uint32_t arg0, uint32_t arg1, uint32_t arg2) 1916*91f16700Schasinglulu { 1917*91f16700Schasinglulu struct drv_odt_lp_config *lp_cfg = &rk3399_dram_status.drv_odt_lp_cfg; 1918*91f16700Schasinglulu uint32_t *low_power = &rk3399_dram_status.low_power_stat; 1919*91f16700Schasinglulu uint32_t dram_type, ch_count, pd_tmp, sr_tmp, i; 1920*91f16700Schasinglulu 1921*91f16700Schasinglulu dram_type = rk3399_dram_status.timing_config.dram_type; 1922*91f16700Schasinglulu ch_count = rk3399_dram_status.timing_config.ch_cnt; 1923*91f16700Schasinglulu 1924*91f16700Schasinglulu lp_cfg->sr_idle = arg0 & 0xff; 1925*91f16700Schasinglulu lp_cfg->sr_mc_gate_idle = (arg0 >> 8) & 0xff; 1926*91f16700Schasinglulu lp_cfg->standby_idle = (arg0 >> 16) & 0xffff; 1927*91f16700Schasinglulu lp_cfg->pd_idle = arg1 & 0xfff; 1928*91f16700Schasinglulu lp_cfg->srpd_lite_idle = (arg1 >> 16) & 0xfff; 1929*91f16700Schasinglulu 1930*91f16700Schasinglulu rk3399_dram_status.timing_config.odt = arg2 & 0x1; 1931*91f16700Schasinglulu 1932*91f16700Schasinglulu exit_low_power(); 1933*91f16700Schasinglulu 1934*91f16700Schasinglulu *low_power = 0; 1935*91f16700Schasinglulu 1936*91f16700Schasinglulu /* pd_idle en */ 1937*91f16700Schasinglulu if (lp_cfg->pd_idle) 1938*91f16700Schasinglulu *low_power |= ((1 << 0) | (1 << 8)); 1939*91f16700Schasinglulu /* sr_idle en srpd_lite_idle */ 1940*91f16700Schasinglulu if (lp_cfg->sr_idle | lp_cfg->srpd_lite_idle) 1941*91f16700Schasinglulu *low_power |= ((1 << 1) | (1 << 9)); 1942*91f16700Schasinglulu /* sr_mc_gate_idle */ 1943*91f16700Schasinglulu if (lp_cfg->sr_mc_gate_idle) 1944*91f16700Schasinglulu *low_power |= ((1 << 2) | (1 << 10)); 1945*91f16700Schasinglulu /* standbyidle */ 1946*91f16700Schasinglulu if (lp_cfg->standby_idle) { 1947*91f16700Schasinglulu if (rk3399_dram_status.timing_config.ch_cnt == 2) 1948*91f16700Schasinglulu *low_power |= ((1 << 3) | (1 << 11)); 1949*91f16700Schasinglulu else 1950*91f16700Schasinglulu *low_power |= (1 << 3); 1951*91f16700Schasinglulu } 1952*91f16700Schasinglulu 1953*91f16700Schasinglulu pd_tmp = arg1; 1954*91f16700Schasinglulu if (dram_type != LPDDR4) 1955*91f16700Schasinglulu pd_tmp = arg1 & 0xfff; 1956*91f16700Schasinglulu sr_tmp = arg0 & 0xffff; 1957*91f16700Schasinglulu for (i = 0; i < ch_count; i++) { 1958*91f16700Schasinglulu mmio_write_32(CTL_REG(i, 102), pd_tmp); 1959*91f16700Schasinglulu mmio_clrsetbits_32(CTL_REG(i, 103), 0xffff, sr_tmp); 1960*91f16700Schasinglulu } 1961*91f16700Schasinglulu mmio_write_32(CIC_BASE + CIC_IDLE_TH, (arg0 >> 16) & 0xffff); 1962*91f16700Schasinglulu 1963*91f16700Schasinglulu return 0; 1964*91f16700Schasinglulu } 1965*91f16700Schasinglulu 1966*91f16700Schasinglulu static void m0_configure_ddr(struct pll_div pll_div, uint32_t ddr_index) 1967*91f16700Schasinglulu { 1968*91f16700Schasinglulu mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(pll_div.fbdiv)); 1969*91f16700Schasinglulu mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON1, 1970*91f16700Schasinglulu POSTDIV2(pll_div.postdiv2) | POSTDIV1(pll_div.postdiv1) | 1971*91f16700Schasinglulu REFDIV(pll_div.refdiv)); 1972*91f16700Schasinglulu 1973*91f16700Schasinglulu mmio_write_32(M0_PARAM_ADDR + PARAM_DRAM_FREQ, pll_div.mhz); 1974*91f16700Schasinglulu 1975*91f16700Schasinglulu mmio_write_32(M0_PARAM_ADDR + PARAM_FREQ_SELECT, ddr_index << 4); 1976*91f16700Schasinglulu dmbst(); 1977*91f16700Schasinglulu m0_configure_execute_addr(M0_BINCODE_BASE); 1978*91f16700Schasinglulu } 1979*91f16700Schasinglulu 1980*91f16700Schasinglulu static uint32_t prepare_ddr_timing(uint32_t mhz) 1981*91f16700Schasinglulu { 1982*91f16700Schasinglulu uint32_t index; 1983*91f16700Schasinglulu struct dram_timing_t dram_timing; 1984*91f16700Schasinglulu 1985*91f16700Schasinglulu rk3399_dram_status.timing_config.freq = mhz; 1986*91f16700Schasinglulu 1987*91f16700Schasinglulu if (mhz < 300) 1988*91f16700Schasinglulu rk3399_dram_status.timing_config.dllbp = 1; 1989*91f16700Schasinglulu else 1990*91f16700Schasinglulu rk3399_dram_status.timing_config.dllbp = 0; 1991*91f16700Schasinglulu 1992*91f16700Schasinglulu if (rk3399_dram_status.timing_config.odt == 1) 1993*91f16700Schasinglulu gen_rk3399_set_odt(1); 1994*91f16700Schasinglulu 1995*91f16700Schasinglulu index = (rk3399_dram_status.current_index + 1) & 0x1; 1996*91f16700Schasinglulu 1997*91f16700Schasinglulu /* 1998*91f16700Schasinglulu * checking if having available gate traiing timing for 1999*91f16700Schasinglulu * target freq. 2000*91f16700Schasinglulu */ 2001*91f16700Schasinglulu dram_get_parameter(&rk3399_dram_status.timing_config, &dram_timing); 2002*91f16700Schasinglulu gen_rk3399_ctl_params(&rk3399_dram_status.timing_config, 2003*91f16700Schasinglulu &dram_timing, index); 2004*91f16700Schasinglulu gen_rk3399_pi_params(&rk3399_dram_status.timing_config, 2005*91f16700Schasinglulu &dram_timing, index); 2006*91f16700Schasinglulu gen_rk3399_phy_params(&rk3399_dram_status.timing_config, 2007*91f16700Schasinglulu &rk3399_dram_status.drv_odt_lp_cfg, 2008*91f16700Schasinglulu &dram_timing, index); 2009*91f16700Schasinglulu rk3399_dram_status.index_freq[index] = mhz; 2010*91f16700Schasinglulu 2011*91f16700Schasinglulu return index; 2012*91f16700Schasinglulu } 2013*91f16700Schasinglulu 2014*91f16700Schasinglulu uint32_t ddr_set_rate(uint32_t hz) 2015*91f16700Schasinglulu { 2016*91f16700Schasinglulu uint32_t low_power, index, ddr_index; 2017*91f16700Schasinglulu uint32_t mhz = hz / (1000 * 1000); 2018*91f16700Schasinglulu 2019*91f16700Schasinglulu if (mhz == 2020*91f16700Schasinglulu rk3399_dram_status.index_freq[rk3399_dram_status.current_index]) 2021*91f16700Schasinglulu return mhz; 2022*91f16700Schasinglulu 2023*91f16700Schasinglulu index = to_get_clk_index(mhz); 2024*91f16700Schasinglulu mhz = dpll_rates_table[index].mhz; 2025*91f16700Schasinglulu 2026*91f16700Schasinglulu ddr_index = prepare_ddr_timing(mhz); 2027*91f16700Schasinglulu gen_rk3399_enable_training(rk3399_dram_status.timing_config.ch_cnt, 2028*91f16700Schasinglulu mhz); 2029*91f16700Schasinglulu if (ddr_index > 1) 2030*91f16700Schasinglulu goto out; 2031*91f16700Schasinglulu 2032*91f16700Schasinglulu /* 2033*91f16700Schasinglulu * Make sure the clock is enabled. The M0 clocks should be on all of the 2034*91f16700Schasinglulu * time during S0. 2035*91f16700Schasinglulu */ 2036*91f16700Schasinglulu m0_configure_ddr(dpll_rates_table[index], ddr_index); 2037*91f16700Schasinglulu m0_start(); 2038*91f16700Schasinglulu m0_wait_done(); 2039*91f16700Schasinglulu m0_stop(); 2040*91f16700Schasinglulu 2041*91f16700Schasinglulu if (rk3399_dram_status.timing_config.odt == 0) 2042*91f16700Schasinglulu gen_rk3399_set_odt(0); 2043*91f16700Schasinglulu 2044*91f16700Schasinglulu rk3399_dram_status.current_index = ddr_index; 2045*91f16700Schasinglulu low_power = rk3399_dram_status.low_power_stat; 2046*91f16700Schasinglulu resume_low_power(low_power); 2047*91f16700Schasinglulu out: 2048*91f16700Schasinglulu gen_rk3399_disable_training(rk3399_dram_status.timing_config.ch_cnt); 2049*91f16700Schasinglulu return mhz; 2050*91f16700Schasinglulu } 2051*91f16700Schasinglulu 2052*91f16700Schasinglulu uint32_t ddr_round_rate(uint32_t hz) 2053*91f16700Schasinglulu { 2054*91f16700Schasinglulu int index; 2055*91f16700Schasinglulu uint32_t mhz = hz / (1000 * 1000); 2056*91f16700Schasinglulu 2057*91f16700Schasinglulu index = to_get_clk_index(mhz); 2058*91f16700Schasinglulu 2059*91f16700Schasinglulu return dpll_rates_table[index].mhz * 1000 * 1000; 2060*91f16700Schasinglulu } 2061*91f16700Schasinglulu 2062*91f16700Schasinglulu void ddr_prepare_for_sys_suspend(void) 2063*91f16700Schasinglulu { 2064*91f16700Schasinglulu uint32_t mhz = 2065*91f16700Schasinglulu rk3399_dram_status.index_freq[rk3399_dram_status.current_index]; 2066*91f16700Schasinglulu 2067*91f16700Schasinglulu /* 2068*91f16700Schasinglulu * If we're not currently at the boot (assumed highest) frequency, we 2069*91f16700Schasinglulu * need to change frequencies to configure out current index. 2070*91f16700Schasinglulu */ 2071*91f16700Schasinglulu rk3399_suspend_status.freq = mhz; 2072*91f16700Schasinglulu exit_low_power(); 2073*91f16700Schasinglulu rk3399_suspend_status.low_power_stat = 2074*91f16700Schasinglulu rk3399_dram_status.low_power_stat; 2075*91f16700Schasinglulu rk3399_suspend_status.odt = rk3399_dram_status.timing_config.odt; 2076*91f16700Schasinglulu rk3399_dram_status.low_power_stat = 0; 2077*91f16700Schasinglulu rk3399_dram_status.timing_config.odt = 1; 2078*91f16700Schasinglulu if (mhz != rk3399_dram_status.boot_freq) 2079*91f16700Schasinglulu ddr_set_rate(rk3399_dram_status.boot_freq * 1000 * 1000); 2080*91f16700Schasinglulu 2081*91f16700Schasinglulu /* 2082*91f16700Schasinglulu * This will configure the other index to be the same frequency as the 2083*91f16700Schasinglulu * current one. We retrain both indices on resume, so both have to be 2084*91f16700Schasinglulu * setup for the same frequency. 2085*91f16700Schasinglulu */ 2086*91f16700Schasinglulu prepare_ddr_timing(rk3399_dram_status.boot_freq); 2087*91f16700Schasinglulu } 2088*91f16700Schasinglulu 2089*91f16700Schasinglulu void ddr_prepare_for_sys_resume(void) 2090*91f16700Schasinglulu { 2091*91f16700Schasinglulu /* Disable multicast */ 2092*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(0, 896), 1); 2093*91f16700Schasinglulu mmio_clrbits_32(PHY_REG(1, 896), 1); 2094*91f16700Schasinglulu 2095*91f16700Schasinglulu /* The suspend code changes the current index, so reset it now. */ 2096*91f16700Schasinglulu rk3399_dram_status.current_index = 2097*91f16700Schasinglulu (mmio_read_32(CTL_REG(0, 111)) >> 16) & 0x3; 2098*91f16700Schasinglulu rk3399_dram_status.low_power_stat = 2099*91f16700Schasinglulu rk3399_suspend_status.low_power_stat; 2100*91f16700Schasinglulu rk3399_dram_status.timing_config.odt = rk3399_suspend_status.odt; 2101*91f16700Schasinglulu 2102*91f16700Schasinglulu /* 2103*91f16700Schasinglulu * Set the saved frequency from suspend if it's different than the 2104*91f16700Schasinglulu * current frequency. 2105*91f16700Schasinglulu */ 2106*91f16700Schasinglulu if (rk3399_suspend_status.freq != 2107*91f16700Schasinglulu rk3399_dram_status.index_freq[rk3399_dram_status.current_index]) { 2108*91f16700Schasinglulu ddr_set_rate(rk3399_suspend_status.freq * 1000 * 1000); 2109*91f16700Schasinglulu return; 2110*91f16700Schasinglulu } 2111*91f16700Schasinglulu 2112*91f16700Schasinglulu gen_rk3399_set_odt(rk3399_dram_status.timing_config.odt); 2113*91f16700Schasinglulu resume_low_power(rk3399_dram_status.low_power_stat); 2114*91f16700Schasinglulu } 2115