Commit 6a585777 authored by Alex Deucher's avatar Alex Deucher

drm/amdgpu: implement VCE 3.0 harvesting support (v4)

For boards with bad VCE blocks, only configure the working
block.

v2: use the harvest info for pipe setup
v3: fix mask check as noted by Leo
v4: add dGPU support

Reviewed-by: Christian König <christian.koenig@amd.com> (v2)
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5e6775ab
...@@ -1614,6 +1614,9 @@ struct amdgpu_uvd { ...@@ -1614,6 +1614,9 @@ struct amdgpu_uvd {
#define AMDGPU_MAX_VCE_HANDLES 16 #define AMDGPU_MAX_VCE_HANDLES 16
#define AMDGPU_VCE_FIRMWARE_OFFSET 256 #define AMDGPU_VCE_FIRMWARE_OFFSET 256
#define AMDGPU_VCE_HARVEST_VCE0 (1 << 0)
#define AMDGPU_VCE_HARVEST_VCE1 (1 << 1)
struct amdgpu_vce { struct amdgpu_vce {
struct amdgpu_bo *vcpu_bo; struct amdgpu_bo *vcpu_bo;
uint64_t gpu_addr; uint64_t gpu_addr;
...@@ -1626,6 +1629,7 @@ struct amdgpu_vce { ...@@ -1626,6 +1629,7 @@ struct amdgpu_vce {
const struct firmware *fw; /* VCE firmware */ const struct firmware *fw; /* VCE firmware */
struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS];
struct amdgpu_irq_src irq; struct amdgpu_irq_src irq;
unsigned harvest_config;
}; };
/* /*
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "oss/oss_2_0_d.h" #include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h" #include "oss/oss_2_0_sh_mask.h"
#include "gca/gfx_8_0_d.h" #include "gca/gfx_8_0_d.h"
#include "smu/smu_7_1_2_d.h"
#include "smu/smu_7_1_2_sh_mask.h"
#define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04
#define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10
...@@ -112,6 +114,10 @@ static int vce_v3_0_start(struct amdgpu_device *adev) ...@@ -112,6 +114,10 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
mutex_lock(&adev->grbm_idx_mutex); mutex_lock(&adev->grbm_idx_mutex);
for (idx = 0; idx < 2; ++idx) { for (idx = 0; idx < 2; ++idx) {
if (adev->vce.harvest_config & (1 << idx))
continue;
if(idx == 0) if(idx == 0)
WREG32_P(mmGRBM_GFX_INDEX, 0, WREG32_P(mmGRBM_GFX_INDEX, 0,
~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
...@@ -190,10 +196,52 @@ static int vce_v3_0_start(struct amdgpu_device *adev) ...@@ -190,10 +196,52 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
return 0; return 0;
} }
#define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074
#define VCE_HARVEST_FUSE_MACRO__SHIFT 27
#define VCE_HARVEST_FUSE_MACRO__MASK 0x18000000
static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
{
u32 tmp;
unsigned ret;
if (adev->flags & AMDGPU_IS_APU)
tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) &
VCE_HARVEST_FUSE_MACRO__MASK) >>
VCE_HARVEST_FUSE_MACRO__SHIFT;
else
tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) &
CC_HARVEST_FUSES__VCE_DISABLE_MASK) >>
CC_HARVEST_FUSES__VCE_DISABLE__SHIFT;
switch (tmp) {
case 1:
ret = AMDGPU_VCE_HARVEST_VCE0;
break;
case 2:
ret = AMDGPU_VCE_HARVEST_VCE1;
break;
case 3:
ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
break;
default:
ret = 0;
}
return ret;
}
static int vce_v3_0_early_init(void *handle) static int vce_v3_0_early_init(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev);
if ((adev->vce.harvest_config &
(AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) ==
(AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1))
return -ENOENT;
vce_v3_0_set_ring_funcs(adev); vce_v3_0_set_ring_funcs(adev);
vce_v3_0_set_irq_funcs(adev); vce_v3_0_set_irq_funcs(adev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment