From: Arindam Nath arindam.nath@amd.com
Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Arindam Nath arindam.nath@amd.com Reviewed-by: Leo Liu leo.liu@amd.com --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_uvd.c | 55 +++++++++++++++++++++++++++---------- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 +++++- 3 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 78a51b3..34694ad 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1674,6 +1674,7 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, #define RADEON_UVD_HEAP_SIZE (1024*1024)
struct radeon_uvd { + bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6edcb54..0897c66 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -34,6 +34,7 @@ #include <drm/drm.h>
#include "radeon.h" +#include "radeon_ucode.h" #include "r600d.h"
/* 1 second timeout */ @@ -47,7 +48,8 @@ #define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin" #define FIRMWARE_SUMO "radeon/SUMO_uvd.bin" #define FIRMWARE_TAHITI "radeon/TAHITI_uvd.bin" -#define FIRMWARE_BONAIRE "radeon/BONAIRE_uvd.bin" +#define FIRMWARE_BONAIRE_LEGACY "radeon/BONAIRE_uvd.bin" +#define FIRMWARE_BONAIRE "radeon/bonaire_uvd.bin"
MODULE_FIRMWARE(FIRMWARE_R600); MODULE_FIRMWARE(FIRMWARE_RS780); @@ -56,6 +58,7 @@ MODULE_FIRMWARE(FIRMWARE_RV710); MODULE_FIRMWARE(FIRMWARE_CYPRESS); MODULE_FIRMWARE(FIRMWARE_SUMO); MODULE_FIRMWARE(FIRMWARE_TAHITI); +MODULE_FIRMWARE(FIRMWARE_BONAIRE_LEGACY); MODULE_FIRMWARE(FIRMWARE_BONAIRE);
static void radeon_uvd_idle_work_handler(struct work_struct *work); @@ -63,7 +66,7 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); int radeon_uvd_init(struct radeon_device *rdev) { unsigned long bo_size; - const char *fw_name; + const char *fw_name = NULL, *legacy_fw_name = NULL; int i, r;
INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler); @@ -74,22 +77,22 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RV620: case CHIP_RV635: - fw_name = FIRMWARE_R600; + legacy_fw_name = FIRMWARE_R600; break;
case CHIP_RS780: case CHIP_RS880: - fw_name = FIRMWARE_RS780; + legacy_fw_name = FIRMWARE_RS780; break;
case CHIP_RV770: - fw_name = FIRMWARE_RV770; + legacy_fw_name = FIRMWARE_RV770; break;
case CHIP_RV710: case CHIP_RV730: case CHIP_RV740: - fw_name = FIRMWARE_RV710; + legacy_fw_name = FIRMWARE_RV710; break;
case CHIP_CYPRESS: @@ -97,7 +100,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_JUNIPER: case CHIP_REDWOOD: case CHIP_CEDAR: - fw_name = FIRMWARE_CYPRESS; + legacy_fw_name = FIRMWARE_CYPRESS; break;
case CHIP_SUMO: @@ -107,7 +110,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: - fw_name = FIRMWARE_SUMO; + legacy_fw_name = FIRMWARE_SUMO; break;
case CHIP_TAHITI: @@ -115,7 +118,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_PITCAIRN: case CHIP_ARUBA: case CHIP_OLAND: - fw_name = FIRMWARE_TAHITI; + legacy_fw_name = FIRMWARE_TAHITI; break;
case CHIP_BONAIRE: @@ -123,6 +126,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_KAVERI: case CHIP_HAWAII: case CHIP_MULLINS: + legacy_fw_name = FIRMWARE_BONAIRE_LEGACY; fw_name = FIRMWARE_BONAIRE; break;
@@ -130,11 +134,34 @@ int radeon_uvd_init(struct radeon_device *rdev) return -EINVAL; }
- r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); - if (r) { - dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", - fw_name); - return r; + rdev->uvd.fw_header_present = false; + if (fw_name) { + /* Let's try to load the newer firmware first */ + r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); + if (r) { + dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", + fw_name); + } else { + r = radeon_ucode_validate(rdev->uvd_fw); + if (r) + return r; + + rdev->uvd.fw_header_present = true; + } + } + + /* + * In case there is only legacy firmware, or we encounter an error + * while loading the new firmware, we fall back to loading the legacy + * firmware now. + */ + if (!fw_name || r) { + r = request_firmware(&rdev->uvd_fw, legacy_fw_name, rdev->dev); + if (r) { + dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", + legacy_fw_name); + return r; + } }
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index d04d507..205562f 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -41,7 +41,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) uint32_t size;
/* programm the VCPU memory controller bits 0-27 */ - addr = rdev->uvd.gpu_addr >> 3; + + /* skip over the header of the new firmware format */ + if (rdev->uvd.fw_header_present) + addr = (rdev->uvd.gpu_addr + 0x200) >> 3; + else + addr = rdev->uvd.gpu_addr >> 3; + size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET0, addr); WREG32(UVD_VCPU_CACHE_SIZE0, size);
From: Arindam Nath arindam.nath@amd.com
Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Arindam Nath arindam.nath@amd.com Reviewed-by: Leo Liu leo.liu@amd.com --- drivers/gpu/drm/radeon/cikd.h | 1 + drivers/gpu/drm/radeon/radeon.h | 9 ++++++--- drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++-------- drivers/gpu/drm/radeon/uvd_v1_0.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v2_2.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 ++++++-- 6 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 391ff9d..cead228 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2071,6 +2071,7 @@ #define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
#define UVD_LMI_EXT40_ADDR 0xf498 +#define UVD_GP_SCRATCH4 0xf4e0 #define UVD_LMI_ADDR_EXT 0xf594 #define UVD_VCPU_CACHE_OFFSET0 0xf608 #define UVD_VCPU_CACHE_SIZE0 0xf60c diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 34694ad..827e623 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1669,15 +1669,18 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, /* * UVD */ -#define RADEON_MAX_UVD_HANDLES 10 -#define RADEON_UVD_STACK_SIZE (1024*1024) -#define RADEON_UVD_HEAP_SIZE (1024*1024) +#define RADEON_DEFAULT_UVD_HANDLES 10 +#define RADEON_MAX_UVD_HANDLES 30 +#define RADEON_UVD_STACK_SIZE (200*1024) +#define RADEON_UVD_HEAP_SIZE (256*1024) +#define RADEON_UVD_SESSION_SIZE (50*1024)
struct radeon_uvd { bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; + unsigned max_handles; atomic_t handles[RADEON_MAX_UVD_HANDLES]; struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; unsigned img_size[RADEON_MAX_UVD_HANDLES]; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 0897c66..f8de6d0 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -135,6 +135,7 @@ int radeon_uvd_init(struct radeon_device *rdev) }
rdev->uvd.fw_header_present = false; + rdev->uvd.max_handles = RADEON_DEFAULT_UVD_HANDLES; if (fw_name) { /* Let's try to load the newer firmware first */ r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); @@ -142,11 +143,27 @@ int radeon_uvd_init(struct radeon_device *rdev) dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", fw_name); } else { + struct common_firmware_header *hdr = (void *)rdev->uvd_fw->data; + unsigned version_major, version_minor, family_id; + r = radeon_ucode_validate(rdev->uvd_fw); if (r) return r;
rdev->uvd.fw_header_present = true; + + family_id = le32_to_cpu(hdr->ucode_version) & 0xff; + version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; + version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; + DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", + version_major, version_minor, family_id); + + /* + * Limit the number of UVD handles depending on + * microcode major and minor versions. + */ + if ((version_major >= 0x01) && (version_minor >= 0x37)) + rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES; } }
@@ -166,7 +183,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE + - RADEON_GPU_PAGE_SIZE; + RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles; r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &rdev->uvd.vcpu_bo); @@ -199,7 +216,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { atomic_set(&rdev->uvd.handles[i], 0); rdev->uvd.filp[i] = NULL; rdev->uvd.img_size[i] = 0; @@ -236,7 +253,7 @@ int radeon_uvd_suspend(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return 0;
- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0) { struct radeon_fence *fence; @@ -311,7 +328,7 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo, void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) { int i, r; - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0 && rdev->uvd.filp[i] == filp) { struct radeon_fence *fence; @@ -496,7 +513,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* try to alloc a new handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { DRM_ERROR("Handle 0x%x already in use!\n", handle); return -EINVAL; @@ -522,7 +539,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* validate the handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { if (p->rdev->uvd.filp[i] != p->filp) { DRM_ERROR("UVD handle collision detected!\n"); @@ -537,7 +554,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
case 2: /* it's a destroy msg, free the handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) + for (i = 0; i < p->rdev->uvd.max_handles; ++i) atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); radeon_bo_kunmap(bo); return 0; @@ -834,7 +851,7 @@ static void radeon_uvd_count_handles(struct radeon_device *rdev, *sd = 0; *hd = 0;
- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { if (!atomic_read(&rdev->uvd.handles[i])) continue;
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index c6b1cbc..ff471cb 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -124,12 +124,13 @@ int uvd_v1_0_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size);
addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 7ed778c..9071e65 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -116,12 +116,13 @@ int uvd_v2_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size);
addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index 205562f..91613b8 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -53,12 +53,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size);
addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
@@ -70,5 +71,8 @@ int uvd_v4_2_resume(struct radeon_device *rdev) addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
+ if (rdev->uvd.fw_header_present) + WREG32(UVD_GP_SCRATCH4, rdev->uvd.max_handles); + return 0; }
On Wed, Apr 6, 2016 at 3:33 PM, Leo Liu leo.liu@amd.com wrote:
From: Arindam Nath arindam.nath@amd.com
Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Arindam Nath arindam.nath@amd.com Reviewed-by: Leo Liu leo.liu@amd.com
Applied the series. Thanks!
Alex
drivers/gpu/drm/radeon/cikd.h | 1 + drivers/gpu/drm/radeon/radeon.h | 9 ++++++--- drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++-------- drivers/gpu/drm/radeon/uvd_v1_0.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v2_2.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 ++++++-- 6 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 391ff9d..cead228 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2071,6 +2071,7 @@ #define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
#define UVD_LMI_EXT40_ADDR 0xf498 +#define UVD_GP_SCRATCH4 0xf4e0 #define UVD_LMI_ADDR_EXT 0xf594 #define UVD_VCPU_CACHE_OFFSET0 0xf608 #define UVD_VCPU_CACHE_SIZE0 0xf60c diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 34694ad..827e623 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1669,15 +1669,18 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, /*
- UVD
*/ -#define RADEON_MAX_UVD_HANDLES 10 -#define RADEON_UVD_STACK_SIZE (1024*1024) -#define RADEON_UVD_HEAP_SIZE (1024*1024) +#define RADEON_DEFAULT_UVD_HANDLES 10 +#define RADEON_MAX_UVD_HANDLES 30 +#define RADEON_UVD_STACK_SIZE (200*1024) +#define RADEON_UVD_HEAP_SIZE (256*1024) +#define RADEON_UVD_SESSION_SIZE (50*1024)
struct radeon_uvd { bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr;
unsigned max_handles; atomic_t handles[RADEON_MAX_UVD_HANDLES]; struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; unsigned img_size[RADEON_MAX_UVD_HANDLES];
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 0897c66..f8de6d0 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -135,6 +135,7 @@ int radeon_uvd_init(struct radeon_device *rdev) }
rdev->uvd.fw_header_present = false;
rdev->uvd.max_handles = RADEON_DEFAULT_UVD_HANDLES; if (fw_name) { /* Let's try to load the newer firmware first */ r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
@@ -142,11 +143,27 @@ int radeon_uvd_init(struct radeon_device *rdev) dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", fw_name); } else {
struct common_firmware_header *hdr = (void *)rdev->uvd_fw->data;
unsigned version_major, version_minor, family_id;
r = radeon_ucode_validate(rdev->uvd_fw); if (r) return r; rdev->uvd.fw_header_present = true;
family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n",
version_major, version_minor, family_id);
/*
* Limit the number of UVD handles depending on
* microcode major and minor versions.
*/
if ((version_major >= 0x01) && (version_minor >= 0x37))
rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES; } }
@@ -166,7 +183,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE +
RADEON_GPU_PAGE_SIZE;
RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles; r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &rdev->uvd.vcpu_bo);
@@ -199,7 +216,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { atomic_set(&rdev->uvd.handles[i], 0); rdev->uvd.filp[i] = NULL; rdev->uvd.img_size[i] = 0;
@@ -236,7 +253,7 @@ int radeon_uvd_suspend(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return 0;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0) { struct radeon_fence *fence;
@@ -311,7 +328,7 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo, void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) { int i, r;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0 && rdev->uvd.filp[i] == filp) { struct radeon_fence *fence;
@@ -496,7 +513,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* try to alloc a new handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { DRM_ERROR("Handle 0x%x already in use!\n", handle); return -EINVAL;
@@ -522,7 +539,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* validate the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { if (p->rdev->uvd.filp[i] != p->filp) { DRM_ERROR("UVD handle collision detected!\n");
@@ -537,7 +554,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
case 2: /* it's a destroy msg, free the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
for (i = 0; i < p->rdev->uvd.max_handles; ++i) atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); radeon_bo_kunmap(bo); return 0;
@@ -834,7 +851,7 @@ static void radeon_uvd_count_handles(struct radeon_device *rdev, *sd = 0; *hd = 0;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { if (!atomic_read(&rdev->uvd.handles[i])) continue;
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index c6b1cbc..ff471cb 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -124,12 +124,13 @@ int uvd_v1_0_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 7ed778c..9071e65 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -116,12 +116,13 @@ int uvd_v2_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index 205562f..91613b8 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -53,12 +53,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
@@ -70,5 +71,8 @@ int uvd_v4_2_resume(struct radeon_device *rdev) addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
if (rdev->uvd.fw_header_present)
WREG32(UVD_GP_SCRATCH4, rdev->uvd.max_handles);
return 0;
}
1.9.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
+ if ((version_major >= 0x01) && (version_minor >= 0x37)) + rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES;
If major version greater than 01 no need to verify for minor version.
Can we modify like this?
if ((version_major > 0x01) || (version_major == 0x01 && version_minor >= 0x37) ) rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES;
Thanks, Ayyappa
On Thu, Apr 7, 2016 at 1:03 AM, Leo Liu leo.liu@amd.com wrote:
From: Arindam Nath arindam.nath@amd.com
Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Arindam Nath arindam.nath@amd.com Reviewed-by: Leo Liu leo.liu@amd.com
drivers/gpu/drm/radeon/cikd.h | 1 + drivers/gpu/drm/radeon/radeon.h | 9 ++++++--- drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++-------- drivers/gpu/drm/radeon/uvd_v1_0.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v2_2.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 ++++++-- 6 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 391ff9d..cead228 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2071,6 +2071,7 @@ #define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
#define UVD_LMI_EXT40_ADDR 0xf498 +#define UVD_GP_SCRATCH4 0xf4e0 #define UVD_LMI_ADDR_EXT 0xf594 #define UVD_VCPU_CACHE_OFFSET0 0xf608 #define UVD_VCPU_CACHE_SIZE0 0xf60c diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 34694ad..827e623 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1669,15 +1669,18 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, /*
- UVD
*/ -#define RADEON_MAX_UVD_HANDLES 10 -#define RADEON_UVD_STACK_SIZE (1024*1024) -#define RADEON_UVD_HEAP_SIZE (1024*1024) +#define RADEON_DEFAULT_UVD_HANDLES 10 +#define RADEON_MAX_UVD_HANDLES 30 +#define RADEON_UVD_STACK_SIZE (200*1024) +#define RADEON_UVD_HEAP_SIZE (256*1024) +#define RADEON_UVD_SESSION_SIZE (50*1024)
struct radeon_uvd { bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr;
unsigned max_handles; atomic_t handles[RADEON_MAX_UVD_HANDLES]; struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; unsigned img_size[RADEON_MAX_UVD_HANDLES];
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 0897c66..f8de6d0 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -135,6 +135,7 @@ int radeon_uvd_init(struct radeon_device *rdev) }
rdev->uvd.fw_header_present = false;
rdev->uvd.max_handles = RADEON_DEFAULT_UVD_HANDLES; if (fw_name) { /* Let's try to load the newer firmware first */ r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
@@ -142,11 +143,27 @@ int radeon_uvd_init(struct radeon_device *rdev) dev_err(rdev->dev, "radeon_uvd: Can't load firmware "%s"\n", fw_name); } else {
struct common_firmware_header *hdr = (void *)rdev->uvd_fw->data;
unsigned version_major, version_minor, family_id;
r = radeon_ucode_validate(rdev->uvd_fw); if (r) return r; rdev->uvd.fw_header_present = true;
family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n",
version_major, version_minor, family_id);
/*
* Limit the number of UVD handles depending on
* microcode major and minor versions.
*/
if ((version_major >= 0x01) && (version_minor >= 0x37))
rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES; } }
@@ -166,7 +183,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE +
RADEON_GPU_PAGE_SIZE;
RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles; r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &rdev->uvd.vcpu_bo);
@@ -199,7 +216,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { atomic_set(&rdev->uvd.handles[i], 0); rdev->uvd.filp[i] = NULL; rdev->uvd.img_size[i] = 0;
@@ -236,7 +253,7 @@ int radeon_uvd_suspend(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return 0;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0) { struct radeon_fence *fence;
@@ -311,7 +328,7 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo, void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) { int i, r;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0 && rdev->uvd.filp[i] == filp) { struct radeon_fence *fence;
@@ -496,7 +513,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* try to alloc a new handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { DRM_ERROR("Handle 0x%x already in use!\n", handle); return -EINVAL;
@@ -522,7 +539,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r;
/* validate the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { if (p->rdev->uvd.filp[i] != p->filp) { DRM_ERROR("UVD handle collision detected!\n");
@@ -537,7 +554,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
case 2: /* it's a destroy msg, free the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
for (i = 0; i < p->rdev->uvd.max_handles; ++i) atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); radeon_bo_kunmap(bo); return 0;
@@ -834,7 +851,7 @@ static void radeon_uvd_count_handles(struct radeon_device *rdev, *sd = 0; *hd = 0;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
for (i = 0; i < rdev->uvd.max_handles; ++i) { if (!atomic_read(&rdev->uvd.handles[i])) continue;
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index c6b1cbc..ff471cb 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -124,12 +124,13 @@ int uvd_v1_0_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 7ed778c..9071e65 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -116,12 +116,13 @@ int uvd_v2_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index 205562f..91613b8 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -53,12 +53,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size);
addr += size;
size = RADEON_UVD_STACK_SIZE >> 3;
size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size;
size = RADEON_UVD_HEAP_SIZE >> 3;
size = (RADEON_UVD_STACK_SIZE +
(RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size);
@@ -70,5 +71,8 @@ int uvd_v4_2_resume(struct radeon_device *rdev) addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
if (rdev->uvd.fw_header_present)
WREG32(UVD_GP_SCRATCH4, rdev->uvd.max_handles);
return 0;
}
1.9.1
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org