[PATCH v4 5/9] spi: Documentation: add page on multi-lane support

David Lechner posted 9 patches 1 month, 3 weeks ago
There is a newer version of this series
[PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by David Lechner 1 month, 3 weeks ago
Add a new page to Documentation/spi/ describing how multi-lane SPI
support works. This is uncommon functionality so it deserves its own
documentation page.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---
v4 changes:
* New patch in v4.
---
 Documentation/spi/index.rst               |   1 +
 Documentation/spi/multiple-data-lanes.rst | 217 ++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+)

diff --git a/Documentation/spi/index.rst b/Documentation/spi/index.rst
index 824ce42ed4f0..2c89b1ee39e2 100644
--- a/Documentation/spi/index.rst
+++ b/Documentation/spi/index.rst
@@ -9,6 +9,7 @@ Serial Peripheral Interface (SPI)
 
    spi-summary
    spidev
+   multiple-data-lanes
    butterfly
    spi-lm70llp
    spi-sc18is602
diff --git a/Documentation/spi/multiple-data-lanes.rst b/Documentation/spi/multiple-data-lanes.rst
new file mode 100644
index 000000000000..b267f31f0bc8
--- /dev/null
+++ b/Documentation/spi/multiple-data-lanes.rst
@@ -0,0 +1,217 @@
+====================================
+SPI devices with multiple data lanes
+====================================
+
+Some specialized SPI controllers and peripherals support multiple data lanes
+that allow reading more than one word at a time in parallel. This is different
+from dual/quad/octal SPI where multiple bits of a single word are transferred
+simultaneously.
+
+For example, controllers that support parallel flash memories have this feature
+as do some simultaneous-sampling ADCs where each channel has its own data lane.
+
+---------------------
+Describing the wiring
+---------------------
+
+The ``spi-tx-bus-width`` and ``spi-rx-bus-width`` properties in the devicetree
+are used to describe how many data lanes are connected between the controller
+and how wide each lane is. The number of items in the array indicates how many
+lanes there are, and the value of each item indicates how many bits wide that
+lane is.
+
+For example, a dual-simultaneous-sampling ADC with two 4-bit lanes might be
+wired up like this::
+
+    +--------------+    +----------+
+    | SPI          |    | AD4630   |
+    | Controller   |    | ADC      |
+    |              |    |          |
+    |          CS0 |--->| CS       |
+    |          SCK |--->| SCK      |
+    |          SDO |--->| SDI      |
+    |              |    |          |
+    |        SDIA0 |<---| SDOA0    |
+    |        SDIA1 |<---| SDOA1    |
+    |        SDIA2 |<---| SDOA2    |
+    |        SDIA3 |<---| SDOA3    |
+    |              |    |          |
+    |        SDIB0 |<---| SDOB0    |
+    |        SDIB1 |<---| SDOB1    |
+    |        SDIB2 |<---| SDOB2    |
+    |        SDIB3 |<---| SDOB3    |
+    |              |    |          |
+    +--------------+    +----------+
+
+It is described in a devicetree like this::
+
+    spi {
+        compatible = "my,spi-controller";
+
+        ...
+
+        adc@0 {
+            compatible = "adi,ad4630";
+            reg = <0>;
+            ...
+            spi-rx-bus-width = <4>, <4>; /* 2 lanes of 4 bits each */
+            ...
+        };
+    };
+
+In most cases, lanes will be wired up symmetrically (A to A, B to B, etc). If
+this isn't the case, extra ``spi-rx-bus-width`` and ``spi-tx-bus-width``
+properties are needed to provide a mapping between controller lanes and the
+physical lane wires.
+
+Here is an example where a multi-lane SPI controller has each lane wired to
+separate single-lane peripherals::
+
+    +--------------+    +----------+
+    | SPI          |    | Thing 1  |
+    | Controller   |    |          |
+    |              |    |          |
+    |          CS0 |--->| CS       |
+    |         SDO0 |--->| SDI      |
+    |         SDI0 |<---| SDO      |
+    |        SCLK0 |--->| SCLK     |
+    |              |    |          |
+    |              |    +----------+
+    |              |
+    |              |    +----------+
+    |              |    | Thing 2  |
+    |              |    |          |
+    |          CS1 |--->| CS       |
+    |         SDO1 |--->| SDI      |
+    |         SDI1 |<---| SDO      |
+    |        SCLK1 |--->| SCLK     |
+    |              |    |          |
+    +--------------+    +----------+
+
+This is described in a devicetree like this::
+
+    spi {
+        compatible = "my,spi-controller";
+
+        ...
+
+        thing1@0 {
+            compatible = "my,thing1";
+            reg = <0>;
+            ...
+        };
+
+        thing2@1 {
+            compatible = "my,thing2";
+            reg = <1>;
+            ...
+            spi-tx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for tx wire */
+            spi-rx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for rx wire */
+            ...
+        };
+    };
+
+
+The default values of ``spi-rx-bus-width`` and ``spi-tx-bus-width`` are ``<1>``,
+so these properties can still be omitted even when ``spi-rx-lane-map`` and
+``spi-tx-lane-map`` are used.
+
+----------------------------
+Usage in a peripheral driver
+----------------------------
+
+These types of SPI controllers generally do not support arbitrary use of the
+multiple lanes. Instead, they operate in one of a few defined modes. Peripheral
+drivers should set the :c:type:`struct spi_transfer.multi_lane_mode <spi_transfer>`
+field to indicate which mode they want to use for a given transfer.
+
+The possible values for this field have the following semantics:
+
+- :c:macro:`SPI_MULTI_BUS_MODE_SINGLE`: Only use the first lane. Other lanes are
+    ignored. This means that it is operating just like a conventional SPI
+    peripheral. This is the default, so it does not need to be explicitly set.
+
+    Example::
+
+        tx_buf[0] = 0x88;
+
+        struct spi_transfer xfer = {
+            .tx_buf = tx_buf,
+            .len = 1,
+        };
+
+        spi_sync_transfer(spi, &xfer, 1);
+
+    Assuming the controller is sending the MSB first, the sequence of bits
+    sent over the tx wire would be (right-most bit is sent first)::
+
+        controller    > data bits >     peripheral
+        ----------   ----------------   ----------
+            SDO 0    0-0-0-1-0-0-0-1    SDI 0
+
+- :c:macro:`SPI_MULTI_BUS_MODE_MIRROR`: Send a single data word over all of the
+    lanes at the same time. This only makes sense for writes and not
+    for reads.
+
+    Example::
+
+        tx_buf[0] = 0x88;
+
+        struct spi_transfer xfer = {
+            .tx_buf = tx_buf,
+            .len = 1,
+            .multi_lane_mode = SPI_MULTI_BUS_MODE_MIRROR,
+        };
+
+        spi_sync_transfer(spi, &xfer, 1);
+
+    The data is mirrored on each tx wire::
+
+        controller    > data bits >     peripheral
+        ----------   ----------------   ----------
+            SDO 0    0-0-0-1-0-0-0-1    SDI 0
+            SDO 1    0-0-0-1-0-0-0-1    SDI 1
+
+- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
+    at the same time, one on each lane. This means that the buffer needs to be
+    sized to hold data for all lanes. Data is interleaved in the buffer, with
+    the first word corresponding to lane 0, the second to lane 1, and so on.
+    Once the last lane is used, the next word in the buffer corresponds to lane
+    0 again. Accordingly, the buffer size must be a multiple of the number of
+    lanes. This mode works for both reads and writes.
+
+    Example::
+
+        struct spi_transfer xfer = {
+            .rx_buf = rx_buf,
+            .len = 2,
+            .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
+        };
+
+        spi_sync_transfer(spi, &xfer, 1);
+
+    Each tx wire has a different data word sent simultaneously::
+
+        controller    < data bits <     peripheral
+        ----------   ----------------   ----------
+            SDI 0    0-0-0-1-0-0-0-1    SDO 0
+            SDI 1    1-0-0-0-1-0-0-0    SDO 1
+
+    After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
+    ``rx_buf[1] == 0x88`` (word from SDO 1).
+
+
+-----------------------------
+SPI controller driver support
+-----------------------------
+
+To support multiple data lanes, SPI controller drivers need to set
+:c:type:`struct spi_controller.num_data_lanes <spi_controller>` to a value
+greater than 1.
+
+Then the part of the driver that handles SPI transfers needs to check the
+:c:type:`struct spi_transfer.multi_lane_mode <spi_transfer>` field and implement
+the appropriate behavior for each supported mode and return an error for
+unsupported modes.
+
+The core SPI code should handle the rest.

