linux-rockchip.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Samuel Holland <samuel@sholland.org>
To: "Heiko Stübner" <heiko@sntech.de>,
	"Sandy Huang" <hjc@rock-chips.com>,
	dri-devel@lists.freedesktop.org
Cc: linux-rockchip@lists.infradead.org,
	"Alistair Francis" <alistair@alistair23.me>,
	"Ondřej Jirman" <x@xff.cz>,
	"Andreas Kemnade" <andreas@kemnade.info>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"David Airlie" <airlied@linux.ie>,
	"Geert Uytterhoeven" <geert@linux-m68k.org>,
	"Samuel Holland" <samuel@sholland.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Liang Chen" <cl@rock-chips.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Michael Riesch" <michael.riesch@wolfvision.net>,
	"Nicolas Frattaroli" <frattaroli.nicolas@gmail.com>,
	"Peter Geis" <pgwipeout@gmail.com>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Sam Ravnborg" <sam@ravnborg.org>,
	"Thierry Reding" <thierry.reding@gmail.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 06/16] drm/rockchip: ebc: Add CRTC refresh thread
Date: Wed, 13 Apr 2022 17:19:06 -0500	[thread overview]
Message-ID: <20220413221916.50995-7-samuel@sholland.org> (raw)
In-Reply-To: <20220413221916.50995-1-samuel@sholland.org>

EPD refreshes are extremely slow; they take anywhere between hundreds of
milliseconds and several seconds. To avoid blocking userspace, perform
these refreshes on a separate thread. The thread will also take care of
initializing the display before first use and clearing it when the CRTC
is disabled.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

 drivers/gpu/drm/rockchip/rockchip_ebc.c | 82 ++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.c b/drivers/gpu/drm/rockchip/rockchip_ebc.c
index 5f9502313657..ebe60d5e011a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_ebc.c
+++ b/drivers/gpu/drm/rockchip/rockchip_ebc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/irq.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
@@ -135,9 +136,15 @@ struct rockchip_ebc {
 	struct drm_plane		plane;
 	struct regmap			*regmap;
 	struct regulator_bulk_data	supplies[EBC_NUM_SUPPLIES];
+	struct task_struct		*refresh_thread;
 	u32				dsp_start;
+	bool				reset_complete;
 };
 
+static bool skip_reset;
+module_param(skip_reset, bool, 0444);
+MODULE_PARM_DESC(skip_reset, "skip the initial display reset");
+
 DEFINE_DRM_GEM_FOPS(rockchip_ebc_fops);
 
 static const struct drm_driver rockchip_ebc_drm_driver = {
@@ -172,6 +179,42 @@ to_ebc_crtc_state(struct drm_crtc_state *crtc_state)
 	return container_of(crtc_state, struct ebc_crtc_state, base);
 }
 
+static int rockchip_ebc_refresh_thread(void *data)
+{
+	struct rockchip_ebc *ebc = data;
+
+	while (!kthread_should_stop()) {
+		/*
+		 * LUTs use both the old and the new pixel values as inputs.
+		 * However, the initial contents of the display are unknown.
+		 * The special RESET waveform will initialize the display to
+		 * known contents (white) regardless of its current contents.
+		 */
+		if (!ebc->reset_complete) {
+			ebc->reset_complete = true;
+			drm_dbg(&ebc->drm, "display reset\n");
+		}
+
+		while (!kthread_should_park()) {
+			drm_dbg(&ebc->drm, "display update\n");
+
+			set_current_state(TASK_IDLE);
+			schedule();
+			__set_current_state(TASK_RUNNING);
+		}
+
+		/*
+		 * Clear the display before disabling the CRTC. Use the
+		 * highest-quality waveform to minimize visible artifacts.
+		 */
+		drm_dbg(&ebc->drm, "display clear\n");
+
+		kthread_parkme();
+	}
+
+	return 0;
+}
+
 static inline struct rockchip_ebc *crtc_to_ebc(struct drm_crtc *crtc)
 {
 	return container_of(crtc, struct rockchip_ebc, crtc);
@@ -296,11 +339,23 @@ static void rockchip_ebc_crtc_atomic_flush(struct drm_crtc *crtc,
 static void rockchip_ebc_crtc_atomic_enable(struct drm_crtc *crtc,
 					    struct drm_atomic_state *state)
 {
+	struct rockchip_ebc *ebc = crtc_to_ebc(crtc);
+	struct drm_crtc_state *crtc_state;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (crtc_state->mode_changed)
+		kthread_unpark(ebc->refresh_thread);
 }
 
 static void rockchip_ebc_crtc_atomic_disable(struct drm_crtc *crtc,
 					     struct drm_atomic_state *state)
 {
+	struct rockchip_ebc *ebc = crtc_to_ebc(crtc);
+	struct drm_crtc_state *crtc_state;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (crtc_state->mode_changed)
+		kthread_park(ebc->refresh_thread);
 }
 
 static const struct drm_crtc_helper_funcs rockchip_ebc_crtc_helper_funcs = {
@@ -408,6 +463,14 @@ static int rockchip_ebc_plane_atomic_check(struct drm_plane *plane,
 static void rockchip_ebc_plane_atomic_update(struct drm_plane *plane,
 					     struct drm_atomic_state *state)
 {
+	struct rockchip_ebc *ebc = plane_to_ebc(plane);
+	struct drm_plane_state *plane_state;
+
+	plane_state = drm_atomic_get_new_plane_state(state, plane);
+	if (!plane_state->crtc)
+		return;
+
+	wake_up_process(ebc->refresh_thread);
 }
 
 static const struct drm_plane_helper_funcs rockchip_ebc_plane_helper_funcs = {
@@ -673,6 +736,7 @@ static int rockchip_ebc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ebc);
 	init_completion(&ebc->display_end);
+	ebc->reset_complete = skip_reset;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -716,12 +780,26 @@ static int rockchip_ebc_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	ebc->refresh_thread = kthread_create(rockchip_ebc_refresh_thread,
+					     ebc, "ebc-refresh/%s",
+					     dev_name(dev));
+	if (IS_ERR(ebc->refresh_thread)) {
+		ret = dev_err_probe(dev, PTR_ERR(ebc->refresh_thread),
+				    "Failed to start refresh thread\n");
+		goto err_disable_pm;
+	}
+
+	kthread_park(ebc->refresh_thread);
+	sched_set_fifo(ebc->refresh_thread);
+
 	ret = rockchip_ebc_drm_init(ebc);
 	if (ret)
-		goto err_disable_pm;
+		goto err_stop_kthread;
 
 	return 0;
 
+err_stop_kthread:
+	kthread_stop(ebc->refresh_thread);
 err_disable_pm:
 	pm_runtime_disable(dev);
 	if (!pm_runtime_status_suspended(dev))
@@ -738,6 +816,8 @@ static int rockchip_ebc_remove(struct platform_device *pdev)
 	drm_dev_unregister(&ebc->drm);
 	drm_atomic_helper_shutdown(&ebc->drm);
 
+	kthread_stop(ebc->refresh_thread);
+
 	pm_runtime_disable(dev);
 	if (!pm_runtime_status_suspended(dev))
 		rockchip_ebc_runtime_suspend(dev);
-- 
2.35.1


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

  parent reply	other threads:[~2022-04-13 22:22 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-13 22:19 [RFC PATCH 00/16] drm/rockchip: Rockchip EBC ("E-Book Controller") display driver Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 01/16] drm: Add a helper library for EPD drivers Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 02/16] dt-bindings: display: rockchip: Add EBC binding Samuel Holland
2022-04-14  8:15   ` Andreas Kemnade
2022-04-15  3:00     ` Samuel Holland
2022-04-15 11:45       ` Andreas Kemnade
2022-04-13 22:19 ` [RFC PATCH 03/16] drm/rockchip: Add EBC platform driver skeleton Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 04/16] drm/rockchip: ebc: Add DRM " Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 05/16] drm/rockchip: ebc: Add CRTC mode setting Samuel Holland
2022-04-13 22:19 ` Samuel Holland [this message]
2022-04-13 22:19 ` [RFC PATCH 07/16] drm/rockchip: ebc: Add CRTC buffer management Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 08/16] drm/rockchip: ebc: Add LUT loading Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 09/16] drm/rockchip: ebc: Implement global refreshes Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 10/16] drm/rockchip: ebc: Implement partial refreshes Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 11/16] drm/rockchip: ebc: Enable diff mode for " Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 12/16] drm/rockchip: ebc: Add support for direct mode Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 13/16] drm/rockchip: ebc: Add a panel reflection option Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 14/16] drm/panel-simple: Add eInk ED103TC2 Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 15/16] arm64: dts: rockchip: rk356x: Add EBC node Samuel Holland
2022-04-13 22:19 ` [RFC PATCH 16/16] [DO NOT MERGE] arm64: dts: rockchip: pinenote: Enable EBC display pipeline Samuel Holland
2022-04-14  8:50 ` [RFC PATCH 00/16] drm/rockchip: Rockchip EBC ("E-Book Controller") display driver Maxime Ripard
2022-05-25 17:18   ` Daniel Vetter
2022-05-31  8:58     ` Maxime Ripard
2022-06-01 12:35       ` Daniel Vetter
2022-06-08 14:48         ` Maxime Ripard
2022-06-08 15:34           ` Daniel Vetter
2022-04-21  6:43 ` Andreas Kemnade
2022-04-21  7:10   ` Nicolas Frattaroli

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=20220413221916.50995-7-samuel@sholland.org \
    --to=samuel@sholland.org \
    --cc=airlied@linux.ie \
    --cc=alistair@alistair23.me \
    --cc=andreas@kemnade.info \
    --cc=cl@rock-chips.com \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=frattaroli.nicolas@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=michael.riesch@wolfvision.net \
    --cc=mripard@kernel.org \
    --cc=pgwipeout@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=sam@ravnborg.org \
    --cc=thierry.reding@gmail.com \
    --cc=tzimmermann@suse.de \
    --cc=x@xff.cz \
    /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;
as well as URLs for NNTP newsgroup(s).