Hi Marek, Thank you for the patch.
On Sun, Aug 09, 2026 at 09:58:06PM +0200, 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 <[email protected]> > --- > Cc: David Airlie <[email protected]> > Cc: Geert Uytterhoeven <[email protected]> > Cc: Kieran Bingham <[email protected]> > Cc: Laurent Pinchart <[email protected]> > Cc: Maarten Lankhorst <[email protected]> > Cc: Magnus Damm <[email protected]> > Cc: Maxime Ripard <[email protected]> > Cc: Simona Vetter <[email protected]> > Cc: Thomas Zimmermann <[email protected]> > Cc: Tomi Valkeinen <[email protected]> > Cc: [email protected] > Cc: [email protected] > Cc: [email protected] > --- > .../gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 42 +++++++++++++++---- > 1 file changed, 35 insertions(+), 7 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..c25218ca4320a 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, 128)); > + } 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; > } > > @@ -1276,6 +1295,13 @@ static int rcar_mipi_dsi_probe(struct platform_device > *pdev) > dsi->dev = &pdev->dev; > dsi->info = of_device_get_match_data(&pdev->dev); > > + dsi->cmd_axi_cpu = dma_alloc_coherent(&pdev->dev, SZ_4K, > &dsi->cmd_axi_dma, > + GFP_KERNEL | GFP_DMA32); I think setting the DMA mask for the device is preferred over using GFP_DMA32. > + if (!dsi->cmd_axi_cpu) { > + return dev_err_probe(&pdev->dev, -ENOMEM, > + "Failed to allocate DSI AXI Access command > buffer\n"); > + } No need for curly braces. > + > ret = rcar_mipi_dsi_parse_dt(dsi); The allocated memory is leaking in error paths. > if (ret < 0) > return ret; > @@ -1309,6 +1335,8 @@ static void rcar_mipi_dsi_remove(struct platform_device > *pdev) > { > struct rcar_mipi_dsi *dsi = platform_get_drvdata(pdev); > > + dma_free_coherent(&pdev->dev, SZ_4K, dsi->cmd_axi_cpu, > dsi->cmd_axi_dma); > + > mipi_dsi_host_unregister(&dsi->host); > } > -- Regards, Laurent Pinchart
