aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c98
1 files changed, 78 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index d9c88d13f8db..b11f4e8868d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -40,9 +40,16 @@
40#include "uvd/uvd_4_2_d.h" 40#include "uvd/uvd_4_2_d.h"
41 41
42/* 1 second timeout */ 42/* 1 second timeout */
43#define UVD_IDLE_TIMEOUT_MS 1000 43#define UVD_IDLE_TIMEOUT msecs_to_jiffies(1000)
44
45/* Firmware versions for VI */
46#define FW_1_65_10 ((1 << 24) | (65 << 16) | (10 << 8))
47#define FW_1_87_11 ((1 << 24) | (87 << 16) | (11 << 8))
48#define FW_1_87_12 ((1 << 24) | (87 << 16) | (12 << 8))
49#define FW_1_37_15 ((1 << 24) | (37 << 16) | (15 << 8))
50
44/* Polaris10/11 firmware version */ 51/* Polaris10/11 firmware version */
45#define FW_1_66_16 ((1 << 24) | (66 << 16) | (16 << 8)) 52#define FW_1_66_16 ((1 << 24) | (66 << 16) | (16 << 8))
46 53
47/* Firmware Names */ 54/* Firmware Names */
48#ifdef CONFIG_DRM_AMDGPU_CIK 55#ifdef CONFIG_DRM_AMDGPU_CIK
@@ -92,7 +99,6 @@ MODULE_FIRMWARE(FIRMWARE_STONEY);
92MODULE_FIRMWARE(FIRMWARE_POLARIS10); 99MODULE_FIRMWARE(FIRMWARE_POLARIS10);
93MODULE_FIRMWARE(FIRMWARE_POLARIS11); 100MODULE_FIRMWARE(FIRMWARE_POLARIS11);
94 101
95static void amdgpu_uvd_note_usage(struct amdgpu_device *adev);
96static void amdgpu_uvd_idle_work_handler(struct work_struct *work); 102static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
97 103
98int amdgpu_uvd_sw_init(struct amdgpu_device *adev) 104int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
@@ -246,6 +252,23 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
246 if (!amdgpu_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) 252 if (!amdgpu_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
247 adev->uvd.address_64_bit = true; 253 adev->uvd.address_64_bit = true;
248 254
255 switch (adev->asic_type) {
256 case CHIP_TONGA:
257 adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_65_10;
258 break;
259 case CHIP_CARRIZO:
260 adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_87_11;
261 break;
262 case CHIP_FIJI:
263 adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_87_12;
264 break;
265 case CHIP_STONEY:
266 adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_37_15;
267 break;
268 default:
269 adev->uvd.use_ctx_buf = adev->asic_type >= CHIP_POLARIS10;
270 }
271
249 return 0; 272 return 0;
250} 273}
251 274
@@ -346,8 +369,6 @@ void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
346 if (handle != 0 && adev->uvd.filp[i] == filp) { 369 if (handle != 0 && adev->uvd.filp[i] == filp) {
347 struct fence *fence; 370 struct fence *fence;
348 371
349 amdgpu_uvd_note_usage(adev);
350
351 r = amdgpu_uvd_get_destroy_msg(ring, handle, 372 r = amdgpu_uvd_get_destroy_msg(ring, handle,
352 false, &fence); 373 false, &fence);
353 if (r) { 374 if (r) {
@@ -438,7 +459,7 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
438 unsigned fs_in_mb = width_in_mb * height_in_mb; 459 unsigned fs_in_mb = width_in_mb * height_in_mb;
439 460
440 unsigned image_size, tmp, min_dpb_size, num_dpb_buffer; 461 unsigned image_size, tmp, min_dpb_size, num_dpb_buffer;
441 unsigned min_ctx_size = 0; 462 unsigned min_ctx_size = ~0;
442 463
443 image_size = width * height; 464 image_size = width * height;
444 image_size += image_size / 2; 465 image_size += image_size / 2;
@@ -557,7 +578,7 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
557 /* reference picture buffer */ 578 /* reference picture buffer */
558 min_dpb_size = image_size * num_dpb_buffer; 579 min_dpb_size = image_size * num_dpb_buffer;
559 580
560 if (adev->asic_type < CHIP_POLARIS10){ 581 if (!adev->uvd.use_ctx_buf){
561 /* macroblock context buffer */ 582 /* macroblock context buffer */
562 min_dpb_size += 583 min_dpb_size +=
563 width_in_mb * height_in_mb * num_dpb_buffer * 192; 584 width_in_mb * height_in_mb * num_dpb_buffer * 192;
@@ -662,7 +683,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
662 } 683 }
663 684
664 DRM_ERROR("No more free UVD handles!\n"); 685 DRM_ERROR("No more free UVD handles!\n");
665 return -EINVAL; 686 return -ENOSPC;
666 687
667 case 1: 688 case 1:
668 /* it's a decode msg, calc buffer sizes */ 689 /* it's a decode msg, calc buffer sizes */
@@ -913,8 +934,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
913 return -EINVAL; 934 return -EINVAL;
914 } 935 }
915 936
916 amdgpu_uvd_note_usage(ctx.parser->adev);
917
918 return 0; 937 return 0;
919} 938}
920 939
@@ -968,7 +987,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
968 987
969 if (direct) { 988 if (direct) {
970 r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f); 989 r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f);
971 job->fence = f; 990 job->fence = fence_get(f);
972 if (r) 991 if (r)
973 goto err_free; 992 goto err_free;
974 993
@@ -1106,24 +1125,18 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
1106 if (fences == 0 && handles == 0) { 1125 if (fences == 0 && handles == 0) {
1107 if (adev->pm.dpm_enabled) { 1126 if (adev->pm.dpm_enabled) {
1108 amdgpu_dpm_enable_uvd(adev, false); 1127 amdgpu_dpm_enable_uvd(adev, false);
1109 /* just work around for uvd clock remain high even
1110 * when uvd dpm disabled on Polaris10 */
1111 if (adev->asic_type == CHIP_POLARIS10)
1112 amdgpu_asic_set_uvd_clocks(adev, 0, 0);
1113 } else { 1128 } else {
1114 amdgpu_asic_set_uvd_clocks(adev, 0, 0); 1129 amdgpu_asic_set_uvd_clocks(adev, 0, 0);
1115 } 1130 }
1116 } else { 1131 } else {
1117 schedule_delayed_work(&adev->uvd.idle_work, 1132 schedule_delayed_work(&adev->uvd.idle_work, UVD_IDLE_TIMEOUT);
1118 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
1119 } 1133 }
1120} 1134}
1121 1135
1122static void amdgpu_uvd_note_usage(struct amdgpu_device *adev) 1136void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring)
1123{ 1137{
1138 struct amdgpu_device *adev = ring->adev;
1124 bool set_clocks = !cancel_delayed_work_sync(&adev->uvd.idle_work); 1139 bool set_clocks = !cancel_delayed_work_sync(&adev->uvd.idle_work);
1125 set_clocks &= schedule_delayed_work(&adev->uvd.idle_work,
1126 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
1127 1140
1128 if (set_clocks) { 1141 if (set_clocks) {
1129 if (adev->pm.dpm_enabled) { 1142 if (adev->pm.dpm_enabled) {
@@ -1133,3 +1146,48 @@ static void amdgpu_uvd_note_usage(struct amdgpu_device *adev)
1133 } 1146 }
1134 } 1147 }
1135} 1148}
1149
1150void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring)
1151{
1152 schedule_delayed_work(&ring->adev->uvd.idle_work, UVD_IDLE_TIMEOUT);
1153}
1154
1155/**
1156 * amdgpu_uvd_ring_test_ib - test ib execution
1157 *
1158 * @ring: amdgpu_ring pointer
1159 *
1160 * Test if we can successfully execute an IB
1161 */
1162int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
1163{
1164 struct fence *fence;
1165 long r;
1166
1167 r = amdgpu_uvd_get_create_msg(ring, 1, NULL);
1168 if (r) {
1169 DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r);
1170 goto error;
1171 }
1172
1173 r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence);
1174 if (r) {
1175 DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r);
1176 goto error;
1177 }
1178
1179 r = fence_wait_timeout(fence, false, timeout);
1180 if (r == 0) {
1181 DRM_ERROR("amdgpu: IB test timed out.\n");
1182 r = -ETIMEDOUT;
1183 } else if (r < 0) {
1184 DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
1185 } else {
1186 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
1187 r = 0;
1188 }
1189
1190error:
1191 fence_put(fence);
1192 return r;
1193}