mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Thierry Escande <thierry.escande@collabora.com>
To: Archit Taneja <architt@codeaurora.org>,
	Inki Dae <inki.dae@samsung.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	Sandy Huang <hjc@rock-chips.com>,
	Sean Paul <seanpaul@chromium.org>,
	David Airlie <airlied@linux.ie>, Tomasz Figa <tfiga@chromium.org>,
	Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: "Haixia Shi" <hshi@chromium.org>,
	"Ørjan Eide" <orjan.eide@arm.com>,
	"Zain Wang" <wzz@rock-chips.com>,
	"Yakir Yang" <ykk@rock-chips.com>,
	"Lin Huang" <hl@rock-chips.com>,
	"Douglas Anderson" <dianders@chromium.org>,
	"Mark Yao" <mark.yao@rock-chips.com>,
	linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org,
	dri-devel@lists.freedesktop.org
Subject: [PATCH v3 40/43] drm/rockchip: psr: Sanitize semantics of allow/disallow API
Date: Tue, 30 Jan 2018 21:29:10 +0100	[thread overview]
Message-ID: <20180130202913.28724-41-thierry.escande@collabora.com> (raw)
In-Reply-To: <20180130202913.28724-1-thierry.escande@collabora.com>

From: Tomasz Figa <tfiga@chromium.org>

Currently both rockchip_drm_psr_activate() and _deactivate() only set the
boolean "active" flag without actually making sure that hardware state
complies with it.

Since we are going to extend the usage of this API to properly lock PSR
for the duration of atomic commits, we change the semantics in following
way:
 - a counter is used to track the number of disallow requests,
 - PSR is actually disabled in hardware on first disallow request,
 - PSR enable work is scheduled on last disallow request.

The above allows using the API as a way to deterministically synchronize
PSR state changes with other DRM events, i.e. atomic commits and cursor
updates. As a nice side effect, the naming is sorted out and we have
"inhibit" for stopping the software logic and "enable" for hardware
state.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c     | 57 ++++++++++++++++++-------
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h     |  4 +-
 3 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 6d45d62466b3..080f05352195 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -134,7 +134,7 @@ static int rockchip_dp_poweron_end(struct analogix_dp_plat_data *plat_data)
 {
 	struct rockchip_dp_device *dp = to_dp(plat_data);
 
-	return rockchip_drm_psr_activate(&dp->encoder);
+	return rockchip_drm_psr_inhibit_put(&dp->encoder);
 }
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
@@ -142,7 +142,7 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 	struct rockchip_dp_device *dp = to_dp(plat_data);
 	int ret;
 
