Some boards have two or more flash devices on separate chip selects
(for example QSPI/OSPI flashes) and need a single filesystem or image
to span them. This series adds MTD virtual concatenation, where
partitions on different flash devices are linked in the device tree
with the "part-concat-next" property and exposed as one concatenated
MTD device:


        flash@0 {
                partitions {
                        compatible = "fixed-partitions";
                        part0: partition@0 {
                                label = "flash0-part";
                                part-concat-next = <&part1>;
                                reg = <0x0 0x800000>;
                        };
                };
        };

        flash@1 {
                partitions {
                        compatible = "fixed-partitions";
                        part1: partition@0 {
                                label = "flash1-part";
                                reg = <0x0 0x800000>;
                        };
                };
        };

With CONFIG_MTD_VIRT_CONCAT enabled, only the concatenated device
("flash0-part-flash1-part-concat") is registered. The member
partitions are not registered individually. Multiple concat groups,
each with two or more partitions, are supported.

This is based on the Linux driver added by
commit 43db6366fc2d ("mtd: Add driver for concatenating devices"):
https://git.kernel.org/torvalds/c/43db6366fc2d

If a group is incomplete, or cannot be joined, a warning is printed
and its partitions are registered individually.

A concatenated device is kept when the partitions are scanned again. It
is destroyed when a flash it uses is removed, e.g. by 'sf probe', or
when mtdparts defines the partitions of that flash instead of the
device tree. It is not destroyed while it is in use: mtdparts is not
applied to its flash then, and removing the flash only prints a warning,
so it should not be in use when its flash is removed.

On ZynqMP, accessing the flash on CS1 needs the GQSPI chip select fix,
which is now sent separately:
"spi: zynqmp_gqspi: Use the device's chip select"
https://patchwork.ozlabs.org/project/uboot/patch/[email protected]/

Patch 7 enables the option for ZynqMP, Versal, Versal NET and Versal
Gen 2.

On ZynqMP, the board has two mt25qu512a QSPI flashes on CS0 and CS1.
Partition "rootfs_a" (flash@0, 0x1000000-0x4000000) is concatenated
with "rootfs_c" (flash@1, 0x1000000-0x4000000) into a single 96 MiB
device, while the remaining partitions on each flash are registered as
usual:

  ZynqMP> mtd list
  SF: Detected mt25qu512a with page size 256 Bytes, erase size 64 KiB, total 64 
MiB
  SF: Detected mt25qu512a with page size 256 Bytes, erase size 64 KiB, total 64 
MiB
  (0): "rootfs_a"
  (1): "rootfs_c"
  List of MTD devices:
  * nor0
    - device: flash@0
    - parent: spi@ff0f0000
    - driver: jedec_spi_nor
    - path: /axi/spi@ff0f0000/flash@0
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000004000000 : "nor0"
        - 0x000000000000-0x000001000000 : "qspi-fsbl-uboot"
  * nor1
    - device: flash@1
    - parent: spi@ff0f0000
    - driver: jedec_spi_nor
    - path: /axi/spi@ff0f0000/flash@1
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000004000000 : "nor1"
        - 0x000000000000-0x000001000000 : "rootfs_b"
  * rootfs_a-rootfs_c-concat
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000006000000 : "rootfs_a-rootfs_c-concat"

Erase/write/read-back across the CS0/CS1 boundary at 0x3000000:

  ZynqMP> mtd erase rootfs_a-rootfs_c-concat 0x02F00000 0x00200000
  Erasing 0x02f00000 ... 0x030fffff (32 eraseblock(s))
  ZynqMP> mtd write rootfs_a-rootfs_c-concat 0x200000 0x02F00000 0x1E3200
  Writing 1978880 byte(s) at offset 0x02f00000
  ZynqMP> mw.b 0x5000000 0x00 0x1E3200
  ZynqMP> mtd read rootfs_a-rootfs_c-concat 0x5000000 0x02F00000 0x1E3200
  Reading 1978880 byte(s) at offset 0x02f00000
  ZynqMP> cmp.b 0x200000 0x5000000 0x1E3200
  Total of 1978880 byte(s) were the same

