Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu/vcn: add vcn support for VCN4_0_3

Add vcn support for VCN4_0_3.

Signed-off-by: James Zhu <James.Zhu@amd.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

James Zhu and committed by
Alex Deucher
b889ef4a e684e654

+1468
+1
drivers/gpu/drm/amd/amdgpu/Makefile
··· 183 183 vcn_v2_5.o \ 184 184 vcn_v3_0.o \ 185 185 vcn_v4_0.o \ 186 + vcn_v4_0_3.o \ 186 187 amdgpu_jpeg.o \ 187 188 jpeg_v1_0.o \ 188 189 jpeg_v2_0.o \
+1438
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
··· 1 + /* 2 + * Copyright 2022 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 <drm/drm_drv.h> 26 + 27 + #include "amdgpu.h" 28 + #include "amdgpu_vcn.h" 29 + #include "amdgpu_pm.h" 30 + #include "soc15.h" 31 + #include "soc15d.h" 32 + #include "soc15_hw_ip.h" 33 + #include "vcn_v2_0.h" 34 + #include "vcn_sw_ring.h" 35 + 36 + #include "vcn/vcn_4_0_3_offset.h" 37 + #include "vcn/vcn_4_0_3_sh_mask.h" 38 + #include "ivsrcid/vcn/irqsrcs_vcn_2_0.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 + static void vcn_v4_0_3_set_dec_ring_funcs(struct amdgpu_device *adev); 49 + static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev); 50 + static int vcn_v4_0_3_set_powergating_state(void *handle, 51 + enum amd_powergating_state state); 52 + static int vcn_v4_0_3_pause_dpg_mode(struct amdgpu_device *adev, 53 + int inst_idx, struct dpg_pause_state *new_state); 54 + 55 + /** 56 + * vcn_v4_0_3_early_init - set function pointers 57 + * 58 + * @handle: amdgpu_device pointer 59 + * 60 + * Set ring and irq function pointers 61 + */ 62 + static int vcn_v4_0_3_early_init(void *handle) 63 + { 64 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 65 + 66 + vcn_v4_0_3_set_dec_ring_funcs(adev); 67 + vcn_v4_0_3_set_irq_funcs(adev); 68 + 69 + return 0; 70 + } 71 + 72 + /** 73 + * vcn_v4_0_3_sw_init - sw init for VCN block 74 + * 75 + * @handle: amdgpu_device pointer 76 + * 77 + * Load firmware and sw initialization 78 + */ 79 + static int vcn_v4_0_3_sw_init(void *handle) 80 + { 81 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 82 + volatile struct amdgpu_fw_shared *fw_shared; 83 + struct amdgpu_ring *ring; 84 + int r; 85 + 86 + r = amdgpu_vcn_sw_init(adev); 87 + if (r) 88 + return r; 89 + 90 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 91 + const struct common_firmware_header *hdr; 92 + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 93 + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN; 94 + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; 95 + adev->firmware.fw_size += 96 + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); 97 + 98 + DRM_DEV_INFO(adev->dev, "Will use PSP to load VCN firmware\n"); 99 + } 100 + 101 + r = amdgpu_vcn_resume(adev); 102 + if (r) 103 + return r; 104 + 105 + /* VCN DEC TRAP */ 106 + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 107 + VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst->irq); 108 + if (r) 109 + return r; 110 + 111 + ring = &adev->vcn.inst->ring_dec; 112 + ring->use_doorbell = false; 113 + ring->vm_hub = AMDGPU_MMHUB0(0); 114 + sprintf(ring->name, "vcn_dec"); 115 + r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0, 116 + AMDGPU_RING_PRIO_DEFAULT, 117 + &adev->vcn.inst->sched_score); 118 + if (r) 119 + return r; 120 + 121 + fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 122 + fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) | 123 + cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG) | 124 + cpu_to_le32(AMDGPU_VCN_FW_SHARED_FLAG_0_RB); 125 + fw_shared->sw_ring.is_enabled = cpu_to_le32(true); 126 + 127 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 128 + adev->vcn.pause_dpg_mode = vcn_v4_0_3_pause_dpg_mode; 129 + 130 + return 0; 131 + } 132 + 133 + /** 134 + * vcn_v4_0_3_sw_fini - sw fini for VCN block 135 + * 136 + * @handle: amdgpu_device pointer 137 + * 138 + * VCN suspend and free up sw allocation 139 + */ 140 + static int vcn_v4_0_3_sw_fini(void *handle) 141 + { 142 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 143 + int r, idx; 144 + 145 + if (drm_dev_enter(&adev->ddev, &idx)) { 146 + volatile struct amdgpu_fw_shared *fw_shared; 147 + 148 + fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 149 + fw_shared->present_flag_0 = 0; 150 + fw_shared->sw_ring.is_enabled = cpu_to_le32(false); 151 + 152 + drm_dev_exit(idx); 153 + } 154 + 155 + r = amdgpu_vcn_suspend(adev); 156 + if (r) 157 + return r; 158 + 159 + r = amdgpu_vcn_sw_fini(adev); 160 + 161 + return r; 162 + } 163 + 164 + /** 165 + * vcn_v4_0_3_hw_init - start and test VCN block 166 + * 167 + * @handle: amdgpu_device pointer 168 + * 169 + * Initialize the hardware, boot up the VCPU and do some testing 170 + */ 171 + static int vcn_v4_0_3_hw_init(void *handle) 172 + { 173 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 174 + struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; 175 + int r; 176 + 177 + r = amdgpu_ring_test_helper(ring); 178 + 179 + if (!r) 180 + DRM_DEV_INFO(adev->dev, "VCN decode initialized successfully(under %s).\n", 181 + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode"); 182 + 183 + return r; 184 + } 185 + 186 + /** 187 + * vcn_v4_0_3_hw_fini - stop the hardware block 188 + * 189 + * @handle: amdgpu_device pointer 190 + * 191 + * Stop the VCN block, mark ring as not ready any more 192 + */ 193 + static int vcn_v4_0_3_hw_fini(void *handle) 194 + { 195 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 196 + 197 + cancel_delayed_work_sync(&adev->vcn.idle_work); 198 + 199 + if (adev->vcn.cur_state != AMD_PG_STATE_GATE) 200 + vcn_v4_0_3_set_powergating_state(adev, AMD_PG_STATE_GATE); 201 + 202 + return 0; 203 + } 204 + 205 + /** 206 + * vcn_v4_0_3_suspend - suspend VCN block 207 + * 208 + * @handle: amdgpu_device pointer 209 + * 210 + * HW fini and suspend VCN block 211 + */ 212 + static int vcn_v4_0_3_suspend(void *handle) 213 + { 214 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 215 + int r; 216 + 217 + r = vcn_v4_0_3_hw_fini(adev); 218 + if (r) 219 + return r; 220 + 221 + r = amdgpu_vcn_suspend(adev); 222 + 223 + return r; 224 + } 225 + 226 + /** 227 + * vcn_v4_0_3_resume - resume VCN block 228 + * 229 + * @handle: amdgpu_device pointer 230 + * 231 + * Resume firmware and hw init VCN block 232 + */ 233 + static int vcn_v4_0_3_resume(void *handle) 234 + { 235 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 236 + int r; 237 + 238 + r = amdgpu_vcn_resume(adev); 239 + if (r) 240 + return r; 241 + 242 + r = vcn_v4_0_3_hw_init(adev); 243 + 244 + return r; 245 + } 246 + 247 + /** 248 + * vcn_v4_0_3_mc_resume - memory controller programming 249 + * 250 + * @adev: amdgpu_device pointer 251 + * 252 + * Let the VCN memory controller know it's offsets 253 + */ 254 + static void vcn_v4_0_3_mc_resume(struct amdgpu_device *adev) 255 + { 256 + uint32_t offset, size; 257 + const struct common_firmware_header *hdr; 258 + 259 + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 260 + size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 261 + 262 + /* cache window 0: fw */ 263 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 264 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 265 + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo)); 266 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 267 + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi)); 268 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_OFFSET0, 0); 269 + offset = 0; 270 + } else { 271 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, 272 + lower_32_bits(adev->vcn.inst->gpu_addr)); 273 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, 274 + upper_32_bits(adev->vcn.inst->gpu_addr)); 275 + offset = size; 276 + if (amdgpu_emu_mode == 1) 277 + /* No signed header here */ 278 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_OFFSET0, 0); 279 + else 280 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_OFFSET0, 281 + AMDGPU_UVD_FIRMWARE_OFFSET >> 3); 282 + } 283 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_SIZE0, size); 284 + 285 + /* cache window 1: stack */ 286 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, 287 + lower_32_bits(adev->vcn.inst->gpu_addr + offset)); 288 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, 289 + upper_32_bits(adev->vcn.inst->gpu_addr + offset)); 290 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_OFFSET1, 0); 291 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE); 292 + 293 + /* cache window 2: context */ 294 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, 295 + lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 296 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, 297 + upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE)); 298 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_OFFSET2, 0); 299 + WREG32_SOC15(VCN, 0, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE); 300 + 301 + /* non-cache window */ 302 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW, 303 + lower_32_bits(adev->vcn.inst->fw_shared.gpu_addr)); 304 + WREG32_SOC15(VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH, 305 + upper_32_bits(adev->vcn.inst->fw_shared.gpu_addr)); 306 + WREG32_SOC15(VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0, 0); 307 + WREG32_SOC15(VCN, 0, regUVD_VCPU_NONCACHE_SIZE0, 308 + AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared))); 309 + } 310 + 311 + /** 312 + * vcn_v4_0_mc_resume_dpg_mode - memory controller programming for dpg mode 313 + * 314 + * @adev: amdgpu_device pointer 315 + * @indirect: indirectly write sram 316 + * 317 + * Let the VCN memory controller know it's offsets with dpg mode 318 + */ 319 + static void vcn_v4_0_3_mc_resume_dpg_mode(struct amdgpu_device *adev, bool indirect) 320 + { 321 + uint32_t offset, size; 322 + const struct common_firmware_header *hdr; 323 + 324 + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 325 + size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 326 + 327 + /* cache window 0: fw */ 328 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 329 + if (!indirect) { 330 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 331 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 332 + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo), 0, indirect); 333 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 334 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 335 + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi), 0, indirect); 336 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 337 + VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 338 + } else { 339 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 340 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect); 341 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 342 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect); 343 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 344 + VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect); 345 + } 346 + offset = 0; 347 + } else { 348 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 349 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 350 + lower_32_bits(adev->vcn.inst->gpu_addr), 0, indirect); 351 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 352 + VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 353 + upper_32_bits(adev->vcn.inst->gpu_addr), 0, indirect); 354 + offset = size; 355 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 356 + VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 357 + 0, 0, indirect); 358 + } 359 + 360 + if (!indirect) 361 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 362 + VCN, 0, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect); 363 + else 364 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 365 + VCN, 0, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect); 366 + 367 + /* cache window 1: stack */ 368 + if (!indirect) { 369 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 370 + VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 371 + lower_32_bits(adev->vcn.inst->gpu_addr + offset), 0, indirect); 372 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 373 + VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 374 + upper_32_bits(adev->vcn.inst->gpu_addr + offset), 0, indirect); 375 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 376 + VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 377 + } else { 378 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 379 + VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect); 380 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 381 + VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect); 382 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 383 + VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect); 384 + } 385 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 386 + VCN, 0, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect); 387 + 388 + /* cache window 2: context */ 389 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 390 + VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), 391 + lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 392 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 393 + VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), 394 + upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect); 395 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 396 + VCN, 0, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect); 397 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 398 + VCN, 0, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect); 399 + 400 + /* non-cache window */ 401 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 402 + VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 403 + lower_32_bits(adev->vcn.inst->fw_shared.gpu_addr), 0, indirect); 404 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 405 + VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 406 + upper_32_bits(adev->vcn.inst->fw_shared.gpu_addr), 0, indirect); 407 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 408 + VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect); 409 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 410 + VCN, 0, regUVD_VCPU_NONCACHE_SIZE0), 411 + AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect); 412 + 413 + /* VCN global tiling registers */ 414 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 415 + VCN, 0, regUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 416 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 417 + VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect); 418 + } 419 + 420 + /** 421 + * vcn_v4_0_disable_static_power_gating - disable VCN static power gating 422 + * 423 + * @adev: amdgpu_device pointer 424 + * 425 + * Disable static power gating for VCN block 426 + */ 427 + static void vcn_v4_0_3_disable_static_power_gating(struct amdgpu_device *adev) 428 + { 429 + uint32_t data = 0; 430 + 431 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 432 + data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 433 + | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 434 + | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 435 + | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 436 + | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 437 + | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 438 + | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 439 + | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 440 + | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 441 + | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 442 + | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 443 + | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 444 + | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 445 + | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 446 + 447 + WREG32_SOC15(VCN, 0, regUVD_PGFSM_CONFIG, data); 448 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_PGFSM_STATUS, 449 + UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0, 0x3F3FFFFF); 450 + } else { 451 + data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 452 + | 1 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 453 + | 1 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 454 + | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 455 + | 1 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 456 + | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 457 + | 1 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 458 + | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 459 + | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 460 + | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 461 + | 1 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 462 + | 1 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 463 + | 1 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 464 + | 1 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 465 + 466 + WREG32_SOC15(VCN, 0, regUVD_PGFSM_CONFIG, data); 467 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_PGFSM_STATUS, 0, 0x3F3FFFFF); 468 + } 469 + 470 + data = RREG32_SOC15(VCN, 0, regUVD_POWER_STATUS); 471 + data &= ~0x103; 472 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN) 473 + data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | 474 + UVD_POWER_STATUS__UVD_PG_EN_MASK; 475 + 476 + WREG32_SOC15(VCN, 0, regUVD_POWER_STATUS, data); 477 + } 478 + 479 + /** 480 + * vcn_v4_0_3_enable_static_power_gating - enable VCN static power gating 481 + * 482 + * @adev: amdgpu_device pointer 483 + * 484 + * Enable static power gating for VCN block 485 + */ 486 + static void vcn_v4_0_3_enable_static_power_gating(struct amdgpu_device *adev) 487 + { 488 + uint32_t data; 489 + 490 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { 491 + /* Before power off, this indicator has to be turned on */ 492 + data = RREG32_SOC15(VCN, 0, regUVD_POWER_STATUS); 493 + data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK; 494 + data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; 495 + WREG32_SOC15(VCN, 0, regUVD_POWER_STATUS, data); 496 + 497 + data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT 498 + | 2 << UVD_PGFSM_CONFIG__UVDS_PWR_CONFIG__SHIFT 499 + | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT 500 + | 2 << UVD_PGFSM_CONFIG__UVDTC_PWR_CONFIG__SHIFT 501 + | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT 502 + | 2 << UVD_PGFSM_CONFIG__UVDTA_PWR_CONFIG__SHIFT 503 + | 2 << UVD_PGFSM_CONFIG__UVDLM_PWR_CONFIG__SHIFT 504 + | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT 505 + | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT 506 + | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT 507 + | 2 << UVD_PGFSM_CONFIG__UVDAB_PWR_CONFIG__SHIFT 508 + | 2 << UVD_PGFSM_CONFIG__UVDTB_PWR_CONFIG__SHIFT 509 + | 2 << UVD_PGFSM_CONFIG__UVDNA_PWR_CONFIG__SHIFT 510 + | 2 << UVD_PGFSM_CONFIG__UVDNB_PWR_CONFIG__SHIFT); 511 + WREG32_SOC15(VCN, 0, regUVD_PGFSM_CONFIG, data); 512 + 513 + data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT 514 + | 2 << UVD_PGFSM_STATUS__UVDS_PWR_STATUS__SHIFT 515 + | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT 516 + | 2 << UVD_PGFSM_STATUS__UVDTC_PWR_STATUS__SHIFT 517 + | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT 518 + | 2 << UVD_PGFSM_STATUS__UVDTA_PWR_STATUS__SHIFT 519 + | 2 << UVD_PGFSM_STATUS__UVDLM_PWR_STATUS__SHIFT 520 + | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT 521 + | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT 522 + | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT 523 + | 2 << UVD_PGFSM_STATUS__UVDAB_PWR_STATUS__SHIFT 524 + | 2 << UVD_PGFSM_STATUS__UVDTB_PWR_STATUS__SHIFT 525 + | 2 << UVD_PGFSM_STATUS__UVDNA_PWR_STATUS__SHIFT 526 + | 2 << UVD_PGFSM_STATUS__UVDNB_PWR_STATUS__SHIFT); 527 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_PGFSM_STATUS, data, 0x3F3FFFFF); 528 + } 529 + } 530 + 531 + /** 532 + * vcn_v4_0_3_disable_clock_gating - disable VCN clock gating 533 + * 534 + * @adev: amdgpu_device pointer 535 + * 536 + * Disable clock gating for VCN block 537 + */ 538 + static void vcn_v4_0_3_disable_clock_gating(struct amdgpu_device *adev) 539 + { 540 + uint32_t data; 541 + 542 + /* VCN disable CGC */ 543 + data = RREG32_SOC15(VCN, 0, regUVD_CGC_CTRL); 544 + if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 545 + data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 546 + else 547 + data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; 548 + data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 549 + data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 550 + WREG32_SOC15(VCN, 0, regUVD_CGC_CTRL, data); 551 + 552 + data = RREG32_SOC15(VCN, 0, regUVD_CGC_GATE); 553 + data &= ~(UVD_CGC_GATE__SYS_MASK 554 + | UVD_CGC_GATE__MPEG2_MASK 555 + | UVD_CGC_GATE__REGS_MASK 556 + | UVD_CGC_GATE__RBC_MASK 557 + | UVD_CGC_GATE__LMI_MC_MASK 558 + | UVD_CGC_GATE__LMI_UMC_MASK 559 + | UVD_CGC_GATE__MPC_MASK 560 + | UVD_CGC_GATE__LBSI_MASK 561 + | UVD_CGC_GATE__LRBBM_MASK 562 + | UVD_CGC_GATE__WCB_MASK 563 + | UVD_CGC_GATE__VCPU_MASK 564 + | UVD_CGC_GATE__MMSCH_MASK); 565 + 566 + WREG32_SOC15(VCN, 0, regUVD_CGC_GATE, data); 567 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_CGC_GATE, 0, 0xFFFFFFFF); 568 + 569 + data = RREG32_SOC15(VCN, 0, regUVD_CGC_CTRL); 570 + data &= ~(UVD_CGC_CTRL__SYS_MODE_MASK 571 + | UVD_CGC_CTRL__MPEG2_MODE_MASK 572 + | UVD_CGC_CTRL__REGS_MODE_MASK 573 + | UVD_CGC_CTRL__RBC_MODE_MASK 574 + | UVD_CGC_CTRL__LMI_MC_MODE_MASK 575 + | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 576 + | UVD_CGC_CTRL__MPC_MODE_MASK 577 + | UVD_CGC_CTRL__LBSI_MODE_MASK 578 + | UVD_CGC_CTRL__LRBBM_MODE_MASK 579 + | UVD_CGC_CTRL__WCB_MODE_MASK 580 + | UVD_CGC_CTRL__VCPU_MODE_MASK 581 + | UVD_CGC_CTRL__MMSCH_MODE_MASK); 582 + WREG32_SOC15(VCN, 0, regUVD_CGC_CTRL, data); 583 + 584 + data = RREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_GATE); 585 + data |= (UVD_SUVD_CGC_GATE__SRE_MASK 586 + | UVD_SUVD_CGC_GATE__SIT_MASK 587 + | UVD_SUVD_CGC_GATE__SMP_MASK 588 + | UVD_SUVD_CGC_GATE__SCM_MASK 589 + | UVD_SUVD_CGC_GATE__SDB_MASK 590 + | UVD_SUVD_CGC_GATE__SRE_H264_MASK 591 + | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK 592 + | UVD_SUVD_CGC_GATE__SIT_H264_MASK 593 + | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK 594 + | UVD_SUVD_CGC_GATE__SCM_H264_MASK 595 + | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK 596 + | UVD_SUVD_CGC_GATE__SDB_H264_MASK 597 + | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK 598 + | UVD_SUVD_CGC_GATE__ENT_MASK 599 + | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK 600 + | UVD_SUVD_CGC_GATE__SITE_MASK 601 + | UVD_SUVD_CGC_GATE__SRE_VP9_MASK 602 + | UVD_SUVD_CGC_GATE__SCM_VP9_MASK 603 + | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK 604 + | UVD_SUVD_CGC_GATE__SDB_VP9_MASK 605 + | UVD_SUVD_CGC_GATE__IME_HEVC_MASK); 606 + WREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_GATE, data); 607 + 608 + data = RREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_CTRL); 609 + data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 610 + | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 611 + | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 612 + | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 613 + | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 614 + | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 615 + | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 616 + | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 617 + WREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_CTRL, data); 618 + } 619 + 620 + /** 621 + * vcn_v4_0_3_disable_clock_gating_dpg_mode - disable VCN clock gating dpg mode 622 + * 623 + * @adev: amdgpu_device pointer 624 + * @sram_sel: sram select 625 + * @indirect: indirectly write sram 626 + * 627 + * Disable clock gating for VCN block with dpg mode 628 + */ 629 + static void vcn_v4_0_3_disable_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel, 630 + uint8_t indirect) 631 + { 632 + uint32_t reg_data = 0; 633 + 634 + /* enable sw clock gating control */ 635 + if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 636 + reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 637 + else 638 + reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 639 + reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 640 + reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 641 + reg_data &= ~(UVD_CGC_CTRL__SYS_MODE_MASK | 642 + UVD_CGC_CTRL__MPEG2_MODE_MASK | 643 + UVD_CGC_CTRL__REGS_MODE_MASK | 644 + UVD_CGC_CTRL__RBC_MODE_MASK | 645 + UVD_CGC_CTRL__LMI_MC_MODE_MASK | 646 + UVD_CGC_CTRL__LMI_UMC_MODE_MASK | 647 + UVD_CGC_CTRL__IDCT_MODE_MASK | 648 + UVD_CGC_CTRL__MPRD_MODE_MASK | 649 + UVD_CGC_CTRL__MPC_MODE_MASK | 650 + UVD_CGC_CTRL__LBSI_MODE_MASK | 651 + UVD_CGC_CTRL__LRBBM_MODE_MASK | 652 + UVD_CGC_CTRL__WCB_MODE_MASK | 653 + UVD_CGC_CTRL__VCPU_MODE_MASK); 654 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 655 + VCN, 0, regUVD_CGC_CTRL), reg_data, sram_sel, indirect); 656 + 657 + /* turn off clock gating */ 658 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 659 + VCN, 0, regUVD_CGC_GATE), 0, sram_sel, indirect); 660 + 661 + /* turn on SUVD clock gating */ 662 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 663 + VCN, 0, regUVD_SUVD_CGC_GATE), 1, sram_sel, indirect); 664 + 665 + /* turn on sw mode in UVD_SUVD_CGC_CTRL */ 666 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 667 + VCN, 0, regUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect); 668 + } 669 + 670 + /** 671 + * vcn_v4_0_enable_clock_gating - enable VCN clock gating 672 + * 673 + * @adev: amdgpu_device pointer 674 + * 675 + * Enable clock gating for VCN block 676 + */ 677 + static void vcn_v4_0_3_enable_clock_gating(struct amdgpu_device *adev) 678 + { 679 + uint32_t data; 680 + 681 + /* enable VCN CGC */ 682 + data = RREG32_SOC15(VCN, 0, regUVD_CGC_CTRL); 683 + if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) 684 + data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 685 + else 686 + data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 687 + data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 688 + data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 689 + WREG32_SOC15(VCN, 0, regUVD_CGC_CTRL, data); 690 + 691 + data = RREG32_SOC15(VCN, 0, regUVD_CGC_CTRL); 692 + data |= (UVD_CGC_CTRL__SYS_MODE_MASK 693 + | UVD_CGC_CTRL__MPEG2_MODE_MASK 694 + | UVD_CGC_CTRL__REGS_MODE_MASK 695 + | UVD_CGC_CTRL__RBC_MODE_MASK 696 + | UVD_CGC_CTRL__LMI_MC_MODE_MASK 697 + | UVD_CGC_CTRL__LMI_UMC_MODE_MASK 698 + | UVD_CGC_CTRL__MPC_MODE_MASK 699 + | UVD_CGC_CTRL__LBSI_MODE_MASK 700 + | UVD_CGC_CTRL__LRBBM_MODE_MASK 701 + | UVD_CGC_CTRL__WCB_MODE_MASK 702 + | UVD_CGC_CTRL__VCPU_MODE_MASK); 703 + WREG32_SOC15(VCN, 0, regUVD_CGC_CTRL, data); 704 + 705 + data = RREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_CTRL); 706 + data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK 707 + | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK 708 + | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK 709 + | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK 710 + | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK 711 + | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK 712 + | UVD_SUVD_CGC_CTRL__IME_MODE_MASK 713 + | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK); 714 + WREG32_SOC15(VCN, 0, regUVD_SUVD_CGC_CTRL, data); 715 + } 716 + 717 + /** 718 + * vcn_v4_0_3_start_dpg_mode - VCN start with dpg mode 719 + * 720 + * @adev: amdgpu_device pointer 721 + * @indirect: indirectly write sram 722 + * 723 + * Start VCN block with dpg mode 724 + */ 725 + static int vcn_v4_0_3_start_dpg_mode(struct amdgpu_device *adev, bool indirect) 726 + { 727 + volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 728 + struct amdgpu_ring *ring; 729 + uint32_t tmp; 730 + 731 + /* disable register anti-hang mechanism */ 732 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_POWER_STATUS), 1, 733 + ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 734 + /* enable dynamic power gating mode */ 735 + tmp = RREG32_SOC15(VCN, 0, regUVD_POWER_STATUS); 736 + tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK; 737 + tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK; 738 + WREG32_SOC15(VCN, 0, regUVD_POWER_STATUS, tmp); 739 + 740 + if (indirect) 741 + adev->vcn.inst->dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst->dpg_sram_cpu_addr; 742 + 743 + /* enable clock gating */ 744 + vcn_v4_0_3_disable_clock_gating_dpg_mode(adev, 0, indirect); 745 + 746 + /* enable VCPU clock */ 747 + tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 748 + tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 749 + tmp |= UVD_VCPU_CNTL__BLK_RST_MASK; 750 + 751 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 752 + VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 753 + 754 + /* disable master interrupt */ 755 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 756 + VCN, 0, regUVD_MASTINT_EN), 0, 0, indirect); 757 + 758 + /* setup regUVD_LMI_CTRL */ 759 + tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 760 + UVD_LMI_CTRL__REQ_MODE_MASK | 761 + UVD_LMI_CTRL__CRC_RESET_MASK | 762 + UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 763 + UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 764 + UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | 765 + (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | 766 + 0x00100000L); 767 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 768 + VCN, 0, regUVD_LMI_CTRL), tmp, 0, indirect); 769 + 770 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 771 + VCN, 0, regUVD_MPC_CNTL), 772 + 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect); 773 + 774 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 775 + VCN, 0, regUVD_MPC_SET_MUXA0), 776 + ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 777 + (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 778 + (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 779 + (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect); 780 + 781 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 782 + VCN, 0, regUVD_MPC_SET_MUXB0), 783 + ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 784 + (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 785 + (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 786 + (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect); 787 + 788 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 789 + VCN, 0, regUVD_MPC_SET_MUX), 790 + ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 791 + (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 792 + (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect); 793 + 794 + vcn_v4_0_3_mc_resume_dpg_mode(adev, indirect); 795 + 796 + tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT); 797 + tmp |= UVD_VCPU_CNTL__CLK_EN_MASK; 798 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 799 + VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect); 800 + 801 + /* enable LMI MC and UMC channels */ 802 + tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT; 803 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 804 + VCN, 0, regUVD_LMI_CTRL2), tmp, 0, indirect); 805 + 806 + /* enable master interrupt */ 807 + WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET( 808 + VCN, 0, regUVD_MASTINT_EN), 809 + UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect); 810 + 811 + if (indirect) 812 + psp_update_vcn_sram(adev, 0, adev->vcn.inst->dpg_sram_gpu_addr, 813 + (uint32_t)((uintptr_t)adev->vcn.inst->dpg_sram_curr_addr - 814 + (uintptr_t)adev->vcn.inst->dpg_sram_cpu_addr)); 815 + 816 + ring = &adev->vcn.inst->ring_dec; 817 + fw_shared->multi_queue.decode_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET); 818 + 819 + /* program the RB_BASE for ring buffer */ 820 + WREG32_SOC15(VCN, 0, regUVD_RB_BASE_LO4, 821 + lower_32_bits(ring->gpu_addr)); 822 + WREG32_SOC15(VCN, 0, regUVD_RB_BASE_HI4, 823 + upper_32_bits(ring->gpu_addr)); 824 + 825 + WREG32_SOC15(VCN, 0, regUVD_RB_SIZE4, ring->ring_size / sizeof(uint32_t)); 826 + 827 + /* resetting ring, fw should not check RB ring */ 828 + tmp = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE); 829 + tmp &= ~(VCN_RB_ENABLE__RB4_EN_MASK); 830 + WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, tmp); 831 + 832 + /* Initialize the ring buffer's read and write pointers */ 833 + WREG32_SOC15(VCN, 0, regUVD_RB_RPTR4, 0); 834 + WREG32_SOC15(VCN, 0, regUVD_RB_WPTR4, 0); 835 + ring->wptr = RREG32_SOC15(VCN, 0, regUVD_RB_WPTR4); 836 + 837 + tmp = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE); 838 + tmp |= VCN_RB_ENABLE__RB4_EN_MASK; 839 + WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, tmp); 840 + 841 + WREG32_SOC15(VCN, 0, regUVD_SCRATCH2, 0); 842 + 843 + /* Reset FW shared memory RBC WPTR/RPTR */ 844 + fw_shared->rb.rptr = 0; 845 + fw_shared->rb.wptr = lower_32_bits(ring->wptr); 846 + 847 + /*resetting done, fw can check RB ring */ 848 + fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); 849 + 850 + return 0; 851 + } 852 + 853 + /** 854 + * vcn_v4_0_3_start - VCN start 855 + * 856 + * @adev: amdgpu_device pointer 857 + * 858 + * Start VCN block 859 + */ 860 + static int vcn_v4_0_3_start(struct amdgpu_device *adev) 861 + { 862 + volatile struct amdgpu_fw_shared *fw_shared; 863 + struct amdgpu_ring *ring; 864 + uint32_t tmp; 865 + int j, k, r; 866 + 867 + if (adev->pm.dpm_enabled) 868 + amdgpu_dpm_enable_uvd(adev, true); 869 + 870 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) 871 + return vcn_v4_0_3_start_dpg_mode(adev, adev->vcn.indirect_sram); 872 + 873 + /* disable VCN power gating */ 874 + vcn_v4_0_3_disable_static_power_gating(adev); 875 + 876 + /* set VCN status busy */ 877 + tmp = RREG32_SOC15(VCN, 0, regUVD_STATUS) | UVD_STATUS__UVD_BUSY; 878 + WREG32_SOC15(VCN, 0, regUVD_STATUS, tmp); 879 + 880 + /*SW clock gating */ 881 + vcn_v4_0_3_disable_clock_gating(adev); 882 + 883 + /* enable VCPU clock */ 884 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 885 + UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK); 886 + 887 + /* disable master interrupt */ 888 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_MASTINT_EN), 0, 889 + ~UVD_MASTINT_EN__VCPU_EN_MASK); 890 + 891 + /* enable LMI MC and UMC channels */ 892 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_LMI_CTRL2), 0, 893 + ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 894 + 895 + tmp = RREG32_SOC15(VCN, 0, regUVD_SOFT_RESET); 896 + tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 897 + tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 898 + WREG32_SOC15(VCN, 0, regUVD_SOFT_RESET, tmp); 899 + 900 + /* setup regUVD_LMI_CTRL */ 901 + tmp = RREG32_SOC15(VCN, 0, regUVD_LMI_CTRL); 902 + WREG32_SOC15(VCN, 0, regUVD_LMI_CTRL, tmp | 903 + UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | 904 + UVD_LMI_CTRL__MASK_MC_URGENT_MASK | 905 + UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | 906 + UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK); 907 + 908 + /* setup regUVD_MPC_CNTL */ 909 + tmp = RREG32_SOC15(VCN, 0, regUVD_MPC_CNTL); 910 + tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK; 911 + tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT; 912 + WREG32_SOC15(VCN, 0, regUVD_MPC_CNTL, tmp); 913 + 914 + /* setup UVD_MPC_SET_MUXA0 */ 915 + WREG32_SOC15(VCN, 0, regUVD_MPC_SET_MUXA0, 916 + ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) | 917 + (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) | 918 + (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) | 919 + (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT))); 920 + 921 + /* setup UVD_MPC_SET_MUXB0 */ 922 + WREG32_SOC15(VCN, 0, regUVD_MPC_SET_MUXB0, 923 + ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) | 924 + (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) | 925 + (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) | 926 + (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT))); 927 + 928 + /* setup UVD_MPC_SET_MUX */ 929 + WREG32_SOC15(VCN, 0, regUVD_MPC_SET_MUX, 930 + ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) | 931 + (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) | 932 + (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT))); 933 + 934 + vcn_v4_0_3_mc_resume(adev); 935 + 936 + /* VCN global tiling registers */ 937 + WREG32_SOC15(VCN, 0, regUVD_GFX8_ADDR_CONFIG, 938 + adev->gfx.config.gb_addr_config); 939 + WREG32_SOC15(VCN, 0, regUVD_GFX10_ADDR_CONFIG, 940 + adev->gfx.config.gb_addr_config); 941 + 942 + /* unblock VCPU register access */ 943 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_RB_ARB_CTRL), 0, 944 + ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 945 + 946 + /* release VCPU reset to boot */ 947 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 0, 948 + ~UVD_VCPU_CNTL__BLK_RST_MASK); 949 + 950 + for (j = 0; j < 10; ++j) { 951 + uint32_t status; 952 + 953 + for (k = 0; k < 100; ++k) { 954 + status = RREG32_SOC15(VCN, 0, regUVD_STATUS); 955 + if (status & 2) 956 + break; 957 + if (amdgpu_emu_mode == 1) 958 + msleep(500); 959 + else 960 + mdelay(10); 961 + } 962 + r = 0; 963 + if (status & 2) 964 + break; 965 + 966 + DRM_DEV_ERROR(adev->dev, 967 + "VCN decode not responding, trying to reset the VCPU!!!\n"); 968 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 969 + UVD_VCPU_CNTL__BLK_RST_MASK, 970 + ~UVD_VCPU_CNTL__BLK_RST_MASK); 971 + mdelay(10); 972 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 0, 973 + ~UVD_VCPU_CNTL__BLK_RST_MASK); 974 + 975 + mdelay(10); 976 + r = -1; 977 + } 978 + 979 + if (r) { 980 + DRM_DEV_ERROR(adev->dev, "VCN decode not responding, giving up!!!\n"); 981 + return r; 982 + } 983 + 984 + /* enable master interrupt */ 985 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_MASTINT_EN), 986 + UVD_MASTINT_EN__VCPU_EN_MASK, 987 + ~UVD_MASTINT_EN__VCPU_EN_MASK); 988 + 989 + /* clear the busy bit of VCN_STATUS */ 990 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS), 0, 991 + ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 992 + 993 + ring = &adev->vcn.inst->ring_dec; 994 + 995 + fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 996 + fw_shared->multi_queue.decode_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET); 997 + 998 + /* program the RB_BASE for ring buffer */ 999 + WREG32_SOC15(VCN, 0, regUVD_RB_BASE_LO4, 1000 + lower_32_bits(ring->gpu_addr)); 1001 + WREG32_SOC15(VCN, 0, regUVD_RB_BASE_HI4, 1002 + upper_32_bits(ring->gpu_addr)); 1003 + 1004 + WREG32_SOC15(VCN, 0, regUVD_RB_SIZE4, ring->ring_size / sizeof(uint32_t)); 1005 + 1006 + /* resetting ring, fw should not check RB ring */ 1007 + tmp = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE); 1008 + tmp &= ~(VCN_RB_ENABLE__RB4_EN_MASK); 1009 + WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, tmp); 1010 + 1011 + /* Initialize the ring buffer's read and write pointers */ 1012 + WREG32_SOC15(VCN, 0, regUVD_RB_RPTR4, 0); 1013 + WREG32_SOC15(VCN, 0, regUVD_RB_WPTR4, 0); 1014 + 1015 + tmp = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE); 1016 + tmp |= VCN_RB_ENABLE__RB4_EN_MASK; 1017 + WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, tmp); 1018 + 1019 + ring->wptr = RREG32_SOC15(VCN, 0, regUVD_RB_WPTR4); 1020 + fw_shared->rb.wptr = cpu_to_le32(lower_32_bits(ring->wptr)); 1021 + fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); 1022 + 1023 + return 0; 1024 + } 1025 + 1026 + /** 1027 + * vcn_v4_0_3_stop_dpg_mode - VCN stop with dpg mode 1028 + * 1029 + * @adev: amdgpu_device pointer 1030 + * 1031 + * Stop VCN block with dpg mode 1032 + */ 1033 + static int vcn_v4_0_3_stop_dpg_mode(struct amdgpu_device *adev) 1034 + { 1035 + uint32_t tmp; 1036 + 1037 + /* Wait for power status to be 1 */ 1038 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_POWER_STATUS, 1, 1039 + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1040 + 1041 + /* wait for read ptr to be equal to write ptr */ 1042 + tmp = RREG32_SOC15(VCN, 0, regUVD_RB_WPTR); 1043 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_RB_RPTR, tmp, 0xFFFFFFFF); 1044 + 1045 + tmp = RREG32_SOC15(VCN, 0, regUVD_RB_WPTR2); 1046 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_RB_RPTR2, tmp, 0xFFFFFFFF); 1047 + 1048 + tmp = RREG32_SOC15(VCN, 0, regUVD_RB_WPTR4); 1049 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_RB_RPTR4, tmp, 0xFFFFFFFF); 1050 + 1051 + SOC15_WAIT_ON_RREG(VCN, 0, regUVD_POWER_STATUS, 1, 1052 + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 1053 + 1054 + /* disable dynamic power gating mode */ 1055 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_POWER_STATUS), 0, 1056 + ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); 1057 + return 0; 1058 + } 1059 + 1060 + /** 1061 + * vcn_v4_0_3_stop - VCN stop 1062 + * 1063 + * @adev: amdgpu_device pointer 1064 + * 1065 + * Stop VCN block 1066 + */ 1067 + static int vcn_v4_0_3_stop(struct amdgpu_device *adev) 1068 + { 1069 + uint32_t tmp; 1070 + int r = 0; 1071 + 1072 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1073 + r = vcn_v4_0_3_stop_dpg_mode(adev); 1074 + goto Done; 1075 + } 1076 + 1077 + /* wait for vcn idle */ 1078 + r = SOC15_WAIT_ON_RREG(VCN, 0, regUVD_STATUS, UVD_STATUS__IDLE, 0x7); 1079 + if (r) 1080 + return r; 1081 + 1082 + tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK | 1083 + UVD_LMI_STATUS__READ_CLEAN_MASK | 1084 + UVD_LMI_STATUS__WRITE_CLEAN_MASK | 1085 + UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK; 1086 + r = SOC15_WAIT_ON_RREG(VCN, 0, regUVD_LMI_STATUS, tmp, tmp); 1087 + if (r) 1088 + return r; 1089 + 1090 + /* stall UMC channel */ 1091 + tmp = RREG32_SOC15(VCN, 0, regUVD_LMI_CTRL2); 1092 + tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK; 1093 + WREG32_SOC15(VCN, 0, regUVD_LMI_CTRL2, tmp); 1094 + tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK| 1095 + UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK; 1096 + r = SOC15_WAIT_ON_RREG(VCN, 0, regUVD_LMI_STATUS, tmp, tmp); 1097 + if (r) 1098 + return r; 1099 + 1100 + /* Unblock VCPU Register access */ 1101 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_RB_ARB_CTRL), 1102 + UVD_RB_ARB_CTRL__VCPU_DIS_MASK, 1103 + ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK); 1104 + 1105 + /* release VCPU reset to boot */ 1106 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 1107 + UVD_VCPU_CNTL__BLK_RST_MASK, 1108 + ~UVD_VCPU_CNTL__BLK_RST_MASK); 1109 + 1110 + /* disable VCPU clock */ 1111 + WREG32_P(SOC15_REG_OFFSET(VCN, 0, regUVD_VCPU_CNTL), 0, 1112 + ~(UVD_VCPU_CNTL__CLK_EN_MASK)); 1113 + 1114 + /* reset LMI UMC/LMI/VCPU */ 1115 + tmp = RREG32_SOC15(VCN, 0, regUVD_SOFT_RESET); 1116 + tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK; 1117 + WREG32_SOC15(VCN, 0, regUVD_SOFT_RESET, tmp); 1118 + 1119 + tmp = RREG32_SOC15(VCN, 0, regUVD_SOFT_RESET); 1120 + tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK; 1121 + WREG32_SOC15(VCN, 0, regUVD_SOFT_RESET, tmp); 1122 + 1123 + tmp = RREG32_SOC15(VCN, 0, regUVD_VCPU_CNTL); 1124 + tmp |= UVD_VCPU_CNTL__BLK_RST_MASK; 1125 + WREG32_SOC15(VCN, 0, regUVD_SOFT_RESET, tmp); 1126 + 1127 + /* clear VCN status */ 1128 + WREG32_SOC15(VCN, 0, regUVD_STATUS, 0); 1129 + 1130 + /* apply HW clock gating */ 1131 + vcn_v4_0_3_enable_clock_gating(adev); 1132 + 1133 + /* enable VCN power gating */ 1134 + vcn_v4_0_3_enable_static_power_gating(adev); 1135 + 1136 + Done: 1137 + if (adev->pm.dpm_enabled) 1138 + amdgpu_dpm_enable_uvd(adev, false); 1139 + 1140 + return 0; 1141 + } 1142 + 1143 + /** 1144 + * vcn_v4_0_3_pause_dpg_mode - VCN pause with dpg mode 1145 + * 1146 + * @adev: amdgpu_device pointer 1147 + * @inst_idx: instance number index 1148 + * @new_state: pause state 1149 + * 1150 + * Pause dpg mode for VCN block 1151 + */ 1152 + static int vcn_v4_0_3_pause_dpg_mode(struct amdgpu_device *adev, int inst_idx, 1153 + struct dpg_pause_state *new_state) 1154 + { 1155 + 1156 + return 0; 1157 + } 1158 + 1159 + /** 1160 + * vcn_v4_0_3_dec_ring_get_rptr - get read pointer 1161 + * 1162 + * @ring: amdgpu_ring pointer 1163 + * 1164 + * Returns the current hardware read pointer 1165 + */ 1166 + static uint64_t vcn_v4_0_3_dec_ring_get_rptr(struct amdgpu_ring *ring) 1167 + { 1168 + struct amdgpu_device *adev = ring->adev; 1169 + 1170 + return RREG32_SOC15(VCN, ring->me, regUVD_RB_RPTR4); 1171 + } 1172 + 1173 + /** 1174 + * vcn_v4_0_3_dec_ring_get_wptr - get write pointer 1175 + * 1176 + * @ring: amdgpu_ring pointer 1177 + * 1178 + * Returns the current hardware write pointer 1179 + */ 1180 + static uint64_t vcn_v4_0_3_dec_ring_get_wptr(struct amdgpu_ring *ring) 1181 + { 1182 + struct amdgpu_device *adev = ring->adev; 1183 + 1184 + if (ring->use_doorbell) 1185 + return adev->wb.wb[ring->wptr_offs]; 1186 + else 1187 + return RREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR4); 1188 + } 1189 + 1190 + /** 1191 + * vcn_v4_0_3_dec_ring_set_wptr - set write pointer 1192 + * 1193 + * @ring: amdgpu_ring pointer 1194 + * 1195 + * Commits the write pointer to the hardware 1196 + */ 1197 + static void vcn_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring) 1198 + { 1199 + struct amdgpu_device *adev = ring->adev; 1200 + volatile struct amdgpu_fw_shared *fw_shared; 1201 + 1202 + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 1203 + /*whenever update RBC_RB_WPTR, we save the wptr in shared rb.wptr and scratch2 */ 1204 + fw_shared = adev->vcn.inst->fw_shared.cpu_addr; 1205 + fw_shared->rb.wptr = lower_32_bits(ring->wptr); 1206 + WREG32_SOC15(VCN, ring->me, regUVD_SCRATCH2, 1207 + lower_32_bits(ring->wptr)); 1208 + } 1209 + 1210 + if (ring->use_doorbell) { 1211 + adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); 1212 + WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 1213 + } else { 1214 + WREG32_SOC15(VCN, ring->me, regUVD_RB_WPTR4, lower_32_bits(ring->wptr)); 1215 + } 1216 + } 1217 + 1218 + static const struct amdgpu_ring_funcs vcn_v4_0_3_dec_sw_ring_vm_funcs = { 1219 + .type = AMDGPU_RING_TYPE_VCN_DEC, 1220 + .align_mask = 0x3f, 1221 + .nop = VCN_DEC_SW_CMD_NO_OP, 1222 + .get_rptr = vcn_v4_0_3_dec_ring_get_rptr, 1223 + .get_wptr = vcn_v4_0_3_dec_ring_get_wptr, 1224 + .set_wptr = vcn_v4_0_3_dec_ring_set_wptr, 1225 + .emit_frame_size = 1226 + SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + 1227 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 + 1228 + VCN_SW_RING_EMIT_FRAME_SIZE, 1229 + .emit_ib_size = 5, /* vcn_dec_sw_ring_emit_ib */ 1230 + .emit_ib = vcn_dec_sw_ring_emit_ib, 1231 + .emit_fence = vcn_dec_sw_ring_emit_fence, 1232 + .emit_vm_flush = vcn_dec_sw_ring_emit_vm_flush, 1233 + .test_ring = amdgpu_vcn_dec_sw_ring_test_ring, 1234 + .test_ib = amdgpu_vcn_dec_sw_ring_test_ib, 1235 + .insert_nop = amdgpu_ring_insert_nop, 1236 + .insert_end = vcn_dec_sw_ring_insert_end, 1237 + .pad_ib = amdgpu_ring_generic_pad_ib, 1238 + .begin_use = amdgpu_vcn_ring_begin_use, 1239 + .end_use = amdgpu_vcn_ring_end_use, 1240 + .emit_wreg = vcn_dec_sw_ring_emit_wreg, 1241 + .emit_reg_wait = vcn_dec_sw_ring_emit_reg_wait, 1242 + .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1243 + }; 1244 + 1245 + /** 1246 + * vcn_v4_0_3_set_dec_ring_funcs - set dec ring functions 1247 + * 1248 + * @adev: amdgpu_device pointer 1249 + * 1250 + * Set decode ring functions 1251 + */ 1252 + static void vcn_v4_0_3_set_dec_ring_funcs(struct amdgpu_device *adev) 1253 + { 1254 + adev->vcn.inst->ring_dec.funcs = &vcn_v4_0_3_dec_sw_ring_vm_funcs; 1255 + adev->vcn.inst->ring_dec.me = 0; 1256 + DRM_DEV_INFO(adev->dev, "VCN decode(Software Ring) is enabled in VM mode\n"); 1257 + } 1258 + 1259 + /** 1260 + * vcn_v4_0_3_is_idle - check VCN block is idle 1261 + * 1262 + * @handle: amdgpu_device pointer 1263 + * 1264 + * Check whether VCN block is idle 1265 + */ 1266 + static bool vcn_v4_0_3_is_idle(void *handle) 1267 + { 1268 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1269 + 1270 + return (RREG32_SOC15(VCN, 0, regUVD_STATUS) == UVD_STATUS__IDLE); 1271 + } 1272 + 1273 + /** 1274 + * vcn_v4_0_3_wait_for_idle - wait for VCN block idle 1275 + * 1276 + * @handle: amdgpu_device pointer 1277 + * 1278 + * Wait for VCN block idle 1279 + */ 1280 + static int vcn_v4_0_3_wait_for_idle(void *handle) 1281 + { 1282 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1283 + 1284 + return SOC15_WAIT_ON_RREG(VCN, 0, regUVD_STATUS, UVD_STATUS__IDLE, 1285 + UVD_STATUS__IDLE); 1286 + } 1287 + 1288 + /** 1289 + * vcn_v4_0_3_set_clockgating_state - set VCN block clockgating state 1290 + * 1291 + * @handle: amdgpu_device pointer 1292 + * @state: clock gating state 1293 + * 1294 + * Set VCN block clockgating state 1295 + */ 1296 + static int vcn_v4_0_3_set_clockgating_state(void *handle, 1297 + enum amd_clockgating_state state) 1298 + { 1299 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1300 + bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 1301 + 1302 + if (enable) { 1303 + if (RREG32_SOC15(VCN, 0, regUVD_STATUS) != UVD_STATUS__IDLE) 1304 + return -EBUSY; 1305 + vcn_v4_0_3_enable_clock_gating(adev); 1306 + } else { 1307 + vcn_v4_0_3_disable_clock_gating(adev); 1308 + } 1309 + 1310 + return 0; 1311 + } 1312 + 1313 + /** 1314 + * vcn_v4_0_3_set_powergating_state - set VCN block powergating state 1315 + * 1316 + * @handle: amdgpu_device pointer 1317 + * @state: power gating state 1318 + * 1319 + * Set VCN block powergating state 1320 + */ 1321 + static int vcn_v4_0_3_set_powergating_state(void *handle, 1322 + enum amd_powergating_state state) 1323 + { 1324 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1325 + int ret; 1326 + 1327 + if (state == adev->vcn.cur_state) 1328 + return 0; 1329 + 1330 + if (state == AMD_PG_STATE_GATE) 1331 + ret = vcn_v4_0_3_stop(adev); 1332 + else 1333 + ret = vcn_v4_0_3_start(adev); 1334 + 1335 + if (!ret) 1336 + adev->vcn.cur_state = state; 1337 + 1338 + return ret; 1339 + } 1340 + 1341 + /** 1342 + * vcn_v4_0_3_set_interrupt_state - set VCN block interrupt state 1343 + * 1344 + * @adev: amdgpu_device pointer 1345 + * @source: interrupt sources 1346 + * @type: interrupt types 1347 + * @state: interrupt states 1348 + * 1349 + * Set VCN block interrupt state 1350 + */ 1351 + static int vcn_v4_0_3_set_interrupt_state(struct amdgpu_device *adev, 1352 + struct amdgpu_irq_src *source, 1353 + unsigned int type, 1354 + enum amdgpu_interrupt_state state) 1355 + { 1356 + return 0; 1357 + } 1358 + 1359 + /** 1360 + * vcn_v4_0_process_interrupt - process VCN block interrupt 1361 + * 1362 + * @adev: amdgpu_device pointer 1363 + * @source: interrupt sources 1364 + * @entry: interrupt entry from clients and sources 1365 + * 1366 + * Process VCN block interrupt 1367 + */ 1368 + static int vcn_v4_0_3_process_interrupt(struct amdgpu_device *adev, 1369 + struct amdgpu_irq_src *source, 1370 + struct amdgpu_iv_entry *entry) 1371 + { 1372 + DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n"); 1373 + 1374 + switch (entry->src_id) { 1375 + case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT: 1376 + amdgpu_fence_process(&adev->vcn.inst->ring_dec); 1377 + break; 1378 + default: 1379 + DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 1380 + entry->src_id, entry->src_data[0]); 1381 + break; 1382 + } 1383 + 1384 + return 0; 1385 + } 1386 + 1387 + static const struct amdgpu_irq_src_funcs vcn_v4_0_3_irq_funcs = { 1388 + .set = vcn_v4_0_3_set_interrupt_state, 1389 + .process = vcn_v4_0_3_process_interrupt, 1390 + }; 1391 + 1392 + /** 1393 + * vcn_v4_0_3_set_irq_funcs - set VCN block interrupt irq functions 1394 + * 1395 + * @adev: amdgpu_device pointer 1396 + * 1397 + * Set VCN block interrupt irq functions 1398 + */ 1399 + static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev) 1400 + { 1401 + int i; 1402 + 1403 + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1404 + if (adev->vcn.harvest_config & (1 << i)) 1405 + continue; 1406 + 1407 + adev->vcn.inst->irq.num_types = 1; 1408 + adev->vcn.inst->irq.funcs = &vcn_v4_0_3_irq_funcs; 1409 + } 1410 + } 1411 + 1412 + static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = { 1413 + .name = "vcn_v4_0_3", 1414 + .early_init = vcn_v4_0_3_early_init, 1415 + .late_init = NULL, 1416 + .sw_init = vcn_v4_0_3_sw_init, 1417 + .sw_fini = vcn_v4_0_3_sw_fini, 1418 + .hw_init = vcn_v4_0_3_hw_init, 1419 + .hw_fini = vcn_v4_0_3_hw_fini, 1420 + .suspend = vcn_v4_0_3_suspend, 1421 + .resume = vcn_v4_0_3_resume, 1422 + .is_idle = vcn_v4_0_3_is_idle, 1423 + .wait_for_idle = vcn_v4_0_3_wait_for_idle, 1424 + .check_soft_reset = NULL, 1425 + .pre_soft_reset = NULL, 1426 + .soft_reset = NULL, 1427 + .post_soft_reset = NULL, 1428 + .set_clockgating_state = vcn_v4_0_3_set_clockgating_state, 1429 + .set_powergating_state = vcn_v4_0_3_set_powergating_state, 1430 + }; 1431 + 1432 + const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block = { 1433 + .type = AMD_IP_BLOCK_TYPE_VCN, 1434 + .major = 4, 1435 + .minor = 0, 1436 + .rev = 3, 1437 + .funcs = &vcn_v4_0_3_ip_funcs, 1438 + };
+29
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.h
··· 1 + /* 2 + * Copyright 2022 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 + #ifndef __VCN_V4_0_3_H__ 25 + #define __VCN_V4_0_3_H__ 26 + 27 + extern const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block; 28 + 29 + #endif /* __VCN_V4_0_3_H__ */