@@ -21,6 +21,15 @@ u-boot,efi-partition-entries-offset
This setting will override any values configured via Kconfig.
+u-boot,mmc-env-partition
+ if present, the environment shall be placed at the last
+ CONFIG_ENV_SIZE blocks of the partition on the
+ CONFIG_SYS_MMC_ENV_DEV.
+
+ if u-boot,mmc-env-offset* is present, this setting will take
+ precedence. In that case, only if the partition is not found,
+ mmc-env-offset* will be tried.
+
u-boot,mmc-env-offset
u-boot,mmc-env-offset-redundant
If present, the values of the 'u-boot,mmc-env-offset' and/or
@@ -15,9 +15,13 @@
#include <malloc.h>
#include <memalign.h>
#include <mmc.h>
+#include <part.h>
#include <search.h>
#include <errno.h>
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
#if defined(CONFIG_ENV_SIZE_REDUND) && \
(CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
@@ -30,18 +34,68 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
#if CONFIG_IS_ENABLED(OF_CONTROL)
+static inline int mmc_offset_try_partition(const char *str, s64 *val)
+{
+ disk_partition_t info;
+ struct blk_desc *desc;
+ int len, i, ret;
+
+ ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
+ if (ret < 0)
+ return (ret);
+
+ for (i = 1;;i++) {
+ ret = part_get_info(desc, i, &info);
+ if (ret < 0)
+ return ret;
+
+ if (!strncmp((const char *)info.name, str, sizeof(str)))
+ break;
+ }
+
+ /* round up to info.blksz */
+ len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
+
+ /* use the top of the partion for the environment */
+ *val = (info.start + info.size - 1) - len / info.blksz;
+
+ return 0;
+}
+
static inline s64 mmc_offset(int copy)
{
- const char *propname = "u-boot,mmc-env-offset";
- s64 defvalue = CONFIG_ENV_OFFSET;
+ const struct {
+ const char *offset_redund;
+ const char *partition;
+ const char *offset;
+ } dt_prop = {
+ .offset_redund = "u-boot,mmc-env-offset-redundant",
+ .partition = "u-boot,mmc-env-partition",
+ .offset = "u-boot,mmc-env-offset",
+ };
+ s64 val, defvalue;
+ const char *propname;
+ const char *str;
+ int err;
+
+ /* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */
+ str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
+ if (str) {
+ /* try to place the environment at end of the partition */
+ err = mmc_offset_try_partition(str, &val);
+ if (!err)
+ return val;
+ }
+
+ defvalue = CONFIG_ENV_OFFSET;
+ propname = dt_prop.offset;
#if defined(CONFIG_ENV_OFFSET_REDUND)
if (copy) {
- propname = "u-boot,mmc-env-offset-redundant";
defvalue = CONFIG_ENV_OFFSET_REDUND;
+ propname = dt_prop.offset_redund;
}
#endif
-
return fdtdec_get_config_int(gd->fdt_blob, propname, defvalue);
}
#else
Allow the platform to define a partition by name at the end of which the environment data will be located. Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> --- doc/device-tree-bindings/config.txt | 9 ++++++ env/mmc.c | 62 ++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 4 deletions(-)