* [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-14 9:30 ` Pavel Machek
2026-04-13 17:18 ` [PATCH 6.1.y-cip 3/7] drm: renesas: rz-du: mipi_dsi: fix kernel panic when rebooting for some panels Chris Brandt
` (5 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
commit 6f392f37165008cfb3f89d723aa019e372ee79b9 upstream.
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
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Tested-by: Chris Brandt <Chris.Brandt@renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20250604145306.1170676-2-hugo@hugovil.com
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
.../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 f1ae7ecddbb2..4ee784f66037 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
@@ -4,9 +4,12 @@
*
* Copyright (C) 2022 Renesas Electronics Corporation
*/
+
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk/renesas.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/math.h>
@@ -27,11 +30,14 @@
#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"
MODULE_IMPORT_NS(RZV2H_CPG);
+#define RZG2L_DCS_BUF_SIZE 128 /* Maximum DCS buffer size in external memory. */
+
#define RZ_MIPI_DSI_FEATURE_16BPP BIT(0)
struct rzg2l_mipi_dsi;
@@ -84,6 +90,10 @@ struct rzg2l_mipi_dsi {
unsigned long mode_flags;
struct rzv2h_dsi_mode_calc mode_calc;
+
+ /* DCS buffer pointers when using external memory. */
+ dma_addr_t dcs_buf_phys;
+ u8 *dcs_buf_virt;
};
static const struct rzv2h_pll_limits rzv2h_plldsi_div_limits = {
@@ -739,6 +749,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
u32 clkbfht;
u32 clkstpt;
u32 golpbkt;
+ u32 dsisetr;
int ret;
ret = pm_runtime_resume_and_get(dsi->dev);
@@ -793,6 +804,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:
@@ -1148,9 +1168,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,
};
/* -----------------------------------------------------------------------------
@@ -1274,6 +1453,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:
@@ -1288,6 +1472,8 @@ static int 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 87963871cacd..2bef20566648 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
@@ -112,6 +112,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)
@@ -180,4 +194,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.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers
2026-04-13 17:18 ` [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers Chris Brandt
@ 2026-04-14 9:30 ` Pavel Machek
2026-04-14 11:33 ` Chris Brandt
0 siblings, 1 reply; 11+ messages in thread
From: Pavel Machek @ 2026-04-14 9:30 UTC (permalink / raw)
To: Chris Brandt; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
[-- Attachment #1: Type: text/plain, Size: 1463 bytes --]
Hi!
> commit 6f392f37165008cfb3f89d723aa019e372ee79b9 upstream.
>
> 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.
> Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
> +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> +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;
This probably should do dev_err or dev_dbg before returning.
> @@ -1274,6 +1453,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;
>
This probably should be { err = -ENOMEM; goto err_pm_disable; }
Thanks and best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread* RE: [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers
2026-04-14 9:30 ` Pavel Machek
@ 2026-04-14 11:33 ` Chris Brandt
2026-04-16 20:59 ` Pavel Machek
0 siblings, 1 reply; 11+ messages in thread
From: Chris Brandt @ 2026-04-14 11:33 UTC (permalink / raw)
To: Pavel Machek; +Cc: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu
Hi Pavel,
These patches are direct backports from mainline.
I am trying to keep the CIP version as close to the mainline version as possible.
> > + if (!(result & RXRSS0R_RXSUC))
> > + return -EPROTO;
>
> This probably should do dev_err or dev_dbg before returning.
Honestly, we are checking for this error, but I have never seen it actually happen in any system.
But, your point is valid because we are printing out messages for other errors.
> > + 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;
> >
>
> This probably should be { err = -ENOMEM; goto err_pm_disable; }
That is a good point.
I wrote that part of the driver for an older version of the kernel a couple years ago before they had those return options.
Then, someone else ported it to the mainline version of the driver and submitted it.
When I reviewed the mainline version, I didn't catch that.
I might push a fix to mainline with CC:stable.
Chris
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers
2026-04-14 11:33 ` Chris Brandt
@ 2026-04-16 20:59 ` Pavel Machek
0 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2026-04-16 20:59 UTC (permalink / raw)
To: Chris Brandt
Cc: Pavel Machek, cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu
[-- Attachment #1: Type: text/plain, Size: 954 bytes --]
Hi!
> These patches are direct backports from mainline.
> I am trying to keep the CIP version as close to the mainline version as possible.
Understood. You don't have to change these in -CIP, but consider
fixing them in mainline.
> > > + 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;
> > >
> >
> > This probably should be { err = -ENOMEM; goto err_pm_disable; }
>
> That is a good point.
> I wrote that part of the driver for an older version of the kernel a couple years ago before they had those return options.
> Then, someone else ported it to the mainline version of the driver and submitted it.
> When I reviewed the mainline version, I didn't catch that.
> I might push a fix to mainline with CC:stable.
>
Yes, please.
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 6.1.y-cip 3/7] drm: renesas: rz-du: mipi_dsi: fix kernel panic when rebooting for some panels
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 4/7] drm: renesas: rz-du: mipi_dsi: Set DSI divider Chris Brandt
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
commit 64aa8b3a60a825134f7d866adf05c024bbe0c24c upstream.
Since commit 56de5e305d4b ("clk: renesas: r9a07g044: Add MSTOP for RZ/G2L")
we may get the following kernel panic, for some panels, when rebooting:
systemd-shutdown[1]: Rebooting.
Call trace:
...
do_serror+0x28/0x68
el1h_64_error_handler+0x34/0x50
el1h_64_error+0x6c/0x70
rzg2l_mipi_dsi_host_transfer+0x114/0x458 (P)
mipi_dsi_device_transfer+0x44/0x58
mipi_dsi_dcs_set_display_off_multi+0x9c/0xc4
ili9881c_unprepare+0x38/0x88
drm_panel_unprepare+0xbc/0x108
This happens for panels that need to send MIPI-DSI commands in their
unprepare() callback. Since the MIPI-DSI interface is stopped at that
point, rzg2l_mipi_dsi_host_transfer() triggers the kernel panic.
Fix by moving rzg2l_mipi_dsi_stop() to new callback function
rzg2l_mipi_dsi_atomic_post_disable().
With this change we now have the correct power-down/stop sequence:
systemd-shutdown[1]: Rebooting.
rzg2l-mipi-dsi 10850000.dsi: rzg2l_mipi_dsi_atomic_disable(): entry
ili9881c-dsi 10850000.dsi.0: ili9881c_unprepare(): entry
rzg2l-mipi-dsi 10850000.dsi: rzg2l_mipi_dsi_atomic_post_disable(): entry
reboot: Restarting system
Suggested-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://patch.msgid.link/20260112154333.655352-1-hugo@hugovil.com
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 8 ++++++++
1 file changed, 8 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 4ee784f66037..d3aae2501b9e 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
@@ -1069,6 +1069,13 @@ static void rzg2l_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
rzg2l_mipi_dsi_stop_video(dsi);
rzg2l_mipi_dsi_stop_hs_clock(dsi);
+}
+
+static void rzg2l_mipi_dsi_atomic_post_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
+{
+ struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
+
rzg2l_mipi_dsi_stop(dsi);
}
@@ -1104,6 +1111,7 @@ static const struct drm_bridge_funcs rzg2l_mipi_dsi_bridge_ops = {
.atomic_pre_enable = rzg2l_mipi_dsi_atomic_pre_enable,
.atomic_enable = rzg2l_mipi_dsi_atomic_enable,
.atomic_disable = rzg2l_mipi_dsi_atomic_disable,
+ .atomic_post_disable = rzg2l_mipi_dsi_atomic_post_disable,
.mode_valid = rzg2l_mipi_dsi_bridge_mode_valid,
};
--
2.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6.1.y-cip 4/7] drm: renesas: rz-du: mipi_dsi: Set DSI divider
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 2/7] drm: renesas: rz-du: Implement MIPI DSI host transfers Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 3/7] drm: renesas: rz-du: mipi_dsi: fix kernel panic when rebooting for some panels Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 5/7] clk: renesas: Use IS_ERR() for pointers that cannot be NULL Chris Brandt
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
commit fb797a70108f3fda83fde6dea30bee4be7d5df8b upstream.
Before the MIPI DSI clock source can be configured, the target divide
ratio needs to be set.
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
Fixes: 5a4326f2e3b1 ("clk: renesas: rzg2l: Remove DSI clock rate restrictions")
Link: https://patch.msgid.link/20260227015216.2721504-1-chris.brandt@renesas.com
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
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 d3aae2501b9e..bb56548fafa1 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
@@ -1123,6 +1123,7 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device)
{
struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host);
+ int bpp;
int ret;
if (device->lanes > dsi->num_data_lanes) {
@@ -1132,7 +1133,8 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host,
return -EINVAL;
}
- switch (mipi_dsi_pixel_format_to_bpp(device->format)) {
+ bpp = mipi_dsi_pixel_format_to_bpp(device->format);
+ switch (bpp) {
case 24:
break;
case 18:
@@ -1163,6 +1165,18 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host,
drm_bridge_add(&dsi->bridge);
+ /*
+ * Report the required division ratio setting for the MIPI clock dividers.
+ *
+ * vclk * bpp = hsclk * 8 * num_lanes
+ *
+ * vclk * DSI_AB_divider = hsclk * 16
+ *
+ * which simplifies to...
+ * DSI_AB_divider = bpp * 2 / num_lanes
+ */
+ rzg2l_cpg_dsi_div_set_divider(bpp * 2 / dsi->lanes, PLL5_TARGET_DSI);
+
return 0;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6.1.y-cip 5/7] clk: renesas: Use IS_ERR() for pointers that cannot be NULL
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
` (2 preceding siblings ...)
2026-04-13 17:18 ` [PATCH 6.1.y-cip 4/7] drm: renesas: rz-du: mipi_dsi: Set DSI divider Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 6/7] clk: renesas: rzg2l: Remove DSI clock rate restrictions Chris Brandt
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
From: Geert Uytterhoeven <geert+renesas@glider.be>
commit 6a636d203cc8d29ae73116bbca8b0ea2c7a90d7f upstream.
The use of IS_ERR_OR_NULL() suggests that "clk" can be a NULL pointer.
Hence smatch assumes so, and issues a "passing zero to 'PTR_ERR'"
warning.
At these checkpoints, "clk" always contains either a valid pointer, or
an error pointer (none of the functions called return NULL pointers).
Hence replace IS_ERR_OR_NULL() by IS_ERR().
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/r/202408032025.ve2JMaoV-lkp@intel.com/
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Link: https://patch.msgid.link/81260328acb5c78e915ab04afad3901a31c16128.1758793709.git.geert+renesas@glider.be
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
drivers/clk/renesas/renesas-cpg-mssr.c | 2 +-
drivers/clk/renesas/rzg2l-cpg.c | 2 +-
drivers/clk/renesas/rzv2h-cpg.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 5cd3069181fd..80bfc225b31b 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -394,7 +394,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
break;
}
- if (IS_ERR_OR_NULL(clk))
+ if (IS_ERR(clk))
goto fail;
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 27e1432d726a..847f5ed51dc7 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -1185,7 +1185,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
goto fail;
}
- if (IS_ERR_OR_NULL(clk))
+ if (IS_ERR(clk))
goto fail;
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 5f1fcc4f4f65..2e11c0c9591a 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -1099,7 +1099,7 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
goto fail;
}
- if (IS_ERR_OR_NULL(clk))
+ if (IS_ERR(clk))
goto fail;
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
--
2.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6.1.y-cip 6/7] clk: renesas: rzg2l: Remove DSI clock rate restrictions
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
` (3 preceding siblings ...)
2026-04-13 17:18 ` [PATCH 6.1.y-cip 5/7] clk: renesas: Use IS_ERR() for pointers that cannot be NULL Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-13 17:18 ` [PATCH 6.1.y-cip 7/7] clk: renesas: Add missing log message terminators Chris Brandt
2026-04-16 20:57 ` [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Pavel Machek
6 siblings, 0 replies; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
commit 5a4326f2e3b1edfb3329c1bee59035dc9f048b59 upstream.
Convert the limited MIPI clock calculations to a full range of settings
based on math including H/W limitation validation.
Since the required DSI division setting must be specified from external
sources before calculations, expose a new API to set it.
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Tested-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20251124131003.992554-2-chris.brandt@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
drivers/clk/renesas/rzg2l-cpg.c | 174 ++++++++++++++++++++++++++------
include/linux/clk/renesas.h | 11 ++
2 files changed, 154 insertions(+), 31 deletions(-)
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 847f5ed51dc7..8a9e55d0974d 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/iopoll.h>
+#include <linux/math64.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_address.h>
@@ -75,6 +76,17 @@
#define MSTOP_OFF(conf) FIELD_GET(GENMASK(31, 16), (conf))
#define MSTOP_MASK(conf) FIELD_GET(GENMASK(15, 0), (conf))
+#define PLL5_FOUTVCO_MIN 800000000
+#define PLL5_FOUTVCO_MAX 3000000000
+#define PLL5_POSTDIV_MIN 1
+#define PLL5_POSTDIV_MAX 7
+#define PLL5_REFDIV_MIN 1
+#define PLL5_REFDIV_MAX 2
+#define PLL5_INTIN_MIN 20
+#define PLL5_INTIN_MAX 320
+#define PLL5_HSCLK_MIN 10000000
+#define PLL5_HSCLK_MAX 187500000
+
/**
* struct clk_hw_data - clock hardware data
* @hw: clock hw
@@ -130,6 +142,12 @@ struct rzg2l_pll5_param {
u8 pl5_spread;
};
+/* PLL5 output will be used for DPI or MIPI-DSI */
+static int dsi_div_target = PLL5_TARGET_DPI;
+
+/* Required division ratio for MIPI D-PHY clock depending on number of lanes and bpp. */
+static u8 dsi_div_ab_desired;
+
struct rzg2l_pll5_mux_dsi_div_param {
u8 clksrc;
u8 dsi_div_a;
@@ -171,6 +189,11 @@ struct rzg2l_cpg_priv {
struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params;
};
+static inline u8 rzg2l_cpg_div_ab(u8 a, u8 b)
+{
+ return (b + 1) << a;
+}
+
static void rzg2l_cpg_del_clk_provider(void *data)
{
of_clk_del_provider(data);
@@ -561,24 +584,121 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core,
return clk_hw->clk;
}
+/*
+ * VCO-->[POSTDIV1,2]--FOUTPOSTDIV--------------->|
+ * | |-->[1/(DSI DIV A * B)]--> MIPI_DSI_VCLK
+ * |-->[1/2]--FOUT1PH0-->|
+ * |
+ * |------->[1/16]--------------------------------> hsclk (MIPI-PHY)
+ */
static unsigned long
-rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
+rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_cpg_priv *priv,
+ struct rzg2l_pll5_param *params,
unsigned long rate)
{
- unsigned long foutpostdiv_rate, foutvco_rate;
+ const u32 extal_hz = EXTAL_FREQ_IN_MEGA_HZ * MEGA;
+ unsigned long foutpostdiv_rate;
+ unsigned int a, b, odd;
+ unsigned long hsclk;
+ u8 dsi_div_ab_calc;
+ u64 foutvco_rate;
+
+ if (dsi_div_target == PLL5_TARGET_DSI) {
+ /* Check hsclk */
+ hsclk = rate * dsi_div_ab_desired / 16;
+ if (hsclk < PLL5_HSCLK_MIN || hsclk > PLL5_HSCLK_MAX) {
+ dev_err(priv->dev, "hsclk out of range\n");
+ return 0;
+ }
+
+ /* Determine the correct clock source based on even/odd of the divider */
+ odd = dsi_div_ab_desired & 1;
+ if (odd) {
+ priv->mux_dsi_div_params.clksrc = 0; /* FOUTPOSTDIV */
+ dsi_div_ab_calc = dsi_div_ab_desired;
+ } else {
+ priv->mux_dsi_div_params.clksrc = 1; /* FOUT1PH0 */
+ dsi_div_ab_calc = dsi_div_ab_desired / 2;
+ }
+
+ /* Calculate the DIV_DSI_A and DIV_DSI_B based on the desired divider */
+ for (a = 0; a < 4; a++) {
+ /* FOUT1PH0: Max output of DIV_DSI_A is 750MHz so at least 1/2 to be safe */
+ if (!odd && a == 0)
+ continue;
+
+ /* FOUTPOSTDIV: DIV_DSI_A must always be 1/1 */
+ if (odd && a != 0)
+ break;
+
+ for (b = 0; b < 16; b++) {
+ /* FOUTPOSTDIV: DIV_DSI_B must always be odd divider 1/(b+1) */
+ if (odd && b & 1)
+ continue;
+
+ if (rzg2l_cpg_div_ab(a, b) == dsi_div_ab_calc) {
+ priv->mux_dsi_div_params.dsi_div_a = a;
+ priv->mux_dsi_div_params.dsi_div_b = b;
+ goto calc_pll_clk;
+ }
+ }
+ }
+
+ dev_err(priv->dev, "Failed to calculate DIV_DSI_A,B\n");
+
+ return 0;
+ } else if (dsi_div_target == PLL5_TARGET_DPI) {
+ /* Fixed settings for DPI */
+ priv->mux_dsi_div_params.clksrc = 0;
+ priv->mux_dsi_div_params.dsi_div_a = 3; /* Divided by 8 */
+ priv->mux_dsi_div_params.dsi_div_b = 0; /* Divided by 1 */
+ dsi_div_ab_desired = rzg2l_cpg_div_ab(priv->mux_dsi_div_params.dsi_div_a,
+ priv->mux_dsi_div_params.dsi_div_b);
+ }
+
+calc_pll_clk:
+ /* PLL5 (MIPI_DSI_PLLCLK) = VCO / POSTDIV1 / POSTDIV2 */
+ for (params->pl5_postdiv1 = PLL5_POSTDIV_MIN;
+ params->pl5_postdiv1 <= PLL5_POSTDIV_MAX;
+ params->pl5_postdiv1++) {
+ for (params->pl5_postdiv2 = PLL5_POSTDIV_MIN;
+ params->pl5_postdiv2 <= PLL5_POSTDIV_MAX;
+ params->pl5_postdiv2++) {
+ foutvco_rate = rate * params->pl5_postdiv1 * params->pl5_postdiv2 *
+ dsi_div_ab_desired;
+ if (foutvco_rate <= PLL5_FOUTVCO_MIN || foutvco_rate >= PLL5_FOUTVCO_MAX)
+ continue;
+
+ for (params->pl5_refdiv = PLL5_REFDIV_MIN;
+ params->pl5_refdiv <= PLL5_REFDIV_MAX;
+ params->pl5_refdiv++) {
+ u32 rem;
+
+ params->pl5_intin = div_u64_rem(foutvco_rate * params->pl5_refdiv,
+ extal_hz, &rem);
+
+ if (params->pl5_intin < PLL5_INTIN_MIN ||
+ params->pl5_intin > PLL5_INTIN_MAX)
+ continue;
+
+ params->pl5_fracin = div_u64((u64)rem << 24, extal_hz);
+
+ goto clk_valid;
+ }
+ }
+ }
- params->pl5_intin = rate / MEGA;
- params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);
- params->pl5_refdiv = 2;
- params->pl5_postdiv1 = 1;
- params->pl5_postdiv2 = 1;
+ dev_err(priv->dev, "Failed to calculate PLL5 settings\n");
+ return 0;
+
+clk_valid:
params->pl5_spread = 0x16;
foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA,
(params->pl5_intin << 24) + params->pl5_fracin),
params->pl5_refdiv) >> 24;
- foutpostdiv_rate = DIV_ROUND_CLOSEST(foutvco_rate,
- params->pl5_postdiv1 * params->pl5_postdiv2);
+ foutpostdiv_rate = DIV_U64_ROUND_CLOSEST(foutvco_rate,
+ params->pl5_postdiv1 * params->pl5_postdiv2);
return foutpostdiv_rate;
}
@@ -612,7 +732,7 @@ static unsigned long rzg2l_cpg_get_vclk_parent_rate(struct clk_hw *hw,
struct rzg2l_pll5_param params;
unsigned long parent_rate;
- parent_rate = rzg2l_cpg_get_foutpostdiv_rate(¶ms, rate);
+ parent_rate = rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, rate);
if (priv->mux_dsi_div_params.clksrc)
parent_rate /= 2;
@@ -628,9 +748,19 @@ static int rzg2l_cpg_dsi_div_determine_rate(struct clk_hw *hw,
req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate);
+ if (!req->best_parent_rate)
+ return -EINVAL;
+
return 0;
}
+void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target)
+{
+ dsi_div_ab_desired = divider;
+ dsi_div_target = target;
+}
+EXPORT_SYMBOL_GPL(rzg2l_cpg_dsi_div_set_divider);
+
static int rzg2l_cpg_dsi_div_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
@@ -802,22 +932,6 @@ struct sipll5 {
#define to_sipll5(_hw) container_of(_hw, struct sipll5, hw)
-static unsigned long rzg2l_cpg_get_vclk_rate(struct clk_hw *hw,
- unsigned long rate)
-{
- struct sipll5 *sipll5 = to_sipll5(hw);
- struct rzg2l_cpg_priv *priv = sipll5->priv;
- unsigned long vclk;
-
- vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) *
- (priv->mux_dsi_div_params.dsi_div_b + 1));
-
- if (priv->mux_dsi_div_params.clksrc)
- vclk /= 2;
-
- return vclk;
-}
-
static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
@@ -863,9 +977,9 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw,
if (!rate)
return -EINVAL;
- vclk_rate = rzg2l_cpg_get_vclk_rate(hw, rate);
+ vclk_rate = rate / dsi_div_ab_desired;
sipll5->foutpostdiv_rate =
- rzg2l_cpg_get_foutpostdiv_rate(¶ms, vclk_rate);
+ rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, vclk_rate);
/* Put PLL5 into standby mode */
writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY);
@@ -953,9 +1067,7 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core,
if (ret)
return ERR_PTR(ret);
- priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */
- priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */
- priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */
+ rzg2l_cpg_dsi_div_set_divider(8, PLL5_TARGET_DPI);
return clk_hw->clk;
}
diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h
index 69d8159deee3..c360df9fa735 100644
--- a/include/linux/clk/renesas.h
+++ b/include/linux/clk/renesas.h
@@ -35,6 +35,17 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev);
#define cpg_mssr_detach_dev NULL
#endif
+enum {
+ PLL5_TARGET_DPI,
+ PLL5_TARGET_DSI
+};
+
+#ifdef CONFIG_CLK_RZG2L
+void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target);
+#else
+static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { }
+#endif
+
/**
* struct rzv2h_pll_limits - PLL parameter constraints
*
--
2.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6.1.y-cip 7/7] clk: renesas: Add missing log message terminators
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
` (4 preceding siblings ...)
2026-04-13 17:18 ` [PATCH 6.1.y-cip 6/7] clk: renesas: rzg2l: Remove DSI clock rate restrictions Chris Brandt
@ 2026-04-13 17:18 ` Chris Brandt
2026-04-16 20:57 ` [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Pavel Machek
6 siblings, 0 replies; 11+ messages in thread
From: Chris Brandt @ 2026-04-13 17:18 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
From: Geert Uytterhoeven <geert+renesas@glider.be>
commit 4fef3fd633be4a1a18c490a63f4131284f6ee0f4 upstream.
Complete printed messages should be terminated by newline characters.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Link: https://patch.msgid.link/cd0b3624066b80ed0bb00d489c99e2c1a06d755f.1768480559.git.geert+renesas@glider.be
Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
drivers/clk/renesas/clk-vbattb.c | 4 ++--
drivers/clk/renesas/renesas-cpg-mssr.c | 2 +-
drivers/clk/renesas/rzg2l-cpg.c | 6 +++---
drivers/clk/renesas/rzv2h-cpg.c | 6 +++---
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/renesas/clk-vbattb.c b/drivers/clk/renesas/clk-vbattb.c
index ff9d1ead455c..2a961775b1d8 100644
--- a/drivers/clk/renesas/clk-vbattb.c
+++ b/drivers/clk/renesas/clk-vbattb.c
@@ -69,11 +69,11 @@ static void vbattb_clk_action(void *data)
ret = reset_control_assert(rstc);
if (ret)
- dev_err(dev, "Failed to de-assert reset!");
+ dev_err(dev, "Failed to de-assert reset!\n");
ret = pm_runtime_put_sync(dev);
if (ret < 0)
- dev_err(dev, "Failed to runtime suspend!");
+ dev_err(dev, "Failed to runtime suspend!\n");
of_clk_del_provider(dev->of_node);
}
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 80bfc225b31b..ec1877d7e44d 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -320,7 +320,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
}
if (IS_ERR(clk))
- dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
+ dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx,
PTR_ERR(clk));
else
dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 8a9e55d0974d..e8ea65446890 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -986,7 +986,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw,
ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val,
!(val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000);
if (ret) {
- dev_err(priv->dev, "failed to release pll5 lock");
+ dev_err(priv->dev, "failed to release pll5 lock\n");
return ret;
}
@@ -1013,7 +1013,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw,
ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val,
(val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000);
if (ret) {
- dev_err(priv->dev, "failed to lock pll5");
+ dev_err(priv->dev, "failed to lock pll5\n");
return ret;
}
@@ -1219,7 +1219,7 @@ static struct clk
}
if (IS_ERR(clk))
- dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
+ dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx,
PTR_ERR(clk));
else
dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 2e11c0c9591a..903000459160 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -602,7 +602,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk,
val, !(val & CPG_PLL_MON_LOCK),
100, 2000);
if (ret) {
- dev_err(priv->dev, "Failed to put PLLDSI into standby mode");
+ dev_err(priv->dev, "Failed to put PLLDSI into standby mode\n");
return ret;
}
@@ -630,7 +630,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk,
val, (val & CPG_PLL_MON_LOCK),
100, 2000);
if (ret) {
- dev_err(priv->dev, "Failed to put PLLDSI into normal mode");
+ dev_err(priv->dev, "Failed to put PLLDSI into normal mode\n");
return ret;
}
@@ -1023,7 +1023,7 @@ static struct clk
}
if (IS_ERR(clk))
- dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
+ dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx,
PTR_ERR(clk));
else
dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
--
2.52.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable
2026-04-13 17:18 [PATCH 6.1.y-cip 1/7] drm: renesas: rz-du: Add atomic_pre_enable Chris Brandt
` (5 preceding siblings ...)
2026-04-13 17:18 ` [PATCH 6.1.y-cip 7/7] clk: renesas: Add missing log message terminators Chris Brandt
@ 2026-04-16 20:57 ` Pavel Machek
6 siblings, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2026-04-16 20:57 UTC (permalink / raw)
To: Chris Brandt; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
[-- Attachment #1: Type: text/plain, Size: 662 bytes --]
Hi!
> commit 5ce16c169a4cb8ffceabfd48853d0bf605ce785a upstream.
>
> When drm_panel.prepare_prev_first is set to true in a panel driver, the
> panel expects the MIPI DSI hardware to be already configured before the
> panel's prepare function is called because it might need to send DCS
> commands.
For whole series: I had some minor comments here, but those should be
fixed in mainline, first, so they should not block the merge.
Reviewed-by: Pavel Machek <pavel@nabladev.com>
I can apply the series if it passes testing and there are no other
comments.
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread