> -----Original Message----- > From: Hugo Villeneuve <hvillene...@dimonoff.com> > Sent: 05 June 2025 14:38 > To: Biju Das <biju.das...@bp.renesas.com>; Hugo Villeneuve <h...@hugovil.com>; > maarten.lankho...@linux.intel.com; mrip...@kernel.org; tzimmerm...@suse.de; > airl...@gmail.com; > sim...@ffwll.ch > Cc: dri-devel@lists.freedesktop.org; linux-renesas-...@vger.kernel.org; > linux-ker...@vger.kernel.org; > Chris Brandt <chris.bra...@renesas.com> > Subject: Re: [PATCH v4 1/1] drm: renesas: rz-du: Implement MIPI DSI host > transfers > > On 6/5/25 04:18, Biju Das wrote: > > Hi Hugo, > > > > Thanks for the patch. > > > >> -----Original Message----- > >> From: dri-devel <dri-devel-boun...@lists.freedesktop.org> On Behalf > >> Of Hugo Villeneuve > >> Sent: 04 June 2025 15:53 > >> Subject: [PATCH v4 1/1] drm: renesas: rz-du: Implement MIPI DSI host > >> transfers > >> > >> From: Hugo Villeneuve <hvillene...@dimonoff.com> > >> > >> Add support for sending MIPI DSI command packets from the host to a > >> peripheral. This is required for panels that need configuration before > >> they accept video data. > >> > >> Also for long reads to work properly, set DCS maximum return packet > >> size to the value of the DMA buffer size. > >> > >> Based on Renesas Linux kernel v5.10 repos [1]. > >> > >> Link: https://github.com/renesas-rz/rz_linux-cip.git > >> Cc: Biju Das <biju.das...@bp.renesas.com> > >> Signed-off-by: Hugo Villeneuve <hvillene...@dimonoff.com> > > > > Reviewed-by: Biju Das <biju.das...@bp.renesas.com> > > > > FYI, Checkpatch is complaining about duplicate signature. > > I can fix this while applying,if there are no more comments for this patch. > > > > I am seeing below duplicate tags with your patch now. > > > > Signed-off-by: Hugo Villeneuve <hvillene...@dimonoff.com> > > Tested-by: Chris Brandt <chris.bra...@renesas.com> > > Signed-off-by: Hugo Villeneuve <hvillene...@dimonoff.com> > > > > $ scripts/checkpatch.pl --strict > > 0001-drm-renesas-rz-du-Implement-MIPI-DSI-host-transfers.patch > > WARNING: Duplicate signature > > #19: > > Signed-off-by: Hugo Villeneuve <hvillene...@dimonoff.com> > > Hi Biju, > I don't know how this is possible, considering that the patch I sent > (https://lore.kernel.org/all/20250604145306.1170676-2-h...@hugovil.com/) > has only this: > > --------------- > Link: https://github.com/renesas-rz/rz_linux-cip.git > Cc: Biju Das <biju.das...@bp.renesas.com> > Signed-off-by: Hugo Villeneuve <hvillene...@dimonoff.com> > --------------- > > > > total: 0 errors, 1 warnings, 0 checks, 306 lines checked > > > > NOTE: For some of the reported defects, checkpatch may be able to > > mechanically convert to the typical style using --fix or > > --fix-inplace. > > > > 0001-drm-renesas-rz-du-Implement-MIPI-DSI-host-transfers.patch has style > > problems, please review. > > > > NOTE: If any of the errors are false positives, please report > > them to the maintainer, see CHECKPATCH in MAINTAINERS. > > > > > >> --- > >> .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 186 ++++++++++++++++++ > >> .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h | 54 +++++ > >> 2 files changed, 240 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > >> b/drivers/gpu/drm/renesas/rz- du/rzg2l_mipi_dsi.c index > >> 91e1a9adad7d6..50ec109aa6ed3 100644 > >> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > >> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > >> @@ -4,8 +4,11 @@ > >> * > >> * Copyright (C) 2022 Renesas Electronics Corporation > >> */ > >> + > > > > Normally, changes like this should reflect in commit message. > > This is linked to the new #include, so this is why I didn't add a separate > changelog entry...
My Bad. I overlooked this. Cheers, Biju > > > > > > Cheers, > > Biju > > > >> +#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/module.h> > >> @@ -23,9 +26,12 @@ > >> #include <drm/drm_of.h> > >> #include <drm/drm_panel.h> > >> #include <drm/drm_probe_helper.h> > >> +#include <video/mipi_display.h> > >> > >> #include "rzg2l_mipi_dsi_regs.h" > >> > >> +#define RZG2L_DCS_BUF_SIZE 128 /* Maximum DCS buffer size in > >> external memory. */ > >> + > >> struct rzg2l_mipi_dsi { > >> struct device *dev; > >> void __iomem *mmio; > >> @@ -44,6 +50,10 @@ struct rzg2l_mipi_dsi { > >> unsigned int num_data_lanes; > >> unsigned int lanes; > >> unsigned long mode_flags; > >> + > >> + /* DCS buffer pointers when using external memory. */ > >> + dma_addr_t dcs_buf_phys; > >> + u8 *dcs_buf_virt; > >> }; > >> > >> static inline struct rzg2l_mipi_dsi * @@ -267,6 +277,7 @@ static > >> int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, > >> u32 clkbfht; > >> u32 clkstpt; > >> u32 golpbkt; > >> + u32 dsisetr; > >> int ret; > >> > >> /* > >> @@ -328,6 +339,15 @@ static int rzg2l_mipi_dsi_startup(struct > >> rzg2l_mipi_dsi *dsi, > >> lptrnstsetr = LPTRNSTSETR_GOLPBKT(golpbkt); > >> rzg2l_mipi_dsi_link_write(dsi, LPTRNSTSETR, lptrnstsetr); > >> > >> + /* > >> + * Increase MRPSZ as the default value of 1 will result in long read > >> + * commands payload not being saved to memory. > >> + */ > >> + dsisetr = rzg2l_mipi_dsi_link_read(dsi, DSISETR); > >> + dsisetr &= ~DSISETR_MRPSZ; > >> + dsisetr |= FIELD_PREP(DSISETR_MRPSZ, RZG2L_DCS_BUF_SIZE); > >> + rzg2l_mipi_dsi_link_write(dsi, DSISETR, dsisetr); > >> + > >> return 0; > >> > >> err_phy: > >> @@ -659,9 +679,168 @@ static int rzg2l_mipi_dsi_host_detach(struct > >> mipi_dsi_host *host, > >> return 0; > >> } > >> > >> +static ssize_t rzg2l_mipi_dsi_read_response(struct rzg2l_mipi_dsi *dsi, > >> + const struct mipi_dsi_msg *msg) { > >> + u8 *msg_rx = msg->rx_buf; > >> + u8 datatype; > >> + u32 result; > >> + u16 size; > >> + > >> + result = rzg2l_mipi_dsi_link_read(dsi, RXRSS0R); > >> + if (result & RXRSS0R_RXPKTDFAIL) { > >> + dev_err(dsi->dev, "packet rx data did not save correctly\n"); > >> + return -EPROTO; > >> + } > >> + > >> + if (result & RXRSS0R_RXFAIL) { > >> + dev_err(dsi->dev, "packet rx failure\n"); > >> + return -EPROTO; > >> + } > >> + > >> + if (!(result & RXRSS0R_RXSUC)) > >> + return -EPROTO; > >> + > >> + datatype = FIELD_GET(RXRSS0R_DT, result); > >> + > >> + switch (datatype) { > >> + case 0: > >> + dev_dbg(dsi->dev, "ACK\n"); > >> + return 0; > >> + case MIPI_DSI_RX_END_OF_TRANSMISSION: > >> + dev_dbg(dsi->dev, "EoTp\n"); > >> + return 0; > >> + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: > >> + dev_dbg(dsi->dev, "Acknowledge and error report: $%02x%02x\n", > >> + (u8)FIELD_GET(RXRSS0R_DATA1, result), > >> + (u8)FIELD_GET(RXRSS0R_DATA0, result)); > >> + return 0; > >> + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: > >> + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: > >> + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); > >> + return 1; > >> + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE: > >> + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: > >> + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); > >> + msg_rx[1] = FIELD_GET(RXRSS0R_DATA1, result); > >> + return 2; > >> + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE: > >> + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE: > >> + size = FIELD_GET(RXRSS0R_WC, result); > >> + > >> + if (size > msg->rx_len) { > >> + dev_err(dsi->dev, "rx buffer too small"); > >> + return -ENOSPC; > >> + } > >> + > >> + memcpy(msg_rx, dsi->dcs_buf_virt, size); > >> + return size; > >> + default: > >> + dev_err(dsi->dev, "unhandled response type: %02x\n", datatype); > >> + return -EPROTO; > >> + } > >> +} > >> + > >> +static ssize_t rzg2l_mipi_dsi_host_transfer(struct mipi_dsi_host *host, > >> + const struct mipi_dsi_msg *msg) { > >> + struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host); > >> + struct mipi_dsi_packet packet; > >> + bool need_bta; > >> + u32 value; > >> + int ret; > >> + > >> + ret = mipi_dsi_create_packet(&packet, msg); > >> + if (ret < 0) > >> + return ret; > >> + > >> + /* Terminate operation after this descriptor is finished */ > >> + value = SQCH0DSC0AR_NXACT_TERM; > >> + > >> + if (msg->flags & MIPI_DSI_MSG_REQ_ACK) { > >> + need_bta = true; /* Message with explicitly requested ACK */ > >> + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NON_READ); > >> + } else if (msg->rx_buf && msg->rx_len > 0) { > >> + need_bta = true; /* Read request */ > >> + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_READ); > >> + } else { > >> + need_bta = false; > >> + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NONE); > >> + } > >> + > >> + /* Set transmission speed */ > >> + if (msg->flags & MIPI_DSI_MSG_USE_LPM) > >> + value |= SQCH0DSC0AR_SPD_LOW; > >> + else > >> + value |= SQCH0DSC0AR_SPD_HIGH; > >> + > >> + /* Write TX packet header */ > >> + value |= FIELD_PREP(SQCH0DSC0AR_DT, packet.header[0]) | > >> + FIELD_PREP(SQCH0DSC0AR_DATA0, packet.header[1]) | > >> + FIELD_PREP(SQCH0DSC0AR_DATA1, packet.header[2]); > >> + > >> + if (mipi_dsi_packet_format_is_long(msg->type)) { > >> + value |= SQCH0DSC0AR_FMT_LONG; > >> + > >> + if (packet.payload_length > RZG2L_DCS_BUF_SIZE) { > >> + dev_err(dsi->dev, "Packet Tx payload size (%d) too > >> large", > >> + (unsigned int)packet.payload_length); > >> + return -ENOSPC; > >> + } > >> + > >> + /* Copy TX packet payload data to memory space */ > >> + memcpy(dsi->dcs_buf_virt, packet.payload, > >> packet.payload_length); > >> + } else { > >> + value |= SQCH0DSC0AR_FMT_SHORT; > >> + } > >> + > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0AR, value); > >> + > >> + /* > >> + * Write: specify payload data source location, only used for > >> + * long packet. > >> + * Read: specify payload data storage location of response > >> + * packet. Note: a read packet is always a short packet. > >> + * If the response packet is a short packet or a long packet > >> + * with WC = 0 (no payload), DTSEL is meaningless. > >> + */ > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0BR, > >> +SQCH0DSC0BR_DTSEL_MEM_SPACE); > >> + > >> + /* > >> + * Set SQCHxSR.AACTFIN bit when descriptor actions are finished. > >> + * Read: set Rx result save slot number to 0 (ACTCODE). > >> + */ > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0CR, SQCH0DSC0CR_FINACT); > >> + > >> + /* Set rx/tx payload data address, only relevant for long packet. */ > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0DR, > >> +(u32)dsi->dcs_buf_phys); > >> + > >> + /* Start sequence 0 operation */ > >> + value = rzg2l_mipi_dsi_link_read(dsi, SQCH0SET0R); > >> + value |= SQCH0SET0R_START; > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0SET0R, value); > >> + > >> + /* Wait for operation to finish */ > >> + ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, > >> + value, value & SQCH0SR_ADESFIN, > >> + 2000, 20000, false, dsi, SQCH0SR); > >> + if (ret == 0) { > >> + /* Success: clear status bit */ > >> + rzg2l_mipi_dsi_link_write(dsi, SQCH0SCR, SQCH0SCR_ADESFIN); > >> + > >> + if (need_bta) > >> + ret = rzg2l_mipi_dsi_read_response(dsi, msg); > >> + else > >> + ret = packet.payload_length; > >> + } > >> + > >> + return ret; > >> +} > >> + > >> static const struct mipi_dsi_host_ops rzg2l_mipi_dsi_host_ops = { > >> .attach = rzg2l_mipi_dsi_host_attach, > >> .detach = rzg2l_mipi_dsi_host_detach, > >> + .transfer = rzg2l_mipi_dsi_host_transfer, > >> }; > >> > >> /* > >> --------------------------------------------------------------------- > >> -------- @@ -779,6 +958,11 @@ static int rzg2l_mipi_dsi_probe(struct > >> platform_device *pdev) > >> if (ret < 0) > >> goto err_pm_disable; > >> > >> + dsi->dcs_buf_virt = dma_alloc_coherent(dsi->host.dev, > >> RZG2L_DCS_BUF_SIZE, > >> + &dsi->dcs_buf_phys, GFP_KERNEL); > >> + if (!dsi->dcs_buf_virt) > >> + return -ENOMEM; > >> + > >> return 0; > >> > >> err_phy: > >> @@ -793,6 +977,8 @@ static void rzg2l_mipi_dsi_remove(struct > >> platform_device *pdev) { > >> struct rzg2l_mipi_dsi *dsi = platform_get_drvdata(pdev); > >> > >> + dma_free_coherent(dsi->host.dev, RZG2L_DCS_BUF_SIZE, dsi->dcs_buf_virt, > >> + dsi->dcs_buf_phys); > >> mipi_dsi_host_unregister(&dsi->host); > >> pm_runtime_disable(&pdev->dev); > >> } > >> diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h > >> b/drivers/gpu/drm/renesas/rz- du/rzg2l_mipi_dsi_regs.h index > >> 1dbc16ec64a4b..26d8a37ee6351 100644 > >> --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h > >> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h > >> @@ -81,6 +81,20 @@ > >> #define RSTSR_SWRSTLP (1 << 1) > >> #define RSTSR_SWRSTHS (1 << 0) > >> > >> +/* DSI Set Register */ > >> +#define DSISETR 0x120 > >> +#define DSISETR_MRPSZ GENMASK(15, 0) > >> + > >> +/* Rx Result Save Slot 0 Register */ > >> +#define RXRSS0R 0x240 > >> +#define RXRSS0R_RXPKTDFAIL BIT(28) > >> +#define RXRSS0R_RXFAIL BIT(27) > >> +#define RXRSS0R_RXSUC BIT(25) > >> +#define RXRSS0R_DT GENMASK(21, 16) > >> +#define RXRSS0R_DATA1 GENMASK(15, 8) > >> +#define RXRSS0R_DATA0 GENMASK(7, 0) > >> +#define RXRSS0R_WC GENMASK(15, 0) /* Word count > >> for long packet. */ > >> + > >> /* Clock Lane Stop Time Set Register */ > >> #define CLSTPTSETR 0x314 > >> #define CLSTPTSETR_CLKKPT(x) ((x) << 24) > >> @@ -148,4 +162,44 @@ > >> #define VICH1HPSETR_HFP(x) (((x) & 0x1fff) << 16) > >> #define VICH1HPSETR_HBP(x) (((x) & 0x1fff) << 0) > >> > >> +/* Sequence Channel 0 Set 0 Register */ > >> +#define SQCH0SET0R 0x5c0 > >> +#define SQCH0SET0R_START BIT(0) > >> + > >> +/* Sequence Channel 0 Status Register */ > >> +#define SQCH0SR 0x5d0 > >> +#define SQCH0SR_ADESFIN BIT(8) > >> + > >> +/* Sequence Channel 0 Status Clear Register */ > >> +#define SQCH0SCR 0x5d4 > >> +#define SQCH0SCR_ADESFIN BIT(8) > >> + > >> +/* Sequence Channel 0 Descriptor 0-A Register */ > >> +#define SQCH0DSC0AR 0x780 > >> +#define SQCH0DSC0AR_NXACT_TERM 0 /* Bit 28 */ > >> +#define SQCH0DSC0AR_BTA GENMASK(27, 26) > >> +#define SQCH0DSC0AR_BTA_NONE 0 > >> +#define SQCH0DSC0AR_BTA_NON_READ 1 > >> +#define SQCH0DSC0AR_BTA_READ 2 > >> +#define SQCH0DSC0AR_BTA_ONLY 3 > >> +#define SQCH0DSC0AR_SPD_HIGH 0 > >> +#define SQCH0DSC0AR_SPD_LOW BIT(25) > >> +#define SQCH0DSC0AR_FMT_SHORT 0 > >> +#define SQCH0DSC0AR_FMT_LONG BIT(24) > >> +#define SQCH0DSC0AR_DT GENMASK(21, 16) > >> +#define SQCH0DSC0AR_DATA1 GENMASK(15, 8) > >> +#define SQCH0DSC0AR_DATA0 GENMASK(7, 0) > >> + > >> +/* Sequence Channel 0 Descriptor 0-B Register */ > >> +#define SQCH0DSC0BR 0x784 > >> +#define SQCH0DSC0BR_DTSEL_MEM_SPACE BIT(24) /* Use external memory > >> */ > >> + > >> +/* Sequence Channel 0 Descriptor 0-C Register */ > >> +#define SQCH0DSC0CR 0x788 > >> +#define SQCH0DSC0CR_FINACT BIT(0) > >> +#define SQCH0DSC0CR_AUXOP BIT(22) > >> + > >> +/* Sequence Channel 0 Descriptor 0-D Register */ > >> +#define SQCH0DSC0DR 0x78c > >> + > >> #endif /* __RZG2L_MIPI_DSI_REGS_H__ */ > >> -- > >> 2.39.5 > >