1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 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: 12 * 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. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 * 25 * Authors: Christian König <christian.koenig@amd.com> 26 */ 27 28 #include <linux/firmware.h> 29 #include <drm/drmP.h> 30 #include "amdgpu.h" 31 #include "amdgpu_vce.h" 32 #include "vid.h" 33 #include "vce/vce_3_0_d.h" 34 #include "vce/vce_3_0_sh_mask.h" 35 #include "oss/oss_3_0_d.h" 36 #include "oss/oss_3_0_sh_mask.h" 37 #include "gca/gfx_8_0_d.h" 38 #include "smu/smu_7_1_2_d.h" 39 #include "smu/smu_7_1_2_sh_mask.h" 40 41 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 42 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 43 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616 44 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617 45 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618 46 47 #define VCE_V3_0_FW_SIZE (384 * 1024) 48 #define VCE_V3_0_STACK_SIZE (64 * 1024) 49 #define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) 50 51 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx); 52 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); 53 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); 54 55 /** 56 * vce_v3_0_ring_get_rptr - get read pointer 57 * 58 * @ring: amdgpu_ring pointer 59 * 60 * Returns the current hardware read pointer 61 */ 62 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring) 63 { 64 struct amdgpu_device *adev = ring->adev; 65 66 if (ring == &adev->vce.ring[0]) 67 return RREG32(mmVCE_RB_RPTR); 68 else 69 return RREG32(mmVCE_RB_RPTR2); 70 } 71 72 /** 73 * vce_v3_0_ring_get_wptr - get write pointer 74 * 75 * @ring: amdgpu_ring pointer 76 * 77 * Returns the current hardware write pointer 78 */ 79 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring) 80 { 81 struct amdgpu_device *adev = ring->adev; 82 83 if (ring == &adev->vce.ring[0]) 84 return RREG32(mmVCE_RB_WPTR); 85 else 86 return RREG32(mmVCE_RB_WPTR2); 87 } 88 89 /** 90 * vce_v3_0_ring_set_wptr - set write pointer 91 * 92 * @ring: amdgpu_ring pointer 93 * 94 * Commits the write pointer to the hardware 95 */ 96 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) 97 { 98 struct amdgpu_device *adev = ring->adev; 99 100 if (ring == &adev->vce.ring[0]) 101 WREG32(mmVCE_RB_WPTR, ring->wptr); 102 else 103 WREG32(mmVCE_RB_WPTR2, ring->wptr); 104 } 105 106 static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override) 107 { 108 u32 tmp, data; 109 110 tmp = data = RREG32(mmVCE_RB_ARB_CTRL); 111 if (override) 112 data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK; 113 else 114 data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK; 115 116 if (tmp != data) 117 WREG32(mmVCE_RB_ARB_CTRL, data); 118 } 119 120 static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev, 121 bool gated) 122 { 123 u32 tmp, data; 124 /* Set Override to disable Clock Gating */ 125 vce_v3_0_override_vce_clock_gating(adev, true); 126 127 if (!gated) { 128 /* Force CLOCK ON for VCE_CLOCK_GATING_B, 129 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0} 130 * VREG can be FORCE ON or set to Dynamic, but can't be OFF 131 */ 132 tmp = data = RREG32(mmVCE_CLOCK_GATING_B); 133 data |= 0x1ff; 134 data &= ~0xef0000; 135 if (tmp != data) 136 WREG32(mmVCE_CLOCK_GATING_B, data); 137 138 /* Force CLOCK ON for VCE_UENC_CLOCK_GATING, 139 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0} 140 */ 141 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING); 142 data |= 0x3ff000; 143 data &= ~0xffc00000; 144 if (tmp != data) 145 WREG32(mmVCE_UENC_CLOCK_GATING, data); 146 147 /* set VCE_UENC_CLOCK_GATING_2 */ 148 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2); 149 data |= 0x2; 150 data &= ~0x2; 151 if (tmp != data) 152 WREG32(mmVCE_UENC_CLOCK_GATING_2, data); 153 154 /* Force CLOCK ON for VCE_UENC_REG_CLOCK_GATING */ 155 tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING); 156 data |= 0x37f; 157 if (tmp != data) 158 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data); 159 160 /* Force VCE_UENC_DMA_DCLK_CTRL Clock ON */ 161 tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL); 162 data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | 163 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | 164 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | 165 0x8; 166 if (tmp != data) 167 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data); 168 } else { 169 /* Force CLOCK OFF for VCE_CLOCK_GATING_B, 170 * {*, *_FORCE_OFF} = {*, 1} 171 * set VREG to Dynamic, as it can't be OFF 172 */ 173 tmp = data = RREG32(mmVCE_CLOCK_GATING_B); 174 data &= ~0x80010; 175 data |= 0xe70008; 176 if (tmp != data) 177 WREG32(mmVCE_CLOCK_GATING_B, data); 178 /* Force CLOCK OFF for VCE_UENC_CLOCK_GATING, 179 * Force ClOCK OFF takes precedent over Force CLOCK ON setting. 180 * {*_FORCE_ON, *_FORCE_OFF} = {*, 1} 181 */ 182 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING); 183 data |= 0xffc00000; 184 if (tmp != data) 185 WREG32(mmVCE_UENC_CLOCK_GATING, data); 186 /* Set VCE_UENC_CLOCK_GATING_2 */ 187 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2); 188 data |= 0x10000; 189 if (tmp != data) 190 WREG32(mmVCE_UENC_CLOCK_GATING_2, data); 191 /* Set VCE_UENC_REG_CLOCK_GATING to dynamic */ 192 tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING); 193 data &= ~0xffc00000; 194 if (tmp != data) 195 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data); 196 /* Set VCE_UENC_DMA_DCLK_CTRL CG always in dynamic mode */ 197 tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL); 198 data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | 199 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | 200 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | 201 0x8); 202 if (tmp != data) 203 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data); 204 } 205 vce_v3_0_override_vce_clock_gating(adev, false); 206 } 207 208 /** 209 * vce_v3_0_start - start VCE block 210 * 211 * @adev: amdgpu_device pointer 212 * 213 * Setup and start the VCE block 214 */ 215 static int vce_v3_0_start(struct amdgpu_device *adev) 216 { 217 struct amdgpu_ring *ring; 218 int idx, i, j, r; 219 220 mutex_lock(&adev->grbm_idx_mutex); 221 for (idx = 0; idx < 2; ++idx) { 222 223 if (adev->vce.harvest_config & (1 << idx)) 224 continue; 225 226 if (idx == 0) 227 WREG32_P(mmGRBM_GFX_INDEX, 0, 228 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 229 else 230 WREG32_P(mmGRBM_GFX_INDEX, 231 GRBM_GFX_INDEX__VCE_INSTANCE_MASK, 232 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 233 234 vce_v3_0_mc_resume(adev, idx); 235 236 /* set BUSY flag */ 237 WREG32_P(mmVCE_STATUS, 1, ~1); 238 if (adev->asic_type >= CHIP_STONEY) 239 WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001); 240 else 241 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, 242 ~VCE_VCPU_CNTL__CLK_EN_MASK); 243 244 WREG32_P(mmVCE_SOFT_RESET, 245 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 246 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 247 248 mdelay(100); 249 250 WREG32_P(mmVCE_SOFT_RESET, 0, 251 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 252 253 for (i = 0; i < 10; ++i) { 254 uint32_t status; 255 for (j = 0; j < 100; ++j) { 256 status = RREG32(mmVCE_STATUS); 257 if (status & 2) 258 break; 259 mdelay(10); 260 } 261 r = 0; 262 if (status & 2) 263 break; 264 265 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 266 WREG32_P(mmVCE_SOFT_RESET, 267 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 268 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 269 mdelay(10); 270 WREG32_P(mmVCE_SOFT_RESET, 0, 271 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 272 mdelay(10); 273 r = -1; 274 } 275 276 /* clear BUSY flag */ 277 WREG32_P(mmVCE_STATUS, 0, ~1); 278 279 /* Set Clock-Gating off */ 280 if (adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG) 281 vce_v3_0_set_vce_sw_clock_gating(adev, false); 282 283 if (r) { 284 DRM_ERROR("VCE not responding, giving up!!!\n"); 285 mutex_unlock(&adev->grbm_idx_mutex); 286 return r; 287 } 288 } 289 290 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 291 mutex_unlock(&adev->grbm_idx_mutex); 292 293 ring = &adev->vce.ring[0]; 294 WREG32(mmVCE_RB_RPTR, ring->wptr); 295 WREG32(mmVCE_RB_WPTR, ring->wptr); 296 WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr); 297 WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 298 WREG32(mmVCE_RB_SIZE, ring->ring_size / 4); 299 300 ring = &adev->vce.ring[1]; 301 WREG32(mmVCE_RB_RPTR2, ring->wptr); 302 WREG32(mmVCE_RB_WPTR2, ring->wptr); 303 WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr); 304 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 305 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); 306 307 return 0; 308 } 309 310 #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074 311 #define VCE_HARVEST_FUSE_MACRO__SHIFT 27 312 #define VCE_HARVEST_FUSE_MACRO__MASK 0x18000000 313 314 static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) 315 { 316 u32 tmp; 317 318 /* Fiji, Stoney are single pipe */ 319 if ((adev->asic_type == CHIP_FIJI) || 320 (adev->asic_type == CHIP_STONEY)) 321 return AMDGPU_VCE_HARVEST_VCE1; 322 323 /* Tonga and CZ are dual or single pipe */ 324 if (adev->flags & AMD_IS_APU) 325 tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) & 326 VCE_HARVEST_FUSE_MACRO__MASK) >> 327 VCE_HARVEST_FUSE_MACRO__SHIFT; 328 else 329 tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) & 330 CC_HARVEST_FUSES__VCE_DISABLE_MASK) >> 331 CC_HARVEST_FUSES__VCE_DISABLE__SHIFT; 332 333 switch (tmp) { 334 case 1: 335 return AMDGPU_VCE_HARVEST_VCE0; 336 case 2: 337 return AMDGPU_VCE_HARVEST_VCE1; 338 case 3: 339 return AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1; 340 default: 341 return 0; 342 } 343 } 344 345 static int vce_v3_0_early_init(void *handle) 346 { 347 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 348 349 adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev); 350 351 if ((adev->vce.harvest_config & 352 (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) == 353 (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) 354 return -ENOENT; 355 356 vce_v3_0_set_ring_funcs(adev); 357 vce_v3_0_set_irq_funcs(adev); 358 359 return 0; 360 } 361 362 static int vce_v3_0_sw_init(void *handle) 363 { 364 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 365 struct amdgpu_ring *ring; 366 int r; 367 368 /* VCE */ 369 r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq); 370 if (r) 371 return r; 372 373 r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE + 374 (VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2); 375 if (r) 376 return r; 377 378 r = amdgpu_vce_resume(adev); 379 if (r) 380 return r; 381 382 ring = &adev->vce.ring[0]; 383 sprintf(ring->name, "vce0"); 384 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 385 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 386 if (r) 387 return r; 388 389 ring = &adev->vce.ring[1]; 390 sprintf(ring->name, "vce1"); 391 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 392 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 393 if (r) 394 return r; 395 396 return r; 397 } 398 399 static int vce_v3_0_sw_fini(void *handle) 400 { 401 int r; 402 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 403 404 r = amdgpu_vce_suspend(adev); 405 if (r) 406 return r; 407 408 r = amdgpu_vce_sw_fini(adev); 409 if (r) 410 return r; 411 412 return r; 413 } 414 415 static int vce_v3_0_hw_init(void *handle) 416 { 417 int r, i; 418 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 419 420 r = vce_v3_0_start(adev); 421 if (r) 422 return r; 423 424 adev->vce.ring[0].ready = false; 425 adev->vce.ring[1].ready = false; 426 427 for (i = 0; i < 2; i++) { 428 r = amdgpu_ring_test_ring(&adev->vce.ring[i]); 429 if (r) 430 return r; 431 else 432 adev->vce.ring[i].ready = true; 433 } 434 435 DRM_INFO("VCE initialized successfully.\n"); 436 437 return 0; 438 } 439 440 static int vce_v3_0_hw_fini(void *handle) 441 { 442 return 0; 443 } 444 445 static int vce_v3_0_suspend(void *handle) 446 { 447 int r; 448 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 449 450 r = vce_v3_0_hw_fini(adev); 451 if (r) 452 return r; 453 454 r = amdgpu_vce_suspend(adev); 455 if (r) 456 return r; 457 458 return r; 459 } 460 461 static int vce_v3_0_resume(void *handle) 462 { 463 int r; 464 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 465 466 r = amdgpu_vce_resume(adev); 467 if (r) 468 return r; 469 470 r = vce_v3_0_hw_init(adev); 471 if (r) 472 return r; 473 474 return r; 475 } 476 477 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) 478 { 479 uint32_t offset, size; 480 481 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16)); 482 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 483 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 484 WREG32(mmVCE_CLOCK_GATING_B, 0xf7); 485 486 WREG32(mmVCE_LMI_CTRL, 0x00398000); 487 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1); 488 WREG32(mmVCE_LMI_SWAP_CNTL, 0); 489 WREG32(mmVCE_LMI_SWAP_CNTL1, 0); 490 WREG32(mmVCE_LMI_VM_CTRL, 0); 491 if (adev->asic_type >= CHIP_STONEY) { 492 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8)); 493 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8)); 494 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8)); 495 } else 496 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); 497 offset = AMDGPU_VCE_FIRMWARE_OFFSET; 498 size = VCE_V3_0_FW_SIZE; 499 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); 500 WREG32(mmVCE_VCPU_CACHE_SIZE0, size); 501 502 if (idx == 0) { 503 offset += size; 504 size = VCE_V3_0_STACK_SIZE; 505 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); 506 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 507 offset += size; 508 size = VCE_V3_0_DATA_SIZE; 509 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); 510 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 511 } else { 512 offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE; 513 size = VCE_V3_0_STACK_SIZE; 514 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff); 515 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 516 offset += size; 517 size = VCE_V3_0_DATA_SIZE; 518 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff); 519 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 520 } 521 522 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 523 524 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK, 525 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 526 } 527 528 static bool vce_v3_0_is_idle(void *handle) 529 { 530 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 531 u32 mask = 0; 532 533 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK; 534 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK; 535 536 return !(RREG32(mmSRBM_STATUS2) & mask); 537 } 538 539 static int vce_v3_0_wait_for_idle(void *handle) 540 { 541 unsigned i; 542 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 543 544 for (i = 0; i < adev->usec_timeout; i++) 545 if (vce_v3_0_is_idle(handle)) 546 return 0; 547 548 return -ETIMEDOUT; 549 } 550 551 static int vce_v3_0_soft_reset(void *handle) 552 { 553 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 554 u32 mask = 0; 555 556 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; 557 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; 558 559 WREG32_P(mmSRBM_SOFT_RESET, mask, 560 ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK | 561 SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK)); 562 mdelay(5); 563 564 return vce_v3_0_start(adev); 565 } 566 567 static void vce_v3_0_print_status(void *handle) 568 { 569 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 570 571 dev_info(adev->dev, "VCE 3.0 registers\n"); 572 dev_info(adev->dev, " VCE_STATUS=0x%08X\n", 573 RREG32(mmVCE_STATUS)); 574 dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n", 575 RREG32(mmVCE_VCPU_CNTL)); 576 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n", 577 RREG32(mmVCE_VCPU_CACHE_OFFSET0)); 578 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n", 579 RREG32(mmVCE_VCPU_CACHE_SIZE0)); 580 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n", 581 RREG32(mmVCE_VCPU_CACHE_OFFSET1)); 582 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n", 583 RREG32(mmVCE_VCPU_CACHE_SIZE1)); 584 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n", 585 RREG32(mmVCE_VCPU_CACHE_OFFSET2)); 586 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n", 587 RREG32(mmVCE_VCPU_CACHE_SIZE2)); 588 dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n", 589 RREG32(mmVCE_SOFT_RESET)); 590 dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n", 591 RREG32(mmVCE_RB_BASE_LO2)); 592 dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n", 593 RREG32(mmVCE_RB_BASE_HI2)); 594 dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n", 595 RREG32(mmVCE_RB_SIZE2)); 596 dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n", 597 RREG32(mmVCE_RB_RPTR2)); 598 dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n", 599 RREG32(mmVCE_RB_WPTR2)); 600 dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n", 601 RREG32(mmVCE_RB_BASE_LO)); 602 dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n", 603 RREG32(mmVCE_RB_BASE_HI)); 604 dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n", 605 RREG32(mmVCE_RB_SIZE)); 606 dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n", 607 RREG32(mmVCE_RB_RPTR)); 608 dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n", 609 RREG32(mmVCE_RB_WPTR)); 610 dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n", 611 RREG32(mmVCE_CLOCK_GATING_A)); 612 dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n", 613 RREG32(mmVCE_CLOCK_GATING_B)); 614 dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n", 615 RREG32(mmVCE_UENC_CLOCK_GATING)); 616 dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n", 617 RREG32(mmVCE_UENC_REG_CLOCK_GATING)); 618 dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n", 619 RREG32(mmVCE_SYS_INT_EN)); 620 dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n", 621 RREG32(mmVCE_LMI_CTRL2)); 622 dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n", 623 RREG32(mmVCE_LMI_CTRL)); 624 dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n", 625 RREG32(mmVCE_LMI_VM_CTRL)); 626 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n", 627 RREG32(mmVCE_LMI_SWAP_CNTL)); 628 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n", 629 RREG32(mmVCE_LMI_SWAP_CNTL1)); 630 dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n", 631 RREG32(mmVCE_LMI_CACHE_CTRL)); 632 } 633 634 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev, 635 struct amdgpu_irq_src *source, 636 unsigned type, 637 enum amdgpu_interrupt_state state) 638 { 639 uint32_t val = 0; 640 641 if (state == AMDGPU_IRQ_STATE_ENABLE) 642 val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK; 643 644 WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 645 return 0; 646 } 647 648 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, 649 struct amdgpu_irq_src *source, 650 struct amdgpu_iv_entry *entry) 651 { 652 DRM_DEBUG("IH: VCE\n"); 653 654 WREG32_P(mmVCE_SYS_INT_STATUS, 655 VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, 656 ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); 657 658 switch (entry->src_data) { 659 case 0: 660 case 1: 661 amdgpu_fence_process(&adev->vce.ring[entry->src_data]); 662 break; 663 default: 664 DRM_ERROR("Unhandled interrupt: %d %d\n", 665 entry->src_id, entry->src_data); 666 break; 667 } 668 669 return 0; 670 } 671 672 static int vce_v3_0_set_clockgating_state(void *handle, 673 enum amd_clockgating_state state) 674 { 675 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 676 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 677 int i; 678 679 if (!(adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG)) 680 return 0; 681 682 mutex_lock(&adev->grbm_idx_mutex); 683 for (i = 0; i < 2; i++) { 684 /* Program VCE Instance 0 or 1 if not harvested */ 685 if (adev->vce.harvest_config & (1 << i)) 686 continue; 687 688 if (i == 0) 689 WREG32_P(mmGRBM_GFX_INDEX, 0, 690 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 691 else 692 WREG32_P(mmGRBM_GFX_INDEX, 693 GRBM_GFX_INDEX__VCE_INSTANCE_MASK, 694 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 695 696 if (enable) { 697 /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */ 698 uint32_t data = RREG32(mmVCE_CLOCK_GATING_A); 699 data &= ~(0xf | 0xff0); 700 data |= ((0x0 << 0) | (0x04 << 4)); 701 WREG32(mmVCE_CLOCK_GATING_A, data); 702 703 /* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */ 704 data = RREG32(mmVCE_UENC_CLOCK_GATING); 705 data &= ~(0xf | 0xff0); 706 data |= ((0x0 << 0) | (0x04 << 4)); 707 WREG32(mmVCE_UENC_CLOCK_GATING, data); 708 } 709 710 vce_v3_0_set_vce_sw_clock_gating(adev, enable); 711 } 712 713 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 714 mutex_unlock(&adev->grbm_idx_mutex); 715 716 return 0; 717 } 718 719 static int vce_v3_0_set_powergating_state(void *handle, 720 enum amd_powergating_state state) 721 { 722 /* This doesn't actually powergate the VCE block. 723 * That's done in the dpm code via the SMC. This 724 * just re-inits the block as necessary. The actual 725 * gating still happens in the dpm code. We should 726 * revisit this when there is a cleaner line between 727 * the smc and the hw blocks 728 */ 729 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 730 731 if (state == AMD_PG_STATE_GATE) 732 /* XXX do we need a vce_v3_0_stop()? */ 733 return 0; 734 else 735 return vce_v3_0_start(adev); 736 } 737 738 const struct amd_ip_funcs vce_v3_0_ip_funcs = { 739 .early_init = vce_v3_0_early_init, 740 .late_init = NULL, 741 .sw_init = vce_v3_0_sw_init, 742 .sw_fini = vce_v3_0_sw_fini, 743 .hw_init = vce_v3_0_hw_init, 744 .hw_fini = vce_v3_0_hw_fini, 745 .suspend = vce_v3_0_suspend, 746 .resume = vce_v3_0_resume, 747 .is_idle = vce_v3_0_is_idle, 748 .wait_for_idle = vce_v3_0_wait_for_idle, 749 .soft_reset = vce_v3_0_soft_reset, 750 .print_status = vce_v3_0_print_status, 751 .set_clockgating_state = vce_v3_0_set_clockgating_state, 752 .set_powergating_state = vce_v3_0_set_powergating_state, 753 }; 754 755 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { 756 .get_rptr = vce_v3_0_ring_get_rptr, 757 .get_wptr = vce_v3_0_ring_get_wptr, 758 .set_wptr = vce_v3_0_ring_set_wptr, 759 .parse_cs = amdgpu_vce_ring_parse_cs, 760 .emit_ib = amdgpu_vce_ring_emit_ib, 761 .emit_fence = amdgpu_vce_ring_emit_fence, 762 .emit_semaphore = amdgpu_vce_ring_emit_semaphore, 763 .test_ring = amdgpu_vce_ring_test_ring, 764 .test_ib = amdgpu_vce_ring_test_ib, 765 .insert_nop = amdgpu_ring_insert_nop, 766 }; 767 768 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) 769 { 770 adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs; 771 adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs; 772 } 773 774 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = { 775 .set = vce_v3_0_set_interrupt_state, 776 .process = vce_v3_0_process_interrupt, 777 }; 778 779 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev) 780 { 781 adev->vce.irq.num_types = 1; 782 adev->vce.irq.funcs = &vce_v3_0_irq_funcs; 783 }; 784