Commit 9b8253ce authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: add ucode loader for cayman

The MC ucode is no longer loaded by the vbios
tables as on previous asics.  It now must be loaded
by the driver.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent b7cfc9fe
...@@ -37,6 +37,11 @@ ...@@ -37,6 +37,11 @@
#define EVERGREEN_RLC_UCODE_SIZE 768 #define EVERGREEN_RLC_UCODE_SIZE 768
#define BTC_MC_UCODE_SIZE 6024 #define BTC_MC_UCODE_SIZE 6024
#define CAYMAN_PFP_UCODE_SIZE 2176
#define CAYMAN_PM4_UCODE_SIZE 2176
#define CAYMAN_RLC_UCODE_SIZE 1024
#define CAYMAN_MC_UCODE_SIZE 6037
/* Firmware Names */ /* Firmware Names */
MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
MODULE_FIRMWARE("radeon/BARTS_me.bin"); MODULE_FIRMWARE("radeon/BARTS_me.bin");
...@@ -48,6 +53,10 @@ MODULE_FIRMWARE("radeon/TURKS_mc.bin"); ...@@ -48,6 +53,10 @@ MODULE_FIRMWARE("radeon/TURKS_mc.bin");
MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
MODULE_FIRMWARE("radeon/CAICOS_me.bin"); MODULE_FIRMWARE("radeon/CAICOS_me.bin");
MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
#define BTC_IO_MC_REGS_SIZE 29 #define BTC_IO_MC_REGS_SIZE 29
...@@ -147,12 +156,44 @@ static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { ...@@ -147,12 +156,44 @@ static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
{0x0000009f, 0x00916a00} {0x0000009f, 0x00916a00}
}; };
static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
{0x00000077, 0xff010100},
{0x00000078, 0x00000000},
{0x00000079, 0x00001434},
{0x0000007a, 0xcc08ec08},
{0x0000007b, 0x00040000},
{0x0000007c, 0x000080c0},
{0x0000007d, 0x09000000},
{0x0000007e, 0x00210404},
{0x00000081, 0x08a8e800},
{0x00000082, 0x00030444},
{0x00000083, 0x00000000},
{0x00000085, 0x00000001},
{0x00000086, 0x00000002},
{0x00000087, 0x48490000},
{0x00000088, 0x20244647},
{0x00000089, 0x00000005},
{0x0000008b, 0x66030000},
{0x0000008c, 0x00006603},
{0x0000008d, 0x00000100},
{0x0000008f, 0x00001c0a},
{0x00000090, 0xff000001},
{0x00000094, 0x00101101},
{0x00000095, 0x00000fff},
{0x00000096, 0x00116fff},
{0x00000097, 0x60010000},
{0x00000098, 0x10010000},
{0x00000099, 0x00006000},
{0x0000009a, 0x00001000},
{0x0000009f, 0x00976b00}
};
int btc_mc_load_microcode(struct radeon_device *rdev) int btc_mc_load_microcode(struct radeon_device *rdev)
{ {
const __be32 *fw_data; const __be32 *fw_data;
u32 mem_type, running, blackout = 0; u32 mem_type, running, blackout = 0;
u32 *io_mc_regs; u32 *io_mc_regs;
int i; int i, ucode_size, regs_size;
if (!rdev->mc_fw) if (!rdev->mc_fw)
return -EINVAL; return -EINVAL;
...@@ -160,13 +201,24 @@ int btc_mc_load_microcode(struct radeon_device *rdev) ...@@ -160,13 +201,24 @@ int btc_mc_load_microcode(struct radeon_device *rdev)
switch (rdev->family) { switch (rdev->family) {
case CHIP_BARTS: case CHIP_BARTS:
io_mc_regs = (u32 *)&barts_io_mc_regs; io_mc_regs = (u32 *)&barts_io_mc_regs;
ucode_size = BTC_MC_UCODE_SIZE;
regs_size = BTC_IO_MC_REGS_SIZE;
break; break;
case CHIP_TURKS: case CHIP_TURKS:
io_mc_regs = (u32 *)&turks_io_mc_regs; io_mc_regs = (u32 *)&turks_io_mc_regs;
ucode_size = BTC_MC_UCODE_SIZE;
regs_size = BTC_IO_MC_REGS_SIZE;
break; break;
case CHIP_CAICOS: case CHIP_CAICOS:
default: default:
io_mc_regs = (u32 *)&caicos_io_mc_regs; io_mc_regs = (u32 *)&caicos_io_mc_regs;
ucode_size = BTC_MC_UCODE_SIZE;
regs_size = BTC_IO_MC_REGS_SIZE;
break;
case CHIP_CAYMAN:
io_mc_regs = (u32 *)&cayman_io_mc_regs;
ucode_size = CAYMAN_MC_UCODE_SIZE;
regs_size = BTC_IO_MC_REGS_SIZE;
break; break;
} }
...@@ -184,13 +236,13 @@ int btc_mc_load_microcode(struct radeon_device *rdev) ...@@ -184,13 +236,13 @@ int btc_mc_load_microcode(struct radeon_device *rdev)
WREG32(MC_SEQ_SUP_CNTL, 0x00000010); WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
/* load mc io regs */ /* load mc io regs */
for (i = 0; i < BTC_IO_MC_REGS_SIZE; i++) { for (i = 0; i < regs_size; i++) {
WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
} }
/* load the MC ucode */ /* load the MC ucode */
fw_data = (const __be32 *)rdev->mc_fw->data; fw_data = (const __be32 *)rdev->mc_fw->data;
for (i = 0; i < BTC_MC_UCODE_SIZE; i++) for (i = 0; i < ucode_size; i++)
WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
/* put the engine back into the active state */ /* put the engine back into the active state */
...@@ -231,23 +283,38 @@ int ni_init_microcode(struct radeon_device *rdev) ...@@ -231,23 +283,38 @@ int ni_init_microcode(struct radeon_device *rdev)
case CHIP_BARTS: case CHIP_BARTS:
chip_name = "BARTS"; chip_name = "BARTS";
rlc_chip_name = "BTC"; rlc_chip_name = "BTC";
pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
mc_req_size = BTC_MC_UCODE_SIZE * 4;
break; break;
case CHIP_TURKS: case CHIP_TURKS:
chip_name = "TURKS"; chip_name = "TURKS";
rlc_chip_name = "BTC"; rlc_chip_name = "BTC";
pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
mc_req_size = BTC_MC_UCODE_SIZE * 4;
break; break;
case CHIP_CAICOS: case CHIP_CAICOS:
chip_name = "CAICOS"; chip_name = "CAICOS";
rlc_chip_name = "BTC"; rlc_chip_name = "BTC";
pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
mc_req_size = BTC_MC_UCODE_SIZE * 4;
break;
case CHIP_CAYMAN:
chip_name = "CAYMAN";
rlc_chip_name = "CAYMAN";
pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
break; break;
default: BUG(); default: BUG();
} }
pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
mc_req_size = BTC_MC_UCODE_SIZE * 4;
DRM_INFO("Loading %s Microcode\n", chip_name); DRM_INFO("Loading %s Microcode\n", chip_name);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
......
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