summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2014-01-23 09:50:49 -0700
committerChristian König <christian.koenig@amd.com>2014-02-18 16:11:26 +0100
commit98ccc291ffdc34ccb9b13f0c29cc51d6eab24022 (patch)
tree3033271c6e683095c118801dc3681f4ae8c4dfc2
parentf7ba8b04b22d7c74898f53a0e118f31b9d40dcc2 (diff)
downloadop-kernel-dev-98ccc291ffdc34ccb9b13f0c29cc51d6eab24022.zip
op-kernel-dev-98ccc291ffdc34ccb9b13f0c29cc51d6eab24022.tar.gz
drm/radeon: add VCE version parsing and checking
Also make the result available to userspace. Signed-off-by: Christian König <christian.koenig@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_vce.c56
-rw-r--r--include/uapi/drm/radeon_drm.h4
4 files changed, 62 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index a58a389..d1491d4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1606,6 +1606,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 ea018d5..baff98b 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -480,6 +480,12 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
else
*value = rdev->pm.default_sclk * 10;
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 6493ca5..1cf18b4 100644
--- a/include/uapi/drm/radeon_drm.h
+++ b/include/uapi/drm/radeon_drm.h
@@ -988,6 +988,10 @@ struct drm_radeon_cs {
#define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19
/* max engine clock - needed for OpenCL */
#define RADEON_INFO_MAX_SCLK 0x1a
+/* 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 {
OpenPOWER on IntegriCloud