xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision 3befe43d907ef2b615f68ddeb032ba74e0375df1)
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 <asm/io.h>
8 #include <asm/arch/rk_atags.h>
9 #include <asm/arch/param.h>
10 
11 DECLARE_GLOBAL_DATA_PTR;
12 
13 #define SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
14 #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
15 #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
16 
17 struct tos_param_t {
18 	u32 version;
19 	u32 checksum;
20 	struct {
21 		char name[8];
22 		s64 phy_addr;
23 		u32 size;
24 		u32 flags;
25 	} tee_mem;
26 	struct {
27 		char name[8];
28 		s64 phy_addr;
29 		u32 size;
30 		u32 flags;
31 	} drm_mem;
32 	s64 reserve[8];
33 };
34 
35 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
36 {
37 	uint16_t i, checksum = 0;
38 
39 	for (i = 0; i < len; i++) {
40 		if (i % 2)
41 			checksum += buf[i] << 8;
42 		else
43 			checksum += buf[i];
44 	}
45 	checksum = ~checksum;
46 
47 	return checksum;
48 }
49 
50 struct sysmem_property param_parse_atf_mem(void)
51 {
52 	struct sysmem_property prop;
53 
54 	prop.name = "ATF";
55 	prop.base = 0;
56 	prop.size = 0;
57 
58 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
59 	struct tag *t = NULL;
60 
61 	/*
62 	 * Get memory region of ATF
63 	 *
64 	 * 1. New way: atags info;
65 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
66 	 */
67 	t = atags_get_tag(ATAG_ATF_MEM);
68 	if (t && t->u.atf_mem.size) {
69 		prop.base = t->u.atf_mem.phy_addr;
70 		prop.size = t->u.atf_mem.size;
71 		/* Sanity */
72 		if (prop.base + prop.size > SDRAM_OFFSET(SZ_1M)) {
73 			printf("%s: ATF reserved region is not within 0-1MB "
74 			       "offset(0x%08llx-0x%08llx)!\n",
75 			       __func__, (u64)prop.base, (u64)prop.base + prop.size);
76 			return prop;
77 		}
78 	}
79 #endif
80 
81 	/* Legacy */
82 	if (!prop.size) {
83 		if (IS_ENABLED(CONFIG_ARM64) ||
84 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
85 			prop.base = SDRAM_OFFSET(0);
86 			prop.size = SZ_1M;
87 		}
88 	}
89 
90 	debug("ATF: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size);
91 
92 	return prop;
93 }
94 
95 struct sysmem_property param_parse_optee_mem(void)
96 {
97 	struct tos_param_t *tos_parameter;
98 	struct sysmem_property prop;
99 	u32 checksum;
100 
101 	prop.name = "OP-TEE";
102 	prop.base = 0;
103 	prop.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 		prop.base = t->u.tos_mem.tee_mem.phy_addr;
117 		prop.size = t->u.tos_mem.tee_mem.size;
118 	}
119 #endif
120 
121 	/* Legacy */
122 	if (!prop.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 			prop.base = tos_parameter->tee_mem.phy_addr;
131 			prop.size = tos_parameter->tee_mem.size;
132 		}
133 	}
134 
135 	if (prop.size)
136 		gd->flags |= GD_FLG_BL32_ENABLED;
137 
138 	debug("TOS: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size);
139 
140 	return prop;
141 }
142 
143 struct sysmem_property param_parse_common_resv_mem(void)
144 {
145 	struct sysmem_property prop;
146 
147 	prop.name = "PSTORE/ATAGS/SHM";
148 	prop.base = SDRAM_OFFSET(SZ_1M);
149 	prop.size = SZ_1M;
150 
151 	return prop;
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