Commit | Line | Data |
---|---|---|
71199aa4 SY |
1 | /* |
2 | * Copyright 2021 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> | |
26 | #include <linux/pci.h> | |
27 | ||
28 | #include "amdgpu.h" | |
29 | #include "amdgpu_atombios.h" | |
30 | #include "amdgpu_ih.h" | |
31 | #include "amdgpu_uvd.h" | |
32 | #include "amdgpu_vce.h" | |
33 | #include "amdgpu_ucode.h" | |
34 | #include "amdgpu_psp.h" | |
35 | #include "amdgpu_smu.h" | |
36 | #include "atom.h" | |
37 | #include "amd_pcie.h" | |
38 | ||
39 | #include "gc/gc_11_0_0_offset.h" | |
40 | #include "gc/gc_11_0_0_sh_mask.h" | |
41 | #include "mp/mp_13_0_0_offset.h" | |
42 | ||
43 | #include "soc15.h" | |
44 | #include "soc15_common.h" | |
caa5eadc | 45 | #include "soc21.h" |
39dd895d | 46 | #include "mxgpu_nv.h" |
71199aa4 SY |
47 | |
48 | static const struct amd_ip_funcs soc21_common_ip_funcs; | |
49 | ||
9ac0edaa JZ |
50 | /* SOC21 */ |
51 | static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array[] = | |
52 | { | |
53 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, | |
54 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, | |
55 | }; | |
56 | ||
57 | static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode = | |
58 | { | |
59 | .codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_encode_array), | |
60 | .codec_array = vcn_4_0_0_video_codecs_encode_array, | |
61 | }; | |
62 | ||
63 | static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] = | |
64 | { | |
65009bf2 | 65 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, |
9ac0edaa JZ |
66 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, |
67 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, | |
68 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, | |
69 | {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, | |
70 | }; | |
71 | ||
72 | static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_decode = | |
73 | { | |
74 | .codec_count = ARRAY_SIZE(vcn_4_0_0_video_codecs_decode_array), | |
75 | .codec_array = vcn_4_0_0_video_codecs_decode_array, | |
76 | }; | |
77 | ||
78 | static int soc21_query_video_codecs(struct amdgpu_device *adev, bool encode, | |
79 | const struct amdgpu_video_codecs **codecs) | |
80 | { | |
81 | switch (adev->ip_versions[UVD_HWIP][0]) { | |
82 | ||
83 | case IP_VERSION(4, 0, 0): | |
1c0a9036 | 84 | case IP_VERSION(4, 0, 2): |
9ac0edaa JZ |
85 | if (encode) |
86 | *codecs = &vcn_4_0_0_video_codecs_encode; | |
87 | else | |
88 | *codecs = &vcn_4_0_0_video_codecs_decode; | |
89 | return 0; | |
90 | default: | |
91 | return -EINVAL; | |
92 | } | |
93 | } | |
71199aa4 SY |
94 | /* |
95 | * Indirect registers accessor | |
96 | */ | |
97 | static u32 soc21_pcie_rreg(struct amdgpu_device *adev, u32 reg) | |
98 | { | |
99 | unsigned long address, data; | |
100 | address = adev->nbio.funcs->get_pcie_index_offset(adev); | |
101 | data = adev->nbio.funcs->get_pcie_data_offset(adev); | |
102 | ||
103 | return amdgpu_device_indirect_rreg(adev, address, data, reg); | |
104 | } | |
105 | ||
106 | static void soc21_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
107 | { | |
108 | unsigned long address, data; | |
109 | ||
110 | address = adev->nbio.funcs->get_pcie_index_offset(adev); | |
111 | data = adev->nbio.funcs->get_pcie_data_offset(adev); | |
112 | ||
113 | amdgpu_device_indirect_wreg(adev, address, data, reg, v); | |
114 | } | |
115 | ||
116 | static u64 soc21_pcie_rreg64(struct amdgpu_device *adev, u32 reg) | |
117 | { | |
118 | unsigned long address, data; | |
119 | address = adev->nbio.funcs->get_pcie_index_offset(adev); | |
120 | data = adev->nbio.funcs->get_pcie_data_offset(adev); | |
121 | ||
122 | return amdgpu_device_indirect_rreg64(adev, address, data, reg); | |
123 | } | |
124 | ||
125 | static void soc21_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) | |
126 | { | |
127 | unsigned long address, data; | |
128 | ||
129 | address = adev->nbio.funcs->get_pcie_index_offset(adev); | |
130 | data = adev->nbio.funcs->get_pcie_data_offset(adev); | |
131 | ||
132 | amdgpu_device_indirect_wreg64(adev, address, data, reg, v); | |
133 | } | |
134 | ||
135 | static u32 soc21_didt_rreg(struct amdgpu_device *adev, u32 reg) | |
136 | { | |
137 | unsigned long flags, address, data; | |
138 | u32 r; | |
139 | ||
140 | address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX); | |
141 | data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA); | |
142 | ||
143 | spin_lock_irqsave(&adev->didt_idx_lock, flags); | |
144 | WREG32(address, (reg)); | |
145 | r = RREG32(data); | |
146 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); | |
147 | return r; | |
148 | } | |
149 | ||
150 | static void soc21_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
151 | { | |
152 | unsigned long flags, address, data; | |
153 | ||
154 | address = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_INDEX); | |
155 | data = SOC15_REG_OFFSET(GC, 0, regDIDT_IND_DATA); | |
156 | ||
157 | spin_lock_irqsave(&adev->didt_idx_lock, flags); | |
158 | WREG32(address, (reg)); | |
159 | WREG32(data, (v)); | |
160 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); | |
161 | } | |
162 | ||
163 | static u32 soc21_get_config_memsize(struct amdgpu_device *adev) | |
164 | { | |
165 | return adev->nbio.funcs->get_memsize(adev); | |
166 | } | |
167 | ||
168 | static u32 soc21_get_xclk(struct amdgpu_device *adev) | |
169 | { | |
170 | return adev->clock.spll.reference_freq; | |
171 | } | |
172 | ||
173 | ||
174 | void soc21_grbm_select(struct amdgpu_device *adev, | |
175 | u32 me, u32 pipe, u32 queue, u32 vmid) | |
176 | { | |
177 | u32 grbm_gfx_cntl = 0; | |
178 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe); | |
179 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me); | |
180 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid); | |
181 | grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue); | |
182 | ||
bbb860d4 | 183 | WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, grbm_gfx_cntl); |
71199aa4 SY |
184 | } |
185 | ||
186 | static void soc21_vga_set_state(struct amdgpu_device *adev, bool state) | |
187 | { | |
188 | /* todo */ | |
189 | } | |
190 | ||
191 | static bool soc21_read_disabled_bios(struct amdgpu_device *adev) | |
192 | { | |
193 | /* todo */ | |
194 | return false; | |
195 | } | |
196 | ||
197 | static struct soc15_allowed_register_entry soc21_allowed_read_registers[] = { | |
198 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS)}, | |
199 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS2)}, | |
200 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE0)}, | |
201 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE1)}, | |
202 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE2)}, | |
203 | { SOC15_REG_ENTRY(GC, 0, regGRBM_STATUS_SE3)}, | |
204 | { SOC15_REG_ENTRY(SDMA0, 0, regSDMA0_STATUS_REG)}, | |
205 | { SOC15_REG_ENTRY(SDMA1, 0, regSDMA1_STATUS_REG)}, | |
206 | { SOC15_REG_ENTRY(GC, 0, regCP_STAT)}, | |
207 | { SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT1)}, | |
208 | { SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT2)}, | |
209 | { SOC15_REG_ENTRY(GC, 0, regCP_STALLED_STAT3)}, | |
210 | { SOC15_REG_ENTRY(GC, 0, regCP_CPF_BUSY_STAT)}, | |
211 | { SOC15_REG_ENTRY(GC, 0, regCP_CPF_STALLED_STAT1)}, | |
212 | { SOC15_REG_ENTRY(GC, 0, regCP_CPF_STATUS)}, | |
213 | { SOC15_REG_ENTRY(GC, 0, regCP_CPC_BUSY_STAT)}, | |
214 | { SOC15_REG_ENTRY(GC, 0, regCP_CPC_STALLED_STAT1)}, | |
215 | { SOC15_REG_ENTRY(GC, 0, regCP_CPC_STATUS)}, | |
216 | { SOC15_REG_ENTRY(GC, 0, regGB_ADDR_CONFIG)}, | |
217 | }; | |
218 | ||
219 | static uint32_t soc21_read_indexed_register(struct amdgpu_device *adev, u32 se_num, | |
220 | u32 sh_num, u32 reg_offset) | |
221 | { | |
222 | uint32_t val; | |
223 | ||
224 | mutex_lock(&adev->grbm_idx_mutex); | |
225 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | |
226 | amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); | |
227 | ||
228 | val = RREG32(reg_offset); | |
229 | ||
230 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | |
231 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | |
232 | mutex_unlock(&adev->grbm_idx_mutex); | |
233 | return val; | |
234 | } | |
235 | ||
236 | static uint32_t soc21_get_register_value(struct amdgpu_device *adev, | |
237 | bool indexed, u32 se_num, | |
238 | u32 sh_num, u32 reg_offset) | |
239 | { | |
240 | if (indexed) { | |
241 | return soc21_read_indexed_register(adev, se_num, sh_num, reg_offset); | |
242 | } else { | |
243 | if (reg_offset == SOC15_REG_OFFSET(GC, 0, regGB_ADDR_CONFIG) && adev->gfx.config.gb_addr_config) | |
244 | return adev->gfx.config.gb_addr_config; | |
245 | return RREG32(reg_offset); | |
246 | } | |
247 | } | |
248 | ||
249 | static int soc21_read_register(struct amdgpu_device *adev, u32 se_num, | |
250 | u32 sh_num, u32 reg_offset, u32 *value) | |
251 | { | |
252 | uint32_t i; | |
253 | struct soc15_allowed_register_entry *en; | |
254 | ||
255 | *value = 0; | |
256 | for (i = 0; i < ARRAY_SIZE(soc21_allowed_read_registers); i++) { | |
257 | en = &soc21_allowed_read_registers[i]; | |
bf1781e1 AD |
258 | if (adev->reg_offset[en->hwip][en->inst] && |
259 | reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] | |
260 | + en->reg_offset)) | |
71199aa4 SY |
261 | continue; |
262 | ||
263 | *value = soc21_get_register_value(adev, | |
264 | soc21_allowed_read_registers[i].grbm_indexed, | |
265 | se_num, sh_num, reg_offset); | |
266 | return 0; | |
267 | } | |
268 | return -EINVAL; | |
269 | } | |
270 | ||
271 | #if 0 | |
272 | static int soc21_asic_mode1_reset(struct amdgpu_device *adev) | |
273 | { | |
274 | u32 i; | |
275 | int ret = 0; | |
276 | ||
277 | amdgpu_atombios_scratch_regs_engine_hung(adev, true); | |
278 | ||
279 | /* disable BM */ | |
280 | pci_clear_master(adev->pdev); | |
281 | ||
282 | amdgpu_device_cache_pci_state(adev->pdev); | |
283 | ||
284 | if (amdgpu_dpm_is_mode1_reset_supported(adev)) { | |
285 | dev_info(adev->dev, "GPU smu mode1 reset\n"); | |
286 | ret = amdgpu_dpm_mode1_reset(adev); | |
287 | } else { | |
288 | dev_info(adev->dev, "GPU psp mode1 reset\n"); | |
289 | ret = psp_gpu_reset(adev); | |
290 | } | |
291 | ||
292 | if (ret) | |
293 | dev_err(adev->dev, "GPU mode1 reset failed\n"); | |
294 | amdgpu_device_load_pci_state(adev->pdev); | |
295 | ||
296 | /* wait for asic to come out of reset */ | |
297 | for (i = 0; i < adev->usec_timeout; i++) { | |
298 | u32 memsize = adev->nbio.funcs->get_memsize(adev); | |
299 | ||
300 | if (memsize != 0xffffffff) | |
301 | break; | |
302 | udelay(1); | |
303 | } | |
304 | ||
305 | amdgpu_atombios_scratch_regs_engine_hung(adev, false); | |
306 | ||
307 | return ret; | |
308 | } | |
309 | #endif | |
310 | ||
311 | static enum amd_reset_method | |
312 | soc21_asic_reset_method(struct amdgpu_device *adev) | |
313 | { | |
314 | if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || | |
ea64228d | 315 | amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || |
71199aa4 SY |
316 | amdgpu_reset_method == AMD_RESET_METHOD_BACO) |
317 | return amdgpu_reset_method; | |
318 | ||
319 | if (amdgpu_reset_method != -1) | |
320 | dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", | |
321 | amdgpu_reset_method); | |
322 | ||
323 | switch (adev->ip_versions[MP1_HWIP][0]) { | |
324 | case IP_VERSION(13, 0, 0): | |
a53bc321 | 325 | case IP_VERSION(13, 0, 7): |
60cfad32 | 326 | case IP_VERSION(13, 0, 10): |
71199aa4 | 327 | return AMD_RESET_METHOD_MODE1; |
ea64228d | 328 | case IP_VERSION(13, 0, 4): |
18ad1885 | 329 | case IP_VERSION(13, 0, 11): |
ea64228d | 330 | return AMD_RESET_METHOD_MODE2; |
71199aa4 SY |
331 | default: |
332 | if (amdgpu_dpm_is_baco_supported(adev)) | |
333 | return AMD_RESET_METHOD_BACO; | |
334 | else | |
335 | return AMD_RESET_METHOD_MODE1; | |
336 | } | |
337 | } | |
338 | ||
339 | static int soc21_asic_reset(struct amdgpu_device *adev) | |
340 | { | |
341 | int ret = 0; | |
342 | ||
343 | switch (soc21_asic_reset_method(adev)) { | |
344 | case AMD_RESET_METHOD_PCI: | |
345 | dev_info(adev->dev, "PCI reset\n"); | |
346 | ret = amdgpu_device_pci_reset(adev); | |
347 | break; | |
348 | case AMD_RESET_METHOD_BACO: | |
349 | dev_info(adev->dev, "BACO reset\n"); | |
350 | ret = amdgpu_dpm_baco_reset(adev); | |
351 | break; | |
ea64228d AD |
352 | case AMD_RESET_METHOD_MODE2: |
353 | dev_info(adev->dev, "MODE2 reset\n"); | |
354 | ret = amdgpu_dpm_mode2_reset(adev); | |
355 | break; | |
71199aa4 SY |
356 | default: |
357 | dev_info(adev->dev, "MODE1 reset\n"); | |
358 | ret = amdgpu_device_mode1_reset(adev); | |
359 | break; | |
360 | } | |
361 | ||
362 | return ret; | |
363 | } | |
364 | ||
365 | static int soc21_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) | |
366 | { | |
367 | /* todo */ | |
368 | return 0; | |
369 | } | |
370 | ||
371 | static int soc21_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) | |
372 | { | |
373 | /* todo */ | |
374 | return 0; | |
375 | } | |
376 | ||
377 | static void soc21_pcie_gen3_enable(struct amdgpu_device *adev) | |
378 | { | |
379 | if (pci_is_root_bus(adev->pdev->bus)) | |
380 | return; | |
381 | ||
382 | if (amdgpu_pcie_gen2 == 0) | |
383 | return; | |
384 | ||
385 | if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | | |
386 | CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) | |
387 | return; | |
388 | ||
389 | /* todo */ | |
390 | } | |
391 | ||
392 | static void soc21_program_aspm(struct amdgpu_device *adev) | |
393 | { | |
62f8f5c3 | 394 | if (!amdgpu_device_should_use_aspm(adev)) |
71199aa4 SY |
395 | return; |
396 | ||
62f8f5c3 EQ |
397 | if (!(adev->flags & AMD_IS_APU) && |
398 | (adev->nbio.funcs->program_aspm)) | |
399 | adev->nbio.funcs->program_aspm(adev); | |
71199aa4 SY |
400 | } |
401 | ||
402 | static void soc21_enable_doorbell_aperture(struct amdgpu_device *adev, | |
403 | bool enable) | |
404 | { | |
405 | adev->nbio.funcs->enable_doorbell_aperture(adev, enable); | |
406 | adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); | |
407 | } | |
408 | ||
409 | const struct amdgpu_ip_block_version soc21_common_ip_block = | |
410 | { | |
411 | .type = AMD_IP_BLOCK_TYPE_COMMON, | |
412 | .major = 1, | |
413 | .minor = 0, | |
414 | .rev = 0, | |
415 | .funcs = &soc21_common_ip_funcs, | |
416 | }; | |
417 | ||
418 | static uint32_t soc21_get_rev_id(struct amdgpu_device *adev) | |
419 | { | |
420 | return adev->nbio.funcs->get_rev_id(adev); | |
421 | } | |
422 | ||
423 | static bool soc21_need_full_reset(struct amdgpu_device *adev) | |
424 | { | |
c0ff84cb LG |
425 | switch (adev->ip_versions[GC_HWIP][0]) { |
426 | case IP_VERSION(11, 0, 0): | |
34dfca89 | 427 | return amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC); |
c0ff84cb | 428 | case IP_VERSION(11, 0, 2): |
2e26bf1e | 429 | case IP_VERSION(11, 0, 3): |
c0ff84cb LG |
430 | return false; |
431 | default: | |
432 | return true; | |
433 | } | |
71199aa4 SY |
434 | } |
435 | ||
436 | static bool soc21_need_reset_on_init(struct amdgpu_device *adev) | |
437 | { | |
438 | u32 sol_reg; | |
439 | ||
440 | if (adev->flags & AMD_IS_APU) | |
441 | return false; | |
442 | ||
443 | /* Check sOS sign of life register to confirm sys driver and sOS | |
444 | * are already been loaded. | |
445 | */ | |
446 | sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); | |
447 | if (sol_reg) | |
448 | return true; | |
449 | ||
450 | return false; | |
451 | } | |
452 | ||
453 | static uint64_t soc21_get_pcie_replay_count(struct amdgpu_device *adev) | |
454 | { | |
455 | ||
456 | /* TODO | |
457 | * dummy implement for pcie_replay_count sysfs interface | |
458 | * */ | |
459 | ||
460 | return 0; | |
461 | } | |
462 | ||
463 | static void soc21_init_doorbell_index(struct amdgpu_device *adev) | |
464 | { | |
465 | adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ; | |
466 | adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0; | |
467 | adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1; | |
468 | adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2; | |
469 | adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3; | |
470 | adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4; | |
471 | adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5; | |
472 | adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6; | |
473 | adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7; | |
474 | adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START; | |
475 | adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END; | |
476 | adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0; | |
477 | adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1; | |
fd0ed91a JX |
478 | adev->doorbell_index.gfx_userqueue_start = |
479 | AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START; | |
480 | adev->doorbell_index.gfx_userqueue_end = | |
481 | AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END; | |
b608e785 JX |
482 | adev->doorbell_index.mes_ring0 = AMDGPU_NAVI10_DOORBELL_MES_RING0; |
483 | adev->doorbell_index.mes_ring1 = AMDGPU_NAVI10_DOORBELL_MES_RING1; | |
71199aa4 SY |
484 | adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0; |
485 | adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1; | |
486 | adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH; | |
487 | adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1; | |
488 | adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3; | |
489 | adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5; | |
490 | adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7; | |
491 | adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP; | |
492 | adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP; | |
493 | ||
494 | adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1; | |
495 | adev->doorbell_index.sdma_doorbell_range = 20; | |
496 | } | |
497 | ||
498 | static void soc21_pre_asic_init(struct amdgpu_device *adev) | |
499 | { | |
500 | } | |
501 | ||
72010239 LG |
502 | static int soc21_update_umd_stable_pstate(struct amdgpu_device *adev, |
503 | bool enter) | |
504 | { | |
505 | if (enter) | |
506 | amdgpu_gfx_rlc_enter_safe_mode(adev); | |
507 | else | |
508 | amdgpu_gfx_rlc_exit_safe_mode(adev); | |
509 | ||
510 | if (adev->gfx.funcs->update_perfmon_mgcg) | |
511 | adev->gfx.funcs->update_perfmon_mgcg(adev, !enter); | |
512 | ||
513 | return 0; | |
514 | } | |
515 | ||
71199aa4 SY |
516 | static const struct amdgpu_asic_funcs soc21_asic_funcs = |
517 | { | |
518 | .read_disabled_bios = &soc21_read_disabled_bios, | |
519 | .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, | |
520 | .read_register = &soc21_read_register, | |
521 | .reset = &soc21_asic_reset, | |
522 | .reset_method = &soc21_asic_reset_method, | |
523 | .set_vga_state = &soc21_vga_set_state, | |
524 | .get_xclk = &soc21_get_xclk, | |
525 | .set_uvd_clocks = &soc21_set_uvd_clocks, | |
526 | .set_vce_clocks = &soc21_set_vce_clocks, | |
527 | .get_config_memsize = &soc21_get_config_memsize, | |
528 | .init_doorbell_index = &soc21_init_doorbell_index, | |
529 | .need_full_reset = &soc21_need_full_reset, | |
530 | .need_reset_on_init = &soc21_need_reset_on_init, | |
531 | .get_pcie_replay_count = &soc21_get_pcie_replay_count, | |
532 | .supports_baco = &amdgpu_dpm_is_baco_supported, | |
533 | .pre_asic_init = &soc21_pre_asic_init, | |
9ac0edaa | 534 | .query_video_codecs = &soc21_query_video_codecs, |
72010239 | 535 | .update_umd_stable_pstate = &soc21_update_umd_stable_pstate, |
71199aa4 SY |
536 | }; |
537 | ||
538 | static int soc21_common_early_init(void *handle) | |
539 | { | |
540 | #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) | |
541 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
542 | ||
543 | adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; | |
544 | adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; | |
545 | adev->smc_rreg = NULL; | |
546 | adev->smc_wreg = NULL; | |
547 | adev->pcie_rreg = &soc21_pcie_rreg; | |
548 | adev->pcie_wreg = &soc21_pcie_wreg; | |
549 | adev->pcie_rreg64 = &soc21_pcie_rreg64; | |
550 | adev->pcie_wreg64 = &soc21_pcie_wreg64; | |
bafd6cbe XD |
551 | adev->pciep_rreg = amdgpu_device_pcie_port_rreg; |
552 | adev->pciep_wreg = amdgpu_device_pcie_port_wreg; | |
71199aa4 SY |
553 | |
554 | /* TODO: will add them during VCN v2 implementation */ | |
555 | adev->uvd_ctx_rreg = NULL; | |
556 | adev->uvd_ctx_wreg = NULL; | |
557 | ||
558 | adev->didt_rreg = &soc21_didt_rreg; | |
559 | adev->didt_wreg = &soc21_didt_wreg; | |
560 | ||
561 | adev->asic_funcs = &soc21_asic_funcs; | |
562 | ||
563 | adev->rev_id = soc21_get_rev_id(adev); | |
564 | adev->external_rev_id = 0xff; | |
565 | switch (adev->ip_versions[GC_HWIP][0]) { | |
566 | case IP_VERSION(11, 0, 0): | |
390db4b8 | 567 | adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG | |
b21348a2 | 568 | AMD_CG_SUPPORT_GFX_CGLS | |
1b586595 | 569 | #if 0 |
915b5ce7 EQ |
570 | AMD_CG_SUPPORT_GFX_3D_CGCG | |
571 | AMD_CG_SUPPORT_GFX_3D_CGLS | | |
1b586595 | 572 | #endif |
915b5ce7 | 573 | AMD_CG_SUPPORT_GFX_MGCG | |
8b719b96 | 574 | AMD_CG_SUPPORT_REPEATER_FGCG | |
915b5ce7 EQ |
575 | AMD_CG_SUPPORT_GFX_FGCG | |
576 | AMD_CG_SUPPORT_GFX_PERF_CLK | | |
7c507d35 | 577 | AMD_CG_SUPPORT_VCN_MGCG | |
c649ed05 EQ |
578 | AMD_CG_SUPPORT_JPEG_MGCG | |
579 | AMD_CG_SUPPORT_ATHUB_MGCG | | |
7ccf6eb0 EQ |
580 | AMD_CG_SUPPORT_ATHUB_LS | |
581 | AMD_CG_SUPPORT_MC_MGCG | | |
20139069 | 582 | AMD_CG_SUPPORT_MC_LS | |
d386f645 EQ |
583 | AMD_CG_SUPPORT_IH_CG | |
584 | AMD_CG_SUPPORT_HDP_SD; | |
8b719b96 | 585 | adev->pg_flags = AMD_PG_SUPPORT_VCN | |
04270390 | 586 | AMD_PG_SUPPORT_VCN_DPG | |
7c507d35 | 587 | AMD_PG_SUPPORT_JPEG | |
8b719b96 | 588 | AMD_PG_SUPPORT_ATHUB | |
a6dec868 | 589 | AMD_PG_SUPPORT_MMHUB; |
71199aa4 SY |
590 | adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update |
591 | break; | |
92fd2153 | 592 | case IP_VERSION(11, 0, 2): |
71dae221 | 593 | adev->cg_flags = |
9503a944 LG |
594 | AMD_CG_SUPPORT_GFX_CGCG | |
595 | AMD_CG_SUPPORT_GFX_CGLS | | |
49401d3a | 596 | AMD_CG_SUPPORT_REPEATER_FGCG | |
7ece9314 | 597 | AMD_CG_SUPPORT_VCN_MGCG | |
49401d3a KF |
598 | AMD_CG_SUPPORT_JPEG_MGCG | |
599 | AMD_CG_SUPPORT_ATHUB_MGCG | | |
b4ddb27d KF |
600 | AMD_CG_SUPPORT_ATHUB_LS | |
601 | AMD_CG_SUPPORT_IH_CG | | |
602 | AMD_CG_SUPPORT_HDP_SD; | |
ebac66a3 | 603 | adev->pg_flags = |
143a34a0 | 604 | AMD_PG_SUPPORT_VCN | |
ec9db74e | 605 | AMD_PG_SUPPORT_VCN_DPG | |
27e3911c KF |
606 | AMD_PG_SUPPORT_JPEG | |
607 | AMD_PG_SUPPORT_ATHUB | | |
608 | AMD_PG_SUPPORT_MMHUB; | |
92fd2153 FC |
609 | adev->external_rev_id = adev->rev_id + 0x10; |
610 | break; | |
11417a92 | 611 | case IP_VERSION(11, 0, 1): |
47231d5e | 612 | adev->cg_flags = |
8df436d5 TH |
613 | AMD_CG_SUPPORT_GFX_CGCG | |
614 | AMD_CG_SUPPORT_GFX_CGLS | | |
615 | AMD_CG_SUPPORT_GFX_MGCG | | |
616 | AMD_CG_SUPPORT_GFX_FGCG | | |
617 | AMD_CG_SUPPORT_REPEATER_FGCG | | |
618 | AMD_CG_SUPPORT_GFX_PERF_CLK | | |
adcd15dc TH |
619 | AMD_CG_SUPPORT_MC_MGCG | |
620 | AMD_CG_SUPPORT_MC_LS | | |
7e4a77de TH |
621 | AMD_CG_SUPPORT_HDP_MGCG | |
622 | AMD_CG_SUPPORT_HDP_LS | | |
8e78c7c4 TH |
623 | AMD_CG_SUPPORT_ATHUB_MGCG | |
624 | AMD_CG_SUPPORT_ATHUB_LS | | |
fa0bbd3b | 625 | AMD_CG_SUPPORT_IH_CG | |
9407feac TH |
626 | AMD_CG_SUPPORT_BIF_MGCG | |
627 | AMD_CG_SUPPORT_BIF_LS | | |
47231d5e SJ |
628 | AMD_CG_SUPPORT_VCN_MGCG | |
629 | AMD_CG_SUPPORT_JPEG_MGCG; | |
630 | adev->pg_flags = | |
dc0a096b | 631 | AMD_PG_SUPPORT_GFX_PG | |
e626d9b9 | 632 | AMD_PG_SUPPORT_VCN | |
0b37f474 | 633 | AMD_PG_SUPPORT_VCN_DPG | |
47231d5e | 634 | AMD_PG_SUPPORT_JPEG; |
11417a92 HR |
635 | adev->external_rev_id = adev->rev_id + 0x1; |
636 | break; | |
6b46251c | 637 | case IP_VERSION(11, 0, 3): |
0f05a2e5 | 638 | adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG | |
4ecdb30e KF |
639 | AMD_CG_SUPPORT_JPEG_MGCG | |
640 | AMD_CG_SUPPORT_GFX_CGCG | | |
641 | AMD_CG_SUPPORT_GFX_CGLS | | |
642 | AMD_CG_SUPPORT_REPEATER_FGCG | | |
bb25849c | 643 | AMD_CG_SUPPORT_GFX_MGCG | |
5630a350 KF |
644 | AMD_CG_SUPPORT_HDP_SD | |
645 | AMD_CG_SUPPORT_ATHUB_MGCG | | |
646 | AMD_CG_SUPPORT_ATHUB_LS; | |
0f05a2e5 SJ |
647 | adev->pg_flags = AMD_PG_SUPPORT_VCN | |
648 | AMD_PG_SUPPORT_VCN_DPG | | |
649 | AMD_PG_SUPPORT_JPEG; | |
6b46251c HZ |
650 | adev->external_rev_id = adev->rev_id + 0x20; |
651 | break; | |
311d5236 | 652 | case IP_VERSION(11, 0, 4): |
f2b91e5a TH |
653 | adev->cg_flags = |
654 | AMD_CG_SUPPORT_GFX_CGCG | | |
655 | AMD_CG_SUPPORT_GFX_CGLS | | |
656 | AMD_CG_SUPPORT_GFX_MGCG | | |
657 | AMD_CG_SUPPORT_GFX_FGCG | | |
658 | AMD_CG_SUPPORT_REPEATER_FGCG | | |
659 | AMD_CG_SUPPORT_GFX_PERF_CLK | | |
660 | AMD_CG_SUPPORT_MC_MGCG | | |
661 | AMD_CG_SUPPORT_MC_LS | | |
662 | AMD_CG_SUPPORT_HDP_MGCG | | |
663 | AMD_CG_SUPPORT_HDP_LS | | |
664 | AMD_CG_SUPPORT_ATHUB_MGCG | | |
665 | AMD_CG_SUPPORT_ATHUB_LS | | |
666 | AMD_CG_SUPPORT_IH_CG | | |
667 | AMD_CG_SUPPORT_BIF_MGCG | | |
668 | AMD_CG_SUPPORT_BIF_LS | | |
669 | AMD_CG_SUPPORT_VCN_MGCG | | |
2a0fe2ca SJ |
670 | AMD_CG_SUPPORT_JPEG_MGCG; |
671 | adev->pg_flags = AMD_PG_SUPPORT_VCN | | |
e1d900df | 672 | AMD_PG_SUPPORT_VCN_DPG | |
2a0fe2ca SJ |
673 | AMD_PG_SUPPORT_GFX_PG | |
674 | AMD_PG_SUPPORT_JPEG; | |
311d5236 YZ |
675 | adev->external_rev_id = adev->rev_id + 0x1; |
676 | break; | |
677 | ||
71199aa4 SY |
678 | default: |
679 | /* FIXME: not supported yet */ | |
680 | return -EINVAL; | |
681 | } | |
682 | ||
39dd895d | 683 | if (amdgpu_sriov_vf(adev)) { |
0cfce240 | 684 | amdgpu_virt_init_setting(adev); |
39dd895d YW |
685 | xgpu_nv_mailbox_set_irq_funcs(adev); |
686 | } | |
0cfce240 | 687 | |
71199aa4 SY |
688 | return 0; |
689 | } | |
690 | ||
691 | static int soc21_common_late_init(void *handle) | |
692 | { | |
39dd895d YW |
693 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
694 | ||
695 | if (amdgpu_sriov_vf(adev)) | |
696 | xgpu_nv_mailbox_get_irq(adev); | |
697 | ||
71199aa4 SY |
698 | return 0; |
699 | } | |
700 | ||
701 | static int soc21_common_sw_init(void *handle) | |
702 | { | |
39dd895d YW |
703 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
704 | ||
705 | if (amdgpu_sriov_vf(adev)) | |
706 | xgpu_nv_mailbox_add_irq_id(adev); | |
707 | ||
71199aa4 SY |
708 | return 0; |
709 | } | |
710 | ||
711 | static int soc21_common_sw_fini(void *handle) | |
712 | { | |
713 | return 0; | |
714 | } | |
715 | ||
716 | static int soc21_common_hw_init(void *handle) | |
717 | { | |
718 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
719 | ||
720 | /* enable pcie gen2/3 link */ | |
721 | soc21_pcie_gen3_enable(adev); | |
722 | /* enable aspm */ | |
723 | soc21_program_aspm(adev); | |
724 | /* setup nbio registers */ | |
725 | adev->nbio.funcs->init_registers(adev); | |
726 | /* remap HDP registers to a hole in mmio space, | |
727 | * for the purpose of expose those registers | |
728 | * to process space | |
729 | */ | |
730 | if (adev->nbio.funcs->remap_hdp_registers) | |
731 | adev->nbio.funcs->remap_hdp_registers(adev); | |
732 | /* enable the doorbell aperture */ | |
733 | soc21_enable_doorbell_aperture(adev, true); | |
734 | ||
735 | return 0; | |
736 | } | |
737 | ||
738 | static int soc21_common_hw_fini(void *handle) | |
739 | { | |
740 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
741 | ||
742 | /* disable the doorbell aperture */ | |
743 | soc21_enable_doorbell_aperture(adev, false); | |
744 | ||
39dd895d YW |
745 | if (amdgpu_sriov_vf(adev)) |
746 | xgpu_nv_mailbox_put_irq(adev); | |
747 | ||
71199aa4 SY |
748 | return 0; |
749 | } | |
750 | ||
751 | static int soc21_common_suspend(void *handle) | |
752 | { | |
753 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
754 | ||
755 | return soc21_common_hw_fini(adev); | |
756 | } | |
757 | ||
758 | static int soc21_common_resume(void *handle) | |
759 | { | |
760 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
761 | ||
762 | return soc21_common_hw_init(adev); | |
763 | } | |
764 | ||
765 | static bool soc21_common_is_idle(void *handle) | |
766 | { | |
767 | return true; | |
768 | } | |
769 | ||
770 | static int soc21_common_wait_for_idle(void *handle) | |
771 | { | |
772 | return 0; | |
773 | } | |
774 | ||
775 | static int soc21_common_soft_reset(void *handle) | |
776 | { | |
777 | return 0; | |
778 | } | |
779 | ||
780 | static int soc21_common_set_clockgating_state(void *handle, | |
781 | enum amd_clockgating_state state) | |
782 | { | |
783 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
784 | ||
785 | switch (adev->ip_versions[NBIO_HWIP][0]) { | |
786 | case IP_VERSION(4, 3, 0): | |
b4ddb27d | 787 | case IP_VERSION(4, 3, 1): |
9407feac | 788 | case IP_VERSION(7, 7, 0): |
71199aa4 SY |
789 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, |
790 | state == AMD_CG_STATE_GATE); | |
791 | adev->nbio.funcs->update_medium_grain_light_sleep(adev, | |
792 | state == AMD_CG_STATE_GATE); | |
793 | adev->hdp.funcs->update_clock_gating(adev, | |
794 | state == AMD_CG_STATE_GATE); | |
795 | break; | |
796 | default: | |
797 | break; | |
798 | } | |
799 | return 0; | |
800 | } | |
801 | ||
802 | static int soc21_common_set_powergating_state(void *handle, | |
803 | enum amd_powergating_state state) | |
804 | { | |
41967850 LG |
805 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
806 | ||
807 | switch (adev->ip_versions[LSDMA_HWIP][0]) { | |
808 | case IP_VERSION(6, 0, 0): | |
362c3c70 | 809 | case IP_VERSION(6, 0, 2): |
41967850 LG |
810 | adev->lsdma.funcs->update_memory_power_gating(adev, |
811 | state == AMD_PG_STATE_GATE); | |
812 | break; | |
813 | default: | |
814 | break; | |
815 | } | |
816 | ||
71199aa4 SY |
817 | return 0; |
818 | } | |
819 | ||
820 | static void soc21_common_get_clockgating_state(void *handle, u64 *flags) | |
821 | { | |
822 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
823 | ||
824 | adev->nbio.funcs->get_clockgating_state(adev, flags); | |
825 | ||
826 | adev->hdp.funcs->get_clock_gating_state(adev, flags); | |
827 | ||
828 | return; | |
829 | } | |
830 | ||
831 | static const struct amd_ip_funcs soc21_common_ip_funcs = { | |
832 | .name = "soc21_common", | |
833 | .early_init = soc21_common_early_init, | |
834 | .late_init = soc21_common_late_init, | |
835 | .sw_init = soc21_common_sw_init, | |
836 | .sw_fini = soc21_common_sw_fini, | |
837 | .hw_init = soc21_common_hw_init, | |
838 | .hw_fini = soc21_common_hw_fini, | |
839 | .suspend = soc21_common_suspend, | |
840 | .resume = soc21_common_resume, | |
841 | .is_idle = soc21_common_is_idle, | |
842 | .wait_for_idle = soc21_common_wait_for_idle, | |
843 | .soft_reset = soc21_common_soft_reset, | |
844 | .set_clockgating_state = soc21_common_set_clockgating_state, | |
845 | .set_powergating_state = soc21_common_set_powergating_state, | |
846 | .get_clockgating_state = soc21_common_get_clockgating_state, | |
847 | }; |