0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/firmware.h>
0032 #include <linux/module.h>
0033
0034 #include <drm/drm.h>
0035
0036 #include "radeon.h"
0037 #include "radeon_ucode.h"
0038 #include "r600d.h"
0039
0040
0041 #define UVD_IDLE_TIMEOUT_MS 1000
0042
0043
0044 #define FIRMWARE_R600 "radeon/R600_uvd.bin"
0045 #define FIRMWARE_RS780 "radeon/RS780_uvd.bin"
0046 #define FIRMWARE_RV770 "radeon/RV770_uvd.bin"
0047 #define FIRMWARE_RV710 "radeon/RV710_uvd.bin"
0048 #define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin"
0049 #define FIRMWARE_SUMO "radeon/SUMO_uvd.bin"
0050 #define FIRMWARE_TAHITI "radeon/TAHITI_uvd.bin"
0051 #define FIRMWARE_BONAIRE_LEGACY "radeon/BONAIRE_uvd.bin"
0052 #define FIRMWARE_BONAIRE "radeon/bonaire_uvd.bin"
0053
0054 MODULE_FIRMWARE(FIRMWARE_R600);
0055 MODULE_FIRMWARE(FIRMWARE_RS780);
0056 MODULE_FIRMWARE(FIRMWARE_RV770);
0057 MODULE_FIRMWARE(FIRMWARE_RV710);
0058 MODULE_FIRMWARE(FIRMWARE_CYPRESS);
0059 MODULE_FIRMWARE(FIRMWARE_SUMO);
0060 MODULE_FIRMWARE(FIRMWARE_TAHITI);
0061 MODULE_FIRMWARE(FIRMWARE_BONAIRE_LEGACY);
0062 MODULE_FIRMWARE(FIRMWARE_BONAIRE);
0063
0064 static void radeon_uvd_idle_work_handler(struct work_struct *work);
0065
0066 int radeon_uvd_init(struct radeon_device *rdev)
0067 {
0068 unsigned long bo_size;
0069 const char *fw_name = NULL, *legacy_fw_name = NULL;
0070 int i, r;
0071
0072 INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
0073
0074 switch (rdev->family) {
0075 case CHIP_RV610:
0076 case CHIP_RV630:
0077 case CHIP_RV670:
0078 case CHIP_RV620:
0079 case CHIP_RV635:
0080 legacy_fw_name = FIRMWARE_R600;
0081 break;
0082
0083 case CHIP_RS780:
0084 case CHIP_RS880:
0085 legacy_fw_name = FIRMWARE_RS780;
0086 break;
0087
0088 case CHIP_RV770:
0089 legacy_fw_name = FIRMWARE_RV770;
0090 break;
0091
0092 case CHIP_RV710:
0093 case CHIP_RV730:
0094 case CHIP_RV740:
0095 legacy_fw_name = FIRMWARE_RV710;
0096 break;
0097
0098 case CHIP_CYPRESS:
0099 case CHIP_HEMLOCK:
0100 case CHIP_JUNIPER:
0101 case CHIP_REDWOOD:
0102 case CHIP_CEDAR:
0103 legacy_fw_name = FIRMWARE_CYPRESS;
0104 break;
0105
0106 case CHIP_SUMO:
0107 case CHIP_SUMO2:
0108 case CHIP_PALM:
0109 case CHIP_CAYMAN:
0110 case CHIP_BARTS:
0111 case CHIP_TURKS:
0112 case CHIP_CAICOS:
0113 legacy_fw_name = FIRMWARE_SUMO;
0114 break;
0115
0116 case CHIP_TAHITI:
0117 case CHIP_VERDE:
0118 case CHIP_PITCAIRN:
0119 case CHIP_ARUBA:
0120 case CHIP_OLAND:
0121 legacy_fw_name = FIRMWARE_TAHITI;
0122 break;
0123
0124 case CHIP_BONAIRE:
0125 case CHIP_KABINI:
0126 case CHIP_KAVERI:
0127 case CHIP_HAWAII:
0128 case CHIP_MULLINS:
0129 legacy_fw_name = FIRMWARE_BONAIRE_LEGACY;
0130 fw_name = FIRMWARE_BONAIRE;
0131 break;
0132
0133 default:
0134 return -EINVAL;
0135 }
0136
0137 rdev->uvd.fw_header_present = false;
0138 rdev->uvd.max_handles = RADEON_DEFAULT_UVD_HANDLES;
0139 if (fw_name) {
0140
0141 r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
0142 if (r) {
0143 dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
0144 fw_name);
0145 } else {
0146 struct common_firmware_header *hdr = (void *)rdev->uvd_fw->data;
0147 unsigned version_major, version_minor, family_id;
0148
0149 r = radeon_ucode_validate(rdev->uvd_fw);
0150 if (r)
0151 return r;
0152
0153 rdev->uvd.fw_header_present = true;
0154
0155 family_id = (__force u32)(hdr->ucode_version) & 0xff;
0156 version_major = (le32_to_cpu((__force __le32)(hdr->ucode_version))
0157 >> 24) & 0xff;
0158 version_minor = (le32_to_cpu((__force __le32)(hdr->ucode_version))
0159 >> 8) & 0xff;
0160 DRM_INFO("Found UVD firmware Version: %u.%u Family ID: %u\n",
0161 version_major, version_minor, family_id);
0162
0163
0164
0165
0166
0167 if ((version_major >= 0x01) && (version_minor >= 0x37))
0168 rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES;
0169 }
0170 }
0171
0172
0173
0174
0175
0176
0177 if (!fw_name || r) {
0178 r = request_firmware(&rdev->uvd_fw, legacy_fw_name, rdev->dev);
0179 if (r) {
0180 dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
0181 legacy_fw_name);
0182 return r;
0183 }
0184 }
0185
0186 bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
0187 RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE +
0188 RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles;
0189 r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
0190 RADEON_GEM_DOMAIN_VRAM, 0, NULL,
0191 NULL, &rdev->uvd.vcpu_bo);
0192 if (r) {
0193 dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r);
0194 return r;
0195 }
0196
0197 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
0198 if (r) {
0199 radeon_bo_unref(&rdev->uvd.vcpu_bo);
0200 dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r);
0201 return r;
0202 }
0203
0204 r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
0205 &rdev->uvd.gpu_addr);
0206 if (r) {
0207 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
0208 radeon_bo_unref(&rdev->uvd.vcpu_bo);
0209 dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r);
0210 return r;
0211 }
0212
0213 r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
0214 if (r) {
0215 dev_err(rdev->dev, "(%d) UVD map failed\n", r);
0216 return r;
0217 }
0218
0219 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
0220
0221 for (i = 0; i < rdev->uvd.max_handles; ++i) {
0222 atomic_set(&rdev->uvd.handles[i], 0);
0223 rdev->uvd.filp[i] = NULL;
0224 rdev->uvd.img_size[i] = 0;
0225 }
0226
0227 return 0;
0228 }
0229
0230 void radeon_uvd_fini(struct radeon_device *rdev)
0231 {
0232 int r;
0233
0234 if (rdev->uvd.vcpu_bo == NULL)
0235 return;
0236
0237 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
0238 if (!r) {
0239 radeon_bo_kunmap(rdev->uvd.vcpu_bo);
0240 radeon_bo_unpin(rdev->uvd.vcpu_bo);
0241 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
0242 }
0243
0244 radeon_bo_unref(&rdev->uvd.vcpu_bo);
0245
0246 radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
0247
0248 release_firmware(rdev->uvd_fw);
0249 }
0250
0251 int radeon_uvd_suspend(struct radeon_device *rdev)
0252 {
0253 int i, r;
0254
0255 if (rdev->uvd.vcpu_bo == NULL)
0256 return 0;
0257
0258 for (i = 0; i < rdev->uvd.max_handles; ++i) {
0259 uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
0260 if (handle != 0) {
0261 struct radeon_fence *fence;
0262
0263 radeon_uvd_note_usage(rdev);
0264
0265 r = radeon_uvd_get_destroy_msg(rdev,
0266 R600_RING_TYPE_UVD_INDEX, handle, &fence);
0267 if (r) {
0268 DRM_ERROR("Error destroying UVD (%d)!\n", r);
0269 continue;
0270 }
0271
0272 radeon_fence_wait(fence, false);
0273 radeon_fence_unref(&fence);
0274
0275 rdev->uvd.filp[i] = NULL;
0276 atomic_set(&rdev->uvd.handles[i], 0);
0277 }
0278 }
0279
0280 return 0;
0281 }
0282
0283 int radeon_uvd_resume(struct radeon_device *rdev)
0284 {
0285 unsigned size;
0286 void *ptr;
0287
0288 if (rdev->uvd.vcpu_bo == NULL)
0289 return -EINVAL;
0290
0291 memcpy_toio((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
0292
0293 size = radeon_bo_size(rdev->uvd.vcpu_bo);
0294 size -= rdev->uvd_fw->size;
0295
0296 ptr = rdev->uvd.cpu_addr;
0297 ptr += rdev->uvd_fw->size;
0298
0299 memset_io((void __iomem *)ptr, 0, size);
0300
0301 return 0;
0302 }
0303
0304 void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo,
0305 uint32_t allowed_domains)
0306 {
0307 int i;
0308
0309 for (i = 0; i < rbo->placement.num_placement; ++i) {
0310 rbo->placements[i].fpfn = 0 >> PAGE_SHIFT;
0311 rbo->placements[i].lpfn = (256 * 1024 * 1024) >> PAGE_SHIFT;
0312 }
0313
0314
0315 if (allowed_domains == RADEON_GEM_DOMAIN_VRAM)
0316 return;
0317
0318
0319 if (rbo->placement.num_placement > 1)
0320 return;
0321
0322
0323 rbo->placements[1] = rbo->placements[0];
0324 rbo->placements[1].fpfn += (256 * 1024 * 1024) >> PAGE_SHIFT;
0325 rbo->placements[1].lpfn += (256 * 1024 * 1024) >> PAGE_SHIFT;
0326 rbo->placement.num_placement++;
0327 rbo->placement.num_busy_placement++;
0328 }
0329
0330 void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp)
0331 {
0332 int i, r;
0333 for (i = 0; i < rdev->uvd.max_handles; ++i) {
0334 uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
0335 if (handle != 0 && rdev->uvd.filp[i] == filp) {
0336 struct radeon_fence *fence;
0337
0338 radeon_uvd_note_usage(rdev);
0339
0340 r = radeon_uvd_get_destroy_msg(rdev,
0341 R600_RING_TYPE_UVD_INDEX, handle, &fence);
0342 if (r) {
0343 DRM_ERROR("Error destroying UVD (%d)!\n", r);
0344 continue;
0345 }
0346
0347 radeon_fence_wait(fence, false);
0348 radeon_fence_unref(&fence);
0349
0350 rdev->uvd.filp[i] = NULL;
0351 atomic_set(&rdev->uvd.handles[i], 0);
0352 }
0353 }
0354 }
0355
0356 static int radeon_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[])
0357 {
0358 unsigned stream_type = msg[4];
0359 unsigned width = msg[6];
0360 unsigned height = msg[7];
0361 unsigned dpb_size = msg[9];
0362 unsigned pitch = msg[28];
0363
0364 unsigned width_in_mb = width / 16;
0365 unsigned height_in_mb = ALIGN(height / 16, 2);
0366
0367 unsigned image_size, tmp, min_dpb_size;
0368
0369 image_size = width * height;
0370 image_size += image_size / 2;
0371 image_size = ALIGN(image_size, 1024);
0372
0373 switch (stream_type) {
0374 case 0:
0375
0376
0377 min_dpb_size = image_size * 17;
0378
0379
0380 min_dpb_size += width_in_mb * height_in_mb * 17 * 192;
0381
0382
0383 min_dpb_size += width_in_mb * height_in_mb * 32;
0384 break;
0385
0386 case 1:
0387
0388
0389 min_dpb_size = image_size * 3;
0390
0391
0392 min_dpb_size += width_in_mb * height_in_mb * 128;
0393
0394
0395 min_dpb_size += width_in_mb * 64;
0396
0397
0398 min_dpb_size += width_in_mb * 128;
0399
0400
0401 tmp = max(width_in_mb, height_in_mb);
0402 min_dpb_size += ALIGN(tmp * 7 * 16, 64);
0403 break;
0404
0405 case 3:
0406
0407
0408 min_dpb_size = image_size * 3;
0409 break;
0410
0411 case 4:
0412
0413
0414 min_dpb_size = image_size * 3;
0415
0416
0417 min_dpb_size += width_in_mb * height_in_mb * 64;
0418
0419
0420 min_dpb_size += ALIGN(width_in_mb * height_in_mb * 32, 64);
0421 break;
0422
0423 default:
0424 DRM_ERROR("UVD codec not handled %d!\n", stream_type);
0425 return -EINVAL;
0426 }
0427
0428 if (width > pitch) {
0429 DRM_ERROR("Invalid UVD decoding target pitch!\n");
0430 return -EINVAL;
0431 }
0432
0433 if (dpb_size < min_dpb_size) {
0434 DRM_ERROR("Invalid dpb_size in UVD message (%d / %d)!\n",
0435 dpb_size, min_dpb_size);
0436 return -EINVAL;
0437 }
0438
0439 buf_sizes[0x1] = dpb_size;
0440 buf_sizes[0x2] = image_size;
0441 return 0;
0442 }
0443
0444 static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,
0445 unsigned stream_type)
0446 {
0447 switch (stream_type) {
0448 case 0:
0449 case 1:
0450
0451 return 0;
0452
0453 case 3:
0454 case 4:
0455
0456 if (p->rdev->family >= CHIP_PALM)
0457 return 0;
0458
0459 fallthrough;
0460 default:
0461 DRM_ERROR("UVD codec not supported by hardware %d!\n",
0462 stream_type);
0463 return -EINVAL;
0464 }
0465 }
0466
0467 static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
0468 unsigned offset, unsigned buf_sizes[])
0469 {
0470 int32_t *msg, msg_type, handle;
0471 unsigned img_size = 0;
0472 void *ptr;
0473 int i, r;
0474
0475 if (offset & 0x3F) {
0476 DRM_ERROR("UVD messages must be 64 byte aligned!\n");
0477 return -EINVAL;
0478 }
0479
0480 r = radeon_bo_kmap(bo, &ptr);
0481 if (r) {
0482 DRM_ERROR("Failed mapping the UVD message (%d)!\n", r);
0483 return r;
0484 }
0485
0486 msg = ptr + offset;
0487
0488 msg_type = msg[1];
0489 handle = msg[2];
0490
0491 if (handle == 0) {
0492 radeon_bo_kunmap(bo);
0493 DRM_ERROR("Invalid UVD handle!\n");
0494 return -EINVAL;
0495 }
0496
0497 switch (msg_type) {
0498 case 0:
0499
0500 img_size = msg[7] * msg[8];
0501
0502 r = radeon_uvd_validate_codec(p, msg[4]);
0503 radeon_bo_kunmap(bo);
0504 if (r)
0505 return r;
0506
0507
0508 for (i = 0; i < p->rdev->uvd.max_handles; ++i) {
0509 if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
0510 DRM_ERROR("Handle 0x%x already in use!\n", handle);
0511 return -EINVAL;
0512 }
0513
0514 if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
0515 p->rdev->uvd.filp[i] = p->filp;
0516 p->rdev->uvd.img_size[i] = img_size;
0517 return 0;
0518 }
0519 }
0520
0521 DRM_ERROR("No more free UVD handles!\n");
0522 return -EINVAL;
0523
0524 case 1:
0525
0526 r = radeon_uvd_validate_codec(p, msg[4]);
0527 if (!r)
0528 r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
0529 radeon_bo_kunmap(bo);
0530 if (r)
0531 return r;
0532
0533
0534 for (i = 0; i < p->rdev->uvd.max_handles; ++i) {
0535 if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
0536 if (p->rdev->uvd.filp[i] != p->filp) {
0537 DRM_ERROR("UVD handle collision detected!\n");
0538 return -EINVAL;
0539 }
0540 return 0;
0541 }
0542 }
0543
0544 DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
0545 return -ENOENT;
0546
0547 case 2:
0548
0549 for (i = 0; i < p->rdev->uvd.max_handles; ++i)
0550 atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
0551 radeon_bo_kunmap(bo);
0552 return 0;
0553
0554 default:
0555 DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
0556 }
0557
0558 radeon_bo_kunmap(bo);
0559 return -EINVAL;
0560 }
0561
0562 static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
0563 int data0, int data1,
0564 unsigned buf_sizes[], bool *has_msg_cmd)
0565 {
0566 struct radeon_cs_chunk *relocs_chunk;
0567 struct radeon_bo_list *reloc;
0568 unsigned idx, cmd, offset;
0569 uint64_t start, end;
0570 int r;
0571
0572 relocs_chunk = p->chunk_relocs;
0573 offset = radeon_get_ib_value(p, data0);
0574 idx = radeon_get_ib_value(p, data1);
0575 if (idx >= relocs_chunk->length_dw) {
0576 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
0577 idx, relocs_chunk->length_dw);
0578 return -EINVAL;
0579 }
0580
0581 reloc = &p->relocs[(idx / 4)];
0582 start = reloc->gpu_offset;
0583 end = start + radeon_bo_size(reloc->robj);
0584 start += offset;
0585
0586 p->ib.ptr[data0] = start & 0xFFFFFFFF;
0587 p->ib.ptr[data1] = start >> 32;
0588
0589 cmd = radeon_get_ib_value(p, p->idx) >> 1;
0590
0591 if (cmd < 0x4) {
0592 if (end <= start) {
0593 DRM_ERROR("invalid reloc offset %X!\n", offset);
0594 return -EINVAL;
0595 }
0596 if ((end - start) < buf_sizes[cmd]) {
0597 DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
0598 (unsigned)(end - start), buf_sizes[cmd]);
0599 return -EINVAL;
0600 }
0601
0602 } else if (cmd != 0x100) {
0603 DRM_ERROR("invalid UVD command %X!\n", cmd);
0604 return -EINVAL;
0605 }
0606
0607 if ((start >> 28) != ((end - 1) >> 28)) {
0608 DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n",
0609 start, end);
0610 return -EINVAL;
0611 }
0612
0613
0614 if ((cmd == 0 || cmd == 0x3) &&
0615 (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) {
0616 DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n",
0617 start, end);
0618 return -EINVAL;
0619 }
0620
0621 if (cmd == 0) {
0622 if (*has_msg_cmd) {
0623 DRM_ERROR("More than one message in a UVD-IB!\n");
0624 return -EINVAL;
0625 }
0626 *has_msg_cmd = true;
0627 r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
0628 if (r)
0629 return r;
0630 } else if (!*has_msg_cmd) {
0631 DRM_ERROR("Message needed before other commands are send!\n");
0632 return -EINVAL;
0633 }
0634
0635 return 0;
0636 }
0637
0638 static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
0639 struct radeon_cs_packet *pkt,
0640 int *data0, int *data1,
0641 unsigned buf_sizes[],
0642 bool *has_msg_cmd)
0643 {
0644 int i, r;
0645
0646 p->idx++;
0647 for (i = 0; i <= pkt->count; ++i) {
0648 switch (pkt->reg + i*4) {
0649 case UVD_GPCOM_VCPU_DATA0:
0650 *data0 = p->idx;
0651 break;
0652 case UVD_GPCOM_VCPU_DATA1:
0653 *data1 = p->idx;
0654 break;
0655 case UVD_GPCOM_VCPU_CMD:
0656 r = radeon_uvd_cs_reloc(p, *data0, *data1,
0657 buf_sizes, has_msg_cmd);
0658 if (r)
0659 return r;
0660 break;
0661 case UVD_ENGINE_CNTL:
0662 case UVD_NO_OP:
0663 break;
0664 default:
0665 DRM_ERROR("Invalid reg 0x%X!\n",
0666 pkt->reg + i*4);
0667 return -EINVAL;
0668 }
0669 p->idx++;
0670 }
0671 return 0;
0672 }
0673
0674 int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
0675 {
0676 struct radeon_cs_packet pkt;
0677 int r, data0 = 0, data1 = 0;
0678
0679
0680 bool has_msg_cmd = false;
0681
0682
0683 unsigned buf_sizes[] = {
0684 [0x00000000] = 2048,
0685 [0x00000001] = 32 * 1024 * 1024,
0686 [0x00000002] = 2048 * 1152 * 3,
0687 [0x00000003] = 2048,
0688 };
0689
0690 if (p->chunk_ib->length_dw % 16) {
0691 DRM_ERROR("UVD IB length (%d) not 16 dwords aligned!\n",
0692 p->chunk_ib->length_dw);
0693 return -EINVAL;
0694 }
0695
0696 if (p->chunk_relocs == NULL) {
0697 DRM_ERROR("No relocation chunk !\n");
0698 return -EINVAL;
0699 }
0700
0701
0702 do {
0703 r = radeon_cs_packet_parse(p, &pkt, p->idx);
0704 if (r)
0705 return r;
0706 switch (pkt.type) {
0707 case RADEON_PACKET_TYPE0:
0708 r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1,
0709 buf_sizes, &has_msg_cmd);
0710 if (r)
0711 return r;
0712 break;
0713 case RADEON_PACKET_TYPE2:
0714 p->idx += pkt.count + 2;
0715 break;
0716 default:
0717 DRM_ERROR("Unknown packet type %d !\n", pkt.type);
0718 return -EINVAL;
0719 }
0720 } while (p->idx < p->chunk_ib->length_dw);
0721
0722 if (!has_msg_cmd) {
0723 DRM_ERROR("UVD-IBs need a msg command!\n");
0724 return -EINVAL;
0725 }
0726
0727 return 0;
0728 }
0729
0730 static int radeon_uvd_send_msg(struct radeon_device *rdev,
0731 int ring, uint64_t addr,
0732 struct radeon_fence **fence)
0733 {
0734 struct radeon_ib ib;
0735 int i, r;
0736
0737 r = radeon_ib_get(rdev, ring, &ib, NULL, 64);
0738 if (r)
0739 return r;
0740
0741 ib.ptr[0] = PACKET0(UVD_GPCOM_VCPU_DATA0, 0);
0742 ib.ptr[1] = addr;
0743 ib.ptr[2] = PACKET0(UVD_GPCOM_VCPU_DATA1, 0);
0744 ib.ptr[3] = addr >> 32;
0745 ib.ptr[4] = PACKET0(UVD_GPCOM_VCPU_CMD, 0);
0746 ib.ptr[5] = 0;
0747 for (i = 6; i < 16; i += 2) {
0748 ib.ptr[i] = PACKET0(UVD_NO_OP, 0);
0749 ib.ptr[i+1] = 0;
0750 }
0751 ib.length_dw = 16;
0752
0753 r = radeon_ib_schedule(rdev, &ib, NULL, false);
0754
0755 if (fence)
0756 *fence = radeon_fence_ref(ib.fence);
0757
0758 radeon_ib_free(rdev, &ib);
0759 return r;
0760 }
0761
0762
0763
0764
0765
0766
0767 int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring,
0768 uint32_t handle, struct radeon_fence **fence)
0769 {
0770
0771 uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) -
0772 RADEON_GPU_PAGE_SIZE;
0773
0774 uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs);
0775 uint64_t addr = rdev->uvd.gpu_addr + offs;
0776
0777 int r, i;
0778
0779 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, true);
0780 if (r)
0781 return r;
0782
0783
0784 writel((__force u32)cpu_to_le32(0x00000de4), &msg[0]);
0785 writel(0x0, (void __iomem *)&msg[1]);
0786 writel((__force u32)cpu_to_le32(handle), &msg[2]);
0787 writel(0x0, &msg[3]);
0788 writel(0x0, &msg[4]);
0789 writel(0x0, &msg[5]);
0790 writel(0x0, &msg[6]);
0791 writel((__force u32)cpu_to_le32(0x00000780), &msg[7]);
0792 writel((__force u32)cpu_to_le32(0x00000440), &msg[8]);
0793 writel(0x0, &msg[9]);
0794 writel((__force u32)cpu_to_le32(0x01b37000), &msg[10]);
0795 for (i = 11; i < 1024; ++i)
0796 writel(0x0, &msg[i]);
0797
0798 r = radeon_uvd_send_msg(rdev, ring, addr, fence);
0799 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
0800 return r;
0801 }
0802
0803 int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
0804 uint32_t handle, struct radeon_fence **fence)
0805 {
0806
0807 uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) -
0808 RADEON_GPU_PAGE_SIZE;
0809
0810 uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs);
0811 uint64_t addr = rdev->uvd.gpu_addr + offs;
0812
0813 int r, i;
0814
0815 r = radeon_bo_reserve(rdev->uvd.vcpu_bo, true);
0816 if (r)
0817 return r;
0818
0819
0820 writel((__force u32)cpu_to_le32(0x00000de4), &msg[0]);
0821 writel((__force u32)cpu_to_le32(0x00000002), &msg[1]);
0822 writel((__force u32)cpu_to_le32(handle), &msg[2]);
0823 writel(0x0, &msg[3]);
0824 for (i = 4; i < 1024; ++i)
0825 writel(0x0, &msg[i]);
0826
0827 r = radeon_uvd_send_msg(rdev, ring, addr, fence);
0828 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
0829 return r;
0830 }
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841 static void radeon_uvd_count_handles(struct radeon_device *rdev,
0842 unsigned *sd, unsigned *hd)
0843 {
0844 unsigned i;
0845
0846 *sd = 0;
0847 *hd = 0;
0848
0849 for (i = 0; i < rdev->uvd.max_handles; ++i) {
0850 if (!atomic_read(&rdev->uvd.handles[i]))
0851 continue;
0852
0853 if (rdev->uvd.img_size[i] >= 720*576)
0854 ++(*hd);
0855 else
0856 ++(*sd);
0857 }
0858 }
0859
0860 static void radeon_uvd_idle_work_handler(struct work_struct *work)
0861 {
0862 struct radeon_device *rdev =
0863 container_of(work, struct radeon_device, uvd.idle_work.work);
0864
0865 if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) {
0866 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
0867 radeon_uvd_count_handles(rdev, &rdev->pm.dpm.sd,
0868 &rdev->pm.dpm.hd);
0869 radeon_dpm_enable_uvd(rdev, false);
0870 } else {
0871 radeon_set_uvd_clocks(rdev, 0, 0);
0872 }
0873 } else {
0874 schedule_delayed_work(&rdev->uvd.idle_work,
0875 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
0876 }
0877 }
0878
0879 void radeon_uvd_note_usage(struct radeon_device *rdev)
0880 {
0881 bool streams_changed = false;
0882 bool set_clocks = !cancel_delayed_work_sync(&rdev->uvd.idle_work);
0883 set_clocks &= schedule_delayed_work(&rdev->uvd.idle_work,
0884 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
0885
0886 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
0887 unsigned hd = 0, sd = 0;
0888 radeon_uvd_count_handles(rdev, &sd, &hd);
0889 if ((rdev->pm.dpm.sd != sd) ||
0890 (rdev->pm.dpm.hd != hd)) {
0891 rdev->pm.dpm.sd = sd;
0892 rdev->pm.dpm.hd = hd;
0893
0894
0895 }
0896 }
0897
0898 if (set_clocks || streams_changed) {
0899 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
0900 radeon_dpm_enable_uvd(rdev, true);
0901 } else {
0902 radeon_set_uvd_clocks(rdev, 53300, 40000);
0903 }
0904 }
0905 }
0906
0907 static unsigned radeon_uvd_calc_upll_post_div(unsigned vco_freq,
0908 unsigned target_freq,
0909 unsigned pd_min,
0910 unsigned pd_even)
0911 {
0912 unsigned post_div = vco_freq / target_freq;
0913
0914
0915 if (post_div < pd_min)
0916 post_div = pd_min;
0917
0918
0919 if ((vco_freq / post_div) > target_freq)
0920 post_div += 1;
0921
0922
0923 if (post_div > pd_even && post_div % 2)
0924 post_div += 1;
0925
0926 return post_div;
0927 }
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949 int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev,
0950 unsigned vclk, unsigned dclk,
0951 unsigned vco_min, unsigned vco_max,
0952 unsigned fb_factor, unsigned fb_mask,
0953 unsigned pd_min, unsigned pd_max,
0954 unsigned pd_even,
0955 unsigned *optimal_fb_div,
0956 unsigned *optimal_vclk_div,
0957 unsigned *optimal_dclk_div)
0958 {
0959 unsigned vco_freq, ref_freq = rdev->clock.spll.reference_freq;
0960
0961
0962 unsigned optimal_score = ~0;
0963
0964
0965 vco_min = max(max(vco_min, vclk), dclk);
0966 for (vco_freq = vco_min; vco_freq <= vco_max; vco_freq += 100) {
0967
0968 uint64_t fb_div = (uint64_t)vco_freq * fb_factor;
0969 unsigned vclk_div, dclk_div, score;
0970
0971 do_div(fb_div, ref_freq);
0972
0973
0974 if (fb_div > fb_mask)
0975 break;
0976
0977 fb_div &= fb_mask;
0978
0979
0980 vclk_div = radeon_uvd_calc_upll_post_div(vco_freq, vclk,
0981 pd_min, pd_even);
0982 if (vclk_div > pd_max)
0983 break;
0984
0985
0986 dclk_div = radeon_uvd_calc_upll_post_div(vco_freq, dclk,
0987 pd_min, pd_even);
0988 if (dclk_div > pd_max)
0989 break;
0990
0991
0992 score = vclk - (vco_freq / vclk_div) + dclk - (vco_freq / dclk_div);
0993
0994
0995 if (score < optimal_score) {
0996 *optimal_fb_div = fb_div;
0997 *optimal_vclk_div = vclk_div;
0998 *optimal_dclk_div = dclk_div;
0999 optimal_score = score;
1000 if (optimal_score == 0)
1001 break;
1002 }
1003 }
1004
1005
1006 if (optimal_score == ~0)
1007 return -EINVAL;
1008
1009 return 0;
1010 }
1011
1012 int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev,
1013 unsigned cg_upll_func_cntl)
1014 {
1015 unsigned i;
1016
1017
1018 WREG32_P(cg_upll_func_cntl, 0, ~UPLL_CTLREQ_MASK);
1019
1020 mdelay(10);
1021
1022
1023 WREG32_P(cg_upll_func_cntl, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
1024
1025
1026 for (i = 0; i < 100; ++i) {
1027 uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
1028 if ((RREG32(cg_upll_func_cntl) & mask) == mask)
1029 break;
1030 mdelay(10);
1031 }
1032
1033
1034 WREG32_P(cg_upll_func_cntl, 0, ~UPLL_CTLREQ_MASK);
1035
1036 if (i == 100) {
1037 DRM_ERROR("Timeout setting UVD clocks!\n");
1038 return -ETIMEDOUT;
1039 }
1040
1041 return 0;
1042 }