drm/radeon/pm: move pm handling into the asic specific code
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Dec 2013 19:07:14 +0000 (14:07 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 24 Dec 2013 22:57:06 +0000 (17:57 -0500)
We need more control over the ordering of dpm init with
respect to the rest of the asic.  Specifically, the SMC
has to be initialized before the rlc and cg/pg.  The pm
code currently initializes late in the driver, but we need
it to happen much earlier so move pm handling into the asic
specific callbacks.

This makes dpm more reliable and makes clockgating work
properly on CIK parts and should help on SI parts as well.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
21 files changed:
drivers/gpu/drm/radeon/btc_dpm.c
drivers/gpu/drm/radeon/ci_dpm.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/ni_dpm.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/si_dpm.c

index 2eb985a0242cd251d707b95d1bd88da85fb2bf43..0fbd36f3d4e9da34b65bc5f8ed302dc143b2d3c7 100644 (file)
@@ -49,6 +49,7 @@ struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 
+extern int ni_mc_load_microcode(struct radeon_device *rdev);
 
 //********* BARTS **************//
 static const u32 barts_cgcg_cgls_default[] =
@@ -2561,7 +2562,11 @@ void btc_dpm_disable(struct radeon_device *rdev)
 void btc_dpm_setup_asic(struct radeon_device *rdev)
 {
        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       int r;
 
+       r = ni_mc_load_microcode(rdev);
+       if (r)
+               DRM_ERROR("Failed to load MC firmware!\n");
        rv770_get_memory_type(rdev);
        rv740_read_clock_registers(rdev);
        btc_read_arb_registers(rdev);
index 6eab12d1641b2d922065dd20da454d2523a62df8..a3c4711d8222f4a22744b47867a7a26ebd20984f 100644 (file)
@@ -171,6 +171,7 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
                                                     struct atom_voltage_table *voltage_table);
 extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
 extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
+extern int ci_mc_load_microcode(struct radeon_device *rdev);
 
 static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev,
                                         struct atom_voltage_table_entry *voltage_table,
@@ -4547,6 +4548,11 @@ void ci_dpm_post_set_power_state(struct radeon_device *rdev)
 
 void ci_dpm_setup_asic(struct radeon_device *rdev)
 {
+       int r;
+
+       r = ci_mc_load_microcode(rdev);
+       if (r)
+               DRM_ERROR("Failed to load MC firmware!\n");
        ci_read_clock_registers(rdev);
        ci_get_memory_type(rdev);
        ci_enable_acpi_power_management(rdev);
index 4ddc3e5c2d97188ba702a0b7d803b10edeb9e3bd..25a6ef6c7e4c0be020437ab2b0b32195da927f04 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;
@@ -7501,7 +7501,7 @@ static int cik_startup(struct radeon_device *rdev)
 
        cik_mc_program(rdev);
 
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       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");
@@ -7710,6 +7710,8 @@ int cik_resume(struct radeon_device *rdev)
        /* init golden registers */
        cik_init_golden_registers(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = cik_startup(rdev);
        if (r) {
@@ -7733,6 +7735,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 +7838,9 @@ int cik_init(struct radeon_device *rdev)
                }
        }
 
+       /* 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 +7921,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);
index 4abf8b651b49f122172b124b629a60916fc61c54..594a3d7abcf8899f4aa88a67fe8654407771defa 100644 (file)
@@ -5109,7 +5109,7 @@ static int evergreen_startup(struct radeon_device *rdev)
 
        evergreen_mc_program(rdev);
 
-       if (ASIC_IS_DCE5(rdev)) {
+       if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) {
                r = ni_mc_load_microcode(rdev);
                if (r) {
                        DRM_ERROR("Failed to load MC firmware!\n");
@@ -5252,6 +5252,8 @@ int evergreen_resume(struct radeon_device *rdev)
        /* init golden registers */
        evergreen_init_golden_registers(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = evergreen_startup(rdev);
        if (r) {
@@ -5266,6 +5268,7 @@ int evergreen_resume(struct radeon_device *rdev)
 
 int evergreen_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r600_audio_fini(rdev);
        uvd_v1_0_fini(rdev);
        radeon_uvd_suspend(rdev);
@@ -5360,6 +5363,9 @@ int evergreen_init(struct radeon_device *rdev)
                }
        }
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -5412,6 +5418,7 @@ int evergreen_init(struct radeon_device *rdev)
 
 void evergreen_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_audio_fini(rdev);
        r700_cp_fini(rdev);
        r600_dma_fini(rdev);
index 757141a75c64751d10a32eab01f670c729c177c2..494ba006e8b10d15f39871d083cdf0f17acf0e9f 100644 (file)
@@ -1866,7 +1866,7 @@ static int cayman_startup(struct radeon_device *rdev)
 
        evergreen_mc_program(rdev);
 
-       if (!(rdev->flags & RADEON_IS_IGP)) {
+       if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
                r = ni_mc_load_microcode(rdev);
                if (r) {
                        DRM_ERROR("Failed to load MC firmware!\n");
@@ -2035,6 +2035,8 @@ int cayman_resume(struct radeon_device *rdev)
        /* init golden registers */
        ni_init_golden_registers(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = cayman_startup(rdev);
        if (r) {
@@ -2047,6 +2049,7 @@ int cayman_resume(struct radeon_device *rdev)
 
 int cayman_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        if (ASIC_IS_DCE6(rdev))
                dce6_audio_fini(rdev);
        else
@@ -2135,6 +2138,9 @@ int cayman_init(struct radeon_device *rdev)
                }
        }
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
 
@@ -2194,6 +2200,7 @@ int cayman_init(struct radeon_device *rdev)
 
 void cayman_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        cayman_cp_fini(rdev);
        cayman_dma_fini(rdev);
        r600_irq_fini(rdev);
index cb92287ca985753db88e6e42611c9ec689461810..c351226ecb31b0d9fa2d94a32ac23d504d61952b 100644 (file)
@@ -720,6 +720,8 @@ static const u32 cayman_sysls_enable[] =
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 
+extern int ni_mc_load_microcode(struct radeon_device *rdev);
+
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
 {
         struct ni_power_info *pi = rdev->pm.dpm.priv;
@@ -3565,7 +3567,11 @@ void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
 void ni_dpm_setup_asic(struct radeon_device *rdev)
 {
        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       int r;
 
+       r = ni_mc_load_microcode(rdev);
+       if (r)
+               DRM_ERROR("Failed to load MC firmware!\n");
        ni_read_clock_registers(rdev);
        btc_read_arb_registers(rdev);
        rv770_get_memory_type(rdev);
index 10abc4d5a6cc396a85bb32d4b7d094b748757f99..526d2aa7d70f30e2b238e36a2b8f69a45058f26d 100644 (file)
@@ -3913,6 +3913,8 @@ int r100_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = r100_startup(rdev);
        if (r) {
@@ -3923,6 +3925,7 @@ int r100_resume(struct radeon_device *rdev)
 
 int r100_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
        r100_irq_disable(rdev);
@@ -3933,6 +3936,7 @@ int r100_suspend(struct radeon_device *rdev)
 
 void r100_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
@@ -4039,6 +4043,9 @@ int r100_init(struct radeon_device *rdev)
        }
        r100_set_safe_registers(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = r100_startup(rdev);
        if (r) {
index d8dd269b9159fcc0dfbed98cf8c3c2037742e671..7c63ef840e86abaf04f216201b32ee2f40323b9b 100644 (file)
@@ -1430,6 +1430,8 @@ int r300_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = r300_startup(rdev);
        if (r) {
@@ -1440,6 +1442,7 @@ int r300_resume(struct radeon_device *rdev)
 
 int r300_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
        r100_irq_disable(rdev);
@@ -1452,6 +1455,7 @@ int r300_suspend(struct radeon_device *rdev)
 
 void r300_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
@@ -1538,6 +1542,9 @@ int r300_init(struct radeon_device *rdev)
        }
        r300_set_reg_safe(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = r300_startup(rdev);
        if (r) {
index 6edf2b3a52b4d7e4ba82cc063048ffb73733a984..3768aab2710b3943261312c4fcc5184b4f18a6fb 100644 (file)
@@ -325,6 +325,8 @@ int r420_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = r420_startup(rdev);
        if (r) {
@@ -335,6 +337,7 @@ int r420_resume(struct radeon_device *rdev)
 
 int r420_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r420_cp_errata_fini(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
@@ -348,6 +351,7 @@ int r420_suspend(struct radeon_device *rdev)
 
 void r420_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
@@ -444,6 +448,9 @@ int r420_init(struct radeon_device *rdev)
        }
        r420_set_reg_safe(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = r420_startup(rdev);
        if (r) {
index e1aece73b370c1ec9d6d9f86273caad0cbb14d36..e209eb75024f9dc1c441518cbe8f8d70a41844f5 100644 (file)
@@ -240,6 +240,8 @@ int r520_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = r520_startup(rdev);
        if (r) {
@@ -312,6 +314,9 @@ int r520_init(struct radeon_device *rdev)
                return r;
        rv515_set_safe_registers(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = r520_startup(rdev);
        if (r) {
index 09e83f26495832818f494c08c756042163df66dd..d05611aba1349d098f6ea3a0b1a6eac3dc81a45c 100644 (file)
@@ -2881,6 +2881,8 @@ int r600_resume(struct radeon_device *rdev)
        /* post card */
        atom_asic_init(rdev->mode_info.atom_context);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = r600_startup(rdev);
        if (r) {
@@ -2894,6 +2896,7 @@ int r600_resume(struct radeon_device *rdev)
 
 int r600_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r600_audio_fini(rdev);
        r600_cp_stop(rdev);
        r600_dma_stop(rdev);
@@ -2970,6 +2973,9 @@ int r600_init(struct radeon_device *rdev)
                }
        }
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -3002,6 +3008,7 @@ int r600_init(struct radeon_device *rdev)
 
 void r600_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_audio_fini(rdev);
        r600_cp_fini(rdev);
        r600_dma_fini(rdev);
index 39b033b441d2a6f76e8d021df7085568538887b3..5f0ff43e5bb915b4cb9ad9912c98f6642eda2531 100644 (file)
@@ -1330,6 +1330,7 @@ int radeon_device_init(struct radeon_device *rdev,
                if (r)
                        return r;
        }
+
        if ((radeon_testing & 1)) {
                if (rdev->accel_working)
                        radeon_test_moves(rdev);
@@ -1455,7 +1456,6 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
 
        radeon_save_bios_scratch_regs(rdev);
 
-       radeon_pm_suspend(rdev);
        radeon_suspend(rdev);
        radeon_hpd_fini(rdev);
        /* evict remaining vram memory */
@@ -1516,14 +1516,22 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
        if (r)
                DRM_ERROR("ib ring test failed (%d).\n", r);
 
-       radeon_pm_resume(rdev);
+       if (rdev->pm.dpm_enabled) {
+               /* do dpm late init */
+               r = radeon_pm_late_init(rdev);
+               if (r) {
+                       rdev->pm.dpm_enabled = false;
+                       DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+               }
+       }
+
        radeon_restore_bios_scratch_regs(rdev);
 
        if (fbcon) {
                radeon_fbdev_set_suspend(rdev, 0);
                console_unlock();
        }
-       
+
        /* init dig PHYs, disp eng pll */
        if (rdev->is_atom_bios) {
                radeon_atom_encoder_init(rdev);
index 7b253815a3237153b668d660e9ef7d56642597ec..7ea647b84733a62e2b0416b6398ad5f33ec983ec 100644 (file)
@@ -1464,12 +1464,22 @@ int radeon_modeset_init(struct radeon_device *rdev)
        /* setup afmt */
        radeon_afmt_init(rdev);
 
-       /* Initialize power management */
-       radeon_pm_init(rdev);
-
        radeon_fbdev_init(rdev);
        drm_kms_helper_poll_init(rdev->ddev);
 
+       if (rdev->pm.dpm_enabled) {
+               /* do dpm late init */
+               ret = radeon_pm_late_init(rdev);
+               if (ret) {
+                       rdev->pm.dpm_enabled = false;
+                       DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+               }
+               /* set the dpm state for PX since there won't be
+                * a modeset to call this.
+                */
+               radeon_pm_compute_clocks(rdev);
+       }
+
        return 0;
 }
 
@@ -1477,7 +1487,6 @@ void radeon_modeset_fini(struct radeon_device *rdev)
 {
        radeon_fbdev_fini(rdev);
        kfree(rdev->mode_info.bios_hardcoded_edid);
-       radeon_pm_fini(rdev);
 
        if (rdev->mode_info.mode_config_initialized) {
                radeon_afmt_fini(rdev);
index 7fc76d165e8995cb391d4f96f1d20c9481bb2ea6..933ada0147b57b5ed9890f8bb09aa14f784c8d36 100644 (file)
@@ -1034,10 +1034,6 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev)
        mutex_unlock(&rdev->pm.mutex);
        if (ret)
                goto dpm_resume_fail;
-       ret = radeon_pm_late_init(rdev);
-       if (ret)
-               goto dpm_resume_fail;
-
        rdev->pm.dpm_enabled = true;
        radeon_pm_compute_clocks(rdev);
        return;
@@ -1176,13 +1172,9 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
        radeon_dpm_setup_asic(rdev);
        ret = radeon_dpm_enable(rdev);
        mutex_unlock(&rdev->pm.mutex);
-       if (ret)
-               goto dpm_failed;
-       ret = radeon_pm_late_init(rdev);
        if (ret)
                goto dpm_failed;
        rdev->pm.dpm_enabled = true;
-       radeon_pm_compute_clocks(rdev);
 
        ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
        if (ret)
@@ -1441,6 +1433,9 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
        struct drm_crtc *crtc;
        struct radeon_crtc *radeon_crtc;
 
+       if (!rdev->pm.dpm_enabled)
+               return;
+
        mutex_lock(&rdev->pm.mutex);
 
        /* update active crtc counts */
index 9566b5940a5ae723f90dfa11427e3f09bac233b3..b5c2369cda2fe28ca043fe91f4fcfe12fc227fc6 100644 (file)
@@ -474,6 +474,8 @@ int rs400_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = rs400_startup(rdev);
        if (r) {
@@ -484,6 +486,7 @@ int rs400_resume(struct radeon_device *rdev)
 
 int rs400_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
        r100_irq_disable(rdev);
@@ -493,6 +496,7 @@ int rs400_suspend(struct radeon_device *rdev)
 
 void rs400_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
@@ -560,6 +564,9 @@ int rs400_init(struct radeon_device *rdev)
                return r;
        r300_set_reg_safe(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = rs400_startup(rdev);
        if (r) {
index 76cc8d3aafec461d0b41668f25500f2a4753dbc3..fdcde7693032c28cc30008b494fd573fd82e58f3 100644 (file)
@@ -1048,6 +1048,8 @@ int rs600_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = rs600_startup(rdev);
        if (r) {
@@ -1058,6 +1060,7 @@ int rs600_resume(struct radeon_device *rdev)
 
 int rs600_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
@@ -1068,6 +1071,7 @@ int rs600_suspend(struct radeon_device *rdev)
 
 void rs600_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
@@ -1136,6 +1140,9 @@ int rs600_init(struct radeon_device *rdev)
                return r;
        rs600_set_safe_registers(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = rs600_startup(rdev);
        if (r) {
index 1c560629575a8906fb74e006285096f07eac7f19..e461b45f29a97ceb849cd983f79864c01e68a349 100644 (file)
@@ -746,6 +746,8 @@ int rs690_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = rs690_startup(rdev);
        if (r) {
@@ -756,6 +758,7 @@ int rs690_resume(struct radeon_device *rdev)
 
 int rs690_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r600_audio_fini(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
@@ -766,6 +769,7 @@ int rs690_suspend(struct radeon_device *rdev)
 
 void rs690_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_audio_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
@@ -835,6 +839,9 @@ int rs690_init(struct radeon_device *rdev)
                return r;
        rs600_set_safe_registers(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = rs690_startup(rdev);
        if (r) {
index 5d1c316115efa31ab7b029de44db66e399322e71..98e8138ff77945ecdba447bdcb94310c30dcb1c7 100644 (file)
@@ -586,6 +586,8 @@ int rv515_resume(struct radeon_device *rdev)
        /* Initialize surface registers */
        radeon_surface_init(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r =  rv515_startup(rdev);
        if (r) {
@@ -596,6 +598,7 @@ int rv515_resume(struct radeon_device *rdev)
 
 int rv515_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r100_cp_disable(rdev);
        radeon_wb_disable(rdev);
        rs600_irq_disable(rdev);
@@ -612,6 +615,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
 
 void rv515_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        radeon_wb_fini(rdev);
        radeon_ib_pool_fini(rdev);
@@ -685,6 +689,9 @@ int rv515_init(struct radeon_device *rdev)
                return r;
        rv515_set_safe_registers(rdev);
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->accel_working = true;
        r = rv515_startup(rdev);
        if (r) {
index 45774ff77d9217b16094f9ea5c769603e3c6b604..82a6d44586f8478f017f2b867c285ff7b723c871 100644 (file)
@@ -1784,6 +1784,8 @@ int rv770_resume(struct radeon_device *rdev)
        /* init golden registers */
        rv770_init_golden_registers(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = rv770_startup(rdev);
        if (r) {
@@ -1798,6 +1800,7 @@ int rv770_resume(struct radeon_device *rdev)
 
 int rv770_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        r600_audio_fini(rdev);
        uvd_v1_0_fini(rdev);
        radeon_uvd_suspend(rdev);
@@ -1876,6 +1879,9 @@ int rv770_init(struct radeon_device *rdev)
                }
        }
 
+       /* Initialize power management */
+       radeon_pm_init(rdev);
+
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -1915,6 +1921,7 @@ int rv770_init(struct radeon_device *rdev)
 
 void rv770_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r700_cp_fini(rdev);
        r600_dma_fini(rdev);
        r600_irq_fini(rdev);
index 1df46316d835e141a4a0cef581eda6138f5dbfdf..7619bc6bb242ae9c17af0d46b7765cc15f46133c 100644 (file)
@@ -1460,7 +1460,7 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
 };
 
 /* ucode loading */
-static int si_mc_load_microcode(struct radeon_device *rdev)
+int si_mc_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
        u32 running, blackout = 0;
@@ -6322,10 +6322,12 @@ static int si_startup(struct radeon_device *rdev)
 
        si_mc_program(rdev);
 
-       r = si_mc_load_microcode(rdev);
-       if (r) {
-               DRM_ERROR("Failed to load MC firmware!\n");
-               return r;
+       if (!rdev->pm.dpm_enabled) {
+               r = si_mc_load_microcode(rdev);
+               if (r) {
+                       DRM_ERROR("Failed to load MC firmware!\n");
+                       return r;
+               }
        }
 
        r = si_pcie_gart_enable(rdev);
@@ -6502,6 +6504,8 @@ int si_resume(struct radeon_device *rdev)
        /* init golden registers */
        si_init_golden_registers(rdev);
 
+       radeon_pm_resume(rdev);
+
        rdev->accel_working = true;
        r = si_startup(rdev);
        if (r) {
@@ -6516,6 +6520,7 @@ int si_resume(struct radeon_device *rdev)
 
 int si_suspend(struct radeon_device *rdev)
 {
+       radeon_pm_suspend(rdev);
        dce6_audio_fini(rdev);
        radeon_vm_manager_fini(rdev);
        si_cp_enable(rdev, false);
@@ -6598,6 +6603,9 @@ int si_init(struct radeon_device *rdev)
                }
        }
 
+       /* 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);
@@ -6664,6 +6672,7 @@ int si_init(struct radeon_device *rdev)
 
 void si_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        si_cp_fini(rdev);
        cayman_dma_fini(rdev);
        si_fini_pg(rdev);
index 05cdd8ddabc44629834ada87bd077cd4ec389d6a..512919b0156aa5d5ec141f9f49627393883fe468 100644 (file)
@@ -1738,6 +1738,8 @@ struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev);
 struct ni_ps *ni_get_ps(struct radeon_ps *rps);
 
+extern int si_mc_load_microcode(struct radeon_device *rdev);
+
 static int si_populate_voltage_value(struct radeon_device *rdev,
                                     const struct atom_voltage_table *table,
                                     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
@@ -5751,6 +5753,11 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,
 
 void si_dpm_setup_asic(struct radeon_device *rdev)
 {
+       int r;
+
+       r = si_mc_load_microcode(rdev);
+       if (r)
+               DRM_ERROR("Failed to load MC firmware!\n");
        rv770_get_memory_type(rdev);
        si_read_clock_registers(rdev);
        si_enable_acpi_power_management(rdev);