1 /* $NetBSD: radeon_uvd_v1_0.c,v 1.6 2021/12/19 00:25:04 riastradh Exp $ */ 2 3 /* 4 * Copyright 2013 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Christian Knig <christian.koenig (at) amd.com> 25 */ 26 27 #include <sys/cdefs.h> 28 __KERNEL_RCSID(0, "$NetBSD: radeon_uvd_v1_0.c,v 1.6 2021/12/19 00:25:04 riastradh Exp $"); 29 30 #include <linux/firmware.h> 31 32 #include "radeon.h" 33 #include "radeon_asic.h" 34 #include "r600d.h" 35 36 /** 37 * uvd_v1_0_get_rptr - get read pointer 38 * 39 * @rdev: radeon_device pointer 40 * @ring: radeon_ring pointer 41 * 42 * Returns the current hardware read pointer 43 */ 44 uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev, 45 struct radeon_ring *ring) 46 { 47 return RREG32(UVD_RBC_RB_RPTR); 48 } 49 50 /** 51 * uvd_v1_0_get_wptr - get write pointer 52 * 53 * @rdev: radeon_device pointer 54 * @ring: radeon_ring pointer 55 * 56 * Returns the current hardware write pointer 57 */ 58 uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev, 59 struct radeon_ring *ring) 60 { 61 return RREG32(UVD_RBC_RB_WPTR); 62 } 63 64 /** 65 * uvd_v1_0_set_wptr - set write pointer 66 * 67 * @rdev: radeon_device pointer 68 * @ring: radeon_ring pointer 69 * 70 * Commits the write pointer to the hardware 71 */ 72 void uvd_v1_0_set_wptr(struct radeon_device *rdev, 73 struct radeon_ring *ring) 74 { 75 WREG32(UVD_RBC_RB_WPTR, ring->wptr); 76 } 77 78 /** 79 * uvd_v1_0_fence_emit - emit an fence & trap command 80 * 81 * @rdev: radeon_device pointer 82 * @fence: fence to emit 83 * 84 * Write a fence and a trap command to the ring. 85 */ 86 void uvd_v1_0_fence_emit(struct radeon_device *rdev, 87 struct radeon_fence *fence) 88 { 89 struct radeon_ring *ring = &rdev->ring[fence->ring]; 90 uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; 91 92 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 93 radeon_ring_write(ring, addr & 0xffffffff); 94 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 95 radeon_ring_write(ring, fence->seq); 96 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 97 radeon_ring_write(ring, 0); 98 99 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0)); 100 radeon_ring_write(ring, 0); 101 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0)); 102 radeon_ring_write(ring, 0); 103 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); 104 radeon_ring_write(ring, 2); 105 return; 106 } 107 108 /** 109 * uvd_v1_0_resume - memory controller programming 110 * 111 * @rdev: radeon_device pointer 112 * 113 * Let the UVD memory controller know it's offsets 114 */ 115 int uvd_v1_0_resume(struct radeon_device *rdev) 116 { 117 uint64_t addr; 118 uint32_t size; 119 int r; 120 121 r = radeon_uvd_resume(rdev); 122 if (r) 123 return r; 124 125 /* programm the VCPU memory controller bits 0-27 */ 126 addr = (rdev->uvd.gpu_addr >> 3) + 16; 127 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3; 128 WREG32(UVD_VCPU_CACHE_OFFSET0, addr); 129 WREG32(UVD_VCPU_CACHE_SIZE0, size); 130 131 addr += size; 132 size = RADEON_UVD_HEAP_SIZE >> 3; 133 WREG32(UVD_VCPU_CACHE_OFFSET1, addr); 134 WREG32(UVD_VCPU_CACHE_SIZE1, size); 135 136 addr += size; 137 size = (RADEON_UVD_STACK_SIZE + 138 (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; 139 WREG32(UVD_VCPU_CACHE_OFFSET2, addr); 140 WREG32(UVD_VCPU_CACHE_SIZE2, size); 141 142 /* bits 28-31 */ 143 addr = (rdev->uvd.gpu_addr >> 28) & 0xF; 144 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); 145 146 /* bits 32-39 */ 147 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; 148 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1U << 31)); 149 150 WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr)); 151 152 return 0; 153 } 154 155 /** 156 * uvd_v1_0_init - start and test UVD block 157 * 158 * @rdev: radeon_device pointer 159 * 160 * Initialize the hardware, boot up the VCPU and do some testing 161 */ 162 int uvd_v1_0_init(struct radeon_device *rdev) 163 { 164 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 165 uint32_t tmp; 166 int r; 167 168 /* raise clocks while booting up the VCPU */ 169 if (rdev->family < CHIP_RV740) 170 radeon_set_uvd_clocks(rdev, 10000, 10000); 171 else 172 radeon_set_uvd_clocks(rdev, 53300, 40000); 173 174 r = uvd_v1_0_start(rdev); 175 if (r) 176 goto done; 177 178 ring->ready = true; 179 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring); 180 if (r) { 181 ring->ready = false; 182 goto done; 183 } 184 185 r = radeon_ring_lock(rdev, ring, 10); 186 if (r) { 187 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r); 188 goto done; 189 } 190 191 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0); 192 radeon_ring_write(ring, tmp); 193 radeon_ring_write(ring, 0xFFFFF); 194 195 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0); 196 radeon_ring_write(ring, tmp); 197 radeon_ring_write(ring, 0xFFFFF); 198 199 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0); 200 radeon_ring_write(ring, tmp); 201 radeon_ring_write(ring, 0xFFFFF); 202 203 /* Clear timeout status bits */ 204 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0)); 205 radeon_ring_write(ring, 0x8); 206 207 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0)); 208 radeon_ring_write(ring, 3); 209 210 radeon_ring_unlock_commit(rdev, ring, false); 211 212 done: 213 /* lower clocks again */ 214 radeon_set_uvd_clocks(rdev, 0, 0); 215 216 if (!r) { 217 switch (rdev->family) { 218 case CHIP_RV610: 219 case CHIP_RV630: 220 case CHIP_RV620: 221 /* 64byte granularity workaround */ 222 WREG32(MC_CONFIG, 0); 223 WREG32(MC_CONFIG, 1 << 4); 224 WREG32(RS_DQ_RD_RET_CONF, 0x3f); 225 WREG32(MC_CONFIG, 0x1f); 226 227 /* fall through */ 228 case CHIP_RV670: 229 case CHIP_RV635: 230 231 /* write clean workaround */ 232 WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10); 233 break; 234 235 default: 236 /* TODO: Do we need more? */ 237 break; 238 } 239 240 DRM_INFO("UVD initialized successfully.\n"); 241 } 242 243 return r; 244 } 245 246 /** 247 * uvd_v1_0_fini - stop the hardware block 248 * 249 * @rdev: radeon_device pointer 250 * 251 * Stop the UVD block, mark ring as not ready any more 252 */ 253 void uvd_v1_0_fini(struct radeon_device *rdev) 254 { 255 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 256 257 uvd_v1_0_stop(rdev); 258 ring->ready = false; 259 } 260 261 /** 262 * uvd_v1_0_start - start UVD block 263 * 264 * @rdev: radeon_device pointer 265 * 266 * Setup and start the UVD block 267 */ 268 int uvd_v1_0_start(struct radeon_device *rdev) 269 { 270 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 271 uint32_t rb_bufsz; 272 int i, j, r; 273 274 /* disable byte swapping */ 275 u32 lmi_swap_cntl = 0; 276 u32 mp_swap_cntl = 0; 277 278 /* disable clock gating */ 279 WREG32(UVD_CGC_GATE, 0); 280 281 /* disable interupt */ 282 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); 283 284 /* Stall UMC and register bus before resetting VCPU */ 285 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); 286 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); 287 mdelay(1); 288 289 /* put LMI, VCPU, RBC etc... into reset */ 290 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | 291 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | 292 CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET); 293 mdelay(5); 294 295 /* take UVD block out of reset */ 296 WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD); 297 mdelay(5); 298 299 /* initialize UVD memory controller */ 300 WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | 301 (1 << 21) | (1 << 9) | (1 << 20)); 302 303 #ifdef __BIG_ENDIAN 304 /* swap (8 in 32) RB and IB */ 305 lmi_swap_cntl = 0xa; 306 mp_swap_cntl = 0; 307 #endif 308 WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl); 309 WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl); 310 311 WREG32(UVD_MPC_SET_MUXA0, 0x40c2040); 312 WREG32(UVD_MPC_SET_MUXA1, 0x0); 313 WREG32(UVD_MPC_SET_MUXB0, 0x40c2040); 314 WREG32(UVD_MPC_SET_MUXB1, 0x0); 315 WREG32(UVD_MPC_SET_ALU, 0); 316 WREG32(UVD_MPC_SET_MUX, 0x88); 317 318 /* take all subblocks out of reset, except VCPU */ 319 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); 320 mdelay(5); 321 322 /* enable VCPU clock */ 323 WREG32(UVD_VCPU_CNTL, 1 << 9); 324 325 /* enable UMC */ 326 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); 327 328 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); 329 330 /* boot up the VCPU */ 331 WREG32(UVD_SOFT_RESET, 0); 332 mdelay(10); 333 334 for (i = 0; i < 10; ++i) { 335 uint32_t status; 336 for (j = 0; j < 100; ++j) { 337 status = RREG32(UVD_STATUS); 338 if (status & 2) 339 break; 340 mdelay(10); 341 } 342 r = 0; 343 if (status & 2) 344 break; 345 346 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); 347 WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET); 348 mdelay(10); 349 WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET); 350 mdelay(10); 351 r = -1; 352 } 353 354 if (r) { 355 DRM_ERROR("UVD not responding, giving up!!!\n"); 356 return r; 357 } 358 359 /* enable interupt */ 360 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1)); 361 362 /* force RBC into idle state */ 363 WREG32(UVD_RBC_RB_CNTL, 0x11010101); 364 365 /* Set the write pointer delay */ 366 WREG32(UVD_RBC_RB_WPTR_CNTL, 0); 367 368 /* programm the 4GB memory segment for rptr and ring buffer */ 369 WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) | 370 (0x7 << 16) | (0x1U << 31)); 371 372 /* Initialize the ring buffer's read and write pointers */ 373 WREG32(UVD_RBC_RB_RPTR, 0x0); 374 375 ring->wptr = RREG32(UVD_RBC_RB_RPTR); 376 WREG32(UVD_RBC_RB_WPTR, ring->wptr); 377 378 /* set the ring address */ 379 WREG32(UVD_RBC_RB_BASE, ring->gpu_addr); 380 381 /* Set ring buffer size */ 382 rb_bufsz = order_base_2(ring->ring_size); 383 rb_bufsz = (0x1 << 8) | rb_bufsz; 384 WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f); 385 386 return 0; 387 } 388 389 /** 390 * uvd_v1_0_stop - stop UVD block 391 * 392 * @rdev: radeon_device pointer 393 * 394 * stop the UVD block 395 */ 396 void uvd_v1_0_stop(struct radeon_device *rdev) 397 { 398 /* force RBC into idle state */ 399 WREG32(UVD_RBC_RB_CNTL, 0x11010101); 400 401 /* Stall UMC and register bus before resetting VCPU */ 402 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); 403 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); 404 mdelay(1); 405 406 /* put VCPU into reset */ 407 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); 408 mdelay(5); 409 410 /* disable VCPU clock */ 411 WREG32(UVD_VCPU_CNTL, 0x0); 412 413 /* Unstall UMC and register bus */ 414 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); 415 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); 416 } 417 418 /** 419 * uvd_v1_0_ring_test - register write test 420 * 421 * @rdev: radeon_device pointer 422 * @ring: radeon_ring pointer 423 * 424 * Test if we can successfully write to the context register 425 */ 426 int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) 427 { 428 uint32_t tmp = 0; 429 unsigned i; 430 int r; 431 432 WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD); 433 r = radeon_ring_lock(rdev, ring, 3); 434 if (r) { 435 DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", 436 ring->idx, r); 437 return r; 438 } 439 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); 440 radeon_ring_write(ring, 0xDEADBEEF); 441 radeon_ring_unlock_commit(rdev, ring, false); 442 for (i = 0; i < rdev->usec_timeout; i++) { 443 tmp = RREG32(UVD_CONTEXT_ID); 444 if (tmp == 0xDEADBEEF) 445 break; 446 udelay(1); 447 } 448 449 if (i < rdev->usec_timeout) { 450 DRM_INFO("ring test on %d succeeded in %d usecs\n", 451 ring->idx, i); 452 } else { 453 DRM_ERROR("radeon: ring %d test failed (0x%08X)\n", 454 ring->idx, tmp); 455 r = -EINVAL; 456 } 457 return r; 458 } 459 460 /** 461 * uvd_v1_0_semaphore_emit - emit semaphore command 462 * 463 * @rdev: radeon_device pointer 464 * @ring: radeon_ring pointer 465 * @semaphore: semaphore to emit commands for 466 * @emit_wait: true if we should emit a wait command 467 * 468 * Emit a semaphore command (either wait or signal) to the UVD ring. 469 */ 470 bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, 471 struct radeon_ring *ring, 472 struct radeon_semaphore *semaphore, 473 bool emit_wait) 474 { 475 /* disable semaphores for UVD V1 hardware */ 476 return false; 477 } 478 479 /** 480 * uvd_v1_0_ib_execute - execute indirect buffer 481 * 482 * @rdev: radeon_device pointer 483 * @ib: indirect buffer to execute 484 * 485 * Write ring commands to execute the indirect buffer 486 */ 487 void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 488 { 489 struct radeon_ring *ring = &rdev->ring[ib->ring]; 490 491 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0)); 492 radeon_ring_write(ring, ib->gpu_addr); 493 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0)); 494 radeon_ring_write(ring, ib->length_dw); 495 } 496 497 /** 498 * uvd_v1_0_ib_test - test ib execution 499 * 500 * @rdev: radeon_device pointer 501 * @ring: radeon_ring pointer 502 * 503 * Test if we can successfully execute an IB 504 */ 505 int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) 506 { 507 struct radeon_fence *fence = NULL; 508 int r; 509 510 if (rdev->family < CHIP_RV740) 511 r = radeon_set_uvd_clocks(rdev, 10000, 10000); 512 else 513 r = radeon_set_uvd_clocks(rdev, 53300, 40000); 514 if (r) { 515 DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r); 516 return r; 517 } 518 519 r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL); 520 if (r) { 521 DRM_ERROR("radeon: failed to get create msg (%d).\n", r); 522 goto error; 523 } 524 525 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence); 526 if (r) { 527 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r); 528 goto error; 529 } 530 531 r = radeon_fence_wait_timeout(fence, false, usecs_to_jiffies( 532 RADEON_USEC_IB_TEST_TIMEOUT)); 533 if (r < 0) { 534 DRM_ERROR("radeon: fence wait failed (%d).\n", r); 535 goto error; 536 } else if (r == 0) { 537 DRM_ERROR("radeon: fence wait timed out.\n"); 538 r = -ETIMEDOUT; 539 goto error; 540 } 541 r = 0; 542 DRM_INFO("ib test on ring %d succeeded\n", ring->idx); 543 error: 544 radeon_fence_unref(&fence); 545 radeon_set_uvd_clocks(rdev, 0, 0); 546 return r; 547 } 548