-- 
2.43.0
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by Marcelo Schmitt 1 month ago
Actually, one more thing ...

On 12/19, David Lechner wrote:
> Add a new page to Documentation/spi/ describing how multi-lane SPI
> support works. This is uncommon functionality so it deserves its own
> documentation page.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
...
> +- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
> +    at the same time, one on each lane. This means that the buffer needs to be
> +    sized to hold data for all lanes. Data is interleaved in the buffer, with
> +    the first word corresponding to lane 0, the second to lane 1, and so on.
> +    Once the last lane is used, the next word in the buffer corresponds to lane
> +    0 again. Accordingly, the buffer size must be a multiple of the number of
> +    lanes. This mode works for both reads and writes.
> +
> +    Example::
> +
> +        struct spi_transfer xfer = {
> +            .rx_buf = rx_buf,
> +            .len = 2,
> +            .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
> +        };
> +
> +        spi_sync_transfer(spi, &xfer, 1);
> +
> +    Each tx wire has a different data word sent simultaneously::
In this example, the controller is reading data so the rx wires have different
data word received?

> +
> +        controller    < data bits <     peripheral
> +        ----------   ----------------   ----------
> +            SDI 0    0-0-0-1-0-0-0-1    SDO 0
> +            SDI 1    1-0-0-0-1-0-0-0    SDO 1
> +
> +    After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
> +    ``rx_buf[1] == 0x88`` (word from SDO 1).
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by David Lechner 1 month ago
On 1/8/26 6:44 AM, Marcelo Schmitt wrote:
> Actually, one more thing ...
> 
> On 12/19, David Lechner wrote:
>> Add a new page to Documentation/spi/ describing how multi-lane SPI
>> support works. This is uncommon functionality so it deserves its own
>> documentation page.
>>
>> Signed-off-by: David Lechner <dlechner@baylibre.com>
>> ---
> ...
>> +- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
>> +    at the same time, one on each lane. This means that the buffer needs to be
>> +    sized to hold data for all lanes. Data is interleaved in the buffer, with
>> +    the first word corresponding to lane 0, the second to lane 1, and so on.
>> +    Once the last lane is used, the next word in the buffer corresponds to lane
>> +    0 again. Accordingly, the buffer size must be a multiple of the number of
>> +    lanes. This mode works for both reads and writes.
>> +
>> +    Example::
>> +
>> +        struct spi_transfer xfer = {
>> +            .rx_buf = rx_buf,
>> +            .len = 2,
>> +            .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
>> +        };
>> +
>> +        spi_sync_transfer(spi, &xfer, 1);
>> +
>> +    Each tx wire has a different data word sent simultaneously::
> In this example, the controller is reading data so the rx wires have different
> data word received?

