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