1*1bb76ff1Sjsg /*
2*1bb76ff1Sjsg * Copyright 2021 Advanced Micro Devices, Inc.
3*1bb76ff1Sjsg *
4*1bb76ff1Sjsg * Permission is hereby granted, free of charge, to any person obtaining a
5*1bb76ff1Sjsg * copy of this software and associated documentation files (the "Software"),
6*1bb76ff1Sjsg * to deal in the Software without restriction, including without limitation
7*1bb76ff1Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*1bb76ff1Sjsg * and/or sell copies of the Software, and to permit persons to whom the
9*1bb76ff1Sjsg * Software is furnished to do so, subject to the following conditions:
10*1bb76ff1Sjsg *
11*1bb76ff1Sjsg * The above copyright notice and this permission notice shall be included in
12*1bb76ff1Sjsg * all copies or substantial portions of the Software.
13*1bb76ff1Sjsg *
14*1bb76ff1Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*1bb76ff1Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*1bb76ff1Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*1bb76ff1Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*1bb76ff1Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*1bb76ff1Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*1bb76ff1Sjsg * OTHER DEALINGS IN THE SOFTWARE.
21*1bb76ff1Sjsg *
22*1bb76ff1Sjsg */
23*1bb76ff1Sjsg
24*1bb76ff1Sjsg #include "amdgpu.h"
25*1bb76ff1Sjsg #include "amdgpu_display.h"
26*1bb76ff1Sjsg #include "hwmgr.h"
27*1bb76ff1Sjsg #include "amdgpu_smu.h"
28*1bb76ff1Sjsg #include "amdgpu_dpm_internal.h"
29*1bb76ff1Sjsg
amdgpu_dpm_get_active_displays(struct amdgpu_device * adev)30*1bb76ff1Sjsg void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
31*1bb76ff1Sjsg {
32*1bb76ff1Sjsg struct drm_device *ddev = adev_to_drm(adev);
33*1bb76ff1Sjsg struct drm_crtc *crtc;
34*1bb76ff1Sjsg struct amdgpu_crtc *amdgpu_crtc;
35*1bb76ff1Sjsg
36*1bb76ff1Sjsg adev->pm.dpm.new_active_crtcs = 0;
37*1bb76ff1Sjsg adev->pm.dpm.new_active_crtc_count = 0;
38*1bb76ff1Sjsg if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
39*1bb76ff1Sjsg list_for_each_entry(crtc,
40*1bb76ff1Sjsg &ddev->mode_config.crtc_list, head) {
41*1bb76ff1Sjsg amdgpu_crtc = to_amdgpu_crtc(crtc);
42*1bb76ff1Sjsg if (amdgpu_crtc->enabled) {
43*1bb76ff1Sjsg adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
44*1bb76ff1Sjsg adev->pm.dpm.new_active_crtc_count++;
45*1bb76ff1Sjsg }
46*1bb76ff1Sjsg }
47*1bb76ff1Sjsg }
48*1bb76ff1Sjsg }
49*1bb76ff1Sjsg
amdgpu_dpm_get_vblank_time(struct amdgpu_device * adev)50*1bb76ff1Sjsg u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
51*1bb76ff1Sjsg {
52*1bb76ff1Sjsg struct drm_device *dev = adev_to_drm(adev);
53*1bb76ff1Sjsg struct drm_crtc *crtc;
54*1bb76ff1Sjsg struct amdgpu_crtc *amdgpu_crtc;
55*1bb76ff1Sjsg u32 vblank_in_pixels;
56*1bb76ff1Sjsg u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
57*1bb76ff1Sjsg
58*1bb76ff1Sjsg if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
59*1bb76ff1Sjsg list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
60*1bb76ff1Sjsg amdgpu_crtc = to_amdgpu_crtc(crtc);
61*1bb76ff1Sjsg if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
62*1bb76ff1Sjsg vblank_in_pixels =
63*1bb76ff1Sjsg amdgpu_crtc->hw_mode.crtc_htotal *
64*1bb76ff1Sjsg (amdgpu_crtc->hw_mode.crtc_vblank_end -
65*1bb76ff1Sjsg amdgpu_crtc->hw_mode.crtc_vdisplay +
66*1bb76ff1Sjsg (amdgpu_crtc->v_border * 2));
67*1bb76ff1Sjsg
68*1bb76ff1Sjsg vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
69*1bb76ff1Sjsg break;
70*1bb76ff1Sjsg }
71*1bb76ff1Sjsg }
72*1bb76ff1Sjsg }
73*1bb76ff1Sjsg
74*1bb76ff1Sjsg return vblank_time_us;
75*1bb76ff1Sjsg }
76*1bb76ff1Sjsg
amdgpu_dpm_get_vrefresh(struct amdgpu_device * adev)77*1bb76ff1Sjsg u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
78*1bb76ff1Sjsg {
79*1bb76ff1Sjsg struct drm_device *dev = adev_to_drm(adev);
80*1bb76ff1Sjsg struct drm_crtc *crtc;
81*1bb76ff1Sjsg struct amdgpu_crtc *amdgpu_crtc;
82*1bb76ff1Sjsg u32 vrefresh = 0;
83*1bb76ff1Sjsg
84*1bb76ff1Sjsg if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
85*1bb76ff1Sjsg list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
86*1bb76ff1Sjsg amdgpu_crtc = to_amdgpu_crtc(crtc);
87*1bb76ff1Sjsg if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
88*1bb76ff1Sjsg vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
89*1bb76ff1Sjsg break;
90*1bb76ff1Sjsg }
91*1bb76ff1Sjsg }
92*1bb76ff1Sjsg }
93*1bb76ff1Sjsg
94*1bb76ff1Sjsg return vrefresh;
95*1bb76ff1Sjsg }
96