Commit 1ebe9280 authored by Alex Deucher's avatar Alex Deucher Committed by Christian König

drm/radeon: add support for newer mc ucode on SI (v2)

May fix stability issues with some newer cards.

v2: print out mc firmware version used and size
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 5fb9cc4d
...@@ -57,6 +57,9 @@ ...@@ -57,6 +57,9 @@
#define BTC_MC_UCODE_SIZE 6024 #define BTC_MC_UCODE_SIZE 6024
#define CAYMAN_MC_UCODE_SIZE 6037 #define CAYMAN_MC_UCODE_SIZE 6037
#define SI_MC_UCODE_SIZE 7769 #define SI_MC_UCODE_SIZE 7769
#define TAHITI_MC_UCODE_SIZE 7808
#define PITCAIRN_MC_UCODE_SIZE 7775
#define VERDE_MC_UCODE_SIZE 7875
#define OLAND_MC_UCODE_SIZE 7863 #define OLAND_MC_UCODE_SIZE 7863
#define CIK_MC_UCODE_SIZE 7866 #define CIK_MC_UCODE_SIZE 7866
#define HAWAII_MC_UCODE_SIZE 7933 #define HAWAII_MC_UCODE_SIZE 7933
......
...@@ -39,30 +39,35 @@ MODULE_FIRMWARE("radeon/TAHITI_pfp.bin"); ...@@ -39,30 +39,35 @@ MODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
MODULE_FIRMWARE("radeon/TAHITI_me.bin"); MODULE_FIRMWARE("radeon/TAHITI_me.bin");
MODULE_FIRMWARE("radeon/TAHITI_ce.bin"); MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
MODULE_FIRMWARE("radeon/TAHITI_mc.bin"); MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
MODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
MODULE_FIRMWARE("radeon/TAHITI_smc.bin"); MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
MODULE_FIRMWARE("radeon/VERDE_me.bin"); MODULE_FIRMWARE("radeon/VERDE_me.bin");
MODULE_FIRMWARE("radeon/VERDE_ce.bin"); MODULE_FIRMWARE("radeon/VERDE_ce.bin");
MODULE_FIRMWARE("radeon/VERDE_mc.bin"); MODULE_FIRMWARE("radeon/VERDE_mc.bin");
MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
MODULE_FIRMWARE("radeon/VERDE_rlc.bin"); MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
MODULE_FIRMWARE("radeon/VERDE_smc.bin"); MODULE_FIRMWARE("radeon/VERDE_smc.bin");
MODULE_FIRMWARE("radeon/OLAND_pfp.bin"); MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
MODULE_FIRMWARE("radeon/OLAND_me.bin"); MODULE_FIRMWARE("radeon/OLAND_me.bin");
MODULE_FIRMWARE("radeon/OLAND_ce.bin"); MODULE_FIRMWARE("radeon/OLAND_ce.bin");
MODULE_FIRMWARE("radeon/OLAND_mc.bin"); MODULE_FIRMWARE("radeon/OLAND_mc.bin");
MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
MODULE_FIRMWARE("radeon/OLAND_smc.bin"); MODULE_FIRMWARE("radeon/OLAND_smc.bin");
MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
MODULE_FIRMWARE("radeon/HAINAN_me.bin"); MODULE_FIRMWARE("radeon/HAINAN_me.bin");
MODULE_FIRMWARE("radeon/HAINAN_ce.bin"); MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
MODULE_FIRMWARE("radeon/HAINAN_mc.bin"); MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
MODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
MODULE_FIRMWARE("radeon/HAINAN_smc.bin"); MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
...@@ -1467,7 +1472,7 @@ int si_mc_load_microcode(struct radeon_device *rdev) ...@@ -1467,7 +1472,7 @@ int si_mc_load_microcode(struct radeon_device *rdev)
const __be32 *fw_data; const __be32 *fw_data;
u32 running, blackout = 0; u32 running, blackout = 0;
u32 *io_mc_regs; u32 *io_mc_regs;
int i, ucode_size, regs_size; int i, regs_size, ucode_size = rdev->mc_fw->size / 4;
if (!rdev->mc_fw) if (!rdev->mc_fw)
return -EINVAL; return -EINVAL;
...@@ -1475,28 +1480,23 @@ int si_mc_load_microcode(struct radeon_device *rdev) ...@@ -1475,28 +1480,23 @@ int si_mc_load_microcode(struct radeon_device *rdev)
switch (rdev->family) { switch (rdev->family) {
case CHIP_TAHITI: case CHIP_TAHITI:
io_mc_regs = (u32 *)&tahiti_io_mc_regs; io_mc_regs = (u32 *)&tahiti_io_mc_regs;
ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE;
break; break;
case CHIP_PITCAIRN: case CHIP_PITCAIRN:
io_mc_regs = (u32 *)&pitcairn_io_mc_regs; io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE;
break; break;
case CHIP_VERDE: case CHIP_VERDE:
default: default:
io_mc_regs = (u32 *)&verde_io_mc_regs; io_mc_regs = (u32 *)&verde_io_mc_regs;
ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE;
break; break;
case CHIP_OLAND: case CHIP_OLAND:
io_mc_regs = (u32 *)&oland_io_mc_regs; io_mc_regs = (u32 *)&oland_io_mc_regs;
ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE;
break; break;
case CHIP_HAINAN: case CHIP_HAINAN:
io_mc_regs = (u32 *)&hainan_io_mc_regs; io_mc_regs = (u32 *)&hainan_io_mc_regs;
ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE;
break; break;
} }
...@@ -1552,7 +1552,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1552,7 +1552,7 @@ static int si_init_microcode(struct radeon_device *rdev)
const char *chip_name; const char *chip_name;
const char *rlc_chip_name; const char *rlc_chip_name;
size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
size_t smc_req_size; size_t smc_req_size, mc2_req_size;
char fw_name[30]; char fw_name[30];
int err; int err;
...@@ -1567,6 +1567,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1567,6 +1567,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4;
mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4); smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
break; break;
case CHIP_PITCAIRN: case CHIP_PITCAIRN:
...@@ -1577,6 +1578,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1577,6 +1578,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4;
mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4); smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
break; break;
case CHIP_VERDE: case CHIP_VERDE:
...@@ -1587,6 +1589,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1587,6 +1589,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4;
mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4); smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
break; break;
case CHIP_OLAND: case CHIP_OLAND:
...@@ -1596,7 +1599,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1596,7 +1599,7 @@ static int si_init_microcode(struct radeon_device *rdev)
me_req_size = SI_PM4_UCODE_SIZE * 4; me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = OLAND_MC_UCODE_SIZE * 4; mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4); smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
break; break;
case CHIP_HAINAN: case CHIP_HAINAN:
...@@ -1606,7 +1609,7 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1606,7 +1609,7 @@ static int si_init_microcode(struct radeon_device *rdev)
me_req_size = SI_PM4_UCODE_SIZE * 4; me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = OLAND_MC_UCODE_SIZE * 4; mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4); smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
break; break;
default: BUG(); default: BUG();
...@@ -1659,16 +1662,22 @@ static int si_init_microcode(struct radeon_device *rdev) ...@@ -1659,16 +1662,22 @@ static int si_init_microcode(struct radeon_device *rdev)
err = -EINVAL; err = -EINVAL;
} }
snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
if (err) {
snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
if (err) if (err)
goto out; goto out;
if (rdev->mc_fw->size != mc_req_size) { }
if ((rdev->mc_fw->size != mc_req_size) &&
(rdev->mc_fw->size != mc2_req_size)) {
printk(KERN_ERR printk(KERN_ERR
"si_mc: Bogus length %zu in firmware \"%s\"\n", "si_mc: Bogus length %zu in firmware \"%s\"\n",
rdev->mc_fw->size, fw_name); rdev->mc_fw->size, fw_name);
err = -EINVAL; err = -EINVAL;
} }
DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
......
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