aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch')
-rw-r--r--package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch409
1 files changed, 0 insertions, 409 deletions
diff --git a/package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch b/package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch
deleted file mode 100644
index 932c4b736a0..00000000000
--- a/package/boot/uboot-mediatek/patches/000-mtk-16-env-add-support-for-generic-MTD-device.patch
+++ /dev/null
@@ -1,409 +0,0 @@
-From eaa9bc597e0bf8bcd1486ea49c8c7c070a37a8aa Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Wed, 3 Mar 2021 10:11:32 +0800
-Subject: [PATCH 16/21] env: add support for generic MTD device
-
-Add an env driver for generic MTD device.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- cmd/nvedit.c | 3 +-
- env/Kconfig | 37 +++++-
- env/Makefile | 1 +
- env/env.c | 3 +
- env/mtd.c | 256 +++++++++++++++++++++++++++++++++++++++++
- include/env_internal.h | 1 +
- tools/Makefile | 1 +
- 7 files changed, 299 insertions(+), 3 deletions(-)
- create mode 100644 env/mtd.c
-
---- a/cmd/nvedit.c
-+++ b/cmd/nvedit.c
-@@ -50,6 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
- defined(CONFIG_ENV_IS_IN_MMC) || \
- defined(CONFIG_ENV_IS_IN_FAT) || \
- defined(CONFIG_ENV_IS_IN_EXT4) || \
-+ defined(CONFIG_ENV_IS_IN_MTD) || \
- defined(CONFIG_ENV_IS_IN_NAND) || \
- defined(CONFIG_ENV_IS_IN_NVRAM) || \
- defined(CONFIG_ENV_IS_IN_ONENAND) || \
-@@ -64,7 +65,7 @@ DECLARE_GLOBAL_DATA_PTR;
-
- #if !defined(ENV_IS_IN_DEVICE) && \
- !defined(CONFIG_ENV_IS_NOWHERE)
--# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\
-+# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|MTD|\
- NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
- #endif
-
---- a/env/Kconfig
-+++ b/env/Kconfig
-@@ -19,7 +19,7 @@ config ENV_IS_NOWHERE
- !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \
- !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \
- !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \
-- !ENV_IS_IN_UBI
-+ !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
- help
- Define this if you don't want to or can't have an environment stored
- on a storage medium. In this case the environment will still exist
-@@ -207,6 +207,27 @@ config ENV_IS_IN_MMC
- This value is also in units of bytes, but must also be aligned to
- an MMC sector boundary.
-
-+config ENV_IS_IN_MTD
-+ bool "Environment in a MTD device"
-+ depends on !CHAIN_OF_TRUST
-+ depends on MTD
-+ help
-+ Define this if you have a MTD device which you want to use for
-+ the environment.
-+
-+ - CONFIG_ENV_MTD_NAME:
-+ - CONFIG_ENV_OFFSET:
-+ - CONFIG_ENV_SIZE:
-+
-+ These three #defines specify the MTD device where the environment
-+ is stored, offset and size of the environment area within the MTD
-+ device. CONFIG_ENV_OFFSET must be aligned to an erase block boundary.
-+
-+ - CONFIG_ENV_SIZE_REDUND:
-+
-+ This #define specify the maximum size allowed for read/write/erase
-+ with skipped bad blocks starting from ENV_OFFSET.
-+
- config ENV_IS_IN_NAND
- bool "Environment in a NAND device"
- depends on !CHAIN_OF_TRUST
-@@ -513,10 +534,16 @@ config ENV_ADDR_REDUND
- Offset from the start of the device (or partition) of the redundant
- environment location.
-
-+config ENV_MTD_NAME
-+ string "Name of the MTD device storing the environment"
-+ depends on ENV_IS_IN_MTD
-+ help
-+ Name of the MTD device that stores the environment
-+
- config ENV_OFFSET
- hex "Environment offset"
- depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
-- ENV_IS_IN_SPI_FLASH
-+ ENV_IS_IN_SPI_FLASH || ENV_IS_IN_MTD
- default 0x3f8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
- default 0x140000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
- default 0x88000 if ARCH_SUNXI
-@@ -560,6 +587,12 @@ config ENV_SECT_SIZE
- help
- Size of the sector containing the environment.
-
-+config ENV_SIZE_REDUND
-+ hex "Redundant environment size"
-+ depends on ENV_IS_IN_MTD
-+ help
-+ The maximum size allowed for read/write/erase with skipped bad blocks.
-+
- config ENV_UBI_PART
- string "UBI partition name"
- depends on ENV_IS_IN_UBI
---- a/env/Makefile
-+++ b/env/Makefile
-@@ -26,6 +26,7 @@ obj-$(CONFIG_$(SPL_TPL_)ENV_IS_NOWHERE)
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_MMC) += mmc.o
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FAT) += fat.o
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_EXT4) += ext4.o
-+obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_MTD) += mtd.o
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_NAND) += nand.o
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_SPI_FLASH) += sf.o
- obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FLASH) += flash.o
---- a/env/env.c
-+++ b/env/env.c
-@@ -69,6 +69,9 @@ static enum env_location env_locations[]
- #ifdef CONFIG_ENV_IS_IN_MMC
- ENVL_MMC,
- #endif
-+#ifdef CONFIG_ENV_IS_IN_MTD
-+ ENVL_MTD,
-+#endif
- #ifdef CONFIG_ENV_IS_IN_NAND
- ENVL_NAND,
- #endif
---- /dev/null
-+++ b/env/mtd.c
-@@ -0,0 +1,256 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ */
-+
-+#include <command.h>
-+#include <env.h>
-+#include <env_internal.h>
-+#include <errno.h>
-+#include <linux/kernel.h>
-+#include <linux/stddef.h>
-+#include <linux/types.h>
-+#include <linux/mtd/mtd.h>
-+#include <malloc.h>
-+#include <memalign.h>
-+#include <mtd.h>
-+#include <search.h>
-+
-+#if CONFIG_ENV_SIZE_REDUND < CONFIG_ENV_SIZE
-+#undef CONFIG_ENV_SIZE_REDUND
-+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
-+#endif
-+
-+#if defined(ENV_IS_EMBEDDED)
-+env_t *env_ptr = &environment;
-+#else /* ! ENV_IS_EMBEDDED */
-+env_t *env_ptr;
-+#endif /* ENV_IS_EMBEDDED */
-+
-+DECLARE_GLOBAL_DATA_PTR;
-+
-+static int env_mtd_init(void)
-+{
-+#if defined(ENV_IS_EMBEDDED)
-+ int crc1_ok = 0, crc2_ok = 0;
-+ env_t *tmp_env1;
-+
-+ tmp_env1 = env_ptr;
-+ crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
-+
-+ if (!crc1_ok && !crc2_ok) {
-+ gd->env_addr = 0;
-+ gd->env_valid = ENV_INVALID;
-+
-+ return 0;
-+ } else if (crc1_ok && !crc2_ok) {
-+ gd->env_valid = ENV_VALID;
-+ }
-+
-+ if (gd->env_valid == ENV_VALID)
-+ env_ptr = tmp_env1;
-+
-+ gd->env_addr = (ulong)env_ptr->data;
-+
-+#else /* ENV_IS_EMBEDDED */
-+ gd->env_addr = (ulong)&default_environment[0];
-+ gd->env_valid = ENV_VALID;
-+#endif /* ENV_IS_EMBEDDED */
-+
-+ return 0;
-+}
-+
-+static struct mtd_info *env_mtd_get_dev(void)
-+{
-+ struct mtd_info *mtd;
-+
-+ mtd_probe_devices();
-+
-+ mtd = get_mtd_device_nm(CONFIG_ENV_MTD_NAME);
-+ if (IS_ERR(mtd) || !mtd) {
-+ printf("MTD device '%s' not found\n", CONFIG_ENV_MTD_NAME);
-+ return NULL;
-+ }
-+
-+ return mtd;
-+}
-+
-+static inline bool mtd_addr_is_block_aligned(struct mtd_info *mtd, u64 addr)
-+{
-+ return (addr & mtd->erasesize_mask) == 0;
-+}
-+
-+static int mtd_io_skip_bad(struct mtd_info *mtd, bool read, loff_t offset,
-+ size_t length, size_t redund, u8 *buffer)
-+{
-+ struct mtd_oob_ops io_op = {};
-+ size_t remaining = length;
-+ loff_t off, end;
-+ int ret;
-+
-+ io_op.mode = MTD_OPS_PLACE_OOB;
-+ io_op.len = mtd->writesize;
-+ io_op.datbuf = (void *)buffer;
-+
-+ /* Search for the first good block after the given offset */
-+ off = offset;
-+ end = (off + redund) | (mtd->erasesize - 1);
-+ while (mtd_block_isbad(mtd, off) && off < end)
-+ off += mtd->erasesize;
-+
-+ /* Reached end position */
-+ if (off >= end)
-+ return -EIO;
-+
-+ /* Loop over the pages to do the actual read/write */
-+ while (remaining) {
-+ /* Skip the block if it is bad */
-+ if (mtd_addr_is_block_aligned(mtd, off) &&
-+ mtd_block_isbad(mtd, off)) {
-+ off += mtd->erasesize;
-+ continue;
-+ }
-+
-+ if (read)
-+ ret = mtd_read_oob(mtd, off, &io_op);
-+ else
-+ ret = mtd_write_oob(mtd, off, &io_op);
-+
-+ if (ret) {
-+ printf("Failure while %s at offset 0x%llx\n",
-+ read ? "reading" : "writing", off);
-+ break;
-+ }
-+
-+ off += io_op.retlen;
-+ remaining -= io_op.retlen;
-+ io_op.datbuf += io_op.retlen;
-+ io_op.oobbuf += io_op.oobretlen;
-+
-+ /* Reached end position */
-+ if (off >= end)
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_CMD_SAVEENV
-+static int mtd_erase_skip_bad(struct mtd_info *mtd, loff_t offset,
-+ size_t length, size_t redund)
-+{
-+ struct erase_info erase_op = {};
-+ loff_t end = (offset + redund) | (mtd->erasesize - 1);
-+ int ret;
-+
-+ erase_op.mtd = mtd;
-+ erase_op.addr = offset;
-+ erase_op.len = length;
-+
-+ while (erase_op.len) {
-+ ret = mtd_erase(mtd, &erase_op);
-+
-+ /* Abort if its not a bad block error */
-+ if (ret != -EIO)
-+ return ret;
-+
-+ printf("Skipping bad block at 0x%08llx\n", erase_op.fail_addr);
-+
-+ /* Skip bad block and continue behind it */
-+ erase_op.len -= erase_op.fail_addr - erase_op.addr;
-+ erase_op.len -= mtd->erasesize;
-+ erase_op.addr = erase_op.fail_addr + mtd->erasesize;
-+
-+ /* Reached end position */
-+ if (erase_op.addr >= end)
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int env_mtd_save(void)
-+{
-+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
-+ struct mtd_info *mtd;
-+ int ret = 0;
-+
-+ ret = env_export(env_new);
-+ if (ret)
-+ return ret;
-+
-+ mtd = env_mtd_get_dev();
-+ if (!mtd)
-+ return 1;
-+
-+ printf("Erasing on MTD device '%s'... ", mtd->name);
-+
-+ ret = mtd_erase_skip_bad(mtd, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
-+ CONFIG_ENV_SIZE_REDUND);
-+
-+ puts(ret ? "FAILED\n" : "OK\n");
-+
-+ if (ret) {
-+ put_mtd_device(mtd);
-+ return 1;
-+ }
-+
-+ printf("Writing to MTD device '%s'... ", mtd->name);
-+
-+ ret = mtd_io_skip_bad(mtd, false, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
-+ CONFIG_ENV_SIZE_REDUND, (u8 *)env_new);
-+
-+ puts(ret ? "FAILED\n" : "OK\n");
-+
-+ put_mtd_device(mtd);
-+
-+ return !!ret;
-+}
-+#endif /* CONFIG_CMD_SAVEENV */
-+
-+static int readenv(size_t offset, u_char *buf)
-+{
-+ struct mtd_info *mtd;
-+ int ret;
-+
-+ mtd = env_mtd_get_dev();
-+ if (!mtd)
-+ return 1;
-+
-+ ret = mtd_io_skip_bad(mtd, true, offset, CONFIG_ENV_SIZE,
-+ CONFIG_ENV_SIZE_REDUND, buf);
-+
-+ put_mtd_device(mtd);
-+
-+ return !!ret;
-+}
-+
-+static int env_mtd_load(void)
-+{
-+#if !defined(ENV_IS_EMBEDDED)
-+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
-+ int ret;
-+
-+ ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
-+ if (ret) {
-+ env_set_default("readenv() failed", 0);
-+ return -EIO;
-+ }
-+
-+ return env_import(buf, 1, H_EXTERNAL);
-+#endif /* ! ENV_IS_EMBEDDED */
-+
-+ return 0;
-+}
-+
-+U_BOOT_ENV_LOCATION(mtd) = {
-+ .location = ENVL_MTD,
-+ ENV_NAME("MTD")
-+ .load = env_mtd_load,
-+#if defined(CONFIG_CMD_SAVEENV)
-+ .save = env_save_ptr(env_mtd_save),
-+#endif
-+ .init = env_mtd_init,
-+};
---- a/include/env_internal.h
-+++ b/include/env_internal.h
-@@ -131,6 +131,7 @@ enum env_location {
- ENVL_FAT,
- ENVL_FLASH,
- ENVL_MMC,
-+ ENVL_MTD,
- ENVL_NAND,
- ENVL_NVRAM,
- ENVL_ONENAND,
---- a/tools/Makefile
-+++ b/tools/Makefile
-@@ -22,6 +22,7 @@ ENVCRC-$(CONFIG_ENV_IS_EMBEDDED) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_EEPROM) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_FLASH) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_ONENAND) = y
-+ENVCRC-$(CONFIG_ENV_IS_IN_MTD) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_NAND) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_NVRAM) = y
- ENVCRC-$(CONFIG_ENV_IS_IN_SPI_FLASH) = y