diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-03-02 20:07:28 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-03-03 11:48:38 +1000 |
commit | 9b8253ce204ad9fcd2aec315066492dfbc73e409 (patch) | |
tree | 082f2f22fb5ae5e70b3ca5af2abe73aba7ec3c23 /drivers/gpu | |
parent | b7cfc9fe921ddd1a926803711df63e1ea52a7563 (diff) |
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: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 5e0bef80ad7f..058aa4f84d19 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -37,6 +37,11 @@ #define EVERGREEN_RLC_UCODE_SIZE 768 #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 */ MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); MODULE_FIRMWARE("radeon/BARTS_me.bin"); @@ -48,6 +53,10 @@ MODULE_FIRMWARE("radeon/TURKS_mc.bin"); MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); MODULE_FIRMWARE("radeon/CAICOS_me.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 @@ -147,12 +156,44 @@ static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { {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) { const __be32 *fw_data; u32 mem_type, running, blackout = 0; u32 *io_mc_regs; - int i; + int i, ucode_size, regs_size; if (!rdev->mc_fw) return -EINVAL; @@ -160,13 +201,24 @@ int btc_mc_load_microcode(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BARTS: io_mc_regs = (u32 *)&barts_io_mc_regs; + ucode_size = BTC_MC_UCODE_SIZE; + regs_size = BTC_IO_MC_REGS_SIZE; break; case CHIP_TURKS: io_mc_regs = (u32 *)&turks_io_mc_regs; + ucode_size = BTC_MC_UCODE_SIZE; + regs_size = BTC_IO_MC_REGS_SIZE; break; case CHIP_CAICOS: default: 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; } @@ -184,13 +236,13 @@ int btc_mc_load_microcode(struct radeon_device *rdev) WREG32(MC_SEQ_SUP_CNTL, 0x00000010); /* 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_DATA, io_mc_regs[(i << 1) + 1]); } /* load the MC ucode */ 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++)); /* put the engine back into the active state */ @@ -231,23 +283,38 @@ int ni_init_microcode(struct radeon_device *rdev) case CHIP_BARTS: chip_name = "BARTS"; 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_TURKS: chip_name = "TURKS"; 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_CAICOS: chip_name = "CAICOS"; 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; 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); snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); |