1*fe877779SCaesar Wang /* 2*fe877779SCaesar Wang * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*fe877779SCaesar Wang * 4*fe877779SCaesar Wang * Redistribution and use in source and binary forms, with or without 5*fe877779SCaesar Wang * modification, are permitted provided that the following conditions are met: 6*fe877779SCaesar Wang * 7*fe877779SCaesar Wang * Redistributions of source code must retain the above copyright notice, this 8*fe877779SCaesar Wang * list of conditions and the following disclaimer. 9*fe877779SCaesar Wang * 10*fe877779SCaesar Wang * Redistributions in binary form must reproduce the above copyright notice, 11*fe877779SCaesar Wang * this list of conditions and the following disclaimer in the documentation 12*fe877779SCaesar Wang * and/or other materials provided with the distribution. 13*fe877779SCaesar Wang * 14*fe877779SCaesar Wang * Neither the name of ARM nor the names of its contributors may be used 15*fe877779SCaesar Wang * to endorse or promote products derived from this software without specific 16*fe877779SCaesar Wang * prior written permission. 17*fe877779SCaesar Wang * 18*fe877779SCaesar Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*fe877779SCaesar Wang * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*fe877779SCaesar Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*fe877779SCaesar Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*fe877779SCaesar Wang * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*fe877779SCaesar Wang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*fe877779SCaesar Wang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*fe877779SCaesar Wang * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*fe877779SCaesar Wang * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*fe877779SCaesar Wang * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*fe877779SCaesar Wang * POSSIBILITY OF SUCH DAMAGE. 29*fe877779SCaesar Wang */ 30*fe877779SCaesar Wang 31*fe877779SCaesar Wang #ifndef __SOC_ROCKCHIP_RK3399_SDRAM_H__ 32*fe877779SCaesar Wang #define __SOC_ROCKCHIP_RK3399_SDRAM_H__ 33*fe877779SCaesar Wang 34*fe877779SCaesar Wang struct rk3399_ddr_cic_regs { 35*fe877779SCaesar Wang uint32_t cic_ctrl0; 36*fe877779SCaesar Wang uint32_t cic_ctrl1; 37*fe877779SCaesar Wang uint32_t cic_idle_th; 38*fe877779SCaesar Wang uint32_t cic_cg_wait_th; 39*fe877779SCaesar Wang uint32_t cic_status0; 40*fe877779SCaesar Wang uint32_t cic_status1; 41*fe877779SCaesar Wang uint32_t cic_ctrl2; 42*fe877779SCaesar Wang uint32_t cic_ctrl3; 43*fe877779SCaesar Wang uint32_t cic_ctrl4; 44*fe877779SCaesar Wang }; 45*fe877779SCaesar Wang 46*fe877779SCaesar Wang /* DENALI_CTL_00 */ 47*fe877779SCaesar Wang #define START (1) 48*fe877779SCaesar Wang 49*fe877779SCaesar Wang /* DENALI_CTL_68 */ 50*fe877779SCaesar Wang #define PWRUP_SREFRESH_EXIT (1 << 16) 51*fe877779SCaesar Wang 52*fe877779SCaesar Wang /* DENALI_CTL_274 */ 53*fe877779SCaesar Wang #define MEM_RST_VALID (1) 54*fe877779SCaesar Wang 55*fe877779SCaesar Wang struct rk3399_ddr_pctl_regs { 56*fe877779SCaesar Wang uint32_t denali_ctl[332]; 57*fe877779SCaesar Wang }; 58*fe877779SCaesar Wang 59*fe877779SCaesar Wang struct rk3399_ddr_publ_regs { 60*fe877779SCaesar Wang uint32_t denali_phy[959]; 61*fe877779SCaesar Wang }; 62*fe877779SCaesar Wang 63*fe877779SCaesar Wang #define PHY_DRV_ODT_Hi_Z (0x0) 64*fe877779SCaesar Wang #define PHY_DRV_ODT_240 (0x1) 65*fe877779SCaesar Wang #define PHY_DRV_ODT_120 (0x8) 66*fe877779SCaesar Wang #define PHY_DRV_ODT_80 (0x9) 67*fe877779SCaesar Wang #define PHY_DRV_ODT_60 (0xc) 68*fe877779SCaesar Wang #define PHY_DRV_ODT_48 (0xd) 69*fe877779SCaesar Wang #define PHY_DRV_ODT_40 (0xe) 70*fe877779SCaesar Wang #define PHY_DRV_ODT_34_3 (0xf) 71*fe877779SCaesar Wang 72*fe877779SCaesar Wang struct rk3399_ddr_pi_regs { 73*fe877779SCaesar Wang uint32_t denali_pi[200]; 74*fe877779SCaesar Wang }; 75*fe877779SCaesar Wang union noc_ddrtiminga0 { 76*fe877779SCaesar Wang uint32_t d32; 77*fe877779SCaesar Wang struct { 78*fe877779SCaesar Wang unsigned acttoact : 6; 79*fe877779SCaesar Wang unsigned reserved0 : 2; 80*fe877779SCaesar Wang unsigned rdtomiss : 6; 81*fe877779SCaesar Wang unsigned reserved1 : 2; 82*fe877779SCaesar Wang unsigned wrtomiss : 6; 83*fe877779SCaesar Wang unsigned reserved2 : 2; 84*fe877779SCaesar Wang unsigned readlatency : 8; 85*fe877779SCaesar Wang } b; 86*fe877779SCaesar Wang }; 87*fe877779SCaesar Wang 88*fe877779SCaesar Wang union noc_ddrtimingb0 { 89*fe877779SCaesar Wang uint32_t d32; 90*fe877779SCaesar Wang struct { 91*fe877779SCaesar Wang unsigned rdtowr : 5; 92*fe877779SCaesar Wang unsigned reserved0 : 3; 93*fe877779SCaesar Wang unsigned wrtord : 5; 94*fe877779SCaesar Wang unsigned reserved1 : 3; 95*fe877779SCaesar Wang unsigned rrd : 4; 96*fe877779SCaesar Wang unsigned reserved2 : 4; 97*fe877779SCaesar Wang unsigned faw : 6; 98*fe877779SCaesar Wang unsigned reserved3 : 2; 99*fe877779SCaesar Wang } b; 100*fe877779SCaesar Wang }; 101*fe877779SCaesar Wang 102*fe877779SCaesar Wang union noc_ddrtimingc0 { 103*fe877779SCaesar Wang uint32_t d32; 104*fe877779SCaesar Wang struct { 105*fe877779SCaesar Wang unsigned burstpenalty : 4; 106*fe877779SCaesar Wang unsigned reserved0 : 4; 107*fe877779SCaesar Wang unsigned wrtomwr : 6; 108*fe877779SCaesar Wang unsigned reserved1 : 18; 109*fe877779SCaesar Wang } b; 110*fe877779SCaesar Wang }; 111*fe877779SCaesar Wang 112*fe877779SCaesar Wang union noc_devtodev0 { 113*fe877779SCaesar Wang uint32_t d32; 114*fe877779SCaesar Wang struct { 115*fe877779SCaesar Wang unsigned busrdtord : 3; 116*fe877779SCaesar Wang unsigned reserved0 : 1; 117*fe877779SCaesar Wang unsigned busrdtowr : 3; 118*fe877779SCaesar Wang unsigned reserved1 : 1; 119*fe877779SCaesar Wang unsigned buswrtord : 3; 120*fe877779SCaesar Wang unsigned reserved2 : 1; 121*fe877779SCaesar Wang unsigned buswrtowr : 3; 122*fe877779SCaesar Wang unsigned reserved3 : 17; 123*fe877779SCaesar Wang } b; 124*fe877779SCaesar Wang }; 125*fe877779SCaesar Wang 126*fe877779SCaesar Wang union noc_ddrmode { 127*fe877779SCaesar Wang uint32_t d32; 128*fe877779SCaesar Wang struct { 129*fe877779SCaesar Wang unsigned autoprecharge : 1; 130*fe877779SCaesar Wang unsigned bypassfiltering : 1; 131*fe877779SCaesar Wang unsigned fawbank : 1; 132*fe877779SCaesar Wang unsigned burstsize : 2; 133*fe877779SCaesar Wang unsigned mwrsize : 2; 134*fe877779SCaesar Wang unsigned reserved2 : 1; 135*fe877779SCaesar Wang unsigned forceorder : 8; 136*fe877779SCaesar Wang unsigned forceorderstate : 8; 137*fe877779SCaesar Wang unsigned reserved3 : 8; 138*fe877779SCaesar Wang } b; 139*fe877779SCaesar Wang }; 140*fe877779SCaesar Wang 141*fe877779SCaesar Wang struct rk3399_msch_regs { 142*fe877779SCaesar Wang uint32_t coreid; 143*fe877779SCaesar Wang uint32_t revisionid; 144*fe877779SCaesar Wang uint32_t ddrconf; 145*fe877779SCaesar Wang uint32_t ddrsize; 146*fe877779SCaesar Wang union noc_ddrtiminga0 ddrtiminga0; 147*fe877779SCaesar Wang union noc_ddrtimingb0 ddrtimingb0; 148*fe877779SCaesar Wang union noc_ddrtimingc0 ddrtimingc0; 149*fe877779SCaesar Wang union noc_devtodev0 devtodev0; 150*fe877779SCaesar Wang uint32_t reserved0[(0x110-0x20)/4]; 151*fe877779SCaesar Wang union noc_ddrmode ddrmode; 152*fe877779SCaesar Wang uint32_t reserved1[(0x1000-0x114)/4]; 153*fe877779SCaesar Wang uint32_t agingx0; 154*fe877779SCaesar Wang }; 155*fe877779SCaesar Wang 156*fe877779SCaesar Wang struct rk3399_msch_timings { 157*fe877779SCaesar Wang union noc_ddrtiminga0 ddrtiminga0; 158*fe877779SCaesar Wang union noc_ddrtimingb0 ddrtimingb0; 159*fe877779SCaesar Wang union noc_ddrtimingc0 ddrtimingc0; 160*fe877779SCaesar Wang union noc_devtodev0 devtodev0; 161*fe877779SCaesar Wang union noc_ddrmode ddrmode; 162*fe877779SCaesar Wang uint32_t agingx0; 163*fe877779SCaesar Wang }; 164*fe877779SCaesar Wang #if 1 165*fe877779SCaesar Wang struct rk3399_sdram_channel { 166*fe877779SCaesar Wang unsigned char rank; 167*fe877779SCaesar Wang /* col = 0, means this channel is invalid */ 168*fe877779SCaesar Wang unsigned char col; 169*fe877779SCaesar Wang /* 3:8bank, 2:4bank */ 170*fe877779SCaesar Wang unsigned char bk; 171*fe877779SCaesar Wang /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */ 172*fe877779SCaesar Wang unsigned char bw; 173*fe877779SCaesar Wang /* die buswidth, 2:32bit, 1:16bit, 0:8bit */ 174*fe877779SCaesar Wang unsigned char dbw; 175*fe877779SCaesar Wang /* row_3_4 = 1: 6Gb or 12Gb die 176*fe877779SCaesar Wang * row_3_4 = 0: normal die, power of 2 177*fe877779SCaesar Wang */ 178*fe877779SCaesar Wang unsigned char row_3_4; 179*fe877779SCaesar Wang unsigned char cs0_row; 180*fe877779SCaesar Wang unsigned char cs1_row; 181*fe877779SCaesar Wang uint32_t ddrconfig; 182*fe877779SCaesar Wang struct rk3399_msch_timings noc_timings; 183*fe877779SCaesar Wang }; 184*fe877779SCaesar Wang 185*fe877779SCaesar Wang struct rk3399_sdram_params { 186*fe877779SCaesar Wang struct rk3399_sdram_channel ch[2]; 187*fe877779SCaesar Wang uint32_t ddr_freq; 188*fe877779SCaesar Wang unsigned char dramtype; 189*fe877779SCaesar Wang unsigned char num_channels; 190*fe877779SCaesar Wang unsigned char stride; 191*fe877779SCaesar Wang unsigned char odt; 192*fe877779SCaesar Wang struct rk3399_ddr_pctl_regs pctl_regs; 193*fe877779SCaesar Wang struct rk3399_ddr_pi_regs pi_regs; 194*fe877779SCaesar Wang struct rk3399_ddr_publ_regs phy_regs; 195*fe877779SCaesar Wang }; 196*fe877779SCaesar Wang #endif 197*fe877779SCaesar Wang struct rk3399_sdram_channel_config { 198*fe877779SCaesar Wang uint32_t bus_width; 199*fe877779SCaesar Wang uint32_t cs_cnt; 200*fe877779SCaesar Wang uint32_t cs0_row; 201*fe877779SCaesar Wang uint32_t cs1_row; 202*fe877779SCaesar Wang uint32_t bank; 203*fe877779SCaesar Wang uint32_t col; 204*fe877779SCaesar Wang uint32_t each_die_bus_width; 205*fe877779SCaesar Wang uint32_t each_die_6gb_or_12gb; 206*fe877779SCaesar Wang }; 207*fe877779SCaesar Wang 208*fe877779SCaesar Wang struct rk3399_sdram_config { 209*fe877779SCaesar Wang struct rk3399_sdram_channel_config ch[2]; 210*fe877779SCaesar Wang uint32_t dramtype; 211*fe877779SCaesar Wang uint32_t channal_num; 212*fe877779SCaesar Wang }; 213*fe877779SCaesar Wang 214*fe877779SCaesar Wang struct rk3399_sdram_default_config { 215*fe877779SCaesar Wang unsigned char bl; 216*fe877779SCaesar Wang /* 1:auto precharge, 0:never auto precharge */ 217*fe877779SCaesar Wang unsigned char ap; 218*fe877779SCaesar Wang /* dram driver strength */ 219*fe877779SCaesar Wang unsigned char dramds; 220*fe877779SCaesar Wang /* dram ODT, if odt=0, this parameter invalid */ 221*fe877779SCaesar Wang unsigned char dramodt; 222*fe877779SCaesar Wang /* ca ODT, if odt=0, this parameter invalid 223*fe877779SCaesar Wang * only used by LPDDR4 224*fe877779SCaesar Wang */ 225*fe877779SCaesar Wang unsigned char caodt; 226*fe877779SCaesar Wang unsigned char burst_ref_cnt; 227*fe877779SCaesar Wang /* zqcs period, unit(s) */ 228*fe877779SCaesar Wang unsigned char zqcsi; 229*fe877779SCaesar Wang }; 230*fe877779SCaesar Wang 231*fe877779SCaesar Wang struct ddr_dts_config_timing { 232*fe877779SCaesar Wang uint32_t ddr3_speed_bin; 233*fe877779SCaesar Wang uint32_t pd_idle; 234*fe877779SCaesar Wang uint32_t sr_idle; 235*fe877779SCaesar Wang uint32_t sr_mc_gate_idle; 236*fe877779SCaesar Wang uint32_t srpd_lite_idle; 237*fe877779SCaesar Wang uint32_t standby_idle; 238*fe877779SCaesar Wang uint32_t ddr3_dll_dis_freq; 239*fe877779SCaesar Wang uint32_t phy_dll_dis_freq; 240*fe877779SCaesar Wang uint32_t ddr3_odt_dis_freq; 241*fe877779SCaesar Wang uint32_t ddr3_drv; 242*fe877779SCaesar Wang uint32_t ddr3_odt; 243*fe877779SCaesar Wang uint32_t phy_ddr3_ca_drv; 244*fe877779SCaesar Wang uint32_t phy_ddr3_dq_drv; 245*fe877779SCaesar Wang uint32_t phy_ddr3_odt; 246*fe877779SCaesar Wang uint32_t lpddr3_odt_dis_freq; 247*fe877779SCaesar Wang uint32_t lpddr3_drv; 248*fe877779SCaesar Wang uint32_t lpddr3_odt; 249*fe877779SCaesar Wang uint32_t phy_lpddr3_ca_drv; 250*fe877779SCaesar Wang uint32_t phy_lpddr3_dq_drv; 251*fe877779SCaesar Wang uint32_t phy_lpddr3_odt; 252*fe877779SCaesar Wang uint32_t lpddr4_odt_dis_freq; 253*fe877779SCaesar Wang uint32_t lpddr4_drv; 254*fe877779SCaesar Wang uint32_t lpddr4_dq_odt; 255*fe877779SCaesar Wang uint32_t lpddr4_ca_odt; 256*fe877779SCaesar Wang uint32_t phy_lpddr4_ca_drv; 257*fe877779SCaesar Wang uint32_t phy_lpddr4_ck_cs_drv; 258*fe877779SCaesar Wang uint32_t phy_lpddr4_dq_drv; 259*fe877779SCaesar Wang uint32_t phy_lpddr4_odt; 260*fe877779SCaesar Wang uint32_t available; 261*fe877779SCaesar Wang }; 262*fe877779SCaesar Wang 263*fe877779SCaesar Wang struct drv_odt_lp_config { 264*fe877779SCaesar Wang uint32_t ddr3_speed_bin; 265*fe877779SCaesar Wang uint32_t pd_idle; 266*fe877779SCaesar Wang uint32_t sr_idle; 267*fe877779SCaesar Wang uint32_t sr_mc_gate_idle; 268*fe877779SCaesar Wang uint32_t srpd_lite_idle; 269*fe877779SCaesar Wang uint32_t standby_idle; 270*fe877779SCaesar Wang 271*fe877779SCaesar Wang uint32_t ddr3_dll_dis_freq;/* for ddr3 only */ 272*fe877779SCaesar Wang uint32_t phy_dll_dis_freq; 273*fe877779SCaesar Wang uint32_t odt_dis_freq; 274*fe877779SCaesar Wang 275*fe877779SCaesar Wang uint32_t dram_side_drv; 276*fe877779SCaesar Wang uint32_t dram_side_dq_odt; 277*fe877779SCaesar Wang uint32_t dram_side_ca_odt; 278*fe877779SCaesar Wang 279*fe877779SCaesar Wang uint32_t phy_side_ca_drv; 280*fe877779SCaesar Wang uint32_t phy_side_ck_cs_drv; 281*fe877779SCaesar Wang uint32_t phy_side_dq_drv; 282*fe877779SCaesar Wang uint32_t phy_side_odt; 283*fe877779SCaesar Wang }; 284*fe877779SCaesar Wang 285*fe877779SCaesar Wang #define KHz (1000) 286*fe877779SCaesar Wang #define MHz (1000*KHz) 287*fe877779SCaesar Wang #define GHz (1000*MHz) 288*fe877779SCaesar Wang 289*fe877779SCaesar Wang #define PI_CA_TRAINING (1 << 0) 290*fe877779SCaesar Wang #define PI_WRITE_LEVELING (1 << 1) 291*fe877779SCaesar Wang #define PI_READ_GATE_TRAINING (1 << 2) 292*fe877779SCaesar Wang #define PI_READ_LEVELING (1 << 3) 293*fe877779SCaesar Wang #define PI_WDQ_LEVELING (1 << 4) 294*fe877779SCaesar Wang #define PI_FULL_TARINING (0xff) 295*fe877779SCaesar Wang 296*fe877779SCaesar Wang #define READ_CH_CNT(val) (1+((val>>12)&0x1)) 297*fe877779SCaesar Wang #define READ_CH_INFO(val) ((val>>28)&0x3) 298*fe877779SCaesar Wang /* row_3_4:0=normal, 1=6Gb or 12Gb */ 299*fe877779SCaesar Wang #define READ_CH_ROW_INFO(val, ch) ((val>>(30+(ch)))&0x1) 300*fe877779SCaesar Wang 301*fe877779SCaesar Wang #define READ_DRAMTYPE_INFO(val) ((val>>13)&0x7) 302*fe877779SCaesar Wang #define READ_CS_INFO(val, ch) ((((val)>>(11+(ch)*16))&0x1)+1) 303*fe877779SCaesar Wang #define READ_BW_INFO(val, ch) (2>>(((val)>>(2+(ch)*16))&0x3)) 304*fe877779SCaesar Wang #define READ_COL_INFO(val, ch) (9+(((val)>>(9+(ch)*16))&0x3)) 305*fe877779SCaesar Wang #define READ_BK_INFO(val, ch) (3-(((val)>>(8+(ch)*16))&0x1)) 306*fe877779SCaesar Wang #define READ_CS0_ROW_INFO(val, ch) (13+(((val)>>(6+(ch)*16))&0x3)) 307*fe877779SCaesar Wang #define READ_CS1_ROW_INFO(val, ch) (13+(((val)>>(4+(ch)*16))&0x3)) 308*fe877779SCaesar Wang #define READ_DIE_BW_INFO(val, ch) (2>>((val>>((ch)*16))&0x3)) 309*fe877779SCaesar Wang 310*fe877779SCaesar Wang #define __sramdata __attribute__((section(".sram.data"))) 311*fe877779SCaesar Wang #define __sramconst __attribute__((section(".sram.rodata"))) 312*fe877779SCaesar Wang #define __sramlocalfunc __attribute__((section(".sram.text"))) 313*fe877779SCaesar Wang #define __sramfunc __attribute__((section(".sram.text"))) \ 314*fe877779SCaesar Wang __attribute__((noinline)) 315*fe877779SCaesar Wang 316*fe877779SCaesar Wang 317*fe877779SCaesar Wang #define DDR_SAVE_SP(save_sp) (save_sp = ddr_save_sp(((uint32_t)\ 318*fe877779SCaesar Wang (SRAM_CODE_BASE + 0x2000) & (~7)))) 319*fe877779SCaesar Wang 320*fe877779SCaesar Wang #define DDR_RESTORE_SP(save_sp) ddr_save_sp(save_sp) 321*fe877779SCaesar Wang 322*fe877779SCaesar Wang void ddr_init(void); 323*fe877779SCaesar Wang uint64_t ddr_set_rate(uint64_t hz); 324*fe877779SCaesar Wang uint64_t ddr_round_rate(uint64_t hz); 325*fe877779SCaesar Wang uint64_t ddr_get_rate(void); 326*fe877779SCaesar Wang void clr_dcf_irq(void); 327*fe877779SCaesar Wang uint64_t dts_timing_receive(uint64_t timing, uint64_t index); 328*fe877779SCaesar Wang #endif 329