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