@@ -30,7 +30,7 @@ struct tilcdc_crtc {
30
30
struct drm_plane primary ;
31
31
const struct tilcdc_panel_info * info ;
32
32
struct drm_pending_vblank_event * event ;
33
- int dpms ;
33
+ bool enabled ;
34
34
wait_queue_head_t frame_done_wq ;
35
35
bool frame_done ;
36
36
spinlock_t irq_lock ;
@@ -137,9 +137,15 @@ static void reset(struct drm_crtc *crtc)
137
137
tilcdc_clear (dev , LCDC_CLK_RESET_REG , LCDC_CLK_MAIN_RESET );
138
138
}
139
139
140
- static void start (struct drm_crtc * crtc )
140
+ static void tilcdc_crtc_enable (struct drm_crtc * crtc )
141
141
{
142
142
struct drm_device * dev = crtc -> dev ;
143
+ struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
144
+
145
+ if (tilcdc_crtc -> enabled )
146
+ return ;
147
+
148
+ pm_runtime_get_sync (dev -> dev );
143
149
144
150
reset (crtc );
145
151
@@ -150,14 +156,19 @@ static void start(struct drm_crtc *crtc)
150
156
tilcdc_set (dev , LCDC_RASTER_CTRL_REG , LCDC_RASTER_ENABLE );
151
157
152
158
drm_crtc_vblank_on (crtc );
159
+
160
+ tilcdc_crtc -> enabled = true;
153
161
}
154
162
155
- static void stop (struct drm_crtc * crtc )
163
+ void tilcdc_crtc_disable (struct drm_crtc * crtc )
156
164
{
157
165
struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
158
166
struct drm_device * dev = crtc -> dev ;
159
167
struct tilcdc_drm_private * priv = dev -> dev_private ;
160
168
169
+ if (!tilcdc_crtc -> enabled )
170
+ return ;
171
+
161
172
tilcdc_crtc -> frame_done = false;
162
173
tilcdc_clear (dev , LCDC_RASTER_CTRL_REG , LCDC_RASTER_ENABLE );
163
174
@@ -177,13 +188,37 @@ static void stop(struct drm_crtc *crtc)
177
188
drm_crtc_vblank_off (crtc );
178
189
179
190
tilcdc_crtc_disable_irqs (dev );
191
+
192
+ pm_runtime_put_sync (dev -> dev );
193
+
194
+ if (tilcdc_crtc -> next_fb ) {
195
+ drm_flip_work_queue (& tilcdc_crtc -> unref_work ,
196
+ tilcdc_crtc -> next_fb );
197
+ tilcdc_crtc -> next_fb = NULL ;
198
+ }
199
+
200
+ if (tilcdc_crtc -> curr_fb ) {
201
+ drm_flip_work_queue (& tilcdc_crtc -> unref_work ,
202
+ tilcdc_crtc -> curr_fb );
203
+ tilcdc_crtc -> curr_fb = NULL ;
204
+ }
205
+
206
+ drm_flip_work_commit (& tilcdc_crtc -> unref_work , priv -> wq );
207
+ tilcdc_crtc -> last_vblank = ktime_set (0 , 0 );
208
+
209
+ tilcdc_crtc -> enabled = false;
210
+ }
211
+
212
+ static bool tilcdc_crtc_is_on (struct drm_crtc * crtc )
213
+ {
214
+ return crtc -> state && crtc -> state -> enable && crtc -> state -> active ;
180
215
}
181
216
182
217
static void tilcdc_crtc_destroy (struct drm_crtc * crtc )
183
218
{
184
219
struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
185
220
186
- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
221
+ tilcdc_crtc_disable (crtc );
187
222
188
223
of_node_put (crtc -> port );
189
224
drm_crtc_cleanup (crtc );
@@ -237,52 +272,6 @@ int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
237
272
return 0 ;
238
273
}
239
274
240
- void tilcdc_crtc_dpms (struct drm_crtc * crtc , int mode )
241
- {
242
- struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
243
- struct drm_device * dev = crtc -> dev ;
244
- struct tilcdc_drm_private * priv = dev -> dev_private ;
245
-
246
- /* we really only care about on or off: */
247
- if (mode != DRM_MODE_DPMS_ON )
248
- mode = DRM_MODE_DPMS_OFF ;
249
-
250
- if (tilcdc_crtc -> dpms == mode )
251
- return ;
252
-
253
- tilcdc_crtc -> dpms = mode ;
254
-
255
- if (mode == DRM_MODE_DPMS_ON ) {
256
- pm_runtime_get_sync (dev -> dev );
257
- start (crtc );
258
- } else {
259
- stop (crtc );
260
- pm_runtime_put_sync (dev -> dev );
261
-
262
- if (tilcdc_crtc -> next_fb ) {
263
- drm_flip_work_queue (& tilcdc_crtc -> unref_work ,
264
- tilcdc_crtc -> next_fb );
265
- tilcdc_crtc -> next_fb = NULL ;
266
- }
267
-
268
- if (tilcdc_crtc -> curr_fb ) {
269
- drm_flip_work_queue (& tilcdc_crtc -> unref_work ,
270
- tilcdc_crtc -> curr_fb );
271
- tilcdc_crtc -> curr_fb = NULL ;
272
- }
273
-
274
- drm_flip_work_commit (& tilcdc_crtc -> unref_work , priv -> wq );
275
- tilcdc_crtc -> last_vblank = ktime_set (0 , 0 );
276
- }
277
- }
278
-
279
- int tilcdc_crtc_current_dpms_state (struct drm_crtc * crtc )
280
- {
281
- struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
282
-
283
- return tilcdc_crtc -> dpms ;
284
- }
285
-
286
275
static bool tilcdc_crtc_mode_fixup (struct drm_crtc * crtc ,
287
276
const struct drm_display_mode * mode ,
288
277
struct drm_display_mode * adjusted_mode )
@@ -312,16 +301,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
312
301
return true;
313
302
}
314
303
315
- static void tilcdc_crtc_disable (struct drm_crtc * crtc )
316
- {
317
- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
318
- }
319
-
320
- static void tilcdc_crtc_enable (struct drm_crtc * crtc )
321
- {
322
- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_ON );
323
- }
324
-
325
304
static void tilcdc_crtc_mode_set_nofb (struct drm_crtc * crtc )
326
305
{
327
306
struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
@@ -655,18 +634,15 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
655
634
656
635
void tilcdc_crtc_update_clk (struct drm_crtc * crtc )
657
636
{
658
- struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
659
637
struct drm_device * dev = crtc -> dev ;
660
638
struct tilcdc_drm_private * priv = dev -> dev_private ;
661
- int dpms = tilcdc_crtc -> dpms ;
662
639
unsigned long lcd_clk ;
663
640
const unsigned clkdiv = 2 ; /* using a fixed divider of 2 */
664
641
int ret ;
665
642
666
643
pm_runtime_get_sync (dev -> dev );
667
644
668
- if (dpms == DRM_MODE_DPMS_ON )
669
- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
645
+ tilcdc_crtc_disable (crtc );
670
646
671
647
/* mode.clock is in KHz, set_rate wants parameter in Hz */
672
648
ret = clk_set_rate (priv -> clk , crtc -> mode .clock * 1000 * clkdiv );
@@ -690,8 +666,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
690
666
LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN |
691
667
LCDC_V2_CORE_CLK_EN );
692
668
693
- if (dpms == DRM_MODE_DPMS_ON )
694
- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_ON );
669
+ if (tilcdc_crtc_is_on ( crtc ) )
670
+ tilcdc_crtc_enable (crtc );
695
671
696
672
out :
697
673
pm_runtime_put_sync (dev -> dev );
@@ -821,7 +797,6 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
821
797
if (ret < 0 )
822
798
goto fail ;
823
799
824
- tilcdc_crtc -> dpms = DRM_MODE_DPMS_OFF ;
825
800
init_waitqueue_head (& tilcdc_crtc -> frame_done_wq );
826
801
827
802
drm_flip_work_init (& tilcdc_crtc -> unref_work ,
0 commit comments