blob: d77e075864d72e8b88831cfca75a315d335afcaf [file] [log] [blame]
Patrick Delaunaydaa5f012020-03-18 09:22:44 +01001// 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 */
19DECLARE_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 */
29static 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 */
42static 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
72void 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}