1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2021 Rockchip Electronics Co., Ltd. 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <syscon.h> 9 #include <asm/io.h> 10 #include <dm/of_access.h> 11 #include <asm/arch/clock.h> 12 #include <asm/arch/rockchip_smccc.h> 13 #include <asm/arch/sdram.h> 14 #include <asm/arch/sdram_common.h> 15 16 #define DDR2_PARAMS_PHANDLE_NAME "ddr2_params" 17 #define DDR3_PARAMS_PHANDLE_NAME "ddr3_params" 18 #define DDR4_PARAMS_PHANDLE_NAME "ddr4_params" 19 #define LPDDR2_PARAMS_PHANDLE_NAME "lpddr2_params" 20 #define LPDDR3_PARAMS_PHANDLE_NAME "lpddr3_params" 21 #define LPDDR4_PARAMS_PHANDLE_NAME "lpddr4_params" 22 #define LPDDR4X_PARAMS_PHANDLE_NAME "lpddr4x_params" 23 #define LPDDR5_PARAMS_PHANDLE_NAME "lpddr5_params" 24 25 #define DTS_PAR_OFFSET (4096) 26 #define PARAMS_INVALID_VAL (0xff00aa99) 27 28 #define PMUGRF_OS_REG(n) (0x200 + (n) * 4) 29 30 /* there is a matching relationship, modify it with caution */ 31 static char *dmc_fsp_params[] = { 32 "debug_print_level", 33 /* if need, add parameter after */ 34 }; 35 36 /* there is a matching relationship, modify it with caution */ 37 static char *ddr_params_v1[] = { 38 /* version information V1.00 */ 39 "version", 40 "expanded_version", 41 "reserved", 42 /* freq info, freq_0 is final frequency, unit: MHz */ 43 "freq_0", 44 "freq_1", 45 "freq_2", 46 "freq_3", 47 "freq_4", 48 "freq_5", 49 /* power save setting */ 50 "pd_idle", 51 "sr_idle", 52 "sr_mc_gate_idle", 53 "srpd_lite_idle", 54 "standby_idle", 55 "pd_dis_freq", 56 "sr_dis_freq", 57 "dram_dll_dis_freq", 58 "phy_dll_dis_freq", 59 /* drv when odt on */ 60 "phy_dq_drv_odten", 61 "phy_ca_drv_odten", 62 "phy_clk_drv_odten", 63 "dram_dq_drv_odten", 64 /* drv when odt off */ 65 "phy_dq_drv_odtoff", 66 "phy_ca_drv_odtoff", 67 "phy_clk_drv_odtoff", 68 "dram_dq_drv_odtoff", 69 /* odt info */ 70 "dram_odt", 71 "phy_odt", 72 "phy_odt_puup_en", 73 "phy_odt_pudn_en", 74 /* odt enable freq */ 75 "dram_dq_odt_en_freq", 76 "phy_odt_en_freq", 77 /* slew rate when odt enable */ 78 "phy_dq_sr_odten", 79 "phy_ca_sr_odten", 80 "phy_clk_sr_odten", 81 /* slew rate when odt disable */ 82 "phy_dq_sr_odtoff", 83 "phy_ca_sr_odtoff", 84 "phy_clk_sr_odtoff", 85 /* ssmod setting*/ 86 "ssmod_downspread", 87 "ssmod_div", 88 "ssmod_spread", 89 /* 2T mode */ 90 "mode_2t", 91 /* speed bin */ 92 "speed_bin", 93 /* dram extended temperature support */ 94 "dram_ext_temp", 95 /* byte map */ 96 "byte_map", 97 /* dq map */ 98 "dq_map_cs0_dq_l", 99 "dq_map_cs0_dq_h", 100 "dq_map_cs1_dq_l", 101 "dq_map_cs1_dq_h", 102 /* for LPDDR4 and LPDDR4X */ 103 /* odt info */ 104 "lp4_ca_odt", 105 "lp4_drv_pu_cal_odten", 106 "lp4_drv_pu_cal_odtoff", 107 "phy_lp4_drv_pulldown_en_odten", 108 "phy_lp4_drv_pulldown_en_odtoff", 109 /* odt enable freq */ 110 "lp4_ca_odt_en_freq", 111 /* lp4 cs drv info and ca odt info */ 112 "phy_lp4_cs_drv_odten", 113 "phy_lp4_cs_drv_odtoff", 114 "lp4_odte_ck_en", 115 "lp4_odte_cs_en", 116 "lp4_odtd_ca_en", 117 /* lp4 vref info when odt enable */ 118 "phy_lp4_dq_vref_odten", 119 "lp4_dq_vref_odten", 120 "lp4_ca_vref_odten", 121 /* lp4 vref info when odt disable */ 122 "phy_lp4_dq_vref_odtoff", 123 "lp4_dq_vref_odtoff", 124 "lp4_ca_vref_odtoff", 125 /* if need, add parameter after and change the minor version. */ 126 }; 127 128 static int get_atf_version(void) 129 { 130 struct arm_smccc_res res; 131 132 res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); 133 134 if (res.a0) 135 return -ENOMEM; 136 else 137 return res.a1; 138 } 139 140 static int dmc_fsp_probe(struct udevice *dev) 141 { 142 struct device_node *np_params; 143 struct arm_smccc_res res; 144 void *pmugrf_base; 145 int *p = NULL; 146 char *phandle_name = NULL; 147 char **ddr_params; 148 int ddr_params_version; 149 u32 dram_type, os_reg2_val, os_reg3_val; 150 u32 i = 0, count = 0, size = 0; 151 ulong atf_version_limit; 152 153 atf_version_limit = dev_get_driver_data(dev); 154 if (get_atf_version() < atf_version_limit) { 155 printf("%s: trusted firmware need to update or is invalid!\n", __func__); 156 printf("%s: current ATF version 0x%x, required version 0x%lx\n", 157 __func__, get_atf_version(), atf_version_limit); 158 return 0; 159 } 160 161 pmugrf_base = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); 162 os_reg2_val = readl(pmugrf_base + PMUGRF_OS_REG(2)); 163 os_reg3_val = readl(pmugrf_base + PMUGRF_OS_REG(3)); 164 dram_type = SYS_REG_DEC_DDRTYPE_V3(os_reg2_val, os_reg3_val); 165 166 if (dram_type == DDR2) 167 phandle_name = DDR2_PARAMS_PHANDLE_NAME; 168 else if (dram_type == DDR3) 169 phandle_name = DDR3_PARAMS_PHANDLE_NAME; 170 else if (dram_type == DDR4) 171 phandle_name = DDR4_PARAMS_PHANDLE_NAME; 172 else if (dram_type == LPDDR2) 173 phandle_name = LPDDR2_PARAMS_PHANDLE_NAME; 174 else if (dram_type == LPDDR3) 175 phandle_name = LPDDR3_PARAMS_PHANDLE_NAME; 176 else if (dram_type == LPDDR4) 177 phandle_name = LPDDR4_PARAMS_PHANDLE_NAME; 178 else if (dram_type == LPDDR4X) 179 phandle_name = LPDDR4X_PARAMS_PHANDLE_NAME; 180 else if (dram_type == LPDDR5) 181 phandle_name = LPDDR5_PARAMS_PHANDLE_NAME; 182 else 183 printf("%s: dram_type unsupported\n", __func__); 184 185 np_params = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0); 186 if (!np_params) { 187 printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name); 188 return -EINVAL; 189 } 190 191 ddr_params_version = ofnode_read_u32_default(np_to_ofnode(np_params), "version", -1); 192 if (ddr_params_version < 0) { 193 printf("%s: get ddr_params_version error\n", __func__); 194 return -EINVAL; 195 } 196 197 if ((ddr_params_version & 0xff00) == 0x100 && 198 (ddr_params_version & 0xffff) <= 0x100) { 199 count = ARRAY_SIZE(ddr_params_v1); 200 ddr_params = ddr_params_v1; 201 } else { 202 printf("%s: ddr_params_version=0x%x unsupported\n", __func__, ddr_params_version); 203 return -EINVAL; 204 } 205 206 size = count * 4; 207 res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, SHARE_PAGE_TYPE_DDRFSP); 208 if (res.a0 != 0) { 209 printf("%s:no share memory for init\n", __func__); 210 return -ENOMEM; 211 } 212 213 /* fill share memory and pass to the atf */ 214 p = (int *)(res.a1); 215 for (i = 0; i < ARRAY_SIZE(dmc_fsp_params); i++) 216 p[i] = dev_read_u32_default(dev, dmc_fsp_params[i], PARAMS_INVALID_VAL); 217 218 p = (int *)(res.a1 + DTS_PAR_OFFSET / 4); 219 for (i = 0; i < count; i++) { 220 p[i] = ofnode_read_u32_default(np_to_ofnode(np_params), ddr_params[i], 221 PARAMS_INVALID_VAL); 222 } 223 224 flush_cache((unsigned long)(res.a1), (DIV_ROUND_UP(size, 4096) + 1) * 0x1000); 225 res = sip_smc_dram(SHARE_PAGE_TYPE_DDRFSP, 0, ROCKCHIP_SIP_CONFIG_DRAM_FSP_INIT); 226 if (res.a0) { 227 printf("%s: rockchip_sip_config_dram_fsp_init error:%lx\n", __func__, res.a0); 228 return -ENOMEM; 229 } 230 231 return 0; 232 } 233 234 static const struct udevice_id rockchip_dmc_fsp_ids[] = { 235 { .compatible = "rockchip,rk3568-dmc-fsp", .data = 0x102}, 236 { } 237 }; 238 239 U_BOOT_DRIVER(dmc_fsp) = { 240 .name = "rockchip_dmc_fsp", 241 .id = UCLASS_DMC, 242 .probe = dmc_fsp_probe, 243 .of_match = rockchip_dmc_fsp_ids, 244 }; 245