]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/radeon/cik.c
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[~andy/linux] / drivers / gpu / drm / radeon / cik.c
index e950fabd7f5e474ab3e60371f669e31805077785..e22be8458d92783f426a699d2e3feef271b7a3f0 100644 (file)
@@ -1697,7 +1697,7 @@ static void cik_srbm_select(struct radeon_device *rdev,
  * 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)
+int ci_mc_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
        u32 running, blackout = 0;
@@ -3046,7 +3046,7 @@ static u32 cik_create_bitmask(u32 bit_width)
 }
 
 /**
- * cik_select_se_sh - select which SE, SH to address
+ * cik_get_rb_disabled - computes the mask of disabled RBs
  *
  * @rdev: radeon_device pointer
  * @max_rb_num: max RBs (render backends) for the asic
@@ -3486,6 +3486,51 @@ int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
        return r;
 }
 
+/**
+ * cik_hdp_flush_cp_ring_emit - emit an hdp flush on the cp
+ *
+ * @rdev: radeon_device pointer
+ * @ridx: radeon ring index
+ *
+ * Emits an hdp flush on the cp.
+ */
+static void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev,
+                                      int ridx)
+{
+       struct radeon_ring *ring = &rdev->ring[ridx];
+       u32 ref_and_mask;
+
+       switch (ring->idx) {
+       case CAYMAN_RING_TYPE_CP1_INDEX:
+       case CAYMAN_RING_TYPE_CP2_INDEX:
+       default:
+               switch (ring->me) {
+               case 0:
+                       ref_and_mask = CP2 << ring->pipe;
+                       break;
+               case 1:
+                       ref_and_mask = CP6 << ring->pipe;
+                       break;
+               default:
+                       return;
+               }
+               break;
+       case RADEON_RING_TYPE_GFX_INDEX:
+               ref_and_mask = CP0;
+               break;
+       }
+
+       radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
+       radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(1) | /* write, wait, write */
+                                WAIT_REG_MEM_FUNCTION(3) |  /* == */
+                                WAIT_REG_MEM_ENGINE(1)));   /* pfp */
+       radeon_ring_write(ring, GPU_HDP_FLUSH_REQ >> 2);
+       radeon_ring_write(ring, GPU_HDP_FLUSH_DONE >> 2);
+       radeon_ring_write(ring, ref_and_mask);
+       radeon_ring_write(ring, ref_and_mask);
+       radeon_ring_write(ring, 0x20); /* poll interval */
+}
+
 /**
  * cik_fence_gfx_ring_emit - emit a fence on the gfx ring
  *
@@ -3512,15 +3557,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(ring, fence->seq);
        radeon_ring_write(ring, 0);
        /* HDP flush */
-       /* We should be using the new WAIT_REG_MEM special op packet here
-        * but it causes the CP to hang
-        */
-       radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
-                                WRITE_DATA_DST_SEL(0)));
-       radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
-       radeon_ring_write(ring, 0);
-       radeon_ring_write(ring, 0);
+       cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
 }
 
 /**
@@ -3550,15 +3587,7 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(ring, fence->seq);
        radeon_ring_write(ring, 0);
        /* HDP flush */
-       /* We should be using the new WAIT_REG_MEM special op packet here
-        * but it causes the CP to hang
-        */
-       radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
-                                WRITE_DATA_DST_SEL(0)));
-       radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
-       radeon_ring_write(ring, 0);
-       radeon_ring_write(ring, 0);
+       cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
 }
 
 bool cik_semaphore_ring_emit(struct radeon_device *rdev,
@@ -3566,8 +3595,6 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev,
                             struct radeon_semaphore *semaphore,
                             bool emit_wait)
 {
-/* TODO: figure out why semaphore cause lockups */
-#if 0
        uint64_t addr = semaphore->gpu_addr;
        unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
 
@@ -3576,9 +3603,6 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel);
 
        return true;
