From: Tomasz Figa tfiga@chromium.org
If we change the state first and reschedule later, we might have the work executed according to previous scheduled time and end up with PSR re-enabled instantly. Let's cancel the work before changing the state.
While at it, consolidate psr_disable_handler() to just call rockchip_drm_do_flush(), as they are both supposed to do the same.
Signed-off-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Thierry Escande thierry.escande@collabora.com Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com ---
drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index a107845ba97c..c8655e625ba2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -138,18 +138,6 @@ static void psr_flush_handler(struct work_struct *work) mutex_unlock(&psr->lock); }
-static void psr_disable_handler(struct work_struct *work) -{ - struct psr_drv *psr = container_of(work, struct psr_drv, disable_work); - - /* If the state has changed since we initiated the flush, do nothing */ - mutex_lock(&psr->lock); - if (psr->state == PSR_ENABLE) - psr_set_state_locked(psr, PSR_FLUSH); - mutex_unlock(&psr->lock); - mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS); -} - /** * rockchip_drm_psr_activate - activate PSR on the given pipe * @encoder: encoder to obtain the PSR encoder @@ -198,6 +186,7 @@ EXPORT_SYMBOL(rockchip_drm_psr_deactivate);
static void rockchip_drm_do_flush(struct psr_drv *psr) { + cancel_delayed_work_sync(&psr->flush_work); psr_set_state(psr, PSR_FLUSH); mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS); } @@ -244,6 +233,13 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev) } EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
+static void psr_disable_handler(struct work_struct *work) +{ + struct psr_drv *psr = container_of(work, struct psr_drv, disable_work); + + rockchip_drm_do_flush(psr); +} + static void psr_input_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
From: Tomasz Figa tfiga@chromium.org
The first time after we call rockchip_drm_do_flush() after rockchip_drm_psr_register(), we go from PSR_DISABLE to PSR_FLUSH. The difference between PSR_DISABLE and PSR_FLUSH is whether or not we have a delayed work pending - PSR is off in either state. However psr_set_state() only catches the transition from PSR_FLUSH to PSR_DISABLE (which never happens), while going from PSR_DISABLE to PSR_FLUSH triggers a call to psr->set() to disable PSR while it's already disabled. This triggers the eDP PHY power-on sequence without being shut down first and this seems to occasionally leave the encoder unable to later enable PSR. Let's just simplify the state machine and simply consider PSR_DISABLE and PSR_FLUSH the same state. This lets us represent the hardware state by a simple boolean called "enabled" and, while at it, rename the misleading "active" boolean to "inhibit", which represents the purpose much better.
Also, userspace can (and does) trigger the rockchip_drm_do_flush() path from drmModeDirtyFB() at any time, whether or the encoder is active. If no mode is set, we call into analogix_dp_psr_set() which returns -EINVAL because encoder->crtc is NULL. Avoid this by starting out with psr->allowed set to false.
Signed-off-by: Kristian H. Kristensen hoegsberg@chromium.org Signed-off-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Thierry Escande thierry.escande@collabora.com Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com ---
drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 79 +++++++++-------------------- 1 file changed, 23 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index c8655e625ba2..448c5fde241c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -22,19 +22,13 @@
#define PSR_FLUSH_TIMEOUT_MS 100
-enum psr_state { - PSR_FLUSH, - PSR_ENABLE, - PSR_DISABLE, -}; - struct psr_drv { struct list_head list; struct drm_encoder *encoder;
struct mutex lock; bool active; - enum psr_state state; + bool enabled;
struct delayed_work flush_work; struct work_struct disable_work; @@ -78,52 +72,22 @@ static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) return psr; }
-static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state) +static int psr_set_state_locked(struct psr_drv *psr, bool enable) { - /* - * Allowed finite state machine: - * - * PSR_ENABLE < = = = = = > PSR_FLUSH - * | ^ | - * | | | - * v | | - * PSR_DISABLE < - - - - - - - - - - */ - if (state == psr->state || !psr->active) - return; - - /* Already disabled in flush, change the state, but not the hardware */ - if (state == PSR_DISABLE && psr->state == PSR_FLUSH) { - psr->state = state; - return; - } + int ret;
- /* Actually commit the state change to hardware */ - switch (state) { - case PSR_ENABLE: - if (psr->set(psr->encoder, true)) - return; - break; - - case PSR_DISABLE: - case PSR_FLUSH: - if (psr->set(psr->encoder, false)) - return; - break; - - default: - pr_err("%s: Unknown state %d\n", __func__, state); - return; - } + if (!psr->active) + return -EINVAL;
- psr->state = state; -} + if (enable == psr->enabled) + return 0;
-static void psr_set_state(struct psr_drv *psr, enum psr_state state) -{ - mutex_lock(&psr->lock); - psr_set_state_locked(psr, state); - mutex_unlock(&psr->lock); + ret = psr->set(psr->encoder, enable); + if (ret) + return ret; + + psr->enabled = enable; + return 0; }
static void psr_flush_handler(struct work_struct *work) @@ -131,10 +95,8 @@ static void psr_flush_handler(struct work_struct *work) struct psr_drv *psr = container_of(to_delayed_work(work), struct psr_drv, flush_work);
- /* If the state has changed since we initiated the flush, do nothing */ mutex_lock(&psr->lock); - if (psr->state == PSR_FLUSH) - psr_set_state_locked(psr, PSR_ENABLE); + psr_set_state_locked(psr, true); mutex_unlock(&psr->lock); }
@@ -176,6 +138,7 @@ int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
mutex_lock(&psr->lock); psr->active = false; + psr->enabled = false; mutex_unlock(&psr->lock); cancel_delayed_work_sync(&psr->flush_work); cancel_work_sync(&psr->disable_work); @@ -187,8 +150,12 @@ EXPORT_SYMBOL(rockchip_drm_psr_deactivate); static void rockchip_drm_do_flush(struct psr_drv *psr) { cancel_delayed_work_sync(&psr->flush_work); - psr_set_state(psr, PSR_FLUSH); - mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS); + + mutex_lock(&psr->lock); + if (!psr_set_state_locked(psr, false)) + mod_delayed_work(system_wq, &psr->flush_work, + PSR_FLUSH_TIMEOUT_MS); + mutex_unlock(&psr->lock); }
/** @@ -355,8 +322,8 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder, INIT_WORK(&psr->disable_work, psr_disable_handler); mutex_init(&psr->lock);
- psr->active = true; - psr->state = PSR_DISABLE; + psr->active = false; + psr->enabled = false; psr->encoder = encoder; psr->set = psr_set;
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 Signed-off-by: Enric Balletbo i Serra enric.balletbo@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));
From: Tomasz Figa tfiga@chromium.org
It looks like the driver subsystem detaches devices from power domains at shutdown without consent of the drivers. This means that we might have our power domain turned off behind our back and the only way to avoid problems is to stop doing any hardware programming at some point before the power is cut. A reboot notifier, despite being a misnomer and handling shutdowns as well, is a good place to do it.
Signed-off-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Thierry Escande thierry.escande@collabora.com Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com ---
drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index e7e16d92d5a1..1bf5cba9a64d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -13,6 +13,7 @@ */
#include <linux/input.h> +#include <linux/reboot.h>
#include <drm/drmP.h> #include <drm/drm_crtc_helper.h> @@ -33,6 +34,7 @@ struct psr_drv { struct delayed_work flush_work; struct work_struct disable_work;
+ struct notifier_block reboot_nb; struct input_handler input_handler;
int (*set)(struct drm_encoder *encoder, bool enable); @@ -309,6 +311,24 @@ static const struct input_device_id psr_ids[] = { { }, };
+static int rockchip_drm_psr_reboot_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct psr_drv *psr = container_of(nb, struct psr_drv, reboot_nb); + + /* + * It looks like the driver subsystem detaches devices from power + * domains at shutdown without consent of the drivers. This means + * that we might have our power domain turned off behind our back + * and the only way to avoid problems is to stop doing any hardware + * programming after this point, which is achieved by the unbalanced + * call below. + */ + rockchip_drm_psr_inhibit_get(psr->encoder); + + return 0; +} + /** * rockchip_drm_psr_register - register encoder to psr driver * @encoder: encoder that obtain the PSR function @@ -361,6 +381,9 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder, if (error) goto err1;
+ psr->reboot_nb.notifier_call = rockchip_drm_psr_reboot_notifier; + register_reboot_notifier(&psr->reboot_nb); + mutex_lock(&drm_drv->psr_list_lock); list_add_tail(&psr->list, &drm_drv->psr_list); mutex_unlock(&drm_drv->psr_list_lock); @@ -403,6 +426,7 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder) WARN_ON(psr->inhibit_count != 1);
list_del(&psr->list); + unregister_reboot_notifier(&psr->reboot_nb); input_unregister_handler(&psr->input_handler); kfree(psr->input_handler.name); kfree(psr);
From: Tomasz Figa tfiga@chromium.org
Currently PSR flush is triggered from CRTC's .atomic_begin() callback, which is executed after modeset disables and enables and before plane updates are committed. Since PSR flush and re-enable can be triggered asynchronously by external sources (input event, delayed work), it can race with hardware programming done in the aforementioned stages.
This patch blocks the PSR completely before hardware programming part begins and unblock after it ends. This relies on reference counted PSR disable introduced with previous patch.
Cc: Kristian H. Kristensen hoegsberg@chromium.org Signed-off-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Signed-off-by: Thierry Escande thierry.escande@collabora.com Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com ---
drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 61 ++++++++++++++++++++++++++++- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 7 ---- 2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index e266539e04e5..d4f4118b482d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -167,8 +167,67 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, return ERR_PTR(ret); }
+static void +rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_encoder *encoder; + u32 encoder_mask = 0; + int i; + + for_each_old_crtc_in_state(state, crtc, crtc_state, i) { + encoder_mask |= crtc_state->encoder_mask; + encoder_mask |= crtc->state->encoder_mask; + } + + drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) + rockchip_drm_psr_inhibit_get(encoder); +} + +static void +rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_encoder *encoder; + u32 encoder_mask = 0; + int i; + + for_each_old_crtc_in_state(state, crtc, crtc_state, i) { + encoder_mask |= crtc_state->encoder_mask; + encoder_mask |= crtc->state->encoder_mask; + } + + drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) + rockchip_drm_psr_inhibit_put(encoder); +} + +static void +rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state) +{ + struct drm_device *dev = old_state->dev; + + rockchip_drm_psr_inhibit_get_state(old_state); + + drm_atomic_helper_commit_modeset_disables(dev, old_state); + + drm_atomic_helper_commit_modeset_enables(dev, old_state); + + drm_atomic_helper_commit_planes(dev, old_state, + DRM_PLANE_COMMIT_ACTIVE_ONLY); + + rockchip_drm_psr_inhibit_put_state(old_state); + + drm_atomic_helper_commit_hw_done(old_state); + + drm_atomic_helper_wait_for_vblanks(dev, old_state); + + drm_atomic_helper_cleanup_planes(dev, old_state); +} + static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = { - .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, + .atomic_commit_tail = rockchip_atomic_helper_commit_tail_rpm, };
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 42562ab04bde..12ebaec740c6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1032,16 +1032,9 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, } }
-static void vop_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) -{ - rockchip_drm_psr_flush(crtc); -} - static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = { .mode_fixup = vop_crtc_mode_fixup, .atomic_flush = vop_crtc_atomic_flush, - .atomic_begin = vop_crtc_atomic_begin, .atomic_enable = vop_crtc_atomic_enable, .atomic_disable = vop_crtc_atomic_disable, };
From: Tomasz Figa tfiga@chromium.org
It is not used anymore after last changes and it was not even correct to begin with as it assumed a 1:1 relation between a CRTC and encoder, while in fact a CRTC can be attached to multiple encoders.
Signed-off-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Thierry Escande thierry.escande@collabora.com Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com ---
drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 35 ----------------------------- drivers/gpu/drm/rockchip/rockchip_drm_psr.h | 1 - 2 files changed, 36 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index 1bf5cba9a64d..b1988ac758d5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -40,23 +40,6 @@ struct psr_drv { int (*set)(struct drm_encoder *encoder, bool enable); };
-static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc) -{ - struct rockchip_drm_private *drm_drv = crtc->dev->dev_private; - struct psr_drv *psr; - - mutex_lock(&drm_drv->psr_list_lock); - list_for_each_entry(psr, &drm_drv->psr_list, list) { - if (psr->encoder->crtc == crtc) - goto out; - } - psr = ERR_PTR(-ENODEV); - -out: - mutex_unlock(&drm_drv->psr_list_lock); - return psr; -} - static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) { struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; @@ -173,24 +156,6 @@ static void rockchip_drm_do_flush(struct psr_drv *psr) mutex_unlock(&psr->lock); }
-/** - * rockchip_drm_psr_flush - flush a single pipe - * @crtc: CRTC of the pipe to flush - * - * Returns: - * 0 on success, -errno on fail - */ -int rockchip_drm_psr_flush(struct drm_crtc *crtc) -{ - struct psr_drv *psr = find_psr_by_crtc(crtc); - if (IS_ERR(psr)) - return PTR_ERR(psr); - - rockchip_drm_do_flush(psr); - return 0; -} -EXPORT_SYMBOL(rockchip_drm_psr_flush); - /** * rockchip_drm_psr_flush_all - force to flush all registered PSR encoders * @dev: drm device diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h index 40e026c14168..860c62494496 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h @@ -16,7 +16,6 @@ #define __ROCKCHIP_DRM_PSR___
void rockchip_drm_psr_flush_all(struct drm_device *dev); -int rockchip_drm_psr_flush(struct drm_crtc *crtc);
int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder); int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder);
dri-devel@lists.freedesktop.org