16ddbd37fSEvan Quan /*
26ddbd37fSEvan Quan  * Copyright 2021 Advanced Micro Devices, Inc.
36ddbd37fSEvan Quan  *
46ddbd37fSEvan Quan  * Permission is hereby granted, free of charge, to any person obtaining a
56ddbd37fSEvan Quan  * copy of this software and associated documentation files (the "Software"),
66ddbd37fSEvan Quan  * to deal in the Software without restriction, including without limitation
76ddbd37fSEvan Quan  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86ddbd37fSEvan Quan  * and/or sell copies of the Software, and to permit persons to whom the
96ddbd37fSEvan Quan  * Software is furnished to do so, subject to the following conditions:
106ddbd37fSEvan Quan  *
116ddbd37fSEvan Quan  * The above copyright notice and this permission notice shall be included in
126ddbd37fSEvan Quan  * all copies or substantial portions of the Software.
136ddbd37fSEvan Quan  *
146ddbd37fSEvan Quan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156ddbd37fSEvan Quan  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
166ddbd37fSEvan Quan  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
176ddbd37fSEvan Quan  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
186ddbd37fSEvan Quan  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
196ddbd37fSEvan Quan  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
206ddbd37fSEvan Quan  * OTHER DEALINGS IN THE SOFTWARE.
216ddbd37fSEvan Quan  *
226ddbd37fSEvan Quan  */
236ddbd37fSEvan Quan 
246ddbd37fSEvan Quan #include "amdgpu.h"
256ddbd37fSEvan Quan #include "amdgpu_display.h"
266ddbd37fSEvan Quan #include "hwmgr.h"
276ddbd37fSEvan Quan #include "amdgpu_smu.h"
28*f54b6bdfSMaíra Canal #include "amdgpu_dpm_internal.h"
296ddbd37fSEvan Quan 
amdgpu_dpm_get_active_displays(struct amdgpu_device * adev)306ddbd37fSEvan Quan void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
316ddbd37fSEvan Quan {
326ddbd37fSEvan Quan 	struct drm_device *ddev = adev_to_drm(adev);
336ddbd37fSEvan Quan 	struct drm_crtc *crtc;
346ddbd37fSEvan Quan 	struct amdgpu_crtc *amdgpu_crtc;
356ddbd37fSEvan Quan 
366ddbd37fSEvan Quan 	adev->pm.dpm.new_active_crtcs = 0;
376ddbd37fSEvan Quan 	adev->pm.dpm.new_active_crtc_count = 0;
386ddbd37fSEvan Quan 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
396ddbd37fSEvan Quan 		list_for_each_entry(crtc,
406ddbd37fSEvan Quan 				    &ddev->mode_config.crtc_list, head) {
416ddbd37fSEvan Quan 			amdgpu_crtc = to_amdgpu_crtc(crtc);
426ddbd37fSEvan Quan 			if (amdgpu_crtc->enabled) {
436ddbd37fSEvan Quan 				adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
446ddbd37fSEvan Quan 				adev->pm.dpm.new_active_crtc_count++;
456ddbd37fSEvan Quan 			}
466ddbd37fSEvan Quan 		}
476ddbd37fSEvan Quan 	}
486ddbd37fSEvan Quan }
496ddbd37fSEvan Quan 
amdgpu_dpm_get_vblank_time(struct amdgpu_device * adev)506ddbd37fSEvan Quan u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
516ddbd37fSEvan Quan {
526ddbd37fSEvan Quan 	struct drm_device *dev = adev_to_drm(adev);
536ddbd37fSEvan Quan 	struct drm_crtc *crtc;
546ddbd37fSEvan Quan 	struct amdgpu_crtc *amdgpu_crtc;
556ddbd37fSEvan Quan 	u32 vblank_in_pixels;
566ddbd37fSEvan Quan 	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
576ddbd37fSEvan Quan 
586ddbd37fSEvan Quan 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
596ddbd37fSEvan Quan 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
606ddbd37fSEvan Quan 			amdgpu_crtc = to_amdgpu_crtc(crtc);
616ddbd37fSEvan Quan 			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
626ddbd37fSEvan Quan 				vblank_in_pixels =
636ddbd37fSEvan Quan 					amdgpu_crtc->hw_mode.crtc_htotal *
646ddbd37fSEvan Quan 					(amdgpu_crtc->hw_mode.crtc_vblank_end -
656ddbd37fSEvan Quan 					amdgpu_crtc->hw_mode.crtc_vdisplay +
666ddbd37fSEvan Quan 					(amdgpu_crtc->v_border * 2));
676ddbd37fSEvan Quan 
686ddbd37fSEvan Quan 				vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
696ddbd37fSEvan Quan 				break;
706ddbd37fSEvan Quan 			}
716ddbd37fSEvan Quan 		}
726ddbd37fSEvan Quan 	}
736ddbd37fSEvan Quan 
746ddbd37fSEvan Quan 	return vblank_time_us;
756ddbd37fSEvan Quan }
766ddbd37fSEvan Quan 
amdgpu_dpm_get_vrefresh(struct amdgpu_device * adev)776ddbd37fSEvan Quan u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
786ddbd37fSEvan Quan {
796ddbd37fSEvan Quan 	struct drm_device *dev = adev_to_drm(adev);
806ddbd37fSEvan Quan 	struct drm_crtc *crtc;
816ddbd37fSEvan Quan 	struct amdgpu_crtc *amdgpu_crtc;
826ddbd37fSEvan Quan 	u32 vrefresh = 0;
836ddbd37fSEvan Quan 
846ddbd37fSEvan Quan 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
856ddbd37fSEvan Quan 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
866ddbd37fSEvan Quan 			amdgpu_crtc = to_amdgpu_crtc(crtc);
876ddbd37fSEvan Quan 			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
886ddbd37fSEvan Quan 				vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
896ddbd37fSEvan Quan 				break;
906ddbd37fSEvan Quan 			}
916ddbd37fSEvan Quan 		}
926ddbd37fSEvan Quan 	}
936ddbd37fSEvan Quan 
946ddbd37fSEvan Quan 	return vrefresh;
956ddbd37fSEvan Quan }
96