summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-12 04:16:55 +0300
committerDave Airlie <airlied@redhat.com>2016-05-12 04:16:55 +0300
commit7d020672615d09cf6ec42c500f34d70adf6758a9 (patch)
tree9802fd588de854c788a59449233ea42acd107cc0 /drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
parent95306975e9dd38ba2775dd96cb29987ecc7d9360 (diff)
parentb4eeed590deeff13a53db641129f0301d70248f3 (diff)
downloadlinux-7d020672615d09cf6ec42c500f34d70adf6758a9.tar.xz
Merge branch 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux into drm-next
More amdgpu fixes for 4.7. Highlights: - enable async pageflips - UVD fixes for polaris - lots of GPUVM fixes - whitespace and code cleanups - misc bug fixes * 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux: (32 commits) drm/amd/powerplay: rewrite pp_sw_init to make code readable drm/amdgpu/dce11: fix audio offset for asics with >7 audio pins drm/amdgpu: fix and cleanup user fence handling v2 drm/amdgpu: move VM fields into job drm/amdgpu: move the context from the IBs into the job drm/amdgpu: move context switch handling into common code v2 drm/amdgpu: move preamble IB handling into common code drm/amdgpu/gfx7: fix pipeline sync amdgpu/uvd: separate context buffer from DPB drm/amdgpu: use fence_context to judge ctx switch v2 drm/amd/amdgpu: Added more named DRM info messages for debugging drm/amd/amdgpu: Add name field to amd_ip_funcs (v2) drm/amdgpu: Support DRM_MODE_PAGE_FLIP_ASYNC (v2) drm/amdgpu/dce11: don't share PLLs on Polaris drm/amdgpu: Drop unused parameter for *get_sleep_divider_id_from_clock drm/amdgpu: Simplify calculation in *get_sleep_divider_id_from_clock drm/amdgpu: Use max macro in *get_sleep_divider_id_from_clock drm/amd/powerplay: Use defined constants for minium engine clock drm/amdgpu: add missing licenses on a couple of files drm/amdgpu: fetch cu_info once at init ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index abda242980ba..01abfc21b4a2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -41,13 +41,15 @@
/* 1 second timeout */
#define UVD_IDLE_TIMEOUT_MS 1000
+/* Polaris10/11 firmware version */
+#define FW_1_66_16 ((1 << 24) | (66 << 16) | (16 << 8))
/* Firmware Names */
#ifdef CONFIG_DRM_AMDGPU_CIK
#define FIRMWARE_BONAIRE "radeon/bonaire_uvd.bin"
-#define FIRMWARE_KABINI "radeon/kabini_uvd.bin"
-#define FIRMWARE_KAVERI "radeon/kaveri_uvd.bin"
-#define FIRMWARE_HAWAII "radeon/hawaii_uvd.bin"
+#define FIRMWARE_KABINI "radeon/kabini_uvd.bin"
+#define FIRMWARE_KAVERI "radeon/kaveri_uvd.bin"
+#define FIRMWARE_HAWAII "radeon/hawaii_uvd.bin"
#define FIRMWARE_MULLINS "radeon/mullins_uvd.bin"
#endif
#define FIRMWARE_TONGA "amdgpu/tonga_uvd.bin"
@@ -184,6 +186,12 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) |
(family_id << 8));
+ if ((adev->asic_type == CHIP_POLARIS10 ||
+ adev->asic_type == CHIP_POLARIS11) &&
+ (adev->uvd.fw_version < FW_1_66_16))
+ DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n",
+ version_major, version_minor);
+
bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8)
+ AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE
+ AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles;
@@ -414,7 +422,8 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
*
* Peek into the decode message and calculate the necessary buffer sizes.
*/
-static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[])
+static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
+ unsigned buf_sizes[])
{
unsigned stream_type = msg[4];
unsigned width = msg[6];
@@ -436,7 +445,6 @@ static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[])
switch (stream_type) {
case 0: /* H264 */
- case 7: /* H264 Perf */
switch(level) {
case 30:
num_dpb_buffer = 8100 / fs_in_mb;
@@ -514,6 +522,54 @@ static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[])
min_dpb_size += ALIGN(width_in_mb * height_in_mb * 32, 64);
break;
+ case 7: /* H264 Perf */
+ switch(level) {
+ case 30:
+ num_dpb_buffer = 8100 / fs_in_mb;
+ break;
+ case 31:
+ num_dpb_buffer = 18000 / fs_in_mb;
+ break;
+ case 32:
+ num_dpb_buffer = 20480 / fs_in_mb;
+ break;
+ case 41:
+ num_dpb_buffer = 32768 / fs_in_mb;
+ break;
+ case 42:
+ num_dpb_buffer = 34816 / fs_in_mb;
+ break;
+ case 50:
+ num_dpb_buffer = 110400 / fs_in_mb;
+ break;
+ case 51:
+ num_dpb_buffer = 184320 / fs_in_mb;
+ break;
+ default:
+ num_dpb_buffer = 184320 / fs_in_mb;
+ break;
+ }
+ num_dpb_buffer++;
+ if (num_dpb_buffer > 17)
+ num_dpb_buffer = 17;
+
+ /* reference picture buffer */
+ min_dpb_size = image_size * num_dpb_buffer;
+
+ if (adev->asic_type < CHIP_POLARIS10){
+ /* macroblock context buffer */
+ min_dpb_size +=
+ width_in_mb * height_in_mb * num_dpb_buffer * 192;
+
+ /* IT surface buffer */
+ min_dpb_size += width_in_mb * height_in_mb * 32;
+ } else {
+ /* macroblock context buffer */
+ min_ctx_size =
+ width_in_mb * height_in_mb * num_dpb_buffer * 192;
+ }
+ break;
+
case 16: /* H265 */
image_size = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
image_size = ALIGN(image_size, 256);
@@ -609,7 +665,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
case 1:
/* it's a decode msg, calc buffer sizes */
- r = amdgpu_uvd_cs_msg_decode(msg, ctx->buf_sizes);
+ r = amdgpu_uvd_cs_msg_decode(adev, msg, ctx->buf_sizes);
amdgpu_bo_kunmap(bo);
if (r)
return r;
@@ -910,7 +966,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
ib->length_dw = 16;
if (direct) {
- r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
+ r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f);
job->fence = f;
if (r)
goto err_free;