Yes, I tried to make that clear below by having a different value
for each.
> 
>> +
>> +        controller    < data bits <     peripheral
>> +        ----------   ----------------   ----------
>> +            SDI 0    0-0-0-1-0-0-0-1    SDO 0
>> +            SDI 1    1-0-0-0-1-0-0-0    SDO 1
>> +
>> +    After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
>> +    ``rx_buf[1] == 0x88`` (word from SDO 1).
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by Marcelo Schmitt 1 month ago
On 01/08, David Lechner wrote:
> On 1/8/26 6:44 AM, Marcelo Schmitt wrote:
> > Actually, one more thing ...
> > 
> > On 12/19, David Lechner wrote:
> >> Add a new page to Documentation/spi/ describing how multi-lane SPI
> >> support works. This is uncommon functionality so it deserves its own
> >> documentation page.
> >>
> >> Signed-off-by: David Lechner <dlechner@baylibre.com>
> >> ---
> > ...
> >> +- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
> >> +    at the same time, one on each lane. This means that the buffer needs to be
> >> +    sized to hold data for all lanes. Data is interleaved in the buffer, with
> >> +    the first word corresponding to lane 0, the second to lane 1, and so on.
> >> +    Once the last lane is used, the next word in the buffer corresponds to lane
> >> +    0 again. Accordingly, the buffer size must be a multiple of the number of
> >> +    lanes. This mode works for both reads and writes.
> >> +
> >> +    Example::
> >> +
> >> +        struct spi_transfer xfer = {
> >> +            .rx_buf = rx_buf,
> >> +            .len = 2,
> >> +            .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
> >> +        };
> >> +
> >> +        spi_sync_transfer(spi, &xfer, 1);
> >> +
> >> +    Each tx wire has a different data word sent simultaneously::
> > In this example, the controller is reading data so the rx wires have different
> > data word received?
> 
> Yes, I tried to make that clear below by having a different value
> for each.

