Commit | Line | Data |
---|---|---|
220ab9bd KW |
1 | /* |
2 | * Copyright 2016 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 | #include <linux/firmware.h> | |
24 | #include <linux/slab.h> | |
25 | #include <linux/module.h> | |
47b757fb SR |
26 | #include <linux/pci.h> |
27 | ||
6f786950 AD |
28 | #include <drm/amdgpu_drm.h> |
29 | ||
220ab9bd | 30 | #include "amdgpu.h" |
d05da0e2 | 31 | #include "amdgpu_atombios.h" |
220ab9bd KW |
32 | #include "amdgpu_ih.h" |
33 | #include "amdgpu_uvd.h" | |
34 | #include "amdgpu_vce.h" | |
35 | #include "amdgpu_ucode.h" | |
36 | #include "amdgpu_psp.h" | |
37 | #include "atom.h" | |
38 | #include "amd_pcie.h" | |
39 | ||
5d735f83 | 40 | #include "uvd/uvd_7_0_offset.h" |
cde5c34f FX |
41 | #include "gc/gc_9_0_offset.h" |
42 | #include "gc/gc_9_0_sh_mask.h" | |
812f77b7 FX |
43 | #include "sdma0/sdma0_4_0_offset.h" |
44 | #include "sdma1/sdma1_4_0_offset.h" | |
b45e18ac | 45 | #include "nbio/nbio_7_0_default.h" |
88807dc8 | 46 | #include "nbio/nbio_7_0_offset.h" |
b45e18ac KR |
47 | #include "nbio/nbio_7_0_sh_mask.h" |
48 | #include "nbio/nbio_7_0_smn.h" | |
9281f12c | 49 | #include "mp/mp_9_0_offset.h" |
220ab9bd KW |
50 | |
51 | #include "soc15.h" | |
52 | #include "soc15_common.h" | |
53 | #include "gfx_v9_0.h" | |
54 | #include "gmc_v9_0.h" | |
55 | #include "gfxhub_v1_0.h" | |
56 | #include "mmhub_v1_0.h" | |
070706c0 | 57 | #include "df_v1_7.h" |
698758bb | 58 | #include "df_v3_6.h" |
bebc0762 HZ |
59 | #include "nbio_v6_1.h" |
60 | #include "nbio_v7_0.h" | |
61 | #include "nbio_v7_4.h" | |
455d40c9 | 62 | #include "hdp_v4_0.h" |
220ab9bd | 63 | #include "vega10_ih.h" |
320a2e0c | 64 | #include "vega20_ih.h" |
c1059360 | 65 | #include "navi10_ih.h" |
220ab9bd KW |
66 | #include "sdma_v4_0.h" |
67 | #include "uvd_v7_0.h" | |
68 | #include "vce_v4_0.h" | |
f2d7e707 | 69 | #include "vcn_v1_0.h" |
279ba48e | 70 | #include "vcn_v2_0.h" |
5be45a26 | 71 | #include "jpeg_v2_0.h" |
08249a3a | 72 | #include "vcn_v2_5.h" |
8c74e590 | 73 | #include "jpeg_v2_5.h" |
0e961589 HZ |
74 | #include "smuio_v9_0.h" |
75 | #include "smuio_v11_0.h" | |
7914a0cd | 76 | #include "smuio_v13_0.h" |
733ee71a | 77 | #include "amdgpu_vkms.h" |
f1a34465 | 78 | #include "mxgpu_ai.h" |
e74609cb AD |
79 | #include "amdgpu_ras.h" |
80 | #include "amdgpu_xgmi.h" | |
88807dc8 | 81 | #include <uapi/linux/kfd_ioctl.h> |
220ab9bd | 82 | |
220ab9bd KW |
83 | #define mmMP0_MISC_CGTT_CTRL0 0x01b9 |
84 | #define mmMP0_MISC_CGTT_CTRL0_BASE_IDX 0 | |
85 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba | |
86 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 | |
87 | ||
2485e275 AD |
88 | static const struct amd_ip_funcs soc15_common_ip_funcs; |
89 | ||
3b246e8b AD |
90 | /* Vega, Raven, Arcturus */ |
91 | static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = | |
92 | { | |
9075096b VG |
93 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, |
94 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, | |
3b246e8b AD |
95 | }; |
96 | ||
97 | static const struct amdgpu_video_codecs vega_video_codecs_encode = | |
98 | { | |
99 | .codec_count = ARRAY_SIZE(vega_video_codecs_encode_array), | |
100 | .codec_array = vega_video_codecs_encode_array, | |
101 | }; | |
102 | ||
103 | /* Vega */ | |
104 | static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = | |
105 | { | |
65009bf2 VG |
106 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, |
107 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, | |
108 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, | |
109 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, | |
9075096b VG |
110 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, |
111 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
3b246e8b AD |
112 | }; |
113 | ||
114 | static const struct amdgpu_video_codecs vega_video_codecs_decode = | |
115 | { | |
116 | .codec_count = ARRAY_SIZE(vega_video_codecs_decode_array), | |
117 | .codec_array = vega_video_codecs_decode_array, | |
118 | }; | |
119 | ||
120 | /* Raven */ | |
121 | static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = | |
122 | { | |
65009bf2 VG |
123 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, |
124 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, | |
125 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, | |
126 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, | |
9075096b VG |
127 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, |
128 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
129 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, | |
3b246e8b AD |
130 | }; |
131 | ||
132 | static const struct amdgpu_video_codecs rv_video_codecs_decode = | |
133 | { | |
134 | .codec_count = ARRAY_SIZE(rv_video_codecs_decode_array), | |
135 | .codec_array = rv_video_codecs_decode_array, | |
136 | }; | |
137 | ||
138 | /* Renoir, Arcturus */ | |
139 | static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = | |
140 | { | |
65009bf2 VG |
141 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, |
142 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, | |
143 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, | |
144 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, | |
9075096b VG |
145 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
146 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
147 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
3b246e8b AD |
148 | }; |
149 | ||
150 | static const struct amdgpu_video_codecs rn_video_codecs_decode = | |
151 | { | |
152 | .codec_count = ARRAY_SIZE(rn_video_codecs_decode_array), | |
153 | .codec_array = rn_video_codecs_decode_array, | |
154 | }; | |
155 | ||
156 | static int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode, | |
157 | const struct amdgpu_video_codecs **codecs) | |
158 | { | |
1d789535 AD |
159 | if (adev->ip_versions[VCE_HWIP][0]) { |
160 | switch (adev->ip_versions[VCE_HWIP][0]) { | |
75a07bcd AD |
161 | case IP_VERSION(4, 0, 0): |
162 | case IP_VERSION(4, 1, 0): | |
163 | if (encode) | |
164 | *codecs = &vega_video_codecs_encode; | |
165 | else | |
166 | *codecs = &vega_video_codecs_decode; | |
167 | return 0; | |
168 | default: | |
169 | return -EINVAL; | |
170 | } | |
171 | } else { | |
1d789535 | 172 | switch (adev->ip_versions[UVD_HWIP][0]) { |
75a07bcd AD |
173 | case IP_VERSION(1, 0, 0): |
174 | case IP_VERSION(1, 0, 1): | |
175 | if (encode) | |
176 | *codecs = &vega_video_codecs_encode; | |
177 | else | |
178 | *codecs = &rv_video_codecs_decode; | |
179 | return 0; | |
180 | case IP_VERSION(2, 5, 0): | |
181 | case IP_VERSION(2, 6, 0): | |
182 | case IP_VERSION(2, 2, 0): | |
183 | if (encode) | |
184 | *codecs = &vega_video_codecs_encode; | |
185 | else | |
186 | *codecs = &rn_video_codecs_decode; | |
187 | return 0; | |
188 | default: | |
189 | return -EINVAL; | |
190 | } | |
3b246e8b AD |
191 | } |
192 | } | |
193 | ||
220ab9bd KW |
194 | static u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) |
195 | { | |
196 | unsigned long flags, address, data; | |
197 | u32 r; | |
198 | ||
199 | address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); | |
200 | data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); | |
201 | ||
202 | spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); | |
203 | WREG32(address, ((reg) & 0x1ff)); | |
204 | r = RREG32(data); | |
205 | spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); | |
206 | return r; | |
207 | } | |
208 | ||
209 | static void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
210 | { | |
211 | unsigned long flags, address, data; | |
212 | ||
213 | address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); | |
214 | data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); | |
215 | ||
216 | spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); | |
217 | WREG32(address, ((reg) & 0x1ff)); | |
218 | WREG32(data, (v)); | |
219 | spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); | |
220 | } | |
221 | ||
222 | static u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg) | |
223 | { | |
224 | unsigned long flags, address, data; | |
225 | u32 r; | |
226 | ||
227 | address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); | |
228 | data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); | |
229 | ||
230 | spin_lock_irqsave(&adev->didt_idx_lock, flags); | |
231 | WREG32(address, (reg)); | |
232 | r = RREG32(data); | |
233 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); | |
234 | return r; | |
235 | } | |
236 | ||
237 | static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
238 | { | |
239 | unsigned long flags, address, data; | |
240 | ||
241 | address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); | |
242 | data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); | |
243 | ||
244 | spin_lock_irqsave(&adev->didt_idx_lock, flags); | |
245 | WREG32(address, (reg)); | |
246 | WREG32(data, (v)); | |
247 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); | |
248 | } | |
249 | ||
560460f2 EQ |
250 | static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) |
251 | { | |
252 | unsigned long flags; | |
253 | u32 r; | |
254 | ||
255 | spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); | |
256 | WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); | |
257 | r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA); | |
258 | spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); | |
259 | return r; | |
260 | } | |
261 | ||
262 | static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
263 | { | |
264 | unsigned long flags; | |
265 | ||
266 | spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); | |
267 | WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); | |
268 | WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v)); | |
269 | spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); | |
270 | } | |
271 | ||
2f11fb02 EQ |
272 | static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg) |
273 | { | |
274 | unsigned long flags; | |
275 | u32 r; | |
276 | ||
277 | spin_lock_irqsave(&adev->se_cac_idx_lock, flags); | |
278 | WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); | |
279 | r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA); | |
280 | spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); | |
281 | return r; | |
282 | } | |
283 | ||
284 | static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
285 | { | |
286 | unsigned long flags; | |
287 | ||
288 | spin_lock_irqsave(&adev->se_cac_idx_lock, flags); | |
289 | WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); | |
290 | WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v)); | |
291 | spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); | |
292 | } | |
293 | ||
220ab9bd KW |
294 | static u32 soc15_get_config_memsize(struct amdgpu_device *adev) |
295 | { | |
bebc0762 | 296 | return adev->nbio.funcs->get_memsize(adev); |
220ab9bd KW |
297 | } |
298 | ||
220ab9bd KW |
299 | static u32 soc15_get_xclk(struct amdgpu_device *adev) |
300 | { | |
b90c4d66 AD |
301 | u32 reference_clock = adev->clock.spll.reference_freq; |
302 | ||
1d789535 AD |
303 | if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) || |
304 | adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) | |
6e80fb8a | 305 | return 10000; |
1d789535 AD |
306 | if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) || |
307 | adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1)) | |
b90c4d66 AD |
308 | return reference_clock / 4; |
309 | ||
310 | return reference_clock; | |
220ab9bd KW |
311 | } |
312 | ||
313 | ||
314 | void soc15_grbm_select(struct amdgpu_device *adev, | |
315 | u32 me, u32 pipe, u32 queue, u32 vmid) | |
316 | { | |
317 | u32 grbm_gfx_cntl = 0; | |
318 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe); | |
319 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me); | |
320 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid); | |
321 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue); | |
322 | ||
1bff7f6c | 323 | WREG32_SOC15_RLC_SHADOW(GC, 0, mmGRBM_GFX_CNTL, grbm_gfx_cntl); |
220ab9bd KW |
324 | } |
325 | ||
326 | static void soc15_vga_set_state(struct amdgpu_device *adev, bool state) | |
327 | { | |
328 | /* todo */ | |
329 | } | |
330 | ||
331 | static bool soc15_read_disabled_bios(struct amdgpu_device *adev) | |
332 | { | |
333 | /* todo */ | |
334 | return false; | |
335 | } | |
336 | ||
946a4d5b SL |
337 | static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = { |
338 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)}, | |
339 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)}, | |
340 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)}, | |
341 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)}, | |
342 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)}, | |
343 | { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)}, | |
344 | { SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)}, | |
345 | { SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)}, | |
346 | { SOC15_REG_ENTRY(GC, 0, mmCP_STAT)}, | |
347 | { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)}, | |
348 | { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)}, | |
349 | { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)}, | |
350 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)}, | |
351 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)}, | |
352 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)}, | |
664fe85a | 353 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)}, |
946a4d5b SL |
354 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)}, |
355 | { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)}, | |
356 | { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)}, | |
5eeae247 | 357 | { SOC15_REG_ENTRY(GC, 0, mmDB_DEBUG2)}, |
220ab9bd KW |
358 | }; |
359 | ||
360 | static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num, | |
361 | u32 sh_num, u32 reg_offset) | |
362 | { | |
363 | uint32_t val; | |
364 | ||
365 | mutex_lock(&adev->grbm_idx_mutex); | |
366 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | |
367 | amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); | |
368 | ||
369 | val = RREG32(reg_offset); | |
370 | ||
371 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | |
372 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | |
373 | mutex_unlock(&adev->grbm_idx_mutex); | |
374 | return val; | |
375 | } | |
376 | ||
c013cea2 AD |
377 | static uint32_t soc15_get_register_value(struct amdgpu_device *adev, |
378 | bool indexed, u32 se_num, | |
379 | u32 sh_num, u32 reg_offset) | |
380 | { | |
381 | if (indexed) { | |
382 | return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset); | |
383 | } else { | |
cd29253f | 384 | if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) |
c013cea2 | 385 | return adev->gfx.config.gb_addr_config; |
5eeae247 AD |
386 | else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) |
387 | return adev->gfx.config.db_debug2; | |
cd29253f | 388 | return RREG32(reg_offset); |
c013cea2 AD |
389 | } |
390 | } | |
391 | ||
220ab9bd KW |
392 | static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, |
393 | u32 sh_num, u32 reg_offset, u32 *value) | |
394 | { | |
3032f350 | 395 | uint32_t i; |
946a4d5b | 396 | struct soc15_allowed_register_entry *en; |
220ab9bd KW |
397 | |
398 | *value = 0; | |
220ab9bd | 399 | for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) { |
946a4d5b | 400 | en = &soc15_allowed_read_registers[i]; |
f651a7b6 AD |
401 | if (!adev->reg_offset[en->hwip][en->inst]) |
402 | continue; | |
403 | else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] | |
946a4d5b | 404 | + en->reg_offset)) |
220ab9bd KW |
405 | continue; |
406 | ||
97fcc76b CK |
407 | *value = soc15_get_register_value(adev, |
408 | soc15_allowed_read_registers[i].grbm_indexed, | |
409 | se_num, sh_num, reg_offset); | |
220ab9bd KW |
410 | return 0; |
411 | } | |
412 | return -EINVAL; | |
413 | } | |
414 | ||
946a4d5b SL |
415 | |
416 | /** | |
417 | * soc15_program_register_sequence - program an array of registers. | |
418 | * | |
419 | * @adev: amdgpu_device pointer | |
420 | * @regs: pointer to the register array | |
421 | * @array_size: size of the register array | |
422 | * | |
423 | * Programs an array or registers with and and or masks. | |
424 | * This is a helper for setting golden registers. | |
425 | */ | |
426 | ||
427 | void soc15_program_register_sequence(struct amdgpu_device *adev, | |
428 | const struct soc15_reg_golden *regs, | |
429 | const u32 array_size) | |
430 | { | |
431 | const struct soc15_reg_golden *entry; | |
432 | u32 tmp, reg; | |
433 | int i; | |
434 | ||
435 | for (i = 0; i < array_size; ++i) { | |
436 | entry = ®s[i]; | |
437 | reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg; | |
438 | ||
439 | if (entry->and_mask == 0xffffffff) { | |
440 | tmp = entry->or_mask; | |
441 | } else { | |
a9dc23be PJZ |
442 | tmp = (entry->hwip == GC_HWIP) ? |
443 | RREG32_SOC15_IP(GC, reg) : RREG32(reg); | |
444 | ||
946a4d5b | 445 | tmp &= ~(entry->and_mask); |
e0d07657 | 446 | tmp |= (entry->or_mask & entry->and_mask); |
946a4d5b | 447 | } |
1bff7f6c TH |
448 | |
449 | if (reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3) || | |
450 | reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE) || | |
451 | reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE_1) || | |
452 | reg == SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG)) | |
453 | WREG32_RLC(reg, tmp); | |
454 | else | |
a9dc23be PJZ |
455 | (entry->hwip == GC_HWIP) ? |
456 | WREG32_SOC15_IP(GC, reg, tmp) : WREG32(reg, tmp); | |
1bff7f6c | 457 | |
946a4d5b SL |
458 | } |
459 | ||
460 | } | |
461 | ||
e2b6d053 JQ |
462 | static int soc15_asic_baco_reset(struct amdgpu_device *adev) |
463 | { | |
956f6705 | 464 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
9530273e | 465 | int ret = 0; |
e2b6d053 | 466 | |
956f6705 | 467 | /* avoid NBIF got stuck when do RAS recovery in BACO reset */ |
8ab0d6f0 | 468 | if (ras && adev->ras_enabled) |
956f6705 LM |
469 | adev->nbio.funcs->enable_doorbell_interrupt(adev, false); |
470 | ||
9530273e EQ |
471 | ret = amdgpu_dpm_baco_reset(adev); |
472 | if (ret) | |
473 | return ret; | |
e2b6d053 | 474 | |
956f6705 | 475 | /* re-enable doorbell interrupt after BACO exit */ |
8ab0d6f0 | 476 | if (ras && adev->ras_enabled) |
956f6705 LM |
477 | adev->nbio.funcs->enable_doorbell_interrupt(adev, true); |
478 | ||
e2b6d053 JQ |
479 | return 0; |
480 | } | |
481 | ||
ee360c0b AD |
482 | static enum amd_reset_method |
483 | soc15_asic_reset_method(struct amdgpu_device *adev) | |
e2b6d053 | 484 | { |
feffbaac | 485 | bool baco_reset = false; |
5c03e584 | 486 | bool connected_to_cpu = false; |
feffbaac | 487 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
e2b6d053 | 488 | |
5c03e584 FX |
489 | if (adev->gmc.xgmi.supported && adev->gmc.xgmi.connected_to_cpu) |
490 | connected_to_cpu = true; | |
491 | ||
273da6ff WS |
492 | if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || |
493 | amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || | |
1176a1e0 | 494 | amdgpu_reset_method == AMD_RESET_METHOD_BACO || |
5c03e584 FX |
495 | amdgpu_reset_method == AMD_RESET_METHOD_PCI) { |
496 | /* If connected to cpu, driver only support mode2 */ | |
497 | if (connected_to_cpu) | |
498 | return AMD_RESET_METHOD_MODE2; | |
499 | return amdgpu_reset_method; | |
500 | } | |
273da6ff WS |
501 | |
502 | if (amdgpu_reset_method != -1) | |
503 | dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", | |
504 | amdgpu_reset_method); | |
505 | ||
1d789535 | 506 | switch (adev->ip_versions[MP1_HWIP][0]) { |
75a07bcd AD |
507 | case IP_VERSION(10, 0, 0): |
508 | case IP_VERSION(10, 0, 1): | |
509 | case IP_VERSION(12, 0, 0): | |
510 | case IP_VERSION(12, 0, 1): | |
ee360c0b | 511 | return AMD_RESET_METHOD_MODE2; |
75a07bcd AD |
512 | case IP_VERSION(9, 0, 0): |
513 | case IP_VERSION(11, 0, 2): | |
514 | if (adev->asic_type == CHIP_VEGA20) { | |
515 | if (adev->psp.sos.fw_version >= 0x80067) | |
516 | baco_reset = amdgpu_dpm_is_baco_supported(adev); | |
517 | /* | |
518 | * 1. PMFW version > 0x284300: all cases use baco | |
519 | * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco | |
520 | */ | |
521 | if (ras && adev->ras_enabled && | |
522 | adev->pm.fw_version <= 0x283400) | |
523 | baco_reset = false; | |
524 | } else { | |
9530273e | 525 | baco_reset = amdgpu_dpm_is_baco_supported(adev); |
75a07bcd | 526 | } |
017d75f1 | 527 | break; |
75a07bcd | 528 | case IP_VERSION(13, 0, 2): |
5c03e584 FX |
529 | /* |
530 | * 1.connected to cpu: driver issue mode2 reset | |
531 | * 2.discret gpu: driver issue mode1 reset | |
532 | */ | |
533 | if (connected_to_cpu) | |
534 | return AMD_RESET_METHOD_MODE2; | |
535 | break; | |
e2b6d053 | 536 | default: |
e2b6d053 JQ |
537 | break; |
538 | } | |
539 | ||
540 | if (baco_reset) | |
ee360c0b AD |
541 | return AMD_RESET_METHOD_BACO; |
542 | else | |
543 | return AMD_RESET_METHOD_MODE1; | |
544 | } | |
545 | ||
546 | static int soc15_asic_reset(struct amdgpu_device *adev) | |
547 | { | |
276cc929 | 548 | /* original raven doesn't have full asic reset */ |
1e2be869 CG |
549 | if ((adev->apu_flags & AMD_APU_IS_RAVEN) || |
550 | (adev->apu_flags & AMD_APU_IS_RAVEN2)) | |
276cc929 AD |
551 | return 0; |
552 | ||
c43b849f | 553 | switch (soc15_asic_reset_method(adev)) { |
1176a1e0 AD |
554 | case AMD_RESET_METHOD_PCI: |
555 | dev_info(adev->dev, "PCI reset\n"); | |
556 | return amdgpu_device_pci_reset(adev); | |
557 | case AMD_RESET_METHOD_BACO: | |
558 | dev_info(adev->dev, "BACO reset\n"); | |
559 | return soc15_asic_baco_reset(adev); | |
560 | case AMD_RESET_METHOD_MODE2: | |
561 | dev_info(adev->dev, "MODE2 reset\n"); | |
562 | return amdgpu_dpm_mode2_reset(adev); | |
563 | default: | |
564 | dev_info(adev->dev, "MODE1 reset\n"); | |
5c03e584 | 565 | return amdgpu_device_mode1_reset(adev); |
c43b849f | 566 | } |
e2b6d053 JQ |
567 | } |
568 | ||
988eb9ff AD |
569 | static bool soc15_supports_baco(struct amdgpu_device *adev) |
570 | { | |
1d789535 | 571 | switch (adev->ip_versions[MP1_HWIP][0]) { |
75a07bcd AD |
572 | case IP_VERSION(9, 0, 0): |
573 | case IP_VERSION(11, 0, 2): | |
574 | if (adev->asic_type == CHIP_VEGA20) { | |
575 | if (adev->psp.sos.fw_version >= 0x80067) | |
576 | return amdgpu_dpm_is_baco_supported(adev); | |
577 | return false; | |
578 | } else { | |
9530273e | 579 | return amdgpu_dpm_is_baco_supported(adev); |
75a07bcd AD |
580 | } |
581 | break; | |
988eb9ff AD |
582 | default: |
583 | return false; | |
584 | } | |
988eb9ff AD |
585 | } |
586 | ||
220ab9bd KW |
587 | /*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock, |
588 | u32 cntl_reg, u32 status_reg) | |
589 | { | |
590 | return 0; | |
591 | }*/ | |
592 | ||
593 | static int soc15_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) | |
594 | { | |
595 | /*int r; | |
596 | ||
597 | r = soc15_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS); | |
598 | if (r) | |
599 | return r; | |
600 | ||
601 | r = soc15_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS); | |
602 | */ | |
603 | return 0; | |
604 | } | |
605 | ||
606 | static int soc15_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) | |
607 | { | |
608 | /* todo */ | |
609 | ||
610 | return 0; | |
611 | } | |
612 | ||
613 | static void soc15_pcie_gen3_enable(struct amdgpu_device *adev) | |
614 | { | |
615 | if (pci_is_root_bus(adev->pdev->bus)) | |
616 | return; | |
617 | ||
618 | if (amdgpu_pcie_gen2 == 0) | |
619 | return; | |
620 | ||
621 | if (adev->flags & AMD_IS_APU) | |
622 | return; | |
623 | ||
624 | if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | | |
625 | CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) | |
626 | return; | |
627 | ||
628 | /* todo */ | |
629 | } | |
630 | ||
631 | static void soc15_program_aspm(struct amdgpu_device *adev) | |
632 | { | |
0ab5d711 | 633 | if (!amdgpu_device_should_use_aspm(adev)) |
220ab9bd KW |
634 | return; |
635 | ||
9d015c0d KF |
636 | if (!(adev->flags & AMD_IS_APU) && |
637 | (adev->nbio.funcs->program_aspm)) | |
638 | adev->nbio.funcs->program_aspm(adev); | |
220ab9bd KW |
639 | } |
640 | ||
641 | static void soc15_enable_doorbell_aperture(struct amdgpu_device *adev, | |
bf383fb6 | 642 | bool enable) |
220ab9bd | 643 | { |
bebc0762 HZ |
644 | adev->nbio.funcs->enable_doorbell_aperture(adev, enable); |
645 | adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); | |
220ab9bd KW |
646 | } |
647 | ||
994470b2 | 648 | const struct amdgpu_ip_block_version vega10_common_ip_block = |
220ab9bd KW |
649 | { |
650 | .type = AMD_IP_BLOCK_TYPE_COMMON, | |
651 | .major = 2, | |
652 | .minor = 0, | |
653 | .rev = 0, | |
654 | .funcs = &soc15_common_ip_funcs, | |
655 | }; | |
656 | ||
4cb0becb HR |
657 | static uint32_t soc15_get_rev_id(struct amdgpu_device *adev) |
658 | { | |
bebc0762 | 659 | return adev->nbio.funcs->get_rev_id(adev); |
4cb0becb HR |
660 | } |
661 | ||
d95f09ac | 662 | static void soc15_reg_base_init(struct amdgpu_device *adev) |
220ab9bd | 663 | { |
4522824c SL |
664 | /* Set IP register base before any HW register access */ |
665 | switch (adev->asic_type) { | |
666 | case CHIP_VEGA10: | |
3084eb00 | 667 | case CHIP_VEGA12: |
4522824c | 668 | case CHIP_RAVEN: |
c1cf79ca | 669 | case CHIP_RENOIR: |
2ae78708 | 670 | vega10_reg_base_init(adev); |
c1cf79ca | 671 | break; |
8ee273e5 FX |
672 | case CHIP_VEGA20: |
673 | vega20_reg_base_init(adev); | |
674 | break; | |
e78705ec LM |
675 | case CHIP_ARCTURUS: |
676 | arct_reg_base_init(adev); | |
677 | break; | |
42b72608 LM |
678 | case CHIP_ALDEBARAN: |
679 | aldebaran_reg_base_init(adev); | |
680 | break; | |
4522824c | 681 | default: |
d95f09ac WS |
682 | DRM_ERROR("Unsupported asic type: %d!\n", adev->asic_type); |
683 | break; | |
4522824c | 684 | } |
d95f09ac WS |
685 | } |
686 | ||
687 | void soc15_set_virt_ops(struct amdgpu_device *adev) | |
688 | { | |
689 | adev->virt.ops = &xgpu_ai_virt_ops; | |
690 | ||
691 | /* init soc15 reg base early enough so we can | |
692 | * request request full access for sriov before | |
693 | * set_ip_blocks. */ | |
694 | soc15_reg_base_init(adev); | |
695 | } | |
696 | ||
adbd4f89 AD |
697 | static bool soc15_need_full_reset(struct amdgpu_device *adev) |
698 | { | |
699 | /* change this when we implement soft reset */ | |
700 | return true; | |
701 | } | |
4a89ad9b | 702 | |
b45e18ac KR |
703 | static void soc15_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, |
704 | uint64_t *count1) | |
705 | { | |
706 | uint32_t perfctr = 0; | |
707 | uint64_t cnt0_of, cnt1_of; | |
708 | int tmp; | |
709 | ||
710 | /* This reports 0 on APUs, so return to avoid writing/reading registers | |
711 | * that may or may not be different from their GPU counterparts | |
712 | */ | |
0172591e ES |
713 | if (adev->flags & AMD_IS_APU) |
714 | return; | |
b45e18ac KR |
715 | |
716 | /* Set the 2 events that we wish to watch, defined above */ | |
9417f703 | 717 | /* Reg 40 is # received msgs */ |
612e4ed9 | 718 | /* Reg 104 is # of posted requests sent */ |
b45e18ac | 719 | perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT0_SEL, 40); |
612e4ed9 | 720 | perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT1_SEL, 104); |
b45e18ac KR |
721 | |
722 | /* Write to enable desired perf counters */ | |
723 | WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK, perfctr); | |
724 | /* Zero out and enable the perf counters | |
725 | * Write 0x5: | |
726 | * Bit 0 = Start all counters(1) | |
727 | * Bit 2 = Global counter reset enable(1) | |
728 | */ | |
729 | WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); | |
730 | ||
731 | msleep(1000); | |
732 | ||
733 | /* Load the shadow and disable the perf counters | |
734 | * Write 0x2: | |
735 | * Bit 0 = Stop counters(0) | |
736 | * Bit 1 = Load the shadow counters(1) | |
737 | */ | |
738 | WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); | |
739 | ||
740 | /* Read register values to get any >32bit overflow */ | |
741 | tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK); | |
742 | cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER0_UPPER); | |
743 | cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER1_UPPER); | |
744 | ||
745 | /* Get the values and add the overflow */ | |
746 | *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK) | (cnt0_of << 32); | |
747 | *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK) | (cnt1_of << 32); | |
748 | } | |
adbd4f89 | 749 | |
612e4ed9 KR |
750 | static void vega20_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, |
751 | uint64_t *count1) | |
752 | { | |
753 | uint32_t perfctr = 0; | |
754 | uint64_t cnt0_of, cnt1_of; | |
755 | int tmp; | |
756 | ||
757 | /* This reports 0 on APUs, so return to avoid writing/reading registers | |
758 | * that may or may not be different from their GPU counterparts | |
759 | */ | |
760 | if (adev->flags & AMD_IS_APU) | |
761 | return; | |
762 | ||
763 | /* Set the 2 events that we wish to watch, defined above */ | |
764 | /* Reg 40 is # received msgs */ | |
765 | /* Reg 108 is # of posted requests sent on VG20 */ | |
766 | perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, | |
767 | EVENT0_SEL, 40); | |
768 | perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, | |
769 | EVENT1_SEL, 108); | |
770 | ||
771 | /* Write to enable desired perf counters */ | |
772 | WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3, perfctr); | |
773 | /* Zero out and enable the perf counters | |
774 | * Write 0x5: | |
775 | * Bit 0 = Start all counters(1) | |
776 | * Bit 2 = Global counter reset enable(1) | |
777 | */ | |
778 | WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); | |
779 | ||
780 | msleep(1000); | |
781 | ||
782 | /* Load the shadow and disable the perf counters | |
783 | * Write 0x2: | |
784 | * Bit 0 = Stop counters(0) | |
785 | * Bit 1 = Load the shadow counters(1) | |
786 | */ | |
787 | WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); | |
788 | ||
789 | /* Read register values to get any >32bit overflow */ | |
790 | tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3); | |
791 | cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER0_UPPER); | |
792 | cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER1_UPPER); | |
793 | ||
794 | /* Get the values and add the overflow */ | |
795 | *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK3) | (cnt0_of << 32); | |
796 | *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK3) | (cnt1_of << 32); | |
797 | } | |
798 | ||
9281f12c AD |
799 | static bool soc15_need_reset_on_init(struct amdgpu_device *adev) |
800 | { | |
801 | u32 sol_reg; | |
802 | ||
72a98763 TY |
803 | /* CP hangs in IGT reloading test on RN, reset to WA */ |
804 | if (adev->asic_type == CHIP_RENOIR) | |
805 | return true; | |
806 | ||
d55f33da AD |
807 | /* Just return false for soc15 GPUs. Reset does not seem to |
808 | * be necessary. | |
809 | */ | |
394e9a14 ED |
810 | if (!amdgpu_passthrough(adev)) |
811 | return false; | |
d55f33da | 812 | |
9281f12c AD |
813 | if (adev->flags & AMD_IS_APU) |
814 | return false; | |
815 | ||
816 | /* Check sOS sign of life register to confirm sys driver and sOS | |
817 | * are already been loaded. | |
818 | */ | |
819 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | |
820 | if (sol_reg) | |
821 | return true; | |
822 | ||
823 | return false; | |
824 | } | |
825 | ||
dcea6e65 KR |
826 | static uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev) |
827 | { | |
828 | uint64_t nak_r, nak_g; | |
829 | ||
830 | /* Get the number of NAKs received and generated */ | |
831 | nak_r = RREG32_PCIE(smnPCIE_RX_NUM_NAK); | |
832 | nak_g = RREG32_PCIE(smnPCIE_RX_NUM_NAK_GENERATED); | |
833 | ||
834 | /* Add the total number of NAKs, i.e the number of replays */ | |
835 | return (nak_r + nak_g); | |
836 | } | |
837 | ||
b0a2db9b AD |
838 | static void soc15_pre_asic_init(struct amdgpu_device *adev) |
839 | { | |
840 | gmc_v9_0_restore_registers(adev); | |
841 | } | |
842 | ||
220ab9bd KW |
843 | static const struct amdgpu_asic_funcs soc15_asic_funcs = |
844 | { | |
845 | .read_disabled_bios = &soc15_read_disabled_bios, | |
04022982 | 846 | .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, |
220ab9bd KW |
847 | .read_register = &soc15_read_register, |
848 | .reset = &soc15_asic_reset, | |
ee360c0b | 849 | .reset_method = &soc15_asic_reset_method, |
220ab9bd KW |
850 | .set_vga_state = &soc15_vga_set_state, |
851 | .get_xclk = &soc15_get_xclk, | |
852 | .set_uvd_clocks = &soc15_set_uvd_clocks, | |
853 | .set_vce_clocks = &soc15_set_vce_clocks, | |
854 | .get_config_memsize = &soc15_get_config_memsize, | |
adbd4f89 | 855 | .need_full_reset = &soc15_need_full_reset, |
062f3807 | 856 | .init_doorbell_index = &vega10_doorbell_index_init, |
b45e18ac | 857 | .get_pcie_usage = &soc15_get_pcie_usage, |
9281f12c | 858 | .need_reset_on_init = &soc15_need_reset_on_init, |
dcea6e65 | 859 | .get_pcie_replay_count = &soc15_get_pcie_replay_count, |
988eb9ff | 860 | .supports_baco = &soc15_supports_baco, |
b0a2db9b | 861 | .pre_asic_init = &soc15_pre_asic_init, |
3b246e8b | 862 | .query_video_codecs = &soc15_query_video_codecs, |
220ab9bd KW |
863 | }; |
864 | ||
c93aa775 OZ |
865 | static const struct amdgpu_asic_funcs vega20_asic_funcs = |
866 | { | |
867 | .read_disabled_bios = &soc15_read_disabled_bios, | |
04022982 | 868 | .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, |
c93aa775 OZ |
869 | .read_register = &soc15_read_register, |
870 | .reset = &soc15_asic_reset, | |
761e0923 | 871 | .reset_method = &soc15_asic_reset_method, |
c93aa775 OZ |
872 | .set_vga_state = &soc15_vga_set_state, |
873 | .get_xclk = &soc15_get_xclk, | |
874 | .set_uvd_clocks = &soc15_set_uvd_clocks, | |
875 | .set_vce_clocks = &soc15_set_vce_clocks, | |
876 | .get_config_memsize = &soc15_get_config_memsize, | |
c93aa775 OZ |
877 | .need_full_reset = &soc15_need_full_reset, |
878 | .init_doorbell_index = &vega20_doorbell_index_init, | |
612e4ed9 | 879 | .get_pcie_usage = &vega20_get_pcie_usage, |
9281f12c | 880 | .need_reset_on_init = &soc15_need_reset_on_init, |
dcea6e65 | 881 | .get_pcie_replay_count = &soc15_get_pcie_replay_count, |
988eb9ff | 882 | .supports_baco = &soc15_supports_baco, |
b0a2db9b | 883 | .pre_asic_init = &soc15_pre_asic_init, |
3b246e8b | 884 | .query_video_codecs = &soc15_query_video_codecs, |
220ab9bd KW |
885 | }; |
886 | ||
887 | static int soc15_common_early_init(void *handle) | |
888 | { | |
88807dc8 | 889 | #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) |
220ab9bd KW |
890 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
891 | ||
e3993811 FK |
892 | if (!amdgpu_sriov_vf(adev)) { |
893 | adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
894 | adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
895 | } | |
220ab9bd KW |
896 | adev->smc_rreg = NULL; |
897 | adev->smc_wreg = NULL; | |
65ba96e9 HZ |
898 | adev->pcie_rreg = &amdgpu_device_indirect_rreg; |
899 | adev->pcie_wreg = &amdgpu_device_indirect_wreg; | |
900 | adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64; | |
901 | adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64; | |
220ab9bd KW |
902 | adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg; |
903 | adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg; | |
904 | adev->didt_rreg = &soc15_didt_rreg; | |
905 | adev->didt_wreg = &soc15_didt_wreg; | |
560460f2 EQ |
906 | adev->gc_cac_rreg = &soc15_gc_cac_rreg; |
907 | adev->gc_cac_wreg = &soc15_gc_cac_wreg; | |
2f11fb02 EQ |
908 | adev->se_cac_rreg = &soc15_se_cac_rreg; |
909 | adev->se_cac_wreg = &soc15_se_cac_wreg; | |
220ab9bd | 910 | |
91e9db33 | 911 | adev->rev_id = soc15_get_rev_id(adev); |
220ab9bd | 912 | adev->external_rev_id = 0xFF; |
75a07bcd AD |
913 | /* TODO: split the GC and PG flags based on the relevant IP version for which |
914 | * they are relevant. | |
915 | */ | |
1d789535 | 916 | switch (adev->ip_versions[GC_HWIP][0]) { |
75a07bcd | 917 | case IP_VERSION(9, 0, 1): |
c93aa775 | 918 | adev->asic_funcs = &soc15_asic_funcs; |
220ab9bd KW |
919 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
920 | AMD_CG_SUPPORT_GFX_MGLS | | |
921 | AMD_CG_SUPPORT_GFX_RLC_LS | | |
922 | AMD_CG_SUPPORT_GFX_CP_LS | | |
923 | AMD_CG_SUPPORT_GFX_3D_CGCG | | |
924 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
925 | AMD_CG_SUPPORT_GFX_CGCG | | |
926 | AMD_CG_SUPPORT_GFX_CGLS | | |
927 | AMD_CG_SUPPORT_BIF_MGCG | | |
928 | AMD_CG_SUPPORT_BIF_LS | | |
929 | AMD_CG_SUPPORT_HDP_LS | | |
930 | AMD_CG_SUPPORT_DRM_MGCG | | |
931 | AMD_CG_SUPPORT_DRM_LS | | |
932 | AMD_CG_SUPPORT_ROM_MGCG | | |
933 | AMD_CG_SUPPORT_DF_MGCG | | |
934 | AMD_CG_SUPPORT_SDMA_MGCG | | |
935 | AMD_CG_SUPPORT_SDMA_LS | | |
936 | AMD_CG_SUPPORT_MC_MGCG | | |
937 | AMD_CG_SUPPORT_MC_LS; | |
938 | adev->pg_flags = 0; | |
939 | adev->external_rev_id = 0x1; | |
940 | break; | |
75a07bcd | 941 | case IP_VERSION(9, 2, 1): |
c93aa775 | 942 | adev->asic_funcs = &soc15_asic_funcs; |
e4a38755 EQ |
943 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
944 | AMD_CG_SUPPORT_GFX_MGLS | | |
945 | AMD_CG_SUPPORT_GFX_CGCG | | |
946 | AMD_CG_SUPPORT_GFX_CGLS | | |
947 | AMD_CG_SUPPORT_GFX_3D_CGCG | | |
948 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
949 | AMD_CG_SUPPORT_GFX_CP_LS | | |
950 | AMD_CG_SUPPORT_MC_LS | | |
951 | AMD_CG_SUPPORT_MC_MGCG | | |
952 | AMD_CG_SUPPORT_SDMA_MGCG | | |
953 | AMD_CG_SUPPORT_SDMA_LS | | |
954 | AMD_CG_SUPPORT_BIF_MGCG | | |
955 | AMD_CG_SUPPORT_BIF_LS | | |
956 | AMD_CG_SUPPORT_HDP_MGCG | | |
957 | AMD_CG_SUPPORT_HDP_LS | | |
958 | AMD_CG_SUPPORT_ROM_MGCG | | |
959 | AMD_CG_SUPPORT_VCE_MGCG | | |
960 | AMD_CG_SUPPORT_UVD_MGCG; | |
692069a1 | 961 | adev->pg_flags = 0; |
f559fe2b | 962 | adev->external_rev_id = adev->rev_id + 0x14; |
692069a1 | 963 | break; |
75a07bcd | 964 | case IP_VERSION(9, 4, 0): |
c93aa775 | 965 | adev->asic_funcs = &vega20_asic_funcs; |
3fdbab5f EQ |
966 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
967 | AMD_CG_SUPPORT_GFX_MGLS | | |
968 | AMD_CG_SUPPORT_GFX_CGCG | | |
969 | AMD_CG_SUPPORT_GFX_CGLS | | |
970 | AMD_CG_SUPPORT_GFX_3D_CGCG | | |
971 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
972 | AMD_CG_SUPPORT_GFX_CP_LS | | |
973 | AMD_CG_SUPPORT_MC_LS | | |
974 | AMD_CG_SUPPORT_MC_MGCG | | |
975 | AMD_CG_SUPPORT_SDMA_MGCG | | |
976 | AMD_CG_SUPPORT_SDMA_LS | | |
977 | AMD_CG_SUPPORT_BIF_MGCG | | |
978 | AMD_CG_SUPPORT_BIF_LS | | |
979 | AMD_CG_SUPPORT_HDP_MGCG | | |
102e4940 | 980 | AMD_CG_SUPPORT_HDP_LS | |
3fdbab5f EQ |
981 | AMD_CG_SUPPORT_ROM_MGCG | |
982 | AMD_CG_SUPPORT_VCE_MGCG | | |
983 | AMD_CG_SUPPORT_UVD_MGCG; | |
935be7a0 FX |
984 | adev->pg_flags = 0; |
985 | adev->external_rev_id = adev->rev_id + 0x28; | |
986 | break; | |
75a07bcd AD |
987 | case IP_VERSION(9, 1, 0): |
988 | case IP_VERSION(9, 2, 2): | |
c93aa775 | 989 | adev->asic_funcs = &soc15_asic_funcs; |
9f6a7857 | 990 | |
520cbe0f | 991 | if (adev->rev_id >= 0x8) |
54f78a76 AD |
992 | adev->apu_flags |= AMD_APU_IS_RAVEN2; |
993 | ||
994 | if (adev->apu_flags & AMD_APU_IS_RAVEN2) | |
7e4545d3 | 995 | adev->external_rev_id = adev->rev_id + 0x79; |
54f78a76 | 996 | else if (adev->apu_flags & AMD_APU_IS_PICASSO) |
741deade | 997 | adev->external_rev_id = adev->rev_id + 0x41; |
7e4545d3 HR |
998 | else if (adev->rev_id == 1) |
999 | adev->external_rev_id = adev->rev_id + 0x20; | |
741deade | 1000 | else |
7e4545d3 | 1001 | adev->external_rev_id = adev->rev_id + 0x01; |
741deade | 1002 | |
54f78a76 | 1003 | if (adev->apu_flags & AMD_APU_IS_RAVEN2) { |
520cbe0f HR |
1004 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1005 | AMD_CG_SUPPORT_GFX_MGLS | | |
1006 | AMD_CG_SUPPORT_GFX_CP_LS | | |
1007 | AMD_CG_SUPPORT_GFX_3D_CGCG | | |
1008 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
1009 | AMD_CG_SUPPORT_GFX_CGCG | | |
1010 | AMD_CG_SUPPORT_GFX_CGLS | | |
1011 | AMD_CG_SUPPORT_BIF_LS | | |
1012 | AMD_CG_SUPPORT_HDP_LS | | |
520cbe0f HR |
1013 | AMD_CG_SUPPORT_MC_MGCG | |
1014 | AMD_CG_SUPPORT_MC_LS | | |
1015 | AMD_CG_SUPPORT_SDMA_MGCG | | |
1016 | AMD_CG_SUPPORT_SDMA_LS | | |
1017 | AMD_CG_SUPPORT_VCN_MGCG; | |
741deade | 1018 | |
d5159591 | 1019 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; |
54f78a76 | 1020 | } else if (adev->apu_flags & AMD_APU_IS_PICASSO) { |
fced5c70 LG |
1021 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1022 | AMD_CG_SUPPORT_GFX_MGLS | | |
741deade | 1023 | AMD_CG_SUPPORT_GFX_CP_LS | |
741deade AD |
1024 | AMD_CG_SUPPORT_GFX_3D_CGLS | |
1025 | AMD_CG_SUPPORT_GFX_CGCG | | |
1026 | AMD_CG_SUPPORT_GFX_CGLS | | |
1027 | AMD_CG_SUPPORT_BIF_LS | | |
1028 | AMD_CG_SUPPORT_HDP_LS | | |
741deade AD |
1029 | AMD_CG_SUPPORT_MC_MGCG | |
1030 | AMD_CG_SUPPORT_MC_LS | | |
1031 | AMD_CG_SUPPORT_SDMA_MGCG | | |
a8f76887 S |
1032 | AMD_CG_SUPPORT_SDMA_LS | |
1033 | AMD_CG_SUPPORT_VCN_MGCG; | |
741deade | 1034 | |
e506db59 EQ |
1035 | /* |
1036 | * MMHUB PG needs to be disabled for Picasso for | |
1037 | * stability reasons. | |
1038 | */ | |
741deade | 1039 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | |
a10aad13 | 1040 | AMD_PG_SUPPORT_VCN; |
741deade | 1041 | } else { |
520cbe0f HR |
1042 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1043 | AMD_CG_SUPPORT_GFX_MGLS | | |
1044 | AMD_CG_SUPPORT_GFX_RLC_LS | | |
1045 | AMD_CG_SUPPORT_GFX_CP_LS | | |
520cbe0f HR |
1046 | AMD_CG_SUPPORT_GFX_3D_CGLS | |
1047 | AMD_CG_SUPPORT_GFX_CGCG | | |
1048 | AMD_CG_SUPPORT_GFX_CGLS | | |
1049 | AMD_CG_SUPPORT_BIF_MGCG | | |
1050 | AMD_CG_SUPPORT_BIF_LS | | |
1051 | AMD_CG_SUPPORT_HDP_MGCG | | |
1052 | AMD_CG_SUPPORT_HDP_LS | | |
1053 | AMD_CG_SUPPORT_DRM_MGCG | | |
1054 | AMD_CG_SUPPORT_DRM_LS | | |
520cbe0f HR |
1055 | AMD_CG_SUPPORT_MC_MGCG | |
1056 | AMD_CG_SUPPORT_MC_LS | | |
1057 | AMD_CG_SUPPORT_SDMA_MGCG | | |
1058 | AMD_CG_SUPPORT_SDMA_LS | | |
1059 | AMD_CG_SUPPORT_VCN_MGCG; | |
61c8e90d | 1060 | |
d5159591 | 1061 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; |
741deade | 1062 | } |
ad5a67a7 | 1063 | break; |
75a07bcd | 1064 | case IP_VERSION(9, 4, 1): |
7f40581c | 1065 | adev->asic_funcs = &vega20_asic_funcs; |
6b76ce62 LM |
1066 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1067 | AMD_CG_SUPPORT_GFX_MGLS | | |
1068 | AMD_CG_SUPPORT_GFX_CGCG | | |
5d111f5b | 1069 | AMD_CG_SUPPORT_GFX_CGLS | |
f9da7c43 | 1070 | AMD_CG_SUPPORT_GFX_CP_LS | |
5d111f5b | 1071 | AMD_CG_SUPPORT_HDP_MGCG | |
f7ee1995 LM |
1072 | AMD_CG_SUPPORT_HDP_LS | |
1073 | AMD_CG_SUPPORT_SDMA_MGCG | | |
a840159c LM |
1074 | AMD_CG_SUPPORT_SDMA_LS | |
1075 | AMD_CG_SUPPORT_MC_MGCG | | |
227f7d58 | 1076 | AMD_CG_SUPPORT_MC_LS | |
e89e2237 LL |
1077 | AMD_CG_SUPPORT_IH_CG | |
1078 | AMD_CG_SUPPORT_VCN_MGCG | | |
1079 | AMD_CG_SUPPORT_JPEG_MGCG; | |
e520859c | 1080 | adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG; |
d57c3d56 | 1081 | adev->external_rev_id = adev->rev_id + 0x32; |
0e54df05 | 1082 | break; |
75a07bcd | 1083 | case IP_VERSION(9, 3, 0): |
e09ce481 | 1084 | adev->asic_funcs = &soc15_asic_funcs; |
5baf4150 PL |
1085 | |
1086 | if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
1087 | adev->external_rev_id = adev->rev_id + 0x91; | |
1088 | else | |
1089 | adev->external_rev_id = adev->rev_id + 0xa1; | |
ec3636a5 PL |
1090 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1091 | AMD_CG_SUPPORT_GFX_MGLS | | |
1092 | AMD_CG_SUPPORT_GFX_3D_CGCG | | |
1093 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
1094 | AMD_CG_SUPPORT_GFX_CGCG | | |
1095 | AMD_CG_SUPPORT_GFX_CGLS | | |
a2d15255 PL |
1096 | AMD_CG_SUPPORT_GFX_CP_LS | |
1097 | AMD_CG_SUPPORT_MC_MGCG | | |
ef0e7d08 PL |
1098 | AMD_CG_SUPPORT_MC_LS | |
1099 | AMD_CG_SUPPORT_SDMA_MGCG | | |
d98930f5 | 1100 | AMD_CG_SUPPORT_SDMA_LS | |
9deac0a4 | 1101 | AMD_CG_SUPPORT_BIF_LS | |
de273070 | 1102 | AMD_CG_SUPPORT_HDP_LS | |
91ec8bbb | 1103 | AMD_CG_SUPPORT_VCN_MGCG | |
099d66e4 | 1104 | AMD_CG_SUPPORT_JPEG_MGCG | |
e2ef3b70 PL |
1105 | AMD_CG_SUPPORT_IH_CG | |
1106 | AMD_CG_SUPPORT_ATHUB_LS | | |
8db63b7c PL |
1107 | AMD_CG_SUPPORT_ATHUB_MGCG | |
1108 | AMD_CG_SUPPORT_DF_MGCG; | |
85400984 TT |
1109 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | |
1110 | AMD_PG_SUPPORT_VCN | | |
099d66e4 | 1111 | AMD_PG_SUPPORT_JPEG | |
85400984 | 1112 | AMD_PG_SUPPORT_VCN_DPG; |
080deab6 | 1113 | break; |
75a07bcd | 1114 | case IP_VERSION(9, 4, 2): |
7906af5e | 1115 | adev->asic_funcs = &vega20_asic_funcs; |
48a6379a LL |
1116 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
1117 | AMD_CG_SUPPORT_GFX_MGLS | | |
48a6379a LL |
1118 | AMD_CG_SUPPORT_GFX_CP_LS | |
1119 | AMD_CG_SUPPORT_HDP_LS | | |
1120 | AMD_CG_SUPPORT_SDMA_MGCG | | |
1121 | AMD_CG_SUPPORT_SDMA_LS | | |
50ca2522 LL |
1122 | AMD_CG_SUPPORT_IH_CG | |
1123 | AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG; | |
bd937973 | 1124 | adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG; |
4f668d3d | 1125 | adev->external_rev_id = adev->rev_id + 0x3c; |
7906af5e | 1126 | break; |
220ab9bd KW |
1127 | default: |
1128 | /* FIXME: not supported yet */ | |
1129 | return -EINVAL; | |
1130 | } | |
1131 | ||
ab276632 XY |
1132 | if (amdgpu_sriov_vf(adev)) { |
1133 | amdgpu_virt_init_setting(adev); | |
1134 | xgpu_ai_mailbox_set_irq_funcs(adev); | |
1135 | } | |
1136 | ||
220ab9bd KW |
1137 | return 0; |
1138 | } | |
1139 | ||
81758c55 ML |
1140 | static int soc15_common_late_init(void *handle) |
1141 | { | |
1142 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1143 | ||
1144 | if (amdgpu_sriov_vf(adev)) | |
1145 | xgpu_ai_mailbox_get_irq(adev); | |
1146 | ||
867e24ca | 1147 | return 0; |
81758c55 ML |
1148 | } |
1149 | ||
220ab9bd KW |
1150 | static int soc15_common_sw_init(void *handle) |
1151 | { | |
81758c55 ML |
1152 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1153 | ||
1154 | if (amdgpu_sriov_vf(adev)) | |
1155 | xgpu_ai_mailbox_add_irq_id(adev); | |
1156 | ||
cace4bff HZ |
1157 | if (adev->df.funcs && |
1158 | adev->df.funcs->sw_init) | |
1159 | adev->df.funcs->sw_init(adev); | |
e4cf4bf5 | 1160 | |
220ab9bd KW |
1161 | return 0; |
1162 | } | |
1163 | ||
1164 | static int soc15_common_sw_fini(void *handle) | |
1165 | { | |
f1d59e00 JZ |
1166 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1167 | ||
cace4bff HZ |
1168 | if (adev->df.funcs && |
1169 | adev->df.funcs->sw_fini) | |
1170 | adev->df.funcs->sw_fini(adev); | |
220ab9bd KW |
1171 | return 0; |
1172 | } | |
1173 | ||
50b0e4d4 AD |
1174 | static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev) |
1175 | { | |
1176 | int i; | |
1177 | ||
1178 | /* sdma doorbell range is programed by hypervisor */ | |
1179 | if (!amdgpu_sriov_vf(adev)) { | |
1180 | for (i = 0; i < adev->sdma.num_instances; i++) { | |
1181 | adev->nbio.funcs->sdma_doorbell_range(adev, i, | |
1182 | true, adev->doorbell_index.sdma_engine[i] << 1, | |
1183 | adev->doorbell_index.sdma_doorbell_range); | |
1184 | } | |
1185 | } | |
1186 | } | |
1187 | ||
220ab9bd KW |
1188 | static int soc15_common_hw_init(void *handle) |
1189 | { | |
1190 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1191 | ||
220ab9bd KW |
1192 | /* enable pcie gen2/3 link */ |
1193 | soc15_pcie_gen3_enable(adev); | |
1194 | /* enable aspm */ | |
1195 | soc15_program_aspm(adev); | |
833fa075 | 1196 | /* setup nbio registers */ |
bebc0762 | 1197 | adev->nbio.funcs->init_registers(adev); |
88807dc8 OZ |
1198 | /* remap HDP registers to a hole in mmio space, |
1199 | * for the purpose of expose those registers | |
1200 | * to process space | |
1201 | */ | |
e3993811 | 1202 | if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) |
bebc0762 | 1203 | adev->nbio.funcs->remap_hdp_registers(adev); |
e4cf4bf5 | 1204 | |
220ab9bd KW |
1205 | /* enable the doorbell aperture */ |
1206 | soc15_enable_doorbell_aperture(adev, true); | |
50b0e4d4 AD |
1207 | /* HW doorbell routing policy: doorbell writing not |
1208 | * in SDMA/IH/MM/ACV range will be routed to CP. So | |
1209 | * we need to init SDMA doorbell range prior | |
1210 | * to CP ip block init and ring test. IH already | |
1211 | * happens before CP. | |
1212 | */ | |
1213 | soc15_sdma_doorbell_range_init(adev); | |
220ab9bd KW |
1214 | |
1215 | return 0; | |
1216 | } | |
1217 | ||
1218 | static int soc15_common_hw_fini(void *handle) | |
1219 | { | |
1220 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1221 | ||
1222 | /* disable the doorbell aperture */ | |
1223 | soc15_enable_doorbell_aperture(adev, false); | |
81758c55 ML |
1224 | if (amdgpu_sriov_vf(adev)) |
1225 | xgpu_ai_mailbox_put_irq(adev); | |
220ab9bd | 1226 | |
cde85ac2 PY |
1227 | if (adev->nbio.ras_if && |
1228 | amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) { | |
2e54fe5d | 1229 | if (adev->nbio.ras && |
1230 | adev->nbio.ras->init_ras_controller_interrupt) | |
22e1d14f | 1231 | amdgpu_irq_put(adev, &adev->nbio.ras_controller_irq, 0); |
2e54fe5d | 1232 | if (adev->nbio.ras && |
1233 | adev->nbio.ras->init_ras_err_event_athub_interrupt) | |
22e1d14f HZ |
1234 | amdgpu_irq_put(adev, &adev->nbio.ras_err_event_athub_irq, 0); |
1235 | } | |
1236 | ||
220ab9bd KW |
1237 | return 0; |
1238 | } | |
1239 | ||
1240 | static int soc15_common_suspend(void *handle) | |
1241 | { | |
1242 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1243 | ||
1244 | return soc15_common_hw_fini(adev); | |
1245 | } | |
1246 | ||
1247 | static int soc15_common_resume(void *handle) | |
1248 | { | |
1249 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1250 | ||
1251 | return soc15_common_hw_init(adev); | |
1252 | } | |
1253 | ||
1254 | static bool soc15_common_is_idle(void *handle) | |
1255 | { | |
1256 | return true; | |
1257 | } | |
1258 | ||
1259 | static int soc15_common_wait_for_idle(void *handle) | |
1260 | { | |
1261 | return 0; | |
1262 | } | |
1263 | ||
1264 | static int soc15_common_soft_reset(void *handle) | |
1265 | { | |
1266 | return 0; | |
1267 | } | |
1268 | ||
220ab9bd KW |
1269 | static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) |
1270 | { | |
1271 | uint32_t def, data; | |
1272 | ||
1273 | def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); | |
1274 | ||
1275 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_MGCG)) | |
1276 | data &= ~(0x01000000 | | |
1277 | 0x02000000 | | |
1278 | 0x04000000 | | |
1279 | 0x08000000 | | |
1280 | 0x10000000 | | |
1281 | 0x20000000 | | |
1282 | 0x40000000 | | |
1283 | 0x80000000); | |
1284 | else | |
1285 | data |= (0x01000000 | | |
1286 | 0x02000000 | | |
1287 | 0x04000000 | | |
1288 | 0x08000000 | | |
1289 | 0x10000000 | | |
1290 | 0x20000000 | | |
1291 | 0x40000000 | | |
1292 | 0x80000000); | |
1293 | ||
1294 | if (def != data) | |
1295 | WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0), data); | |
1296 | } | |
1297 | ||
1298 | static void soc15_update_drm_light_sleep(struct amdgpu_device *adev, bool enable) | |
1299 | { | |
1300 | uint32_t def, data; | |
1301 | ||
1302 | def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); | |
1303 | ||
1304 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS)) | |
1305 | data |= 1; | |
1306 | else | |
1307 | data &= ~1; | |
1308 | ||
1309 | if (def != data) | |
1310 | WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL), data); | |
1311 | } | |
1312 | ||
220ab9bd KW |
1313 | static int soc15_common_set_clockgating_state(void *handle, |
1314 | enum amd_clockgating_state state) | |
1315 | { | |
1316 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1317 | ||
6e9dc861 ML |
1318 | if (amdgpu_sriov_vf(adev)) |
1319 | return 0; | |
1320 | ||
1d789535 | 1321 | switch (adev->ip_versions[NBIO_HWIP][0]) { |
75a07bcd AD |
1322 | case IP_VERSION(6, 1, 0): |
1323 | case IP_VERSION(6, 2, 0): | |
1324 | case IP_VERSION(7, 4, 0): | |
bebc0762 | 1325 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, |
a9d4fe2f | 1326 | state == AMD_CG_STATE_GATE); |
bebc0762 | 1327 | adev->nbio.funcs->update_medium_grain_light_sleep(adev, |
a9d4fe2f | 1328 | state == AMD_CG_STATE_GATE); |
455d40c9 | 1329 | adev->hdp.funcs->update_clock_gating(adev, |
a9d4fe2f | 1330 | state == AMD_CG_STATE_GATE); |
220ab9bd | 1331 | soc15_update_drm_clock_gating(adev, |
a9d4fe2f | 1332 | state == AMD_CG_STATE_GATE); |
220ab9bd | 1333 | soc15_update_drm_light_sleep(adev, |
a9d4fe2f | 1334 | state == AMD_CG_STATE_GATE); |
0e961589 | 1335 | adev->smuio.funcs->update_rom_clock_gating(adev, |
a9d4fe2f | 1336 | state == AMD_CG_STATE_GATE); |
bdf84a80 | 1337 | adev->df.funcs->update_medium_grain_clock_gating(adev, |
a9d4fe2f | 1338 | state == AMD_CG_STATE_GATE); |
220ab9bd | 1339 | break; |
75a07bcd AD |
1340 | case IP_VERSION(7, 0, 0): |
1341 | case IP_VERSION(7, 0, 1): | |
1342 | case IP_VERSION(2, 5, 0): | |
bebc0762 | 1343 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, |
a9d4fe2f | 1344 | state == AMD_CG_STATE_GATE); |
bebc0762 | 1345 | adev->nbio.funcs->update_medium_grain_light_sleep(adev, |
a9d4fe2f | 1346 | state == AMD_CG_STATE_GATE); |
455d40c9 | 1347 | adev->hdp.funcs->update_clock_gating(adev, |
a9d4fe2f | 1348 | state == AMD_CG_STATE_GATE); |
9e5a9eb4 | 1349 | soc15_update_drm_clock_gating(adev, |
a9d4fe2f | 1350 | state == AMD_CG_STATE_GATE); |
9e5a9eb4 | 1351 | soc15_update_drm_light_sleep(adev, |
a9d4fe2f | 1352 | state == AMD_CG_STATE_GATE); |
9e5a9eb4 | 1353 | break; |
75a07bcd AD |
1354 | case IP_VERSION(7, 4, 1): |
1355 | case IP_VERSION(7, 4, 4): | |
455d40c9 | 1356 | adev->hdp.funcs->update_clock_gating(adev, |
a9d4fe2f | 1357 | state == AMD_CG_STATE_GATE); |
6acb87ac | 1358 | break; |
220ab9bd KW |
1359 | default: |
1360 | break; | |
1361 | } | |
1362 | return 0; | |
1363 | } | |
1364 | ||
25faeddc | 1365 | static void soc15_common_get_clockgating_state(void *handle, u64 *flags) |
f9abe35c HR |
1366 | { |
1367 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
1368 | int data; | |
1369 | ||
1370 | if (amdgpu_sriov_vf(adev)) | |
1371 | *flags = 0; | |
1372 | ||
bebc0762 | 1373 | adev->nbio.funcs->get_clockgating_state(adev, flags); |
f9abe35c | 1374 | |
455d40c9 | 1375 | adev->hdp.funcs->get_clock_gating_state(adev, flags); |
f9abe35c | 1376 | |
1d789535 | 1377 | if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2)) { |
f9abe35c | 1378 | |
48a6379a LL |
1379 | /* AMD_CG_SUPPORT_DRM_MGCG */ |
1380 | data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); | |
1381 | if (!(data & 0x01000000)) | |
1382 | *flags |= AMD_CG_SUPPORT_DRM_MGCG; | |
1383 | ||
1384 | /* AMD_CG_SUPPORT_DRM_LS */ | |
1385 | data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); | |
1386 | if (data & 0x1) | |
1387 | *flags |= AMD_CG_SUPPORT_DRM_LS; | |
1388 | } | |
f9abe35c HR |
1389 | |
1390 | /* AMD_CG_SUPPORT_ROM_MGCG */ | |
0e961589 | 1391 | adev->smuio.funcs->get_clock_gating_state(adev, flags); |
f9abe35c | 1392 | |
bdf84a80 | 1393 | adev->df.funcs->get_clockgating_state(adev, flags); |
f9abe35c HR |
1394 | } |
1395 | ||
220ab9bd KW |
1396 | static int soc15_common_set_powergating_state(void *handle, |
1397 | enum amd_powergating_state state) | |
1398 | { | |
1399 | /* todo */ | |
1400 | return 0; | |
1401 | } | |
1402 | ||
2485e275 | 1403 | static const struct amd_ip_funcs soc15_common_ip_funcs = { |
220ab9bd KW |
1404 | .name = "soc15_common", |
1405 | .early_init = soc15_common_early_init, | |
81758c55 | 1406 | .late_init = soc15_common_late_init, |
220ab9bd KW |
1407 | .sw_init = soc15_common_sw_init, |
1408 | .sw_fini = soc15_common_sw_fini, | |
1409 | .hw_init = soc15_common_hw_init, | |
1410 | .hw_fini = soc15_common_hw_fini, | |
1411 | .suspend = soc15_common_suspend, | |
1412 | .resume = soc15_common_resume, | |
1413 | .is_idle = soc15_common_is_idle, | |
1414 | .wait_for_idle = soc15_common_wait_for_idle, | |
1415 | .soft_reset = soc15_common_soft_reset, | |
1416 | .set_clockgating_state = soc15_common_set_clockgating_state, | |
1417 | .set_powergating_state = soc15_common_set_powergating_state, | |
f9abe35c | 1418 | .get_clockgating_state= soc15_common_get_clockgating_state, |
220ab9bd | 1419 | }; |