]>
Commit | Line | Data |
---|---|---|
28a18bab RZ |
1 | /* |
2 | * Copyright 2015 Advanced Micro Devices, Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | */ | |
23 | ||
24 | #include "hwmgr.h" | |
25 | #include "cz_clockpowergating.h" | |
26 | #include "cz_ppsmc.h" | |
27 | ||
28 | /* PhyID -> Status Mapping in DDI_PHY_GEN_STATUS | |
29 | 0 GFX0L (3:0), (27:24), | |
30 | 1 GFX0H (7:4), (31:28), | |
31 | 2 GFX1L (3:0), (19:16), | |
32 | 3 GFX1H (7:4), (23:20), | |
33 | 4 DDIL (3:0), (11: 8), | |
34 | 5 DDIH (7:4), (15:12), | |
35 | 6 DDI2L (3:0), ( 3: 0), | |
36 | 7 DDI2H (7:4), ( 7: 4), | |
37 | */ | |
38 | #define DDI_PHY_GEN_STATUS_VAL(phyID) (1 << ((3 - ((phyID & 0x07)/2))*8 + (phyID & 0x01)*4)) | |
39 | #define IS_PHY_ID_USED_BY_PLL(PhyID) (((0xF3 & (1 << PhyID)) & 0xFF) ? true : false) | |
40 | ||
41 | ||
42 | int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating) | |
43 | { | |
44 | int ret = 0; | |
45 | ||
46 | switch (block) { | |
47 | case PHM_AsicBlock_UVD_MVC: | |
48 | case PHM_AsicBlock_UVD: | |
49 | case PHM_AsicBlock_UVD_HD: | |
50 | case PHM_AsicBlock_UVD_SD: | |
51 | if (gating == PHM_ClockGateSetting_StaticOff) | |
52 | ret = cz_dpm_powerdown_uvd(hwmgr); | |
53 | else | |
54 | ret = cz_dpm_powerup_uvd(hwmgr); | |
55 | break; | |
56 | case PHM_AsicBlock_GFX: | |
57 | default: | |
58 | break; | |
59 | } | |
60 | ||
61 | return ret; | |
62 | } | |
63 | ||
64 | ||
65 | bool cz_phm_is_safe_for_asic_block(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, enum PHM_AsicBlock block) | |
66 | { | |
67 | return true; | |
68 | } | |
69 | ||
70 | ||
71 | int cz_phm_enable_disable_gfx_power_gating(struct pp_hwmgr *hwmgr, bool enable) | |
72 | { | |
73 | return 0; | |
74 | } | |
75 | ||
76 | int cz_phm_smu_power_up_down_pcie(struct pp_hwmgr *hwmgr, uint32_t target, bool up, uint32_t args) | |
77 | { | |
78 | /* TODO */ | |
79 | return 0; | |
80 | } | |
81 | ||
82 | int cz_phm_initialize_display_phy_access(struct pp_hwmgr *hwmgr, bool initialize, bool accesshw) | |
83 | { | |
84 | /* TODO */ | |
85 | return 0; | |
86 | } | |
87 | ||
88 | int cz_phm_get_display_phy_access_info(struct pp_hwmgr *hwmgr) | |
89 | { | |
90 | /* TODO */ | |
91 | return 0; | |
92 | } | |
93 | ||
94 | int cz_phm_gate_unused_display_phys(struct pp_hwmgr *hwmgr) | |
95 | { | |
96 | /* TODO */ | |
97 | return 0; | |
98 | } | |
99 | ||
100 | int cz_phm_ungate_all_display_phys(struct pp_hwmgr *hwmgr) | |
101 | { | |
102 | /* TODO */ | |
103 | return 0; | |
104 | } | |
105 | ||
106 | static int cz_tf_uvd_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result) | |
107 | { | |
108 | return 0; | |
109 | } | |
110 | ||
111 | static int cz_tf_vce_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result) | |
112 | { | |
113 | return 0; | |
114 | } | |
115 | ||
116 | int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable) | |
117 | { | |
118 | struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); | |
119 | uint32_t dpm_features = 0; | |
120 | ||
121 | if (enable && | |
122 | phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | |
123 | PHM_PlatformCaps_UVDDPM)) { | |
124 | cz_hwmgr->dpm_flags |= DPMFlags_UVD_Enabled; | |
125 | dpm_features |= UVD_DPM_MASK; | |
126 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | |
127 | PPSMC_MSG_EnableAllSmuFeatures, dpm_features); | |
128 | } else { | |
129 | dpm_features |= UVD_DPM_MASK; | |
130 | cz_hwmgr->dpm_flags &= ~DPMFlags_UVD_Enabled; | |
131 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | |
132 | PPSMC_MSG_DisableAllSmuFeatures, dpm_features); | |
133 | } | |
134 | return 0; | |
135 | } | |
136 | ||
137 | int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) | |
138 | { | |
139 | struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); | |
140 | uint32_t dpm_features = 0; | |
141 | ||
142 | if (enable && phm_cap_enabled( | |
143 | hwmgr->platform_descriptor.platformCaps, | |
144 | PHM_PlatformCaps_VCEDPM)) { | |
145 | cz_hwmgr->dpm_flags |= DPMFlags_VCE_Enabled; | |
146 | dpm_features |= VCE_DPM_MASK; | |
147 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | |
148 | PPSMC_MSG_EnableAllSmuFeatures, dpm_features); | |
149 | } else { | |
150 | dpm_features |= VCE_DPM_MASK; | |
151 | cz_hwmgr->dpm_flags &= ~DPMFlags_VCE_Enabled; | |
152 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | |
153 | PPSMC_MSG_DisableAllSmuFeatures, dpm_features); | |
154 | } | |
155 | ||
156 | return 0; | |
157 | } | |
158 | ||
159 | ||
160 | int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate) | |
161 | { | |
162 | struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); | |
163 | ||
164 | if (cz_hwmgr->uvd_power_gated == bgate) | |
165 | return 0; | |
166 | ||
167 | cz_hwmgr->uvd_power_gated = bgate; | |
168 | ||
169 | if (bgate) { | |
170 | cgs_set_clockgating_state(hwmgr->device, | |
171 | AMD_IP_BLOCK_TYPE_UVD, | |
172 | AMD_CG_STATE_UNGATE); | |
173 | cgs_set_powergating_state(hwmgr->device, | |
174 | AMD_IP_BLOCK_TYPE_UVD, | |
175 | AMD_PG_STATE_GATE); | |
176 | cz_dpm_update_uvd_dpm(hwmgr, true); | |
177 | cz_dpm_powerdown_uvd(hwmgr); | |
178 | } else { | |
179 | cz_dpm_powerup_uvd(hwmgr); | |
180 | cgs_set_clockgating_state(hwmgr->device, | |
181 | AMD_IP_BLOCK_TYPE_UVD, | |
182 | AMD_PG_STATE_GATE); | |
183 | cgs_set_powergating_state(hwmgr->device, | |
184 | AMD_IP_BLOCK_TYPE_UVD, | |
185 | AMD_CG_STATE_UNGATE); | |
186 | cz_dpm_update_uvd_dpm(hwmgr, false); | |
187 | } | |
188 | ||
189 | return 0; | |
190 | } | |
191 | ||
192 | int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) | |
193 | { | |
194 | struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); | |
195 | ||
196 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | |
197 | PHM_PlatformCaps_VCEPowerGating)) { | |
198 | if (cz_hwmgr->vce_power_gated != bgate) { | |
199 | if (bgate) { | |
200 | cgs_set_clockgating_state( | |
201 | hwmgr->device, | |
202 | AMD_IP_BLOCK_TYPE_VCE, | |
203 | AMD_CG_STATE_UNGATE); | |
204 | cgs_set_powergating_state( | |
205 | hwmgr->device, | |
206 | AMD_IP_BLOCK_TYPE_VCE, | |
207 | AMD_PG_STATE_GATE); | |
208 | cz_enable_disable_vce_dpm(hwmgr, false); | |
209 | /* TODO: to figure out why vce can't be poweroff*/ | |
210 | cz_hwmgr->vce_power_gated = true; | |
211 | } else { | |
212 | cz_dpm_powerup_vce(hwmgr); | |
213 | cz_hwmgr->vce_power_gated = false; | |
214 | cgs_set_clockgating_state( | |
215 | hwmgr->device, | |
216 | AMD_IP_BLOCK_TYPE_VCE, | |
217 | AMD_PG_STATE_GATE); | |
218 | cgs_set_powergating_state( | |
219 | hwmgr->device, | |
220 | AMD_IP_BLOCK_TYPE_VCE, | |
221 | AMD_CG_STATE_UNGATE); | |
222 | cz_dpm_update_vce_dpm(hwmgr); | |
223 | cz_enable_disable_vce_dpm(hwmgr, true); | |
224 | return 0; | |
225 | } | |
226 | } | |
227 | } else { | |
228 | cz_dpm_update_vce_dpm(hwmgr); | |
370afa7a | 229 | cz_enable_disable_vce_dpm(hwmgr, !bgate); |
28a18bab RZ |
230 | return 0; |
231 | } | |
232 | ||
233 | if (!cz_hwmgr->vce_power_gated) | |
234 | cz_dpm_update_vce_dpm(hwmgr); | |
235 | ||
236 | return 0; | |
237 | } | |
238 | ||
239 | ||
240 | static struct phm_master_table_item cz_enable_clock_power_gatings_list[] = { | |
241 | /*we don't need an exit table here, because there is only D3 cold on Kv*/ | |
242 | { phm_cf_want_uvd_power_gating, cz_tf_uvd_power_gating_initialize }, | |
243 | { phm_cf_want_vce_power_gating, cz_tf_vce_power_gating_initialize }, | |
244 | /* to do { NULL, cz_tf_xdma_power_gating_enable }, */ | |
245 | { NULL, NULL } | |
246 | }; | |
247 | ||
248 | struct phm_master_table_header cz_phm_enable_clock_power_gatings_master = { | |
249 | 0, | |
250 | PHM_MasterTableFlag_None, | |
251 | cz_enable_clock_power_gatings_list | |
252 | }; |