board: stm32mp1: move board_get_mtdparts in st common directory
[oweals/u-boot.git] / board / st / common / stm32mp_mtdparts.c
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 <dm.h>
8 #include <env.h>
9 #include <env_internal.h>
10 #include <mtd.h>
11 #include <mtd_node.h>
12
13 #define MTDPARTS_LEN            256
14 #define MTDIDS_LEN              128
15
16 /*
17  * Get a global data pointer
18  */
19 DECLARE_GLOBAL_DATA_PTR;
20
21 /**
22  * The mtdparts_nand0 and mtdparts_nor0 variable tends to be long.
23  * If we need to access it before the env is relocated, then we need
24  * to use our own stack buffer. gd->env_buf will be too small.
25  *
26  * @param buf temporary buffer pointer MTDPARTS_LEN long
27  * @return mtdparts variable string, NULL if not found
28  */
29 static const char *env_get_mtdparts(const char *str, char *buf)
30 {
31         if (gd->flags & GD_FLG_ENV_READY)
32                 return env_get(str);
33         if (env_get_f(str, buf, MTDPARTS_LEN) != -1)
34                 return buf;
35
36         return NULL;
37 }
38
39 /**
40  * update the variables "mtdids" and "mtdparts" with content of mtdparts_<dev>
41  */
42 static void board_get_mtdparts(const char *dev,
43                                char *mtdids,
44                                char *mtdparts)
45 {
46         char env_name[32] = "mtdparts_";
47         char tmp_mtdparts[MTDPARTS_LEN];
48         const char *tmp;
49
50         /* name of env variable to read = mtdparts_<dev> */
51         strcat(env_name, dev);
52         tmp = env_get_mtdparts(env_name, tmp_mtdparts);
53         if (tmp) {
54                 /* mtdids: "<dev>=<dev>, ...." */
55                 if (mtdids[0] != '\0')
56                         strcat(mtdids, ",");
57                 strcat(mtdids, dev);
58                 strcat(mtdids, "=");
59                 strcat(mtdids, dev);
60
61                 /* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */
62                 if (mtdparts[0] != '\0')
63                         strncat(mtdparts, ";", MTDPARTS_LEN);
64                 else
65                         strcat(mtdparts, "mtdparts=");
66                 strncat(mtdparts, dev, MTDPARTS_LEN);
67                 strncat(mtdparts, ":", MTDPARTS_LEN);
68                 strncat(mtdparts, tmp, MTDPARTS_LEN);
69         }
70 }
71
72 void board_mtdparts_default(const char **mtdids, const char **mtdparts)
73 {
74         struct mtd_info *mtd;
75         struct udevice *dev;
76         static char parts[3 * MTDPARTS_LEN + 1];
77         static char ids[MTDIDS_LEN + 1];
78         static bool mtd_initialized;
79
80         if (mtd_initialized) {
81                 *mtdids = ids;
82                 *mtdparts = parts;
83                 return;
84         }
85
86         memset(parts, 0, sizeof(parts));
87         memset(ids, 0, sizeof(ids));
88
89         /* probe all MTD devices */
90         for (uclass_first_device(UCLASS_MTD, &dev);
91              dev;
92              uclass_next_device(&dev)) {
93                 pr_debug("mtd device = %s\n", dev->name);
94         }
95
96         mtd = get_mtd_device_nm("nand0");
97         if (!IS_ERR_OR_NULL(mtd)) {
98                 board_get_mtdparts("nand0", ids, parts);
99                 put_mtd_device(mtd);
100         }
101
102         mtd = get_mtd_device_nm("spi-nand0");
103         if (!IS_ERR_OR_NULL(mtd)) {
104                 board_get_mtdparts("spi-nand0", ids, parts);
105                 put_mtd_device(mtd);
106         }
107
108         if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev))
109                 board_get_mtdparts("nor0", ids, parts);
110
111         mtd_initialized = true;
112         *mtdids = ids;
113         *mtdparts = parts;
114         debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts);
115 }