-#else
-       return false;
-#endif
 }
 
 /**
@@ -3816,6 +3840,8 @@ static void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable)
        if (enable)
                WREG32(CP_ME_CNTL, 0);
        else {
+               if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
+                       radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
                WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
                rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
        }
@@ -4014,18 +4040,50 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
                rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
                return r;
        }
+
+       if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
+               radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
+
        return 0;
 }
 
-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring)
+u32 cik_gfx_get_rptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring)
 {
        u32 rptr;
 
+       if (rdev->wb.enabled)
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
+       else
+               rptr = RREG32(CP_RB0_RPTR);
 
+       return rptr;
+}
+
+u32 cik_gfx_get_wptr(struct radeon_device *rdev,
+                    struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       wptr = RREG32(CP_RB0_WPTR);
+
+       return wptr;
+}
+
+void cik_gfx_set_wptr(struct radeon_device *rdev,
+                     struct radeon_ring *ring)
+{
+       WREG32(CP_RB0_WPTR, ring->wptr);
+       (void)RREG32(CP_RB0_WPTR);
+}
+
+u32 cik_compute_get_rptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
+{
+       u32 rptr;
 
        if (rdev->wb.enabled) {
-               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+               rptr = rdev->wb.wb[ring->rptr_offs/4];
        } else {
                mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4037,13 +4095,14 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
        return rptr;
 }
 
-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
-                             struct radeon_ring *ring)
+u32 cik_compute_get_wptr(struct radeon_device *rdev,
+                        struct radeon_ring *ring)
 {
        u32 wptr;
 
        if (rdev->wb.enabled) {
-               wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
+               /* XXX check if swapping is necessary on BE */
+               wptr = rdev->wb.wb[ring->wptr_offs/4];
        } else {
                mutex_lock(&rdev->srbm_mutex);
                cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4055,10 +4114,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
        return wptr;
 }
 
-void cik_compute_ring_set_wptr(struct radeon_device *rdev,
-                              struct radeon_ring *ring)
+void cik_compute_set_wptr(struct radeon_device *rdev,
+                         struct radeon_ring *ring)
 {
-       rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr);
+       /* XXX check if swapping is necessary on BE */
+       rdev->wb.wb[ring->wptr_offs/4] = ring->wptr;
        WDOORBELL32(ring->doorbell_index, ring->wptr);
 }
 
@@ -4852,6 +4912,160 @@ static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
        cik_print_gpu_status_regs(rdev);
 }
 
