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 #ifdef CONFIG_ARM64 149 mem.base = SDRAM_OFFSET(SZ_1M); 150 mem.size = SZ_1M; 151 #else 152 mem.size = 0; 153 #endif 154 return mem; 155 } 156 157 int param_parse_bootdev(char **devtype, char **devnum) 158 { 159 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 160 struct tag *t; 161 162 t = atags_get_tag(ATAG_BOOTDEV); 163 if (t) { 164 switch (t->u.bootdev.devtype) { 165 #ifdef CONFIG_DM_MMC 166 case BOOT_TYPE_EMMC: 167 *devtype = "mmc"; 168 *devnum = "0"; 169 break; 170 case BOOT_TYPE_SD0: 171 case BOOT_TYPE_SD1: 172 *devtype = "mmc"; 173 *devnum = "1"; 174 /* 175 * If preloader does not pass sdupdate value, we treat it 176 * as a unknown card and call the rkimgtest cmd to find 177 * out what it is. 178 * 179 * If preloader pass sdupdate value as an update card, 180 * we just set "sdfwupdate" to bootargs instead of 181 * calling rkimgtest cmd which consumes time. 182 */ 183 if (t->u.bootdev.sdupdate == SD_UNKNOWN_CARD) { 184 run_command("mmc dev 1", 0); 185 run_command("rkimgtest mmc 1", 0); 186 } else if (t->u.bootdev.sdupdate == SD_UPDATE_CARD) { 187 env_update("bootargs", "sdfwupdate"); 188 } 189 break; 190 #endif 191 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND) 192 case BOOT_TYPE_NAND: 193 *devtype = "rknand"; 194 *devnum = "0"; 195 break; 196 #endif 197 #ifdef CONFIG_RKSFC_NAND 198 case BOOT_TYPE_SPI_NAND: 199 *devtype = "spinand"; 200 *devnum = "0"; 201 break; 202 #endif 203 #ifdef CONFIG_RKSFC_NOR 204 case BOOT_TYPE_SPI_NOR: 205 *devtype = "spinor"; 206 *devnum = "1"; 207 break; 208 #endif 209 #ifdef CONFIG_DM_RAMDISK 210 case BOOT_TYPE_RAM: 211 *devtype = "ramdisk"; 212 *devnum = "0"; 213 break; 214 #endif 215 default: 216 printf("Unknown bootdev type: 0x%x\n", 217 t->u.bootdev.devtype); 218 return -EINVAL; 219 } 220 221 return 0; 222 } 223 #endif 224 225 return -ENOSYS; 226 } 227 #endif 228 229 struct memblock *param_parse_ddr_mem(int *out_count) 230 { 231 struct udevice *dev; 232 struct memblock *mem; 233 struct ram_info ram; 234 int i, ret, count; 235 236 /* 237 * Get memory region of DDR 238 * 239 * 1. New: atags info; 240 * 2. Leagcy: os register; 241 */ 242 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 243 struct tag *t; 244 245 t = atags_get_tag(ATAG_DDR_MEM); 246 if (t && t->u.ddr_mem.count) { 247 count = t->u.ddr_mem.count; 248 mem = calloc(count, sizeof(*mem)); 249 if (!mem) { 250 printf("Calloc ddr memory failed\n"); 251 return 0; 252 } 253 254 for (i = 0; i < count; i++) { 255 mem[i].base = t->u.ddr_mem.bank[i]; 256 mem[i].size = t->u.ddr_mem.bank[i + count]; 257 } 258 259 *out_count = count; 260 return mem; 261 } 262 #endif 263 264 /* Leagcy */ 265 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 266 if (ret) { 267 debug("DRAM init failed: %d\n", ret); 268 return NULL; 269 } 270 ret = ram_get_info(dev, &ram); 271 if (ret) { 272 debug("Cannot get DRAM size: %d\n", ret); 273 return NULL; 274 } 275 276 debug("SDRAM base=%lx, size=%lx\n", 277 (unsigned long)ram.base, (unsigned long)ram.size); 278 279 count = 1; 280 mem = calloc(1, sizeof(*mem)); 281 if (!mem) { 282 printf("Calloc ddr memory failed\n"); 283 return 0; 284 } 285 286 for (i = 0; i < count; i++) { 287 mem[i].base = CONFIG_SYS_SDRAM_BASE; 288 mem[i].size = ram.size; 289 } 290 291 *out_count = count; 292 return mem; 293 } 294