xref: /openbsd-src/sys/dev/pci/drm/amd/pm/amdgpu_dpm_internal.c (revision 1bb76ff151c0aba8e3312a604e4cd2e5195cf4b7)
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