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