Yes, that part is clear. What came a bit odd when reading the doc is that the
first two examples ilustrate the controller writing data to the peripheral and
refer to buffers from controller's perspective ('sent over the tx wire', 
'data is mirrored on each tx wire').
IIUC, in this third example, the controller is reading data so we would describe
it like 'Each rx read has a different data word read simultaneously', no?


> > 
> >> +
> >> +        controller    < data bits <     peripheral
> >> +        ----------   ----------------   ----------
> >> +            SDI 0    0-0-0-1-0-0-0-1    SDO 0
> >> +            SDI 1    1-0-0-0-1-0-0-0    SDO 1
> >> +
> >> +    After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
> >> +    ``rx_buf[1] == 0x88`` (word from SDO 1).
>
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by David Lechner 1 month ago
On 1/8/26 10:43 AM, Marcelo Schmitt wrote:
> On 01/08, David Lechner wrote:
>> On 1/8/26 6:44 AM, Marcelo Schmitt wrote:
>>> Actually, one more thing ...
>>>
>>> On 12/19, David Lechner wrote:
>>>> Add a new page to Documentation/spi/ describing how multi-lane SPI
>>>> support works. This is uncommon functionality so it deserves its own
>>>> documentation page.
>>>>
>>>> Signed-off-by: David Lechner <dlechner@baylibre.com>
>>>> ---
>>> ...
>>>> +- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
>>>> +    at the same time, one on each lane. This means that the buffer needs to be
>>>> +    sized to hold data for all lanes. Data is interleaved in the buffer, with
>>>> +    the first word corresponding to lane 0, the second to lane 1, and so on.
>>>> +    Once the last lane is used, the next word in the buffer corresponds to lane
>>>> +    0 again. Accordingly, the buffer size must be a multiple of the number of
>>>> +    lanes. This mode works for both reads and writes.
>>>> +
>>>> +    Example::
>>>> +
>>>> +        struct spi_transfer xfer = {
>>>> +            .rx_buf = rx_buf,
>>>> +            .len = 2,
>>>> +            .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
>>>> +        };
>>>> +
>>>> +        spi_sync_transfer(spi, &xfer, 1);
>>>> +
>>>> +    Each tx wire has a different data word sent simultaneously::
>>> In this example, the controller is reading data so the rx wires have different
>>> data word received?
>>
>> Yes, I tried to make that clear below by having a different value
>> for each.
> 
> Yes, that part is clear. What came a bit odd when reading the doc is that the
> first two examples ilustrate the controller writing data to the peripheral and
> refer to buffers from controller's perspective ('sent over the tx wire', 
> 'data is mirrored on each tx wire').
> IIUC, in this third example, the controller is reading data so we would describe
> it like 'Each rx read has a different data word read simultaneously', no?
> 

Oh, I see. There is just a copy/paste typo.

