History

drm/rockchip: Don't use atomic constructs for psr

Instead of using timer and spinlocks, use delayed_work and mutexes for rockchip psr. This allows us to make blocking calls when enabling/disabling psr (which is sort of important given we're talking over dpcd to the display).

Sean Paul committed 8 years ago

Commit 60beecc1 parent 7f3c1913 files · +31 −41Browse files

Unified · Split

3 files
  1. drivers/gpu/drm/rockchip/rockchip_drm_drv.c +1 −1
  2. drivers/gpu/drm/rockchip/rockchip_drm_drv.h +1 −1
  3. drivers/gpu/drm/rockchip/rockchip_drm_psr.c +29 −39
drivers/gpu/drm/rockchip/rockchip_drm_drv.c+1−1
@@ -134,7 +134,7 @@ static int rockchip_drm_bind(struct device *dev) · 133 unmodified lines
134 drm_dev->dev_private = private;134 drm_dev->dev_private = private;
135 135
136 INIT_LIST_HEAD(&private->psr_list);136 INIT_LIST_HEAD(&private->psr_list);
137 spin_lock_init(&private->psr_list_lock);137 mutex_init(&private->psr_list_lock);
138 138
139 ret = rockchip_drm_init_iommu(drm_dev);139 ret = rockchip_drm_init_iommu(drm_dev);
140 if (ret)140 if (ret)
drivers/gpu/drm/rockchip/rockchip_drm_drv.h+1−1
@@ -55,7 +55,7 @@ struct rockchip_drm_private { · 54 unmodified lines
55 struct mutex mm_lock;55 struct mutex mm_lock;
56 struct drm_mm mm;56 struct drm_mm mm;
57 struct list_head psr_list;57 struct list_head psr_list;
58 spinlock_t psr_list_lock;58 struct mutex psr_list_lock;
59};59};
60 60
61int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,61int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
drivers/gpu/drm/rockchip/rockchip_drm_psr.c+29−39
@@ -18,7 +18,7 @@ · 17 unmodified lines
18#include "rockchip_drm_drv.h"18#include "rockchip_drm_drv.h"
19#include "rockchip_drm_psr.h"19#include "rockchip_drm_psr.h"
20 20
21#define PSR_FLUSH_TIMEOUT msecs_to_jiffies(100)21#define PSR_FLUSH_TIMEOUT_MS 100
22 22
23enum psr_state {23enum psr_state {
24 PSR_FLUSH,24 PSR_FLUSH,
@@ -30,11 +30,11 @@ struct psr_drv { · 5 unmodified lines
30 struct list_head list;30 struct list_head list;
31 struct drm_encoder *encoder;31 struct drm_encoder *encoder;
32 32
33 spinlock_t lock;33 struct mutex lock;
34 bool active;34 bool active;
35 enum psr_state state;35 enum psr_state state;
36 36
37 struct timer_list flush_timer;37 struct delayed_work flush_work;
38 38
39 void (*set)(struct drm_encoder *encoder, bool enable);39 void (*set)(struct drm_encoder *encoder, bool enable);
40};40};
@@ -43,9 +43,8 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc) · 2 unmodified lines
43{43{
44 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;44 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
45 struct psr_drv *psr;45 struct psr_drv *psr;
46 unsigned long flags;
47 46
48 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);47 mutex_lock(&drm_drv->psr_list_lock);
49 list_for_each_entry(psr, &drm_drv->psr_list, list) {48 list_for_each_entry(psr, &drm_drv->psr_list, list) {
50 if (psr->encoder->crtc == crtc)49 if (psr->encoder->crtc == crtc)
51 goto out;50 goto out;
@@ -53,7 +52,7 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc) · 1 unmodified line
53 psr = ERR_PTR(-ENODEV);52 psr = ERR_PTR(-ENODEV);
54 53
55out:54out:
56 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);55 mutex_unlock(&drm_drv->psr_list_lock);
57 return psr;56 return psr;
58}57}
59 58
@@ -61,9 +60,8 @@ static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) · 1 unmodified line
61{60{
62 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;61 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
63 struct psr_drv *psr;62 struct psr_drv *psr;
64 unsigned long flags;
65 63
66 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);64 mutex_lock(&drm_drv->psr_list_lock);
67 list_for_each_entry(psr, &drm_drv->psr_list, list) {65 list_for_each_entry(psr, &drm_drv->psr_list, list) {
68 if (psr->encoder == encoder)66 if (psr->encoder == encoder)
69 goto out;67 goto out;
@@ -71,7 +69,7 @@ static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) · 1 unmodified line
71 psr = ERR_PTR(-ENODEV);69 psr = ERR_PTR(-ENODEV);
72 70
73out:71out:
74 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);72 mutex_unlock(&drm_drv->psr_list_lock);
75 return psr;73 return psr;
76}74}
77 75
@@ -112,23 +110,21 @@ static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state) · 34 unmodified lines
112 110
113static void psr_set_state(struct psr_drv *psr, enum psr_state state)111static void psr_set_state(struct psr_drv *psr, enum psr_state state)
114{112{
115 unsigned long flags;113 mutex_lock(&psr->lock);
116
117 spin_lock_irqsave(&psr->lock, flags);
118 psr_set_state_locked(psr, state);114 psr_set_state_locked(psr, state);
119 spin_unlock_irqrestore(&psr->lock, flags);115 mutex_unlock(&psr->lock);
120}116}
121 117
122static void psr_flush_handler(struct timer_list *t)118static void psr_flush_handler(struct work_struct *work)
123{119{
124 struct psr_drv *psr = from_timer(psr, t, flush_timer);120 struct psr_drv *psr = container_of(to_delayed_work(work),
125 unsigned long flags;121 struct psr_drv, flush_work);
126 122
127 /* If the state has changed since we initiated the flush, do nothing */123 /* If the state has changed since we initiated the flush, do nothing */
128 spin_lock_irqsave(&psr->lock, flags);124 mutex_lock(&psr->lock);
129 if (psr->state == PSR_FLUSH)125 if (psr->state == PSR_FLUSH)
130 psr_set_state_locked(psr, PSR_ENABLE);126 psr_set_state_locked(psr, PSR_ENABLE);
131 spin_unlock_irqrestore(&psr->lock, flags);127 mutex_unlock(&psr->lock);
132}128}
133 129
134/**130/**
@@ -141,14 +137,13 @@ static void psr_flush_handler(struct timer_list *t) · 6 unmodified lines
141int rockchip_drm_psr_activate(struct drm_encoder *encoder)137int rockchip_drm_psr_activate(struct drm_encoder *encoder)
142{138{
143 struct psr_drv *psr = find_psr_by_encoder(encoder);139 struct psr_drv *psr = find_psr_by_encoder(encoder);
144 unsigned long flags;
145 140
146 if (IS_ERR(psr))141 if (IS_ERR(psr))
147 return PTR_ERR(psr);142 return PTR_ERR(psr);
148 143
149 spin_lock_irqsave(&psr->lock, flags);144 mutex_lock(&psr->lock);
150 psr->active = true;145 psr->active = true;
151 spin_unlock_irqrestore(&psr->lock, flags);146 mutex_unlock(&psr->lock);
152 147
153 return 0;148 return 0;
154}149}
@@ -164,15 +159,14 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate); · 9 unmodified lines
164int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)159int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
165{160{
166 struct psr_drv *psr = find_psr_by_encoder(encoder);161 struct psr_drv *psr = find_psr_by_encoder(encoder);
167 unsigned long flags;
168 162
169 if (IS_ERR(psr))163 if (IS_ERR(psr))
170 return PTR_ERR(psr);164 return PTR_ERR(psr);
171 165
172 spin_lock_irqsave(&psr->lock, flags);166 mutex_lock(&psr->lock);
173 psr->active = false;167 psr->active = false;
174 spin_unlock_irqrestore(&psr->lock, flags);168 mutex_unlock(&psr->lock);
175 del_timer_sync(&psr->flush_timer);169 cancel_delayed_work_sync(&psr->flush_work);
176 170
177 return 0;171 return 0;
178}172}
@@ -180,9 +174,8 @@ EXPORT_SYMBOL(rockchip_drm_psr_deactivate); · 1 unmodified line
180 174
181static void rockchip_drm_do_flush(struct psr_drv *psr)175static void rockchip_drm_do_flush(struct psr_drv *psr)
182{176{
183 mod_timer(&psr->flush_timer,
184 round_jiffies_up(jiffies + PSR_FLUSH_TIMEOUT));
185 psr_set_state(psr, PSR_FLUSH);177 psr_set_state(psr, PSR_FLUSH);
178 mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS);
186}179}
187 180
188/**181/**
@@ -219,12 +212,11 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev) · 30 unmodified lines
219{212{
220 struct rockchip_drm_private *drm_drv = dev->dev_private;213 struct rockchip_drm_private *drm_drv = dev->dev_private;
221 struct psr_drv *psr;214 struct psr_drv *psr;
222 unsigned long flags;
223 215
224 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);216 mutex_lock(&drm_drv->psr_list_lock);
225 list_for_each_entry(psr, &drm_drv->psr_list, list)217 list_for_each_entry(psr, &drm_drv->psr_list, list)
226 rockchip_drm_do_flush(psr);218 rockchip_drm_do_flush(psr);
227 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);219 mutex_unlock(&drm_drv->psr_list_lock);
228}220}
229EXPORT_SYMBOL(rockchip_drm_psr_flush_all);221EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
230 222
@@ -241,7 +233,6 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder, · 10 unmodified lines
241{233{
242 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;234 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
243 struct psr_drv *psr;235 struct psr_drv *psr;
244 unsigned long flags;
245 236
246 if (!encoder || !psr_set)237 if (!encoder || !psr_set)
247 return -EINVAL;238 return -EINVAL;
@@ -250,17 +241,17 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder, · 2 unmodified lines
250 if (!psr)241 if (!psr)
251 return -ENOMEM;242 return -ENOMEM;
252 243
253 timer_setup(&psr->flush_timer, psr_flush_handler, 0);244 INIT_DELAYED_WORK(&psr->flush_work, psr_flush_handler);
254 spin_lock_init(&psr->lock);245 mutex_init(&psr->lock);
255 246
256 psr->active = true;247 psr->active = true;
257 psr->state = PSR_DISABLE;248 psr->state = PSR_DISABLE;
258 psr->encoder = encoder;249 psr->encoder = encoder;
259 psr->set = psr_set;250 psr->set = psr_set;
260 251
261 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);252 mutex_lock(&drm_drv->psr_list_lock);
262 list_add_tail(&psr->list, &drm_drv->psr_list);253 list_add_tail(&psr->list, &drm_drv->psr_list);
263 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);254 mutex_unlock(&drm_drv->psr_list_lock);
264 255
265 return 0;256 return 0;
266}257}
@@ -278,16 +269,15 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder) · 11 unmodified lines
278{269{
279 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;270 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
280 struct psr_drv *psr, *n;271 struct psr_drv *psr, *n;
281 unsigned long flags;
282 272
283 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);273 mutex_lock(&drm_drv->psr_list_lock);
284 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {274 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
285 if (psr->encoder == encoder) {275 if (psr->encoder == encoder) {
286 del_timer(&psr->flush_timer);276 cancel_delayed_work_sync(&psr->flush_work);
287 list_del(&psr->list);277 list_del(&psr->list);
288 kfree(psr);278 kfree(psr);
289 }279 }
290 }280 }
291 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);281 mutex_unlock(&drm_drv->psr_list_lock);
292}282}
293EXPORT_SYMBOL(rockchip_drm_psr_unregister);283EXPORT_SYMBOL(rockchip_drm_psr_unregister);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t