1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <common.h>
7 #include <dfu.h>
8 #include <dm.h>
9 #include <env.h>
10 #include <env_internal.h>
11 #include <log.h>
12 #include <mtd.h>
13 #include <mtd_node.h>
14 #include <tee.h>
15 #include <asm/arch/stm32prog.h>
16 #include <asm/arch/sys_proto.h>
17 #include <asm/global_data.h>
18 
19 #define MTDPARTS_LEN		256
20 #define MTDIDS_LEN		128
21 
22 /*
23  * Get a global data pointer
24  */
25 DECLARE_GLOBAL_DATA_PTR;
26 
27 /**
28  * update the variables "mtdids" and "mtdparts" with boot, tee and user strings
29  */
board_set_mtdparts(const char * dev,char * mtdids,char * mtdparts,const char * boot,const char * tee,const char * user)30 static void board_set_mtdparts(const char *dev,
31 			       char *mtdids,
32 			       char *mtdparts,
33 			       const char *boot,
34 			       const char *tee,
35 			       const char *user)
36 {
37 	/* mtdids: "<dev>=<dev>, ...." */
38 	if (mtdids[0] != '\0')
39 		strcat(mtdids, ",");
40 	strcat(mtdids, dev);
41 	strcat(mtdids, "=");
42 	strcat(mtdids, dev);
43 
44 	/* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */
45 	if (mtdparts[0] != '\0')
46 		strncat(mtdparts, ";", MTDPARTS_LEN);
47 	else
48 		strcat(mtdparts, "mtdparts=");
49 
50 	strncat(mtdparts, dev, MTDPARTS_LEN);
51 	strncat(mtdparts, ":", MTDPARTS_LEN);
52 
53 	if (boot) {
54 		strncat(mtdparts, boot, MTDPARTS_LEN);
55 		strncat(mtdparts, ",", MTDPARTS_LEN);
56 	}
57 
58 	if (tee) {
59 		strncat(mtdparts, tee, MTDPARTS_LEN);
60 		strncat(mtdparts, ",", MTDPARTS_LEN);
61 	}
62 
63 	strncat(mtdparts, user, MTDPARTS_LEN);
64 }
65 
board_mtdparts_default(const char ** mtdids,const char ** mtdparts)66 void board_mtdparts_default(const char **mtdids, const char **mtdparts)
67 {
68 	struct mtd_info *mtd;
69 	struct udevice *dev;
70 	static char parts[3 * MTDPARTS_LEN + 1];
71 	static char ids[MTDIDS_LEN + 1];
72 	static bool mtd_initialized;
73 	bool tee, nor, nand, spinand, serial;
74 
75 	if (mtd_initialized) {
76 		*mtdids = ids;
77 		*mtdparts = parts;
78 		return;
79 	}
80 
81 	tee = false;
82 	nor = false;
83 	nand = false;
84 	spinand = false;
85 	serial = false;
86 
87 	switch (get_bootmode() & TAMP_BOOT_DEVICE_MASK) {
88 	case BOOT_SERIAL_UART:
89 	case BOOT_SERIAL_USB:
90 		serial = true;
91 		if (CONFIG_IS_ENABLED(CMD_STM32PROG)) {
92 			tee = stm32prog_get_tee_partitions();
93 			nor = stm32prog_get_fsbl_nor();
94 		}
95 		nand = true;
96 		spinand = true;
97 		break;
98 	case BOOT_FLASH_NAND:
99 		nand = true;
100 		break;
101 	case BOOT_FLASH_SPINAND:
102 		spinand = true;
103 		break;
104 	case BOOT_FLASH_NOR:
105 		nor = true;
106 		break;
107 	default:
108 		break;
109 	}
110 
111 	if (!serial && CONFIG_IS_ENABLED(OPTEE) &&
112 	    tee_find_device(NULL, NULL, NULL, NULL))
113 		tee = true;
114 
115 	memset(parts, 0, sizeof(parts));
116 	memset(ids, 0, sizeof(ids));
117 
118 	/* probe all MTD devices */
119 	for (uclass_first_device(UCLASS_MTD, &dev);
120 	     dev;
121 	     uclass_next_device(&dev)) {
122 		log_debug("mtd device = %s\n", dev->name);
123 	}
124 
125 	if (nand) {
126 		mtd = get_mtd_device_nm("nand0");
127 		if (!IS_ERR_OR_NULL(mtd)) {
128 			const char *mtd_tee = CONFIG_MTDPARTS_NAND0_TEE;
129 			board_set_mtdparts("nand0", ids, parts,
130 					   CONFIG_MTDPARTS_NAND0_BOOT,
131 					   !nor && tee ? mtd_tee : NULL,
132 					   "-(UBI)");
133 			put_mtd_device(mtd);
134 		}
135 	}
136 
137 	if (spinand) {
138 		mtd = get_mtd_device_nm("spi-nand0");
139 		if (!IS_ERR_OR_NULL(mtd)) {
140 			const char *mtd_tee = CONFIG_MTDPARTS_SPINAND0_TEE;
141 			board_set_mtdparts("spi-nand0", ids, parts,
142 					   CONFIG_MTDPARTS_SPINAND0_BOOT,
143 					   !nor && tee ? mtd_tee : NULL,
144 					   "-(UBI)");
145 			put_mtd_device(mtd);
146 		}
147 	}
148 
149 	if (nor) {
150 		if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) {
151 			const char *mtd_tee = CONFIG_MTDPARTS_NOR0_TEE;
152 			board_set_mtdparts("nor0", ids, parts,
153 					   CONFIG_MTDPARTS_NOR0_BOOT,
154 					   tee ? mtd_tee : NULL,
155 					   "-(nor_user)");
156 		}
157 	}
158 
159 	mtd_initialized = true;
160 	*mtdids = ids;
161 	*mtdparts = parts;
162 	log_debug("mtdids=%s & mtdparts=%s\n", ids, parts);
163 }
164