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