1111#include <linux/media-bus-format.h>
1212#include <linux/pm_runtime.h>
1313
14+ #include <drm/drm_atomic_helper.h>
15+ #include <drm/drm_atomic_state_helper.h>
16+ #include <drm/drm_atomic_uapi.h>
1417#include <drm/drm_crtc.h>
1518#include <drm/drm_crtc_helper.h>
1619#include <drm/drm_fb_dma_helper.h>
@@ -199,20 +202,14 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
199202 struct drm_crtc * crtc = & scrtc -> base ;
200203 struct shmob_drm_device * sdev = to_shmob_device (crtc -> dev );
201204 const struct shmob_drm_interface_data * idata = & sdev -> pdata -> iface ;
202- const struct shmob_drm_format_info * format ;
203- struct drm_device * dev = & sdev -> ddev ;
204- struct drm_plane * plane ;
205+ struct device * dev = sdev -> dev ;
205206 u32 value ;
206207 int ret ;
207208
208209 if (scrtc -> started )
209210 return ;
210211
211- format = shmob_drm_format_info (crtc -> primary -> fb -> format -> format );
212- if (WARN_ON (format == NULL ))
213- return ;
214-
215- ret = pm_runtime_resume_and_get (sdev -> dev );
212+ ret = pm_runtime_resume_and_get (dev );
216213 if (ret )
217214 return ;
218215
@@ -249,23 +246,8 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
249246 /* Setup geometry, format, frame buffer memory and operation mode. */
250247 shmob_drm_crtc_setup_geometry (scrtc );
251248
252- /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
253- lcdc_write (sdev , LDDFR , format -> lddfr | LDDFR_CF1 );
254- lcdc_write (sdev , LDMLSR , scrtc -> line_size );
255- lcdc_write (sdev , LDSA1R , scrtc -> dma [0 ]);
256- if (shmob_drm_format_is_yuv (format ))
257- lcdc_write (sdev , LDSA2R , scrtc -> dma [1 ]);
258249 lcdc_write (sdev , LDSM1R , 0 );
259250
260- /* Word and long word swap. */
261- lcdc_write (sdev , LDDDSR , format -> ldddsr );
262-
263- /* Setup planes. */
264- drm_for_each_legacy_plane (plane , dev ) {
265- if (plane -> crtc == crtc )
266- shmob_drm_plane_setup (plane );
267- }
268-
269251 /* Enable the display output. */
270252 lcdc_write (sdev , LDCNT1R , LDCNT1R_DE );
271253
@@ -317,42 +299,6 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
317299 shmob_drm_crtc_start (scrtc );
318300}
319301
320- static void shmob_drm_crtc_compute_base (struct shmob_drm_crtc * scrtc ,
321- int x , int y )
322- {
323- struct drm_crtc * crtc = & scrtc -> base ;
324- struct drm_framebuffer * fb = crtc -> primary -> fb ;
325- struct drm_gem_dma_object * gem ;
326- unsigned int bpp ;
327-
328- bpp = shmob_drm_format_is_yuv (scrtc -> format ) ? 8 : scrtc -> format -> bpp ;
329- gem = drm_fb_dma_get_gem_obj (fb , 0 );
330- scrtc -> dma [0 ] = gem -> dma_addr + fb -> offsets [0 ]
331- + y * fb -> pitches [0 ] + x * bpp / 8 ;
332-
333- if (shmob_drm_format_is_yuv (scrtc -> format )) {
334- bpp = scrtc -> format -> bpp - 8 ;
335- gem = drm_fb_dma_get_gem_obj (fb , 1 );
336- scrtc -> dma [1 ] = gem -> dma_addr + fb -> offsets [1 ]
337- + y / (bpp == 4 ? 2 : 1 ) * fb -> pitches [1 ]
338- + x * (bpp == 16 ? 2 : 1 );
339- }
340- }
341-
342- static void shmob_drm_crtc_update_base (struct shmob_drm_crtc * scrtc )
343- {
344- struct drm_crtc * crtc = & scrtc -> base ;
345- struct shmob_drm_device * sdev = to_shmob_device (crtc -> dev );
346-
347- shmob_drm_crtc_compute_base (scrtc , crtc -> x , crtc -> y );
348-
349- lcdc_write_mirror (sdev , LDSA1R , scrtc -> dma [0 ]);
350- if (shmob_drm_format_is_yuv (scrtc -> format ))
351- lcdc_write_mirror (sdev , LDSA2R , scrtc -> dma [1 ]);
352-
353- lcdc_write (sdev , LDRCNTR , lcdc_read (sdev , LDRCNTR ) ^ LDRCNTR_MRS );
354- }
355-
356302static inline struct shmob_drm_crtc * to_shmob_crtc (struct drm_crtc * crtc )
357303{
358304 return container_of (crtc , struct shmob_drm_crtc , base );
@@ -378,50 +324,45 @@ static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc)
378324 shmob_drm_crtc_dpms (crtc , DRM_MODE_DPMS_OFF );
379325}
380326
381- static int shmob_drm_crtc_mode_set (struct drm_crtc * crtc ,
382- struct drm_display_mode * mode ,
383- struct drm_display_mode * adjusted_mode ,
384- int x , int y ,
385- struct drm_framebuffer * old_fb )
327+ static void shmob_drm_crtc_mode_commit (struct drm_crtc * crtc )
386328{
387- struct shmob_drm_device * sdev = to_shmob_device (crtc -> dev );
388- struct shmob_drm_crtc * scrtc = to_shmob_crtc (crtc );
389- const struct shmob_drm_format_info * format ;
390-
391- format = shmob_drm_format_info (crtc -> primary -> fb -> format -> format );
392- if (format == NULL ) {
393- dev_dbg (sdev -> dev , "mode_set: unsupported format %p4cc\n" ,
394- & crtc -> primary -> fb -> format -> format );
395- return - EINVAL ;
396- }
397-
398- scrtc -> format = format ;
399- scrtc -> line_size = crtc -> primary -> fb -> pitches [0 ];
400-
401- shmob_drm_crtc_compute_base (scrtc , x , y );
329+ shmob_drm_crtc_dpms (crtc , DRM_MODE_DPMS_ON );
330+ }
402331
332+ static int shmob_drm_crtc_atomic_check (struct drm_crtc * crtc ,
333+ struct drm_atomic_state * state )
334+ {
403335 return 0 ;
404336}
405337
406- static void shmob_drm_crtc_mode_commit (struct drm_crtc * crtc )
338+ static void shmob_drm_crtc_atomic_begin (struct drm_crtc * crtc ,
339+ struct drm_atomic_state * state )
407340{
408- shmob_drm_crtc_dpms (crtc , DRM_MODE_DPMS_ON );
409341}
410342
411- static int shmob_drm_crtc_mode_set_base (struct drm_crtc * crtc , int x , int y ,
412- struct drm_framebuffer * old_fb )
343+ static void shmob_drm_crtc_atomic_flush (struct drm_crtc * crtc ,
344+ struct drm_atomic_state * state )
413345{
414- shmob_drm_crtc_update_base (to_shmob_crtc (crtc ));
346+ struct drm_pending_vblank_event * event ;
347+ struct drm_device * dev = crtc -> dev ;
348+ unsigned long flags ;
415349
416- return 0 ;
350+ if (crtc -> state -> event ) {
351+ spin_lock_irqsave (& dev -> event_lock , flags );
352+ event = crtc -> state -> event ;
353+ crtc -> state -> event = NULL ;
354+ drm_crtc_send_vblank_event (crtc , event );
355+ spin_unlock_irqrestore (& dev -> event_lock , flags );
356+ }
417357}
418358
419359static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
420360 .dpms = shmob_drm_crtc_dpms ,
421361 .prepare = shmob_drm_crtc_mode_prepare ,
422362 .commit = shmob_drm_crtc_mode_commit ,
423- .mode_set = shmob_drm_crtc_mode_set ,
424- .mode_set_base = shmob_drm_crtc_mode_set_base ,
363+ .atomic_check = shmob_drm_crtc_atomic_check ,
364+ .atomic_begin = shmob_drm_crtc_atomic_begin ,
365+ .atomic_flush = shmob_drm_crtc_atomic_flush ,
425366};
426367
427368static int shmob_drm_crtc_page_flip (struct drm_crtc * crtc ,
@@ -441,8 +382,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
441382 }
442383 spin_unlock_irqrestore (& dev -> event_lock , flags );
443384
444- crtc -> primary -> fb = fb ;
445- shmob_drm_crtc_update_base (scrtc );
385+ drm_atomic_set_fb_for_plane (crtc -> primary -> state , fb );
446386
447387 if (event ) {
448388 event -> pipe = 0 ;
@@ -489,9 +429,12 @@ static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
489429}
490430
491431static const struct drm_crtc_funcs crtc_funcs = {
432+ .reset = drm_atomic_helper_crtc_reset ,
492433 .destroy = drm_crtc_cleanup ,
493- .set_config = drm_crtc_helper_set_config ,
434+ .set_config = drm_atomic_helper_set_config ,
494435 .page_flip = shmob_drm_crtc_page_flip ,
436+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state ,
437+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state ,
495438 .enable_vblank = shmob_drm_enable_vblank ,
496439 .disable_vblank = shmob_drm_disable_vblank ,
497440};
@@ -627,8 +570,11 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
627570
628571static const struct drm_connector_funcs connector_funcs = {
629572 .dpms = drm_helper_connector_dpms ,
573+ .reset = drm_atomic_helper_connector_reset ,
630574 .fill_modes = drm_helper_probe_single_connector_modes ,
631575 .destroy = shmob_drm_connector_destroy ,
576+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state ,
577+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state ,
632578};
633579
634580static struct drm_connector *
0 commit comments