1*16a92a42STang Yun ping // SPDX-License-Identifier: GPL-2.0 2*16a92a42STang Yun ping /* 3*16a92a42STang Yun ping * (C) Copyright 2018 Rockchip Electronics Co., Ltd 4*16a92a42STang Yun ping */ 5*16a92a42STang Yun ping #include <asm/arch/rockchip_smccc.h> 6*16a92a42STang Yun ping #include <asm/arch/rockchip_dmc.h> 7*16a92a42STang Yun ping #include <asm/io.h> 8*16a92a42STang Yun ping #include <asm/psci.h> 9*16a92a42STang Yun ping #include <common.h> 10*16a92a42STang Yun ping #include <clk.h> 11*16a92a42STang Yun ping #include <dm.h> 12*16a92a42STang Yun ping #include <dm/of_access.h> 13*16a92a42STang Yun ping #include <dt-structs.h> 14*16a92a42STang Yun ping #include <linux/arm-smccc.h> 15*16a92a42STang Yun ping #include <linux/err.h> 16*16a92a42STang Yun ping #include <linux/errno.h> 17*16a92a42STang Yun ping #include <ram.h> 18*16a92a42STang Yun ping #include <regmap.h> 19*16a92a42STang Yun ping 20*16a92a42STang Yun ping #define DTS_PAR_OFFSET (4096) 21*16a92a42STang Yun ping 22*16a92a42STang Yun ping struct share_params { 23*16a92a42STang Yun ping u32 hz; 24*16a92a42STang Yun ping u32 lcdc_type; 25*16a92a42STang Yun ping u32 vop; 26*16a92a42STang Yun ping u32 vop_dclk_mode; 27*16a92a42STang Yun ping u32 sr_idle_en; 28*16a92a42STang Yun ping u32 addr_mcu_el3; 29*16a92a42STang Yun ping /* 30*16a92a42STang Yun ping * 1: need to wait flag1 31*16a92a42STang Yun ping * 0: never wait flag1 32*16a92a42STang Yun ping */ 33*16a92a42STang Yun ping u32 wait_flag1; 34*16a92a42STang Yun ping /* 35*16a92a42STang Yun ping * 1: need to wait flag1 36*16a92a42STang Yun ping * 0: never wait flag1 37*16a92a42STang Yun ping */ 38*16a92a42STang Yun ping u32 wait_flag0; 39*16a92a42STang Yun ping u32 complt_hwirq; 40*16a92a42STang Yun ping /* if need, add parameter after */ 41*16a92a42STang Yun ping }; 42*16a92a42STang Yun ping 43*16a92a42STang Yun ping static struct share_params *ddr_psci_param; 44*16a92a42STang Yun ping 45*16a92a42STang Yun ping /* hope this define can adapt all future platfor */ 46*16a92a42STang Yun ping static const char * const rk3328_dts_timing[] = { 47*16a92a42STang Yun ping "ddr3_speed_bin", 48*16a92a42STang Yun ping "ddr4_speed_bin", 49*16a92a42STang Yun ping "pd_idle", 50*16a92a42STang Yun ping "sr_idle", 51*16a92a42STang Yun ping "sr_mc_gate_idle", 52*16a92a42STang Yun ping "srpd_lite_idle", 53*16a92a42STang Yun ping "standby_idle", 54*16a92a42STang Yun ping 55*16a92a42STang Yun ping "auto_pd_dis_freq", 56*16a92a42STang Yun ping "auto_sr_dis_freq", 57*16a92a42STang Yun ping "ddr3_dll_dis_freq", 58*16a92a42STang Yun ping "ddr4_dll_dis_freq", 59*16a92a42STang Yun ping "phy_dll_dis_freq", 60*16a92a42STang Yun ping 61*16a92a42STang Yun ping "ddr3_odt_dis_freq", 62*16a92a42STang Yun ping "phy_ddr3_odt_dis_freq", 63*16a92a42STang Yun ping "ddr3_drv", 64*16a92a42STang Yun ping "ddr3_odt", 65*16a92a42STang Yun ping "phy_ddr3_ca_drv", 66*16a92a42STang Yun ping "phy_ddr3_ck_drv", 67*16a92a42STang Yun ping "phy_ddr3_dq_drv", 68*16a92a42STang Yun ping "phy_ddr3_odt", 69*16a92a42STang Yun ping 70*16a92a42STang Yun ping "lpddr3_odt_dis_freq", 71*16a92a42STang Yun ping "phy_lpddr3_odt_dis_freq", 72*16a92a42STang Yun ping "lpddr3_drv", 73*16a92a42STang Yun ping "lpddr3_odt", 74*16a92a42STang Yun ping "phy_lpddr3_ca_drv", 75*16a92a42STang Yun ping "phy_lpddr3_ck_drv", 76*16a92a42STang Yun ping "phy_lpddr3_dq_drv", 77*16a92a42STang Yun ping "phy_lpddr3_odt", 78*16a92a42STang Yun ping 79*16a92a42STang Yun ping "lpddr4_odt_dis_freq", 80*16a92a42STang Yun ping "phy_lpddr4_odt_dis_freq", 81*16a92a42STang Yun ping "lpddr4_drv", 82*16a92a42STang Yun ping "lpddr4_dq_odt", 83*16a92a42STang Yun ping "lpddr4_ca_odt", 84*16a92a42STang Yun ping "phy_lpddr4_ca_drv", 85*16a92a42STang Yun ping "phy_lpddr4_ck_cs_drv", 86*16a92a42STang Yun ping "phy_lpddr4_dq_drv", 87*16a92a42STang Yun ping "phy_lpddr4_odt", 88*16a92a42STang Yun ping 89*16a92a42STang Yun ping "ddr4_odt_dis_freq", 90*16a92a42STang Yun ping "phy_ddr4_odt_dis_freq", 91*16a92a42STang Yun ping "ddr4_drv", 92*16a92a42STang Yun ping "ddr4_odt", 93*16a92a42STang Yun ping "phy_ddr4_ca_drv", 94*16a92a42STang Yun ping "phy_ddr4_ck_drv", 95*16a92a42STang Yun ping "phy_ddr4_dq_drv", 96*16a92a42STang Yun ping "phy_ddr4_odt", 97*16a92a42STang Yun ping }; 98*16a92a42STang Yun ping 99*16a92a42STang Yun ping static const char * const px30_dts_timing[] = { 100*16a92a42STang Yun ping "ddr2_speed_bin", 101*16a92a42STang Yun ping "ddr3_speed_bin", 102*16a92a42STang Yun ping "ddr4_speed_bin", 103*16a92a42STang Yun ping "pd_idle", 104*16a92a42STang Yun ping "sr_idle", 105*16a92a42STang Yun ping "sr_mc_gate_idle", 106*16a92a42STang Yun ping "srpd_lite_idle", 107*16a92a42STang Yun ping "standby_idle", 108*16a92a42STang Yun ping 109*16a92a42STang Yun ping "auto_pd_dis_freq", 110*16a92a42STang Yun ping "auto_sr_dis_freq", 111*16a92a42STang Yun ping "ddr2_dll_dis_freq", 112*16a92a42STang Yun ping "ddr3_dll_dis_freq", 113*16a92a42STang Yun ping "ddr4_dll_dis_freq", 114*16a92a42STang Yun ping "phy_dll_dis_freq", 115*16a92a42STang Yun ping 116*16a92a42STang Yun ping "ddr2_odt_dis_freq", 117*16a92a42STang Yun ping "phy_ddr2_odt_dis_freq", 118*16a92a42STang Yun ping "ddr2_drv", 119*16a92a42STang Yun ping "ddr2_odt", 120*16a92a42STang Yun ping "phy_ddr2_ca_drv", 121*16a92a42STang Yun ping "phy_ddr2_ck_drv", 122*16a92a42STang Yun ping "phy_ddr2_dq_drv", 123*16a92a42STang Yun ping "phy_ddr2_odt", 124*16a92a42STang Yun ping 125*16a92a42STang Yun ping "ddr3_odt_dis_freq", 126*16a92a42STang Yun ping "phy_ddr3_odt_dis_freq", 127*16a92a42STang Yun ping "ddr3_drv", 128*16a92a42STang Yun ping "ddr3_odt", 129*16a92a42STang Yun ping "phy_ddr3_ca_drv", 130*16a92a42STang Yun ping "phy_ddr3_ck_drv", 131*16a92a42STang Yun ping "phy_ddr3_dq_drv", 132*16a92a42STang Yun ping "phy_ddr3_odt", 133*16a92a42STang Yun ping 134*16a92a42STang Yun ping "phy_lpddr2_odt_dis_freq", 135*16a92a42STang Yun ping "lpddr2_drv", 136*16a92a42STang Yun ping "phy_lpddr2_ca_drv", 137*16a92a42STang Yun ping "phy_lpddr2_ck_drv", 138*16a92a42STang Yun ping "phy_lpddr2_dq_drv", 139*16a92a42STang Yun ping "phy_lpddr2_odt", 140*16a92a42STang Yun ping 141*16a92a42STang Yun ping "lpddr3_odt_dis_freq", 142*16a92a42STang Yun ping "phy_lpddr3_odt_dis_freq", 143*16a92a42STang Yun ping "lpddr3_drv", 144*16a92a42STang Yun ping "lpddr3_odt", 145*16a92a42STang Yun ping "phy_lpddr3_ca_drv", 146*16a92a42STang Yun ping "phy_lpddr3_ck_drv", 147*16a92a42STang Yun ping "phy_lpddr3_dq_drv", 148*16a92a42STang Yun ping "phy_lpddr3_odt", 149*16a92a42STang Yun ping 150*16a92a42STang Yun ping "lpddr4_odt_dis_freq", 151*16a92a42STang Yun ping "phy_lpddr4_odt_dis_freq", 152*16a92a42STang Yun ping "lpddr4_drv", 153*16a92a42STang Yun ping "lpddr4_dq_odt", 154*16a92a42STang Yun ping "lpddr4_ca_odt", 155*16a92a42STang Yun ping "phy_lpddr4_ca_drv", 156*16a92a42STang Yun ping "phy_lpddr4_ck_cs_drv", 157*16a92a42STang Yun ping "phy_lpddr4_dq_drv", 158*16a92a42STang Yun ping "phy_lpddr4_odt", 159*16a92a42STang Yun ping 160*16a92a42STang Yun ping "ddr4_odt_dis_freq", 161*16a92a42STang Yun ping "phy_ddr4_odt_dis_freq", 162*16a92a42STang Yun ping "ddr4_drv", 163*16a92a42STang Yun ping "ddr4_odt", 164*16a92a42STang Yun ping "phy_ddr4_ca_drv", 165*16a92a42STang Yun ping "phy_ddr4_ck_drv", 166*16a92a42STang Yun ping "phy_ddr4_dq_drv", 167*16a92a42STang Yun ping "phy_ddr4_odt", 168*16a92a42STang Yun ping }; 169*16a92a42STang Yun ping 170*16a92a42STang Yun ping static const char * const rk3328_dts_ca_timing[] = { 171*16a92a42STang Yun ping "ddr3a1_ddr4a9_de-skew", 172*16a92a42STang Yun ping "ddr3a0_ddr4a10_de-skew", 173*16a92a42STang Yun ping "ddr3a3_ddr4a6_de-skew", 174*16a92a42STang Yun ping "ddr3a2_ddr4a4_de-skew", 175*16a92a42STang Yun ping "ddr3a5_ddr4a8_de-skew", 176*16a92a42STang Yun ping "ddr3a4_ddr4a5_de-skew", 177*16a92a42STang Yun ping "ddr3a7_ddr4a11_de-skew", 178*16a92a42STang Yun ping "ddr3a6_ddr4a7_de-skew", 179*16a92a42STang Yun ping "ddr3a9_ddr4a0_de-skew", 180*16a92a42STang Yun ping "ddr3a8_ddr4a13_de-skew", 181*16a92a42STang Yun ping "ddr3a11_ddr4a3_de-skew", 182*16a92a42STang Yun ping "ddr3a10_ddr4cs0_de-skew", 183*16a92a42STang Yun ping "ddr3a13_ddr4a2_de-skew", 184*16a92a42STang Yun ping "ddr3a12_ddr4ba1_de-skew", 185*16a92a42STang Yun ping "ddr3a15_ddr4odt0_de-skew", 186*16a92a42STang Yun ping "ddr3a14_ddr4a1_de-skew", 187*16a92a42STang Yun ping "ddr3ba1_ddr4a15_de-skew", 188*16a92a42STang Yun ping "ddr3ba0_ddr4bg0_de-skew", 189*16a92a42STang Yun ping "ddr3ras_ddr4cke_de-skew", 190*16a92a42STang Yun ping "ddr3ba2_ddr4ba0_de-skew", 191*16a92a42STang Yun ping "ddr3we_ddr4bg1_de-skew", 192*16a92a42STang Yun ping "ddr3cas_ddr4a12_de-skew", 193*16a92a42STang Yun ping "ddr3ckn_ddr4ckn_de-skew", 194*16a92a42STang Yun ping "ddr3ckp_ddr4ckp_de-skew", 195*16a92a42STang Yun ping "ddr3cke_ddr4a16_de-skew", 196*16a92a42STang Yun ping "ddr3odt0_ddr4a14_de-skew", 197*16a92a42STang Yun ping "ddr3cs0_ddr4act_de-skew", 198*16a92a42STang Yun ping "ddr3reset_ddr4reset_de-skew", 199*16a92a42STang Yun ping "ddr3cs1_ddr4cs1_de-skew", 200*16a92a42STang Yun ping "ddr3odt1_ddr4odt1_de-skew", 201*16a92a42STang Yun ping }; 202*16a92a42STang Yun ping 203*16a92a42STang Yun ping static const char * const rk3328_dts_cs0_timing[] = { 204*16a92a42STang Yun ping "cs0_dm0_rx_de-skew", 205*16a92a42STang Yun ping "cs0_dm0_tx_de-skew", 206*16a92a42STang Yun ping "cs0_dq0_rx_de-skew", 207*16a92a42STang Yun ping "cs0_dq0_tx_de-skew", 208*16a92a42STang Yun ping "cs0_dq1_rx_de-skew", 209*16a92a42STang Yun ping "cs0_dq1_tx_de-skew", 210*16a92a42STang Yun ping "cs0_dq2_rx_de-skew", 211*16a92a42STang Yun ping "cs0_dq2_tx_de-skew", 212*16a92a42STang Yun ping "cs0_dq3_rx_de-skew", 213*16a92a42STang Yun ping "cs0_dq3_tx_de-skew", 214*16a92a42STang Yun ping "cs0_dq4_rx_de-skew", 215*16a92a42STang Yun ping "cs0_dq4_tx_de-skew", 216*16a92a42STang Yun ping "cs0_dq5_rx_de-skew", 217*16a92a42STang Yun ping "cs0_dq5_tx_de-skew", 218*16a92a42STang Yun ping "cs0_dq6_rx_de-skew", 219*16a92a42STang Yun ping "cs0_dq6_tx_de-skew", 220*16a92a42STang Yun ping "cs0_dq7_rx_de-skew", 221*16a92a42STang Yun ping "cs0_dq7_tx_de-skew", 222*16a92a42STang Yun ping "cs0_dqs0_rx_de-skew", 223*16a92a42STang Yun ping "cs0_dqs0p_tx_de-skew", 224*16a92a42STang Yun ping "cs0_dqs0n_tx_de-skew", 225*16a92a42STang Yun ping 226*16a92a42STang Yun ping "cs0_dm1_rx_de-skew", 227*16a92a42STang Yun ping "cs0_dm1_tx_de-skew", 228*16a92a42STang Yun ping "cs0_dq8_rx_de-skew", 229*16a92a42STang Yun ping "cs0_dq8_tx_de-skew", 230*16a92a42STang Yun ping "cs0_dq9_rx_de-skew", 231*16a92a42STang Yun ping "cs0_dq9_tx_de-skew", 232*16a92a42STang Yun ping "cs0_dq10_rx_de-skew", 233*16a92a42STang Yun ping "cs0_dq10_tx_de-skew", 234*16a92a42STang Yun ping "cs0_dq11_rx_de-skew", 235*16a92a42STang Yun ping "cs0_dq11_tx_de-skew", 236*16a92a42STang Yun ping "cs0_dq12_rx_de-skew", 237*16a92a42STang Yun ping "cs0_dq12_tx_de-skew", 238*16a92a42STang Yun ping "cs0_dq13_rx_de-skew", 239*16a92a42STang Yun ping "cs0_dq13_tx_de-skew", 240*16a92a42STang Yun ping "cs0_dq14_rx_de-skew", 241*16a92a42STang Yun ping "cs0_dq14_tx_de-skew", 242*16a92a42STang Yun ping "cs0_dq15_rx_de-skew", 243*16a92a42STang Yun ping "cs0_dq15_tx_de-skew", 244*16a92a42STang Yun ping "cs0_dqs1_rx_de-skew", 245*16a92a42STang Yun ping "cs0_dqs1p_tx_de-skew", 246*16a92a42STang Yun ping "cs0_dqs1n_tx_de-skew", 247*16a92a42STang Yun ping 248*16a92a42STang Yun ping "cs0_dm2_rx_de-skew", 249*16a92a42STang Yun ping "cs0_dm2_tx_de-skew", 250*16a92a42STang Yun ping "cs0_dq16_rx_de-skew", 251*16a92a42STang Yun ping "cs0_dq16_tx_de-skew", 252*16a92a42STang Yun ping "cs0_dq17_rx_de-skew", 253*16a92a42STang Yun ping "cs0_dq17_tx_de-skew", 254*16a92a42STang Yun ping "cs0_dq18_rx_de-skew", 255*16a92a42STang Yun ping "cs0_dq18_tx_de-skew", 256*16a92a42STang Yun ping "cs0_dq19_rx_de-skew", 257*16a92a42STang Yun ping "cs0_dq19_tx_de-skew", 258*16a92a42STang Yun ping "cs0_dq20_rx_de-skew", 259*16a92a42STang Yun ping "cs0_dq20_tx_de-skew", 260*16a92a42STang Yun ping "cs0_dq21_rx_de-skew", 261*16a92a42STang Yun ping "cs0_dq21_tx_de-skew", 262*16a92a42STang Yun ping "cs0_dq22_rx_de-skew", 263*16a92a42STang Yun ping "cs0_dq22_tx_de-skew", 264*16a92a42STang Yun ping "cs0_dq23_rx_de-skew", 265*16a92a42STang Yun ping "cs0_dq23_tx_de-skew", 266*16a92a42STang Yun ping "cs0_dqs2_rx_de-skew", 267*16a92a42STang Yun ping "cs0_dqs2p_tx_de-skew", 268*16a92a42STang Yun ping "cs0_dqs2n_tx_de-skew", 269*16a92a42STang Yun ping 270*16a92a42STang Yun ping "cs0_dm3_rx_de-skew", 271*16a92a42STang Yun ping "cs0_dm3_tx_de-skew", 272*16a92a42STang Yun ping "cs0_dq24_rx_de-skew", 273*16a92a42STang Yun ping "cs0_dq24_tx_de-skew", 274*16a92a42STang Yun ping "cs0_dq25_rx_de-skew", 275*16a92a42STang Yun ping "cs0_dq25_tx_de-skew", 276*16a92a42STang Yun ping "cs0_dq26_rx_de-skew", 277*16a92a42STang Yun ping "cs0_dq26_tx_de-skew", 278*16a92a42STang Yun ping "cs0_dq27_rx_de-skew", 279*16a92a42STang Yun ping "cs0_dq27_tx_de-skew", 280*16a92a42STang Yun ping "cs0_dq28_rx_de-skew", 281*16a92a42STang Yun ping "cs0_dq28_tx_de-skew", 282*16a92a42STang Yun ping "cs0_dq29_rx_de-skew", 283*16a92a42STang Yun ping "cs0_dq29_tx_de-skew", 284*16a92a42STang Yun ping "cs0_dq30_rx_de-skew", 285*16a92a42STang Yun ping "cs0_dq30_tx_de-skew", 286*16a92a42STang Yun ping "cs0_dq31_rx_de-skew", 287*16a92a42STang Yun ping "cs0_dq31_tx_de-skew", 288*16a92a42STang Yun ping "cs0_dqs3_rx_de-skew", 289*16a92a42STang Yun ping "cs0_dqs3p_tx_de-skew", 290*16a92a42STang Yun ping "cs0_dqs3n_tx_de-skew", 291*16a92a42STang Yun ping }; 292*16a92a42STang Yun ping 293*16a92a42STang Yun ping static const char * const rk3328_dts_cs1_timing[] = { 294*16a92a42STang Yun ping "cs1_dm0_rx_de-skew", 295*16a92a42STang Yun ping "cs1_dm0_tx_de-skew", 296*16a92a42STang Yun ping "cs1_dq0_rx_de-skew", 297*16a92a42STang Yun ping "cs1_dq0_tx_de-skew", 298*16a92a42STang Yun ping "cs1_dq1_rx_de-skew", 299*16a92a42STang Yun ping "cs1_dq1_tx_de-skew", 300*16a92a42STang Yun ping "cs1_dq2_rx_de-skew", 301*16a92a42STang Yun ping "cs1_dq2_tx_de-skew", 302*16a92a42STang Yun ping "cs1_dq3_rx_de-skew", 303*16a92a42STang Yun ping "cs1_dq3_tx_de-skew", 304*16a92a42STang Yun ping "cs1_dq4_rx_de-skew", 305*16a92a42STang Yun ping "cs1_dq4_tx_de-skew", 306*16a92a42STang Yun ping "cs1_dq5_rx_de-skew", 307*16a92a42STang Yun ping "cs1_dq5_tx_de-skew", 308*16a92a42STang Yun ping "cs1_dq6_rx_de-skew", 309*16a92a42STang Yun ping "cs1_dq6_tx_de-skew", 310*16a92a42STang Yun ping "cs1_dq7_rx_de-skew", 311*16a92a42STang Yun ping "cs1_dq7_tx_de-skew", 312*16a92a42STang Yun ping "cs1_dqs0_rx_de-skew", 313*16a92a42STang Yun ping "cs1_dqs0p_tx_de-skew", 314*16a92a42STang Yun ping "cs1_dqs0n_tx_de-skew", 315*16a92a42STang Yun ping 316*16a92a42STang Yun ping "cs1_dm1_rx_de-skew", 317*16a92a42STang Yun ping "cs1_dm1_tx_de-skew", 318*16a92a42STang Yun ping "cs1_dq8_rx_de-skew", 319*16a92a42STang Yun ping "cs1_dq8_tx_de-skew", 320*16a92a42STang Yun ping "cs1_dq9_rx_de-skew", 321*16a92a42STang Yun ping "cs1_dq9_tx_de-skew", 322*16a92a42STang Yun ping "cs1_dq10_rx_de-skew", 323*16a92a42STang Yun ping "cs1_dq10_tx_de-skew", 324*16a92a42STang Yun ping "cs1_dq11_rx_de-skew", 325*16a92a42STang Yun ping "cs1_dq11_tx_de-skew", 326*16a92a42STang Yun ping "cs1_dq12_rx_de-skew", 327*16a92a42STang Yun ping "cs1_dq12_tx_de-skew", 328*16a92a42STang Yun ping "cs1_dq13_rx_de-skew", 329*16a92a42STang Yun ping "cs1_dq13_tx_de-skew", 330*16a92a42STang Yun ping "cs1_dq14_rx_de-skew", 331*16a92a42STang Yun ping "cs1_dq14_tx_de-skew", 332*16a92a42STang Yun ping "cs1_dq15_rx_de-skew", 333*16a92a42STang Yun ping "cs1_dq15_tx_de-skew", 334*16a92a42STang Yun ping "cs1_dqs1_rx_de-skew", 335*16a92a42STang Yun ping "cs1_dqs1p_tx_de-skew", 336*16a92a42STang Yun ping "cs1_dqs1n_tx_de-skew", 337*16a92a42STang Yun ping 338*16a92a42STang Yun ping "cs1_dm2_rx_de-skew", 339*16a92a42STang Yun ping "cs1_dm2_tx_de-skew", 340*16a92a42STang Yun ping "cs1_dq16_rx_de-skew", 341*16a92a42STang Yun ping "cs1_dq16_tx_de-skew", 342*16a92a42STang Yun ping "cs1_dq17_rx_de-skew", 343*16a92a42STang Yun ping "cs1_dq17_tx_de-skew", 344*16a92a42STang Yun ping "cs1_dq18_rx_de-skew", 345*16a92a42STang Yun ping "cs1_dq18_tx_de-skew", 346*16a92a42STang Yun ping "cs1_dq19_rx_de-skew", 347*16a92a42STang Yun ping "cs1_dq19_tx_de-skew", 348*16a92a42STang Yun ping "cs1_dq20_rx_de-skew", 349*16a92a42STang Yun ping "cs1_dq20_tx_de-skew", 350*16a92a42STang Yun ping "cs1_dq21_rx_de-skew", 351*16a92a42STang Yun ping "cs1_dq21_tx_de-skew", 352*16a92a42STang Yun ping "cs1_dq22_rx_de-skew", 353*16a92a42STang Yun ping "cs1_dq22_tx_de-skew", 354*16a92a42STang Yun ping "cs1_dq23_rx_de-skew", 355*16a92a42STang Yun ping "cs1_dq23_tx_de-skew", 356*16a92a42STang Yun ping "cs1_dqs2_rx_de-skew", 357*16a92a42STang Yun ping "cs1_dqs2p_tx_de-skew", 358*16a92a42STang Yun ping "cs1_dqs2n_tx_de-skew", 359*16a92a42STang Yun ping 360*16a92a42STang Yun ping "cs1_dm3_rx_de-skew", 361*16a92a42STang Yun ping "cs1_dm3_tx_de-skew", 362*16a92a42STang Yun ping "cs1_dq24_rx_de-skew", 363*16a92a42STang Yun ping "cs1_dq24_tx_de-skew", 364*16a92a42STang Yun ping "cs1_dq25_rx_de-skew", 365*16a92a42STang Yun ping "cs1_dq25_tx_de-skew", 366*16a92a42STang Yun ping "cs1_dq26_rx_de-skew", 367*16a92a42STang Yun ping "cs1_dq26_tx_de-skew", 368*16a92a42STang Yun ping "cs1_dq27_rx_de-skew", 369*16a92a42STang Yun ping "cs1_dq27_tx_de-skew", 370*16a92a42STang Yun ping "cs1_dq28_rx_de-skew", 371*16a92a42STang Yun ping "cs1_dq28_tx_de-skew", 372*16a92a42STang Yun ping "cs1_dq29_rx_de-skew", 373*16a92a42STang Yun ping "cs1_dq29_tx_de-skew", 374*16a92a42STang Yun ping "cs1_dq30_rx_de-skew", 375*16a92a42STang Yun ping "cs1_dq30_tx_de-skew", 376*16a92a42STang Yun ping "cs1_dq31_rx_de-skew", 377*16a92a42STang Yun ping "cs1_dq31_tx_de-skew", 378*16a92a42STang Yun ping "cs1_dqs3_rx_de-skew", 379*16a92a42STang Yun ping "cs1_dqs3p_tx_de-skew", 380*16a92a42STang Yun ping "cs1_dqs3n_tx_de-skew", 381*16a92a42STang Yun ping }; 382*16a92a42STang Yun ping 383*16a92a42STang Yun ping struct rk3328_ddr_dts_config_timing { 384*16a92a42STang Yun ping unsigned int ddr3_speed_bin; 385*16a92a42STang Yun ping unsigned int ddr4_speed_bin; 386*16a92a42STang Yun ping unsigned int pd_idle; 387*16a92a42STang Yun ping unsigned int sr_idle; 388*16a92a42STang Yun ping unsigned int sr_mc_gate_idle; 389*16a92a42STang Yun ping unsigned int srpd_lite_idle; 390*16a92a42STang Yun ping unsigned int standby_idle; 391*16a92a42STang Yun ping 392*16a92a42STang Yun ping unsigned int auto_pd_dis_freq; 393*16a92a42STang Yun ping unsigned int auto_sr_dis_freq; 394*16a92a42STang Yun ping /* for ddr3 only */ 395*16a92a42STang Yun ping unsigned int ddr3_dll_dis_freq; 396*16a92a42STang Yun ping /* for ddr4 only */ 397*16a92a42STang Yun ping unsigned int ddr4_dll_dis_freq; 398*16a92a42STang Yun ping unsigned int phy_dll_dis_freq; 399*16a92a42STang Yun ping 400*16a92a42STang Yun ping unsigned int ddr3_odt_dis_freq; 401*16a92a42STang Yun ping unsigned int phy_ddr3_odt_dis_freq; 402*16a92a42STang Yun ping unsigned int ddr3_drv; 403*16a92a42STang Yun ping unsigned int ddr3_odt; 404*16a92a42STang Yun ping unsigned int phy_ddr3_ca_drv; 405*16a92a42STang Yun ping unsigned int phy_ddr3_ck_drv; 406*16a92a42STang Yun ping unsigned int phy_ddr3_dq_drv; 407*16a92a42STang Yun ping unsigned int phy_ddr3_odt; 408*16a92a42STang Yun ping 409*16a92a42STang Yun ping unsigned int lpddr3_odt_dis_freq; 410*16a92a42STang Yun ping unsigned int phy_lpddr3_odt_dis_freq; 411*16a92a42STang Yun ping unsigned int lpddr3_drv; 412*16a92a42STang Yun ping unsigned int lpddr3_odt; 413*16a92a42STang Yun ping unsigned int phy_lpddr3_ca_drv; 414*16a92a42STang Yun ping unsigned int phy_lpddr3_ck_drv; 415*16a92a42STang Yun ping unsigned int phy_lpddr3_dq_drv; 416*16a92a42STang Yun ping unsigned int phy_lpddr3_odt; 417*16a92a42STang Yun ping 418*16a92a42STang Yun ping unsigned int lpddr4_odt_dis_freq; 419*16a92a42STang Yun ping unsigned int phy_lpddr4_odt_dis_freq; 420*16a92a42STang Yun ping unsigned int lpddr4_drv; 421*16a92a42STang Yun ping unsigned int lpddr4_dq_odt; 422*16a92a42STang Yun ping unsigned int lpddr4_ca_odt; 423*16a92a42STang Yun ping unsigned int phy_lpddr4_ca_drv; 424*16a92a42STang Yun ping unsigned int phy_lpddr4_ck_cs_drv; 425*16a92a42STang Yun ping unsigned int phy_lpddr4_dq_drv; 426*16a92a42STang Yun ping unsigned int phy_lpddr4_odt; 427*16a92a42STang Yun ping 428*16a92a42STang Yun ping unsigned int ddr4_odt_dis_freq; 429*16a92a42STang Yun ping unsigned int phy_ddr4_odt_dis_freq; 430*16a92a42STang Yun ping unsigned int ddr4_drv; 431*16a92a42STang Yun ping unsigned int ddr4_odt; 432*16a92a42STang Yun ping unsigned int phy_ddr4_ca_drv; 433*16a92a42STang Yun ping unsigned int phy_ddr4_ck_drv; 434*16a92a42STang Yun ping unsigned int phy_ddr4_dq_drv; 435*16a92a42STang Yun ping unsigned int phy_ddr4_odt; 436*16a92a42STang Yun ping 437*16a92a42STang Yun ping unsigned int ca_skew[15]; 438*16a92a42STang Yun ping unsigned int cs0_skew[44]; 439*16a92a42STang Yun ping unsigned int cs1_skew[44]; 440*16a92a42STang Yun ping 441*16a92a42STang Yun ping unsigned int available; 442*16a92a42STang Yun ping }; 443*16a92a42STang Yun ping 444*16a92a42STang Yun ping struct px30_ddr_dts_config_timing { 445*16a92a42STang Yun ping unsigned int ddr2_speed_bin; 446*16a92a42STang Yun ping unsigned int ddr3_speed_bin; 447*16a92a42STang Yun ping unsigned int ddr4_speed_bin; 448*16a92a42STang Yun ping unsigned int pd_idle; 449*16a92a42STang Yun ping unsigned int sr_idle; 450*16a92a42STang Yun ping unsigned int sr_mc_gate_idle; 451*16a92a42STang Yun ping unsigned int srpd_lite_idle; 452*16a92a42STang Yun ping unsigned int standby_idle; 453*16a92a42STang Yun ping 454*16a92a42STang Yun ping unsigned int auto_pd_dis_freq; 455*16a92a42STang Yun ping unsigned int auto_sr_dis_freq; 456*16a92a42STang Yun ping /* for ddr2 only */ 457*16a92a42STang Yun ping unsigned int ddr2_dll_dis_freq; 458*16a92a42STang Yun ping /* for ddr3 only */ 459*16a92a42STang Yun ping unsigned int ddr3_dll_dis_freq; 460*16a92a42STang Yun ping /* for ddr4 only */ 461*16a92a42STang Yun ping unsigned int ddr4_dll_dis_freq; 462*16a92a42STang Yun ping unsigned int phy_dll_dis_freq; 463*16a92a42STang Yun ping 464*16a92a42STang Yun ping unsigned int ddr2_odt_dis_freq; 465*16a92a42STang Yun ping unsigned int phy_ddr2_odt_dis_freq; 466*16a92a42STang Yun ping unsigned int ddr2_drv; 467*16a92a42STang Yun ping unsigned int ddr2_odt; 468*16a92a42STang Yun ping unsigned int phy_ddr2_ca_drv; 469*16a92a42STang Yun ping unsigned int phy_ddr2_ck_drv; 470*16a92a42STang Yun ping unsigned int phy_ddr2_dq_drv; 471*16a92a42STang Yun ping unsigned int phy_ddr2_odt; 472*16a92a42STang Yun ping 473*16a92a42STang Yun ping unsigned int ddr3_odt_dis_freq; 474*16a92a42STang Yun ping unsigned int phy_ddr3_odt_dis_freq; 475*16a92a42STang Yun ping unsigned int ddr3_drv; 476*16a92a42STang Yun ping unsigned int ddr3_odt; 477*16a92a42STang Yun ping unsigned int phy_ddr3_ca_drv; 478*16a92a42STang Yun ping unsigned int phy_ddr3_ck_drv; 479*16a92a42STang Yun ping unsigned int phy_ddr3_dq_drv; 480*16a92a42STang Yun ping unsigned int phy_ddr3_odt; 481*16a92a42STang Yun ping 482*16a92a42STang Yun ping unsigned int phy_lpddr2_odt_dis_freq; 483*16a92a42STang Yun ping unsigned int lpddr2_drv; 484*16a92a42STang Yun ping unsigned int phy_lpddr2_ca_drv; 485*16a92a42STang Yun ping unsigned int phy_lpddr2_ck_drv; 486*16a92a42STang Yun ping unsigned int phy_lpddr2_dq_drv; 487*16a92a42STang Yun ping unsigned int phy_lpddr2_odt; 488*16a92a42STang Yun ping 489*16a92a42STang Yun ping unsigned int lpddr3_odt_dis_freq; 490*16a92a42STang Yun ping unsigned int phy_lpddr3_odt_dis_freq; 491*16a92a42STang Yun ping unsigned int lpddr3_drv; 492*16a92a42STang Yun ping unsigned int lpddr3_odt; 493*16a92a42STang Yun ping unsigned int phy_lpddr3_ca_drv; 494*16a92a42STang Yun ping unsigned int phy_lpddr3_ck_drv; 495*16a92a42STang Yun ping unsigned int phy_lpddr3_dq_drv; 496*16a92a42STang Yun ping unsigned int phy_lpddr3_odt; 497*16a92a42STang Yun ping 498*16a92a42STang Yun ping unsigned int lpddr4_odt_dis_freq; 499*16a92a42STang Yun ping unsigned int phy_lpddr4_odt_dis_freq; 500*16a92a42STang Yun ping unsigned int lpddr4_drv; 501*16a92a42STang Yun ping unsigned int lpddr4_dq_odt; 502*16a92a42STang Yun ping unsigned int lpddr4_ca_odt; 503*16a92a42STang Yun ping unsigned int phy_lpddr4_ca_drv; 504*16a92a42STang Yun ping unsigned int phy_lpddr4_ck_cs_drv; 505*16a92a42STang Yun ping unsigned int phy_lpddr4_dq_drv; 506*16a92a42STang Yun ping unsigned int phy_lpddr4_odt; 507*16a92a42STang Yun ping 508*16a92a42STang Yun ping unsigned int ddr4_odt_dis_freq; 509*16a92a42STang Yun ping unsigned int phy_ddr4_odt_dis_freq; 510*16a92a42STang Yun ping unsigned int ddr4_drv; 511*16a92a42STang Yun ping unsigned int ddr4_odt; 512*16a92a42STang Yun ping unsigned int phy_ddr4_ca_drv; 513*16a92a42STang Yun ping unsigned int phy_ddr4_ck_drv; 514*16a92a42STang Yun ping unsigned int phy_ddr4_dq_drv; 515*16a92a42STang Yun ping unsigned int phy_ddr4_odt; 516*16a92a42STang Yun ping 517*16a92a42STang Yun ping unsigned int ca_skew[15]; 518*16a92a42STang Yun ping unsigned int cs0_skew[44]; 519*16a92a42STang Yun ping unsigned int cs1_skew[44]; 520*16a92a42STang Yun ping 521*16a92a42STang Yun ping unsigned int available; 522*16a92a42STang Yun ping }; 523*16a92a42STang Yun ping 524*16a92a42STang Yun ping struct rk3328_ddr_de_skew_setting { 525*16a92a42STang Yun ping unsigned int ca_de_skew[30]; 526*16a92a42STang Yun ping unsigned int cs0_de_skew[84]; 527*16a92a42STang Yun ping unsigned int cs1_de_skew[84]; 528*16a92a42STang Yun ping }; 529*16a92a42STang Yun ping 530*16a92a42STang Yun ping static void 531*16a92a42STang Yun ping rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting *de_skew, 532*16a92a42STang Yun ping struct rk3328_ddr_dts_config_timing *tim) 533*16a92a42STang Yun ping { 534*16a92a42STang Yun ping u32 n; 535*16a92a42STang Yun ping u32 offset; 536*16a92a42STang Yun ping u32 shift; 537*16a92a42STang Yun ping 538*16a92a42STang Yun ping memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew)); 539*16a92a42STang Yun ping memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew)); 540*16a92a42STang Yun ping memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew)); 541*16a92a42STang Yun ping 542*16a92a42STang Yun ping /* CA de-skew */ 543*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) { 544*16a92a42STang Yun ping offset = n / 2; 545*16a92a42STang Yun ping shift = n % 2; 546*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 547*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 548*16a92a42STang Yun ping tim->ca_skew[offset] &= ~(0xf << shift); 549*16a92a42STang Yun ping tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift); 550*16a92a42STang Yun ping } 551*16a92a42STang Yun ping 552*16a92a42STang Yun ping /* CS0 data de-skew */ 553*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) { 554*16a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2); 555*16a92a42STang Yun ping shift = ((n % 21) % 2); 556*16a92a42STang Yun ping if ((n % 21) == 20) 557*16a92a42STang Yun ping shift = 0; 558*16a92a42STang Yun ping else 559*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 560*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 561*16a92a42STang Yun ping tim->cs0_skew[offset] &= ~(0xf << shift); 562*16a92a42STang Yun ping tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift); 563*16a92a42STang Yun ping } 564*16a92a42STang Yun ping 565*16a92a42STang Yun ping /* CS1 data de-skew */ 566*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) { 567*16a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2); 568*16a92a42STang Yun ping shift = ((n % 21) % 2); 569*16a92a42STang Yun ping if ((n % 21) == 20) 570*16a92a42STang Yun ping shift = 0; 571*16a92a42STang Yun ping else 572*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 573*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 574*16a92a42STang Yun ping tim->cs1_skew[offset] &= ~(0xf << shift); 575*16a92a42STang Yun ping tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift); 576*16a92a42STang Yun ping } 577*16a92a42STang Yun ping } 578*16a92a42STang Yun ping 579*16a92a42STang Yun ping static void px30_de_skew_set_2_reg(struct rk3328_ddr_de_skew_setting *de_skew, 580*16a92a42STang Yun ping struct px30_ddr_dts_config_timing *tim) 581*16a92a42STang Yun ping { 582*16a92a42STang Yun ping u32 n; 583*16a92a42STang Yun ping u32 offset; 584*16a92a42STang Yun ping u32 shift; 585*16a92a42STang Yun ping 586*16a92a42STang Yun ping memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew)); 587*16a92a42STang Yun ping memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew)); 588*16a92a42STang Yun ping memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew)); 589*16a92a42STang Yun ping 590*16a92a42STang Yun ping /* CA de-skew */ 591*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) { 592*16a92a42STang Yun ping offset = n / 2; 593*16a92a42STang Yun ping shift = n % 2; 594*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 595*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 596*16a92a42STang Yun ping tim->ca_skew[offset] &= ~(0xf << shift); 597*16a92a42STang Yun ping tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift); 598*16a92a42STang Yun ping } 599*16a92a42STang Yun ping 600*16a92a42STang Yun ping /* CS0 data de-skew */ 601*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) { 602*16a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2); 603*16a92a42STang Yun ping shift = ((n % 21) % 2); 604*16a92a42STang Yun ping if ((n % 21) == 20) 605*16a92a42STang Yun ping shift = 0; 606*16a92a42STang Yun ping else 607*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 608*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 609*16a92a42STang Yun ping tim->cs0_skew[offset] &= ~(0xf << shift); 610*16a92a42STang Yun ping tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift); 611*16a92a42STang Yun ping } 612*16a92a42STang Yun ping 613*16a92a42STang Yun ping /* CS1 data de-skew */ 614*16a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) { 615*16a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2); 616*16a92a42STang Yun ping shift = ((n % 21) % 2); 617*16a92a42STang Yun ping if ((n % 21) == 20) 618*16a92a42STang Yun ping shift = 0; 619*16a92a42STang Yun ping else 620*16a92a42STang Yun ping /* 0 => 4; 1 => 0 */ 621*16a92a42STang Yun ping shift = (shift == 0) ? 4 : 0; 622*16a92a42STang Yun ping tim->cs1_skew[offset] &= ~(0xf << shift); 623*16a92a42STang Yun ping tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift); 624*16a92a42STang Yun ping } 625*16a92a42STang Yun ping } 626*16a92a42STang Yun ping 627*16a92a42STang Yun ping static void of_get_rk3328_timings(struct udevice *dev, uint32_t *timing) 628*16a92a42STang Yun ping { 629*16a92a42STang Yun ping struct device_node *np_tim; 630*16a92a42STang Yun ping u32 *p; 631*16a92a42STang Yun ping struct rk3328_ddr_dts_config_timing *dts_timing; 632*16a92a42STang Yun ping struct rk3328_ddr_de_skew_setting *de_skew; 633*16a92a42STang Yun ping int ret = 0; 634*16a92a42STang Yun ping u32 i; 635*16a92a42STang Yun ping 636*16a92a42STang Yun ping dts_timing = 637*16a92a42STang Yun ping (struct rk3328_ddr_dts_config_timing *)(timing + 638*16a92a42STang Yun ping DTS_PAR_OFFSET / 4); 639*16a92a42STang Yun ping 640*16a92a42STang Yun ping np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), 641*16a92a42STang Yun ping "ddr_timing", 0); 642*16a92a42STang Yun ping if (!np_tim) { 643*16a92a42STang Yun ping ret = -EINVAL; 644*16a92a42STang Yun ping goto end; 645*16a92a42STang Yun ping } 646*16a92a42STang Yun ping de_skew = malloc(sizeof(*de_skew)); 647*16a92a42STang Yun ping if (!de_skew) { 648*16a92a42STang Yun ping ret = -ENOMEM; 649*16a92a42STang Yun ping goto end; 650*16a92a42STang Yun ping } 651*16a92a42STang Yun ping p = (u32 *)dts_timing; 652*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_timing); i++) 653*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 654*16a92a42STang Yun ping rk3328_dts_timing[i], p + i); 655*16a92a42STang Yun ping 656*16a92a42STang Yun ping p = (u32 *)de_skew->ca_de_skew; 657*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++) 658*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 659*16a92a42STang Yun ping rk3328_dts_ca_timing[i], p + i); 660*16a92a42STang Yun ping p = (u32 *)de_skew->cs0_de_skew; 661*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++) 662*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 663*16a92a42STang Yun ping rk3328_dts_cs0_timing[i], p + i); 664*16a92a42STang Yun ping p = (u32 *)de_skew->cs1_de_skew; 665*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++) 666*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 667*16a92a42STang Yun ping rk3328_dts_cs1_timing[i], p + i); 668*16a92a42STang Yun ping 669*16a92a42STang Yun ping if (!ret) 670*16a92a42STang Yun ping rk3328_de_skew_setting_2_register(de_skew, dts_timing); 671*16a92a42STang Yun ping free(de_skew); 672*16a92a42STang Yun ping end: 673*16a92a42STang Yun ping if (!ret) { 674*16a92a42STang Yun ping dts_timing->available = 1; 675*16a92a42STang Yun ping } else { 676*16a92a42STang Yun ping dts_timing->available = 0; 677*16a92a42STang Yun ping printf("of_get_ddr_timings: fail\n"); 678*16a92a42STang Yun ping } 679*16a92a42STang Yun ping } 680*16a92a42STang Yun ping 681*16a92a42STang Yun ping static void of_get_px30_timings(struct udevice *dev, uint32_t *timing) 682*16a92a42STang Yun ping { 683*16a92a42STang Yun ping struct device_node *np_tim; 684*16a92a42STang Yun ping u32 *p; 685*16a92a42STang Yun ping struct px30_ddr_dts_config_timing *dts_timing; 686*16a92a42STang Yun ping struct rk3328_ddr_de_skew_setting *de_skew; 687*16a92a42STang Yun ping int ret = 0; 688*16a92a42STang Yun ping u32 i; 689*16a92a42STang Yun ping 690*16a92a42STang Yun ping dts_timing = 691*16a92a42STang Yun ping (struct px30_ddr_dts_config_timing *)(timing + 692*16a92a42STang Yun ping DTS_PAR_OFFSET / 4); 693*16a92a42STang Yun ping 694*16a92a42STang Yun ping np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), 695*16a92a42STang Yun ping "ddr_timing", 0); 696*16a92a42STang Yun ping if (!np_tim) { 697*16a92a42STang Yun ping ret = -EINVAL; 698*16a92a42STang Yun ping goto end; 699*16a92a42STang Yun ping } 700*16a92a42STang Yun ping de_skew = malloc(sizeof(*de_skew)); 701*16a92a42STang Yun ping if (!de_skew) { 702*16a92a42STang Yun ping ret = -ENOMEM; 703*16a92a42STang Yun ping goto end; 704*16a92a42STang Yun ping } 705*16a92a42STang Yun ping p = (u32 *)dts_timing; 706*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(px30_dts_timing); i++) 707*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), px30_dts_timing[i], 708*16a92a42STang Yun ping p + i); 709*16a92a42STang Yun ping p = (u32 *)de_skew->ca_de_skew; 710*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++) 711*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 712*16a92a42STang Yun ping rk3328_dts_ca_timing[i], p + i); 713*16a92a42STang Yun ping p = (u32 *)de_skew->cs0_de_skew; 714*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++) 715*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 716*16a92a42STang Yun ping rk3328_dts_cs0_timing[i], p + i); 717*16a92a42STang Yun ping p = (u32 *)de_skew->cs1_de_skew; 718*16a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++) 719*16a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), 720*16a92a42STang Yun ping rk3328_dts_cs1_timing[i], p + i); 721*16a92a42STang Yun ping if (!ret) 722*16a92a42STang Yun ping px30_de_skew_set_2_reg(de_skew, dts_timing); 723*16a92a42STang Yun ping free(de_skew); 724*16a92a42STang Yun ping end: 725*16a92a42STang Yun ping if (!ret) { 726*16a92a42STang Yun ping dts_timing->available = 1; 727*16a92a42STang Yun ping } else { 728*16a92a42STang Yun ping dts_timing->available = 0; 729*16a92a42STang Yun ping printf("of_get_ddr_timings: fail\n"); 730*16a92a42STang Yun ping } 731*16a92a42STang Yun ping } 732*16a92a42STang Yun ping 733*16a92a42STang Yun ping static __maybe_unused int rk3328_devfreq_init(struct udevice *dev) 734*16a92a42STang Yun ping { 735*16a92a42STang Yun ping struct arm_smccc_res res; 736*16a92a42STang Yun ping u32 size; 737*16a92a42STang Yun ping 738*16a92a42STang Yun ping res = sip_smc_dram(0, 0, 739*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); 740*16a92a42STang Yun ping printf("current ATF version 0x%lx!\n", res.a1); 741*16a92a42STang Yun ping if (res.a0 || res.a1 < 0x101) { 742*16a92a42STang Yun ping printf("trusted firmware need to update or is invalid!\n"); 743*16a92a42STang Yun ping return -ENXIO; 744*16a92a42STang Yun ping } 745*16a92a42STang Yun ping 746*16a92a42STang Yun ping printf("read tf version 0x%lx!\n", res.a1); 747*16a92a42STang Yun ping 748*16a92a42STang Yun ping /* 749*16a92a42STang Yun ping * first 4KB is used for interface parameters 750*16a92a42STang Yun ping * after 4KB * N is dts parameters 751*16a92a42STang Yun ping */ 752*16a92a42STang Yun ping size = sizeof(struct rk3328_ddr_dts_config_timing); 753*16a92a42STang Yun ping res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, 754*16a92a42STang Yun ping SHARE_PAGE_TYPE_DDR); 755*16a92a42STang Yun ping if (res.a0 != 0) { 756*16a92a42STang Yun ping printf("no ATF memory for init\n"); 757*16a92a42STang Yun ping return -ENOMEM; 758*16a92a42STang Yun ping } 759*16a92a42STang Yun ping ddr_psci_param = (struct share_params *)res.a1; 760*16a92a42STang Yun ping of_get_rk3328_timings(dev, (uint32_t *)ddr_psci_param); 761*16a92a42STang Yun ping 762*16a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, 763*16a92a42STang Yun ping (DIV_ROUND_UP(size, 4096) + 1) * 0x1000); 764*16a92a42STang Yun ping 765*16a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, 766*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_INIT); 767*16a92a42STang Yun ping if (res.a0) { 768*16a92a42STang Yun ping printf("rockchip_sip_config_dram_init error:%lx\n", 769*16a92a42STang Yun ping res.a0); 770*16a92a42STang Yun ping return -ENOMEM; 771*16a92a42STang Yun ping } 772*16a92a42STang Yun ping 773*16a92a42STang Yun ping return 0; 774*16a92a42STang Yun ping } 775*16a92a42STang Yun ping 776*16a92a42STang Yun ping static __maybe_unused int px30_devfreq_init(struct udevice *dev) 777*16a92a42STang Yun ping { 778*16a92a42STang Yun ping struct arm_smccc_res res; 779*16a92a42STang Yun ping u32 size; 780*16a92a42STang Yun ping 781*16a92a42STang Yun ping res = sip_smc_dram(0, 0, 782*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); 783*16a92a42STang Yun ping printf("current ATF version 0x%lx!\n", res.a1); 784*16a92a42STang Yun ping if (res.a0 || res.a1 < 0x103) { 785*16a92a42STang Yun ping printf("trusted firmware need to update or is invalid!\n"); 786*16a92a42STang Yun ping return -ENXIO; 787*16a92a42STang Yun ping } 788*16a92a42STang Yun ping 789*16a92a42STang Yun ping printf("read tf version 0x%lx!\n", res.a1); 790*16a92a42STang Yun ping 791*16a92a42STang Yun ping /* 792*16a92a42STang Yun ping * first 4KB is used for interface parameters 793*16a92a42STang Yun ping * after 4KB * N is dts parameters 794*16a92a42STang Yun ping */ 795*16a92a42STang Yun ping size = sizeof(struct px30_ddr_dts_config_timing); 796*16a92a42STang Yun ping res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, 797*16a92a42STang Yun ping SHARE_PAGE_TYPE_DDR); 798*16a92a42STang Yun ping if (res.a0 != 0) { 799*16a92a42STang Yun ping printf("no ATF memory for init\n"); 800*16a92a42STang Yun ping return -ENOMEM; 801*16a92a42STang Yun ping } 802*16a92a42STang Yun ping 803*16a92a42STang Yun ping ddr_psci_param = (struct share_params *)res.a1; 804*16a92a42STang Yun ping of_get_px30_timings(dev, (uint32_t *)ddr_psci_param); 805*16a92a42STang Yun ping 806*16a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, 807*16a92a42STang Yun ping (DIV_ROUND_UP(size, 4096) + 1) * 0x1000); 808*16a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, 809*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_INIT); 810*16a92a42STang Yun ping if (res.a0) { 811*16a92a42STang Yun ping printf("rockchip_sip_config_dram_init error:%lx\n", 812*16a92a42STang Yun ping res.a0); 813*16a92a42STang Yun ping return -ENOMEM; 814*16a92a42STang Yun ping } 815*16a92a42STang Yun ping 816*16a92a42STang Yun ping return 0; 817*16a92a42STang Yun ping } 818*16a92a42STang Yun ping 819*16a92a42STang Yun ping int rockchip_ddrclk_sip_set_rate_v2(unsigned long drate) 820*16a92a42STang Yun ping { 821*16a92a42STang Yun ping struct share_params *p; 822*16a92a42STang Yun ping struct arm_smccc_res res; 823*16a92a42STang Yun ping 824*16a92a42STang Yun ping p = ddr_psci_param; 825*16a92a42STang Yun ping 826*16a92a42STang Yun ping p->hz = drate; 827*16a92a42STang Yun ping p->lcdc_type = 0; 828*16a92a42STang Yun ping p->wait_flag1 = 0; 829*16a92a42STang Yun ping p->wait_flag0 = 0; 830*16a92a42STang Yun ping p->complt_hwirq = 105; 831*16a92a42STang Yun ping 832*16a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params)); 833*16a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, 834*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE); 835*16a92a42STang Yun ping 836*16a92a42STang Yun ping return res.a0; 837*16a92a42STang Yun ping } 838*16a92a42STang Yun ping 839*16a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_recalc_rate_v2(void) 840*16a92a42STang Yun ping { 841*16a92a42STang Yun ping struct arm_smccc_res res; 842*16a92a42STang Yun ping 843*16a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, 844*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE); 845*16a92a42STang Yun ping if (!res.a0) 846*16a92a42STang Yun ping return res.a1; 847*16a92a42STang Yun ping else 848*16a92a42STang Yun ping return 0; 849*16a92a42STang Yun ping } 850*16a92a42STang Yun ping 851*16a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_round_rate_v2(unsigned long rate) 852*16a92a42STang Yun ping { 853*16a92a42STang Yun ping struct share_params *p; 854*16a92a42STang Yun ping struct arm_smccc_res res; 855*16a92a42STang Yun ping 856*16a92a42STang Yun ping p = ddr_psci_param; 857*16a92a42STang Yun ping 858*16a92a42STang Yun ping p->hz = rate; 859*16a92a42STang Yun ping 860*16a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params)); 861*16a92a42STang Yun ping 862*16a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, 863*16a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE); 864*16a92a42STang Yun ping if (!res.a0) 865*16a92a42STang Yun ping return res.a1; 866*16a92a42STang Yun ping else 867*16a92a42STang Yun ping return 0; 868*16a92a42STang Yun ping } 869*16a92a42STang Yun ping 870*16a92a42STang Yun ping int rockchip_dmcfreq_probe(struct udevice *dev) 871*16a92a42STang Yun ping { 872*16a92a42STang Yun ping int ret; 873*16a92a42STang Yun ping 874*16a92a42STang Yun ping #if defined(CONFIG_ROCKCHIP_PX30) 875*16a92a42STang Yun ping ret = px30_devfreq_init(dev); 876*16a92a42STang Yun ping #elif defined(CONFIG_ROCKCHIP_RK3328) 877*16a92a42STang Yun ping ret = rk3328_devfreq_init(dev); 878*16a92a42STang Yun ping #else 879*16a92a42STang Yun ping ret = -1; 880*16a92a42STang Yun ping printf("Unsupported chip type\n"); 881*16a92a42STang Yun ping #endif 882*16a92a42STang Yun ping if (ret) 883*16a92a42STang Yun ping return ret; 884*16a92a42STang Yun ping 885*16a92a42STang Yun ping printf("dram freq:%ld Hz\n", rockchip_ddrclk_sip_recalc_rate_v2()); 886*16a92a42STang Yun ping 887*16a92a42STang Yun ping return 0; 888*16a92a42STang Yun ping } 889