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