On Versal NET, the board has two mx66uw2g345gx0 OSPI flashes on CS0
and CS1 of the Cadence OSPI controller. Partition "ospi-flash1"
(flash@0, 0x200000-0x8000000) is concatenated with "ospi-flash2"
(flash@1, 0x0-0x200000) into a single 128 MiB device. This test also
used "mtd: spi-nor: Remove SPI_NOR_OCTAL_DTR_READ flag for
mx66uw2g345gx0 flash part", which the flashes on this board need and
which is not part of this series:

  Versal NET> mtd list
  SF: Detected mx66uw2g345gx0 with page size 256 Bytes, erase size 64 KiB, 
total 256 MiB
  SF: Detected mx66uw2g345gx0 with page size 256 Bytes, erase size 64 KiB, 
total 256 MiB
  SF: Detected mx25u3235f with page size 256 Bytes, erase size 4 KiB, total 4 
MiB
  (0): "ospi-flash1"
  (1): "ospi-flash2"
  List of MTD devices:
  * nor0
    - device: flash@1
    - parent: spi@f1010000
    - driver: jedec_spi_nor
    - path: /axi/spi@f1010000/flash@1
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000010000000 : "nor0"
        - 0x000000200000-0x000008000000 : "ospi-flash3"
  * nor1
    - device: flash@0
    - parent: spi@f1010000
    - driver: jedec_spi_nor
    - path: /axi/spi@f1010000/flash@0
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000010000000 : "nor1"
        - 0x000000000000-0x000000200000 : "ospi-flash0"
  * nor2
    - device: flash@2
    - parent: spi@f1970000
    - driver: jedec_spi_nor
    - path: /axi/spi@f1970000/flash@2
    - type: NOR flash
    - block size: 0x1000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000000400000 : "nor2"
        - 0x000000000000-0x000000080000 : "spi0-flash0"
  * ospi-flash1-ospi-flash2-concat
    - type: NOR flash
    - block size: 0x10000 bytes
    - min I/O: 0x1 bytes
    - 0x000000000000-0x000008000000 : "ospi-flash1-ospi-flash2-concat"

Erase/write/read-back across the CS0/CS1 boundary at 0x7e00000, then
reading each flash directly to check that each half landed on the
right one:

  Versal NET> mw.b 2000000 cd 200000
  Versal NET> mtd erase ospi-flash1-ospi-flash2-concat 7d00000 200000
  Erasing 0x07d00000 ... 0x07efffff (32 eraseblock(s))
  Versal NET> mtd write ospi-flash1-ospi-flash2-concat 2000000 7d00000 200000
  Writing 2097152 byte(s) at offset 0x07d00000
  Versal NET> mtd read  ospi-flash1-ospi-flash2-concat 3000000 7d00000 200000
  Reading 2097152 byte(s) at offset 0x07d00000
  Versal NET> cmp.b 2000000 3000000 200000
  Total of 2097152 byte(s) were the same
  Versal NET> sf probe 0:0
  SF: Detected mx66uw2g345gx0 with page size 256 Bytes, erase size 64 KiB, 
total 256 MiB
  Versal NET> sf read 4000000 7f00000 100000
  device 0 offset 0x7f00000, size 0x100000
  SF: 1048576 bytes @ 0x7f00000 Read: OK
  Versal NET> cmp.b 2000000 4000000 100000
  Total of 1048576 byte(s) were the same
  Versal NET> sf probe 0:1
  SF: Detected mx66uw2g345gx0 with page size 256 Bytes, erase size 64 KiB, 
total 256 MiB
  Versal NET> sf read 5000000 0 100000
  device 0 offset 0x0, size 0x100000
  SF: 1048576 bytes @ 0x0 Read: OK
  Versal NET> cmp.b 2100000 5000000 100000
  Total of 1048576 byte(s) were the same

After 'sf probe' re-probed both flashes, the next 'mtd list' printed
the concatenated device again, as the scan created it again.

