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 case BOOT_TYPE_EMMC: 166 *devtype = "mmc"; 167 *devnum = "0"; 168 break; 169 case BOOT_TYPE_SD0: 170 case BOOT_TYPE_SD1: 171 *devtype = "mmc"; 172 *devnum = "1"; 173 break; 174 case BOOT_TYPE_NAND: 175 *devtype = "rknand"; 176 *devnum = "0"; 177 break; 178 case BOOT_TYPE_SPI_NAND: 179 *devtype = "spinand"; 180 *devnum = "0"; 181 break; 182 case BOOT_TYPE_SPI_NOR: 183 *devtype = "spinor"; 184 *devnum = "1"; 185 break; 186 case BOOT_TYPE_RAM: 187 *devtype = "ramdisk"; 188 *devnum = "0"; 189 break; 190 default: 191 printf("Unknown bootdev type: 0x%x\n", 192 t->u.bootdev.devtype); 193 return -EINVAL; 194 } 195 196 return 0; 197 } 198 #endif 199 200 return -ENOSYS; 201 } 202 #endif 203 204 struct memblock *param_parse_ddr_mem(int *out_count) 205 { 206 struct udevice *dev; 207 struct memblock *mem; 208 struct ram_info ram; 209 int i, ret, count; 210 211 /* 212 * Get memory region of DDR 213 * 214 * 1. New: atags info; 215 * 2. Leagcy: os register; 216 */ 217 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 218 struct tag *t; 219 220 t = atags_get_tag(ATAG_DDR_MEM); 221 if (t && t->u.ddr_mem.count) { 222 count = t->u.ddr_mem.count; 223 mem = calloc(count, sizeof(*mem)); 224 if (!mem) { 225 printf("Calloc ddr memory failed\n"); 226 return 0; 227 } 228 229 for (i = 0; i < count; i++) { 230 mem[i].base = t->u.ddr_mem.bank[i]; 231 mem[i].size = t->u.ddr_mem.bank[i + count]; 232 } 233 234 *out_count = count; 235 return mem; 236 } 237 #endif 238 239 /* Leagcy */ 240 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 241 if (ret) { 242 debug("DRAM init failed: %d\n", ret); 243 return NULL; 244 } 245 ret = ram_get_info(dev, &ram); 246 if (ret) { 247 debug("Cannot get DRAM size: %d\n", ret); 248 return NULL; 249 } 250 251 debug("SDRAM base=%lx, size=%lx\n", 252 (unsigned long)ram.base, (unsigned long)ram.size); 253 254 count = 1; 255 mem = calloc(1, sizeof(*mem)); 256 if (!mem) { 257 printf("Calloc ddr memory failed\n"); 258 return 0; 259 } 260 261 for (i = 0; i < count; i++) { 262 mem[i].base = CONFIG_SYS_SDRAM_BASE; 263 mem[i].size = ram.size; 264 } 265 266 *out_count = count; 267 return mem; 268 } 269