+struct kv_reset_save_regs {
+       u32 gmcon_reng_execute;
+       u32 gmcon_misc;
+       u32 gmcon_misc3;
+};
+
+static void kv_save_regs_for_reset(struct radeon_device *rdev,
+                                  struct kv_reset_save_regs *save)
+{
+       save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE);
+       save->gmcon_misc = RREG32(GMCON_MISC);
+       save->gmcon_misc3 = RREG32(GMCON_MISC3);
+
+       WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP);
+       WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE |
+                                               STCTRL_STUTTER_EN));
+}
+
+static void kv_restore_regs_for_reset(struct radeon_device *rdev,
+                                     struct kv_reset_save_regs *save)
+{
+       int i;
+
+       WREG32(GMCON_PGFSM_WRITE, 0);
+       WREG32(GMCON_PGFSM_CONFIG, 0x200010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0);
+       WREG32(GMCON_PGFSM_CONFIG, 0x300010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x210000);
+       WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x21003);
+       WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x2b00);
+       WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0);
+       WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x420000);
+       WREG32(GMCON_PGFSM_CONFIG, 0x100010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x120202);
+       WREG32(GMCON_PGFSM_CONFIG, 0x500010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x3e3e36);
+       WREG32(GMCON_PGFSM_CONFIG, 0x600010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x373f3e);
+       WREG32(GMCON_PGFSM_CONFIG, 0x700010ff);
+
+       for (i = 0; i < 5; i++)
+               WREG32(GMCON_PGFSM_WRITE, 0);
+
+       WREG32(GMCON_PGFSM_WRITE, 0x3e1332);
+       WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff);
+
+       WREG32(GMCON_MISC3, save->gmcon_misc3);
+       WREG32(GMCON_MISC, save->gmcon_misc);
+       WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute);
+}
+
+static void cik_gpu_pci_config_reset(struct radeon_device *rdev)
+{
+       struct evergreen_mc_save save;
+       struct kv_reset_save_regs kv_save = { 0 };
+       u32 tmp, i;
+
+       dev_info(rdev->dev, "GPU pci config reset\n");
+
+       /* disable dpm? */
+
+       /* disable cg/pg */
+       cik_fini_pg(rdev);
+       cik_fini_cg(rdev);
+
+       /* Disable GFX parsing/prefetching */
+       WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
+
+       /* Disable MEC parsing/prefetching */
+       WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
+
+       /* sdma0 */
+       tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
+       tmp |= SDMA_HALT;
+       WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
+       /* sdma1 */
+       tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
+       tmp |= SDMA_HALT;
+       WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
+       /* XXX other engines? */
+
+       /* halt the rlc, disable cp internal ints */
+       cik_rlc_stop(rdev);
+
+       udelay(50);
+
+       /* disable mem access */
+       evergreen_mc_stop(rdev, &save);
+       if (evergreen_mc_wait_for_idle(rdev)) {
+               dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
+       }
+
+       if (rdev->flags & RADEON_IS_IGP)
+               kv_save_regs_for_reset(rdev, &kv_save);
+
+       /* disable BM */
+       pci_clear_master(rdev->pdev);
+       /* reset */
+       radeon_pci_config_reset(rdev);
+
+       udelay(100);
+
+       /* wait for asic to come out of reset */
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
+                       break;
+               udelay(1);
+       }
+
+       /* does asic init need to be run first??? */
+       if (rdev->flags & RADEON_IS_IGP)
+               kv_restore_regs_for_reset(rdev, &kv_save);
+}
+
 /**
  * cik_asic_reset - soft reset GPU
  *
@@ -4870,10 +5084,17 @@ int cik_asic_reset(struct radeon_device *rdev)
        if (reset_mask)
                r600_set_bios_scratch_engine_hung(rdev, true);
 
+       /* try soft reset */
        cik_gpu_soft_reset(rdev, reset_mask);
 
        reset_mask = cik_gpu_check_soft_reset(rdev);
 
+       /* try pci config reset */
+       if (reset_mask && radeon_hard_reset)
+               cik_gpu_pci_config_reset(rdev);
+
+       reset_mask = cik_gpu_check_soft_reset(rdev);
+
        if (!reset_mask)
                r600_set_bios_scratch_engine_hung(rdev, false);
 
@@ -5138,20 +5359,6 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
                                WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
                                WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
 
-       /* TC cache setup ??? */
-       WREG32(TC_CFG_L1_LOAD_POLICY0, 0);
-       WREG32(TC_CFG_L1_LOAD_POLICY1, 0);
-       WREG32(TC_CFG_L1_STORE_POLICY, 0);
-
-       WREG32(TC_CFG_L2_LOAD_POLICY0, 0);
-       WREG32(TC_CFG_L2_LOAD_POLICY1, 0);
-       WREG32(TC_CFG_L2_STORE_POLICY0, 0);
-       WREG32(TC_CFG_L2_STORE_POLICY1, 0);
-       WREG32(TC_CFG_L2_ATOMIC_POLICY, 0);
-
-       WREG32(TC_CFG_L1_VOLATILE, 0);
-       WREG32(TC_CFG_L2_VOLATILE, 0);
-
        if (rdev->family == CHIP_KAVERI) {
                u32 tmp = RREG32(CHUB_CONTROL);
                tmp &= ~BYPASS_VM;
@@ -5367,16 +5574,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
        radeon_ring_write(ring, VMID(0));
 
        /* HDP flush */
-       /* We should be using the WAIT_REG_MEM packet here like in
-        * cik_fence_ring_emit(), but it causes the CP to hang in this
-        * context...
-        */
-       radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
-                                WRITE_DATA_DST_SEL(0)));
-       radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
-       radeon_ring_write(ring, 0);
-       radeon_ring_write(ring, 0);
+       cik_hdp_flush_cp_ring_emit(rdev, ridx);
 
        /* bits 0-15 are the VM contexts0-15 */
        radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
