2 * Copyright 2016 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
27 #include <linux/firmware.h>
30 #include "amdgpu_vce.h"
32 #include "soc15_common.h"
33 #include "mmsch_v1_0.h"
35 #include "vce/vce_4_0_offset.h"
36 #include "vce/vce_4_0_default.h"
37 #include "vce/vce_4_0_sh_mask.h"
38 #include "mmhub/mmhub_1_0_offset.h"
39 #include "mmhub/mmhub_1_0_sh_mask.h"
41 #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
43 #define VCE_V4_0_FW_SIZE (384 * 1024)
44 #define VCE_V4_0_STACK_SIZE (64 * 1024)
45 #define VCE_V4_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
47 static void vce_v4_0_mc_resume(struct amdgpu_device
*adev
);
48 static void vce_v4_0_set_ring_funcs(struct amdgpu_device
*adev
);
49 static void vce_v4_0_set_irq_funcs(struct amdgpu_device
*adev
);
52 * vce_v4_0_ring_get_rptr - get read pointer
54 * @ring: amdgpu_ring pointer
56 * Returns the current hardware read pointer
58 static uint64_t vce_v4_0_ring_get_rptr(struct amdgpu_ring
*ring
)
60 struct amdgpu_device
*adev
= ring
->adev
;
62 if (ring
== &adev
->vce
.ring
[0])
63 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR
));
64 else if (ring
== &adev
->vce
.ring
[1])
65 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR2
));
67 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR3
));
71 * vce_v4_0_ring_get_wptr - get write pointer
73 * @ring: amdgpu_ring pointer
75 * Returns the current hardware write pointer
77 static uint64_t vce_v4_0_ring_get_wptr(struct amdgpu_ring
*ring
)
79 struct amdgpu_device
*adev
= ring
->adev
;
81 if (ring
->use_doorbell
)
82 return adev
->wb
.wb
[ring
->wptr_offs
];
84 if (ring
== &adev
->vce
.ring
[0])
85 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR
));
86 else if (ring
== &adev
->vce
.ring
[1])
87 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR2
));
89 return RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR3
));
93 * vce_v4_0_ring_set_wptr - set write pointer
95 * @ring: amdgpu_ring pointer
97 * Commits the write pointer to the hardware
99 static void vce_v4_0_ring_set_wptr(struct amdgpu_ring
*ring
)
101 struct amdgpu_device
*adev
= ring
->adev
;
103 if (ring
->use_doorbell
) {
104 /* XXX check if swapping is necessary on BE */
105 adev
->wb
.wb
[ring
->wptr_offs
] = lower_32_bits(ring
->wptr
);
106 WDOORBELL32(ring
->doorbell_index
, lower_32_bits(ring
->wptr
));
110 if (ring
== &adev
->vce
.ring
[0])
111 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR
),
112 lower_32_bits(ring
->wptr
));
113 else if (ring
== &adev
->vce
.ring
[1])
114 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR2
),
115 lower_32_bits(ring
->wptr
));
117 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR3
),
118 lower_32_bits(ring
->wptr
));
121 static int vce_v4_0_firmware_loaded(struct amdgpu_device
*adev
)
125 for (i
= 0; i
< 10; ++i
) {
126 for (j
= 0; j
< 100; ++j
) {
128 RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
));
130 if (status
& VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK
)
135 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
136 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SOFT_RESET
),
137 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
,
138 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
);
140 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SOFT_RESET
), 0,
141 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
);
149 static int vce_v4_0_mmsch_start(struct amdgpu_device
*adev
,
150 struct amdgpu_mm_table
*table
)
152 uint32_t data
= 0, loop
;
153 uint64_t addr
= table
->gpu_addr
;
154 struct mmsch_v1_0_init_header
*header
= (struct mmsch_v1_0_init_header
*)table
->cpu_addr
;
157 size
= header
->header_size
+ header
->vce_table_size
+ header
->uvd_table_size
;
159 /* 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of memory descriptor location */
160 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_CTX_ADDR_LO
), lower_32_bits(addr
));
161 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_CTX_ADDR_HI
), upper_32_bits(addr
));
163 /* 2, update vmid of descriptor */
164 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_VMID
));
165 data
&= ~VCE_MMSCH_VF_VMID__VF_CTX_VMID_MASK
;
166 data
|= (0 << VCE_MMSCH_VF_VMID__VF_CTX_VMID__SHIFT
); /* use domain0 for MM scheduler */
167 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_VMID
), data
);
169 /* 3, notify mmsch about the size of this descriptor */
170 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_CTX_SIZE
), size
);
172 /* 4, set resp to zero */
173 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_MAILBOX_RESP
), 0);
175 WDOORBELL32(adev
->vce
.ring
[0].doorbell_index
, 0);
176 adev
->wb
.wb
[adev
->vce
.ring
[0].wptr_offs
] = 0;
177 adev
->vce
.ring
[0].wptr
= 0;
178 adev
->vce
.ring
[0].wptr_old
= 0;
180 /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
181 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_MAILBOX_HOST
), 0x10000001);
183 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_MAILBOX_RESP
));
185 while ((data
& 0x10000002) != 0x10000002) {
187 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_MMSCH_VF_MAILBOX_RESP
));
194 dev_err(adev
->dev
, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data
);
201 static int vce_v4_0_sriov_start(struct amdgpu_device
*adev
)
203 struct amdgpu_ring
*ring
;
204 uint32_t offset
, size
;
205 uint32_t table_size
= 0;
206 struct mmsch_v1_0_cmd_direct_write direct_wt
= { { 0 } };
207 struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt
= { { 0 } };
208 struct mmsch_v1_0_cmd_direct_polling direct_poll
= { { 0 } };
209 struct mmsch_v1_0_cmd_end end
= { { 0 } };
210 uint32_t *init_table
= adev
->virt
.mm_table
.cpu_addr
;
211 struct mmsch_v1_0_init_header
*header
= (struct mmsch_v1_0_init_header
*)init_table
;
213 direct_wt
.cmd_header
.command_type
= MMSCH_COMMAND__DIRECT_REG_WRITE
;
214 direct_rd_mod_wt
.cmd_header
.command_type
= MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE
;
215 direct_poll
.cmd_header
.command_type
= MMSCH_COMMAND__DIRECT_REG_POLLING
;
216 end
.cmd_header
.command_type
= MMSCH_COMMAND__END
;
218 if (header
->vce_table_offset
== 0 && header
->vce_table_size
== 0) {
219 header
->version
= MMSCH_VERSION
;
220 header
->header_size
= sizeof(struct mmsch_v1_0_init_header
) >> 2;
222 if (header
->uvd_table_offset
== 0 && header
->uvd_table_size
== 0)
223 header
->vce_table_offset
= header
->header_size
;
225 header
->vce_table_offset
= header
->uvd_table_size
+ header
->uvd_table_offset
;
227 init_table
+= header
->vce_table_offset
;
229 ring
= &adev
->vce
.ring
[0];
230 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_LO
),
231 lower_32_bits(ring
->gpu_addr
));
232 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_HI
),
233 upper_32_bits(ring
->gpu_addr
));
234 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_SIZE
),
235 ring
->ring_size
/ 4);
237 /* BEGING OF MC_RESUME */
238 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CTRL
), 0x398000);
239 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CACHE_CTRL
), ~0x1, 0);
240 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_SWAP_CNTL
), 0);
241 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_SWAP_CNTL1
), 0);
242 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VM_CTRL
), 0);
244 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
245 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
246 mmVCE_LMI_VCPU_CACHE_40BIT_BAR0
),
247 adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].mc_addr
>> 8);
248 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
249 mmVCE_LMI_VCPU_CACHE_64BIT_BAR0
),
250 (adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].mc_addr
>> 40) & 0xff);
252 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
253 mmVCE_LMI_VCPU_CACHE_40BIT_BAR0
),
254 adev
->vce
.gpu_addr
>> 8);
255 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
256 mmVCE_LMI_VCPU_CACHE_64BIT_BAR0
),
257 (adev
->vce
.gpu_addr
>> 40) & 0xff);
259 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
260 mmVCE_LMI_VCPU_CACHE_40BIT_BAR1
),
261 adev
->vce
.gpu_addr
>> 8);
262 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
263 mmVCE_LMI_VCPU_CACHE_64BIT_BAR1
),
264 (adev
->vce
.gpu_addr
>> 40) & 0xff);
265 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
266 mmVCE_LMI_VCPU_CACHE_40BIT_BAR2
),
267 adev
->vce
.gpu_addr
>> 8);
268 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0,
269 mmVCE_LMI_VCPU_CACHE_64BIT_BAR2
),
270 (adev
->vce
.gpu_addr
>> 40) & 0xff);
272 offset
= AMDGPU_VCE_FIRMWARE_OFFSET
;
273 size
= VCE_V4_0_FW_SIZE
;
274 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET0
),
275 offset
& ~0x0f000000);
276 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE0
), size
);
278 offset
= (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
) ? offset
+ size
: 0;
279 size
= VCE_V4_0_STACK_SIZE
;
280 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET1
),
281 (offset
& ~0x0f000000) | (1 << 24));
282 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE1
), size
);
285 size
= VCE_V4_0_DATA_SIZE
;
286 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET2
),
287 (offset
& ~0x0f000000) | (2 << 24));
288 MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE2
), size
);
290 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CTRL2
), ~0x100, 0);
291 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SYS_INT_EN
),
292 VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
,
293 VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
);
295 /* end of MC_RESUME */
296 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
),
297 VCE_STATUS__JOB_BUSY_MASK
, ~VCE_STATUS__JOB_BUSY_MASK
);
298 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CNTL
),
299 ~0x200001, VCE_VCPU_CNTL__CLK_EN_MASK
);
300 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SOFT_RESET
),
301 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
, 0);
303 MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
),
304 VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK
,
305 VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK
);
307 /* clear BUSY flag */
308 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
),
309 ~VCE_STATUS__JOB_BUSY_MASK
, 0);
312 memcpy((void *)init_table
, &end
, sizeof(struct mmsch_v1_0_cmd_end
));
313 table_size
+= sizeof(struct mmsch_v1_0_cmd_end
) / 4;
314 header
->vce_table_size
= table_size
;
317 return vce_v4_0_mmsch_start(adev
, &adev
->virt
.mm_table
);
321 * vce_v4_0_start - start VCE block
323 * @adev: amdgpu_device pointer
325 * Setup and start the VCE block
327 static int vce_v4_0_start(struct amdgpu_device
*adev
)
329 struct amdgpu_ring
*ring
;
332 ring
= &adev
->vce
.ring
[0];
334 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR
), lower_32_bits(ring
->wptr
));
335 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR
), lower_32_bits(ring
->wptr
));
336 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_LO
), ring
->gpu_addr
);
337 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_HI
), upper_32_bits(ring
->gpu_addr
));
338 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_SIZE
), ring
->ring_size
/ 4);
340 ring
= &adev
->vce
.ring
[1];
342 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR2
), lower_32_bits(ring
->wptr
));
343 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR2
), lower_32_bits(ring
->wptr
));
344 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_LO2
), ring
->gpu_addr
);
345 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_HI2
), upper_32_bits(ring
->gpu_addr
));
346 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_SIZE2
), ring
->ring_size
/ 4);
348 ring
= &adev
->vce
.ring
[2];
350 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_RPTR3
), lower_32_bits(ring
->wptr
));
351 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_WPTR3
), lower_32_bits(ring
->wptr
));
352 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_LO3
), ring
->gpu_addr
);
353 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_BASE_HI3
), upper_32_bits(ring
->gpu_addr
));
354 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_SIZE3
), ring
->ring_size
/ 4);
356 vce_v4_0_mc_resume(adev
);
357 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
), VCE_STATUS__JOB_BUSY_MASK
,
358 ~VCE_STATUS__JOB_BUSY_MASK
);
360 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CNTL
), 1, ~0x200001);
362 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SOFT_RESET
), 0,
363 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
);
366 r
= vce_v4_0_firmware_loaded(adev
);
368 /* clear BUSY flag */
369 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
), 0, ~VCE_STATUS__JOB_BUSY_MASK
);
372 DRM_ERROR("VCE not responding, giving up!!!\n");
379 static int vce_v4_0_stop(struct amdgpu_device
*adev
)
382 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CNTL
), 0, ~0x200001);
385 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SOFT_RESET
),
386 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
,
387 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK
);
389 /* clear BUSY flag */
390 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
), 0, ~VCE_STATUS__JOB_BUSY_MASK
);
392 /* Set Clock-Gating off */
393 /* if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
394 vce_v4_0_set_vce_sw_clock_gating(adev, false);
400 static int vce_v4_0_early_init(void *handle
)
402 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
404 if (amdgpu_sriov_vf(adev
)) /* currently only VCN0 support SRIOV */
405 adev
->vce
.num_rings
= 1;
407 adev
->vce
.num_rings
= 3;
409 vce_v4_0_set_ring_funcs(adev
);
410 vce_v4_0_set_irq_funcs(adev
);
415 static int vce_v4_0_sw_init(void *handle
)
417 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
418 struct amdgpu_ring
*ring
;
422 r
= amdgpu_irq_add_id(adev
, AMDGPU_IH_CLIENTID_VCE0
, 167, &adev
->vce
.irq
);
426 size
= VCE_V4_0_STACK_SIZE
+ VCE_V4_0_DATA_SIZE
;
427 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
428 size
+= VCE_V4_0_FW_SIZE
;
430 r
= amdgpu_vce_sw_init(adev
, size
);
434 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
435 const struct common_firmware_header
*hdr
;
436 unsigned size
= amdgpu_bo_size(adev
->vce
.vcpu_bo
);
438 adev
->vce
.saved_bo
= kmalloc(size
, GFP_KERNEL
);
439 if (!adev
->vce
.saved_bo
)
442 hdr
= (const struct common_firmware_header
*)adev
->vce
.fw
->data
;
443 adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].ucode_id
= AMDGPU_UCODE_ID_VCE
;
444 adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].fw
= adev
->vce
.fw
;
445 adev
->firmware
.fw_size
+=
446 ALIGN(le32_to_cpu(hdr
->ucode_size_bytes
), PAGE_SIZE
);
447 DRM_INFO("PSP loading VCE firmware\n");
449 r
= amdgpu_vce_resume(adev
);
454 for (i
= 0; i
< adev
->vce
.num_rings
; i
++) {
455 ring
= &adev
->vce
.ring
[i
];
456 sprintf(ring
->name
, "vce%d", i
);
457 if (amdgpu_sriov_vf(adev
)) {
458 /* DOORBELL only works under SRIOV */
459 ring
->use_doorbell
= true;
461 /* currently only use the first encoding ring for sriov,
462 * so set unused location for other unused rings.
465 ring
->doorbell_index
= AMDGPU_DOORBELL64_VCE_RING0_1
* 2;
467 ring
->doorbell_index
= AMDGPU_DOORBELL64_VCE_RING2_3
* 2 + 1;
469 r
= amdgpu_ring_init(adev
, ring
, 512, &adev
->vce
.irq
, 0);
474 r
= amdgpu_virt_alloc_mm_table(adev
);
481 static int vce_v4_0_sw_fini(void *handle
)
484 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
487 amdgpu_virt_free_mm_table(adev
);
489 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
490 kfree(adev
->vce
.saved_bo
);
491 adev
->vce
.saved_bo
= NULL
;
494 r
= amdgpu_vce_suspend(adev
);
498 return amdgpu_vce_sw_fini(adev
);
501 static int vce_v4_0_hw_init(void *handle
)
504 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
506 if (amdgpu_sriov_vf(adev
))
507 r
= vce_v4_0_sriov_start(adev
);
509 r
= vce_v4_0_start(adev
);
513 for (i
= 0; i
< adev
->vce
.num_rings
; i
++)
514 adev
->vce
.ring
[i
].ready
= false;
516 for (i
= 0; i
< adev
->vce
.num_rings
; i
++) {
517 r
= amdgpu_ring_test_ring(&adev
->vce
.ring
[i
]);
521 adev
->vce
.ring
[i
].ready
= true;
524 DRM_INFO("VCE initialized successfully.\n");
529 static int vce_v4_0_hw_fini(void *handle
)
531 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
534 if (!amdgpu_sriov_vf(adev
)) {
535 /* vce_v4_0_wait_for_idle(handle); */
538 /* full access mode, so don't touch any VCE register */
539 DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
542 for (i
= 0; i
< adev
->vce
.num_rings
; i
++)
543 adev
->vce
.ring
[i
].ready
= false;
548 static int vce_v4_0_suspend(void *handle
)
550 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
553 if (adev
->vce
.vcpu_bo
== NULL
)
556 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
557 unsigned size
= amdgpu_bo_size(adev
->vce
.vcpu_bo
);
558 void *ptr
= adev
->vce
.cpu_addr
;
560 memcpy_fromio(adev
->vce
.saved_bo
, ptr
, size
);
563 r
= vce_v4_0_hw_fini(adev
);
567 return amdgpu_vce_suspend(adev
);
570 static int vce_v4_0_resume(void *handle
)
572 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
575 if (adev
->vce
.vcpu_bo
== NULL
)
578 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
579 unsigned size
= amdgpu_bo_size(adev
->vce
.vcpu_bo
);
580 void *ptr
= adev
->vce
.cpu_addr
;
582 memcpy_toio(ptr
, adev
->vce
.saved_bo
, size
);
584 r
= amdgpu_vce_resume(adev
);
589 return vce_v4_0_hw_init(adev
);
592 static void vce_v4_0_mc_resume(struct amdgpu_device
*adev
)
594 uint32_t offset
, size
;
596 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_A
), 0, ~(1 << 16));
597 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
), 0x1FF000, ~0xFF9FF000);
598 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_REG_CLOCK_GATING
), 0x3F, ~0x3F);
599 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_B
), 0x1FF);
601 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CTRL
), 0x00398000);
602 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CACHE_CTRL
), 0x0, ~0x1);
603 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_SWAP_CNTL
), 0);
604 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_SWAP_CNTL1
), 0);
605 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VM_CTRL
), 0);
607 if (adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) {
608 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR0
),
609 (adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].mc_addr
>> 8));
610 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_64BIT_BAR0
),
611 (adev
->firmware
.ucode
[AMDGPU_UCODE_ID_VCE
].mc_addr
>> 40) & 0xff);
613 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR0
),
614 (adev
->vce
.gpu_addr
>> 8));
615 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_64BIT_BAR0
),
616 (adev
->vce
.gpu_addr
>> 40) & 0xff);
619 offset
= AMDGPU_VCE_FIRMWARE_OFFSET
;
620 size
= VCE_V4_0_FW_SIZE
;
621 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET0
), offset
& ~0x0f000000);
622 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE0
), size
);
624 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR1
), (adev
->vce
.gpu_addr
>> 8));
625 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_64BIT_BAR1
), (adev
->vce
.gpu_addr
>> 40) & 0xff);
626 offset
= (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
) ? offset
+ size
: 0;
627 size
= VCE_V4_0_STACK_SIZE
;
628 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET1
), (offset
& ~0x0f000000) | (1 << 24));
629 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE1
), size
);
631 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR2
), (adev
->vce
.gpu_addr
>> 8));
632 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_VCPU_CACHE_64BIT_BAR2
), (adev
->vce
.gpu_addr
>> 40) & 0xff);
634 size
= VCE_V4_0_DATA_SIZE
;
635 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_OFFSET2
), (offset
& ~0x0f000000) | (2 << 24));
636 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_VCPU_CACHE_SIZE2
), size
);
638 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_LMI_CTRL2
), 0x0, ~0x100);
639 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SYS_INT_EN
),
640 VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
,
641 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
);
644 static int vce_v4_0_set_clockgating_state(void *handle
,
645 enum amd_clockgating_state state
)
647 /* needed for driver unload*/
652 static bool vce_v4_0_is_idle(void *handle
)
654 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
657 mask
|= (adev
->vce
.harvest_config
& AMDGPU_VCE_HARVEST_VCE0
) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK
;
658 mask
|= (adev
->vce
.harvest_config
& AMDGPU_VCE_HARVEST_VCE1
) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK
;
660 return !(RREG32(mmSRBM_STATUS2
) & mask
);
663 static int vce_v4_0_wait_for_idle(void *handle
)
666 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
668 for (i
= 0; i
< adev
->usec_timeout
; i
++)
669 if (vce_v4_0_is_idle(handle
))
675 #define VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK 0x00000008L /* AUTO_BUSY */
676 #define VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK 0x00000010L /* RB0_BUSY */
677 #define VCE_STATUS_VCPU_REPORT_RB1_BUSY_MASK 0x00000020L /* RB1_BUSY */
678 #define AMDGPU_VCE_STATUS_BUSY_MASK (VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK | \
679 VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK)
681 static bool vce_v4_0_check_soft_reset(void *handle
)
683 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
684 u32 srbm_soft_reset
= 0;
686 /* According to VCE team , we should use VCE_STATUS instead
687 * SRBM_STATUS.VCE_BUSY bit for busy status checking.
688 * GRBM_GFX_INDEX.INSTANCE_INDEX is used to specify which VCE
689 * instance's registers are accessed
690 * (0 for 1st instance, 10 for 2nd instance).
693 *|UENC|ACPI|AUTO ACTIVE|RB1 |RB0 |RB2 | |FW_LOADED|JOB |
694 *|----+----+-----------+----+----+----+----------+---------+----|
695 *|bit8|bit7| bit6 |bit5|bit4|bit3| bit2 | bit1 |bit0|
697 * VCE team suggest use bit 3--bit 6 for busy status check
699 mutex_lock(&adev
->grbm_idx_mutex
);
700 WREG32_FIELD(GRBM_GFX_INDEX
, INSTANCE_INDEX
, 0);
701 if (RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
) & AMDGPU_VCE_STATUS_BUSY_MASK
) {
702 srbm_soft_reset
= REG_SET_FIELD(srbm_soft_reset
, SRBM_SOFT_RESET
, SOFT_RESET_VCE0
, 1);
703 srbm_soft_reset
= REG_SET_FIELD(srbm_soft_reset
, SRBM_SOFT_RESET
, SOFT_RESET_VCE1
, 1);
705 WREG32_FIELD(GRBM_GFX_INDEX
, INSTANCE_INDEX
, 0x10);
706 if (RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_STATUS
) & AMDGPU_VCE_STATUS_BUSY_MASK
) {
707 srbm_soft_reset
= REG_SET_FIELD(srbm_soft_reset
, SRBM_SOFT_RESET
, SOFT_RESET_VCE0
, 1);
708 srbm_soft_reset
= REG_SET_FIELD(srbm_soft_reset
, SRBM_SOFT_RESET
, SOFT_RESET_VCE1
, 1);
710 WREG32_FIELD(GRBM_GFX_INDEX
, INSTANCE_INDEX
, 0);
711 mutex_unlock(&adev
->grbm_idx_mutex
);
713 if (srbm_soft_reset
) {
714 adev
->vce
.srbm_soft_reset
= srbm_soft_reset
;
717 adev
->vce
.srbm_soft_reset
= 0;
722 static int vce_v4_0_soft_reset(void *handle
)
724 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
727 if (!adev
->vce
.srbm_soft_reset
)
729 srbm_soft_reset
= adev
->vce
.srbm_soft_reset
;
731 if (srbm_soft_reset
) {
734 tmp
= RREG32(mmSRBM_SOFT_RESET
);
735 tmp
|= srbm_soft_reset
;
736 dev_info(adev
->dev
, "SRBM_SOFT_RESET=0x%08X\n", tmp
);
737 WREG32(mmSRBM_SOFT_RESET
, tmp
);
738 tmp
= RREG32(mmSRBM_SOFT_RESET
);
742 tmp
&= ~srbm_soft_reset
;
743 WREG32(mmSRBM_SOFT_RESET
, tmp
);
744 tmp
= RREG32(mmSRBM_SOFT_RESET
);
746 /* Wait a little for things to settle down */
753 static int vce_v4_0_pre_soft_reset(void *handle
)
755 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
757 if (!adev
->vce
.srbm_soft_reset
)
762 return vce_v4_0_suspend(adev
);
766 static int vce_v4_0_post_soft_reset(void *handle
)
768 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
770 if (!adev
->vce
.srbm_soft_reset
)
775 return vce_v4_0_resume(adev
);
778 static void vce_v4_0_override_vce_clock_gating(struct amdgpu_device
*adev
, bool override
)
782 tmp
= data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_ARB_CTRL
));
784 data
|= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK
;
786 data
&= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK
;
789 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_RB_ARB_CTRL
), data
);
792 static void vce_v4_0_set_vce_sw_clock_gating(struct amdgpu_device
*adev
,
797 /* Set Override to disable Clock Gating */
798 vce_v4_0_override_vce_clock_gating(adev
, true);
800 /* This function enables MGCG which is controlled by firmware.
801 With the clocks in the gated state the core is still
802 accessible but the firmware will throttle the clocks on the
806 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_B
));
809 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_B
), data
);
811 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
));
814 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
), data
);
816 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING_2
));
819 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING_2
), data
);
821 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_REG_CLOCK_GATING
));
823 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_REG_CLOCK_GATING
), data
);
825 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_DMA_DCLK_CTRL
));
826 data
|= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK
|
827 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK
|
828 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK
|
830 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_DMA_DCLK_CTRL
), data
);
832 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_B
));
835 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_B
), data
);
837 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
));
839 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
), data
);
841 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING_2
));
843 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING_2
), data
);
845 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_REG_CLOCK_GATING
));
847 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_REG_CLOCK_GATING
), data
);
849 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_DMA_DCLK_CTRL
));
850 data
&= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK
|
851 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK
|
852 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK
|
854 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_DMA_DCLK_CTRL
), data
);
856 vce_v4_0_override_vce_clock_gating(adev
, false);
859 static void vce_v4_0_set_bypass_mode(struct amdgpu_device
*adev
, bool enable
)
861 u32 tmp
= RREG32_SMC(ixGCK_DFS_BYPASS_CNTL
);
864 tmp
|= GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK
;
866 tmp
&= ~GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK
;
868 WREG32_SMC(ixGCK_DFS_BYPASS_CNTL
, tmp
);
871 static int vce_v4_0_set_clockgating_state(void *handle
,
872 enum amd_clockgating_state state
)
874 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
875 bool enable
= (state
== AMD_CG_STATE_GATE
) ? true : false;
878 if ((adev
->asic_type
== CHIP_POLARIS10
) ||
879 (adev
->asic_type
== CHIP_TONGA
) ||
880 (adev
->asic_type
== CHIP_FIJI
))
881 vce_v4_0_set_bypass_mode(adev
, enable
);
883 if (!(adev
->cg_flags
& AMD_CG_SUPPORT_VCE_MGCG
))
886 mutex_lock(&adev
->grbm_idx_mutex
);
887 for (i
= 0; i
< 2; i
++) {
888 /* Program VCE Instance 0 or 1 if not harvested */
889 if (adev
->vce
.harvest_config
& (1 << i
))
892 WREG32_FIELD(GRBM_GFX_INDEX
, VCE_INSTANCE
, i
);
895 /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */
896 uint32_t data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_A
);
897 data
&= ~(0xf | 0xff0);
898 data
|= ((0x0 << 0) | (0x04 << 4));
899 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_CLOCK_GATING_A
, data
);
901 /* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */
902 data
= RREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
);
903 data
&= ~(0xf | 0xff0);
904 data
|= ((0x0 << 0) | (0x04 << 4));
905 WREG32(SOC15_REG_OFFSET(VCE
, 0, mmVCE_UENC_CLOCK_GATING
, data
);
908 vce_v4_0_set_vce_sw_clock_gating(adev
, enable
);
911 WREG32_FIELD(GRBM_GFX_INDEX
, VCE_INSTANCE
, 0);
912 mutex_unlock(&adev
->grbm_idx_mutex
);
917 static int vce_v4_0_set_powergating_state(void *handle
,
918 enum amd_powergating_state state
)
920 /* This doesn't actually powergate the VCE block.
921 * That's done in the dpm code via the SMC. This
922 * just re-inits the block as necessary. The actual
923 * gating still happens in the dpm code. We should
924 * revisit this when there is a cleaner line between
925 * the smc and the hw blocks
927 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
929 if (!(adev
->pg_flags
& AMD_PG_SUPPORT_VCE
))
932 if (state
== AMD_PG_STATE_GATE
)
933 /* XXX do we need a vce_v4_0_stop()? */
936 return vce_v4_0_start(adev
);
940 static void vce_v4_0_ring_emit_ib(struct amdgpu_ring
*ring
,
941 struct amdgpu_ib
*ib
, unsigned int vmid
, bool ctx_switch
)
943 amdgpu_ring_write(ring
, VCE_CMD_IB_VM
);
944 amdgpu_ring_write(ring
, vmid
);
945 amdgpu_ring_write(ring
, lower_32_bits(ib
->gpu_addr
));
946 amdgpu_ring_write(ring
, upper_32_bits(ib
->gpu_addr
));
947 amdgpu_ring_write(ring
, ib
->length_dw
);
950 static void vce_v4_0_ring_emit_fence(struct amdgpu_ring
*ring
, u64 addr
,
951 u64 seq
, unsigned flags
)
953 WARN_ON(flags
& AMDGPU_FENCE_FLAG_64BIT
);
955 amdgpu_ring_write(ring
, VCE_CMD_FENCE
);
956 amdgpu_ring_write(ring
, addr
);
957 amdgpu_ring_write(ring
, upper_32_bits(addr
));
958 amdgpu_ring_write(ring
, seq
);
959 amdgpu_ring_write(ring
, VCE_CMD_TRAP
);
962 static void vce_v4_0_ring_insert_end(struct amdgpu_ring
*ring
)
964 amdgpu_ring_write(ring
, VCE_CMD_END
);
967 static void vce_v4_0_emit_vm_flush(struct amdgpu_ring
*ring
,
968 unsigned int vmid
, uint64_t pd_addr
)
970 struct amdgpu_vmhub
*hub
= &ring
->adev
->vmhub
[ring
->funcs
->vmhub
];
971 uint32_t req
= ring
->adev
->gart
.gart_funcs
->get_invalidate_req(vmid
);
972 uint64_t flags
= AMDGPU_PTE_VALID
;
973 unsigned eng
= ring
->vm_inv_eng
;
975 amdgpu_gart_get_vm_pde(ring
->adev
, -1, &pd_addr
, &flags
);
978 amdgpu_ring_write(ring
, VCE_CMD_REG_WRITE
);
979 amdgpu_ring_write(ring
, (hub
->ctx0_ptb_addr_hi32
+ vmid
* 2) << 2);
980 amdgpu_ring_write(ring
, upper_32_bits(pd_addr
));
982 amdgpu_ring_write(ring
, VCE_CMD_REG_WRITE
);
983 amdgpu_ring_write(ring
, (hub
->ctx0_ptb_addr_lo32
+ vmid
* 2) << 2);
984 amdgpu_ring_write(ring
, lower_32_bits(pd_addr
));
986 amdgpu_ring_write(ring
, VCE_CMD_REG_WAIT
);
987 amdgpu_ring_write(ring
, (hub
->ctx0_ptb_addr_lo32
+ vmid
* 2) << 2);
988 amdgpu_ring_write(ring
, 0xffffffff);
989 amdgpu_ring_write(ring
, lower_32_bits(pd_addr
));
992 amdgpu_ring_write(ring
, VCE_CMD_REG_WRITE
);
993 amdgpu_ring_write(ring
, (hub
->vm_inv_eng0_req
+ eng
) << 2);
994 amdgpu_ring_write(ring
, req
);
997 amdgpu_ring_write(ring
, VCE_CMD_REG_WAIT
);
998 amdgpu_ring_write(ring
, (hub
->vm_inv_eng0_ack
+ eng
) << 2);
999 amdgpu_ring_write(ring
, 1 << vmid
);
1000 amdgpu_ring_write(ring
, 1 << vmid
);
1003 static int vce_v4_0_set_interrupt_state(struct amdgpu_device
*adev
,
1004 struct amdgpu_irq_src
*source
,
1006 enum amdgpu_interrupt_state state
)
1010 if (!amdgpu_sriov_vf(adev
)) {
1011 if (state
== AMDGPU_IRQ_STATE_ENABLE
)
1012 val
|= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
;
1014 WREG32_P(SOC15_REG_OFFSET(VCE
, 0, mmVCE_SYS_INT_EN
), val
,
1015 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK
);
1020 static int vce_v4_0_process_interrupt(struct amdgpu_device
*adev
,
1021 struct amdgpu_irq_src
*source
,
1022 struct amdgpu_iv_entry
*entry
)
1024 DRM_DEBUG("IH: VCE\n");
1026 switch (entry
->src_data
[0]) {
1030 amdgpu_fence_process(&adev
->vce
.ring
[entry
->src_data
[0]]);
1033 DRM_ERROR("Unhandled interrupt: %d %d\n",
1034 entry
->src_id
, entry
->src_data
[0]);
1041 const struct amd_ip_funcs vce_v4_0_ip_funcs
= {
1043 .early_init
= vce_v4_0_early_init
,
1045 .sw_init
= vce_v4_0_sw_init
,
1046 .sw_fini
= vce_v4_0_sw_fini
,
1047 .hw_init
= vce_v4_0_hw_init
,
1048 .hw_fini
= vce_v4_0_hw_fini
,
1049 .suspend
= vce_v4_0_suspend
,
1050 .resume
= vce_v4_0_resume
,
1051 .is_idle
= NULL
/* vce_v4_0_is_idle */,
1052 .wait_for_idle
= NULL
/* vce_v4_0_wait_for_idle */,
1053 .check_soft_reset
= NULL
/* vce_v4_0_check_soft_reset */,
1054 .pre_soft_reset
= NULL
/* vce_v4_0_pre_soft_reset */,
1055 .soft_reset
= NULL
/* vce_v4_0_soft_reset */,
1056 .post_soft_reset
= NULL
/* vce_v4_0_post_soft_reset */,
1057 .set_clockgating_state
= vce_v4_0_set_clockgating_state
,
1058 .set_powergating_state
= NULL
/* vce_v4_0_set_powergating_state */,
1061 static const struct amdgpu_ring_funcs vce_v4_0_ring_vm_funcs
= {
1062 .type
= AMDGPU_RING_TYPE_VCE
,
1064 .nop
= VCE_CMD_NO_OP
,
1065 .support_64bit_ptrs
= false,
1066 .vmhub
= AMDGPU_MMHUB
,
1067 .get_rptr
= vce_v4_0_ring_get_rptr
,
1068 .get_wptr
= vce_v4_0_ring_get_wptr
,
1069 .set_wptr
= vce_v4_0_ring_set_wptr
,
1070 .parse_cs
= amdgpu_vce_ring_parse_cs_vm
,
1072 17 + /* vce_v4_0_emit_vm_flush */
1073 5 + 5 + /* amdgpu_vce_ring_emit_fence x2 vm fence */
1074 1, /* vce_v4_0_ring_insert_end */
1075 .emit_ib_size
= 5, /* vce_v4_0_ring_emit_ib */
1076 .emit_ib
= vce_v4_0_ring_emit_ib
,
1077 .emit_vm_flush
= vce_v4_0_emit_vm_flush
,
1078 .emit_fence
= vce_v4_0_ring_emit_fence
,
1079 .test_ring
= amdgpu_vce_ring_test_ring
,
1080 .test_ib
= amdgpu_vce_ring_test_ib
,
1081 .insert_nop
= amdgpu_ring_insert_nop
,
1082 .insert_end
= vce_v4_0_ring_insert_end
,
1083 .pad_ib
= amdgpu_ring_generic_pad_ib
,
1084 .begin_use
= amdgpu_vce_ring_begin_use
,
1085 .end_use
= amdgpu_vce_ring_end_use
,
1088 static void vce_v4_0_set_ring_funcs(struct amdgpu_device
*adev
)
1092 for (i
= 0; i
< adev
->vce
.num_rings
; i
++)
1093 adev
->vce
.ring
[i
].funcs
= &vce_v4_0_ring_vm_funcs
;
1094 DRM_INFO("VCE enabled in VM mode\n");
1097 static const struct amdgpu_irq_src_funcs vce_v4_0_irq_funcs
= {
1098 .set
= vce_v4_0_set_interrupt_state
,
1099 .process
= vce_v4_0_process_interrupt
,
1102 static void vce_v4_0_set_irq_funcs(struct amdgpu_device
*adev
)
1104 adev
->vce
.irq
.num_types
= 1;
1105 adev
->vce
.irq
.funcs
= &vce_v4_0_irq_funcs
;
1108 const struct amdgpu_ip_block_version vce_v4_0_ip_block
=
1110 .type
= AMD_IP_BLOCK_TYPE_VCE
,
1114 .funcs
= &vce_v4_0_ip_funcs
,