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