> 
>>>
>>>> +
>>>> +        controller    < data bits <     peripheral
>>>> +        ----------   ----------------   ----------
>>>> +            SDI 0    0-0-0-1-0-0-0-1    SDO 0
>>>> +            SDI 1    1-0-0-0-1-0-0-0    SDO 1
>>>> +
>>>> +    After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
>>>> +    ``rx_buf[1] == 0x88`` (word from SDO 1).
>>
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by Marcelo Schmitt 1 month ago
Hi David,

Thanks for adding a doc for the multi-lane stuff.
Two minor comments inline.

Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>

On 12/19, David Lechner wrote:
> Add a new page to Documentation/spi/ describing how multi-lane SPI
> support works. This is uncommon functionality so it deserves its own
> documentation page.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> v4 changes:
> * New patch in v4.
> ---
>  Documentation/spi/index.rst               |   1 +
>  Documentation/spi/multiple-data-lanes.rst | 217 ++++++++++++++++++++++++++++++
>  2 files changed, 218 insertions(+)
> 
> diff --git a/Documentation/spi/index.rst b/Documentation/spi/index.rst
> index 824ce42ed4f0..2c89b1ee39e2 100644
> --- a/Documentation/spi/index.rst
> +++ b/Documentation/spi/index.rst
> @@ -9,6 +9,7 @@ Serial Peripheral Interface (SPI)
>  
>     spi-summary
>     spidev
> +   multiple-data-lanes
>     butterfly
>     spi-lm70llp
>     spi-sc18is602
> diff --git a/Documentation/spi/multiple-data-lanes.rst b/Documentation/spi/multiple-data-lanes.rst
> new file mode 100644
> index 000000000000..b267f31f0bc8
> --- /dev/null
> +++ b/Documentation/spi/multiple-data-lanes.rst
> @@ -0,0 +1,217 @@
> +====================================
> +SPI devices with multiple data lanes
> +====================================
> +
> +Some specialized SPI controllers and peripherals support multiple data lanes
> +that allow reading more than one word at a time in parallel. This is different
> +from dual/quad/octal SPI where multiple bits of a single word are transferred
> +simultaneously.
> +
> +For example, controllers that support parallel flash memories have this feature
> +as do some simultaneous-sampling ADCs where each channel has its own data lane.
> +
> +---------------------
> +Describing the wiring
> +---------------------
> +
> +The ``spi-tx-bus-width`` and ``spi-rx-bus-width`` properties in the devicetree
> +are used to describe how many data lanes are connected between the controller
> +and how wide each lane is. The number of items in the array indicates how many
> +lanes there are, and the value of each item indicates how many bits wide that
> +lane is.
> +
> +For example, a dual-simultaneous-sampling ADC with two 4-bit lanes might be
> +wired up like this::
At first, I thought calling these '4-bit lanes' was a bit confusing. I was
thinking about suggesting '4-wire lanes' but I guess 4-bit is more generic in
case we ever see a setup where data navigates through something besides wires.

> +
> +    +--------------+    +----------+
> +    | SPI          |    | AD4630   |
> +    | Controller   |    | ADC      |
> +    |              |    |          |
> +    |          CS0 |--->| CS       |
> +    |          SCK |--->| SCK      |
> +    |          SDO |--->| SDI      |
> +    |              |    |          |
> +    |        SDIA0 |<---| SDOA0    |
> +    |        SDIA1 |<---| SDOA1    |
> +    |        SDIA2 |<---| SDOA2    |
> +    |        SDIA3 |<---| SDOA3    |
> +    |              |    |          |
> +    |        SDIB0 |<---| SDOB0    |
> +    |        SDIB1 |<---| SDOB1    |
> +    |        SDIB2 |<---| SDOB2    |
> +    |        SDIB3 |<---| SDOB3    |
> +    |              |    |          |
> +    +--------------+    +----------+
> +
> +It is described in a devicetree like this::
> +
> +    spi {
> +        compatible = "my,spi-controller";
> +
> +        ...
> +
> +        adc@0 {
> +            compatible = "adi,ad4630";
> +            reg = <0>;
> +            ...
> +            spi-rx-bus-width = <4>, <4>; /* 2 lanes of 4 bits each */
> +            ...
> +        };
> +    };
> +
> +In most cases, lanes will be wired up symmetrically (A to A, B to B, etc). If
> +this isn't the case, extra ``spi-rx-bus-width`` and ``spi-tx-bus-width``
> +properties are needed to provide a mapping between controller lanes and the
> +physical lane wires.
> +
> +Here is an example where a multi-lane SPI controller has each lane wired to
> +separate single-lane peripherals::
> +
> +    +--------------+    +----------+
> +    | SPI          |    | Thing 1  |
> +    | Controller   |    |          |
> +    |              |    |          |
> +    |          CS0 |--->| CS       |
> +    |         SDO0 |--->| SDI      |
> +    |         SDI0 |<---| SDO      |
> +    |        SCLK0 |--->| SCLK     |
> +    |              |    |          |
> +    |              |    +----------+
> +    |              |
> +    |              |    +----------+
> +    |              |    | Thing 2  |
> +    |              |    |          |
> +    |          CS1 |--->| CS       |
> +    |         SDO1 |--->| SDI      |
> +    |         SDI1 |<---| SDO      |
> +    |        SCLK1 |--->| SCLK     |
> +    |              |    |          |
> +    +--------------+    +----------+
> +
> +This is described in a devicetree like this::
> +
> +    spi {
> +        compatible = "my,spi-controller";
> +
> +        ...
> +
> +        thing1@0 {
> +            compatible = "my,thing1";
> +            reg = <0>;
> +            ...
> +        };
> +
> +        thing2@1 {
> +            compatible = "my,thing2";
> +            reg = <1>;
> +            ...
> +            spi-tx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for tx wire */
> +            spi-rx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for rx wire */
In this example, even though lane 0 is not used by thing2, it is being used by
thing1, right?
Just checking I understand it correctly.

> +            ...
> +        };
> +    };
> +
Re: [PATCH v4 5/9] spi: Documentation: add page on multi-lane support
Posted by David Lechner 1 month ago
On 1/8/26 6:40 AM, Marcelo Schmitt wrote:
> Hi David,
> 
> Thanks for adding a doc for the multi-lane stuff.
> Two minor comments inline.
> 
> Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
> 
> On 12/19, David Lechner wrote:
>> Add a new page to Documentation/spi/ describing how multi-lane SPI
>> support works. This is uncommon functionality so it deserves its own
>> documentation page.
>>
>> Signed-off-by: David Lechner <dlechner@baylibre.com>
>> ---
>> v4 changes:
>> * New patch in v4.
>> ---
>>  Documentation/spi/index.rst               |   1 +
>>  Documentation/spi/multiple-data-lanes.rst | 217 ++++++++++++++++++++++++++++++
>>  2 files changed, 218 insertions(+)
>>
>> diff --git a/Documentation/spi/index.rst b/Documentation/spi/index.rst
>> index 824ce42ed4f0..2c89b1ee39e2 100644
>> --- a/Documentation/spi/index.rst
>> +++ b/Documentation/spi/index.rst
>> @@ -9,6 +9,7 @@ Serial Peripheral Interface (SPI)
>>  
>>     spi-summary
>>     spidev
>> +   multiple-data-lanes
>>     butterfly
>>     spi-lm70llp
>>     spi-sc18is602
>> diff --git a/Documentation/spi/multiple-data-lanes.rst b/Documentation/spi/multiple-data-lanes.rst
>> new file mode 100644
>> index 000000000000..b267f31f0bc8
>> --- /dev/null
>> +++ b/Documentation/spi/multiple-data-lanes.rst
>> @@ -0,0 +1,217 @@
>> +====================================
>> +SPI devices with multiple data lanes
>> +====================================
>> +
>> +Some specialized SPI controllers and peripherals support multiple data lanes
>> +that allow reading more than one word at a time in parallel. This is different
>> +from dual/quad/octal SPI where multiple bits of a single word are transferred
>> +simultaneously.
>> +
>> +For example, controllers that support parallel flash memories have this feature
>> +as do some simultaneous-sampling ADCs where each channel has its own data lane.
>> +
>> +---------------------
>> +Describing the wiring
>> +---------------------
>> +
>> +The ``spi-tx-bus-width`` and ``spi-rx-bus-width`` properties in the devicetree
>> +are used to describe how many data lanes are connected between the controller
>> +and how wide each lane is. The number of items in the array indicates how many
>> +lanes there are, and the value of each item indicates how many bits wide that
>> +lane is.
>> +
>> +For example, a dual-simultaneous-sampling ADC with two 4-bit lanes might be
>> +wired up like this::
> At first, I thought calling these '4-bit lanes' was a bit confusing. I was
> thinking about suggesting '4-wire lanes' but I guess 4-bit is more generic in
> case we ever see a setup where data navigates through something besides wires.
> 
>> +
>> +    +--------------+    +----------+
>> +    | SPI          |    | AD4630   |
>> +    | Controller   |    | ADC      |
>> +    |              |    |          |
>> +    |          CS0 |--->| CS       |
>> +    |          SCK |--->| SCK      |
>> +    |          SDO |--->| SDI      |
>> +    |              |    |          |
>> +    |        SDIA0 |<---| SDOA0    |
>> +    |        SDIA1 |<---| SDOA1    |
>> +    |        SDIA2 |<---| SDOA2    |
>> +    |        SDIA3 |<---| SDOA3    |
>> +    |              |    |          |
>> +    |        SDIB0 |<---| SDOB0    |
>> +    |        SDIB1 |<---| SDOB1    |
>> +    |        SDIB2 |<---| SDOB2    |
>> +    |        SDIB3 |<---| SDOB3    |
>> +    |              |    |          |
>> +    +--------------+    +----------+
>> +
>> +It is described in a devicetree like this::
>> +
>> +    spi {
>> +        compatible = "my,spi-controller";
>> +
>> +        ...
>> +
>> +        adc@0 {
>> +            compatible = "adi,ad4630";
>> +            reg = <0>;
>> +            ...
>> +            spi-rx-bus-width = <4>, <4>; /* 2 lanes of 4 bits each */
>> +            ...
>> +        };
>> +    };
>> +
>> +In most cases, lanes will be wired up symmetrically (A to A, B to B, etc). If
>> +this isn't the case, extra ``spi-rx-bus-width`` and ``spi-tx-bus-width``
>> +properties are needed to provide a mapping between controller lanes and the
>> +physical lane wires.
>> +
>> +Here is an example where a multi-lane SPI controller has each lane wired to
>> +separate single-lane peripherals::
>> +
>> +    +--------------+    +----------+
>> +    | SPI          |    | Thing 1  |
>> +    | Controller   |    |          |
>> +    |              |    |          |
>> +    |          CS0 |--->| CS       |
>> +    |         SDO0 |--->| SDI      |
>> +    |         SDI0 |<---| SDO      |
>> +    |        SCLK0 |--->| SCLK     |
>> +    |              |    |          |
>> +    |              |    +----------+
>> +    |              |
>> +    |              |    +----------+
>> +    |              |    | Thing 2  |
>> +    |              |    |          |
>> +    |          CS1 |--->| CS       |
>> +    |         SDO1 |--->| SDI      |
>> +    |         SDI1 |<---| SDO      |
>> +    |        SCLK1 |--->| SCLK     |
>> +    |              |    |          |
>> +    +--------------+    +----------+
>> +
>> +This is described in a devicetree like this::
>> +
>> +    spi {
>> +        compatible = "my,spi-controller";
>> +
>> +        ...
>> +
>> +        thing1@0 {
>> +            compatible = "my,thing1";
>> +            reg = <0>;
>> +            ...
>> +        };
>> +
>> +        thing2@1 {
>> +            compatible = "my,thing2";
>> +            reg = <1>;
>> +            ...
>> +            spi-tx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for tx wire */
>> +            spi-rx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for rx wire */
> In this example, even though lane 0 is not used by thing2, it is being used by
> thing1, right?

Yes, I can improve the comments to make it more clear.

> Just checking I understand it correctly.
> 
>> +            ...
>> +        };
>> +    };
>> +