@@ -937,7 +937,49 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
937937
938938}
939939#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 );
940959
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+ }
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
941983static int amdgpu_dm_init (struct amdgpu_device * adev )
942984{
943985 struct dc_init_data init_data ;
@@ -957,6 +999,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
957999
9581000 mutex_init (& adev -> dm .dc_lock );
9591001 mutex_init (& adev -> dm .audio_lock );
1002+ #if defined(CONFIG_DRM_AMD_DC_DCN )
1003+ spin_lock_init (& adev -> dm .vblank_lock );
1004+ #endif
9601005
9611006 if (amdgpu_dm_irq_init (adev )) {
9621007 DRM_ERROR ("amdgpu: failed to initialize DM IRQ support.\n" );
@@ -1071,6 +1116,17 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
10711116
10721117 amdgpu_dm_init_color_mod ();
10731118
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+
10741130#ifdef CONFIG_DRM_AMD_DC_HDCP
10751131 if (adev -> dm .dc -> caps .max_links > 0 && adev -> asic_type >= CHIP_RAVEN ) {
10761132 adev -> dm .hdcp_workqueue = hdcp_create_workqueue (adev , & init_params .cp_psp , adev -> dm .dc );
@@ -1936,7 +1992,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
19361992 dc_commit_updates_for_stream (
19371993 dm -> dc , bundle -> surface_updates ,
19381994 dc_state -> stream_status -> plane_count ,
1939- dc_state -> streams [k ], & bundle -> stream_update );
1995+ dc_state -> streams [k ], & bundle -> stream_update , dc_state );
19401996 }
19411997
19421998cleanup :
@@ -1967,7 +2023,8 @@ static void dm_set_dpms_off(struct dc_link *link)
19672023
19682024 stream_update .stream = stream_state ;
19692025 dc_commit_updates_for_stream (stream_state -> ctx -> dc , NULL , 0 ,
1970- stream_state , & stream_update );
2026+ stream_state , & stream_update ,
2027+ stream_state -> ctx -> dc -> current_state );
19712028 mutex_unlock (& adev -> dm .dc_lock );
19722029}
19732030
@@ -5374,7 +5431,10 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
53745431 struct amdgpu_crtc * acrtc = to_amdgpu_crtc (crtc );
53755432 struct amdgpu_device * adev = drm_to_adev (crtc -> dev );
53765433 struct dm_crtc_state * acrtc_state = to_dm_crtc_state (crtc -> state );
5434+ #if defined(CONFIG_DRM_AMD_DC_DCN )
53775435 struct amdgpu_display_manager * dm = & adev -> dm ;
5436+ unsigned long flags ;
5437+ #endif
53785438 int rc = 0 ;
53795439
53805440 if (enable ) {
@@ -5397,22 +5457,15 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
53975457 if (amdgpu_in_reset (adev ))
53985458 return 0 ;
53995459
5400- mutex_lock (& dm -> dc_lock );
5401-
5402- if (enable )
5403- dm -> active_vblank_irq_count ++ ;
5404- else
5405- dm -> active_vblank_irq_count -- ;
5406-
54075460#if defined(CONFIG_DRM_AMD_DC_DCN )
5408- dc_allow_idle_optimizations (
5409- adev -> dm .dc , dm -> active_vblank_irq_count == 0 ? true : false);
5410-
5411- 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 );
54125467#endif
54135468
5414- mutex_unlock (& dm -> dc_lock );
5415-
54165469 return 0 ;
54175470}
54185471
@@ -7663,7 +7716,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
76637716 struct drm_crtc * pcrtc ,
76647717 bool wait_for_vblank )
76657718{
7666- int i ;
7719+ uint32_t i ;
76677720 uint64_t timestamp_ns ;
76687721 struct drm_plane * plane ;
76697722 struct drm_plane_state * old_plane_state , * new_plane_state ;
@@ -7704,7 +7757,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
77047757 amdgpu_dm_commit_cursors (state );
77057758
77067759 /* update planes when needed */
7707- for_each_oldnew_plane_in_state_reverse (state , plane , old_plane_state , new_plane_state , i ) {
7760+ for_each_oldnew_plane_in_state (state , plane , old_plane_state , new_plane_state , i ) {
77087761 struct drm_crtc * crtc = new_plane_state -> crtc ;
77097762 struct drm_crtc_state * new_crtc_state ;
77107763 struct drm_framebuffer * fb = new_plane_state -> fb ;
@@ -7927,7 +7980,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
79277980 bundle -> surface_updates ,
79287981 planes_count ,
79297982 acrtc_state -> stream ,
7930- & bundle -> stream_update );
7983+ & bundle -> stream_update ,
7984+ dc_state );
79317985
79327986 /**
79337987 * Enable or disable the interrupts on the backend.
@@ -8263,13 +8317,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
82638317 struct dm_connector_state * dm_new_con_state = to_dm_connector_state (new_con_state );
82648318 struct dm_connector_state * dm_old_con_state = to_dm_connector_state (old_con_state );
82658319 struct amdgpu_crtc * acrtc = to_amdgpu_crtc (dm_new_con_state -> base .crtc );
8266- struct dc_surface_update surface_updates [MAX_SURFACES ];
8320+ struct dc_surface_update dummy_updates [MAX_SURFACES ];
82678321 struct dc_stream_update stream_update ;
82688322 struct dc_info_packet hdr_packet ;
82698323 struct dc_stream_status * status = NULL ;
82708324 bool abm_changed , hdr_changed , scaling_changed ;
82718325
8272- memset (& surface_updates , 0 , sizeof (surface_updates ));
8326+ memset (& dummy_updates , 0 , sizeof (dummy_updates ));
82738327 memset (& stream_update , 0 , sizeof (stream_update ));
82748328
82758329 if (acrtc ) {
@@ -8326,15 +8380,16 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
83268380 * To fix this, DC should permit updating only stream properties.
83278381 */
83288382 for (j = 0 ; j < status -> plane_count ; j ++ )
8329- surface_updates [j ].surface = status -> plane_states [j ];
8383+ dummy_updates [j ].surface = status -> plane_states [0 ];
83308384
83318385
83328386 mutex_lock (& dm -> dc_lock );
83338387 dc_commit_updates_for_stream (dm -> dc ,
8334- surface_updates ,
8388+ dummy_updates ,
83358389 status -> plane_count ,
83368390 dm_new_crtc_state -> stream ,
8337- & stream_update );
8391+ & stream_update ,
8392+ dc_state );
83388393 mutex_unlock (& dm -> dc_lock );
83398394 }
83408395
0 commit comments