[RFC PATCH 0/2] Add support for stacked and parallel memories
Hello Everyone,
Following an email discussion with Miquel regarding the binding changes and overall architecture for implementing support for stacked and parallel memories, I’m sharing this RFC to initiate a discussion on the proposed updates to current bindings and to finalize the implementation architecture.
Before diving into the main topic, here is some background on stacked and parallel memories.
The AMD QSPI controller supports two advanced connection modes(Stacked and Parallel) which allow the controller to treat two different flashes as one storage.
Stacked: Flashes share the same SPI bus, but different CS line, controller driver asserts the CS of the flash to which it needs to communicate. Stacked mode is a software abstraction rather than a controller feature or capability. At any given time, the controller communicates with one of the two connected flash devices, as determined by the requested address and data length. If an operation starts on one flash and ends on the other, the core needs to split it into two separate operations and adjust the data length accordingly.
Parallel(Multi-CS): Both the flashes have their separate SPI bus, CS of both the flashes will be asserted/de-asserted at the same time. In this mode data will be split across both the flashes by enabling the STRIPE setting in the controller. Parallel mode is a controller feature where if the STRIPE bit is set then the controller internally handles the data split during data write to the flashes and while reading data from the flash the controller internally merges data from both the flashes before writing to the controller FIFO. If STRIPE is not enabled, then same data will be sent to both the devices. In parallel mode both the flashes should be identical.
For more information on the modes please feel free to go through the controller flash interface below [1].
Mirochip QSPI controller[2] also supports "Dual Parallel 8-bit IO mode", but they call it "Twin Quad Mode".
Initially in [3] [4] [5] Miquel had tried to extend MTD-CONCAT driver to support Stacked mode, but the bindings were not accepted. So, the MTD-CONCAT approach was dropped and the DT bindings that got accepted [6] [7] [8] that describes the two flash devices as being one. SPI core changes to support the above bindings were added [9]. While adding the support in SPI-NOR Tudor provided additional feedback, leading to a discussion on updating the current stacked and parallel DT bindings.
Proposed Solution: The solution has two parts:
1. Update MTD-CONCAT Update MTD-CONCAT to create virtual concatinated mtd devices as defined in the device tree.
2. Add a New Layer Add a new layer between the SPI-NOR and MTD layers to support stacked and parallel configurations. This new layer will be part of spi-nor, located in mtd/spi-nor/, can be included/excluded via Kconfig, will be maintained by AMD and will:
- During probing, store information from all connected flashes in stacked or parallel mode and present them as a single device to the MTD layer. - Register callbacks and manage MTD device registration within the new layer instead of spi-nor/core.c. - Make minimal changes in spi-nor/core.c, as stacked and parallel handling will be managed by the new layer on top of SPI-NOR. - Handle odd byte count requests from the MTD layer during flash operations in parallel mode.
[1] https://docs.amd.com/r/en-US/am011-versal-acap-trm/QSPI-Flash-Device-Interfa... [2] https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocu... [3] https://lore.kernel.org/all/20191113171505.26128-4-miquel.raynal@bootlin.com... [4] https://lore.kernel.org/all/20191127105522.31445-5-miquel.raynal@bootlin.com... [5]https://lore.kernel.org/all/20211112152411.818321-1-miquel.raynal@bootlin.co... [6] https://github.com/torvalds/linux/commit/f89504300e94524d5d5846ff8b728592ac7... [7] https://github.com/torvalds/linux/commit/eba5368503b4291db7819512600fa014ea1... [8] https://github.com/torvalds/linux/commit/e2edd1b64f1c79e8abda365149ed62a2a9a... [9]https://github.com/torvalds/linux/commit/4d8ff6b0991d5e86b17b235fc46ec62e919...
Thanks, Amit
Amit Kumar Mahapatra (2): dt-bindings: mtd: Add bindings for describing concatinated MTD devices dt-bindings: spi: Update stacked and parallel bindings
.../mtd/partitions/fixed-partitions.yaml | 18 +++++++++++++++ .../bindings/mtd/partitions/partitions.yaml | 6 +++++ .../bindings/spi/spi-controller.yaml | 23 +++++++++++++++++-- .../bindings/spi/spi-peripheral-props.yaml | 9 +++----- 4 files changed, 48 insertions(+), 8 deletions(-)
This approach was suggested by Rob [1] during a discussion on Miquel's initial approach [2] to extend the MTD-CONCAT driver to support stacked memories. Define each flash node separately with its respective partitions, and add a 'concat-parts' binding to link the partitions of the two flash nodes that need to be concatenated.
flash@0 { compatible = "jedec,spi-nor" ... partitions { compatible = "fixed-partitions"; concat-partition = <&flash0_partition &flash1_partition>; flash0_partition: partition@0 { label = "part0_0"; reg = <0x0 0x800000>; } } } flash@1 { compatible = "jedec,spi-nor" ... partitions { compatible = "fixed-partitions"; concat-partition = <&flash0_partition &flash1_partition>; flash1_partition: partition@0 { label = "part0_1"; reg = <0x0 0x800000>; } } }
Based on the bindings the MTD-CONCAT driver need to be updated to create virtual mtd-concat devices.
[1] https://lore.kernel.org/all/20191118221341.GA30937@bogus/ [2] https://lore.kernel.org/all/20191113171505.26128-4-miquel.raynal@bootlin.com...
Signed-off-by: Amit Kumar Mahapatra amit.kumar-mahapatra@amd.com --- .../mtd/partitions/fixed-partitions.yaml | 18 ++++++++++++++++++ .../bindings/mtd/partitions/partitions.yaml | 6 ++++++ 2 files changed, 24 insertions(+)
diff --git a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml index 058253d6d889..df4ccb3dfeba 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml @@ -183,3 +183,21 @@ examples: read-only; }; }; + + - | + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + concat-parts = <&part0 &part1>; + + part0: partition@0 { + label = "flash0-part0"; + reg = <0x0000000 0x100000>; + }; + + part1: partition@100000 { + label = "flash1-part0"; + reg = <0x0100000 0x200000>; + }; + }; diff --git a/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml index 1dda2c80747b..86bbd83c3f6d 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml @@ -32,6 +32,12 @@ properties: '#size-cells': enum: [1, 2]
+ concat-parts: + description: List of MTD partitions phandles that should be concatenated. + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 2 + maxItems: 4 + patternProperties: "^partition(-.+|@[0-9a-f]+)$": $ref: partition.yaml
On 26/10/2024 09:53, Amit Kumar Mahapatra wrote:
This approach was suggested by Rob [1] during a discussion on Miquel's initial approach [2] to extend the MTD-CONCAT driver to support stacked memories. Define each flash node separately with its respective partitions, and add a 'concat-parts' binding to link the partitions of the two flash nodes that need to be concatenated.
I understand this was not sent to proper addresses for review because it is a RFC. It's fine then.
If this was not the intention and this should be reviewed (and tested, although I assume you tested these patches first), then please read the standard form bellow:
<form letter> Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about `b4 prep --auto-to-cc` if you added new patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be tested by automated tooling. Performing review on untested code might be a waste of time.
Please kindly resend and include all necessary To/Cc entries. </form letter>
Best regards, Krzysztof
Hello Krzysztof
This approach was suggested by Rob [1] during a discussion on Miquel's initial approach [2] to extend the MTD-CONCAT driver to support stacked memories. Define each flash node separately with its respective partitions, and add a 'concat-parts' binding to link the partitions of the two flash nodes that need to be concatenated.
I understand this was not sent to proper addresses for review because it is a RFC.
Yes, that’s correct.
Regards, Amit
It's fine then.
If this was not the intention and this should be reviewed (and tested, although I assume you tested these patches first), then please read the standard form bellow:
<form letter> Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.
Tools like b4 or scripts/get_maintainer.pl provide you proper list of people, so fix your workflow. Tools might also fail if you work on some ancient tree (don't, instead use mainline) or work on fork of kernel (don't, instead use mainline). Just use b4 and everything should be fine, although remember about `b4 prep --auto-to-cc` if you added new patches to the patchset.
You missed at least devicetree list (maybe more), so this won't be tested by automated tooling. Performing review on untested code might be a waste of time.
Please kindly resend and include all necessary To/Cc entries.
</form letter>
Best regards, Krzysztof
For implementing the proposed solution the current 'stacked-memories' & 'parallel-memories' bindings need to be updated as follow.
stacked-memories binding changes: - Each flash will have its own flash node. This approach allows flashes of different makes and sizes to be stacked together, as each flash will be probed individually. - Each of the flash node will have its own “reg” property that will contain its physical CS. - Remove the size information from the bindings as it can be retrived drirectly from the flash. - The stacked-memories DT bindings will contain the phandles of the flash nodes connected in stacked mode.
The new layer will update the mtd->size and other mtd_info parameters after both the flashes are probed and will call mtd_device_register with the combined information.
spi@0 { ... flash@0 { compatible = "jedec,spi-nor" reg = <0x00>; stacked-memories = <&flash@0 &flash@1>; spi-max-frequency = <50000000>; ... partitions { compatible = "fixed-partitions"; concat-partition = <&flash0_partition &flash1_partition>; flash0_partition: partition@0 { label = "part0_0"; reg = <0x0 0x800000>; } } } flash@1 { compatible = "jedec,spi-nor" reg = <0x01>; stacked-memories = <&flash@0 &flash@1>; spi-max-frequency = <50000000>; ... partitions { compatible = "fixed-partitions"; concat-partition = <&flash0_partition &flash1_partition>; flash1_partition: partition@0 { label = "part0_1"; reg = <0x0 0x800000>; } } }
}
parallel-memories binding changes: - Remove the size information from the bindings and change the type to boolen. - Each flash connected in parallel mode should be identical and will have one flash node for both the flash devices. - The “reg” prop will contain the physical CS number for both the connected flashes.
The new layer will double the mtd-> size and register it with the mtd layer.
spi@1 { ... flash@3 { compatible = "jedec,spi-nor" reg = <0x00 0x01>; paralle-memories ; spi-max-frequency = <50000000>; ... partitions { compatible = "fixed-partitions"; flash0_partition: partition@0 { label = "part0_0"; reg = <0x0 0x800000>; } } } }
Signed-off-by: Amit Kumar Mahapatra amit.kumar-mahapatra@amd.com --- .../bindings/spi/spi-controller.yaml | 23 +++++++++++++++++-- .../bindings/spi/spi-peripheral-props.yaml | 9 +++----- 2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 093150c0cb87..2d300f98dd72 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -185,7 +185,26 @@ examples: flash@2 { compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; - reg = <2>, <3>; - stacked-memories = /bits/ 64 <0x10000000 0x10000000>; + reg = <2>; + stacked-memories = <&flash0 &flash1>; }; + }; + + - | + spi@90010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-spi"; + reg = <0x90010000 0x2000>; + interrupts = <96>; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <0>, <1>; + parallel-memories; + }; + }; diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml index 15938f81fdce..2a014160d701 100644 --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -96,7 +96,7 @@ properties: space with only a single additional wire, while still needing to repeat the commands when crossing a chip boundary. The size of each chip should be provided as members of the array. - $ref: /schemas/types.yaml#/definitions/uint64-array + $ref: /schemas/types.yaml#/definitions/phandle-array minItems: 2 maxItems: 4
@@ -107,11 +107,8 @@ properties: different memories (eg. even bits are stored in one memory, odd bits in the other). This basically doubles the address space and the throughput while greatly complexifying the wiring because as - many busses as devices must be wired. The size of each chip should - be provided as members of the array. - $ref: /schemas/types.yaml#/definitions/uint64-array - minItems: 2 - maxItems: 4 + many busses as devices must be wired. + $ref: /schemas/types.yaml#/definitions/flag
st,spi-midi-ns: description: |
participants (3)
-
Amit Kumar Mahapatra
-
Krzysztof Kozlowski
-
Mahapatra, Amit Kumar