1 /* 2 * Copyright 2011 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 */ 26 /* 27 * Authors: 28 * Christian König <deathsimple@vodafone.de> 29 */ 30 31 #include <linux/firmware.h> 32 #include <linux/module.h> 33 #include <drm/drmP.h> 34 #include <drm/drm.h> 35 36 #include "radeon.h" 37 #include "r600d.h" 38 39 /* 1 second timeout */ 40 #define UVD_IDLE_TIMEOUT_MS 1000 41 42 /* Firmware Names */ 43 #define FIRMWARE_RV710 "radeon/RV710_uvd.bin" 44 #define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin" 45 #define FIRMWARE_SUMO "radeon/SUMO_uvd.bin" 46 #define FIRMWARE_TAHITI "radeon/TAHITI_uvd.bin" 47 #define FIRMWARE_BONAIRE "radeon/BONAIRE_uvd.bin" 48 49 MODULE_FIRMWARE(FIRMWARE_RV710); 50 MODULE_FIRMWARE(FIRMWARE_CYPRESS); 51 MODULE_FIRMWARE(FIRMWARE_SUMO); 52 MODULE_FIRMWARE(FIRMWARE_TAHITI); 53 MODULE_FIRMWARE(FIRMWARE_BONAIRE); 54 55 static void radeon_uvd_idle_work_handler(struct work_struct *work); 56 57 int radeon_uvd_init(struct radeon_device *rdev) 58 { 59 const struct firmware *fw; 60 unsigned long bo_size; 61 const char *fw_name; 62 int i, r; 63 64 INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler); 65 66 switch (rdev->family) { 67 case CHIP_RV710: 68 case CHIP_RV730: 69 case CHIP_RV740: 70 fw_name = FIRMWARE_RV710; 71 break; 72 73 case CHIP_CYPRESS: 74 case CHIP_HEMLOCK: 75 case CHIP_JUNIPER: 76 case CHIP_REDWOOD: 77 case CHIP_CEDAR: 78 fw_name = FIRMWARE_CYPRESS; 79 break; 80 81 case CHIP_SUMO: 82 case CHIP_SUMO2: 83 case CHIP_PALM: 84 case CHIP_CAYMAN: 85 case CHIP_BARTS: 86 case CHIP_TURKS: 87 case CHIP_CAICOS: 88 fw_name = FIRMWARE_SUMO; 89 break; 90 91 case CHIP_TAHITI: 92 case CHIP_VERDE: 93 case CHIP_PITCAIRN: 94 case CHIP_ARUBA: 95 fw_name = FIRMWARE_TAHITI; 96 break; 97 98 case CHIP_BONAIRE: 99 case CHIP_KABINI: 100 case CHIP_KAVERI: 101 fw_name = FIRMWARE_BONAIRE; 102 break; 103 104 default: 105 return -EINVAL; 106 } 107 108 r = request_firmware(&fw, fw_name, rdev->dev); 109 if (r) { 110 dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", 111 fw_name); 112 return r; 113 } 114 115 bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) + 116 RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; 117 r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, 118 RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); 119 if (r) { 120 dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r); 121 return r; 122 } 123 124 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); 125 if (r) { 126 radeon_bo_unref(&rdev->uvd.vcpu_bo); 127 dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); 128 return r; 129 } 130 131 r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, 132 &rdev->uvd.gpu_addr); 133 if (r) { 134 radeon_bo_unreserve(rdev->uvd.vcpu_bo); 135 radeon_bo_unref(&rdev->uvd.vcpu_bo); 136 dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); 137 return r; 138 } 139 140 r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); 141 if (r) { 142 dev_err(rdev->dev, "(%d) UVD map failed\n", r); 143 return r; 144 } 145 146 radeon_bo_unreserve(rdev->uvd.vcpu_bo); 147 148 rdev->uvd.fw_size = fw->size; 149 memset(rdev->uvd.cpu_addr, 0, bo_size); 150 memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); 151 152 release_firmware(fw); 153 154 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { 155 atomic_set(&rdev->uvd.handles[i], 0); 156 rdev->uvd.filp[i] = NULL; 157 } 158 159 return 0; 160 } 161 162 void radeon_uvd_fini(struct radeon_device *rdev) 163 { 164 int r; 165 166 if (rdev->uvd.vcpu_bo == NULL) 167 return; 168 169 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); 170 if (!r) { 171 radeon_bo_kunmap(rdev->uvd.vcpu_bo); 172 radeon_bo_unpin(rdev->uvd.vcpu_bo); 173 radeon_bo_unreserve(rdev->uvd.vcpu_bo); 174 } 175 176 radeon_bo_unref(&rdev->uvd.vcpu_bo); 177 } 178 179 int radeon_uvd_suspend(struct radeon_device *rdev) 180 { 181 unsigned size; 182 183 if (rdev->uvd.vcpu_bo == NULL) 184 return 0; 185 186 size = radeon_bo_size(rdev->uvd.vcpu_bo); 187 rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); 188 memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); 189 190 return 0; 191 } 192 193 int radeon_uvd_resume(struct radeon_device *rdev) 194 { 195 if (rdev->uvd.vcpu_bo == NULL) 196 return -EINVAL; 197 198 if (rdev->uvd.saved_bo != NULL) { 199 unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo); 200 memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); 201 kfree(rdev->uvd.saved_bo); 202 rdev->uvd.saved_bo = NULL; 203 } 204 205 return 0; 206 } 207 208 void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo) 209 { 210 rbo->placement.fpfn = 0 >> PAGE_SHIFT; 211 rbo->placement.lpfn = (256 * 1024 * 1024) >> PAGE_SHIFT; 212 } 213 214 void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) 215 { 216 int i, r; 217 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { 218 if (rdev->uvd.filp[i] == filp) { 219 uint32_t handle = atomic_read(&rdev->uvd.handles[i]); 220 struct radeon_fence *fence; 221 222 r = radeon_uvd_get_destroy_msg(rdev, 223 R600_RING_TYPE_UVD_INDEX, handle, &fence); 224 if (r) { 225 DRM_ERROR("Error destroying UVD (%d)!\n", r); 226 continue; 227 } 228 229 radeon_fence_wait(fence, false); 230 radeon_fence_unref(&fence); 231 232 rdev->uvd.filp[i] = NULL; 233 atomic_set(&rdev->uvd.handles[i], 0); 234 } 235 } 236 } 237 238 static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) 239 { 240 unsigned stream_type = msg[4]; 241 unsigned width = msg[6]; 242 unsigned height = msg[7]; 243 unsigned dpb_size = msg[9]; 244 unsigned pitch = msg[28]; 245 246 unsigned width_in_mb = width / 16; 247 unsigned height_in_mb = ALIGN(height / 16, 2); 248 249 unsigned image_size, tmp, min_dpb_size; 250 251 image_size = width * height; 252 image_size += image_size / 2; 253 image_size = ALIGN(image_size, 1024); 254 255 switch (stream_type) { 256 case 0: /* H264 */ 257 258 /* reference picture buffer */ 259 min_dpb_size = image_size * 17; 260 261 /* macroblock context buffer */ 262 min_dpb_size += width_in_mb * height_in_mb * 17 * 192; 263 264 /* IT surface buffer */ 265 min_dpb_size += width_in_mb * height_in_mb * 32; 266 break; 267 268 case 1: /* VC1 */ 269 270 /* reference picture buffer */ 271 min_dpb_size = image_size * 3; 272 273 /* CONTEXT_BUFFER */ 274 min_dpb_size += width_in_mb * height_in_mb * 128; 275 276 /* IT surface buffer */ 277 min_dpb_size += width_in_mb * 64; 278 279 /* DB surface buffer */ 280 min_dpb_size += width_in_mb * 128; 281 282 /* BP */ 283 tmp = max(width_in_mb, height_in_mb); 284 min_dpb_size += ALIGN(tmp * 7 * 16, 64); 285 break; 286 287 case 3: /* MPEG2 */ 288 289 /* reference picture buffer */ 290 min_dpb_size = image_size * 3; 291 break; 292 293 case 4: /* MPEG4 */ 294 295 /* reference picture buffer */ 296 min_dpb_size = image_size * 3; 297 298 /* CM */ 299 min_dpb_size += width_in_mb * height_in_mb * 64; 300 301 /* IT surface buffer */ 302 min_dpb_size += ALIGN(width_in_mb * height_in_mb * 32, 64); 303 break; 304 305 default: 306 DRM_ERROR("UVD codec not handled %d!\n", stream_type); 307 return -EINVAL; 308 } 309 310 if (width > pitch) { 311 DRM_ERROR("Invalid UVD decoding target pitch!\n"); 312 return -EINVAL; 313 } 314 315 if (dpb_size < min_dpb_size) { 316 DRM_ERROR("Invalid dpb_size in UVD message (%d / %d)!\n", 317 dpb_size, min_dpb_size); 318 return -EINVAL; 319 } 320 321 buf_sizes[0x1] = dpb_size; 322 buf_sizes[0x2] = image_size; 323 return 0; 324 } 325 326 static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, 327 unsigned offset, unsigned buf_sizes[]) 328 { 329 int32_t *msg, msg_type, handle; 330 void *ptr; 331 332 int i, r; 333 334 if (offset & 0x3F) { 335 DRM_ERROR("UVD messages must be 64 byte aligned!\n"); 336 return -EINVAL; 337 } 338 339 r = radeon_bo_kmap(bo, &ptr); 340 if (r) 341 return r; 342 343 msg = ptr + offset; 344 345 msg_type = msg[1]; 346 handle = msg[2]; 347 348 if (handle == 0) { 349 DRM_ERROR("Invalid UVD handle!\n"); 350 return -EINVAL; 351 } 352 353 if (msg_type == 1) { 354 /* it's a decode msg, calc buffer sizes */ 355 r = radeon_uvd_cs_msg_decode(msg, buf_sizes); 356 radeon_bo_kunmap(bo); 357 if (r) 358 return r; 359 360 } else if (msg_type == 2) { 361 /* it's a destroy msg, free the handle */ 362 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) 363 atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); 364 radeon_bo_kunmap(bo); 365 return 0; 366 } else { 367 /* it's a create msg, no special handling needed */ 368 radeon_bo_kunmap(bo); 369 } 370 371 /* create or decode, validate the handle */ 372 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { 373 if (atomic_read(&p->rdev->uvd.handles[i]) == handle) 374 return 0; 375 } 376 377 /* handle not found try to alloc a new one */ 378 for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { 379 if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) { 380 p->rdev->uvd.filp[i] = p->filp; 381 return 0; 382 } 383 } 384 385 DRM_ERROR("No more free UVD handles!\n"); 386 return -EINVAL; 387 } 388 389 static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, 390 int data0, int data1, 391 unsigned buf_sizes[]) 392 { 393 struct radeon_cs_chunk *relocs_chunk; 394 struct radeon_cs_reloc *reloc; 395 unsigned idx, cmd, offset; 396 uint64_t start, end; 397 int r; 398 399 relocs_chunk = &p->chunks[p->chunk_relocs_idx]; 400 offset = radeon_get_ib_value(p, data0); 401 idx = radeon_get_ib_value(p, data1); 402 if (idx >= relocs_chunk->length_dw) { 403 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", 404 idx, relocs_chunk->length_dw); 405 return -EINVAL; 406 } 407 408 reloc = p->relocs_ptr[(idx / 4)]; 409 start = reloc->lobj.gpu_offset; 410 end = start + radeon_bo_size(reloc->robj); 411 start += offset; 412 413 p->ib.ptr[data0] = start & 0xFFFFFFFF; 414 p->ib.ptr[data1] = start >> 32; 415 416 cmd = radeon_get_ib_value(p, p->idx) >> 1; 417 418 if (cmd < 0x4) { 419 if ((end - start) < buf_sizes[cmd]) { 420 DRM_ERROR("buffer to small (%d / %d)!\n", 421 (unsigned)(end - start), buf_sizes[cmd]); 422 return -EINVAL; 423 } 424 425 } else if (cmd != 0x100) { 426 DRM_ERROR("invalid UVD command %X!\n", cmd); 427 return -EINVAL; 428 } 429 430 if ((start >> 28) != (end >> 28)) { 431 DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n", 432 start, end); 433 return -EINVAL; 434 } 435 436 /* TODO: is this still necessary on NI+ ? */ 437 if ((cmd == 0 || cmd == 0x3) && 438 (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) { 439 DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", 440 start, end); 441 return -EINVAL; 442 } 443 444 if (cmd == 0) { 445 r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes); 446 if (r) 447 return r; 448 } 449 450 return 0; 451 } 452 453 static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, 454 struct radeon_cs_packet *pkt, 455 int *data0, int *data1, 456 unsigned buf_sizes[]) 457 { 458 int i, r; 459 460 p->idx++; 461 for (i = 0; i <= pkt->count; ++i) { 462 switch (pkt->reg + i*4) { 463 case UVD_GPCOM_VCPU_DATA0: 464 *data0 = p->idx; 465 break; 466 case UVD_GPCOM_VCPU_DATA1: 467 *data1 = p->idx; 468 break; 469 case UVD_GPCOM_VCPU_CMD: 470 r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes); 471 if (r) 472 return r; 473 break; 474 case UVD_ENGINE_CNTL: 475 break; 476 default: 477 DRM_ERROR("Invalid reg 0x%X!\n", 478 pkt->reg + i*4); 479 return -EINVAL; 480 } 481 p->idx++; 482 } 483 return 0; 484 } 485 486 int radeon_uvd_cs_parse(struct radeon_cs_parser *p) 487 { 488 struct radeon_cs_packet pkt; 489 int r, data0 = 0, data1 = 0; 490 491 /* minimum buffer sizes */ 492 unsigned buf_sizes[] = { 493 [0x00000000] = 2048, 494 [0x00000001] = 32 * 1024 * 1024, 495 [0x00000002] = 2048 * 1152 * 3, 496 [0x00000003] = 2048, 497 }; 498 499 if (p->chunks[p->chunk_ib_idx].length_dw % 16) { 500 DRM_ERROR("UVD IB length (%d) not 16 dwords aligned!\n", 501 p->chunks[p->chunk_ib_idx].length_dw); 502 return -EINVAL; 503 } 504 505 if (p->chunk_relocs_idx == -1) { 506 DRM_ERROR("No relocation chunk !\n"); 507 return -EINVAL; 508 } 509 510 511 do { 512 r = radeon_cs_packet_parse(p, &pkt, p->idx); 513 if (r) 514 return r; 515 switch (pkt.type) { 516 case RADEON_PACKET_TYPE0: 517 r = radeon_uvd_cs_reg(p, &pkt, &data0, 518 &data1, buf_sizes); 519 if (r) 520 return r; 521 break; 522 case RADEON_PACKET_TYPE2: 523 p->idx += pkt.count + 2; 524 break; 525 default: 526 DRM_ERROR("Unknown packet type %d !\n", pkt.type); 527 return -EINVAL; 528 } 529 } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); 530 return 0; 531 } 532 533 static int radeon_uvd_send_msg(struct radeon_device *rdev, 534 int ring, struct radeon_bo *bo, 535 struct radeon_fence **fence) 536 { 537 struct ttm_validate_buffer tv; 538 struct ww_acquire_ctx ticket; 539 struct list_head head; 540 struct radeon_ib ib; 541 uint64_t addr; 542 int i, r; 543 544 memset(&tv, 0, sizeof(tv)); 545 tv.bo = &bo->tbo; 546 547 INIT_LIST_HEAD(&head); 548 list_add(&tv.head, &head); 549 550 r = ttm_eu_reserve_buffers(&ticket, &head); 551 if (r) 552 return r; 553 554 radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_VRAM); 555 radeon_uvd_force_into_uvd_segment(bo); 556 557 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 558 if (r) 559 goto err; 560 561 r = radeon_ib_get(rdev, ring, &ib, NULL, 16); 562 if (r) 563 goto err; 564 565 addr = radeon_bo_gpu_offset(bo); 566 ib.ptr[0] = PACKET0(UVD_GPCOM_VCPU_DATA0, 0); 567 ib.ptr[1] = addr; 568 ib.ptr[2] = PACKET0(UVD_GPCOM_VCPU_DATA1, 0); 569 ib.ptr[3] = addr >> 32; 570 ib.ptr[4] = PACKET0(UVD_GPCOM_VCPU_CMD, 0); 571 ib.ptr[5] = 0; 572 for (i = 6; i < 16; ++i) 573 ib.ptr[i] = PACKET2(0); 574 ib.length_dw = 16; 575 576 r = radeon_ib_schedule(rdev, &ib, NULL); 577 if (r) 578 goto err; 579 ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence); 580 581 if (fence) 582 *fence = radeon_fence_ref(ib.fence); 583 584 radeon_ib_free(rdev, &ib); 585 radeon_bo_unref(&bo); 586 return 0; 587 588 err: 589 ttm_eu_backoff_reservation(&ticket, &head); 590 return r; 591 } 592 593 /* multiple fence commands without any stream commands in between can 594 crash the vcpu so just try to emmit a dummy create/destroy msg to 595 avoid this */ 596 int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, 597 uint32_t handle, struct radeon_fence **fence) 598 { 599 struct radeon_bo *bo; 600 uint32_t *msg; 601 int r, i; 602 603 r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true, 604 RADEON_GEM_DOMAIN_VRAM, NULL, &bo); 605 if (r) 606 return r; 607 608 r = radeon_bo_reserve(bo, false); 609 if (r) { 610 radeon_bo_unref(&bo); 611 return r; 612 } 613 614 r = radeon_bo_kmap(bo, (void **)&msg); 615 if (r) { 616 radeon_bo_unreserve(bo); 617 radeon_bo_unref(&bo); 618 return r; 619 } 620 621 /* stitch together an UVD create msg */ 622 msg[0] = cpu_to_le32(0x00000de4); 623 msg[1] = cpu_to_le32(0x00000000); 624 msg[2] = cpu_to_le32(handle); 625 msg[3] = cpu_to_le32(0x00000000); 626 msg[4] = cpu_to_le32(0x00000000); 627 msg[5] = cpu_to_le32(0x00000000); 628 msg[6] = cpu_to_le32(0x00000000); 629 msg[7] = cpu_to_le32(0x00000780); 630 msg[8] = cpu_to_le32(0x00000440); 631 msg[9] = cpu_to_le32(0x00000000); 632 msg[10] = cpu_to_le32(0x01b37000); 633 for (i = 11; i < 1024; ++i) 634 msg[i] = cpu_to_le32(0x0); 635 636 radeon_bo_kunmap(bo); 637 radeon_bo_unreserve(bo); 638 639 return radeon_uvd_send_msg(rdev, ring, bo, fence); 640 } 641 642 int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, 643 uint32_t handle, struct radeon_fence **fence) 644 { 645 struct radeon_bo *bo; 646 uint32_t *msg; 647 int r, i; 648 649 r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true, 650 RADEON_GEM_DOMAIN_VRAM, NULL, &bo); 651 if (r) 652 return r; 653 654 r = radeon_bo_reserve(bo, false); 655 if (r) { 656 radeon_bo_unref(&bo); 657 return r; 658 } 659 660 r = radeon_bo_kmap(bo, (void **)&msg); 661 if (r) { 662 radeon_bo_unreserve(bo); 663 radeon_bo_unref(&bo); 664 return r; 665 } 666 667 /* stitch together an UVD destroy msg */ 668 msg[0] = cpu_to_le32(0x00000de4); 669 msg[1] = cpu_to_le32(0x00000002); 670 msg[2] = cpu_to_le32(handle); 671 msg[3] = cpu_to_le32(0x00000000); 672 for (i = 4; i < 1024; ++i) 673 msg[i] = cpu_to_le32(0x0); 674 675 radeon_bo_kunmap(bo); 676 radeon_bo_unreserve(bo); 677 678 return radeon_uvd_send_msg(rdev, ring, bo, fence); 679 } 680 681 static void radeon_uvd_idle_work_handler(struct work_struct *work) 682 { 683 struct radeon_device *rdev = 684 container_of(work, struct radeon_device, uvd.idle_work.work); 685 686 if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) { 687 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 688 mutex_lock(&rdev->pm.mutex); 689 rdev->pm.dpm.uvd_active = false; 690 mutex_unlock(&rdev->pm.mutex); 691 radeon_pm_compute_clocks(rdev); 692 } else { 693 radeon_set_uvd_clocks(rdev, 0, 0); 694 } 695 } else { 696 schedule_delayed_work(&rdev->uvd.idle_work, 697 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS)); 698 } 699 } 700 701 void radeon_uvd_note_usage(struct radeon_device *rdev) 702 { 703 bool set_clocks = !cancel_delayed_work_sync(&rdev->uvd.idle_work); 704 set_clocks &= schedule_delayed_work(&rdev->uvd.idle_work, 705 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS)); 706 if (set_clocks) { 707 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 708 /* XXX pick SD/HD/MVC */ 709 radeon_dpm_enable_power_state(rdev, POWER_STATE_TYPE_INTERNAL_UVD); 710 } else { 711 radeon_set_uvd_clocks(rdev, 53300, 40000); 712 } 713 } 714 } 715 716 static unsigned radeon_uvd_calc_upll_post_div(unsigned vco_freq, 717 unsigned target_freq, 718 unsigned pd_min, 719 unsigned pd_even) 720 { 721 unsigned post_div = vco_freq / target_freq; 722 723 /* adjust to post divider minimum value */ 724 if (post_div < pd_min) 725 post_div = pd_min; 726 727 /* we alway need a frequency less than or equal the target */ 728 if ((vco_freq / post_div) > target_freq) 729 post_div += 1; 730 731 /* post dividers above a certain value must be even */ 732 if (post_div > pd_even && post_div % 2) 733 post_div += 1; 734 735 return post_div; 736 } 737 738 /** 739 * radeon_uvd_calc_upll_dividers - calc UPLL clock dividers 740 * 741 * @rdev: radeon_device pointer 742 * @vclk: wanted VCLK 743 * @dclk: wanted DCLK 744 * @vco_min: minimum VCO frequency 745 * @vco_max: maximum VCO frequency 746 * @fb_factor: factor to multiply vco freq with 747 * @fb_mask: limit and bitmask for feedback divider 748 * @pd_min: post divider minimum 749 * @pd_max: post divider maximum 750 * @pd_even: post divider must be even above this value 751 * @optimal_fb_div: resulting feedback divider 752 * @optimal_vclk_div: resulting vclk post divider 753 * @optimal_dclk_div: resulting dclk post divider 754 * 755 * Calculate dividers for UVDs UPLL (R6xx-SI, except APUs). 756 * Returns zero on success -EINVAL on error. 757 */ 758 int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev, 759 unsigned vclk, unsigned dclk, 760 unsigned vco_min, unsigned vco_max, 761 unsigned fb_factor, unsigned fb_mask, 762 unsigned pd_min, unsigned pd_max, 763 unsigned pd_even, 764 unsigned *optimal_fb_div, 765 unsigned *optimal_vclk_div, 766 unsigned *optimal_dclk_div) 767 { 768 unsigned vco_freq, ref_freq = rdev->clock.spll.reference_freq; 769 770 /* start off with something large */ 771 unsigned optimal_score = ~0; 772 773 /* loop through vco from low to high */ 774 vco_min = max(max(vco_min, vclk), dclk); 775 for (vco_freq = vco_min; vco_freq <= vco_max; vco_freq += 100) { 776 777 uint64_t fb_div = (uint64_t)vco_freq * fb_factor; 778 unsigned vclk_div, dclk_div, score; 779 780 do_div(fb_div, ref_freq); 781 782 /* fb div out of range ? */ 783 if (fb_div > fb_mask) 784 break; /* it can oly get worse */ 785 786 fb_div &= fb_mask; 787 788 /* calc vclk divider with current vco freq */ 789 vclk_div = radeon_uvd_calc_upll_post_div(vco_freq, vclk, 790 pd_min, pd_even); 791 if (vclk_div > pd_max) 792 break; /* vco is too big, it has to stop */ 793 794 /* calc dclk divider with current vco freq */ 795 dclk_div = radeon_uvd_calc_upll_post_div(vco_freq, dclk, 796 pd_min, pd_even); 797 if (vclk_div > pd_max) 798 break; /* vco is too big, it has to stop */ 799 800 /* calc score with current vco freq */ 801 score = vclk - (vco_freq / vclk_div) + dclk - (vco_freq / dclk_div); 802 803 /* determine if this vco setting is better than current optimal settings */ 804 if (score < optimal_score) { 805 *optimal_fb_div = fb_div; 806 *optimal_vclk_div = vclk_div; 807 *optimal_dclk_div = dclk_div; 808 optimal_score = score; 809 if (optimal_score == 0) 810 break; /* it can't get better than this */ 811 } 812 } 813 814 /* did we found a valid setup ? */ 815 if (optimal_score == ~0) 816 return -EINVAL; 817 818 return 0; 819 } 820 821 int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev, 822 unsigned cg_upll_func_cntl) 823 { 824 unsigned i; 825 826 /* make sure UPLL_CTLREQ is deasserted */ 827 WREG32_P(cg_upll_func_cntl, 0, ~UPLL_CTLREQ_MASK); 828 829 mdelay(10); 830 831 /* assert UPLL_CTLREQ */ 832 WREG32_P(cg_upll_func_cntl, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK); 833 834 /* wait for CTLACK and CTLACK2 to get asserted */ 835 for (i = 0; i < 100; ++i) { 836 uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK; 837 if ((RREG32(cg_upll_func_cntl) & mask) == mask) 838 break; 839 mdelay(10); 840 } 841 842 /* deassert UPLL_CTLREQ */ 843 WREG32_P(cg_upll_func_cntl, 0, ~UPLL_CTLREQ_MASK); 844 845 if (i == 100) { 846 DRM_ERROR("Timeout setting UVD clocks!\n"); 847 return -ETIMEDOUT; 848 } 849 850 return 0; 851 } 852