diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2016-12-28 06:43:23 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-01-27 11:12:58 -0500 |
commit | 1c86380248467b99a0d9a9f7fdd0834fa0c6c5aa (patch) | |
tree | 45b21f37f3b7478c4c3e1e6cd654a2fb0c6769a9 | |
parent | ae6a58e4090365f0ed6b24e0a67b8a08f6b55856 (diff) |
drm/amd/powerplay: refine powerplay interface.
v2: add pp_check function to check pp_instance
valid.
1. powerplay export two new interface to amdgpu,
amd_powerplay_create/amd_powerplay_destroy.
2. create pp_instance/smumgr/hwmgr/eventmgr in
early init, destroy them when lata_fini.
3. in sw_init, create and init asic private smumgr
data, and free them when sw_fini.
4. in hw_init, create and init asic private hwmgr
data, and free them when hw_fini.
5. export powerplay state: PP_DPM_DISABLED.
when user disabled powerplay or hwmgr/eventmgr
init failed, powerplay return this state to amdgpu.
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 108 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 709 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 114 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/eventmgr.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/pp_instance.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/smumgr.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | 17 |
10 files changed, 518 insertions, 479 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index b1921c7da36b..8856eccc37fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
@@ -34,63 +34,34 @@ | |||
34 | #include "cik_dpm.h" | 34 | #include "cik_dpm.h" |
35 | #include "vi_dpm.h" | 35 | #include "vi_dpm.h" |
36 | 36 | ||
37 | static int amdgpu_powerplay_init(struct amdgpu_device *adev) | 37 | static int amdgpu_create_pp_handle(struct amdgpu_device *adev) |
38 | { | 38 | { |
39 | int ret = 0; | 39 | struct amd_pp_init pp_init; |
40 | struct amd_powerplay *amd_pp; | 40 | struct amd_powerplay *amd_pp; |
41 | int ret; | ||
41 | 42 | ||
42 | amd_pp = &(adev->powerplay); | 43 | amd_pp = &(adev->powerplay); |
43 | 44 | pp_init.chip_family = adev->family; | |
44 | if (adev->pp_enabled) { | 45 | pp_init.chip_id = adev->asic_type; |
45 | struct amd_pp_init *pp_init; | 46 | pp_init.pm_en = amdgpu_dpm != 0 ? true : false; |
46 | 47 | pp_init.feature_mask = amdgpu_pp_feature_mask; | |
47 | pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL); | 48 | pp_init.device = amdgpu_cgs_create_device(adev); |
48 | 49 | ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle)); | |
49 | if (pp_init == NULL) | 50 | if (ret) |
50 | return -ENOMEM; | 51 | return -EINVAL; |
51 | 52 | return 0; | |
52 | pp_init->chip_family = adev->family; | ||
53 | pp_init->chip_id = adev->asic_type; | ||
54 | pp_init->device = amdgpu_cgs_create_device(adev); | ||
55 | ret = amd_powerplay_init(pp_init, amd_pp); | ||
56 | kfree(pp_init); | ||
57 | } else { | ||
58 | amd_pp->pp_handle = (void *)adev; | ||
59 | |||
60 | switch (adev->asic_type) { | ||
61 | #ifdef CONFIG_DRM_AMDGPU_SI | ||
62 | case CHIP_TAHITI: | ||
63 | case CHIP_PITCAIRN: | ||
64 | case CHIP_VERDE: | ||
65 | case CHIP_OLAND: | ||
66 | case CHIP_HAINAN: | ||
67 | amd_pp->ip_funcs = &si_dpm_ip_funcs; | ||
68 | break; | ||
69 | #endif | ||
70 | #ifdef CONFIG_DRM_AMDGPU_CIK | ||
71 | case CHIP_BONAIRE: | ||
72 | case CHIP_HAWAII: | ||
73 | amd_pp->ip_funcs = &ci_dpm_ip_funcs; | ||
74 | break; | ||
75 | case CHIP_KABINI: | ||
76 | case CHIP_MULLINS: | ||
77 | case CHIP_KAVERI: | ||
78 | amd_pp->ip_funcs = &kv_dpm_ip_funcs; | ||
79 | break; | ||
80 | #endif | ||
81 | default: | ||
82 | ret = -EINVAL; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | return ret; | ||
87 | } | 53 | } |
88 | 54 | ||
89 | static int amdgpu_pp_early_init(void *handle) | 55 | static int amdgpu_pp_early_init(void *handle) |
90 | { | 56 | { |
91 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 57 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
58 | struct amd_powerplay *amd_pp; | ||
92 | int ret = 0; | 59 | int ret = 0; |
93 | 60 | ||
61 | amd_pp = &(adev->powerplay); | ||
62 | adev->pp_enabled = false; | ||
63 | amd_pp->pp_handle = (void *)adev; | ||
64 | |||
94 | switch (adev->asic_type) { | 65 | switch (adev->asic_type) { |
95 | case CHIP_POLARIS11: | 66 | case CHIP_POLARIS11: |
96 | case CHIP_POLARIS10: | 67 | case CHIP_POLARIS10: |
@@ -101,25 +72,45 @@ static int amdgpu_pp_early_init(void *handle) | |||
101 | case CHIP_CARRIZO: | 72 | case CHIP_CARRIZO: |
102 | case CHIP_STONEY: | 73 | case CHIP_STONEY: |
103 | adev->pp_enabled = true; | 74 | adev->pp_enabled = true; |
75 | if (amdgpu_create_pp_handle(adev)) | ||
76 | return -EINVAL; | ||
77 | amd_pp->ip_funcs = &pp_ip_funcs; | ||
78 | amd_pp->pp_funcs = &pp_dpm_funcs; | ||
104 | break; | 79 | break; |
105 | /* These chips don't have powerplay implemenations */ | 80 | /* These chips don't have powerplay implemenations */ |
81 | #ifdef CONFIG_DRM_AMDGPU_SI | ||
82 | case CHIP_TAHITI: | ||
83 | case CHIP_PITCAIRN: | ||
84 | case CHIP_VERDE: | ||
85 | case CHIP_OLAND: | ||
86 | case CHIP_HAINAN: | ||
87 | amd_pp->ip_funcs = &si_dpm_ip_funcs; | ||
88 | break; | ||
89 | #endif | ||
90 | #ifdef CONFIG_DRM_AMDGPU_CIK | ||
106 | case CHIP_BONAIRE: | 91 | case CHIP_BONAIRE: |
107 | case CHIP_HAWAII: | 92 | case CHIP_HAWAII: |
93 | amd_pp->ip_funcs = &ci_dpm_ip_funcs; | ||
94 | break; | ||
108 | case CHIP_KABINI: | 95 | case CHIP_KABINI: |
109 | case CHIP_MULLINS: | 96 | case CHIP_MULLINS: |
110 | case CHIP_KAVERI: | 97 | case CHIP_KAVERI: |
98 | amd_pp->ip_funcs = &kv_dpm_ip_funcs; | ||
99 | break; | ||
100 | #endif | ||
111 | default: | 101 | default: |
112 | adev->pp_enabled = false; | 102 | ret = -EINVAL; |
113 | break; | 103 | break; |
114 | } | 104 | } |
115 | 105 | ||
116 | ret = amdgpu_powerplay_init(adev); | ||
117 | if (ret) | ||
118 | return ret; | ||
119 | |||
120 | if (adev->powerplay.ip_funcs->early_init) | 106 | if (adev->powerplay.ip_funcs->early_init) |
121 | ret = adev->powerplay.ip_funcs->early_init( | 107 | ret = adev->powerplay.ip_funcs->early_init( |
122 | adev->powerplay.pp_handle); | 108 | adev->powerplay.pp_handle); |
109 | |||
110 | if (ret == PP_DPM_DISABLED) { | ||
111 | adev->pm.dpm_enabled = false; | ||
112 | return 0; | ||
113 | } | ||
123 | return ret; | 114 | return ret; |
124 | } | 115 | } |
125 | 116 | ||
@@ -179,6 +170,11 @@ static int amdgpu_pp_hw_init(void *handle) | |||
179 | ret = adev->powerplay.ip_funcs->hw_init( | 170 | ret = adev->powerplay.ip_funcs->hw_init( |
180 | adev->powerplay.pp_handle); | 171 | adev->powerplay.pp_handle); |
181 | 172 | ||
173 | if (ret == PP_DPM_DISABLED) { | ||
174 | adev->pm.dpm_enabled = false; | ||
175 | return 0; | ||
176 | } | ||
177 | |||
182 | if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev)) | 178 | if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev)) |
183 | adev->pm.dpm_enabled = true; | 179 | adev->pm.dpm_enabled = true; |
184 | 180 | ||
@@ -204,14 +200,14 @@ static void amdgpu_pp_late_fini(void *handle) | |||
204 | { | 200 | { |
205 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 201 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
206 | 202 | ||
207 | if (adev->pp_enabled) { | ||
208 | amdgpu_pm_sysfs_fini(adev); | ||
209 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
210 | } | ||
211 | |||
212 | if (adev->powerplay.ip_funcs->late_fini) | 203 | if (adev->powerplay.ip_funcs->late_fini) |
213 | adev->powerplay.ip_funcs->late_fini( | 204 | adev->powerplay.ip_funcs->late_fini( |
214 | adev->powerplay.pp_handle); | 205 | adev->powerplay.pp_handle); |
206 | |||
207 | if (adev->pp_enabled && adev->pm.dpm_enabled) | ||
208 | amdgpu_pm_sysfs_fini(adev); | ||
209 | |||
210 | amd_powerplay_destroy(adev->powerplay.pp_handle); | ||
215 | } | 211 | } |
216 | 212 | ||
217 | static int amdgpu_pp_suspend(void *handle) | 213 | static int amdgpu_pp_suspend(void *handle) |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index fbbac6ba0d17..429f18b99323 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -32,162 +32,152 @@ | |||
32 | #include "eventmanager.h" | 32 | #include "eventmanager.h" |
33 | 33 | ||
34 | 34 | ||
35 | #define PP_CHECK(handle) \ | 35 | static inline int pp_check(struct pp_instance *handle) |
36 | do { \ | ||
37 | if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \ | ||
38 | return -EINVAL; \ | ||
39 | } while (0) | ||
40 | |||
41 | #define PP_CHECK_HW(hwmgr) \ | ||
42 | do { \ | ||
43 | if ((hwmgr) == NULL || (hwmgr)->hwmgr_func == NULL) \ | ||
44 | return 0; \ | ||
45 | } while (0) | ||
46 | |||
47 | static int pp_early_init(void *handle) | ||
48 | { | 36 | { |
49 | return 0; | 37 | if (handle == NULL || handle->pp_valid != PP_VALID) |
50 | } | 38 | return -EINVAL; |
51 | |||
52 | static int pp_sw_init(void *handle) | ||
53 | { | ||
54 | struct pp_instance *pp_handle; | ||
55 | struct pp_hwmgr *hwmgr; | ||
56 | int ret = 0; | ||
57 | 39 | ||
58 | if (handle == NULL) | 40 | if (handle->smu_mgr == NULL || handle->smu_mgr->smumgr_funcs == NULL) |
59 | return -EINVAL; | 41 | return -EINVAL; |
60 | 42 | ||
61 | pp_handle = (struct pp_instance *)handle; | 43 | if (handle->pm_en == 0) |
62 | hwmgr = pp_handle->hwmgr; | 44 | return PP_DPM_DISABLED; |
63 | 45 | ||
64 | PP_CHECK_HW(hwmgr); | 46 | if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL |
47 | || handle->eventmgr == NULL) | ||
48 | return PP_DPM_DISABLED; | ||
65 | 49 | ||
66 | if (hwmgr->pptable_func == NULL || | 50 | return 0; |
67 | hwmgr->pptable_func->pptable_init == NULL || | 51 | } |
68 | hwmgr->hwmgr_func->backend_init == NULL) | ||
69 | return -EINVAL; | ||
70 | 52 | ||
71 | ret = hwmgr->pptable_func->pptable_init(hwmgr); | 53 | static int pp_early_init(void *handle) |
72 | if (ret) | 54 | { |
73 | goto err; | 55 | int ret; |
56 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
74 | 57 | ||
75 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); | 58 | ret = smum_early_init(pp_handle); |
76 | if (ret) | 59 | if (ret) |
77 | goto err1; | 60 | return ret; |
61 | |||
62 | if ((pp_handle->pm_en == 0) | ||
63 | || cgs_is_virtualization_enabled(pp_handle->device)) | ||
64 | return PP_DPM_DISABLED; | ||
78 | 65 | ||
79 | if (hwmgr->hwmgr_func->request_firmware) { | 66 | ret = hwmgr_early_init(pp_handle); |
80 | ret = hwmgr->hwmgr_func->request_firmware(hwmgr); | 67 | if (ret) { |
81 | if (ret) | 68 | pp_handle->pm_en = 0; |
82 | goto err2; | 69 | return PP_DPM_DISABLED; |
83 | } | 70 | } |
84 | 71 | ||
85 | pr_info("initialized.\n"); | 72 | ret = eventmgr_early_init(pp_handle); |
73 | if (ret) { | ||
74 | kfree(pp_handle->hwmgr); | ||
75 | pp_handle->hwmgr = NULL; | ||
76 | pp_handle->pm_en = 0; | ||
77 | return PP_DPM_DISABLED; | ||
78 | } | ||
86 | 79 | ||
87 | return 0; | 80 | return 0; |
88 | err2: | ||
89 | if (hwmgr->hwmgr_func->backend_fini) | ||
90 | hwmgr->hwmgr_func->backend_fini(hwmgr); | ||
91 | err1: | ||
92 | if (hwmgr->pptable_func->pptable_fini) | ||
93 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
94 | err: | ||
95 | pr_err("initialization failed\n"); | ||
96 | return ret; | ||
97 | } | 81 | } |
98 | 82 | ||
99 | static int pp_sw_fini(void *handle) | 83 | static int pp_sw_init(void *handle) |
100 | { | 84 | { |
101 | struct pp_instance *pp_handle; | 85 | struct pp_smumgr *smumgr; |
102 | struct pp_hwmgr *hwmgr; | ||
103 | int ret = 0; | 86 | int ret = 0; |
87 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
104 | 88 | ||
105 | if (handle == NULL) | 89 | ret = pp_check(pp_handle); |
106 | return -EINVAL; | ||
107 | 90 | ||
108 | pp_handle = (struct pp_instance *)handle; | 91 | if (ret == 0 || ret == PP_DPM_DISABLED) { |
109 | hwmgr = pp_handle->hwmgr; | 92 | smumgr = pp_handle->smu_mgr; |
110 | 93 | ||
111 | PP_CHECK_HW(hwmgr); | 94 | if (smumgr->smumgr_funcs->smu_init == NULL) |
95 | return -EINVAL; | ||
112 | 96 | ||
113 | if (hwmgr->hwmgr_func->release_firmware) | 97 | ret = smumgr->smumgr_funcs->smu_init(smumgr); |
114 | ret = hwmgr->hwmgr_func->release_firmware(hwmgr); | ||
115 | 98 | ||
116 | if (hwmgr->hwmgr_func->backend_fini != NULL) | 99 | pr_info("amdgpu: powerplay sw initialized\n"); |
117 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); | 100 | } |
101 | return ret; | ||
102 | } | ||
118 | 103 | ||
119 | if (hwmgr->pptable_func->pptable_fini) | 104 | static int pp_sw_fini(void *handle) |
120 | hwmgr->pptable_func->pptable_fini(hwmgr); | 105 | { |
106 | struct pp_smumgr *smumgr; | ||
107 | int ret = 0; | ||
108 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
109 | |||
110 | ret = pp_check(pp_handle); | ||
111 | if (ret == 0 || ret == PP_DPM_DISABLED) { | ||
112 | smumgr = pp_handle->smu_mgr; | ||
121 | 113 | ||
114 | if (smumgr->smumgr_funcs->smu_fini == NULL) | ||
115 | return -EINVAL; | ||
116 | |||
117 | ret = smumgr->smumgr_funcs->smu_fini(smumgr); | ||
118 | } | ||
122 | return ret; | 119 | return ret; |
123 | } | 120 | } |
124 | 121 | ||
125 | static int pp_hw_init(void *handle) | 122 | static int pp_hw_init(void *handle) |
126 | { | 123 | { |
127 | struct pp_instance *pp_handle; | ||
128 | struct pp_smumgr *smumgr; | 124 | struct pp_smumgr *smumgr; |
129 | struct pp_eventmgr *eventmgr; | 125 | struct pp_eventmgr *eventmgr; |
130 | struct pp_hwmgr *hwmgr; | ||
131 | int ret = 0; | 126 | int ret = 0; |
127 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
132 | 128 | ||
133 | if (handle == NULL) | 129 | ret = pp_check(pp_handle); |
134 | return -EINVAL; | ||
135 | 130 | ||
136 | pp_handle = (struct pp_instance *)handle; | 131 | if (ret == 0 || ret == PP_DPM_DISABLED) { |
137 | smumgr = pp_handle->smu_mgr; | 132 | smumgr = pp_handle->smu_mgr; |
138 | hwmgr = pp_handle->hwmgr; | ||
139 | |||
140 | if (smumgr == NULL || smumgr->smumgr_funcs == NULL || | ||
141 | smumgr->smumgr_funcs->smu_init == NULL || | ||
142 | smumgr->smumgr_funcs->start_smu == NULL) | ||
143 | return -EINVAL; | ||
144 | 133 | ||
145 | ret = smumgr->smumgr_funcs->smu_init(smumgr); | 134 | if (smumgr->smumgr_funcs->start_smu == NULL) |
146 | if (ret) { | 135 | return -EINVAL; |
147 | pr_err("smc initialization failed\n"); | ||
148 | return ret; | ||
149 | } | ||
150 | 136 | ||
151 | ret = smumgr->smumgr_funcs->start_smu(smumgr); | 137 | if(smumgr->smumgr_funcs->start_smu(smumgr)) { |
152 | if (ret) { | 138 | pr_err("smc start failed\n"); |
153 | pr_err("smc start failed\n"); | 139 | smumgr->smumgr_funcs->smu_fini(smumgr); |
154 | smumgr->smumgr_funcs->smu_fini(smumgr); | 140 | return -EINVAL;; |
155 | return ret; | 141 | } |
142 | if (ret == PP_DPM_DISABLED) | ||
143 | return PP_DPM_DISABLED; | ||
156 | } | 144 | } |
157 | 145 | ||
158 | PP_CHECK_HW(hwmgr); | 146 | ret = hwmgr_hw_init(pp_handle); |
159 | 147 | if (ret) | |
160 | hw_init_power_state_table(hwmgr); | 148 | goto err; |
161 | 149 | ||
162 | eventmgr = pp_handle->eventmgr; | 150 | eventmgr = pp_handle->eventmgr; |
163 | if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL) | 151 | if (eventmgr->pp_eventmgr_init == NULL || |
164 | return -EINVAL; | 152 | eventmgr->pp_eventmgr_init(eventmgr)) |
153 | goto err; | ||
165 | 154 | ||
166 | ret = eventmgr->pp_eventmgr_init(eventmgr); | ||
167 | return 0; | 155 | return 0; |
156 | err: | ||
157 | pp_handle->pm_en = 0; | ||
158 | kfree(pp_handle->eventmgr); | ||
159 | kfree(pp_handle->hwmgr); | ||
160 | pp_handle->hwmgr = NULL; | ||
161 | pp_handle->eventmgr = NULL; | ||
162 | return PP_DPM_DISABLED; | ||
168 | } | 163 | } |
169 | 164 | ||
170 | static int pp_hw_fini(void *handle) | 165 | static int pp_hw_fini(void *handle) |
171 | { | 166 | { |
172 | struct pp_instance *pp_handle; | ||
173 | struct pp_smumgr *smumgr; | ||
174 | struct pp_eventmgr *eventmgr; | 167 | struct pp_eventmgr *eventmgr; |
168 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
169 | int ret = 0; | ||
175 | 170 | ||
176 | if (handle == NULL) | 171 | ret = pp_check(pp_handle); |
177 | return -EINVAL; | ||
178 | |||
179 | pp_handle = (struct pp_instance *)handle; | ||
180 | eventmgr = pp_handle->eventmgr; | ||
181 | |||
182 | if (eventmgr != NULL && eventmgr->pp_eventmgr_fini != NULL) | ||
183 | eventmgr->pp_eventmgr_fini(eventmgr); | ||
184 | 172 | ||
185 | smumgr = pp_handle->smu_mgr; | 173 | if (ret == 0) { |
174 | eventmgr = pp_handle->eventmgr; | ||
186 | 175 | ||
187 | if (smumgr != NULL && smumgr->smumgr_funcs != NULL && | 176 | if (eventmgr->pp_eventmgr_fini != NULL) |
188 | smumgr->smumgr_funcs->smu_fini != NULL) | 177 | eventmgr->pp_eventmgr_fini(eventmgr); |
189 | smumgr->smumgr_funcs->smu_fini(smumgr); | ||
190 | 178 | ||
179 | hwmgr_hw_fini(pp_handle); | ||
180 | } | ||
191 | return 0; | 181 | return 0; |
192 | } | 182 | } |
193 | 183 | ||
@@ -210,13 +200,15 @@ static int pp_sw_reset(void *handle) | |||
210 | int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id) | 200 | int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id) |
211 | { | 201 | { |
212 | struct pp_hwmgr *hwmgr; | 202 | struct pp_hwmgr *hwmgr; |
203 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
204 | int ret = 0; | ||
213 | 205 | ||
214 | if (handle == NULL) | 206 | ret = pp_check(pp_handle); |
215 | return -EINVAL; | ||
216 | 207 | ||
217 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 208 | if (ret != 0) |
209 | return ret; | ||
218 | 210 | ||
219 | PP_CHECK_HW(hwmgr); | 211 | hwmgr = pp_handle->hwmgr; |
220 | 212 | ||
221 | if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { | 213 | if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { |
222 | pr_info("%s was not implemented.\n", __func__); | 214 | pr_info("%s was not implemented.\n", __func__); |
@@ -230,13 +222,15 @@ static int pp_set_powergating_state(void *handle, | |||
230 | enum amd_powergating_state state) | 222 | enum amd_powergating_state state) |
231 | { | 223 | { |
232 | struct pp_hwmgr *hwmgr; | 224 | struct pp_hwmgr *hwmgr; |
225 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
226 | int ret = 0; | ||
233 | 227 | ||
234 | if (handle == NULL) | 228 | ret = pp_check(pp_handle); |
235 | return -EINVAL; | ||
236 | 229 | ||
237 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 230 | if (ret != 0) |
231 | return ret; | ||
238 | 232 | ||
239 | PP_CHECK_HW(hwmgr); | 233 | hwmgr = pp_handle->hwmgr; |
240 | 234 | ||
241 | if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) { | 235 | if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) { |
242 | pr_info("%s was not implemented.\n", __func__); | 236 | pr_info("%s was not implemented.\n", __func__); |
@@ -250,37 +244,38 @@ static int pp_set_powergating_state(void *handle, | |||
250 | 244 | ||
251 | static int pp_suspend(void *handle) | 245 | static int pp_suspend(void *handle) |
252 | { | 246 | { |
253 | struct pp_instance *pp_handle; | ||
254 | struct pp_eventmgr *eventmgr; | 247 | struct pp_eventmgr *eventmgr; |
255 | struct pem_event_data event_data = { {0} }; | 248 | struct pem_event_data event_data = { {0} }; |
249 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
250 | int ret = 0; | ||
256 | 251 | ||
257 | if (handle == NULL) | 252 | ret = pp_check(pp_handle); |
258 | return -EINVAL; | 253 | |
254 | if (ret != 0) | ||
255 | return ret; | ||
259 | 256 | ||
260 | pp_handle = (struct pp_instance *)handle; | ||
261 | eventmgr = pp_handle->eventmgr; | 257 | eventmgr = pp_handle->eventmgr; |
258 | pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data); | ||
262 | 259 | ||
263 | if (eventmgr != NULL) | ||
264 | pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data); | ||
265 | return 0; | 260 | return 0; |
266 | } | 261 | } |
267 | 262 | ||
268 | static int pp_resume(void *handle) | 263 | static int pp_resume(void *handle) |
269 | { | 264 | { |
270 | struct pp_instance *pp_handle; | ||
271 | struct pp_eventmgr *eventmgr; | 265 | struct pp_eventmgr *eventmgr; |
272 | struct pem_event_data event_data = { {0} }; | 266 | struct pem_event_data event_data = { {0} }; |
273 | struct pp_smumgr *smumgr; | 267 | struct pp_smumgr *smumgr; |
274 | int ret; | 268 | int ret, ret1; |
269 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
275 | 270 | ||
276 | if (handle == NULL) | 271 | ret1 = pp_check(pp_handle); |
277 | return -EINVAL; | 272 | |
273 | if (ret1 != 0 && ret1 != PP_DPM_DISABLED) | ||
274 | return ret1; | ||
278 | 275 | ||
279 | pp_handle = (struct pp_instance *)handle; | ||
280 | smumgr = pp_handle->smu_mgr; | 276 | smumgr = pp_handle->smu_mgr; |
281 | 277 | ||
282 | if (smumgr == NULL || smumgr->smumgr_funcs == NULL || | 278 | if (smumgr->smumgr_funcs->start_smu == NULL) |
283 | smumgr->smumgr_funcs->start_smu == NULL) | ||
284 | return -EINVAL; | 279 | return -EINVAL; |
285 | 280 | ||
286 | ret = smumgr->smumgr_funcs->start_smu(smumgr); | 281 | ret = smumgr->smumgr_funcs->start_smu(smumgr); |
@@ -290,9 +285,12 @@ static int pp_resume(void *handle) | |||
290 | return ret; | 285 | return ret; |
291 | } | 286 | } |
292 | 287 | ||
288 | if (ret1 == PP_DPM_DISABLED) | ||
289 | return ret1; | ||
290 | |||
293 | eventmgr = pp_handle->eventmgr; | 291 | eventmgr = pp_handle->eventmgr; |
294 | if (eventmgr != NULL) | 292 | |
295 | pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data); | 293 | pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data); |
296 | 294 | ||
297 | return 0; | 295 | return 0; |
298 | } | 296 | } |
@@ -327,18 +325,17 @@ static int pp_dpm_fw_loading_complete(void *handle) | |||
327 | static int pp_dpm_force_performance_level(void *handle, | 325 | static int pp_dpm_force_performance_level(void *handle, |
328 | enum amd_dpm_forced_level level) | 326 | enum amd_dpm_forced_level level) |
329 | { | 327 | { |
330 | struct pp_instance *pp_handle; | ||
331 | struct pp_hwmgr *hwmgr; | 328 | struct pp_hwmgr *hwmgr; |
329 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
330 | int ret = 0; | ||
332 | 331 | ||
333 | if (handle == NULL) | 332 | ret = pp_check(pp_handle); |
334 | return -EINVAL; | ||
335 | 333 | ||
336 | pp_handle = (struct pp_instance *)handle; | 334 | if (ret != 0) |
335 | return ret; | ||
337 | 336 | ||
338 | hwmgr = pp_handle->hwmgr; | 337 | hwmgr = pp_handle->hwmgr; |
339 | 338 | ||
340 | PP_CHECK_HW(hwmgr); | ||
341 | |||
342 | if (hwmgr->hwmgr_func->force_dpm_level == NULL) { | 339 | if (hwmgr->hwmgr_func->force_dpm_level == NULL) { |
343 | pr_info("%s was not implemented.\n", __func__); | 340 | pr_info("%s was not implemented.\n", __func__); |
344 | return 0; | 341 | return 0; |
@@ -353,27 +350,31 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level( | |||
353 | void *handle) | 350 | void *handle) |
354 | { | 351 | { |
355 | struct pp_hwmgr *hwmgr; | 352 | struct pp_hwmgr *hwmgr; |
353 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
354 | int ret = 0; | ||
356 | 355 | ||
357 | if (handle == NULL) | 356 | ret = pp_check(pp_handle); |
358 | return -EINVAL; | ||
359 | 357 | ||
360 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 358 | if (ret != 0) |
359 | return ret; | ||
361 | 360 | ||
362 | PP_CHECK_HW(hwmgr); | 361 | hwmgr = pp_handle->hwmgr; |
363 | 362 | ||
364 | return (((struct pp_instance *)handle)->hwmgr->dpm_level); | 363 | return hwmgr->dpm_level; |
365 | } | 364 | } |
366 | 365 | ||
367 | static int pp_dpm_get_sclk(void *handle, bool low) | 366 | static int pp_dpm_get_sclk(void *handle, bool low) |
368 | { | 367 | { |
369 | struct pp_hwmgr *hwmgr; | 368 | struct pp_hwmgr *hwmgr; |
369 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
370 | int ret = 0; | ||
370 | 371 | ||
371 | if (handle == NULL) | 372 | ret = pp_check(pp_handle); |
372 | return -EINVAL; | ||
373 | 373 | ||
374 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 374 | if (ret != 0) |
375 | return ret; | ||
375 | 376 | ||
376 | PP_CHECK_HW(hwmgr); | 377 | hwmgr = pp_handle->hwmgr; |
377 | 378 | ||
378 | if (hwmgr->hwmgr_func->get_sclk == NULL) { | 379 | if (hwmgr->hwmgr_func->get_sclk == NULL) { |
379 | pr_info("%s was not implemented.\n", __func__); | 380 | pr_info("%s was not implemented.\n", __func__); |
@@ -386,13 +387,15 @@ static int pp_dpm_get_sclk(void *handle, bool low) | |||
386 | static int pp_dpm_get_mclk(void *handle, bool low) | 387 | static int pp_dpm_get_mclk(void *handle, bool low) |
387 | { | 388 | { |
388 | struct pp_hwmgr *hwmgr; | 389 | struct pp_hwmgr *hwmgr; |
390 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
391 | int ret = 0; | ||
389 | 392 | ||
390 | if (handle == NULL) | 393 | ret = pp_check(pp_handle); |
391 | return -EINVAL; | ||
392 | 394 | ||
393 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 395 | if (ret != 0) |
396 | return ret; | ||
394 | 397 | ||
395 | PP_CHECK_HW(hwmgr); | 398 | hwmgr = pp_handle->hwmgr; |
396 | 399 | ||
397 | if (hwmgr->hwmgr_func->get_mclk == NULL) { | 400 | if (hwmgr->hwmgr_func->get_mclk == NULL) { |
398 | pr_info("%s was not implemented.\n", __func__); | 401 | pr_info("%s was not implemented.\n", __func__); |
@@ -405,13 +408,15 @@ static int pp_dpm_get_mclk(void *handle, bool low) | |||
405 | static int pp_dpm_powergate_vce(void *handle, bool gate) | 408 | static int pp_dpm_powergate_vce(void *handle, bool gate) |
406 | { | 409 | { |
407 | struct pp_hwmgr *hwmgr; | 410 | struct pp_hwmgr *hwmgr; |
411 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
412 | int ret = 0; | ||
408 | 413 | ||
409 | if (handle == NULL) | 414 | ret = pp_check(pp_handle); |
410 | return -EINVAL; | ||
411 | 415 | ||
412 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 416 | if (ret != 0) |
417 | return ret; | ||
413 | 418 | ||
414 | PP_CHECK_HW(hwmgr); | 419 | hwmgr = pp_handle->hwmgr; |
415 | 420 | ||
416 | if (hwmgr->hwmgr_func->powergate_vce == NULL) { | 421 | if (hwmgr->hwmgr_func->powergate_vce == NULL) { |
417 | pr_info("%s was not implemented.\n", __func__); | 422 | pr_info("%s was not implemented.\n", __func__); |
@@ -424,13 +429,15 @@ static int pp_dpm_powergate_vce(void *handle, bool gate) | |||
424 | static int pp_dpm_powergate_uvd(void *handle, bool gate) | 429 | static int pp_dpm_powergate_uvd(void *handle, bool gate) |
425 | { | 430 | { |
426 | struct pp_hwmgr *hwmgr; | 431 | struct pp_hwmgr *hwmgr; |
432 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
433 | int ret = 0; | ||
427 | 434 | ||
428 | if (handle == NULL) | 435 | ret = pp_check(pp_handle); |
429 | return -EINVAL; | ||
430 | 436 | ||
431 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 437 | if (ret != 0) |
438 | return ret; | ||
432 | 439 | ||
433 | PP_CHECK_HW(hwmgr); | 440 | hwmgr = pp_handle->hwmgr; |
434 | 441 | ||
435 | if (hwmgr->hwmgr_func->powergate_uvd == NULL) { | 442 | if (hwmgr->hwmgr_func->powergate_uvd == NULL) { |
436 | pr_info("%s was not implemented.\n", __func__); | 443 | pr_info("%s was not implemented.\n", __func__); |
@@ -458,16 +465,13 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, | |||
458 | void *input, void *output) | 465 | void *input, void *output) |
459 | { | 466 | { |
460 | int ret = 0; | 467 | int ret = 0; |
461 | struct pp_instance *pp_handle; | ||
462 | struct pem_event_data data = { {0} }; | 468 | struct pem_event_data data = { {0} }; |
469 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
463 | 470 | ||
464 | pp_handle = (struct pp_instance *)handle; | 471 | ret = pp_check(pp_handle); |
465 | 472 | ||
466 | if (pp_handle == NULL) | 473 | if (ret != 0) |
467 | return -EINVAL; | 474 | return ret; |
468 | |||
469 | if (pp_handle->eventmgr == NULL) | ||
470 | return 0; | ||
471 | 475 | ||
472 | switch (event_id) { | 476 | switch (event_id) { |
473 | case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE: | 477 | case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE: |
@@ -501,13 +505,17 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) | |||
501 | { | 505 | { |
502 | struct pp_hwmgr *hwmgr; | 506 | struct pp_hwmgr *hwmgr; |
503 | struct pp_power_state *state; | 507 | struct pp_power_state *state; |
508 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
509 | int ret = 0; | ||
504 | 510 | ||
505 | if (handle == NULL) | 511 | ret = pp_check(pp_handle); |
506 | return -EINVAL; | ||
507 | 512 | ||
508 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 513 | if (ret != 0) |
514 | return ret; | ||
509 | 515 | ||
510 | if (hwmgr == NULL || hwmgr->current_ps == NULL) | 516 | hwmgr = pp_handle->hwmgr; |
517 | |||
518 | if (hwmgr->current_ps == NULL) | ||
511 | return -EINVAL; | 519 | return -EINVAL; |
512 | 520 | ||
513 | state = hwmgr->current_ps; | 521 | state = hwmgr->current_ps; |
@@ -530,13 +538,15 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) | |||
530 | static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) | 538 | static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) |
531 | { | 539 | { |
532 | struct pp_hwmgr *hwmgr; | 540 | struct pp_hwmgr *hwmgr; |
541 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
542 | int ret = 0; | ||
533 | 543 | ||
534 | if (handle == NULL) | 544 | ret = pp_check(pp_handle); |
535 | return -EINVAL; | ||
536 | 545 | ||
537 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 546 | if (ret != 0) |
547 | return ret; | ||
538 | 548 | ||
539 | PP_CHECK_HW(hwmgr); | 549 | hwmgr = pp_handle->hwmgr; |
540 | 550 | ||
541 | if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) { | 551 | if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) { |
542 | pr_info("%s was not implemented.\n", __func__); | 552 | pr_info("%s was not implemented.\n", __func__); |
@@ -549,13 +559,15 @@ static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) | |||
549 | static int pp_dpm_get_fan_control_mode(void *handle) | 559 | static int pp_dpm_get_fan_control_mode(void *handle) |
550 | { | 560 | { |
551 | struct pp_hwmgr *hwmgr; | 561 | struct pp_hwmgr *hwmgr; |
562 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
563 | int ret = 0; | ||
552 | 564 | ||
553 | if (handle == NULL) | 565 | ret = pp_check(pp_handle); |
554 | return -EINVAL; | ||
555 | 566 | ||
556 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 567 | if (ret != 0) |
568 | return ret; | ||
557 | 569 | ||
558 | PP_CHECK_HW(hwmgr); | 570 | hwmgr = pp_handle->hwmgr; |
559 | 571 | ||
560 | if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) { | 572 | if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) { |
561 | pr_info("%s was not implemented.\n", __func__); | 573 | pr_info("%s was not implemented.\n", __func__); |
@@ -568,13 +580,15 @@ static int pp_dpm_get_fan_control_mode(void *handle) | |||
568 | static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent) | 580 | static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent) |
569 | { | 581 | { |
570 | struct pp_hwmgr *hwmgr; | 582 | struct pp_hwmgr *hwmgr; |
583 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
584 | int ret = 0; | ||
571 | 585 | ||
572 | if (handle == NULL) | 586 | ret = pp_check(pp_handle); |
573 | return -EINVAL; | ||
574 | 587 | ||
575 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 588 | if (ret != 0) |
589 | return ret; | ||
576 | 590 | ||
577 | PP_CHECK_HW(hwmgr); | 591 | hwmgr = pp_handle->hwmgr; |
578 | 592 | ||
579 | if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) { | 593 | if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) { |
580 | pr_info("%s was not implemented.\n", __func__); | 594 | pr_info("%s was not implemented.\n", __func__); |
@@ -587,13 +601,15 @@ static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent) | |||
587 | static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed) | 601 | static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed) |
588 | { | 602 | { |
589 | struct pp_hwmgr *hwmgr; | 603 | struct pp_hwmgr *hwmgr; |
604 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
605 | int ret = 0; | ||
590 | 606 | ||
591 | if (handle == NULL) | 607 | ret = pp_check(pp_handle); |
592 | return -EINVAL; | ||
593 | 608 | ||
594 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 609 | if (ret != 0) |
610 | return ret; | ||
595 | 611 | ||
596 | PP_CHECK_HW(hwmgr); | 612 | hwmgr = pp_handle->hwmgr; |
597 | 613 | ||
598 | if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) { | 614 | if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) { |
599 | pr_info("%s was not implemented.\n", __func__); | 615 | pr_info("%s was not implemented.\n", __func__); |
@@ -606,13 +622,15 @@ static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed) | |||
606 | static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm) | 622 | static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm) |
607 | { | 623 | { |
608 | struct pp_hwmgr *hwmgr; | 624 | struct pp_hwmgr *hwmgr; |
625 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
626 | int ret = 0; | ||
609 | 627 | ||
610 | if (handle == NULL) | 628 | ret = pp_check(pp_handle); |
611 | return -EINVAL; | ||
612 | 629 | ||
613 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 630 | if (ret != 0) |
631 | return ret; | ||
614 | 632 | ||
615 | PP_CHECK_HW(hwmgr); | 633 | hwmgr = pp_handle->hwmgr; |
616 | 634 | ||
617 | if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL) | 635 | if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL) |
618 | return -EINVAL; | 636 | return -EINVAL; |
@@ -623,13 +641,15 @@ static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm) | |||
623 | static int pp_dpm_get_temperature(void *handle) | 641 | static int pp_dpm_get_temperature(void *handle) |
624 | { | 642 | { |
625 | struct pp_hwmgr *hwmgr; | 643 | struct pp_hwmgr *hwmgr; |
644 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
645 | int ret = 0; | ||
626 | 646 | ||
627 | if (handle == NULL) | 647 | ret = pp_check(pp_handle); |
628 | return -EINVAL; | ||
629 | 648 | ||
630 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 649 | if (ret != 0) |
650 | return ret; | ||
631 | 651 | ||
632 | PP_CHECK_HW(hwmgr); | 652 | hwmgr = pp_handle->hwmgr; |
633 | 653 | ||
634 | if (hwmgr->hwmgr_func->get_temperature == NULL) { | 654 | if (hwmgr->hwmgr_func->get_temperature == NULL) { |
635 | pr_info("%s was not implemented.\n", __func__); | 655 | pr_info("%s was not implemented.\n", __func__); |
@@ -644,13 +664,17 @@ static int pp_dpm_get_pp_num_states(void *handle, | |||
644 | { | 664 | { |
645 | struct pp_hwmgr *hwmgr; | 665 | struct pp_hwmgr *hwmgr; |
646 | int i; | 666 | int i; |
667 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
668 | int ret = 0; | ||
647 | 669 | ||
648 | if (!handle) | 670 | ret = pp_check(pp_handle); |
649 | return -EINVAL; | ||
650 | 671 | ||
651 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 672 | if (ret != 0) |
673 | return ret; | ||
674 | |||
675 | hwmgr = pp_handle->hwmgr; | ||
652 | 676 | ||
653 | if (hwmgr == NULL || hwmgr->ps == NULL) | 677 | if (hwmgr->ps == NULL) |
654 | return -EINVAL; | 678 | return -EINVAL; |
655 | 679 | ||
656 | data->nums = hwmgr->num_ps; | 680 | data->nums = hwmgr->num_ps; |
@@ -682,13 +706,15 @@ static int pp_dpm_get_pp_num_states(void *handle, | |||
682 | static int pp_dpm_get_pp_table(void *handle, char **table) | 706 | static int pp_dpm_get_pp_table(void *handle, char **table) |
683 | { | 707 | { |
684 | struct pp_hwmgr *hwmgr; | 708 | struct pp_hwmgr *hwmgr; |
709 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
710 | int ret = 0; | ||
685 | 711 | ||
686 | if (!handle) | 712 | ret = pp_check(pp_handle); |
687 | return -EINVAL; | ||
688 | 713 | ||
689 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 714 | if (ret != 0) |
715 | return ret; | ||
690 | 716 | ||
691 | PP_CHECK_HW(hwmgr); | 717 | hwmgr = pp_handle->hwmgr; |
692 | 718 | ||
693 | if (!hwmgr->soft_pp_table) | 719 | if (!hwmgr->soft_pp_table) |
694 | return -EINVAL; | 720 | return -EINVAL; |
@@ -701,13 +727,15 @@ static int pp_dpm_get_pp_table(void *handle, char **table) | |||
701 | static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) | 727 | static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) |
702 | { | 728 | { |
703 | struct pp_hwmgr *hwmgr; | 729 | struct pp_hwmgr *hwmgr; |
730 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
731 | int ret = 0; | ||
704 | 732 | ||
705 | if (!handle) | 733 | ret = pp_check(pp_handle); |
706 | return -EINVAL; | ||
707 | 734 | ||
708 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 735 | if (ret != 0) |
736 | return ret; | ||
709 | 737 | ||
710 | PP_CHECK_HW(hwmgr); | 738 | hwmgr = pp_handle->hwmgr; |
711 | 739 | ||
712 | if (!hwmgr->hardcode_pp_table) { | 740 | if (!hwmgr->hardcode_pp_table) { |
713 | hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table, | 741 | hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table, |
@@ -729,13 +757,15 @@ static int pp_dpm_force_clock_level(void *handle, | |||
729 | enum pp_clock_type type, uint32_t mask) | 757 | enum pp_clock_type type, uint32_t mask) |
730 | { | 758 | { |
731 | struct pp_hwmgr *hwmgr; | 759 | struct pp_hwmgr *hwmgr; |
760 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
761 | int ret = 0; | ||
732 | 762 | ||
733 | if (!handle) | 763 | ret = pp_check(pp_handle); |
734 | return -EINVAL; | ||
735 | 764 | ||
736 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 765 | if (ret != 0) |
766 | return ret; | ||
737 | 767 | ||
738 | PP_CHECK_HW(hwmgr); | 768 | hwmgr = pp_handle->hwmgr; |
739 | 769 | ||
740 | if (hwmgr->hwmgr_func->force_clock_level == NULL) { | 770 | if (hwmgr->hwmgr_func->force_clock_level == NULL) { |
741 | pr_info("%s was not implemented.\n", __func__); | 771 | pr_info("%s was not implemented.\n", __func__); |
@@ -749,13 +779,15 @@ static int pp_dpm_print_clock_levels(void *handle, | |||
749 | enum pp_clock_type type, char *buf) | 779 | enum pp_clock_type type, char *buf) |
750 | { | 780 | { |
751 | struct pp_hwmgr *hwmgr; | 781 | struct pp_hwmgr *hwmgr; |
782 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
783 | int ret = 0; | ||
752 | 784 | ||
753 | if (!handle) | 785 | ret = pp_check(pp_handle); |
754 | return -EINVAL; | ||
755 | 786 | ||
756 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 787 | if (ret != 0) |
788 | return ret; | ||
757 | 789 | ||
758 | PP_CHECK_HW(hwmgr); | 790 | hwmgr = pp_handle->hwmgr; |
759 | 791 | ||
760 | if (hwmgr->hwmgr_func->print_clock_levels == NULL) { | 792 | if (hwmgr->hwmgr_func->print_clock_levels == NULL) { |
761 | pr_info("%s was not implemented.\n", __func__); | 793 | pr_info("%s was not implemented.\n", __func__); |
@@ -767,13 +799,15 @@ static int pp_dpm_print_clock_levels(void *handle, | |||
767 | static int pp_dpm_get_sclk_od(void *handle) | 799 | static int pp_dpm_get_sclk_od(void *handle) |
768 | { | 800 | { |
769 | struct pp_hwmgr *hwmgr; | 801 | struct pp_hwmgr *hwmgr; |
802 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
803 | int ret = 0; | ||
770 | 804 | ||
771 | if (!handle) | 805 | ret = pp_check(pp_handle); |
772 | return -EINVAL; | ||
773 | 806 | ||
774 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 807 | if (ret != 0) |
808 | return ret; | ||
775 | 809 | ||
776 | PP_CHECK_HW(hwmgr); | 810 | hwmgr = pp_handle->hwmgr; |
777 | 811 | ||
778 | if (hwmgr->hwmgr_func->get_sclk_od == NULL) { | 812 | if (hwmgr->hwmgr_func->get_sclk_od == NULL) { |
779 | pr_info("%s was not implemented.\n", __func__); | 813 | pr_info("%s was not implemented.\n", __func__); |
@@ -786,13 +820,15 @@ static int pp_dpm_get_sclk_od(void *handle) | |||
786 | static int pp_dpm_set_sclk_od(void *handle, uint32_t value) | 820 | static int pp_dpm_set_sclk_od(void *handle, uint32_t value) |
787 | { | 821 | { |
788 | struct pp_hwmgr *hwmgr; | 822 | struct pp_hwmgr *hwmgr; |
823 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
824 | int ret = 0; | ||
789 | 825 | ||
790 | if (!handle) | 826 | ret = pp_check(pp_handle); |
791 | return -EINVAL; | ||
792 | 827 | ||
793 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 828 | if (ret != 0) |
829 | return ret; | ||
794 | 830 | ||
795 | PP_CHECK_HW(hwmgr); | 831 | hwmgr = pp_handle->hwmgr; |
796 | 832 | ||
797 | if (hwmgr->hwmgr_func->set_sclk_od == NULL) { | 833 | if (hwmgr->hwmgr_func->set_sclk_od == NULL) { |
798 | pr_info("%s was not implemented.\n", __func__); | 834 | pr_info("%s was not implemented.\n", __func__); |
@@ -805,13 +841,15 @@ static int pp_dpm_set_sclk_od(void *handle, uint32_t value) | |||
805 | static int pp_dpm_get_mclk_od(void *handle) | 841 | static int pp_dpm_get_mclk_od(void *handle) |
806 | { | 842 | { |
807 | struct pp_hwmgr *hwmgr; | 843 | struct pp_hwmgr *hwmgr; |
844 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
845 | int ret = 0; | ||
808 | 846 | ||
809 | if (!handle) | 847 | ret = pp_check(pp_handle); |
810 | return -EINVAL; | ||
811 | 848 | ||
812 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 849 | if (ret != 0) |
850 | return ret; | ||
813 | 851 | ||
814 | PP_CHECK_HW(hwmgr); | 852 | hwmgr = pp_handle->hwmgr; |
815 | 853 | ||
816 | if (hwmgr->hwmgr_func->get_mclk_od == NULL) { | 854 | if (hwmgr->hwmgr_func->get_mclk_od == NULL) { |
817 | pr_info("%s was not implemented.\n", __func__); | 855 | pr_info("%s was not implemented.\n", __func__); |
@@ -824,13 +862,15 @@ static int pp_dpm_get_mclk_od(void *handle) | |||
824 | static int pp_dpm_set_mclk_od(void *handle, uint32_t value) | 862 | static int pp_dpm_set_mclk_od(void *handle, uint32_t value) |
825 | { | 863 | { |
826 | struct pp_hwmgr *hwmgr; | 864 | struct pp_hwmgr *hwmgr; |
865 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
866 | int ret = 0; | ||
827 | 867 | ||
828 | if (!handle) | 868 | ret = pp_check(pp_handle); |
829 | return -EINVAL; | ||
830 | 869 | ||
831 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 870 | if (ret != 0) |
871 | return ret; | ||
832 | 872 | ||
833 | PP_CHECK_HW(hwmgr); | 873 | hwmgr = pp_handle->hwmgr; |
834 | 874 | ||
835 | if (hwmgr->hwmgr_func->set_mclk_od == NULL) { | 875 | if (hwmgr->hwmgr_func->set_mclk_od == NULL) { |
836 | pr_info("%s was not implemented.\n", __func__); | 876 | pr_info("%s was not implemented.\n", __func__); |
@@ -843,13 +883,15 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value) | |||
843 | static int pp_dpm_read_sensor(void *handle, int idx, int32_t *value) | 883 | static int pp_dpm_read_sensor(void *handle, int idx, int32_t *value) |
844 | { | 884 | { |
845 | struct pp_hwmgr *hwmgr; | 885 | struct pp_hwmgr *hwmgr; |
886 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
887 | int ret = 0; | ||
846 | 888 | ||
847 | if (!handle) | 889 | ret = pp_check(pp_handle); |
848 | return -EINVAL; | ||
849 | 890 | ||
850 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 891 | if (ret != 0) |
892 | return ret; | ||
851 | 893 | ||
852 | PP_CHECK_HW(hwmgr); | 894 | hwmgr = pp_handle->hwmgr; |
853 | 895 | ||
854 | if (hwmgr->hwmgr_func->read_sensor == NULL) { | 896 | if (hwmgr->hwmgr_func->read_sensor == NULL) { |
855 | pr_info("%s was not implemented.\n", __func__); | 897 | pr_info("%s was not implemented.\n", __func__); |
@@ -863,13 +905,18 @@ static struct amd_vce_state* | |||
863 | pp_dpm_get_vce_clock_state(void *handle, unsigned idx) | 905 | pp_dpm_get_vce_clock_state(void *handle, unsigned idx) |
864 | { | 906 | { |
865 | struct pp_hwmgr *hwmgr; | 907 | struct pp_hwmgr *hwmgr; |
908 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
909 | int ret = 0; | ||
866 | 910 | ||
867 | if (handle) { | 911 | ret = pp_check(pp_handle); |
868 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
869 | 912 | ||
870 | if (hwmgr && idx < hwmgr->num_vce_state_tables) | 913 | if (ret != 0) |
871 | return &hwmgr->vce_states[idx]; | 914 | return NULL; |
872 | } | 915 | |
916 | hwmgr = pp_handle->hwmgr; | ||
917 | |||
918 | if (hwmgr && idx < hwmgr->num_vce_state_tables) | ||
919 | return &hwmgr->vce_states[idx]; | ||
873 | 920 | ||
874 | return NULL; | 921 | return NULL; |
875 | } | 922 | } |
@@ -904,89 +951,44 @@ const struct amd_powerplay_funcs pp_dpm_funcs = { | |||
904 | .get_vce_clock_state = pp_dpm_get_vce_clock_state, | 951 | .get_vce_clock_state = pp_dpm_get_vce_clock_state, |
905 | }; | 952 | }; |
906 | 953 | ||
907 | static int amd_pp_instance_init(struct amd_pp_init *pp_init, | 954 | int amd_powerplay_create(struct amd_pp_init *pp_init, |
908 | struct amd_powerplay *amd_pp) | 955 | void **handle) |
909 | { | 956 | { |
910 | int ret; | 957 | struct pp_instance *instance; |
911 | struct pp_instance *handle; | ||
912 | |||
913 | handle = kzalloc(sizeof(struct pp_instance), GFP_KERNEL); | ||
914 | if (handle == NULL) | ||
915 | return -ENOMEM; | ||
916 | |||
917 | handle->pp_valid = PP_VALID; | ||
918 | |||
919 | ret = smum_init(pp_init, handle); | ||
920 | if (ret) | ||
921 | goto fail_smum; | ||
922 | |||
923 | |||
924 | amd_pp->pp_handle = handle; | ||
925 | 958 | ||
926 | if ((amdgpu_dpm == 0) | 959 | if (pp_init == NULL || handle == NULL) |
927 | || cgs_is_virtualization_enabled(pp_init->device)) | 960 | return -EINVAL; |
928 | return 0; | ||
929 | 961 | ||
930 | ret = hwmgr_init(pp_init, handle); | 962 | instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL); |
931 | if (ret) | 963 | if (instance == NULL) |
932 | goto fail_hwmgr; | 964 | return -ENOMEM; |
933 | 965 | ||
934 | ret = eventmgr_init(handle); | 966 | instance->pp_valid = PP_VALID; |
935 | if (ret) | 967 | instance->chip_family = pp_init->chip_family; |
936 | goto fail_eventmgr; | 968 | instance->chip_id = pp_init->chip_id; |
969 | instance->pm_en = pp_init->pm_en; | ||
970 | instance->feature_mask = pp_init->feature_mask; | ||
971 | instance->device = pp_init->device; | ||
972 | *handle = instance; | ||
937 | 973 | ||
938 | return 0; | 974 | return 0; |
939 | |||
940 | fail_eventmgr: | ||
941 | hwmgr_fini(handle->hwmgr); | ||
942 | fail_hwmgr: | ||
943 | smum_fini(handle->smu_mgr); | ||
944 | fail_smum: | ||
945 | kfree(handle); | ||
946 | return ret; | ||
947 | } | 975 | } |
948 | 976 | ||
949 | static int amd_pp_instance_fini(void *handle) | 977 | int amd_powerplay_destroy(void *handle) |
950 | { | 978 | { |
951 | struct pp_instance *instance = (struct pp_instance *)handle; | 979 | struct pp_instance *instance = (struct pp_instance *)handle; |
952 | 980 | ||
953 | if (instance == NULL) | 981 | if (instance->pm_en) { |
954 | return -EINVAL; | 982 | kfree(instance->eventmgr); |
955 | 983 | kfree(instance->hwmgr); | |
956 | if ((amdgpu_dpm != 0) | 984 | instance->hwmgr = NULL; |
957 | && !cgs_is_virtualization_enabled(instance->smu_mgr->device)) { | 985 | instance->eventmgr = NULL; |
958 | eventmgr_fini(instance->eventmgr); | ||
959 | hwmgr_fini(instance->hwmgr); | ||
960 | } | 986 | } |
961 | 987 | ||
962 | smum_fini(instance->smu_mgr); | 988 | kfree(instance->smu_mgr); |
963 | kfree(handle); | 989 | instance->smu_mgr = NULL; |
964 | return 0; | 990 | kfree(instance); |
965 | } | 991 | instance = NULL; |
966 | |||
967 | int amd_powerplay_init(struct amd_pp_init *pp_init, | ||
968 | struct amd_powerplay *amd_pp) | ||
969 | { | ||
970 | int ret; | ||
971 | |||
972 | if (pp_init == NULL || amd_pp == NULL) | ||
973 | return -EINVAL; | ||
974 | |||
975 | ret = amd_pp_instance_init(pp_init, amd_pp); | ||
976 | |||
977 | if (ret) | ||
978 | return ret; | ||
979 | |||
980 | amd_pp->ip_funcs = &pp_ip_funcs; | ||
981 | amd_pp->pp_funcs = &pp_dpm_funcs; | ||
982 | |||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | int amd_powerplay_fini(void *handle) | ||
987 | { | ||
988 | amd_pp_instance_fini(handle); | ||
989 | |||
990 | return 0; | 992 | return 0; |
991 | } | 993 | } |
992 | 994 | ||
@@ -997,33 +999,25 @@ int amd_powerplay_reset(void *handle) | |||
997 | struct pem_event_data event_data = { {0} }; | 999 | struct pem_event_data event_data = { {0} }; |
998 | int ret; | 1000 | int ret; |
999 | 1001 | ||
1000 | if (instance == NULL) | 1002 | if (cgs_is_virtualization_enabled(instance->smu_mgr->device)) |
1001 | return -EINVAL; | 1003 | return PP_DPM_DISABLED; |
1002 | |||
1003 | eventmgr = instance->eventmgr; | ||
1004 | if (!eventmgr || !eventmgr->pp_eventmgr_fini) | ||
1005 | return -EINVAL; | ||
1006 | |||
1007 | eventmgr->pp_eventmgr_fini(eventmgr); | ||
1008 | 1004 | ||
1009 | ret = pp_sw_fini(handle); | 1005 | ret = pp_check(instance); |
1010 | if (ret) | 1006 | if (ret != 0) |
1011 | return ret; | 1007 | return ret; |
1012 | 1008 | ||
1013 | kfree(instance->hwmgr->ps); | 1009 | ret = pp_hw_fini(handle); |
1014 | |||
1015 | ret = pp_sw_init(handle); | ||
1016 | if (ret) | 1010 | if (ret) |
1017 | return ret; | 1011 | return ret; |
1018 | 1012 | ||
1019 | if ((amdgpu_dpm == 0) | 1013 | ret = hwmgr_hw_init(instance); |
1020 | || cgs_is_virtualization_enabled(instance->smu_mgr->device)) | 1014 | if (ret) |
1021 | return 0; | 1015 | return PP_DPM_DISABLED; |
1022 | 1016 | ||
1023 | hw_init_power_state_table(instance->hwmgr); | 1017 | eventmgr = instance->eventmgr; |
1024 | 1018 | ||
1025 | if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL) | 1019 | if (eventmgr->pp_eventmgr_init == NULL) |
1026 | return -EINVAL; | 1020 | return PP_DPM_DISABLED; |
1027 | 1021 | ||
1028 | ret = eventmgr->pp_eventmgr_init(eventmgr); | 1022 | ret = eventmgr->pp_eventmgr_init(eventmgr); |
1029 | if (ret) | 1023 | if (ret) |
@@ -1038,12 +1032,15 @@ int amd_powerplay_display_configuration_change(void *handle, | |||
1038 | const struct amd_pp_display_configuration *display_config) | 1032 | const struct amd_pp_display_configuration *display_config) |
1039 | { | 1033 | { |
1040 | struct pp_hwmgr *hwmgr; | 1034 | struct pp_hwmgr *hwmgr; |
1035 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1036 | int ret = 0; | ||
1041 | 1037 | ||
1042 | PP_CHECK((struct pp_instance *)handle); | 1038 | ret = pp_check(pp_handle); |
1043 | 1039 | ||
1044 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 1040 | if (ret != 0) |
1041 | return ret; | ||
1045 | 1042 | ||
1046 | PP_CHECK_HW(hwmgr); | 1043 | hwmgr = pp_handle->hwmgr; |
1047 | 1044 | ||
1048 | phm_store_dal_configuration_data(hwmgr, display_config); | 1045 | phm_store_dal_configuration_data(hwmgr, display_config); |
1049 | 1046 | ||
@@ -1054,15 +1051,18 @@ int amd_powerplay_get_display_power_level(void *handle, | |||
1054 | struct amd_pp_simple_clock_info *output) | 1051 | struct amd_pp_simple_clock_info *output) |
1055 | { | 1052 | { |
1056 | struct pp_hwmgr *hwmgr; | 1053 | struct pp_hwmgr *hwmgr; |
1054 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1055 | int ret = 0; | ||
1057 | 1056 | ||
1058 | PP_CHECK((struct pp_instance *)handle); | 1057 | ret = pp_check(pp_handle); |
1059 | 1058 | ||
1060 | if (output == NULL) | 1059 | if (ret != 0) |
1061 | return -EINVAL; | 1060 | return ret; |
1062 | 1061 | ||
1063 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 1062 | hwmgr = pp_handle->hwmgr; |
1064 | 1063 | ||
1065 | PP_CHECK_HW(hwmgr); | 1064 | if (output == NULL) |
1065 | return -EINVAL; | ||
1066 | 1066 | ||
1067 | return phm_get_dal_power_level(hwmgr, output); | 1067 | return phm_get_dal_power_level(hwmgr, output); |
1068 | } | 1068 | } |
@@ -1070,18 +1070,18 @@ int amd_powerplay_get_display_power_level(void *handle, | |||
1070 | int amd_powerplay_get_current_clocks(void *handle, | 1070 | int amd_powerplay_get_current_clocks(void *handle, |
1071 | struct amd_pp_clock_info *clocks) | 1071 | struct amd_pp_clock_info *clocks) |
1072 | { | 1072 | { |
1073 | struct pp_hwmgr *hwmgr; | ||
1074 | struct amd_pp_simple_clock_info simple_clocks; | 1073 | struct amd_pp_simple_clock_info simple_clocks; |
1075 | struct pp_clock_info hw_clocks; | 1074 | struct pp_clock_info hw_clocks; |
1075 | struct pp_hwmgr *hwmgr; | ||
1076 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1077 | int ret = 0; | ||
1076 | 1078 | ||
1077 | PP_CHECK((struct pp_instance *)handle); | 1079 | ret = pp_check(pp_handle); |
1078 | |||
1079 | if (clocks == NULL) | ||
1080 | return -EINVAL; | ||
1081 | 1080 | ||
1082 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | 1081 | if (ret != 0) |
1082 | return ret; | ||
1083 | 1083 | ||
1084 | PP_CHECK_HW(hwmgr); | 1084 | hwmgr = pp_handle->hwmgr; |
1085 | 1085 | ||
1086 | phm_get_dal_power_level(hwmgr, &simple_clocks); | 1086 | phm_get_dal_power_level(hwmgr, &simple_clocks); |
1087 | 1087 | ||
@@ -1117,18 +1117,20 @@ int amd_powerplay_get_current_clocks(void *handle, | |||
1117 | int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks) | 1117 | int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks) |
1118 | { | 1118 | { |
1119 | int result = -1; | 1119 | int result = -1; |
1120 | struct pp_hwmgr *hwmgr; | ||
1121 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1122 | int ret = 0; | ||
1120 | 1123 | ||
1121 | struct pp_hwmgr *hwmgr; | 1124 | ret = pp_check(pp_handle); |
1122 | 1125 | ||
1123 | PP_CHECK((struct pp_instance *)handle); | 1126 | if (ret != 0) |
1127 | return ret; | ||
1128 | |||
1129 | hwmgr = pp_handle->hwmgr; | ||
1124 | 1130 | ||
1125 | if (clocks == NULL) | 1131 | if (clocks == NULL) |
1126 | return -EINVAL; | 1132 | return -EINVAL; |
1127 | 1133 | ||
1128 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
1129 | |||
1130 | PP_CHECK_HW(hwmgr); | ||
1131 | |||
1132 | result = phm_get_clock_by_type(hwmgr, type, clocks); | 1134 | result = phm_get_clock_by_type(hwmgr, type, clocks); |
1133 | 1135 | ||
1134 | return result; | 1136 | return result; |
@@ -1137,21 +1139,24 @@ int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, s | |||
1137 | int amd_powerplay_get_display_mode_validation_clocks(void *handle, | 1139 | int amd_powerplay_get_display_mode_validation_clocks(void *handle, |
1138 | struct amd_pp_simple_clock_info *clocks) | 1140 | struct amd_pp_simple_clock_info *clocks) |
1139 | { | 1141 | { |
1140 | int result = -1; | ||
1141 | struct pp_hwmgr *hwmgr; | 1142 | struct pp_hwmgr *hwmgr; |
1143 | struct pp_instance *pp_handle = (struct pp_instance *)handle; | ||
1144 | int ret = 0; | ||
1142 | 1145 | ||
1143 | PP_CHECK((struct pp_instance *)handle); | 1146 | ret = pp_check(pp_handle); |
1144 | 1147 | ||
1145 | if (clocks == NULL) | 1148 | if (ret != 0) |
1146 | return -EINVAL; | 1149 | return ret; |
1150 | |||
1151 | hwmgr = pp_handle->hwmgr; | ||
1147 | 1152 | ||
1148 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
1149 | 1153 | ||
1150 | PP_CHECK_HW(hwmgr); | 1154 | if (clocks == NULL) |
1155 | return -EINVAL; | ||
1151 | 1156 | ||
1152 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState)) | 1157 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState)) |
1153 | result = phm_get_max_high_clocks(hwmgr, clocks); | 1158 | ret = phm_get_max_high_clocks(hwmgr, clocks); |
1154 | 1159 | ||
1155 | return result; | 1160 | return ret; |
1156 | } | 1161 | } |
1157 | 1162 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index fb88e4e5d625..781e53dcf128 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | |||
@@ -60,9 +60,8 @@ static void pem_fini(struct pp_eventmgr *eventmgr) | |||
60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); | 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); |
61 | } | 61 | } |
62 | 62 | ||
63 | int eventmgr_init(struct pp_instance *handle) | 63 | int eventmgr_early_init(struct pp_instance *handle) |
64 | { | 64 | { |
65 | int result = 0; | ||
66 | struct pp_eventmgr *eventmgr; | 65 | struct pp_eventmgr *eventmgr; |
67 | 66 | ||
68 | if (handle == NULL) | 67 | if (handle == NULL) |
@@ -79,12 +78,6 @@ int eventmgr_init(struct pp_instance *handle) | |||
79 | eventmgr->pp_eventmgr_init = pem_init; | 78 | eventmgr->pp_eventmgr_init = pem_init; |
80 | eventmgr->pp_eventmgr_fini = pem_fini; | 79 | eventmgr->pp_eventmgr_fini = pem_fini; |
81 | 80 | ||
82 | return result; | ||
83 | } | ||
84 | |||
85 | int eventmgr_fini(struct pp_eventmgr *eventmgr) | ||
86 | { | ||
87 | kfree(eventmgr); | ||
88 | return 0; | 81 | return 0; |
89 | } | 82 | } |
90 | 83 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index bd4ca681e260..6bc63f26623d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
@@ -50,11 +50,11 @@ uint8_t convert_to_vid(uint16_t vddc) | |||
50 | return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); | 50 | return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25); |
51 | } | 51 | } |
52 | 52 | ||
53 | int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | 53 | int hwmgr_early_init(struct pp_instance *handle) |
54 | { | 54 | { |
55 | struct pp_hwmgr *hwmgr; | 55 | struct pp_hwmgr *hwmgr; |
56 | 56 | ||
57 | if ((handle == NULL) || (pp_init == NULL)) | 57 | if (handle == NULL) |
58 | return -EINVAL; | 58 | return -EINVAL; |
59 | 59 | ||
60 | hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL); | 60 | hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL); |
@@ -63,9 +63,9 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
63 | 63 | ||
64 | handle->hwmgr = hwmgr; | 64 | handle->hwmgr = hwmgr; |
65 | hwmgr->smumgr = handle->smu_mgr; | 65 | hwmgr->smumgr = handle->smu_mgr; |
66 | hwmgr->device = pp_init->device; | 66 | hwmgr->device = handle->device; |
67 | hwmgr->chip_family = pp_init->chip_family; | 67 | hwmgr->chip_family = handle->chip_family; |
68 | hwmgr->chip_id = pp_init->chip_id; | 68 | hwmgr->chip_id = handle->chip_id; |
69 | hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; | 69 | hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; |
70 | hwmgr->power_source = PP_PowerSource_AC; | 70 | hwmgr->power_source = PP_PowerSource_AC; |
71 | hwmgr->pp_table_version = PP_TABLE_V1; | 71 | hwmgr->pp_table_version = PP_TABLE_V1; |
@@ -112,28 +112,7 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
115 | int hwmgr_fini(struct pp_hwmgr *hwmgr) | 115 | static int hw_init_power_state_table(struct pp_hwmgr *hwmgr) |
116 | { | ||
117 | if (hwmgr == NULL || hwmgr->ps == NULL) | ||
118 | return -EINVAL; | ||
119 | |||
120 | /* do hwmgr finish*/ | ||
121 | kfree(hwmgr->hardcode_pp_table); | ||
122 | |||
123 | kfree(hwmgr->backend); | ||
124 | |||
125 | kfree(hwmgr->start_thermal_controller.function_list); | ||
126 | |||
127 | kfree(hwmgr->set_temperature_range.function_list); | ||
128 | |||
129 | kfree(hwmgr->ps); | ||
130 | kfree(hwmgr->current_ps); | ||
131 | kfree(hwmgr->request_ps); | ||
132 | kfree(hwmgr); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | int hw_init_power_state_table(struct pp_hwmgr *hwmgr) | ||
137 | { | 116 | { |
138 | int result; | 117 | int result; |
139 | unsigned int i; | 118 | unsigned int i; |
@@ -157,12 +136,20 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr) | |||
157 | return -ENOMEM; | 136 | return -ENOMEM; |
158 | 137 | ||
159 | hwmgr->request_ps = kzalloc(size, GFP_KERNEL); | 138 | hwmgr->request_ps = kzalloc(size, GFP_KERNEL); |
160 | if (hwmgr->request_ps == NULL) | 139 | if (hwmgr->request_ps == NULL) { |
140 | kfree(hwmgr->ps); | ||
141 | hwmgr->ps = NULL; | ||
161 | return -ENOMEM; | 142 | return -ENOMEM; |
143 | } | ||
162 | 144 | ||
163 | hwmgr->current_ps = kzalloc(size, GFP_KERNEL); | 145 | hwmgr->current_ps = kzalloc(size, GFP_KERNEL); |
164 | if (hwmgr->current_ps == NULL) | 146 | if (hwmgr->current_ps == NULL) { |
147 | kfree(hwmgr->request_ps); | ||
148 | kfree(hwmgr->ps); | ||
149 | hwmgr->request_ps = NULL; | ||
150 | hwmgr->ps = NULL; | ||
165 | return -ENOMEM; | 151 | return -ENOMEM; |
152 | } | ||
166 | 153 | ||
167 | state = hwmgr->ps; | 154 | state = hwmgr->ps; |
168 | 155 | ||
@@ -182,8 +169,75 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr) | |||
182 | state = (struct pp_power_state *)((unsigned long)state + size); | 169 | state = (struct pp_power_state *)((unsigned long)state + size); |
183 | } | 170 | } |
184 | 171 | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int hw_fini_power_state_table(struct pp_hwmgr *hwmgr) | ||
176 | { | ||
177 | if (hwmgr == NULL) | ||
178 | return -EINVAL; | ||
179 | |||
180 | kfree(hwmgr->current_ps); | ||
181 | kfree(hwmgr->request_ps); | ||
182 | kfree(hwmgr->ps); | ||
183 | hwmgr->request_ps = NULL; | ||
184 | hwmgr->ps = NULL; | ||
185 | hwmgr->current_ps = NULL; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | int hwmgr_hw_init(struct pp_instance *handle) | ||
190 | { | ||
191 | struct pp_hwmgr *hwmgr; | ||
192 | int ret = 0; | ||
193 | |||
194 | if (handle == NULL) | ||
195 | return -EINVAL; | ||
196 | |||
197 | hwmgr = handle->hwmgr; | ||
198 | |||
199 | if (hwmgr->pptable_func == NULL || | ||
200 | hwmgr->pptable_func->pptable_init == NULL || | ||
201 | hwmgr->hwmgr_func->backend_init == NULL) | ||
202 | return -EINVAL; | ||
203 | |||
204 | ret = hwmgr->pptable_func->pptable_init(hwmgr); | ||
205 | if (ret) | ||
206 | goto err; | ||
207 | |||
208 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); | ||
209 | if (ret) | ||
210 | goto err1; | ||
185 | 211 | ||
212 | ret = hw_init_power_state_table(hwmgr); | ||
213 | if (ret) | ||
214 | goto err2; | ||
186 | return 0; | 215 | return 0; |
216 | err2: | ||
217 | if (hwmgr->hwmgr_func->backend_fini) | ||
218 | hwmgr->hwmgr_func->backend_fini(hwmgr); | ||
219 | err1: | ||
220 | if (hwmgr->pptable_func->pptable_fini) | ||
221 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
222 | err: | ||
223 | pr_err("amdgpu: powerplay initialization failed\n"); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | int hwmgr_hw_fini(struct pp_instance *handle) | ||
228 | { | ||
229 | struct pp_hwmgr *hwmgr; | ||
230 | |||
231 | if (handle == NULL) | ||
232 | return -EINVAL; | ||
233 | |||
234 | hwmgr = handle->hwmgr; | ||
235 | |||
236 | if (hwmgr->hwmgr_func->backend_fini) | ||
237 | hwmgr->hwmgr_func->backend_fini(hwmgr); | ||
238 | if (hwmgr->pptable_func->pptable_fini) | ||
239 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
240 | return hw_fini_power_state_table(hwmgr); | ||
187 | } | 241 | } |
188 | 242 | ||
189 | 243 | ||
@@ -289,7 +343,7 @@ int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table) | |||
289 | 343 | ||
290 | memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table)); | 344 | memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table)); |
291 | kfree(table); | 345 | kfree(table); |
292 | 346 | table = NULL; | |
293 | return 0; | 347 | return 0; |
294 | } | 348 | } |
295 | 349 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 6d52a397ff88..6dd5f0e9ef87 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | |||
@@ -29,7 +29,10 @@ | |||
29 | #include "amd_shared.h" | 29 | #include "amd_shared.h" |
30 | #include "cgs_common.h" | 30 | #include "cgs_common.h" |
31 | 31 | ||
32 | extern int amdgpu_dpm; | 32 | extern const struct amd_ip_funcs pp_ip_funcs; |
33 | extern const struct amd_powerplay_funcs pp_dpm_funcs; | ||
34 | |||
35 | #define PP_DPM_DISABLED 0xCCCC | ||
33 | 36 | ||
34 | enum amd_pp_sensors { | 37 | enum amd_pp_sensors { |
35 | AMDGPU_PP_SENSOR_GFX_SCLK = 0, | 38 | AMDGPU_PP_SENSOR_GFX_SCLK = 0, |
@@ -139,6 +142,8 @@ struct amd_pp_init { | |||
139 | struct cgs_device *device; | 142 | struct cgs_device *device; |
140 | uint32_t chip_family; | 143 | uint32_t chip_family; |
141 | uint32_t chip_id; | 144 | uint32_t chip_id; |
145 | bool pm_en; | ||
146 | uint32_t feature_mask; | ||
142 | }; | 147 | }; |
143 | 148 | ||
144 | enum amd_pp_display_config_type{ | 149 | enum amd_pp_display_config_type{ |
@@ -364,10 +369,10 @@ struct amd_powerplay { | |||
364 | const struct amd_powerplay_funcs *pp_funcs; | 369 | const struct amd_powerplay_funcs *pp_funcs; |
365 | }; | 370 | }; |
366 | 371 | ||
367 | int amd_powerplay_init(struct amd_pp_init *pp_init, | 372 | int amd_powerplay_create(struct amd_pp_init *pp_init, |
368 | struct amd_powerplay *amd_pp); | 373 | void **handle); |
369 | 374 | ||
370 | int amd_powerplay_fini(void *handle); | 375 | int amd_powerplay_destroy(void *handle); |
371 | 376 | ||
372 | int amd_powerplay_reset(void *handle); | 377 | int amd_powerplay_reset(void *handle); |
373 | 378 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h b/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h index d63ef83b2628..7bd8a7e57080 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/eventmgr.h | |||
@@ -119,7 +119,6 @@ struct pp_eventmgr { | |||
119 | void (*pp_eventmgr_fini)(struct pp_eventmgr *eventmgr); | 119 | void (*pp_eventmgr_fini)(struct pp_eventmgr *eventmgr); |
120 | }; | 120 | }; |
121 | 121 | ||
122 | int eventmgr_init(struct pp_instance *handle); | 122 | int eventmgr_early_init(struct pp_instance *handle); |
123 | int eventmgr_fini(struct pp_eventmgr *eventmgr); | ||
124 | 123 | ||
125 | #endif /* _EVENTMGR_H_ */ | 124 | #endif /* _EVENTMGR_H_ */ |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 3b7450ee7163..0d93801f21ea 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -653,19 +653,12 @@ struct pp_hwmgr { | |||
653 | uint32_t feature_mask; | 653 | uint32_t feature_mask; |
654 | }; | 654 | }; |
655 | 655 | ||
656 | 656 | extern int hwmgr_early_init(struct pp_instance *handle); | |
657 | extern int hwmgr_init(struct amd_pp_init *pp_init, | 657 | extern int hwmgr_hw_init(struct pp_instance *handle); |
658 | struct pp_instance *handle); | 658 | extern int hwmgr_hw_fini(struct pp_instance *handle); |
659 | |||
660 | extern int hwmgr_fini(struct pp_hwmgr *hwmgr); | ||
661 | |||
662 | extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr); | ||
663 | |||
664 | extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, | 659 | extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, |
665 | uint32_t value, uint32_t mask); | 660 | uint32_t value, uint32_t mask); |
666 | 661 | ||
667 | |||
668 | |||
669 | extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr, | 662 | extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr, |
670 | uint32_t indirect_port, | 663 | uint32_t indirect_port, |
671 | uint32_t index, | 664 | uint32_t index, |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h index 4d8ed1f33de4..ab8494fb5c6b 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h | |||
@@ -31,6 +31,11 @@ | |||
31 | 31 | ||
32 | struct pp_instance { | 32 | struct pp_instance { |
33 | uint32_t pp_valid; | 33 | uint32_t pp_valid; |
34 | uint32_t chip_family; | ||
35 | uint32_t chip_id; | ||
36 | bool pm_en; | ||
37 | uint32_t feature_mask; | ||
38 | void *device; | ||
34 | struct pp_smumgr *smu_mgr; | 39 | struct pp_smumgr *smu_mgr; |
35 | struct pp_hwmgr *hwmgr; | 40 | struct pp_hwmgr *hwmgr; |
36 | struct pp_eventmgr *eventmgr; | 41 | struct pp_eventmgr *eventmgr; |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 2139072065cc..0e5937295835 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h | |||
@@ -133,11 +133,7 @@ struct pp_smumgr { | |||
133 | const struct pp_smumgr_func *smumgr_funcs; | 133 | const struct pp_smumgr_func *smumgr_funcs; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | 136 | extern int smum_early_init(struct pp_instance *handle); | |
137 | extern int smum_init(struct amd_pp_init *pp_init, | ||
138 | struct pp_instance *handle); | ||
139 | |||
140 | extern int smum_fini(struct pp_smumgr *smumgr); | ||
141 | 137 | ||
142 | extern int smum_get_argument(struct pp_smumgr *smumgr); | 138 | extern int smum_get_argument(struct pp_smumgr *smumgr); |
143 | 139 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index 45737cd3c055..d5244c16d2d5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
@@ -41,20 +41,20 @@ MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); | |||
41 | MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); | 41 | MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); |
42 | MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); | 42 | MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); |
43 | 43 | ||
44 | int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | 44 | int smum_early_init(struct pp_instance *handle) |
45 | { | 45 | { |
46 | struct pp_smumgr *smumgr; | 46 | struct pp_smumgr *smumgr; |
47 | 47 | ||
48 | if ((handle == NULL) || (pp_init == NULL)) | 48 | if (handle == NULL) |
49 | return -EINVAL; | 49 | return -EINVAL; |
50 | 50 | ||
51 | smumgr = kzalloc(sizeof(struct pp_smumgr), GFP_KERNEL); | 51 | smumgr = kzalloc(sizeof(struct pp_smumgr), GFP_KERNEL); |
52 | if (smumgr == NULL) | 52 | if (smumgr == NULL) |
53 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | 54 | ||
55 | smumgr->device = pp_init->device; | 55 | smumgr->device = handle->device; |
56 | smumgr->chip_family = pp_init->chip_family; | 56 | smumgr->chip_family = handle->chip_family; |
57 | smumgr->chip_id = pp_init->chip_id; | 57 | smumgr->chip_id = handle->chip_id; |
58 | smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; | 58 | smumgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; |
59 | smumgr->reload_fw = 1; | 59 | smumgr->reload_fw = 1; |
60 | handle->smu_mgr = smumgr; | 60 | handle->smu_mgr = smumgr; |
@@ -91,13 +91,6 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | int smum_fini(struct pp_smumgr *smumgr) | ||
95 | { | ||
96 | kfree(smumgr->device); | ||
97 | kfree(smumgr); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr, | 94 | int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr, |
102 | void *input, void *output, void *storage, int result) | 95 | void *input, void *output, void *storage, int result) |
103 | { | 96 | { |