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 struct amdgpu_ring *ring; 418 int r; 419 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 420 421 r = vce_v3_0_start(adev); 422 if (r) 423 return r; 424 425 ring = &adev->vce.ring[0]; 426 ring->ready = true; 427 r = amdgpu_ring_test_ring(ring); 428 if (r) { 429 ring->ready = false; 430 return r; 431 } 432 433 ring = &adev->vce.ring[1]; 434 ring->ready = true; 435 r = amdgpu_ring_test_ring(ring); 436 if (r) { 437 ring->ready = false; 438 return r; 439 } 440 441 DRM_INFO("VCE initialized successfully.\n"); 442 443 return 0; 444 } 445 446 static int vce_v3_0_hw_fini(void *handle) 447 { 448 return 0; 449 } 450 451 static int vce_v3_0_suspend(void *handle) 452 { 453 int r; 454 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 455 456 r = vce_v3_0_hw_fini(adev); 457 if (r) 458 return r; 459 460 r = amdgpu_vce_suspend(adev); 461 if (r) 462 return r; 463 464 return r; 465 } 466 467 static int vce_v3_0_resume(void *handle) 468 { 469 int r; 470 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 471 472 r = amdgpu_vce_resume(adev); 473 if (r) 474 return r; 475 476 r = vce_v3_0_hw_init(adev); 477 if (r) 478 return r; 479 480 return r; 481 } 482 483 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) 484 { 485 uint32_t offset, size; 486 487 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16)); 488 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 489 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 490 WREG32(mmVCE_CLOCK_GATING_B, 0xf7); 491 492 WREG32(mmVCE_LMI_CTRL, 0x00398000); 493 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1); 494 WREG32(mmVCE_LMI_SWAP_CNTL, 0); 495 WREG32(mmVCE_LMI_SWAP_CNTL1, 0); 496 WREG32(mmVCE_LMI_VM_CTRL, 0); 497 if (adev->asic_type >= CHIP_STONEY) { 498 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8)); 499 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8)); 500 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8)); 501 } else 502 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); 503 offset = AMDGPU_VCE_FIRMWARE_OFFSET; 504 size = VCE_V3_0_FW_SIZE; 505 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); 506 WREG32(mmVCE_VCPU_CACHE_SIZE0, size); 507 508 if (idx == 0) { 509 offset += size; 510 size = VCE_V3_0_STACK_SIZE; 511 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); 512 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 513 offset += size; 514 size = VCE_V3_0_DATA_SIZE; 515 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); 516 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 517 } else { 518 offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE; 519 size = VCE_V3_0_STACK_SIZE; 520 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff); 521 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 522 offset += size; 523 size = VCE_V3_0_DATA_SIZE; 524 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff); 525 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 526 } 527 528 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 529 530 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK, 531 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 532 } 533 534 static bool vce_v3_0_is_idle(void *handle) 535 { 536 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 537 u32 mask = 0; 538 539 mask |= (adev->vce.harvest_config & (1<<0)) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK; 540 mask |= (adev->vce.harvest_config & (1<<1)) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK; 541 542 return !(RREG32(mmSRBM_STATUS2) & mask); 543 } 544 545 static int vce_v3_0_wait_for_idle(void *handle) 546 { 547 unsigned i; 548 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 549 550 for (i = 0; i < adev->usec_timeout; i++) 551 if (vce_v3_0_is_idle(handle)) 552 return 0; 553 554 return -ETIMEDOUT; 555 } 556 557 static int vce_v3_0_soft_reset(void *handle) 558 { 559 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 560 u32 mask = 0; 561 int idx; 562 563 for (idx = 0; idx < 2; ++idx) { 564 if (adev->vce.harvest_config & (1 << idx)) 565 continue; 566 567 if (idx == 0) 568 mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; 569 else 570 mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; 571 } 572 WREG32_P(mmSRBM_SOFT_RESET, mask, 573 ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK | 574 SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK)); 575 mdelay(5); 576 577 return vce_v3_0_start(adev); 578 } 579 580 static void vce_v3_0_print_status(void *handle) 581 { 582 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 583 584 dev_info(adev->dev, "VCE 3.0 registers\n"); 585 dev_info(adev->dev, " VCE_STATUS=0x%08X\n", 586 RREG32(mmVCE_STATUS)); 587 dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n", 588 RREG32(mmVCE_VCPU_CNTL)); 589 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n", 590 RREG32(mmVCE_VCPU_CACHE_OFFSET0)); 591 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n", 592 RREG32(mmVCE_VCPU_CACHE_SIZE0)); 593 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n", 594 RREG32(mmVCE_VCPU_CACHE_OFFSET1)); 595 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n", 596 RREG32(mmVCE_VCPU_CACHE_SIZE1)); 597 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n", 598 RREG32(mmVCE_VCPU_CACHE_OFFSET2)); 599 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n", 600 RREG32(mmVCE_VCPU_CACHE_SIZE2)); 601 dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n", 602 RREG32(mmVCE_SOFT_RESET)); 603 dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n", 604 RREG32(mmVCE_RB_BASE_LO2)); 605 dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n", 606 RREG32(mmVCE_RB_BASE_HI2)); 607 dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n", 608 RREG32(mmVCE_RB_SIZE2)); 609 dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n", 610 RREG32(mmVCE_RB_RPTR2)); 611 dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n", 612 RREG32(mmVCE_RB_WPTR2)); 613 dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n", 614 RREG32(mmVCE_RB_BASE_LO)); 615 dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n", 616 RREG32(mmVCE_RB_BASE_HI)); 617 dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n", 618 RREG32(mmVCE_RB_SIZE)); 619 dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n", 620 RREG32(mmVCE_RB_RPTR)); 621 dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n", 622 RREG32(mmVCE_RB_WPTR)); 623 dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n", 624 RREG32(mmVCE_CLOCK_GATING_A)); 625 dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n", 626 RREG32(mmVCE_CLOCK_GATING_B)); 627 dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n", 628 RREG32(mmVCE_UENC_CLOCK_GATING)); 629 dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n", 630 RREG32(mmVCE_UENC_REG_CLOCK_GATING)); 631 dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n", 632 RREG32(mmVCE_SYS_INT_EN)); 633 dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n", 634 RREG32(mmVCE_LMI_CTRL2)); 635 dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n", 636 RREG32(mmVCE_LMI_CTRL)); 637 dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n", 638 RREG32(mmVCE_LMI_VM_CTRL)); 639 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n", 640 RREG32(mmVCE_LMI_SWAP_CNTL)); 641 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n", 642 RREG32(mmVCE_LMI_SWAP_CNTL1)); 643 dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n", 644 RREG32(mmVCE_LMI_CACHE_CTRL)); 645 } 646 647 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev, 648 struct amdgpu_irq_src *source, 649 unsigned type, 650 enum amdgpu_interrupt_state state) 651 { 652 uint32_t val = 0; 653 654 if (state == AMDGPU_IRQ_STATE_ENABLE) 655 val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK; 656 657 WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 658 return 0; 659 } 660 661 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, 662 struct amdgpu_irq_src *source, 663 struct amdgpu_iv_entry *entry) 664 { 665 DRM_DEBUG("IH: VCE\n"); 666 667 WREG32_P(mmVCE_SYS_INT_STATUS, 668 VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, 669 ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); 670 671 switch (entry->src_data) { 672 case 0: 673 amdgpu_fence_process(&adev->vce.ring[0]); 674 break; 675 case 1: 676 amdgpu_fence_process(&adev->vce.ring[1]); 677 break; 678 default: 679 DRM_ERROR("Unhandled interrupt: %d %d\n", 680 entry->src_id, entry->src_data); 681 break; 682 } 683 684 return 0; 685 } 686 687 static int vce_v3_0_set_clockgating_state(void *handle, 688 enum amd_clockgating_state state) 689 { 690 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 691 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 692 int i; 693 694 if (!(adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG)) 695 return 0; 696 697 mutex_lock(&adev->grbm_idx_mutex); 698 for (i = 0; i < 2; i++) { 699 /* Program VCE Instance 0 or 1 if not harvested */ 700 if (adev->vce.harvest_config & (1 << i)) 701 continue; 702 703 if (i == 0) 704 WREG32_P(mmGRBM_GFX_INDEX, 0, 705 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 706 else 707 WREG32_P(mmGRBM_GFX_INDEX, 708 GRBM_GFX_INDEX__VCE_INSTANCE_MASK, 709 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 710 711 if (enable) { 712 /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */ 713 uint32_t data = RREG32(mmVCE_CLOCK_GATING_A); 714 data &= ~(0xf | 0xff0); 715 data |= ((0x0 << 0) | (0x04 << 4)); 716 WREG32(mmVCE_CLOCK_GATING_A, data); 717 718 /* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */ 719 data = RREG32(mmVCE_UENC_CLOCK_GATING); 720 data &= ~(0xf | 0xff0); 721 data |= ((0x0 << 0) | (0x04 << 4)); 722 WREG32(mmVCE_UENC_CLOCK_GATING, data); 723 } 724 725 vce_v3_0_set_vce_sw_clock_gating(adev, enable); 726 } 727 728 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 729 mutex_unlock(&adev->grbm_idx_mutex); 730 731 return 0; 732 } 733 734 static int vce_v3_0_set_powergating_state(void *handle, 735 enum amd_powergating_state state) 736 { 737 /* This doesn't actually powergate the VCE block. 738 * That's done in the dpm code via the SMC. This 739 * just re-inits the block as necessary. The actual 740 * gating still happens in the dpm code. We should 741 * revisit this when there is a cleaner line between 742 * the smc and the hw blocks 743 */ 744 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 745 746 if (state == AMD_PG_STATE_GATE) 747 /* XXX do we need a vce_v3_0_stop()? */ 748 return 0; 749 else 750 return vce_v3_0_start(adev); 751 } 752 753 const struct amd_ip_funcs vce_v3_0_ip_funcs = { 754 .early_init = vce_v3_0_early_init, 755 .late_init = NULL, 756 .sw_init = vce_v3_0_sw_init, 757 .sw_fini = vce_v3_0_sw_fini, 758 .hw_init = vce_v3_0_hw_init, 759 .hw_fini = vce_v3_0_hw_fini, 760 .suspend = vce_v3_0_suspend, 761 .resume = vce_v3_0_resume, 762 .is_idle = vce_v3_0_is_idle, 763 .wait_for_idle = vce_v3_0_wait_for_idle, 764 .soft_reset = vce_v3_0_soft_reset, 765 .print_status = vce_v3_0_print_status, 766 .set_clockgating_state = vce_v3_0_set_clockgating_state, 767 .set_powergating_state = vce_v3_0_set_powergating_state, 768 }; 769 770 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { 771 .get_rptr = vce_v3_0_ring_get_rptr, 772 .get_wptr = vce_v3_0_ring_get_wptr, 773 .set_wptr = vce_v3_0_ring_set_wptr, 774 .parse_cs = amdgpu_vce_ring_parse_cs, 775 .emit_ib = amdgpu_vce_ring_emit_ib, 776 .emit_fence = amdgpu_vce_ring_emit_fence, 777 .emit_semaphore = amdgpu_vce_ring_emit_semaphore, 778 .test_ring = amdgpu_vce_ring_test_ring, 779 .test_ib = amdgpu_vce_ring_test_ib, 780 .insert_nop = amdgpu_ring_insert_nop, 781 }; 782 783 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) 784 { 785 adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs; 786 adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs; 787 } 788 789 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = { 790 .set = vce_v3_0_set_interrupt_state, 791 .process = vce_v3_0_process_interrupt, 792 }; 793 794 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev) 795 { 796 adev->vce.irq.num_types = 1; 797 adev->vce.irq.funcs = &vce_v3_0_irq_funcs; 798 }; 799