]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
Merge tag 'for-linus-6.1-1' of https://github.com/cminyard/linux-ipmi
[linux.git] / drivers / gpu / drm / amd / amdgpu / vcn_v4_0.c
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
24 #include <linux/firmware.h>
25 #include "amdgpu.h"
26 #include "amdgpu_vcn.h"
27 #include "amdgpu_pm.h"
28 #include "amdgpu_cs.h"
29 #include "soc15.h"
30 #include "soc15d.h"
31 #include "soc15_hw_ip.h"
32 #include "vcn_v2_0.h"
33 #include "mmsch_v4_0.h"
34
35 #include "vcn/vcn_4_0_0_offset.h"
36 #include "vcn/vcn_4_0_0_sh_mask.h"
37 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
38
39 #include <drm/drm_drv.h>
40
41 #define mmUVD_DPG_LMA_CTL                                                       regUVD_DPG_LMA_CTL
42 #define mmUVD_DPG_LMA_CTL_BASE_IDX                                              regUVD_DPG_LMA_CTL_BASE_IDX
43 #define mmUVD_DPG_LMA_DATA                                                      regUVD_DPG_LMA_DATA
44 #define mmUVD_DPG_LMA_DATA_BASE_IDX                                             regUVD_DPG_LMA_DATA_BASE_IDX
45
46 #define VCN_VID_SOC_ADDRESS_2_0                                                 0x1fb00
47 #define VCN1_VID_SOC_ADDRESS_3_0                                                0x48300
48
49 #define VCN_HARVEST_MMSCH                                                               0
50
51 #define RDECODE_MSG_CREATE                                                      0x00000000
52 #define RDECODE_MESSAGE_CREATE                                                  0x00000001
53
54 static int amdgpu_ih_clientid_vcns[] = {
55         SOC15_IH_CLIENTID_VCN,
56         SOC15_IH_CLIENTID_VCN1
57 };
58
59 static int vcn_v4_0_start_sriov(struct amdgpu_device *adev);
60 static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev);
61 static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev);
62 static int vcn_v4_0_set_powergating_state(void *handle,
63         enum amd_powergating_state state);
64 static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev,
65         int inst_idx, struct dpg_pause_state *new_state);
66 static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring);
67
68 /**
69  * vcn_v4_0_early_init - set function pointers
70  *
71  * @handle: amdgpu_device pointer
72  *
73  * Set ring and irq function pointers
74  */
75 static int vcn_v4_0_early_init(void *handle)
76 {
77         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78
79         if (amdgpu_sriov_vf(adev))
80                 adev->vcn.harvest_config = VCN_HARVEST_MMSCH;
81
82         /* re-use enc ring as unified ring */
83         adev->vcn.num_enc_rings = 1;
84
85         vcn_v4_0_set_unified_ring_funcs(adev);
86         vcn_v4_0_set_irq_funcs(adev);
87
88         return 0;
89 }
90
91 /**
92  * vcn_v4_0_sw_init - sw init for VCN block
93  *
94  * @handle: amdgpu_device pointer
95  *
96  * Load firmware and sw initialization
97  */
98 static int vcn_v4_0_sw_init(void *handle)
99 {
100         struct amdgpu_ring *ring;
101         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
102         int i, r;
103         int vcn_doorbell_index = 0;
104
105         r = amdgpu_vcn_sw_init(adev);
106         if (r)
107                 return r;
108
109         amdgpu_vcn_setup_ucode(adev);
110
111         r = amdgpu_vcn_resume(adev);
112         if (r)
113                 return r;
114
115         if (amdgpu_sriov_vf(adev)) {
116                 vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
117                 /* get DWORD offset */
118                 vcn_doorbell_index = vcn_doorbell_index << 1;
119         }
120
121         for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
122                 volatile struct amdgpu_vcn4_fw_shared *fw_shared;
123
124                 if (adev->vcn.harvest_config & (1 << i))
125                         continue;
126
127                 atomic_set(&adev->vcn.inst[i].sched_score, 0);
128
129                 /* VCN UNIFIED TRAP */
130                 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i],
131                                 VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq);
132                 if (r)
133                         return r;
134
135                 ring = &adev->vcn.inst[i].ring_enc[0];
136                 ring->use_doorbell = true;
137                 if (amdgpu_sriov_vf(adev))
138                         ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1;
139                 else
140                         ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
141
142                 sprintf(ring->name, "vcn_unified_%d", i);
143
144                 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
145                                                 AMDGPU_RING_PRIO_0, &adev->vcn.inst[i].sched_score);
146                 if (r)
147                         return r;
148
149                 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
150                 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
151                 fw_shared->sq.is_enabled = 1;
152
153                 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
154                 fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
155                         AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
156
157                 if (amdgpu_sriov_vf(adev))
158                         fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
159
160                 if (amdgpu_vcnfw_log)
161                         amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
162         }
163
164         if (amdgpu_sriov_vf(adev)) {
165                 r = amdgpu_virt_alloc_mm_table(adev);
166                 if (r)
167                         return r;
168         }
169
170         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
171                 adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
172
173         return 0;
174 }
175
176 /**
177  * vcn_v4_0_sw_fini - sw fini for VCN block
178  *
179  * @handle: amdgpu_device pointer
180  *
181  * VCN suspend and free up sw allocation
182  */
183 static int vcn_v4_0_sw_fini(void *handle)
184 {
185         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
186         int i, r, idx;
187
188         if (drm_dev_enter(adev_to_drm(adev), &idx)) {
189                 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
190                         volatile struct amdgpu_vcn4_fw_shared *fw_shared;
191
192                         if (adev->vcn.harvest_config & (1 << i))
193                                 continue;
194
195                         fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
196                         fw_shared->present_flag_0 = 0;
197                         fw_shared->sq.is_enabled = 0;
198                 }
199
200                 drm_dev_exit(idx);
201         }
202
203         if (amdgpu_sriov_vf(adev))
204                 amdgpu_virt_free_mm_table(adev);
205
206         r = amdgpu_vcn_suspend(adev);
207         if (r)
208                 return r;
209
210         r = amdgpu_vcn_sw_fini(adev);
211
212         return r;
213 }
214
215 /**
216  * vcn_v4_0_hw_init - start and test VCN block
217  *
218  * @handle: amdgpu_device pointer
219  *
220  * Initialize the hardware, boot up the VCPU and do some testing
221  */
222 static int vcn_v4_0_hw_init(void *handle)
223 {
224         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
225         struct amdgpu_ring *ring;
226         int i, r;
227
228         if (amdgpu_sriov_vf(adev)) {
229                 r = vcn_v4_0_start_sriov(adev);
230                 if (r)
231                         goto done;
232
233                 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
234                         if (adev->vcn.harvest_config & (1 << i))
235                                 continue;
236
237                         ring = &adev->vcn.inst[i].ring_enc[0];
238                         if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
239                                 ring->sched.ready = false;
240                                 ring->no_scheduler = true;
241                                 dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
242                         } else {
243                                 ring->wptr = 0;
244                                 ring->wptr_old = 0;
245                                 vcn_v4_0_unified_ring_set_wptr(ring);
246                                 ring->sched.ready = true;
247                         }
248                 }
249         } else {
250                 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
251                         if (adev->vcn.harvest_config & (1 << i))
252                                 continue;
253
254                         ring = &adev->vcn.inst[i].ring_enc[0];
255
256                         adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
257                                         ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
258
259                         r = amdgpu_ring_test_helper(ring);
260                         if (r)
261                                 goto done;
262
263                 }
264         }
265
266 done:
267         if (!r)
268                 DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
269                         (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
270
271         return r;
272 }
273
274 /**
275  * vcn_v4_0_hw_fini - stop the hardware block
276  *
277  * @handle: amdgpu_device pointer
278  *
279  * Stop the VCN block, mark ring as not ready any more
280  */
281 static int vcn_v4_0_hw_fini(void *handle)
282 {
283         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
284         int i;
285
286         cancel_delayed_work_sync(&adev->vcn.idle_work);
287
288         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
289                 if (adev->vcn.harvest_config & (1 << i))
290                         continue;
291                 if (!amdgpu_sriov_vf(adev)) {
292                         if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
293                         (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
294                                 RREG32_SOC15(VCN, i, regUVD_STATUS))) {
295                         vcn_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
296                         }
297                 }
298
299         }
300
301         return 0;
302 }
303
304 /**
305  * vcn_v4_0_suspend - suspend VCN block
306  *
307  * @handle: amdgpu_device pointer
308  *
309  * HW fini and suspend VCN block
310  */
311 static int vcn_v4_0_suspend(void *handle)
312 {
313         int r;
314         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
315
316         r = vcn_v4_0_hw_fini(adev);
317         if (r)
318                 return r;
319
320         r = amdgpu_vcn_suspend(adev);
321
322         return r;
323 }
324
325 /**
326  * vcn_v4_0_resume - resume VCN block
327  *
328  * @handle: amdgpu_device pointer
329  *
330  * Resume firmware and hw init VCN block
331  */
332 static int vcn_v4_0_resume(void *handle)
333 {
334         int r;
335         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
336
337         r = amdgpu_vcn_resume(adev);
338         if (r)
339                 return r;
340
341         r = vcn_v4_0_hw_init(adev);
342
343         return r;
344 }
345
346 /**
347  * vcn_v4_0_mc_resume - memory controller programming
348  *
349  * @adev: amdgpu_device pointer
350  * @inst: instance number
351  *
352  * Let the VCN memory controller know it's offsets
353  */
354 static void vcn_v4_0_mc_resume(struct amdgpu_device *adev, int inst)
355 {
356         uint32_t offset, size;
357         const struct common_firmware_header *hdr;
358
359         hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
360         size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
361
362         /* cache window 0: fw */
363         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
364                 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
365                         (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));
366                 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
367                         (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));
368                 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, 0);
369                 offset = 0;
370         } else {
371                 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
372                         lower_32_bits(adev->vcn.inst[inst].gpu_addr));
373                 WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
374                         upper_32_bits(adev->vcn.inst[inst].gpu_addr));
375                 offset = size;
376                 WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET0, AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
377         }
378         WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE0, size);
379
380         /* cache window 1: stack */
381         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
382                 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
383         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
384                 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
385         WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET1, 0);
386         WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
387
388         /* cache window 2: context */
389         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
390                 lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
391         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
392                 upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
393         WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_OFFSET2, 0);
394         WREG32_SOC15(VCN, inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
395
396         /* non-cache window */
397         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
398                 lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
399         WREG32_SOC15(VCN, inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
400                 upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
401         WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_OFFSET0, 0);
402         WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_SIZE0,
403                 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
404 }
405
406 /**
407  * vcn_v4_0_mc_resume_dpg_mode - memory controller programming for dpg mode
408  *
409  * @adev: amdgpu_device pointer
410  * @inst_idx: instance number index
411  * @indirect: indirectly write sram
412  *
413  * Let the VCN memory controller know it's offsets with dpg mode
414  */
415 static void vcn_v4_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
416 {
417         uint32_t offset, size;
418         const struct common_firmware_header *hdr;
419         hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
420         size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
421
422         /* cache window 0: fw */
423         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
424                 if (!indirect) {
425                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
426                                 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
427                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
428                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
429                                 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
430                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
431                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
432                                 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
433                 } else {
434                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
435                                 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
436                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
437                                 VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
438                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
439                                 VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
440                 }
441                 offset = 0;
442         } else {
443                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
444                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
445                         lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
446                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
447                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
448                         upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
449                 offset = size;
450                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
451                         VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET0),
452                         AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
453         }
454
455         if (!indirect)
456                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
457                         VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
458         else
459                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
460                         VCN, inst_idx, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
461
462         /* cache window 1: stack */
463         if (!indirect) {
464                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
465                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
466                         lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
467                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
468                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
469                         upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
470                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
471                         VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
472         } else {
473                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
474                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
475                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
476                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
477                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
478                         VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
479         }
480         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
481                         VCN, inst_idx, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
482
483         /* cache window 2: context */
484         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
485                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
486                         lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
487         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
488                         VCN, inst_idx, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
489                         upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
490         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
491                         VCN, inst_idx, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
492         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
493                         VCN, inst_idx, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
494
495         /* non-cache window */
496         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
497                         VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
498                         lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
499         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
500                         VCN, inst_idx, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
501                         upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
502         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
503                         VCN, inst_idx, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
504         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
505                         VCN, inst_idx, regUVD_VCPU_NONCACHE_SIZE0),
506                         AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect);
507
508         /* VCN global tiling registers */
509         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
510                 VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
511 }
512
513 /**
514  * vcn_v4_0_disable_static_power_gating - disable VCN static power gating
515  *
516  * @adev: amdgpu_device pointer
517  * @inst: instance number
518  *
519  * Disable static power gating for VCN block
520  */
521 static void vcn_v4_0_disable_static_power_gating(struct amdgpu_device *adev, int inst)
522 {
523         uint32_t data = 0;
524
525         if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
526                 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
527                         | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT
528                         | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
529                         | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
530                         | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT
531                         | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
532                         | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT
533                         | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
534                         | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
535                         | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
536                         | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
537                         | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT
538                         | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
539                         | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
540
541                 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data);
542                 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS,
543                         UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0, 0x3F3FFFFF);
544         } else {
545                 uint32_t value;
546
547                 value = (inst) ? 0x2200800 : 0;
548                 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
549                         | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT
550                         | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
551                         | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
552                         | 1 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT
553                         | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
554                         | 1 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT
555                         | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
556                         | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
557                         | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
558                         | 1 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
559                         | 1 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT
560                         | 1 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
561                         | 1 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
562
563                 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data);
564                 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS, value,  0x3F3FFFFF);
565         }
566
567         data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS);
568         data &= ~0x103;
569         if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
570                 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON |
571                         UVD_POWER_STATUS__UVD_PG_EN_MASK;
572
573         WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data);
574
575         return;
576 }
577
578 /**
579  * vcn_v4_0_enable_static_power_gating - enable VCN static power gating
580  *
581  * @adev: amdgpu_device pointer
582  * @inst: instance number
583  *
584  * Enable static power gating for VCN block
585  */
586 static void vcn_v4_0_enable_static_power_gating(struct amdgpu_device *adev, int inst)
587 {
588         uint32_t data;
589
590         if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
591                 /* Before power off, this indicator has to be turned on */
592                 data = RREG32_SOC15(VCN, inst, regUVD_POWER_STATUS);
593                 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
594                 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
595                 WREG32_SOC15(VCN, inst, regUVD_POWER_STATUS, data);
596
597                 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
598                         | 2 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT
599                         | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
600                         | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT
601                         | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
602                         | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT
603                         | 2 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT
604                         | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
605                         | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
606                         | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
607                         | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT
608                         | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT
609                         | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT
610                         | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT);
611                 WREG32_SOC15(VCN, inst, regUVD_PGFSM_CONFIG, data);
612
613                 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
614                         | 2 << UVD_PGFSM_STATUS__UVDS_PWR_STATUS__SHIFT
615                         | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
616                         | 2 << UVD_PGFSM_STATUS__UVDTC_PWR_STATUS__SHIFT
617                         | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
618                         | 2 << UVD_PGFSM_STATUS__UVDTA_PWR_STATUS__SHIFT
619                         | 2 << UVD_PGFSM_STATUS__UVDLM_PWR_STATUS__SHIFT
620                         | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
621                         | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
622                         | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
623                         | 2 << UVD_PGFSM_STATUS__UVDAB_PWR_STATUS__SHIFT
624                         | 2 << UVD_PGFSM_STATUS__UVDTB_PWR_STATUS__SHIFT
625                         | 2 << UVD_PGFSM_STATUS__UVDNA_PWR_STATUS__SHIFT
626                         | 2 << UVD_PGFSM_STATUS__UVDNB_PWR_STATUS__SHIFT);
627                 SOC15_WAIT_ON_RREG(VCN, inst, regUVD_PGFSM_STATUS, data, 0x3F3FFFFF);
628         }
629
630         return;
631 }
632
633 /**
634  * vcn_v4_0_disable_clock_gating - disable VCN clock gating
635  *
636  * @adev: amdgpu_device pointer
637  * @inst: instance number
638  *
639  * Disable clock gating for VCN block
640  */
641 static void vcn_v4_0_disable_clock_gating(struct amdgpu_device *adev, int inst)
642 {
643         uint32_t data;
644
645         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
646                 return;
647
648         /* VCN disable CGC */
649         data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);
650         data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
651         data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
652         data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
653         WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);
654
655         data = RREG32_SOC15(VCN, inst, regUVD_CGC_GATE);
656         data &= ~(UVD_CGC_GATE__SYS_MASK
657                 | UVD_CGC_GATE__UDEC_MASK
658                 | UVD_CGC_GATE__MPEG2_MASK
659                 | UVD_CGC_GATE__REGS_MASK
660                 | UVD_CGC_GATE__RBC_MASK
661                 | UVD_CGC_GATE__LMI_MC_MASK
662                 | UVD_CGC_GATE__LMI_UMC_MASK
663                 | UVD_CGC_GATE__IDCT_MASK
664                 | UVD_CGC_GATE__MPRD_MASK
665                 | UVD_CGC_GATE__MPC_MASK
666                 | UVD_CGC_GATE__LBSI_MASK
667                 | UVD_CGC_GATE__LRBBM_MASK
668                 | UVD_CGC_GATE__UDEC_RE_MASK
669                 | UVD_CGC_GATE__UDEC_CM_MASK
670                 | UVD_CGC_GATE__UDEC_IT_MASK
671                 | UVD_CGC_GATE__UDEC_DB_MASK
672                 | UVD_CGC_GATE__UDEC_MP_MASK
673                 | UVD_CGC_GATE__WCB_MASK
674                 | UVD_CGC_GATE__VCPU_MASK
675                 | UVD_CGC_GATE__MMSCH_MASK);
676
677         WREG32_SOC15(VCN, inst, regUVD_CGC_GATE, data);
678         SOC15_WAIT_ON_RREG(VCN, inst, regUVD_CGC_GATE, 0,  0xFFFFFFFF);
679
680         data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);
681         data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
682                 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
683                 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
684                 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
685                 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
686                 | UVD_CGC_CTRL__SYS_MODE_MASK
687                 | UVD_CGC_CTRL__UDEC_MODE_MASK
688                 | UVD_CGC_CTRL__MPEG2_MODE_MASK
689                 | UVD_CGC_CTRL__REGS_MODE_MASK
690                 | UVD_CGC_CTRL__RBC_MODE_MASK
691                 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
692                 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
693                 | UVD_CGC_CTRL__IDCT_MODE_MASK
694                 | UVD_CGC_CTRL__MPRD_MODE_MASK
695                 | UVD_CGC_CTRL__MPC_MODE_MASK
696                 | UVD_CGC_CTRL__LBSI_MODE_MASK
697                 | UVD_CGC_CTRL__LRBBM_MODE_MASK
698                 | UVD_CGC_CTRL__WCB_MODE_MASK
699                 | UVD_CGC_CTRL__VCPU_MODE_MASK
700                 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
701         WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);
702
703         data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE);
704         data |= (UVD_SUVD_CGC_GATE__SRE_MASK
705                 | UVD_SUVD_CGC_GATE__SIT_MASK
706                 | UVD_SUVD_CGC_GATE__SMP_MASK
707                 | UVD_SUVD_CGC_GATE__SCM_MASK
708                 | UVD_SUVD_CGC_GATE__SDB_MASK
709                 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
710                 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
711                 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
712                 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
713                 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
714                 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
715                 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
716                 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
717                 | UVD_SUVD_CGC_GATE__SCLR_MASK
718                 | UVD_SUVD_CGC_GATE__UVD_SC_MASK
719                 | UVD_SUVD_CGC_GATE__ENT_MASK
720                 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
721                 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
722                 | UVD_SUVD_CGC_GATE__SITE_MASK
723                 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
724                 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
725                 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
726                 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
727                 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
728         WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_GATE, data);
729
730         data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL);
731         data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
732                 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
733                 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
734                 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
735                 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
736                 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
737                 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
738                 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
739                 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
740                 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
741         WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data);
742 }
743
744 /**
745  * vcn_v4_0_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode
746  *
747  * @adev: amdgpu_device pointer
748  * @sram_sel: sram select
749  * @inst_idx: instance number index
750  * @indirect: indirectly write sram
751  *
752  * Disable clock gating for VCN block with dpg mode
753  */
754 static void vcn_v4_0_disable_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel,
755       int inst_idx, uint8_t indirect)
756 {
757         uint32_t reg_data = 0;
758
759         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
760                 return;
761
762         /* enable sw clock gating control */
763         reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
764         reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
765         reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
766         reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
767                  UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
768                  UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
769                  UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
770                  UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
771                  UVD_CGC_CTRL__SYS_MODE_MASK |
772                  UVD_CGC_CTRL__UDEC_MODE_MASK |
773                  UVD_CGC_CTRL__MPEG2_MODE_MASK |
774                  UVD_CGC_CTRL__REGS_MODE_MASK |
775                  UVD_CGC_CTRL__RBC_MODE_MASK |
776                  UVD_CGC_CTRL__LMI_MC_MODE_MASK |
777                  UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
778                  UVD_CGC_CTRL__IDCT_MODE_MASK |
779                  UVD_CGC_CTRL__MPRD_MODE_MASK |
780                  UVD_CGC_CTRL__MPC_MODE_MASK |
781                  UVD_CGC_CTRL__LBSI_MODE_MASK |
782                  UVD_CGC_CTRL__LRBBM_MODE_MASK |
783                  UVD_CGC_CTRL__WCB_MODE_MASK |
784                  UVD_CGC_CTRL__VCPU_MODE_MASK);
785         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
786                 VCN, inst_idx, regUVD_CGC_CTRL), reg_data, sram_sel, indirect);
787
788         /* turn off clock gating */
789         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
790                 VCN, inst_idx, regUVD_CGC_GATE), 0, sram_sel, indirect);
791
792         /* turn on SUVD clock gating */
793         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
794                 VCN, inst_idx, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
795
796         /* turn on sw mode in UVD_SUVD_CGC_CTRL */
797         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
798                 VCN, inst_idx, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
799 }
800
801 /**
802  * vcn_v4_0_enable_clock_gating - enable VCN clock gating
803  *
804  * @adev: amdgpu_device pointer
805  * @inst: instance number
806  *
807  * Enable clock gating for VCN block
808  */
809 static void vcn_v4_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
810 {
811         uint32_t data;
812
813         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
814                 return;
815
816         /* enable VCN CGC */
817         data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);
818         data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
819         data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
820         data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
821         WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);
822
823         data = RREG32_SOC15(VCN, inst, regUVD_CGC_CTRL);
824         data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
825                 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
826                 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
827                 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
828                 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
829                 | UVD_CGC_CTRL__SYS_MODE_MASK
830                 | UVD_CGC_CTRL__UDEC_MODE_MASK
831                 | UVD_CGC_CTRL__MPEG2_MODE_MASK
832                 | UVD_CGC_CTRL__REGS_MODE_MASK
833                 | UVD_CGC_CTRL__RBC_MODE_MASK
834                 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
835                 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
836                 | UVD_CGC_CTRL__IDCT_MODE_MASK
837                 | UVD_CGC_CTRL__MPRD_MODE_MASK
838                 | UVD_CGC_CTRL__MPC_MODE_MASK
839                 | UVD_CGC_CTRL__LBSI_MODE_MASK
840                 | UVD_CGC_CTRL__LRBBM_MODE_MASK
841                 | UVD_CGC_CTRL__WCB_MODE_MASK
842                 | UVD_CGC_CTRL__VCPU_MODE_MASK
843                 | UVD_CGC_CTRL__MMSCH_MODE_MASK);
844         WREG32_SOC15(VCN, inst, regUVD_CGC_CTRL, data);
845
846         data = RREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL);
847         data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
848                 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
849                 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
850                 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
851                 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
852                 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
853                 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
854                 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
855                 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
856                 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
857         WREG32_SOC15(VCN, inst, regUVD_SUVD_CGC_CTRL, data);
858
859         return;
860 }
861
862 /**
863  * vcn_v4_0_start_dpg_mode - VCN start with dpg mode
864  *
865  * @adev: amdgpu_device pointer
866  * @inst_idx: instance number index
867  * @indirect: indirectly write sram
868  *
869  * Start VCN block with dpg mode
870  */
871 static int vcn_v4_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
872 {
873         volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
874         struct amdgpu_ring *ring;
875         uint32_t tmp;
876
877         /* disable register anti-hang mechanism */
878         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 1,
879                 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
880         /* enable dynamic power gating mode */
881         tmp = RREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS);
882         tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
883         tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
884         WREG32_SOC15(VCN, inst_idx, regUVD_POWER_STATUS, tmp);
885
886         if (indirect)
887                 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
888
889         /* enable clock gating */
890         vcn_v4_0_disable_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
891
892         /* enable VCPU clock */
893         tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
894         tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK;
895         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
896                 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect);
897
898         /* disable master interupt */
899         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
900                 VCN, inst_idx, regUVD_MASTINT_EN), 0, 0, indirect);
901
902         /* setup regUVD_LMI_CTRL */
903         tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
904                 UVD_LMI_CTRL__REQ_MODE_MASK |
905                 UVD_LMI_CTRL__CRC_RESET_MASK |
906                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
907                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
908                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
909                 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
910                 0x00100000L);
911         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
912                 VCN, inst_idx, regUVD_LMI_CTRL), tmp, 0, indirect);
913
914         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
915                 VCN, inst_idx, regUVD_MPC_CNTL),
916                 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
917
918         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
919                 VCN, inst_idx, regUVD_MPC_SET_MUXA0),
920                 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
921                  (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
922                  (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
923                  (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
924
925         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
926                 VCN, inst_idx, regUVD_MPC_SET_MUXB0),
927                  ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
928                  (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
929                  (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
930                  (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
931
932         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
933                 VCN, inst_idx, regUVD_MPC_SET_MUX),
934                 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
935                  (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
936                  (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
937
938         vcn_v4_0_mc_resume_dpg_mode(adev, inst_idx, indirect);
939
940         tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
941         tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
942         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
943                 VCN, inst_idx, regUVD_VCPU_CNTL), tmp, 0, indirect);
944
945         /* enable LMI MC and UMC channels */
946         tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT;
947         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
948                 VCN, inst_idx, regUVD_LMI_CTRL2), tmp, 0, indirect);
949
950         /* enable master interrupt */
951         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
952                 VCN, inst_idx, regUVD_MASTINT_EN),
953                 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
954
955
956         if (indirect)
957                 psp_update_vcn_sram(adev, inst_idx, adev->vcn.inst[inst_idx].dpg_sram_gpu_addr,
958                         (uint32_t)((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr -
959                                 (uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr));
960
961         ring = &adev->vcn.inst[inst_idx].ring_enc[0];
962
963         WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_LO, ring->gpu_addr);
964         WREG32_SOC15(VCN, inst_idx, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
965         WREG32_SOC15(VCN, inst_idx, regUVD_RB_SIZE, ring->ring_size / 4);
966
967         tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE);
968         tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
969         WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp);
970         fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
971         WREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR, 0);
972         WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, 0);
973
974         tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_RPTR);
975         WREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR, tmp);
976         ring->wptr = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR);
977
978         tmp = RREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE);
979         tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
980         WREG32_SOC15(VCN, inst_idx, regVCN_RB_ENABLE, tmp);
981         fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
982
983         WREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL,
984                         ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
985                         VCN_RB1_DB_CTRL__EN_MASK);
986
987         return 0;
988 }
989
990
991 /**
992  * vcn_v4_0_start - VCN start
993  *
994  * @adev: amdgpu_device pointer
995  *
996  * Start VCN block
997  */
998 static int vcn_v4_0_start(struct amdgpu_device *adev)
999 {
1000         volatile struct amdgpu_vcn4_fw_shared *fw_shared;
1001         struct amdgpu_ring *ring;
1002         uint32_t tmp;
1003         int i, j, k, r;
1004
1005         if (adev->pm.dpm_enabled)
1006                 amdgpu_dpm_enable_uvd(adev, true);
1007
1008         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1009                 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1010
1011                 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1012                         r = vcn_v4_0_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
1013                         continue;
1014                 }
1015
1016                 /* disable VCN power gating */
1017                 vcn_v4_0_disable_static_power_gating(adev, i);
1018
1019                 /* set VCN status busy */
1020                 tmp = RREG32_SOC15(VCN, i, regUVD_STATUS) | UVD_STATUS__UVD_BUSY;
1021                 WREG32_SOC15(VCN, i, regUVD_STATUS, tmp);
1022
1023                 /*SW clock gating */
1024                 vcn_v4_0_disable_clock_gating(adev, i);
1025
1026                 /* enable VCPU clock */
1027                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),
1028                                 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1029
1030                 /* disable master interrupt */
1031                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN), 0,
1032                                 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1033
1034                 /* enable LMI MC and UMC channels */
1035                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_LMI_CTRL2), 0,
1036                                 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1037
1038                 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);
1039                 tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1040                 tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1041                 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);
1042
1043                 /* setup regUVD_LMI_CTRL */
1044                 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL);
1045                 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL, tmp |
1046                                 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1047                                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1048                                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1049                                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1050
1051                 /* setup regUVD_MPC_CNTL */
1052                 tmp = RREG32_SOC15(VCN, i, regUVD_MPC_CNTL);
1053                 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1054                 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1055                 WREG32_SOC15(VCN, i, regUVD_MPC_CNTL, tmp);
1056
1057                 /* setup UVD_MPC_SET_MUXA0 */
1058                 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXA0,
1059                                 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1060                                  (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1061                                  (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1062                                  (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1063
1064                 /* setup UVD_MPC_SET_MUXB0 */
1065                 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUXB0,
1066                                 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1067                                  (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1068                                  (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1069                                  (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1070
1071                 /* setup UVD_MPC_SET_MUX */
1072                 WREG32_SOC15(VCN, i, regUVD_MPC_SET_MUX,
1073                                 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1074                                  (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1075                                  (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1076
1077                 vcn_v4_0_mc_resume(adev, i);
1078
1079                 /* VCN global tiling registers */
1080                 WREG32_SOC15(VCN, i, regUVD_GFX10_ADDR_CONFIG,
1081                                 adev->gfx.config.gb_addr_config);
1082
1083                 /* unblock VCPU register access */
1084                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL), 0,
1085                                 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1086
1087                 /* release VCPU reset to boot */
1088                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,
1089                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1090
1091                 for (j = 0; j < 10; ++j) {
1092                         uint32_t status;
1093
1094                         for (k = 0; k < 100; ++k) {
1095                                 status = RREG32_SOC15(VCN, i, regUVD_STATUS);
1096                                 if (status & 2)
1097                                         break;
1098                                 mdelay(10);
1099                                 if (amdgpu_emu_mode==1)
1100                                         msleep(1);
1101                         }
1102
1103                         if (amdgpu_emu_mode==1) {
1104                                 r = -1;
1105                                 if (status & 2) {
1106                                         r = 0;
1107                                         break;
1108                                 }
1109                         } else {
1110                                 r = 0;
1111                                 if (status & 2)
1112                                         break;
1113
1114                                 dev_err(adev->dev, "VCN[%d] is not responding, trying to reset the VCPU!!!\n", i);
1115                                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),
1116                                                         UVD_VCPU_CNTL__BLK_RST_MASK,
1117                                                         ~UVD_VCPU_CNTL__BLK_RST_MASK);
1118                                 mdelay(10);
1119                                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,
1120                                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1121
1122                                 mdelay(10);
1123                                 r = -1;
1124                         }
1125                 }
1126
1127                 if (r) {
1128                         dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i);
1129                         return r;
1130                 }
1131
1132                 /* enable master interrupt */
1133                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_MASTINT_EN),
1134                                 UVD_MASTINT_EN__VCPU_EN_MASK,
1135                                 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1136
1137                 /* clear the busy bit of VCN_STATUS */
1138                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_STATUS), 0,
1139                                 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1140
1141                 ring = &adev->vcn.inst[i].ring_enc[0];
1142                 WREG32_SOC15(VCN, i, regVCN_RB1_DB_CTRL,
1143                                 ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
1144                                 VCN_RB1_DB_CTRL__EN_MASK);
1145
1146                 WREG32_SOC15(VCN, i, regUVD_RB_BASE_LO, ring->gpu_addr);
1147                 WREG32_SOC15(VCN, i, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1148                 WREG32_SOC15(VCN, i, regUVD_RB_SIZE, ring->ring_size / 4);
1149
1150                 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE);
1151                 tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
1152                 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp);
1153                 fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
1154                 WREG32_SOC15(VCN, i, regUVD_RB_RPTR, 0);
1155                 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, 0);
1156
1157                 tmp = RREG32_SOC15(VCN, i, regUVD_RB_RPTR);
1158                 WREG32_SOC15(VCN, i, regUVD_RB_WPTR, tmp);
1159                 ring->wptr = RREG32_SOC15(VCN, i, regUVD_RB_WPTR);
1160
1161                 tmp = RREG32_SOC15(VCN, i, regVCN_RB_ENABLE);
1162                 tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
1163                 WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp);
1164                 fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
1165         }
1166
1167         return 0;
1168 }
1169
1170 static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
1171 {
1172         int i;
1173         struct amdgpu_ring *ring_enc;
1174         uint64_t cache_addr;
1175         uint64_t rb_enc_addr;
1176         uint64_t ctx_addr;
1177         uint32_t param, resp, expected;
1178         uint32_t offset, cache_size;
1179         uint32_t tmp, timeout;
1180
1181         struct amdgpu_mm_table *table = &adev->virt.mm_table;
1182         uint32_t *table_loc;
1183         uint32_t table_size;
1184         uint32_t size, size_dw;
1185         uint32_t init_status;
1186         uint32_t enabled_vcn;
1187
1188         struct mmsch_v4_0_cmd_direct_write
1189                 direct_wt = { {0} };
1190         struct mmsch_v4_0_cmd_direct_read_modify_write
1191                 direct_rd_mod_wt = { {0} };
1192         struct mmsch_v4_0_cmd_end end = { {0} };
1193         struct mmsch_v4_0_init_header header;
1194
1195         volatile struct amdgpu_vcn4_fw_shared *fw_shared;
1196         volatile struct amdgpu_fw_shared_rb_setup *rb_setup;
1197
1198         direct_wt.cmd_header.command_type =
1199                 MMSCH_COMMAND__DIRECT_REG_WRITE;
1200         direct_rd_mod_wt.cmd_header.command_type =
1201                 MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1202         end.cmd_header.command_type =
1203                 MMSCH_COMMAND__END;
1204
1205         header.version = MMSCH_VERSION;
1206         header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2;
1207         for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
1208                 header.inst[i].init_status = 0;
1209                 header.inst[i].table_offset = 0;
1210                 header.inst[i].table_size = 0;
1211         }
1212
1213         table_loc = (uint32_t *)table->cpu_addr;
1214         table_loc += header.total_size;
1215         for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1216                 if (adev->vcn.harvest_config & (1 << i))
1217                         continue;
1218
1219                 table_size = 0;
1220
1221                 MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
1222                         regUVD_STATUS),
1223                         ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1224
1225                 cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
1226
1227                 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1228                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1229                                 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1230                                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
1231                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1232                                 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1233                                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
1234                         offset = 0;
1235                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1236                                 regUVD_VCPU_CACHE_OFFSET0),
1237                                 0);
1238                 } else {
1239                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1240                                 regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1241                                 lower_32_bits(adev->vcn.inst[i].gpu_addr));
1242                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1243                                 regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1244                                 upper_32_bits(adev->vcn.inst[i].gpu_addr));
1245                         offset = cache_size;
1246                         MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1247                                 regUVD_VCPU_CACHE_OFFSET0),
1248                                 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1249                 }
1250
1251                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1252                         regUVD_VCPU_CACHE_SIZE0),
1253                         cache_size);
1254
1255                 cache_addr = adev->vcn.inst[i].gpu_addr + offset;
1256                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1257                         regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1258                         lower_32_bits(cache_addr));
1259                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1260                         regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1261                         upper_32_bits(cache_addr));
1262                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1263                         regUVD_VCPU_CACHE_OFFSET1),
1264                         0);
1265                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1266                         regUVD_VCPU_CACHE_SIZE1),
1267                         AMDGPU_VCN_STACK_SIZE);
1268
1269                 cache_addr = adev->vcn.inst[i].gpu_addr + offset +
1270                         AMDGPU_VCN_STACK_SIZE;
1271                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1272                         regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1273                         lower_32_bits(cache_addr));
1274                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1275                         regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1276                         upper_32_bits(cache_addr));
1277                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1278                         regUVD_VCPU_CACHE_OFFSET2),
1279                         0);
1280                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1281                         regUVD_VCPU_CACHE_SIZE2),
1282                         AMDGPU_VCN_CONTEXT_SIZE);
1283
1284                 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1285                 rb_setup = &fw_shared->rb_setup;
1286
1287                 ring_enc = &adev->vcn.inst[i].ring_enc[0];
1288                 ring_enc->wptr = 0;
1289                 rb_enc_addr = ring_enc->gpu_addr;
1290
1291                 rb_setup->is_rb_enabled_flags |= RB_ENABLED;
1292                 rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
1293                 rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
1294                 rb_setup->rb_size = ring_enc->ring_size / 4;
1295                 fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
1296
1297                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1298                         regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
1299                         lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
1300                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1301                         regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
1302                         upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
1303                 MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
1304                         regUVD_VCPU_NONCACHE_SIZE0),
1305                         AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
1306
1307                 /* add end packet */
1308                 MMSCH_V4_0_INSERT_END();
1309
1310                 /* refine header */
1311                 header.inst[i].init_status = 0;
1312                 header.inst[i].table_offset = header.total_size;
1313                 header.inst[i].table_size = table_size;
1314                 header.total_size += table_size;
1315         }
1316
1317         /* Update init table header in memory */
1318         size = sizeof(struct mmsch_v4_0_init_header);
1319         table_loc = (uint32_t *)table->cpu_addr;
1320         memcpy((void *)table_loc, &header, size);
1321
1322         /* message MMSCH (in VCN[0]) to initialize this client
1323          * 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
1324          * of memory descriptor location
1325          */
1326         ctx_addr = table->gpu_addr;
1327         WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
1328         WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
1329
1330         /* 2, update vmid of descriptor */
1331         tmp = RREG32_SOC15(VCN, 0, regMMSCH_VF_VMID);
1332         tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1333         /* use domain0 for MM scheduler */
1334         tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1335         WREG32_SOC15(VCN, 0, regMMSCH_VF_VMID, tmp);
1336
1337         /* 3, notify mmsch about the size of this descriptor */
1338         size = header.total_size;
1339         WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE, size);
1340
1341         /* 4, set resp to zero */
1342         WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP, 0);
1343
1344         /* 5, kick off the initialization and wait until
1345          * MMSCH_VF_MAILBOX_RESP becomes non-zero
1346          */
1347         param = 0x00000001;
1348         WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_HOST, param);
1349         tmp = 0;
1350         timeout = 1000;
1351         resp = 0;
1352         expected = MMSCH_VF_MAILBOX_RESP__OK;
1353         while (resp != expected) {
1354                 resp = RREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP);
1355                 if (resp != 0)
1356                         break;
1357
1358                 udelay(10);
1359                 tmp = tmp + 10;
1360                 if (tmp >= timeout) {
1361                         DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
1362                                 " waiting for regMMSCH_VF_MAILBOX_RESP "\
1363                                 "(expected=0x%08x, readback=0x%08x)\n",
1364                                 tmp, expected, resp);
1365                         return -EBUSY;
1366                 }
1367         }
1368         enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0;
1369         init_status = ((struct mmsch_v4_0_init_header *)(table_loc))->inst[enabled_vcn].init_status;
1370         if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE
1371         && init_status != MMSCH_VF_ENGINE_STATUS__PASS)
1372                 DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\
1373                         "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status);
1374
1375         return 0;
1376 }
1377
1378 /**
1379  * vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode
1380  *
1381  * @adev: amdgpu_device pointer
1382  * @inst_idx: instance number index
1383  *
1384  * Stop VCN block with dpg mode
1385  */
1386 static void vcn_v4_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
1387 {
1388         uint32_t tmp;
1389
1390         /* Wait for power status to be 1 */
1391         SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1,
1392                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1393
1394         /* wait for read ptr to be equal to write ptr */
1395         tmp = RREG32_SOC15(VCN, inst_idx, regUVD_RB_WPTR);
1396         SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1397
1398         SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1,
1399                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1400
1401         /* disable dynamic power gating mode */
1402         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0,
1403                 ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1404 }
1405
1406 /**
1407  * vcn_v4_0_stop - VCN stop
1408  *
1409  * @adev: amdgpu_device pointer
1410  *
1411  * Stop VCN block
1412  */
1413 static int vcn_v4_0_stop(struct amdgpu_device *adev)
1414 {
1415         volatile struct amdgpu_vcn4_fw_shared *fw_shared;
1416         uint32_t tmp;
1417         int i, r = 0;
1418
1419         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1420                 fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1421                 fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
1422
1423                 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1424                         vcn_v4_0_stop_dpg_mode(adev, i);
1425                         continue;
1426                 }
1427
1428                 /* wait for vcn idle */
1429                 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1430                 if (r)
1431                         return r;
1432
1433                 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1434                         UVD_LMI_STATUS__READ_CLEAN_MASK |
1435                         UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1436                         UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1437                 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp);
1438                 if (r)
1439                         return r;
1440
1441                 /* disable LMI UMC channel */
1442                 tmp = RREG32_SOC15(VCN, i, regUVD_LMI_CTRL2);
1443                 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1444                 WREG32_SOC15(VCN, i, regUVD_LMI_CTRL2, tmp);
1445                 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
1446                         UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1447                 r = SOC15_WAIT_ON_RREG(VCN, i, regUVD_LMI_STATUS, tmp, tmp);
1448                 if (r)
1449                         return r;
1450
1451                 /* block VCPU register access */
1452                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_RB_ARB_CTRL),
1453                                 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1454                                 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1455
1456                 /* reset VCPU */
1457                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL),
1458                                 UVD_VCPU_CNTL__BLK_RST_MASK,
1459                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1460
1461                 /* disable VCPU clock */
1462                 WREG32_P(SOC15_REG_OFFSET(VCN, i, regUVD_VCPU_CNTL), 0,
1463                                 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1464
1465                 /* apply soft reset */
1466                 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);
1467                 tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1468                 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);
1469                 tmp = RREG32_SOC15(VCN, i, regUVD_SOFT_RESET);
1470                 tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1471                 WREG32_SOC15(VCN, i, regUVD_SOFT_RESET, tmp);
1472
1473                 /* clear status */
1474                 WREG32_SOC15(VCN, i, regUVD_STATUS, 0);
1475
1476                 /* apply HW clock gating */
1477                 vcn_v4_0_enable_clock_gating(adev, i);
1478
1479                 /* enable VCN power gating */
1480                 vcn_v4_0_enable_static_power_gating(adev, i);
1481         }
1482
1483         if (adev->pm.dpm_enabled)
1484                 amdgpu_dpm_enable_uvd(adev, false);
1485
1486         return 0;
1487 }
1488
1489 /**
1490  * vcn_v4_0_pause_dpg_mode - VCN pause with dpg mode
1491  *
1492  * @adev: amdgpu_device pointer
1493  * @inst_idx: instance number index
1494  * @new_state: pause state
1495  *
1496  * Pause dpg mode for VCN block
1497  */
1498 static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx,
1499       struct dpg_pause_state *new_state)
1500 {
1501         uint32_t reg_data = 0;
1502         int ret_code;
1503
1504         /* pause/unpause if state is changed */
1505         if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1506                 DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d",
1507                         adev->vcn.inst[inst_idx].pause_state.fw_based,  new_state->fw_based);
1508                 reg_data = RREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE) &
1509                         (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1510
1511                 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1512                         ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 0x1,
1513                                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1514
1515                         if (!ret_code) {
1516                                 /* pause DPG */
1517                                 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1518                                 WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data);
1519
1520                                 /* wait for ACK */
1521                                 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_DPG_PAUSE,
1522                                         UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1523                                         UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1524
1525                                 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS,
1526                                         UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1527                         }
1528                 } else {
1529                         /* unpause dpg, no need to wait */
1530                         reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1531                         WREG32_SOC15(VCN, inst_idx, regUVD_DPG_PAUSE, reg_data);
1532                 }
1533                 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1534         }
1535
1536         return 0;
1537 }
1538
1539 /**
1540  * vcn_v4_0_unified_ring_get_rptr - get unified read pointer
1541  *
1542  * @ring: amdgpu_ring pointer
1543  *
1544  * Returns the current hardware unified read pointer
1545  */
1546 static uint64_t vcn_v4_0_unified_ring_get_rptr(struct amdgpu_ring *ring)
1547 {
1548         struct amdgpu_device *adev = ring->adev;
1549
1550         if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1551                 DRM_ERROR("wrong ring id is identified in %s", __func__);
1552
1553         return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR);
1554 }
1555
1556 /**
1557  * vcn_v4_0_unified_ring_get_wptr - get unified write pointer
1558  *
1559  * @ring: amdgpu_ring pointer
1560  *
1561  * Returns the current hardware unified write pointer
1562  */
1563 static uint64_t vcn_v4_0_unified_ring_get_wptr(struct amdgpu_ring *ring)
1564 {
1565         struct amdgpu_device *adev = ring->adev;
1566
1567         if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1568                 DRM_ERROR("wrong ring id is identified in %s", __func__);
1569
1570         if (ring->use_doorbell)
1571                 return *ring->wptr_cpu_addr;
1572         else
1573                 return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR);
1574 }
1575
1576 /**
1577  * vcn_v4_0_unified_ring_set_wptr - set enc write pointer
1578  *
1579  * @ring: amdgpu_ring pointer
1580  *
1581  * Commits the enc write pointer to the hardware
1582  */
1583 static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring)
1584 {
1585         struct amdgpu_device *adev = ring->adev;
1586
1587         if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1588                 DRM_ERROR("wrong ring id is identified in %s", __func__);
1589
1590         if (ring->use_doorbell) {
1591                 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1592                 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1593         } else {
1594                 WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR, lower_32_bits(ring->wptr));
1595         }
1596 }
1597
1598 static int vcn_v4_0_limit_sched(struct amdgpu_cs_parser *p,
1599                                 struct amdgpu_job *job)
1600 {
1601         struct drm_gpu_scheduler **scheds;
1602
1603         /* The create msg must be in the first IB submitted */
1604         if (atomic_read(&job->base.entity->fence_seq))
1605                 return -EINVAL;
1606
1607         scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC]
1608                 [AMDGPU_RING_PRIO_0].sched;
1609         drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
1610         return 0;
1611 }
1612
1613 static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
1614                             uint64_t addr)
1615 {
1616         struct ttm_operation_ctx ctx = { false, false };
1617         struct amdgpu_bo_va_mapping *map;
1618         uint32_t *msg, num_buffers;
1619         struct amdgpu_bo *bo;
1620         uint64_t start, end;
1621         unsigned int i;
1622         void *ptr;
1623         int r;
1624
1625         addr &= AMDGPU_GMC_HOLE_MASK;
1626         r = amdgpu_cs_find_mapping(p, addr, &bo, &map);
1627         if (r) {
1628                 DRM_ERROR("Can't find BO for addr 0x%08llx\n", addr);
1629                 return r;
1630         }
1631
1632         start = map->start * AMDGPU_GPU_PAGE_SIZE;
1633         end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE;
1634         if (addr & 0x7) {
1635                 DRM_ERROR("VCN messages must be 8 byte aligned!\n");
1636                 return -EINVAL;
1637         }
1638
1639         bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
1640         amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
1641         r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
1642         if (r) {
1643                 DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r);
1644                 return r;
1645         }
1646
1647         r = amdgpu_bo_kmap(bo, &ptr);
1648         if (r) {
1649                 DRM_ERROR("Failed mapping the VCN message (%d)!\n", r);
1650                 return r;
1651         }
1652
1653         msg = ptr + addr - start;
1654
1655         /* Check length */
1656         if (msg[1] > end - addr) {
1657                 r = -EINVAL;
1658                 goto out;
1659         }
1660
1661         if (msg[3] != RDECODE_MSG_CREATE)
1662                 goto out;
1663
1664         num_buffers = msg[2];
1665         for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
1666                 uint32_t offset, size, *create;
1667
1668                 if (msg[0] != RDECODE_MESSAGE_CREATE)
1669                         continue;
1670
1671                 offset = msg[1];
1672                 size = msg[2];
1673
1674                 if (offset + size > end) {
1675                         r = -EINVAL;
1676                         goto out;
1677                 }
1678
1679                 create = ptr + addr + offset - start;
1680
1681                 /* H246, HEVC and VP9 can run on any instance */
1682                 if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
1683                         continue;
1684
1685                 r = vcn_v4_0_limit_sched(p, job);
1686                 if (r)
1687                         goto out;
1688         }
1689
1690 out:
1691         amdgpu_bo_kunmap(bo);
1692         return r;
1693 }
1694
1695 #define RADEON_VCN_ENGINE_TYPE_DECODE                                 (0x00000003)
1696
1697 static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
1698                                            struct amdgpu_job *job,
1699                                            struct amdgpu_ib *ib)
1700 {
1701         struct amdgpu_ring *ring = amdgpu_job_ring(job);
1702         struct amdgpu_vcn_decode_buffer *decode_buffer;
1703         uint64_t addr;
1704         uint32_t val;
1705
1706         /* The first instance can decode anything */
1707         if (!ring->me)
1708                 return 0;
1709
1710         /* unified queue ib header has 8 double words. */
1711         if (ib->length_dw < 8)
1712                 return 0;
1713
1714         val = amdgpu_ib_get_value(ib, 6); //RADEON_VCN_ENGINE_TYPE
1715         if (val != RADEON_VCN_ENGINE_TYPE_DECODE)
1716                 return 0;
1717
1718         decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[10];
1719
1720         if (!(decode_buffer->valid_buf_flag  & 0x1))
1721                 return 0;
1722
1723         addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
1724                 decode_buffer->msg_buffer_address_lo;
1725         return vcn_v4_0_dec_msg(p, job, addr);
1726 }
1727
1728 static const struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = {
1729         .type = AMDGPU_RING_TYPE_VCN_ENC,
1730         .align_mask = 0x3f,
1731         .nop = VCN_ENC_CMD_NO_OP,
1732         .vmhub = AMDGPU_MMHUB_0,
1733         .get_rptr = vcn_v4_0_unified_ring_get_rptr,
1734         .get_wptr = vcn_v4_0_unified_ring_get_wptr,
1735         .set_wptr = vcn_v4_0_unified_ring_set_wptr,
1736         .patch_cs_in_place = vcn_v4_0_ring_patch_cs_in_place,
1737         .emit_frame_size =
1738                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1739                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1740                 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1741                 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1742                 1, /* vcn_v2_0_enc_ring_insert_end */
1743         .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1744         .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1745         .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1746         .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1747         .test_ring = amdgpu_vcn_enc_ring_test_ring,
1748         .test_ib = amdgpu_vcn_unified_ring_test_ib,
1749         .insert_nop = amdgpu_ring_insert_nop,
1750         .insert_end = vcn_v2_0_enc_ring_insert_end,
1751         .pad_ib = amdgpu_ring_generic_pad_ib,
1752         .begin_use = amdgpu_vcn_ring_begin_use,
1753         .end_use = amdgpu_vcn_ring_end_use,
1754         .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1755         .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1756         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1757 };
1758
1759 /**
1760  * vcn_v4_0_set_unified_ring_funcs - set unified ring functions
1761  *
1762  * @adev: amdgpu_device pointer
1763  *
1764  * Set unified ring functions
1765  */
1766 static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev)
1767 {
1768         int i;
1769
1770         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1771                 if (adev->vcn.harvest_config & (1 << i))
1772                         continue;
1773
1774                 adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v4_0_unified_ring_vm_funcs;
1775                 adev->vcn.inst[i].ring_enc[0].me = i;
1776
1777                 DRM_INFO("VCN(%d) encode/decode are enabled in VM mode\n", i);
1778         }
1779 }
1780
1781 /**
1782  * vcn_v4_0_is_idle - check VCN block is idle
1783  *
1784  * @handle: amdgpu_device pointer
1785  *
1786  * Check whether VCN block is idle
1787  */
1788 static bool vcn_v4_0_is_idle(void *handle)
1789 {
1790         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1791         int i, ret = 1;
1792
1793         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1794                 if (adev->vcn.harvest_config & (1 << i))
1795                         continue;
1796
1797                 ret &= (RREG32_SOC15(VCN, i, regUVD_STATUS) == UVD_STATUS__IDLE);
1798         }
1799
1800         return ret;
1801 }
1802
1803 /**
1804  * vcn_v4_0_wait_for_idle - wait for VCN block idle
1805  *
1806  * @handle: amdgpu_device pointer
1807  *
1808  * Wait for VCN block idle
1809  */
1810 static int vcn_v4_0_wait_for_idle(void *handle)
1811 {
1812         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1813         int i, ret = 0;
1814
1815         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1816                 if (adev->vcn.harvest_config & (1 << i))
1817                         continue;
1818
1819                 ret = SOC15_WAIT_ON_RREG(VCN, i, regUVD_STATUS, UVD_STATUS__IDLE,
1820                         UVD_STATUS__IDLE);
1821                 if (ret)
1822                         return ret;
1823         }
1824
1825         return ret;
1826 }
1827
1828 /**
1829  * vcn_v4_0_set_clockgating_state - set VCN block clockgating state
1830  *
1831  * @handle: amdgpu_device pointer
1832  * @state: clock gating state
1833  *
1834  * Set VCN block clockgating state
1835  */
1836 static int vcn_v4_0_set_clockgating_state(void *handle, enum amd_clockgating_state state)
1837 {
1838         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1839         bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1840         int i;
1841
1842         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1843                 if (adev->vcn.harvest_config & (1 << i))
1844                         continue;
1845
1846                 if (enable) {
1847                         if (RREG32_SOC15(VCN, i, regUVD_STATUS) != UVD_STATUS__IDLE)
1848                                 return -EBUSY;
1849                         vcn_v4_0_enable_clock_gating(adev, i);
1850                 } else {
1851                         vcn_v4_0_disable_clock_gating(adev, i);
1852                 }
1853         }
1854
1855         return 0;
1856 }
1857
1858 /**
1859  * vcn_v4_0_set_powergating_state - set VCN block powergating state
1860  *
1861  * @handle: amdgpu_device pointer
1862  * @state: power gating state
1863  *
1864  * Set VCN block powergating state
1865  */
1866 static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_state state)
1867 {
1868         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1869         int ret;
1870
1871         /* for SRIOV, guest should not control VCN Power-gating
1872          * MMSCH FW should control Power-gating and clock-gating
1873          * guest should avoid touching CGC and PG
1874          */
1875         if (amdgpu_sriov_vf(adev)) {
1876                 adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
1877                 return 0;
1878         }
1879
1880         if(state == adev->vcn.cur_state)
1881                 return 0;
1882
1883         if (state == AMD_PG_STATE_GATE)
1884                 ret = vcn_v4_0_stop(adev);
1885         else
1886                 ret = vcn_v4_0_start(adev);
1887
1888         if(!ret)
1889                 adev->vcn.cur_state = state;
1890
1891         return ret;
1892 }
1893
1894 /**
1895  * vcn_v4_0_set_interrupt_state - set VCN block interrupt state
1896  *
1897  * @adev: amdgpu_device pointer
1898  * @source: interrupt sources
1899  * @type: interrupt types
1900  * @state: interrupt states
1901  *
1902  * Set VCN block interrupt state
1903  */
1904 static int vcn_v4_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
1905       unsigned type, enum amdgpu_interrupt_state state)
1906 {
1907         return 0;
1908 }
1909
1910 /**
1911  * vcn_v4_0_process_interrupt - process VCN block interrupt
1912  *
1913  * @adev: amdgpu_device pointer
1914  * @source: interrupt sources
1915  * @entry: interrupt entry from clients and sources
1916  *
1917  * Process VCN block interrupt
1918  */
1919 static int vcn_v4_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
1920       struct amdgpu_iv_entry *entry)
1921 {
1922         uint32_t ip_instance;
1923
1924         switch (entry->client_id) {
1925         case SOC15_IH_CLIENTID_VCN:
1926                 ip_instance = 0;
1927                 break;
1928         case SOC15_IH_CLIENTID_VCN1:
1929                 ip_instance = 1;
1930                 break;
1931         default:
1932                 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1933                 return 0;
1934         }
1935
1936         DRM_DEBUG("IH: VCN TRAP\n");
1937
1938         switch (entry->src_id) {
1939         case VCN_4_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1940                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1941                 break;
1942         default:
1943                 DRM_ERROR("Unhandled interrupt: %d %d\n",
1944                           entry->src_id, entry->src_data[0]);
1945                 break;
1946         }
1947
1948         return 0;
1949 }
1950
1951 static const struct amdgpu_irq_src_funcs vcn_v4_0_irq_funcs = {
1952         .set = vcn_v4_0_set_interrupt_state,
1953         .process = vcn_v4_0_process_interrupt,
1954 };
1955
1956 /**
1957  * vcn_v4_0_set_irq_funcs - set VCN block interrupt irq functions
1958  *
1959  * @adev: amdgpu_device pointer
1960  *
1961  * Set VCN block interrupt irq functions
1962  */
1963 static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev)
1964 {
1965         int i;
1966
1967         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1968                 if (adev->vcn.harvest_config & (1 << i))
1969                         continue;
1970
1971                 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;
1972                 adev->vcn.inst[i].irq.funcs = &vcn_v4_0_irq_funcs;
1973         }
1974 }
1975
1976 static const struct amd_ip_funcs vcn_v4_0_ip_funcs = {
1977         .name = "vcn_v4_0",
1978         .early_init = vcn_v4_0_early_init,
1979         .late_init = NULL,
1980         .sw_init = vcn_v4_0_sw_init,
1981         .sw_fini = vcn_v4_0_sw_fini,
1982         .hw_init = vcn_v4_0_hw_init,
1983         .hw_fini = vcn_v4_0_hw_fini,
1984         .suspend = vcn_v4_0_suspend,
1985         .resume = vcn_v4_0_resume,
1986         .is_idle = vcn_v4_0_is_idle,
1987         .wait_for_idle = vcn_v4_0_wait_for_idle,
1988         .check_soft_reset = NULL,
1989         .pre_soft_reset = NULL,
1990         .soft_reset = NULL,
1991         .post_soft_reset = NULL,
1992         .set_clockgating_state = vcn_v4_0_set_clockgating_state,
1993         .set_powergating_state = vcn_v4_0_set_powergating_state,
1994 };
1995
1996 const struct amdgpu_ip_block_version vcn_v4_0_ip_block =
1997 {
1998         .type = AMD_IP_BLOCK_TYPE_VCN,
1999         .major = 4,
2000         .minor = 0,
2001         .rev = 0,
2002         .funcs = &vcn_v4_0_ip_funcs,
2003 };
This page took 0.151654 seconds and 4 git commands to generate.