xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision dbf8423e3707ad742e7c65cc402e8a6c8972a9df)
1*dbf8423eSJoseph Chen // SPDX-License-Identifier: GPL-2.0
2*dbf8423eSJoseph Chen /*
3*dbf8423eSJoseph Chen  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4*dbf8423eSJoseph Chen  */
5*dbf8423eSJoseph Chen 
6*dbf8423eSJoseph Chen #include <common.h>
7*dbf8423eSJoseph Chen #include <asm/io.h>
8*dbf8423eSJoseph Chen #include <asm/arch/rk_atags.h>
9*dbf8423eSJoseph Chen #include <asm/arch/param.h>
10*dbf8423eSJoseph Chen 
11*dbf8423eSJoseph Chen DECLARE_GLOBAL_DATA_PTR;
12*dbf8423eSJoseph Chen 
13*dbf8423eSJoseph Chen #define SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
14*dbf8423eSJoseph Chen #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
15*dbf8423eSJoseph Chen #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
16*dbf8423eSJoseph Chen 
17*dbf8423eSJoseph Chen struct tos_param_t {
18*dbf8423eSJoseph Chen 	u32 version;
19*dbf8423eSJoseph Chen 	u32 checksum;
20*dbf8423eSJoseph Chen 	struct {
21*dbf8423eSJoseph Chen 		char name[8];
22*dbf8423eSJoseph Chen 		s64 phy_addr;
23*dbf8423eSJoseph Chen 		u32 size;
24*dbf8423eSJoseph Chen 		u32 flags;
25*dbf8423eSJoseph Chen 	} tee_mem;
26*dbf8423eSJoseph Chen 	struct {
27*dbf8423eSJoseph Chen 		char name[8];
28*dbf8423eSJoseph Chen 		s64 phy_addr;
29*dbf8423eSJoseph Chen 		u32 size;
30*dbf8423eSJoseph Chen 		u32 flags;
31*dbf8423eSJoseph Chen 	} drm_mem;
32*dbf8423eSJoseph Chen 	s64 reserve[8];
33*dbf8423eSJoseph Chen };
34*dbf8423eSJoseph Chen 
35*dbf8423eSJoseph Chen static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
36*dbf8423eSJoseph Chen {
37*dbf8423eSJoseph Chen 	uint16_t i, checksum = 0;
38*dbf8423eSJoseph Chen 
39*dbf8423eSJoseph Chen 	for (i = 0; i < len; i++) {
40*dbf8423eSJoseph Chen 		if (i % 2)
41*dbf8423eSJoseph Chen 			checksum += buf[i] << 8;
42*dbf8423eSJoseph Chen 		else
43*dbf8423eSJoseph Chen 			checksum += buf[i];
44*dbf8423eSJoseph Chen 	}
45*dbf8423eSJoseph Chen 	checksum = ~checksum;
46*dbf8423eSJoseph Chen 
47*dbf8423eSJoseph Chen 	return checksum;
48*dbf8423eSJoseph Chen }
49*dbf8423eSJoseph Chen 
50*dbf8423eSJoseph Chen struct sysmem_property param_parse_atf_mem(void)
51*dbf8423eSJoseph Chen {
52*dbf8423eSJoseph Chen 	struct sysmem_property prop;
53*dbf8423eSJoseph Chen 
54*dbf8423eSJoseph Chen 	prop.name = "ATF";
55*dbf8423eSJoseph Chen 	prop.base = 0;
56*dbf8423eSJoseph Chen 	prop.size = 0;
57*dbf8423eSJoseph Chen 
58*dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
59*dbf8423eSJoseph Chen 	struct tag *t = NULL;
60*dbf8423eSJoseph Chen 
61*dbf8423eSJoseph Chen 	/*
62*dbf8423eSJoseph Chen 	 * Get memory region of ATF
63*dbf8423eSJoseph Chen 	 *
64*dbf8423eSJoseph Chen 	 * 1. New way: atags info;
65*dbf8423eSJoseph Chen 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
66*dbf8423eSJoseph Chen 	 */
67*dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_ATF_MEM);
68*dbf8423eSJoseph Chen 	if (t && t->u.atf_mem.size) {
69*dbf8423eSJoseph Chen 		prop.base = t->u.atf_mem.phy_addr;
70*dbf8423eSJoseph Chen 		prop.size = t->u.atf_mem.size;
71*dbf8423eSJoseph Chen 		/* Sanity */
72*dbf8423eSJoseph Chen 		if (prop.base + prop.size > SDRAM_OFFSET(SZ_1M)) {
73*dbf8423eSJoseph Chen 			printf("%s: ATF reserved region is not within 0-1MB "
74*dbf8423eSJoseph Chen 			       "offset(0x%08llx-0x%08llx)!\n",
75*dbf8423eSJoseph Chen 			       __func__, (u64)prop.base, (u64)prop.base + prop.size);
76*dbf8423eSJoseph Chen 			return prop;
77*dbf8423eSJoseph Chen 		}
78*dbf8423eSJoseph Chen 	}
79*dbf8423eSJoseph Chen #endif
80*dbf8423eSJoseph Chen 
81*dbf8423eSJoseph Chen 	/* Legacy */
82*dbf8423eSJoseph Chen 	if (!prop.size) {
83*dbf8423eSJoseph Chen 		if (IS_ENABLED(CONFIG_ARM64) ||
84*dbf8423eSJoseph Chen 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
85*dbf8423eSJoseph Chen 			prop.base = SDRAM_OFFSET(0);
86*dbf8423eSJoseph Chen 			prop.size = SZ_1M;
87*dbf8423eSJoseph Chen 		}
88*dbf8423eSJoseph Chen 	}
89*dbf8423eSJoseph Chen 
90*dbf8423eSJoseph Chen 	debug("ATF: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size);
91*dbf8423eSJoseph Chen 
92*dbf8423eSJoseph Chen 	return prop;
93*dbf8423eSJoseph Chen }
94*dbf8423eSJoseph Chen 
95*dbf8423eSJoseph Chen struct sysmem_property param_parse_optee_mem(void)
96*dbf8423eSJoseph Chen {
97*dbf8423eSJoseph Chen 	struct tos_param_t *tos_parameter;
98*dbf8423eSJoseph Chen 	struct sysmem_property prop;
99*dbf8423eSJoseph Chen 	u32 checksum;
100*dbf8423eSJoseph Chen 
101*dbf8423eSJoseph Chen 	prop.name = "OP-TEE";
102*dbf8423eSJoseph Chen 	prop.base = 0;
103*dbf8423eSJoseph Chen 	prop.size = 0;
104*dbf8423eSJoseph Chen 
105*dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
106*dbf8423eSJoseph Chen 	struct tag *t = NULL;
107*dbf8423eSJoseph Chen 
108*dbf8423eSJoseph Chen 	/*
109*dbf8423eSJoseph Chen 	 * Get memory region of OP-TEE
110*dbf8423eSJoseph Chen 	 *
111*dbf8423eSJoseph Chen 	 * 1. New way: atags info;
112*dbf8423eSJoseph Chen 	 * 2. Leagcy way: info in ddr 34M offset;
113*dbf8423eSJoseph Chen 	 */
114*dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_TOS_MEM);
115*dbf8423eSJoseph Chen 	if (t && (t->u.tos_mem.tee_mem.flags == 1)) {
116*dbf8423eSJoseph Chen 		prop.base = t->u.tos_mem.tee_mem.phy_addr;
117*dbf8423eSJoseph Chen 		prop.size = t->u.tos_mem.tee_mem.size;
118*dbf8423eSJoseph Chen 	}
119*dbf8423eSJoseph Chen #endif
120*dbf8423eSJoseph Chen 
121*dbf8423eSJoseph Chen 	/* Legacy */
122*dbf8423eSJoseph Chen 	if (!prop.size) {
123*dbf8423eSJoseph Chen 		tos_parameter =
124*dbf8423eSJoseph Chen 		(struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET));
125*dbf8423eSJoseph Chen 		checksum =
126*dbf8423eSJoseph Chen 		trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8,
127*dbf8423eSJoseph Chen 			       sizeof(struct tos_param_t) - 8);
128*dbf8423eSJoseph Chen 		if ((checksum == tos_parameter->checksum) &&
129*dbf8423eSJoseph Chen 		    (tos_parameter->tee_mem.flags == 1)) {
130*dbf8423eSJoseph Chen 			prop.base = tos_parameter->tee_mem.phy_addr;
131*dbf8423eSJoseph Chen 			prop.size = tos_parameter->tee_mem.size;
132*dbf8423eSJoseph Chen 			gd->flags |= GD_FLG_BL32_ENABLED;
133*dbf8423eSJoseph Chen 		}
134*dbf8423eSJoseph Chen 	}
135*dbf8423eSJoseph Chen 
136*dbf8423eSJoseph Chen 	debug("TOS: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size);
137*dbf8423eSJoseph Chen 
138*dbf8423eSJoseph Chen 	return prop;
139*dbf8423eSJoseph Chen }
140*dbf8423eSJoseph Chen 
141*dbf8423eSJoseph Chen struct sysmem_property param_parse_common_resv_mem(void)
142*dbf8423eSJoseph Chen {
143*dbf8423eSJoseph Chen 	struct sysmem_property prop;
144*dbf8423eSJoseph Chen 
145*dbf8423eSJoseph Chen 	prop.name = "PSTORE/ATAGS/SHM";
146*dbf8423eSJoseph Chen 	prop.base = SDRAM_OFFSET(SZ_1M);
147*dbf8423eSJoseph Chen 	prop.size = SZ_1M;
148*dbf8423eSJoseph Chen 
149*dbf8423eSJoseph Chen 	return prop;
150*dbf8423eSJoseph Chen }
151*dbf8423eSJoseph Chen 
152*dbf8423eSJoseph Chen int param_parse_bootdev(char **devtype, char **devnum)
153*dbf8423eSJoseph Chen {
154*dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
155*dbf8423eSJoseph Chen 	struct tag *t;
156*dbf8423eSJoseph Chen 
157*dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_BOOTDEV);
158*dbf8423eSJoseph Chen 	if (t) {
159*dbf8423eSJoseph Chen 		switch (t->u.bootdev.devtype) {
160*dbf8423eSJoseph Chen 		case BOOT_TYPE_EMMC:
161*dbf8423eSJoseph Chen 			*devtype = "mmc";
162*dbf8423eSJoseph Chen 			*devnum = "0";
163*dbf8423eSJoseph Chen 			break;
164*dbf8423eSJoseph Chen 		case BOOT_TYPE_SD0:
165*dbf8423eSJoseph Chen 		case BOOT_TYPE_SD1:
166*dbf8423eSJoseph Chen 			*devtype = "mmc";
167*dbf8423eSJoseph Chen 			*devnum = "1";
168*dbf8423eSJoseph Chen 			break;
169*dbf8423eSJoseph Chen 		case BOOT_TYPE_NAND:
170*dbf8423eSJoseph Chen 			*devtype = "rknand";
171*dbf8423eSJoseph Chen 			*devnum = "0";
172*dbf8423eSJoseph Chen 			break;
173*dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NAND:
174*dbf8423eSJoseph Chen 			*devtype = "spinand";
175*dbf8423eSJoseph Chen 			*devnum = "0";
176*dbf8423eSJoseph Chen 			break;
177*dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NOR:
178*dbf8423eSJoseph Chen 			*devtype = "spinor";
179*dbf8423eSJoseph Chen 			*devnum = "1";
180*dbf8423eSJoseph Chen 			break;
181*dbf8423eSJoseph Chen 		case BOOT_TYPE_RAM:
182*dbf8423eSJoseph Chen 			*devtype = "ramdisk";
183*dbf8423eSJoseph Chen 			*devnum = "0";
184*dbf8423eSJoseph Chen 			break;
185*dbf8423eSJoseph Chen 		default:
186*dbf8423eSJoseph Chen 			printf("Unknown bootdev type: 0x%x\n",
187*dbf8423eSJoseph Chen 			       t->u.bootdev.devtype);
188*dbf8423eSJoseph Chen 			return -EINVAL;
189*dbf8423eSJoseph Chen 		}
190*dbf8423eSJoseph Chen 
191*dbf8423eSJoseph Chen 		return 0;
192*dbf8423eSJoseph Chen 	}
193*dbf8423eSJoseph Chen #endif
194*dbf8423eSJoseph Chen 
195*dbf8423eSJoseph Chen 	return -ENOSYS;
196*dbf8423eSJoseph Chen }
197