1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <ram.h> 9 #include <asm/io.h> 10 #include <asm/arch/rk_atags.h> 11 #include <asm/arch/param.h> 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 #if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD) 16 #define SDRAM_OFFSET(offset) (CONFIG_SYS_SDRAM_BASE + (offset)) 17 #define PARAM_DRAM_INFO_OFFSET (SZ_32M) 18 #define PARAM_OPTEE_INFO_OFFSET (SZ_32M + SZ_2M) 19 20 struct tos_param_t { 21 u32 version; 22 u32 checksum; 23 struct { 24 char name[8]; 25 s64 phy_addr; 26 u32 size; 27 u32 flags; 28 } tee_mem; 29 struct { 30 char name[8]; 31 s64 phy_addr; 32 u32 size; 33 u32 flags; 34 } drm_mem; 35 s64 reserve[8]; 36 }; 37 38 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len) 39 { 40 uint16_t i, checksum = 0; 41 42 for (i = 0; i < len; i++) { 43 if (i % 2) 44 checksum += buf[i] << 8; 45 else 46 checksum += buf[i]; 47 } 48 checksum = ~checksum; 49 50 return checksum; 51 } 52 53 struct memblock param_parse_atf_mem(void) 54 { 55 struct memblock mem; 56 57 mem.base = 0; 58 mem.size = 0; 59 60 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 61 struct tag *t = NULL; 62 63 /* 64 * Get memory region of ATF 65 * 66 * 1. New way: atags info; 67 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset; 68 */ 69 t = atags_get_tag(ATAG_ATF_MEM); 70 if (t && t->u.atf_mem.size) { 71 mem.base = t->u.atf_mem.phy_addr; 72 mem.size = t->u.atf_mem.size; 73 /* Sanity */ 74 if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) { 75 printf("%s: ATF reserved region is not within 0-1MB " 76 "offset(0x%08llx-0x%08llx)!\n", 77 __func__, (u64)mem.base, (u64)mem.base + mem.size); 78 return mem; 79 } 80 } 81 #endif 82 83 /* Legacy */ 84 if (!mem.size) { 85 if (IS_ENABLED(CONFIG_ARM64) || 86 IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) { 87 mem.base = SDRAM_OFFSET(0); 88 mem.size = SZ_1M; 89 } 90 } 91 92 debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size); 93 94 return mem; 95 } 96 97 struct memblock param_parse_optee_mem(void) 98 { 99 struct tos_param_t *tos_parameter; 100 struct memblock mem; 101 u32 checksum; 102 103 mem.base = 0; 104 mem.size = 0; 105 106 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 107 struct tag *t = NULL; 108 109 /* 110 * Get memory region of OP-TEE 111 * 112 * 1. New way: atags info; 113 * 2. Leagcy way: info in ddr 34M offset; 114 */ 115 t = atags_get_tag(ATAG_TOS_MEM); 116 if (t && (t->u.tos_mem.tee_mem.flags == 1)) { 117 mem.base = t->u.tos_mem.tee_mem.phy_addr; 118 mem.size = t->u.tos_mem.tee_mem.size; 119 } 120 #endif 121 122 /* Legacy */ 123 if (!mem.size) { 124 tos_parameter = 125 (struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET)); 126 checksum = 127 trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8, 128 sizeof(struct tos_param_t) - 8); 129 if ((checksum == tos_parameter->checksum) && 130 (tos_parameter->tee_mem.flags == 1)) { 131 mem.base = tos_parameter->tee_mem.phy_addr; 132 mem.size = tos_parameter->tee_mem.size; 133 } 134 } 135 136 if (mem.size) 137 gd->flags |= GD_FLG_BL32_ENABLED; 138 139 debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size); 140 141 return mem; 142 } 143 144 struct memblock param_parse_common_resv_mem(void) 145 { 146 struct memblock mem; 147 148 #if defined(CONFIG_ARM64) 149 mem.base = SDRAM_OFFSET(SZ_1M); 150 mem.size = SZ_1M; 151 /* 152 * The ARMv8 platform enabling AArch32 mode should reserve memory the same 153 * as AArch64 mode(because there is no difference about ATF), only some 154 * platform has special request, they are: RK3308. 155 */ 156 #elif defined(CONFIG_ARM64_BOOT_AARCH32) && !defined(CONFIG_ROCKCHIP_RK3308) 157 mem.base = SDRAM_OFFSET(SZ_1M); 158 mem.size = SZ_1M; 159 #else 160 mem.size = 0; 161 #endif 162 return mem; 163 } 164 165 int param_parse_bootdev(char **devtype, char **devnum) 166 { 167 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 168 struct tag *t; 169 170 t = atags_get_tag(ATAG_BOOTDEV); 171 if (t) { 172 switch (t->u.bootdev.devtype) { 173 #ifdef CONFIG_DM_MMC 174 case BOOT_TYPE_EMMC: 175 *devtype = "mmc"; 176 *devnum = "0"; 177 break; 178 case BOOT_TYPE_SD0: 179 case BOOT_TYPE_SD1: 180 *devtype = "mmc"; 181 *devnum = "1"; 182 /* 183 * If preloader does not pass sdupdate value, we treat it 184 * as a unknown card and call the rkimgtest cmd to find 185 * out what it is. 186 * 187 * If preloader pass sdupdate value as an update card, 188 * we just set "sdfwupdate" to bootargs instead of 189 * calling rkimgtest cmd which consumes time. 190 */ 191 if (t->u.bootdev.sdupdate == SD_UNKNOWN_CARD) { 192 run_command("mmc dev 1", 0); 193 run_command("rkimgtest mmc 1", 0); 194 } else if (t->u.bootdev.sdupdate == SD_UPDATE_CARD) { 195 env_update("bootargs", "sdfwupdate"); 196 } 197 break; 198 #endif 199 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND) 200 case BOOT_TYPE_NAND: 201 *devtype = "rknand"; 202 *devnum = "0"; 203 break; 204 #endif 205 #ifdef CONFIG_RKSFC_NAND 206 case BOOT_TYPE_SPI_NAND: 207 *devtype = "spinand"; 208 *devnum = "0"; 209 break; 210 #endif 211 #ifdef CONFIG_RKSFC_NOR 212 case BOOT_TYPE_SPI_NOR: 213 *devtype = "spinor"; 214 *devnum = "1"; 215 break; 216 #endif 217 #ifdef CONFIG_DM_RAMDISK 218 case BOOT_TYPE_RAM: 219 *devtype = "ramdisk"; 220 *devnum = "0"; 221 break; 222 #endif 223 default: 224 printf("Unknown bootdev type: 0x%x\n", 225 t->u.bootdev.devtype); 226 return -EINVAL; 227 } 228 229 return 0; 230 } 231 #endif 232 233 return -ENOSYS; 234 } 235 #endif 236 237 static phys_size_t ddr_mem_get_usable_size(u64 base, u64 size) 238 { 239 return (base + size >= CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE) ? 240 (CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE - base) : size; 241 } 242 243 struct memblock *param_parse_ddr_mem(int *out_count) 244 { 245 struct udevice *dev; 246 struct memblock *mem; 247 struct ram_info ram; 248 int i, ret, count; 249 250 /* 251 * Get memory region of DDR 252 * 253 * 1. New: atags info; 254 * 2. Leagcy: os register; 255 */ 256 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 257 struct tag *t; 258 259 t = atags_get_tag(ATAG_DDR_MEM); 260 if (t && t->u.ddr_mem.count) { 261 count = t->u.ddr_mem.count; 262 mem = calloc(count, sizeof(*mem)); 263 if (!mem) { 264 printf("Calloc ddr memory failed\n"); 265 return 0; 266 } 267 268 for (i = 0; i < count; i++) { 269 mem[i].base = t->u.ddr_mem.bank[i]; 270 mem[i].size = 271 ddr_mem_get_usable_size(t->u.ddr_mem.bank[i], 272 t->u.ddr_mem.bank[i + count]); 273 } 274 275 *out_count = count; 276 return mem; 277 } 278 #endif 279 280 /* Leagcy */ 281 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 282 if (ret) { 283 debug("DRAM init failed: %d\n", ret); 284 return NULL; 285 } 286 ret = ram_get_info(dev, &ram); 287 if (ret) { 288 debug("Cannot get DRAM size: %d\n", ret); 289 return NULL; 290 } 291 292 debug("SDRAM base=%lx, size=%lx\n", 293 (unsigned long)ram.base, (unsigned long)ram.size); 294 295 count = 1; 296 mem = calloc(1, sizeof(*mem)); 297 if (!mem) { 298 printf("Calloc ddr memory failed\n"); 299 return 0; 300 } 301 302 for (i = 0; i < count; i++) { 303 mem[i].base = CONFIG_SYS_SDRAM_BASE; 304 mem[i].size = ddr_mem_get_usable_size(mem[i].base, ram.size); 305 } 306 307 *out_count = count; 308 return mem; 309 } 310