Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5078 → Rev 6104

/drivers/video/drm/radeon/vce_v1_0.c
31,6 → 31,23
#include "radeon_asic.h"
#include "sid.h"
 
#define VCE_V1_0_FW_SIZE (256 * 1024)
#define VCE_V1_0_STACK_SIZE (64 * 1024)
#define VCE_V1_0_DATA_SIZE (7808 * (RADEON_MAX_VCE_HANDLES + 1))
 
struct vce_v1_0_fw_signature
{
int32_t off;
uint32_t len;
int32_t num;
struct {
uint32_t chip_id;
uint32_t keyselect;
uint32_t nonce[4];
uint32_t sigval[4];
} val[8];
};
 
/**
* vce_v1_0_get_rptr - get read pointer
*
82,6 → 99,186
WREG32(VCE_RB_WPTR2, ring->wptr);
}
 
void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable)
{
u32 tmp;
 
if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) {
tmp = RREG32(VCE_CLOCK_GATING_A);
tmp |= CGC_DYN_CLOCK_MODE;
WREG32(VCE_CLOCK_GATING_A, tmp);
 
tmp = RREG32(VCE_UENC_CLOCK_GATING);
tmp &= ~0x1ff000;
tmp |= 0xff800000;
WREG32(VCE_UENC_CLOCK_GATING, tmp);
 
tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
tmp &= ~0x3ff;
WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
} else {
tmp = RREG32(VCE_CLOCK_GATING_A);
tmp &= ~CGC_DYN_CLOCK_MODE;
WREG32(VCE_CLOCK_GATING_A, tmp);
 
tmp = RREG32(VCE_UENC_CLOCK_GATING);
tmp |= 0x1ff000;
tmp &= ~0xff800000;
WREG32(VCE_UENC_CLOCK_GATING, tmp);
 
tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
tmp |= 0x3ff;
WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
}
}
 
static void vce_v1_0_init_cg(struct radeon_device *rdev)
{
u32 tmp;
 
tmp = RREG32(VCE_CLOCK_GATING_A);
tmp |= CGC_DYN_CLOCK_MODE;
WREG32(VCE_CLOCK_GATING_A, tmp);
 
tmp = RREG32(VCE_CLOCK_GATING_B);
tmp |= 0x1e;
tmp &= ~0xe100e1;
WREG32(VCE_CLOCK_GATING_B, tmp);
 
tmp = RREG32(VCE_UENC_CLOCK_GATING);
tmp &= ~0xff9ff000;
WREG32(VCE_UENC_CLOCK_GATING, tmp);
 
tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
tmp &= ~0x3ff;
WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
}
 
int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data)
{
struct vce_v1_0_fw_signature *sign = (void*)rdev->vce_fw->data;
uint32_t chip_id;
int i;
 
switch (rdev->family) {
case CHIP_TAHITI:
chip_id = 0x01000014;
break;
case CHIP_VERDE:
chip_id = 0x01000015;
break;
case CHIP_PITCAIRN:
case CHIP_OLAND:
chip_id = 0x01000016;
break;
case CHIP_ARUBA:
chip_id = 0x01000017;
break;
default:
return -EINVAL;
}
 
for (i = 0; i < sign->num; ++i) {
if (sign->val[i].chip_id == chip_id)
break;
}
 
if (i == sign->num)
return -EINVAL;
 
data += (256 - 64) / 4;
data[0] = sign->val[i].nonce[0];
data[1] = sign->val[i].nonce[1];
data[2] = sign->val[i].nonce[2];
data[3] = sign->val[i].nonce[3];
data[4] = sign->len + 64;
 
memset(&data[5], 0, 44);
memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign));
 
data += data[4] / 4;
data[0] = sign->val[i].sigval[0];
data[1] = sign->val[i].sigval[1];
data[2] = sign->val[i].sigval[2];
data[3] = sign->val[i].sigval[3];
 
rdev->vce.keyselect = sign->val[i].keyselect;
 
return 0;
}
 
unsigned vce_v1_0_bo_size(struct radeon_device *rdev)
{
WARN_ON(VCE_V1_0_FW_SIZE < rdev->vce_fw->size);
return VCE_V1_0_FW_SIZE + VCE_V1_0_STACK_SIZE + VCE_V1_0_DATA_SIZE;
}
 
int vce_v1_0_resume(struct radeon_device *rdev)
{
uint64_t addr = rdev->vce.gpu_addr;
uint32_t size;
int i;
 
WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16));
WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
WREG32(VCE_CLOCK_GATING_B, 0);
 
WREG32_P(VCE_LMI_FW_PERIODIC_CTRL, 0x4, ~0x4);
 
WREG32(VCE_LMI_CTRL, 0x00398000);
WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1);
WREG32(VCE_LMI_SWAP_CNTL, 0);
WREG32(VCE_LMI_SWAP_CNTL1, 0);
WREG32(VCE_LMI_VM_CTRL, 0);
 
WREG32(VCE_VCPU_SCRATCH7, RADEON_MAX_VCE_HANDLES);
 
addr += 256;
size = VCE_V1_0_FW_SIZE;
WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
WREG32(VCE_VCPU_CACHE_SIZE0, size);
 
addr += size;
size = VCE_V1_0_STACK_SIZE;
WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
WREG32(VCE_VCPU_CACHE_SIZE1, size);
 
addr += size;
size = VCE_V1_0_DATA_SIZE;
WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
WREG32(VCE_VCPU_CACHE_SIZE2, size);
 
WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100);
 
WREG32(VCE_LMI_FW_START_KEYSEL, rdev->vce.keyselect);
 
for (i = 0; i < 10; ++i) {
mdelay(10);
if (RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_DONE)
break;
}
 
if (i == 10)
return -ETIMEDOUT;
 
if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_PASS))
return -EINVAL;
 
for (i = 0; i < 10; ++i) {
mdelay(10);
if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_BUSY))
break;
}
 
if (i == 10)
return -ETIMEDOUT;
 
vce_v1_0_init_cg(rdev);
 
return 0;
}
 
/**
* vce_v1_0_start - start VCE block
*