-	ret = rockchip_drm_psr_deactivate(&dp->encoder);
+	ret = rockchip_drm_psr_inhibit_get(&dp->encoder);
 	if (ret != 0)
 		return ret;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 448c5fde241c..e7e16d92d5a1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -27,7 +27,7 @@ struct psr_drv {
 	struct drm_encoder	*encoder;
 
 	struct mutex		lock;
-	bool			active;
+	int			inhibit_count;
 	bool			enabled;
 
 	struct delayed_work	flush_work;
@@ -76,7 +76,7 @@ static int psr_set_state_locked(struct psr_drv *psr, bool enable)
 {
 	int ret;
 
-	if (!psr->active)
+	if (psr->inhibit_count > 0)
 		return -EINVAL;
 
 	if (enable == psr->enabled)
@@ -101,13 +101,18 @@ static void psr_flush_handler(struct work_struct *work)
 }
 
 /**
- * rockchip_drm_psr_activate - activate PSR on the given pipe
+ * rockchip_drm_psr_inhibit_put - release PSR inhibit on given encoder
  * @encoder: encoder to obtain the PSR encoder
  *
+ * Decrements PSR inhibit count on given encoder. Should be called only
+ * for a PSR inhibit count increment done before. If PSR inhibit counter
+ * reaches zero, PSR flush work is scheduled to make the hardware enter
+ * PSR mode in PSR_FLUSH_TIMEOUT_MS.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_activate(struct drm_encoder *encoder)
+int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder)
 {
 	struct psr_drv *psr = find_psr_by_encoder(encoder);
 
@@ -115,21 +120,29 @@ int rockchip_drm_psr_activate(struct drm_encoder *encoder)
 		return PTR_ERR(psr);
 
 	mutex_lock(&psr->lock);
-	psr->active = true;
+	--psr->inhibit_count;
+	if (!psr->inhibit_count)
+		mod_delayed_work(system_wq, &psr->flush_work,
+				 PSR_FLUSH_TIMEOUT_MS);
 	mutex_unlock(&psr->lock);
 
 	return 0;
 }
-EXPORT_SYMBOL(rockchip_drm_psr_activate);
+EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put);
 
 /**
- * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe
+ * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder
  * @encoder: encoder to obtain the PSR encoder
  *
+ * Increments PSR inhibit count on given encoder. This function guarantees
+ * that after it returns PSR is turned off on given encoder and no PSR-related
+ * hardware state change occurs at least until a matching call to
+ * rockchip_drm_psr_inhibit_put() is done.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
+int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder)
 {
 	struct psr_drv *psr = find_psr_by_encoder(encoder);
 
@@ -137,15 +150,15 @@ int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
 		return PTR_ERR(psr);
 
 	mutex_lock(&psr->lock);
-	psr->active = false;
-	psr->enabled = false;
+	psr_set_state_locked(psr, false);
+	++psr->inhibit_count;
 	mutex_unlock(&psr->lock);
 	cancel_delayed_work_sync(&psr->flush_work);
 	cancel_work_sync(&psr->disable_work);
 
 	return 0;
 }
-EXPORT_SYMBOL(rockchip_drm_psr_deactivate);
+EXPORT_SYMBOL(rockchip_drm_psr_inhibit_get);
 
 static void rockchip_drm_do_flush(struct psr_drv *psr)
 {
@@ -301,6 +314,11 @@ static const struct input_device_id psr_ids[] = {
  * @encoder: encoder that obtain the PSR function
  * @psr_set: call back to set PSR state
  *
+ * The function returns with PSR inhibit counter initialized with one
+ * and the caller (typically encoder driver) needs to call
+ * rockchip_drm_psr_inhibit_put() when it becomes ready to accept PSR
+ * enable request.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -322,7 +340,7 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
 	INIT_WORK(&psr->disable_work, psr_disable_handler);
 	mutex_init(&psr->lock);
 
-	psr->active = false;
+	psr->inhibit_count = 1;
 	psr->enabled = false;
 	psr->encoder = encoder;
 	psr->set = psr_set;
@@ -362,6 +380,11 @@ EXPORT_SYMBOL(rockchip_drm_psr_register);
  * @encoder: encoder that obtain the PSR function
  * @psr_set: call back to set PSR state
  *
+ * It is expected that the PSR inhibit counter is 1 when this function is
+ * called, which corresponds to a state when related encoder has been
+ * disconnected from any CRTCs and its driver called
+ * rockchip_drm_psr_inhibit_get() to stop the PSR logic.
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -373,10 +396,14 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
 	mutex_lock(&drm_drv->psr_list_lock);
 	list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
 		if (psr->encoder == encoder) {
-			input_unregister_handler(&psr->input_handler);
-			cancel_delayed_work_sync(&psr->flush_work);
-			cancel_work_sync(&psr->disable_work);
+			/*
+			 * Any other value would mean that the encoder
+			 * is still in use.
+			 */
+			WARN_ON(psr->inhibit_count != 1);
+
 			list_del(&psr->list);
+			input_unregister_handler(&psr->input_handler);
 			kfree(psr->input_handler.name);
 			kfree(psr);
 		}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index 06537ee27565..40e026c14168 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -18,8 +18,8 @@
 void rockchip_drm_psr_flush_all(struct drm_device *dev);
 int rockchip_drm_psr_flush(struct drm_crtc *crtc);
 
-int rockchip_drm_psr_activate(struct drm_encoder *encoder);
-int rockchip_drm_psr_deactivate(struct drm_encoder *encoder);
+int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder);
+int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder);
 
 int rockchip_drm_psr_register(struct drm_encoder *encoder,
 			int (*psr_set)(struct drm_encoder *, bool enable));
-- 
2.14.1

  parent reply	other threads:[~2018-01-30 20:30 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20180131083447epcas3p3633663f2f88e637ffe54ab8307ce5d14@epcas3p3.samsung.com>
2018-01-30 20:28 ` [PATCH v3 00/43] DRM Rockchip rk3399 (Kevin) Thierry Escande
2018-01-30 20:28   ` [PATCH v3 01/43] drm/rockchip: Get rid of unnecessary struct fields Thierry Escande
2018-02-18 10:50     ` Heiko Stuebner
2018-01-30 20:28   ` [PATCH v3 02/43] drm/rockchip: support prime import sg table Thierry Escande
2018-02-18 10:51     ` Heiko Stuebner
2018-01-30 20:28   ` [PATCH v3 03/43] drm/rockchip: Respect page offset for PRIME mmap calls Thierry Escande
2018-02-18 10:53     ` Heiko Stuebner
2018-01-30 20:28   ` [PATCH v3 04/43] drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge Thierry Escande
2018-01-30 20:28   ` [PATCH v3 05/43] drm/bridge: analogix_dp: Don't power bridge in analogix_dp_bind Thierry Escande
2018-02-28 14:37     ` Heiko Stübner
2018-02-28 14:54       ` Marc Zyngier
2018-02-28 14:56         ` Heiko Stübner
2018-02-28 15:20     ` Heiko Stübner
2018-03-01  8:19       ` Marek Szyprowski
2018-03-01 13:37     ` Marek Szyprowski
2018-01-30 20:28   ` [PATCH v3 06/43] drm/rockchip: Don't use atomic constructs for psr Thierry Escande
2018-01-30 20:28   ` [PATCH v3 07/43] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR Thierry Escande
2018-01-30 20:28   ` [PATCH v3 08/43] drm/rockchip: Remove analogix psr worker Thierry Escande
2018-01-30 20:28   ` [PATCH v3 09/43] drm/bridge: analogix_dp: Don't change psr while bridge is disabled Thierry Escande
2018-01-30 20:28   ` [PATCH v3 10/43] drm/rockchip: add mutex vop lock Thierry Escande
2018-01-30 20:28   ` [PATCH v3 11/43] drm/bridge: analogix_dp: add fast link train for eDP Thierry Escande
2018-01-30 20:28   ` [PATCH v3 12/43] drm/rockchip: Only wait for panel ACK on PSR entry Thierry Escande
2018-01-30 20:28   ` [PATCH v3 13/43] drm/bridge: analogix_dp: Move enable video into config_video() Thierry Escande
2018-01-30 20:28   ` [PATCH v3 14/43] drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer Thierry Escande
2018-01-30 20:28   ` [PATCH v3 15/43] drm/bridge: analogix_dp: Don't use fast link training when panel just powered up Thierry Escande
2018-01-30 20:28   ` [PATCH v3 16/43] drm/bridge: analogix_dp: Retry bridge enable when it failed Thierry Escande
2018-01-30 20:28   ` [PATCH v3 17/43] drm/bridge: analogix_dp: Wait for HPD signal before configuring link Thierry Escande
2018-01-30 20:28   ` [PATCH v3 18/43] drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy Thierry Escande
2018-01-30 20:28   ` [PATCH v3 19/43] drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the panel Thierry Escande
2018-01-30 20:28   ` [PATCH v3 20/43] drm/bridge: analogix_dp: Extend hpd check time to 100ms Thierry Escande
2018-01-30 20:28   ` [PATCH v3 21/43] drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode Thierry Escande
2018-01-30 20:28   ` [PATCH v3 22/43] drm/bridge: analogix_dp: Check dpcd write/read status Thierry Escande
2018-01-30 20:28   ` [PATCH v3 23/43] drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip Thierry Escande
2018-01-30 20:28   ` [PATCH v3 24/43] drm/bridge: analogix_dp: Reset aux channel if an error occurred Thierry Escande
2018-01-30 20:28   ` [PATCH v3 25/43] drm/rockchip: Restore psr->state when enable/disable psr failed Thierry Escande
2018-01-30 20:28   ` [PATCH v3 26/43] drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll Thierry Escande
2018-01-30 20:28   ` [PATCH v3 27/43] drm/bridge: analogix_dp: Fix timeout of video streamclk config Thierry Escande
2018-01-30 20:28   ` [PATCH v3 28/43] drm/bridge: analogix_dp: Fix incorrect operations with register ANALOGIX_DP_FUNC_EN_1 Thierry Escande
2018-01-30 20:28   ` [PATCH v3 29/43] drm/bridge: analogix_dp: Move fast link training detect to set_bridge Thierry Escande
2018-01-30 20:29   ` [PATCH v3 30/43] drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner Thierry Escande
2018-01-30 20:29   ` [PATCH v3 31/43] drm/bridge: analogix_dp: Properly log AUX CH errors Thierry Escande
2018-01-30 20:29   ` [PATCH v3 32/43] drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip Thierry Escande
2018-01-30 20:29   ` [PATCH v3 33/43] drm/panel: simple: Change mode for Sharp lq123p1jx31 Thierry Escande
2018-01-31 12:54     ` Lucas Stach
2018-01-31 15:16       ` Sean Paul
2018-01-31 16:52         ` Doug Anderson
2018-02-16 12:34           ` Enric Balletbo Serra
2018-02-16 20:54             ` Doug Anderson
2018-02-19  9:42               ` Enric Balletbo Serra
2018-01-30 20:29   ` [PATCH v3 34/43] drm/rockchip: pre dither down when output bpc is 8bit Thierry Escande
2018-01-30 20:29   ` [PATCH v3 35/43] drm/bridge: analogix_dp: Split the platform-specific poweron in two parts Thierry Escande
2018-01-30 20:29   ` [PATCH v3 36/43] drm/rockchip: analogix_dp: Do not call Analogix code before bind Thierry Escande
2018-01-30 20:29   ` [PATCH v3 37/43] drm/rockchip: Disable PSR on input events Thierry Escande
2018-01-30 20:29   ` [PATCH v3 38/43] drm/rockchip: Cancel PSR enable work before changing the state Thierry Escande
2018-01-30 20:29   ` [PATCH v3 39/43] drm/rockchip: psr: Avoid redundant calls to .set() callback Thierry Escande
2018-01-30 20:29   ` Thierry Escande [this message]
2018-01-30 20:29   ` [PATCH v3 41/43] drm/rockchip: Disable PSR from reboot notifier Thierry Escande
2018-01-30 20:29   ` [PATCH v3 42/43] drm/rockchip: Disallow PSR for the whole atomic commit Thierry Escande
2018-01-30 20:29   ` [PATCH v3 43/43] drm/rockchip: psr: Remove flush by CRTC Thierry Escande
2018-03-01  8:50   ` [PATCH v3 00/43] DRM Rockchip rk3399 (Kevin) Marek Szyprowski
2018-03-01 11:06     ` Marek Szyprowski
2018-03-01 12:56       ` Marek Szyprowski

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=20180130202913.28724-41-thierry.escande@collabora.com \
    --to=thierry.escande@collabora.com \
    --cc=airlied@linux.ie \
    --cc=architt@codeaurora.org \
    --cc=dianders@chromium.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=enric.balletbo@collabora.com \
    --cc=hjc@rock-chips.com \
    --cc=hl@rock-chips.com \
    --cc=hshi@chromium.org \
    --cc=inki.dae@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mark.yao@rock-chips.com \
    --cc=orjan.eide@arm.com \
    --cc=seanpaul@chromium.org \
    --cc=tfiga@chromium.org \
    --cc=thierry.reding@gmail.com \
    --cc=wzz@rock-chips.com \
    --cc=ykk@rock-chips.com \
    /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

all inboxes | Powered by JetHome®