1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Author: Yakir Yang <ykk@rock-chips.com>
8 #include <drm/drm_atomic.h>
9 #include <drm/drm_probe_helper.h>
11 #include "rockchip_drm_drv.h"
12 #include "rockchip_drm_psr.h"
14 #define PSR_FLUSH_TIMEOUT_MS 100
17 struct list_head list;
18 struct drm_encoder *encoder;
24 struct delayed_work flush_work;
26 int (*set)(struct drm_encoder *encoder, bool enable);
29 static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder)
31 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
34 mutex_lock(&drm_drv->psr_list_lock);
35 list_for_each_entry(psr, &drm_drv->psr_list, list) {
36 if (psr->encoder == encoder)
39 psr = ERR_PTR(-ENODEV);
42 mutex_unlock(&drm_drv->psr_list_lock);
46 static int psr_set_state_locked(struct psr_drv *psr, bool enable)
50 if (psr->inhibit_count > 0)
53 if (enable == psr->enabled)
56 ret = psr->set(psr->encoder, enable);
60 psr->enabled = enable;
64 static void psr_flush_handler(struct work_struct *work)
66 struct psr_drv *psr = container_of(to_delayed_work(work),
67 struct psr_drv, flush_work);
69 mutex_lock(&psr->lock);
70 psr_set_state_locked(psr, true);
71 mutex_unlock(&psr->lock);
75 * rockchip_drm_psr_inhibit_put - release PSR inhibit on given encoder
76 * @encoder: encoder to obtain the PSR encoder
78 * Decrements PSR inhibit count on given encoder. Should be called only
79 * for a PSR inhibit count increment done before. If PSR inhibit counter
80 * reaches zero, PSR flush work is scheduled to make the hardware enter
81 * PSR mode in PSR_FLUSH_TIMEOUT_MS.
84 * Zero on success, negative errno on failure.
86 int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder)
88 struct psr_drv *psr = find_psr_by_encoder(encoder);
93 mutex_lock(&psr->lock);
95 WARN_ON(psr->inhibit_count < 0);
96 if (!psr->inhibit_count)
97 mod_delayed_work(system_wq, &psr->flush_work,
98 PSR_FLUSH_TIMEOUT_MS);
99 mutex_unlock(&psr->lock);
103 EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put);
105 void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
107 struct drm_crtc *crtc;
108 struct drm_crtc_state *crtc_state;
109 struct drm_encoder *encoder;
110 u32 encoder_mask = 0;
113 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
114 encoder_mask |= crtc_state->encoder_mask;
115 encoder_mask |= crtc->state->encoder_mask;
118 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
119 rockchip_drm_psr_inhibit_get(encoder);
121 EXPORT_SYMBOL(rockchip_drm_psr_inhibit_get_state);
123 void rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
125 struct drm_crtc *crtc;
126 struct drm_crtc_state *crtc_state;
127 struct drm_encoder *encoder;
128 u32 encoder_mask = 0;
131 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
132 encoder_mask |= crtc_state->encoder_mask;
133 encoder_mask |= crtc->state->encoder_mask;
136 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
137 rockchip_drm_psr_inhibit_put(encoder);
139 EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put_state);
142 * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder
143 * @encoder: encoder to obtain the PSR encoder
145 * Increments PSR inhibit count on given encoder. This function guarantees
146 * that after it returns PSR is turned off on given encoder and no PSR-related
147 * hardware state change occurs at least until a matching call to
148 * rockchip_drm_psr_inhibit_put() is done.
151 * Zero on success, negative errno on failure.
153 int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder)
155 struct psr_drv *psr = find_psr_by_encoder(encoder);
160 mutex_lock(&psr->lock);
161 psr_set_state_locked(psr, false);
162 ++psr->inhibit_count;
163 mutex_unlock(&psr->lock);
164 cancel_delayed_work_sync(&psr->flush_work);
168 EXPORT_SYMBOL(rockchip_drm_psr_inhibit_get);
170 static void rockchip_drm_do_flush(struct psr_drv *psr)
172 cancel_delayed_work_sync(&psr->flush_work);
174 mutex_lock(&psr->lock);
175 if (!psr_set_state_locked(psr, false))
176 mod_delayed_work(system_wq, &psr->flush_work,
177 PSR_FLUSH_TIMEOUT_MS);
178 mutex_unlock(&psr->lock);
182 * rockchip_drm_psr_flush_all - force to flush all registered PSR encoders
185 * Disable the PSR function for all registered encoders, and then enable the
186 * PSR function back after PSR_FLUSH_TIMEOUT. If encoder PSR state have been
187 * changed during flush time, then keep the state no change after flush
191 * Zero on success, negative errno on failure.
193 void rockchip_drm_psr_flush_all(struct drm_device *dev)
195 struct rockchip_drm_private *drm_drv = dev->dev_private;
198 mutex_lock(&drm_drv->psr_list_lock);
199 list_for_each_entry(psr, &drm_drv->psr_list, list)
200 rockchip_drm_do_flush(psr);
201 mutex_unlock(&drm_drv->psr_list_lock);
203 EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
206 * rockchip_drm_psr_register - register encoder to psr driver
207 * @encoder: encoder that obtain the PSR function
208 * @psr_set: call back to set PSR state
210 * The function returns with PSR inhibit counter initialized with one
211 * and the caller (typically encoder driver) needs to call
212 * rockchip_drm_psr_inhibit_put() when it becomes ready to accept PSR
216 * Zero on success, negative errno on failure.
218 int rockchip_drm_psr_register(struct drm_encoder *encoder,
219 int (*psr_set)(struct drm_encoder *, bool enable))
221 struct rockchip_drm_private *drm_drv;
224 if (!encoder || !psr_set)
227 drm_drv = encoder->dev->dev_private;
229 psr = kzalloc(sizeof(struct psr_drv), GFP_KERNEL);
233 INIT_DELAYED_WORK(&psr->flush_work, psr_flush_handler);
234 mutex_init(&psr->lock);
236 psr->inhibit_count = 1;
237 psr->enabled = false;
238 psr->encoder = encoder;
241 mutex_lock(&drm_drv->psr_list_lock);
242 list_add_tail(&psr->list, &drm_drv->psr_list);
243 mutex_unlock(&drm_drv->psr_list_lock);
247 EXPORT_SYMBOL(rockchip_drm_psr_register);
250 * rockchip_drm_psr_unregister - unregister encoder to psr driver
251 * @encoder: encoder that obtain the PSR function
252 * @psr_set: call back to set PSR state
254 * It is expected that the PSR inhibit counter is 1 when this function is
255 * called, which corresponds to a state when related encoder has been
256 * disconnected from any CRTCs and its driver called
257 * rockchip_drm_psr_inhibit_get() to stop the PSR logic.
260 * Zero on success, negative errno on failure.
262 void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
264 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
265 struct psr_drv *psr, *n;
267 mutex_lock(&drm_drv->psr_list_lock);
268 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
269 if (psr->encoder == encoder) {
271 * Any other value would mean that the encoder
274 WARN_ON(psr->inhibit_count != 1);
276 list_del(&psr->list);
280 mutex_unlock(&drm_drv->psr_list_lock);
282 EXPORT_SYMBOL(rockchip_drm_psr_unregister);