@@ -7503,26 +7701,7 @@ static int cik_startup(struct radeon_device *rdev)
 
        cik_mc_program(rdev);
 
-       if (rdev->flags & RADEON_IS_IGP) {
-               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
-                   !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
-                       r = cik_init_microcode(rdev);
-                       if (r) {
-                               DRM_ERROR("Failed to load firmware!\n");
-                               return r;
-                       }
-               }
-       } else {
-               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
-                   !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
-                   !rdev->mc_fw) {
-                       r = cik_init_microcode(rdev);
-                       if (r) {
-                               DRM_ERROR("Failed to load firmware!\n");
-                               return r;
-                       }
-               }
-
+       if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
                r = ci_mc_load_microcode(rdev);
                if (r) {
                        DRM_ERROR("Failed to load MC firmware!\n");
@@ -7627,7 +7806,6 @@ static int cik_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-                            CP_RB0_RPTR, CP_RB0_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        if (r)
                return r;
@@ -7636,7 +7814,6 @@ static int cik_startup(struct radeon_device *rdev)
        /* type-2 packets are deprecated on MEC, use type-3 instead */
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
-                            CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        if (r)
                return r;
@@ -7648,7 +7825,6 @@ static int cik_startup(struct radeon_device *rdev)
        /* type-2 packets are deprecated on MEC, use type-3 instead */
        ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
-                            CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
                             PACKET3(PACKET3_NOP, 0x3FFF));
        if (r)
                return r;
@@ -7660,16 +7836,12 @@ static int cik_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-                            SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET,
-                            SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET,
                             SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
        if (r)
                return r;
 
        ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-                            SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET,
-                            SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET,
                             SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
        if (r)
                return r;
@@ -7685,7 +7857,6 @@ static int cik_startup(struct radeon_device *rdev)
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
                r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
                                     RADEON_CP_PACKET2);
                if (!r)
                        r = uvd_v1_0_init(rdev);
@@ -7731,6 +7902,9 @@ int cik_resume(struct radeon_device *rdev)
        /* init golden registers */
        cik_init_golden_registers(rdev);
 
+       if (rdev->pm.pm_method == PM_METHOD_DPM)
+               radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = cik_startup(rdev);
        if (r) {
@@ -7754,6 +7928,7 @@ int cik_resume(struct radeon_device *rdev)
  */
 int cik_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        dce6_audio_fini(rdev);
        radeon_vm_manager_fini(rdev);
        cik_cp_enable(rdev, false);
@@ -7835,6 +8010,30 @@ int cik_init(struct radeon_device *rdev)
        if (r)
                return r;
 
+       if (rdev->flags & RADEON_IS_IGP) {
+               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+                   !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
+                       r = cik_init_microcode(rdev);
+                       if (r) {
+                               DRM_ERROR("Failed to load firmware!\n");
+                               return r;
+                       }
+               }
+       } else {
+               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+                   !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
+                   !rdev->mc_fw) {
+                       r = cik_init_microcode(rdev);
+                       if (r) {
+                               DRM_ERROR("Failed to load firmware!\n");
+                               return r;
+                       }
+               }
+       }
+
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
@@ -7915,6 +8114,7 @@ int cik_init(struct radeon_device *rdev)
  */
 void cik_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        cik_cp_fini(rdev);
        cik_sdma_fini(rdev);
        cik_fini_pg(rdev);