drm/radeon/kms: add ucode loader for cayman
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 3 Mar 2011 01:07:28 +0000 (20:07 -0500)
committerDave Airlie <airlied@redhat.com>
Thu, 3 Mar 2011 01:48:38 +0000 (11:48 +1000)
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>
drivers/gpu/drm/radeon/ni.c

index 5e0bef8..058aa4f 100644 (file)
 #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);