@@ -30,7 +30,7 @@ struct tilcdc_crtc {
3030 struct drm_plane primary ;
3131 const struct tilcdc_panel_info * info ;
3232 struct drm_pending_vblank_event * event ;
33- int dpms ;
33+ bool enabled ;
3434 wait_queue_head_t frame_done_wq ;
3535 bool frame_done ;
3636 spinlock_t irq_lock ;
@@ -137,9 +137,15 @@ static void reset(struct drm_crtc *crtc)
137137 tilcdc_clear (dev , LCDC_CLK_RESET_REG , LCDC_CLK_MAIN_RESET );
138138}
139139
140- static void start (struct drm_crtc * crtc )
140+ static void tilcdc_crtc_enable (struct drm_crtc * crtc )
141141{
142142 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 );
143149
144150 reset (crtc );
145151
@@ -150,14 +156,19 @@ static void start(struct drm_crtc *crtc)
150156 tilcdc_set (dev , LCDC_RASTER_CTRL_REG , LCDC_RASTER_ENABLE );
151157
152158 drm_crtc_vblank_on (crtc );
159+
160+ tilcdc_crtc -> enabled = true;
153161}
154162
155- static void stop (struct drm_crtc * crtc )
163+ void tilcdc_crtc_disable (struct drm_crtc * crtc )
156164{
157165 struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
158166 struct drm_device * dev = crtc -> dev ;
159167 struct tilcdc_drm_private * priv = dev -> dev_private ;
160168
169+ if (!tilcdc_crtc -> enabled )
170+ return ;
171+
161172 tilcdc_crtc -> frame_done = false;
162173 tilcdc_clear (dev , LCDC_RASTER_CTRL_REG , LCDC_RASTER_ENABLE );
163174
@@ -177,13 +188,37 @@ static void stop(struct drm_crtc *crtc)
177188 drm_crtc_vblank_off (crtc );
178189
179190 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 ;
180215}
181216
182217static void tilcdc_crtc_destroy (struct drm_crtc * crtc )
183218{
184219 struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
185220
186- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
221+ tilcdc_crtc_disable (crtc );
187222
188223 of_node_put (crtc -> port );
189224 drm_crtc_cleanup (crtc );
@@ -237,52 +272,6 @@ int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
237272 return 0 ;
238273}
239274
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-
286275static bool tilcdc_crtc_mode_fixup (struct drm_crtc * crtc ,
287276 const struct drm_display_mode * mode ,
288277 struct drm_display_mode * adjusted_mode )
@@ -312,16 +301,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
312301 return true;
313302}
314303
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-
325304static void tilcdc_crtc_mode_set_nofb (struct drm_crtc * crtc )
326305{
327306 struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
@@ -655,18 +634,15 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
655634
656635void tilcdc_crtc_update_clk (struct drm_crtc * crtc )
657636{
658- struct tilcdc_crtc * tilcdc_crtc = to_tilcdc_crtc (crtc );
659637 struct drm_device * dev = crtc -> dev ;
660638 struct tilcdc_drm_private * priv = dev -> dev_private ;
661- int dpms = tilcdc_crtc -> dpms ;
662639 unsigned long lcd_clk ;
663640 const unsigned clkdiv = 2 ; /* using a fixed divider of 2 */
664641 int ret ;
665642
666643 pm_runtime_get_sync (dev -> dev );
667644
668- if (dpms == DRM_MODE_DPMS_ON )
669- tilcdc_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
645+ tilcdc_crtc_disable (crtc );
670646
671647 /* mode.clock is in KHz, set_rate wants parameter in Hz */
672648 ret = clk_set_rate (priv -> clk , crtc -> mode .clock * 1000 * clkdiv );
@@ -690,8 +666,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
690666 LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN |
691667 LCDC_V2_CORE_CLK_EN );
692668
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 );
695671
696672out :
697673 pm_runtime_put_sync (dev -> dev );
@@ -821,7 +797,6 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
821797 if (ret < 0 )
822798 goto fail ;
823799
824- tilcdc_crtc -> dpms = DRM_MODE_DPMS_OFF ;
825800 init_waitqueue_head (& tilcdc_crtc -> frame_done_wq );
826801
827802 drm_flip_work_init (& tilcdc_crtc -> unref_work ,
0 commit comments