Patch 4 fixes concat_write_oob() and concat_read_oob(), which made any
write to a concatenated NAND device fail. It is needed to use the new
support with NAND partitions.

The sandbox tests in patch 5 cover joining, access across the boundary
between the flashes, rescanning, flashes and concatenated devices which
are in use, removing a flash, incomplete groups and a partition which is
out of reach. They also cover patch 4, with a concatenated NAND device.
Patch 3 fixes the existing NAND tests, which otherwise fail when they
run after a test that probes the MTD devices. Patch 6 adds the
documentation, in doc/usage/mtd_concat.rst.

Changes in v2:
- New patch to fix the lengths returned by concat_write_oob() and
  concat_read_oob()
- Drop "mtd: Move struct mtd_concat definition to header file", which
  the driver no longer needs
- New patch to move the DFS helpers to ofnode, with tests
- Register the partitions of incomplete or failed groups individually
  with a warning
- Warn about an invalid part-concat-next property
- Do not concatenate a partition which is out of reach, or which is
  found more than once
- Free the member partitions when a group is freed, and keep a concat
  device that is still in use
- Keep a concat device when the partitions are scanned again, and only
  destroy it when a flash it uses is removed, or when mtdparts replaces
  the partitions of that flash
- Do not apply mtdparts to a flash while a concat device which uses it
  is in use
- Fix mtd_virt_concat_destroy(), which never matched, and call it from
  del_mtd_device() so that every kind of flash is covered
- Drop the IS_ENABLED() checks, and depend on MTD_PARTITIONS but no
  longer on MTD_CONCAT, which also joins NAND and CFI flash chips
- Refer to the merged Linux commit
- Send the ZynqMP GQSPI fix as a separate patch
- New patch to fix the NAND tests when they run after an MTD test
- New patch with sandbox tests
- New patch with documentation
- Do not enable CONFIG_MTD_CONCAT in the defconfigs

Link to v1: https://patchwork.ozlabs.org/project/uboot/list/?series=529258


Padmarao Begari (7):
  dm: core: Add ofnode_find_node_with_property()
  mtd: Add virtual concat support via device tree
  test: dm: nand: Probe the NAND controller in the test
  mtd: concat: Fix the lengths in the concat OOB functions
  test: dm: Add tests for MTD virtual concat
  doc: Add documentation for MTD virtual concat
  arm64: xilinx: Enable MTD virtual concat

 MAINTAINERS                              |   9 +
 arch/sandbox/dts/test.dts                |  23 +
 configs/amd_versal2_virt_defconfig       |   1 +
 configs/sandbox_defconfig                |   1 +
 configs/xilinx_versal_net_virt_defconfig |   1 +
 configs/xilinx_versal_virt_defconfig     |   1 +
 configs/xilinx_zynqmp_virt_defconfig     |   1 +
 doc/usage/index.rst                      |   1 +
 doc/usage/mtd_concat.rst                 | 146 ++++++
 drivers/core/ofnode.c                    |  31 ++
 drivers/mtd/Kconfig                      |  17 +
 drivers/mtd/Makefile                     |   5 +-
 drivers/mtd/mtd_uboot.c                  |  48 +-
 drivers/mtd/mtd_virt_concat.c            | 457 +++++++++++++++++++
 drivers/mtd/mtdconcat.c                  |   5 +-
 drivers/mtd/mtdcore.c                    |  12 +
 drivers/mtd/mtdpart.c                    |  17 +
 include/dm/ofnode.h                      |  23 +
 include/linux/mtd/concat.h               |  86 +++-
 test/dm/Makefile                         |   1 +
 test/dm/mtd_concat.c                     | 543 +++++++++++++++++++++++
 test/dm/nand.c                           |  10 +
 test/dm/ofnode.c                         |  55 +++
 23 files changed, 1488 insertions(+), 6 deletions(-)
 create mode 100644 doc/usage/mtd_concat.rst
 create mode 100644 drivers/mtd/mtd_virt_concat.c
 create mode 100644 test/dm/mtd_concat.c

-- 
2.34.1

Reply via email to