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