public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: phucduc.bui@gmail.com
To: phucduc.bui@gmail.com
Cc: airlied@gmail.com, dri-devel@lists.freedesktop.org,
	geert+renesas@glider.be, laurent.pinchart@ideasonboard.com,
	linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	maarten.lankhorst@linux.intel.com, mripard@kernel.org,
	simona@ffwll.ch, tzimmermann@suse.de
Subject: [PATCH v2] drm: shmobile: Fix blank screen after resume when LCDC is stopped
Date: Thu, 26 Feb 2026 12:40:35 +0700	[thread overview]
Message-ID: <20260226054035.30330-1-phucduc.bui@gmail.com> (raw)
In-Reply-To: <20260226051338.27460-1-phucduc.bui@gmail.com>

From: bui duc phuc <phucduc.bui@gmail.com>

The LCDC controller on R8A7740 loses its register state during
deep sleep. Upon resume, the driver's Mirror Register mechanism
(MRS) fails to update active registers because the controller is
stopped (DO=0).

According to the datasheet (Section 38.7.1, Figure 38.13), the
Two-Set Register Switching logic only triggers a change between
Set A and Set B when a Frame End Interrupt occurs at the
completion of a display frame. During resume, as the LCDC is
stopped, no frame is processed and no Frame End pulse is
generated. This leaves the Display Data Start Address (SA)
pending in the standby set, while the active register (Side A)
remains at 0x00000000, preventing the display engine from
starting.Debug logs collected during resume confirm this
behavior, showing the start address written to the standby set
while the active register remains unchanged.

Prime both register sets when the LCDC is stopped:

    If DO=0: Use lcdc_write() to force the Start Address (SA)
    into both Set A and Set B registers. This bypasses the
    switching logic and ensures the engine has a valid base
    address immediately upon being enabled.

    If DO=1: Maintain the standard Mirror mechanism and MRS
    toggle for normal, tear-free operation.

Verified on R8A7740.

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---

Changes in v2:
 - Fix incorrect use of lcdc_write_mirror() for LDSA2R in
   the DO=0 path; use lcdc_write() to update both register
   sets as intended.

 .../gpu/drm/renesas/shmobile/shmob_drm_plane.c  | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 9d166ab2af8b..6371bdc2371a 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -70,6 +70,7 @@ static void shmob_drm_primary_plane_setup(struct shmob_drm_plane *splane,
 	struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
 	struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
 	struct drm_framebuffer *fb = state->fb;
+	u32 ldcnt2r;
 
 	/* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
 	lcdc_write(sdev, LDDFR, sstate->format->lddfr | LDDFR_CF1);
@@ -78,11 +79,19 @@ static void shmob_drm_primary_plane_setup(struct shmob_drm_plane *splane,
 	/* Word and long word swap. */
 	lcdc_write(sdev, LDDDSR, sstate->format->ldddsr);
 
-	lcdc_write_mirror(sdev, LDSA1R, sstate->dma[0]);
-	if (shmob_drm_format_is_yuv(sstate->format))
-		lcdc_write_mirror(sdev, LDSA2R, sstate->dma[1]);
+	ldcnt2r = lcdc_read(sdev, LDCNT2R);
+
+	if (ldcnt2r & LDCNT2R_DO) {
+		lcdc_write_mirror(sdev, LDSA1R, sstate->dma[0]);
+		if (shmob_drm_format_is_yuv(sstate->format))
+			lcdc_write_mirror(sdev, LDSA2R, sstate->dma[1]);
 
-	lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
+		lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
+	} else {
+		lcdc_write(sdev, LDSA1R, sstate->dma[0]);
+		if (shmob_drm_format_is_yuv(sstate->format))
+			lcdc_write(sdev, LDSA2R, sstate->dma[1]);
+	}
 }
 
 static void shmob_drm_overlay_plane_setup(struct shmob_drm_plane *splane,
-- 
2.43.0


  reply	other threads:[~2026-02-26  5:40 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-26  5:13 [PATCH] drm: shmobile: Fix blank screen after resume when LCDC is stopped phucduc.bui
2026-02-26  5:40 ` phucduc.bui [this message]
2026-02-26  8:09   ` [PATCH v2] " Geert Uytterhoeven
2026-02-27  9:57     ` phucduc.bui
2026-03-13  8:37       ` Geert Uytterhoeven
2026-03-13  8:42         ` Geert Uytterhoeven
2026-03-16 11:25           ` phucduc.bui
2026-03-16 13:14             ` Geert Uytterhoeven
2026-03-17  7:17               ` [PATCH v2] drm: shmobile: Fix blank screen after resume when phucduc.bui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260226054035.30330-1-phucduc.bui@gmail.com \
    --to=phucduc.bui@gmail.com \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=geert+renesas@glider.be \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox