* [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access
@ 2026-09-10 18:19 Marek Vasut
2026-09-10 18:29 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Marek Vasut @ 2026-09-10 18:19 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, David Airlie, Geert Uytterhoeven, Kieran Bingham,
Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
Simona Vetter, Thomas Zimmermann, Tomi Valkeinen, linux-kernel,
linux-renesas-soc
Currently, the driver supports register access mode for DSI command
transfer, which limits both TX and RX to only 16 Bytes long packets.
Implement support for DSI command TX using AXI memory access mode,
which extends the packet transfer length up to 128 Bytes long in LP
and 1024 Bytes long in HS. Support for DSI command RX using the AXI
access mode is not implemented due to missing test hardware.
The implementation allocates a DMAble 4k page. In case the command
transfer is longer than 16 Bytes, the payload is copied into the
page and sent out using the AXI access mode, otherwise the register
access mode is used.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: David Airlie <airlied@gmail.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: - Use dma_set_mask_and_coherent() to set up global DMA mask and
drop GFP_DMA32 from dma_alloc_coherent() gfp flags.
- Fix DMA memory leak in missing fail path in rcar_mipi_dsi_probe()
and move dma_alloc_coherent() almost to the end of the probe
function, so as much as possible of the probe function is devm
managed.
- Unregister DSI host first, then free the DMA page
V3: - Limit transfer to 1024 Bytes
---
.../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 50 ++++++++++++++++---
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
index 6e46d6d99f3c0..7a9c0a281ea6d 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
@@ -8,6 +8,7 @@
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/math64.h>
@@ -75,6 +76,9 @@ struct rcar_mipi_dsi {
unsigned long mode_flags;
unsigned int num_data_lanes;
unsigned int lanes;
+
+ void *cmd_axi_cpu;
+ dma_addr_t cmd_axi_dma;
};
struct dsi_setup_info {
@@ -977,6 +981,7 @@ static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
bool is_rx_xfer)
{
const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
+ const bool is_tx_axi = !is_rx_xfer && is_tx_long && (msg->tx_len > 16);
struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
struct mipi_dsi_packet packet;
u8 payload[16] = { 0 };
@@ -987,9 +992,14 @@ static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
if (ret)
return ret;
- /* Configure LP or HS command transfer. */
- rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
- TXCMSETR_SPDTYP : 0);
+ /* Configure LP or HS and register or AXI command transfer. */
+ rcar_mipi_dsi_write(dsi, TXCMSETR, ((msg->flags & MIPI_DSI_MSG_USE_LPM) ?
+ TXCMSETR_SPDTYP : 0) |
+ (is_tx_axi ? TXCMSETR_LPPDACC : 0));
+
+ /* Configure DMA source address for AXI command transfer. */
+ if (is_tx_axi)
+ rcar_mipi_dsi_write(dsi, TXCMADDRSET0R, dsi->cmd_axi_dma);
/* Register access mode for RX transfer. */
if (is_rx_xfer)
@@ -1011,7 +1021,10 @@ static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
TXCMPHDR_DATA1(packet.header[2]) |
TXCMPHDR_DATA0(packet.header[1]));
- if (is_tx_long) {
+ if (is_tx_axi) {
+ memcpy(dsi->cmd_axi_cpu, packet.payload,
+ min(msg->tx_len, 1024));
+ } else if (is_tx_long) {
memcpy(payload, packet.payload,
min(msg->tx_len, sizeof(payload)));
@@ -1162,10 +1175,16 @@ static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
int ret;
- if (msg->tx_len > 16 || msg->rx_len > 16) {
- /* ToDo: Implement Memory on AXI bus command mode. */
+ if (msg->tx_len > 1024 || msg->rx_len > 16) {
+ /* ToDo: Implement Memory on AXI bus RX command mode. */
dev_warn(dsi->dev,
- "Register-based command mode supports only up to 16 Bytes long payload\n");
+ "Command mode supports only up to 1024B long TX and 16B long RX payload\n");
+ return -EOPNOTSUPP;
+ }
+
+ if ((msg->flags & MIPI_DSI_MSG_USE_LPM) && msg->tx_len > 128) {
+ dev_warn(dsi->dev,
+ "Command mode in LP supports only up to 128B long TX payload\n");
return -EOPNOTSUPP;
}
@@ -1266,6 +1285,10 @@ static int rcar_mipi_dsi_probe(struct platform_device *pdev)
struct rcar_mipi_dsi *dsi;
int ret;
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "No suitable DMA available\n");
+
dsi = devm_drm_bridge_alloc(&pdev->dev, struct rcar_mipi_dsi, bridge,
&rcar_mipi_dsi_bridge_ops);
if (IS_ERR(dsi))
@@ -1295,12 +1318,21 @@ static int rcar_mipi_dsi_probe(struct platform_device *pdev)
return PTR_ERR(dsi->rstc);
}
+ dsi->cmd_axi_cpu = dma_alloc_coherent(&pdev->dev, SZ_4K, &dsi->cmd_axi_dma,
+ GFP_KERNEL);
+ if (!dsi->cmd_axi_cpu) {
+ return dev_err_probe(&pdev->dev, -ENOMEM,
+ "Failed to allocate DSI AXI Access command buffer\n");
+ }
+
/* Initialize the DSI host. */
dsi->host.dev = dsi->dev;
dsi->host.ops = &rcar_mipi_dsi_host_ops;
ret = mipi_dsi_host_register(&dsi->host);
- if (ret < 0)
+ if (ret < 0) {
+ dma_free_coherent(&pdev->dev, SZ_4K, dsi->cmd_axi_cpu, dsi->cmd_axi_dma);
return ret;
+ }
return 0;
}
@@ -1310,6 +1342,8 @@ static void rcar_mipi_dsi_remove(struct platform_device *pdev)
struct rcar_mipi_dsi *dsi = platform_get_drvdata(pdev);
mipi_dsi_host_unregister(&dsi->host);
+
+ dma_free_coherent(&pdev->dev, SZ_4K, dsi->cmd_axi_cpu, dsi->cmd_axi_dma);
}
static const struct rcar_mipi_dsi_device_info v3u_data = {
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access
2026-09-10 18:19 [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access Marek Vasut
@ 2026-09-10 18:29 ` sashiko-bot
2026-09-11 5:15 ` Tomi Valkeinen
2026-09-11 7:05 ` Tomi Valkeinen
2 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-09-10 18:29 UTC (permalink / raw)
To: Marek Vasut; +Cc: dri-devel, wsa+renesas
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Silent truncation of TX payloads > 16 bytes when a transfer requests an ACK or involves an RX response, leading to hardware desynchronization.
--
commit 13f2cd4029598c96fbe1cf82c539c77f33326afa
Author: Marek Vasut <marek.vasut+renesas@mailbox.org>
drm/rcar-du: dsi: Implement DSI command TX using AXI memory access
Currently, the driver supports register access mode for DSI command
transfer, which limits both TX and RX to only 16 Bytes long packets.
Implement support for DSI command TX using AXI memory access mode,
which extends the packet transfer length up to 128 Bytes long in LP
and 1024 Bytes long in HS.
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
[ ... ]
> @@ -977,6 +981,7 @@ static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
> bool is_rx_xfer)
> {
> const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type);
> + const bool is_tx_axi = !is_rx_xfer && is_tx_long && (msg->tx_len > 16);
[Severity: High]
If a DSI panel driver initiates a transfer with a payload > 16 bytes and
requests an ACK (by setting MIPI_DSI_MSG_REQ_ACK in msg->flags), is_rx_xfer
evaluates to true. Does this unintentionally force the driver to bypass AXI
mode and use register mode, regardless of tx_len?
> struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> struct mipi_dsi_packet packet;
[ ... ]
> @@ -1011,7 +1021,10 @@ static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host,
> TXCMPHDR_DATA1(packet.header[2]) |
> TXCMPHDR_DATA0(packet.header[1]));
>
> - if (is_tx_long) {
> + if (is_tx_axi) {
> + memcpy(dsi->cmd_axi_cpu, packet.payload,
> + min(msg->tx_len, 1024));
> + } else if (is_tx_long) {
> memcpy(payload, packet.payload,
> min(msg->tx_len, sizeof(payload)));
[Severity: High]
When AXI mode is bypassed for a long write (because is_rx_xfer is true),
the payload is silently truncated to 16 bytes here. Since the hardware header
will still expect the full transfer size, can this starve the hardware FIFO,
leading to garbage data transmission and a DSI link timeout?
[ ... ]
> @@ -1162,10 +1175,16 @@ static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
> struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> int ret;
>
> - if (msg->tx_len > 16 || msg->rx_len > 16) {
> - /* ToDo: Implement Memory on AXI bus command mode. */
> + if (msg->tx_len > 1024 || msg->rx_len > 16) {
> + /* ToDo: Implement Memory on AXI bus RX command mode. */
> dev_warn(dsi->dev,
> - "Register-based command mode supports only up to 16 Bytes long payload\n");
> + "Command mode supports only up to 1024B long TX and 16B long RX payload\n");
> + return -EOPNOTSUPP;
> + }
[Severity: High]
This overarching validation check permits transfers with tx_len > 16 to
proceed even if is_rx_xfer is true. Since AXI mode isn't supported for RX
transfers, and long writes requiring an ACK are forced to bypass AXI mode,
should this block tx_len > 16 when is_rx_xfer is true to prevent silent
truncation?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260910182003.31612-1-marek.vasut+renesas@mailbox.org?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access
2026-09-10 18:19 [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access Marek Vasut
2026-09-10 18:29 ` sashiko-bot
@ 2026-09-11 5:15 ` Tomi Valkeinen
2026-09-11 7:05 ` Tomi Valkeinen
2 siblings, 0 replies; 4+ messages in thread
From: Tomi Valkeinen @ 2026-09-11 5:15 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
Simona Vetter, Thomas Zimmermann, linux-kernel, linux-renesas-soc
Hi,
On 10/09/2026 21:19, Marek Vasut wrote:
> Currently, the driver supports register access mode for DSI command
> transfer, which limits both TX and RX to only 16 Bytes long packets.
> Implement support for DSI command TX using AXI memory access mode,
> which extends the packet transfer length up to 128 Bytes long in LP
> and 1024 Bytes long in HS. Support for DSI command RX using the AXI
> access mode is not implemented due to missing test hardware.
>
> The implementation allocates a DMAble 4k page. In case the command
> transfer is longer than 16 Bytes, the payload is copied into the
> page and sent out using the AXI access mode, otherwise the register
> access mode is used.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: David Airlie <airlied@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
> V2: - Use dma_set_mask_and_coherent() to set up global DMA mask and
> drop GFP_DMA32 from dma_alloc_coherent() gfp flags.
> - Fix DMA memory leak in missing fail path in rcar_mipi_dsi_probe()
> and move dma_alloc_coherent() almost to the end of the probe
> function, so as much as possible of the probe function is devm
> managed.
> - Unregister DSI host first, then free the DMA page
> V3: - Limit transfer to 1024 Bytes
> ---
> .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 50 ++++++++++++++++---
> 1 file changed, 42 insertions(+), 8 deletions(-)
Reviewed-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Tomi
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access
2026-09-10 18:19 [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access Marek Vasut
2026-09-10 18:29 ` sashiko-bot
2026-09-11 5:15 ` Tomi Valkeinen
@ 2026-09-11 7:05 ` Tomi Valkeinen
2 siblings, 0 replies; 4+ messages in thread
From: Tomi Valkeinen @ 2026-09-11 7:05 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: David Airlie, Geert Uytterhoeven, Kieran Bingham,
Laurent Pinchart, Maarten Lankhorst, Magnus Damm, Maxime Ripard,
Simona Vetter, Thomas Zimmermann, linux-kernel, linux-renesas-soc
Hi,
On 10/09/2026 21:19, Marek Vasut wrote:
> Currently, the driver supports register access mode for DSI command
> transfer, which limits both TX and RX to only 16 Bytes long packets.
> Implement support for DSI command TX using AXI memory access mode,
> which extends the packet transfer length up to 128 Bytes long in LP
> and 1024 Bytes long in HS. Support for DSI command RX using the AXI
> access mode is not implemented due to missing test hardware.
>
> The implementation allocates a DMAble 4k page. In case the command
> transfer is longer than 16 Bytes, the payload is copied into the
> page and sent out using the AXI access mode, otherwise the register
> access mode is used.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: David Airlie <airlied@gmail.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
> V2: - Use dma_set_mask_and_coherent() to set up global DMA mask and
> drop GFP_DMA32 from dma_alloc_coherent() gfp flags.
> - Fix DMA memory leak in missing fail path in rcar_mipi_dsi_probe()
> and move dma_alloc_coherent() almost to the end of the probe
> function, so as much as possible of the probe function is devm
> managed.
> - Unregister DSI host first, then free the DMA page
> V3: - Limit transfer to 1024 Bytes
> ---
> .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 50 ++++++++++++++++---
> 1 file changed, 42 insertions(+), 8 deletions(-)
Thanks, pushed to drm-misc-next.
Tomi
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-11 7:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 18:19 [PATCH v3] drm/rcar-du: dsi: Implement DSI command TX using AXI memory access Marek Vasut
2026-09-10 18:29 ` sashiko-bot
2026-09-11 5:15 ` Tomi Valkeinen
2026-09-11 7:05 ` Tomi Valkeinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox