drm/radeon: add support mc ucode loading on CIK (v2)
authorAlex Deucher <alexander.deucher@amd.com>
Fri, 29 Jun 2012 23:44:04 +0000 (19:44 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Jun 2013 21:50:27 +0000 (17:50 -0400)
Load the GDDR5 ucode and train the links.

v2: update ucode

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/cikd.h

index 36e0fc9d11da7d1c733f4acffd3eb52aec8f0735..8eec582867b5eb3d14d397b41aa725b8a702abbb 100644 (file)
@@ -65,6 +65,122 @@ extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa
 extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
 extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
 
+#define BONAIRE_IO_MC_REGS_SIZE 36
+
+static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
+{
+       {0x00000070, 0x04400000},
+       {0x00000071, 0x80c01803},
+       {0x00000072, 0x00004004},
+       {0x00000073, 0x00000100},
+       {0x00000074, 0x00ff0000},
+       {0x00000075, 0x34000000},
+       {0x00000076, 0x08000014},
+       {0x00000077, 0x00cc08ec},
+       {0x00000078, 0x00000400},
+       {0x00000079, 0x00000000},
+       {0x0000007a, 0x04090000},
+       {0x0000007c, 0x00000000},
+       {0x0000007e, 0x4408a8e8},
+       {0x0000007f, 0x00000304},
+       {0x00000080, 0x00000000},
+       {0x00000082, 0x00000001},
+       {0x00000083, 0x00000002},
+       {0x00000084, 0xf3e4f400},
+       {0x00000085, 0x052024e3},
+       {0x00000087, 0x00000000},
+       {0x00000088, 0x01000000},
+       {0x0000008a, 0x1c0a0000},
+       {0x0000008b, 0xff010000},
+       {0x0000008d, 0xffffefff},
+       {0x0000008e, 0xfff3efff},
+       {0x0000008f, 0xfff3efbf},
+       {0x00000092, 0xf7ffffff},
+       {0x00000093, 0xffffff7f},
+       {0x00000095, 0x00101101},
+       {0x00000096, 0x00000fff},
+       {0x00000097, 0x00116fff},
+       {0x00000098, 0x60010000},
+       {0x00000099, 0x10010000},
+       {0x0000009a, 0x00006000},
+       {0x0000009b, 0x00001000},
+       {0x0000009f, 0x00b48000}
+};
+
+/* ucode loading */
+/**
+ * ci_mc_load_microcode - load MC ucode into the hw
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Load the GDDR MC ucode into the hw (CIK).
+ * Returns 0 on success, error on failure.
+ */
+static int ci_mc_load_microcode(struct radeon_device *rdev)
+{
+       const __be32 *fw_data;
+       u32 running, blackout = 0;
+       u32 *io_mc_regs;
+       int i, ucode_size, regs_size;
+
+       if (!rdev->mc_fw)
+               return -EINVAL;
+
+       switch (rdev->family) {
+       case CHIP_BONAIRE:
+       default:
+               io_mc_regs = (u32 *)&bonaire_io_mc_regs;
+               ucode_size = CIK_MC_UCODE_SIZE;
+               regs_size = BONAIRE_IO_MC_REGS_SIZE;
+               break;
+       }
+
+       running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
+
+       if (running == 0) {
+               if (running) {
+                       blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
+               }
+
+               /* reset the engine and set to writable */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
+
+               /* load mc io regs */
+               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 < ucode_size; i++)
+                       WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+
+               /* put the engine back into the active state */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
+
+               /* wait for training to complete */
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
+                               break;
+                       udelay(1);
+               }
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
+                               break;
+                       udelay(1);
+               }
+
+               if (running)
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+       }
+
+       return 0;
+}
+
 /**
  * cik_init_microcode - load ucode images from disk
  *
index 0dab9c545003c12a85074b7fd8ed2ca72a52df38..2300ae0f09da918b5876ac5603172ca2d15964e1 100644 (file)
 #define                ENABLE_ADVANCED_DRIVER_MODEL                    (1 << 6)
 #define        MC_VM_FB_OFFSET                                 0x2068
 
+#define MC_SHARED_BLACKOUT_CNTL                        0x20ac
+
 #define        MC_ARB_RAMCFG                                   0x2760
 #define                NOOFBANK_SHIFT                                  0
 #define                NOOFBANK_MASK                                   0x00000003
 #define                NOOFGROUPS_SHIFT                                12
 #define                NOOFGROUPS_MASK                                 0x00001000
 
+#define MC_SEQ_SUP_CNTL                                0x28c8
+#define                RUN_MASK                                (1 << 0)
+#define MC_SEQ_SUP_PGM                                 0x28cc
+
+#define        MC_SEQ_TRAIN_WAKEUP_CNTL                        0x28e8
+#define                TRAIN_DONE_D0                           (1 << 30)
+#define                TRAIN_DONE_D1                           (1 << 31)
+
+#define MC_IO_PAD_CNTL_D0                              0x29d0
+#define                MEM_FALL_OUT_CMD                        (1 << 8)
+
+#define MC_SEQ_IO_DEBUG_INDEX                          0x2a44
+#define MC_SEQ_IO_DEBUG_DATA                                   0x2a48
+
 #define        HDP_HOST_PATH_CNTL                              0x2C00
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08