20
20
#include "regs-vp.h"
21
21
22
22
#include <linux/kernel.h>
23
+ #include <linux/ktime.h>
23
24
#include <linux/spinlock.h>
24
25
#include <linux/wait.h>
25
26
#include <linux/i2c.h>
@@ -352,15 +353,62 @@ static void mixer_cfg_vp_blend(struct mixer_context *ctx, unsigned int alpha)
352
353
mixer_reg_write (ctx , MXR_VIDEO_CFG , val );
353
354
}
354
355
355
- static void mixer_vsync_set_update (struct mixer_context * ctx , bool enable )
356
+ static bool mixer_is_synced (struct mixer_context * ctx )
356
357
{
357
- /* block update on vsync */
358
- mixer_reg_writemask (ctx , MXR_STATUS , enable ?
359
- MXR_STATUS_SYNC_ENABLE : 0 , MXR_STATUS_SYNC_ENABLE );
358
+ u32 base , shadow ;
360
359
360
+ if (ctx -> mxr_ver == MXR_VER_16_0_33_0 ||
361
+ ctx -> mxr_ver == MXR_VER_128_0_0_184 )
362
+ return !(mixer_reg_read (ctx , MXR_CFG ) &
363
+ MXR_CFG_LAYER_UPDATE_COUNT_MASK );
364
+
365
+ if (test_bit (MXR_BIT_VP_ENABLED , & ctx -> flags ) &&
366
+ vp_reg_read (ctx , VP_SHADOW_UPDATE ))
367
+ return false;
368
+
369
+ base = mixer_reg_read (ctx , MXR_CFG );
370
+ shadow = mixer_reg_read (ctx , MXR_CFG_S );
371
+ if (base != shadow )
372
+ return false;
373
+
374
+ base = mixer_reg_read (ctx , MXR_GRAPHIC_BASE (0 ));
375
+ shadow = mixer_reg_read (ctx , MXR_GRAPHIC_BASE_S (0 ));
376
+ if (base != shadow )
377
+ return false;
378
+
379
+ base = mixer_reg_read (ctx , MXR_GRAPHIC_BASE (1 ));
380
+ shadow = mixer_reg_read (ctx , MXR_GRAPHIC_BASE_S (1 ));
381
+ if (base != shadow )
382
+ return false;
383
+
384
+ return true;
385
+ }
386
+
387
+ static int mixer_wait_for_sync (struct mixer_context * ctx )
388
+ {
389
+ ktime_t timeout = ktime_add_us (ktime_get (), 100000 );
390
+
391
+ while (!mixer_is_synced (ctx )) {
392
+ usleep_range (1000 , 2000 );
393
+ if (ktime_compare (ktime_get (), timeout ) > 0 )
394
+ return - ETIMEDOUT ;
395
+ }
396
+ return 0 ;
397
+ }
398
+
399
+ static void mixer_disable_sync (struct mixer_context * ctx )
400
+ {
401
+ mixer_reg_writemask (ctx , MXR_STATUS , 0 , MXR_STATUS_SYNC_ENABLE );
402
+ }
403
+
404
+ static void mixer_enable_sync (struct mixer_context * ctx )
405
+ {
406
+ if (ctx -> mxr_ver == MXR_VER_16_0_33_0 ||
407
+ ctx -> mxr_ver == MXR_VER_128_0_0_184 )
408
+ mixer_reg_writemask (ctx , MXR_CFG , ~0 , MXR_CFG_LAYER_UPDATE );
409
+ mixer_reg_writemask (ctx , MXR_STATUS , ~0 , MXR_STATUS_SYNC_ENABLE );
361
410
if (test_bit (MXR_BIT_VP_ENABLED , & ctx -> flags ))
362
- vp_reg_write (ctx , VP_SHADOW_UPDATE , enable ?
363
- VP_SHADOW_UPDATE_ENABLE : 0 );
411
+ vp_reg_write (ctx , VP_SHADOW_UPDATE , VP_SHADOW_UPDATE_ENABLE );
364
412
}
365
413
366
414
static void mixer_cfg_scan (struct mixer_context * ctx , int width , int height )
@@ -498,7 +546,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
498
546
499
547
spin_lock_irqsave (& ctx -> reg_slock , flags );
500
548
501
- vp_reg_write (ctx , VP_SHADOW_UPDATE , 1 );
502
549
/* interlace or progressive scan mode */
503
550
val = (test_bit (MXR_BIT_INTERLACE , & ctx -> flags ) ? ~0 : 0 );
504
551
vp_reg_writemask (ctx , VP_MODE , val , VP_MODE_LINE_SKIP );
@@ -553,11 +600,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
553
600
vp_regs_dump (ctx );
554
601
}
555
602
556
- static void mixer_layer_update (struct mixer_context * ctx )
557
- {
558
- mixer_reg_writemask (ctx , MXR_CFG , ~0 , MXR_CFG_LAYER_UPDATE );
559
- }
560
-
561
603
static void mixer_graph_buffer (struct mixer_context * ctx ,
562
604
struct exynos_drm_plane * plane )
563
605
{
@@ -640,11 +682,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
640
682
mixer_cfg_layer (ctx , win , priority , true);
641
683
mixer_cfg_gfx_blend (ctx , win , pixel_alpha , state -> base .alpha );
642
684
643
- /* layer update mandatory for mixer 16.0.33.0 */
644
- if (ctx -> mxr_ver == MXR_VER_16_0_33_0 ||
645
- ctx -> mxr_ver == MXR_VER_128_0_0_184 )
646
- mixer_layer_update (ctx );
647
-
648
685
spin_unlock_irqrestore (& ctx -> reg_slock , flags );
649
686
650
687
mixer_regs_dump (ctx );
@@ -709,7 +746,7 @@ static void mixer_win_reset(struct mixer_context *ctx)
709
746
static irqreturn_t mixer_irq_handler (int irq , void * arg )
710
747
{
711
748
struct mixer_context * ctx = arg ;
712
- u32 val , base , shadow ;
749
+ u32 val ;
713
750
714
751
spin_lock (& ctx -> reg_slock );
715
752
@@ -723,26 +760,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
723
760
val &= ~MXR_INT_STATUS_VSYNC ;
724
761
725
762
/* interlace scan need to check shadow register */
726
- if (test_bit (MXR_BIT_INTERLACE , & ctx -> flags )) {
727
- if (test_bit (MXR_BIT_VP_ENABLED , & ctx -> flags ) &&
728
- vp_reg_read (ctx , VP_SHADOW_UPDATE ))
729
- goto out ;
730
-
731
- base = mixer_reg_read (ctx , MXR_CFG );
732
- shadow = mixer_reg_read (ctx , MXR_CFG_S );
733
- if (base != shadow )
734
- goto out ;
735
-
736
- base = mixer_reg_read (ctx , MXR_GRAPHIC_BASE (0 ));
737
- shadow = mixer_reg_read (ctx , MXR_GRAPHIC_BASE_S (0 ));
738
- if (base != shadow )
739
- goto out ;
740
-
741
- base = mixer_reg_read (ctx , MXR_GRAPHIC_BASE (1 ));
742
- shadow = mixer_reg_read (ctx , MXR_GRAPHIC_BASE_S (1 ));
743
- if (base != shadow )
744
- goto out ;
745
- }
763
+ if (test_bit (MXR_BIT_INTERLACE , & ctx -> flags )
764
+ && !mixer_is_synced (ctx ))
765
+ goto out ;
746
766
747
767
drm_crtc_handle_vblank (& ctx -> crtc -> base );
748
768
}
@@ -917,12 +937,14 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
917
937
918
938
static void mixer_atomic_begin (struct exynos_drm_crtc * crtc )
919
939
{
920
- struct mixer_context * mixer_ctx = crtc -> ctx ;
940
+ struct mixer_context * ctx = crtc -> ctx ;
921
941
922
- if (!test_bit (MXR_BIT_POWERED , & mixer_ctx -> flags ))
942
+ if (!test_bit (MXR_BIT_POWERED , & ctx -> flags ))
923
943
return ;
924
944
925
- mixer_vsync_set_update (mixer_ctx , false);
945
+ if (mixer_wait_for_sync (ctx ))
946
+ dev_err (ctx -> dev , "timeout waiting for VSYNC\n" );
947
+ mixer_disable_sync (ctx );
926
948
}
927
949
928
950
static void mixer_update_plane (struct exynos_drm_crtc * crtc ,
@@ -964,7 +986,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
964
986
if (!test_bit (MXR_BIT_POWERED , & mixer_ctx -> flags ))
965
987
return ;
966
988
967
- mixer_vsync_set_update (mixer_ctx , true );
989
+ mixer_enable_sync (mixer_ctx );
968
990
exynos_crtc_handle_event (crtc );
969
991
}
970
992
@@ -979,7 +1001,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
979
1001
980
1002
exynos_drm_pipe_clk_enable (crtc , true);
981
1003
982
- mixer_vsync_set_update (ctx , false );
1004
+ mixer_disable_sync (ctx );
983
1005
984
1006
mixer_reg_writemask (ctx , MXR_STATUS , ~0 , MXR_STATUS_SOFT_RESET );
985
1007
@@ -992,7 +1014,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
992
1014
993
1015
mixer_commit (ctx );
994
1016
995
- mixer_vsync_set_update (ctx , true );
1017
+ mixer_enable_sync (ctx );
996
1018
997
1019
set_bit (MXR_BIT_POWERED , & ctx -> flags );
998
1020
}
0 commit comments