aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-amd/0029-drm-radeon-add-VCE-version-parsing-and-checking.patch
blob: 694d4f324dff20e2d036f36bce50fb71e76364fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
From ce7f14da5704849b2e549cf17df8fcc1e2852906 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
Date: Thu, 23 Jan 2014 09:50:49 -0700
Subject: [PATCH 29/60] drm/radeon: add VCE version parsing and checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Also make the result available to userspace.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/radeon.h     |  2 ++
 drivers/gpu/drm/radeon/radeon_kms.c |  6 ++++
 drivers/gpu/drm/radeon/radeon_vce.c | 56 +++++++++++++++++++++++++++++++++----
 include/uapi/drm/radeon_drm.h       |  4 +++
 4 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 0abbe5e..43f8f74 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1607,6 +1607,8 @@ struct radeon_vce {
 	struct radeon_bo	*vcpu_bo;
 	void			*cpu_addr;
 	uint64_t		gpu_addr;
+	unsigned		fw_version;
+	unsigned		fb_version;
 	atomic_t		handles[RADEON_MAX_VCE_HANDLES];
 	struct drm_file		*filp[RADEON_MAX_VCE_HANDLES];
 };
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 5f37f06..131b517 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -457,6 +457,12 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 			DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n");
 		}
 		break;
+	case RADEON_INFO_VCE_FW_VERSION:
+		*value = rdev->vce.fw_version;
+		break;
+	case RADEON_INFO_VCE_FB_VERSION:
+		*value = rdev->vce.fb_version;
+		break;
 	default:
 		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
index 2547d8e..f46563b 100644
--- a/drivers/gpu/drm/radeon/radeon_vce.c
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -48,8 +48,11 @@ MODULE_FIRMWARE(FIRMWARE_BONAIRE);
  */
 int radeon_vce_init(struct radeon_device *rdev)
 {
-	unsigned long bo_size;
-	const char *fw_name;
+	static const char *fw_version = "[ATI LIB=VCEFW,";
+	static const char *fb_version = "[ATI LIB=VCEFWSTATS,";
+	unsigned long size;
+	const char *fw_name, *c;
+	uint8_t start, mid, end;
 	int i, r;
 
 	switch (rdev->family) {
@@ -70,9 +73,50 @@ int radeon_vce_init(struct radeon_device *rdev)
 		return r;
 	}
 
-	bo_size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) +
-		  RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE;
-	r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
+	/* search for firmware version */
+
+	size = rdev->vce_fw->size - strlen(fw_version) - 9;
+	c = rdev->vce_fw->data;
+	for (;size > 0; --size, ++c)
+		if (strncmp(c, fw_version, strlen(fw_version)) == 0)
+			break;
+
+	if (size == 0)
+		return -EINVAL;
+
+	c += strlen(fw_version);
+	if (sscanf(c, "%2hhd.%2hhd.%2hhd]", &start, &mid, &end) != 3)
+		return -EINVAL;
+
+	/* search for feedback version */
+
+	size = rdev->vce_fw->size - strlen(fb_version) - 3;
+	c = rdev->vce_fw->data;
+	for (;size > 0; --size, ++c)
+		if (strncmp(c, fb_version, strlen(fb_version)) == 0)
+			break;
+
+	if (size == 0)
+		return -EINVAL;
+
+	c += strlen(fb_version);
+	if (sscanf(c, "%2u]", &rdev->vce.fb_version) != 1)
+		return -EINVAL;
+
+	DRM_INFO("Found VCE firmware/feedback version %hhd.%hhd.%hhd / %d!\n",
+		 start, mid, end, rdev->vce.fb_version);
+
+	rdev->vce.fw_version = (start << 24) | (mid << 16) | (end << 8);
+
+	/* we can only work with this fw version for now */
+	if (rdev->vce.fw_version != ((40 << 24) | (2 << 16) | (2 << 8)))
+		return -EINVAL;
+
+	/* load firmware into VRAM */
+
+	size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) +
+	       RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE;
+	r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
 			     RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo);
 	if (r) {
 		dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r);
@@ -83,7 +127,7 @@ int radeon_vce_init(struct radeon_device *rdev)
 	if (r)
 		return r;
 
-	memset(rdev->vce.cpu_addr, 0, bo_size);
+	memset(rdev->vce.cpu_addr, 0, size);
 	memcpy(rdev->vce.cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size);
 
 	r = radeon_vce_suspend(rdev);
diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
index b93c92a..2ff6e71 100644
--- a/include/uapi/drm/radeon_drm.h
+++ b/include/uapi/drm/radeon_drm.h
@@ -986,6 +986,10 @@ struct drm_radeon_cs {
 #define RADEON_INFO_CIK_MACROTILE_MODE_ARRAY	0x18
 /* query the number of render backends */
 #define RADEON_INFO_SI_BACKEND_ENABLED_MASK	0x19
+/* version of VCE firmware */
+#define RADEON_INFO_VCE_FW_VERSION	0x1b
+/* version of VCE feedback */
+#define RADEON_INFO_VCE_FB_VERSION	0x1c
 
 
 struct drm_radeon_info {
-- 
1.9.1