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