@@ -937,7 +937,49 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
937
937
938
938
}
939
939
#endif
940
+ #if defined(CONFIG_DRM_AMD_DC_DCN )
941
+ static void event_mall_stutter (struct work_struct * work )
942
+ {
943
+
944
+ struct vblank_workqueue * vblank_work = container_of (work , struct vblank_workqueue , mall_work );
945
+ struct amdgpu_display_manager * dm = vblank_work -> dm ;
946
+
947
+ mutex_lock (& dm -> dc_lock );
948
+
949
+ if (vblank_work -> enable )
950
+ dm -> active_vblank_irq_count ++ ;
951
+ else
952
+ dm -> active_vblank_irq_count -- ;
953
+
954
+
955
+ dc_allow_idle_optimizations (
956
+ dm -> dc , dm -> active_vblank_irq_count == 0 ? true : false);
957
+
958
+ DRM_DEBUG_DRIVER ("Allow idle optimizations (MALL): %d\n" , dm -> active_vblank_irq_count == 0 );
959
+
960
+
961
+ mutex_unlock (& dm -> dc_lock );
962
+ }
963
+
964
+ static struct vblank_workqueue * vblank_create_workqueue (struct amdgpu_device * adev , struct dc * dc )
965
+ {
966
+
967
+ int max_caps = dc -> caps .max_links ;
968
+ struct vblank_workqueue * vblank_work ;
969
+ int i = 0 ;
970
+
971
+ vblank_work = kcalloc (max_caps , sizeof (* vblank_work ), GFP_KERNEL );
972
+ if (ZERO_OR_NULL_PTR (vblank_work )) {
973
+ kfree (vblank_work );
974
+ return NULL ;
975
+ }
940
976
977
+ for (i = 0 ; i < max_caps ; i ++ )
978
+ INIT_WORK (& vblank_work [i ].mall_work , event_mall_stutter );
979
+
980
+ return vblank_work ;
981
+ }
982
+ #endif
941
983
static int amdgpu_dm_init (struct amdgpu_device * adev )
942
984
{
943
985
struct dc_init_data init_data ;
@@ -957,6 +999,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
957
999
958
1000
mutex_init (& adev -> dm .dc_lock );
959
1001
mutex_init (& adev -> dm .audio_lock );
1002
+ #if defined(CONFIG_DRM_AMD_DC_DCN )
1003
+ spin_lock_init (& adev -> dm .vblank_lock );
1004
+ #endif
960
1005
961
1006
if (amdgpu_dm_irq_init (adev )) {
962
1007
DRM_ERROR ("amdgpu: failed to initialize DM IRQ support.\n" );
@@ -1071,6 +1116,17 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
1071
1116
1072
1117
amdgpu_dm_init_color_mod ();
1073
1118
1119
+ #if defined(CONFIG_DRM_AMD_DC_DCN )
1120
+ if (adev -> dm .dc -> caps .max_links > 0 ) {
1121
+ adev -> dm .vblank_workqueue = vblank_create_workqueue (adev , adev -> dm .dc );
1122
+
1123
+ if (!adev -> dm .vblank_workqueue )
1124
+ DRM_ERROR ("amdgpu: failed to initialize vblank_workqueue.\n" );
1125
+ else
1126
+ DRM_DEBUG_DRIVER ("amdgpu: vblank_workqueue init done %p.\n" , adev -> dm .vblank_workqueue );
1127
+ }
1128
+ #endif
1129
+
1074
1130
#ifdef CONFIG_DRM_AMD_DC_HDCP
1075
1131
if (adev -> dm .dc -> caps .max_links > 0 && adev -> asic_type >= CHIP_RAVEN ) {
1076
1132
adev -> dm .hdcp_workqueue = hdcp_create_workqueue (adev , & init_params .cp_psp , adev -> dm .dc );
@@ -5375,7 +5431,10 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
5375
5431
struct amdgpu_crtc * acrtc = to_amdgpu_crtc (crtc );
5376
5432
struct amdgpu_device * adev = drm_to_adev (crtc -> dev );
5377
5433
struct dm_crtc_state * acrtc_state = to_dm_crtc_state (crtc -> state );
5434
+ #if defined(CONFIG_DRM_AMD_DC_DCN )
5378
5435
struct amdgpu_display_manager * dm = & adev -> dm ;
5436
+ unsigned long flags ;
5437
+ #endif
5379
5438
int rc = 0 ;
5380
5439
5381
5440
if (enable ) {
@@ -5398,22 +5457,15 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
5398
5457
if (amdgpu_in_reset (adev ))
5399
5458
return 0 ;
5400
5459
5401
- mutex_lock (& dm -> dc_lock );
5402
-
5403
- if (enable )
5404
- dm -> active_vblank_irq_count ++ ;
5405
- else
5406
- dm -> active_vblank_irq_count -- ;
5407
-
5408
5460
#if defined(CONFIG_DRM_AMD_DC_DCN )
5409
- dc_allow_idle_optimizations (
5410
- adev -> dm .dc , dm -> active_vblank_irq_count == 0 ? true : false);
5411
-
5412
- DRM_DEBUG_DRIVER ("Allow idle optimizations (MALL): %d\n" , dm -> active_vblank_irq_count == 0 );
5461
+ spin_lock_irqsave (& dm -> vblank_lock , flags );
5462
+ dm -> vblank_workqueue -> dm = dm ;
5463
+ dm -> vblank_workqueue -> otg_inst = acrtc -> otg_inst ;
5464
+ dm -> vblank_workqueue -> enable = enable ;
5465
+ spin_unlock_irqrestore (& dm -> vblank_lock , flags );
5466
+ schedule_work (& dm -> vblank_workqueue -> mall_work );
5413
5467
#endif
5414
5468
5415
- mutex_unlock (& dm -> dc_lock );
5416
-
5417
5469
return 0 ;
5418
5470
}
5419
5471
0 commit comments