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 #define SDRAM_OFFSET(offset) (CONFIG_SYS_SDRAM_BASE + (offset)) 16 #define PARAM_DRAM_INFO_OFFSET (SZ_32M) 17 #define PARAM_OPTEE_INFO_OFFSET (SZ_32M + SZ_2M) 18 19 struct tos_param_t { 20 u32 version; 21 u32 checksum; 22 struct { 23 char name[8]; 24 s64 phy_addr; 25 u32 size; 26 u32 flags; 27 } tee_mem; 28 struct { 29 char name[8]; 30 s64 phy_addr; 31 u32 size; 32 u32 flags; 33 } drm_mem; 34 s64 reserve[8]; 35 }; 36 37 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len) 38 { 39 uint16_t i, checksum = 0; 40 41 for (i = 0; i < len; i++) { 42 if (i % 2) 43 checksum += buf[i] << 8; 44 else 45 checksum += buf[i]; 46 } 47 checksum = ~checksum; 48 49 return checksum; 50 } 51 52 struct memblock param_parse_atf_mem(void) 53 { 54 struct memblock mem; 55 56 mem.base = 0; 57 mem.size = 0; 58 59 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 60 struct tag *t = NULL; 61 62 /* 63 * Get memory region of ATF 64 * 65 * 1. New way: atags info; 66 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset; 67 */ 68 t = atags_get_tag(ATAG_ATF_MEM); 69 if (t && t->u.atf_mem.size) { 70 mem.base = t->u.atf_mem.phy_addr; 71 mem.size = t->u.atf_mem.size; 72 /* Sanity */ 73 if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) { 74 printf("%s: ATF reserved region is not within 0-1MB " 75 "offset(0x%08llx-0x%08llx)!\n", 76 __func__, (u64)mem.base, (u64)mem.base + mem.size); 77 return mem; 78 } 79 } 80 #endif 81 82 /* Legacy */ 83 if (!mem.size) { 84 if (IS_ENABLED(CONFIG_ARM64) || 85 IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) { 86 mem.base = SDRAM_OFFSET(0); 87 mem.size = SZ_1M; 88 } 89 } 90 91 debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size); 92 93 return mem; 94 } 95 96 struct memblock param_parse_optee_mem(void) 97 { 98 struct tos_param_t *tos_parameter; 99 struct memblock mem; 100 u32 checksum; 101 102 mem.base = 0; 103 mem.size = 0; 104 105 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 106 struct tag *t = NULL; 107 108 /* 109 * Get memory region of OP-TEE 110 * 111 * 1. New way: atags info; 112 * 2. Leagcy way: info in ddr 34M offset; 113 */ 114 t = atags_get_tag(ATAG_TOS_MEM); 115 if (t && (t->u.tos_mem.tee_mem.flags == 1)) { 116 mem.base = t->u.tos_mem.tee_mem.phy_addr; 117 mem.size = t->u.tos_mem.tee_mem.size; 118 } 119 #endif 120 121 /* Legacy */ 122 if (!mem.size) { 123 tos_parameter = 124 (struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET)); 125 checksum = 126 trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8, 127 sizeof(struct tos_param_t) - 8); 128 if ((checksum == tos_parameter->checksum) && 129 (tos_parameter->tee_mem.flags == 1)) { 130 mem.base = tos_parameter->tee_mem.phy_addr; 131 mem.size = tos_parameter->tee_mem.size; 132 } 133 } 134 135 if (mem.size) 136 gd->flags |= GD_FLG_BL32_ENABLED; 137 138 debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size); 139 140 return mem; 141 } 142 143 struct memblock param_parse_common_resv_mem(void) 144 { 145 struct memblock mem; 146 147 mem.base = SDRAM_OFFSET(SZ_1M); 148 mem.size = SZ_1M; 149 150 return mem; 151 } 152 153 int param_parse_bootdev(char **devtype, char **devnum) 154 { 155 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 156 struct tag *t; 157 158 t = atags_get_tag(ATAG_BOOTDEV); 159 if (t) { 160 switch (t->u.bootdev.devtype) { 161 case BOOT_TYPE_EMMC: 162 *devtype = "mmc"; 163 *devnum = "0"; 164 break; 165 case BOOT_TYPE_SD0: 166 case BOOT_TYPE_SD1: 167 *devtype = "mmc"; 168 *devnum = "1"; 169 break; 170 case BOOT_TYPE_NAND: 171 *devtype = "rknand"; 172 *devnum = "0"; 173 break; 174 case BOOT_TYPE_SPI_NAND: 175 *devtype = "spinand"; 176 *devnum = "0"; 177 break; 178 case BOOT_TYPE_SPI_NOR: 179 *devtype = "spinor"; 180 *devnum = "1"; 181 break; 182 case BOOT_TYPE_RAM: 183 *devtype = "ramdisk"; 184 *devnum = "0"; 185 break; 186 default: 187 printf("Unknown bootdev type: 0x%x\n", 188 t->u.bootdev.devtype); 189 return -EINVAL; 190 } 191 192 return 0; 193 } 194 #endif 195 196 return -ENOSYS; 197 } 198 199 struct memblock *param_parse_ddr_mem(int *out_count) 200 { 201 struct udevice *dev; 202 struct memblock *mem; 203 struct ram_info ram; 204 int i, ret, count; 205 206 /* 207 * Get memory region of DDR 208 * 209 * 1. New: atags info; 210 * 2. Leagcy: os register; 211 */ 212 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 213 struct tag *t; 214 215 t = atags_get_tag(ATAG_DDR_MEM); 216 if (t && t->u.ddr_mem.count) { 217 count = t->u.ddr_mem.count; 218 mem = calloc(count, sizeof(*mem)); 219 if (!mem) { 220 printf("Calloc ddr memory failed\n"); 221 return 0; 222 } 223 224 for (i = 0; i < count; i++) { 225 mem[i].base = t->u.ddr_mem.bank[i]; 226 mem[i].size = t->u.ddr_mem.bank[i + count]; 227 } 228 229 *out_count = count; 230 return mem; 231 } 232 #endif 233 234 /* Leagcy */ 235 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 236 if (ret) { 237 debug("DRAM init failed: %d\n", ret); 238 return NULL; 239 } 240 ret = ram_get_info(dev, &ram); 241 if (ret) { 242 debug("Cannot get DRAM size: %d\n", ret); 243 return NULL; 244 } 245 246 debug("SDRAM base=%lx, size=%lx\n", 247 (unsigned long)ram.base, (unsigned long)ram.size); 248 249 count = 1; 250 mem = calloc(1, sizeof(*mem)); 251 if (!mem) { 252 printf("Calloc ddr memory failed\n"); 253 return 0; 254 } 255 256 for (i = 0; i < count; i++) { 257 mem[i].base = CONFIG_SYS_SDRAM_BASE; 258 mem[i].size = ram.size; 259 } 260 261 *out_count = count; 262 return mem; 263 } 264