]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/radeon: properly handle crtc powergating
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 26 Jul 2012 17:38:52 +0000 (13:38 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Aug 2012 02:31:40 +0000 (19:31 -0700)
commit 6c0ae2ab85fc4a95cae82047a7db1f688a7737ab upstream.

Need to make sure the crtc is gated on before modesetting.
Explicitly gate the crtc on in prepare() and set a flag
so that the dpms functions don't gate it off during
mode set.

Noticed by sylware on IRC.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_mode.h

index 3904d7964a4b02e3b0e34930f3bc97a65c07add3..7915944db31b2fe179fac754dd779c2924219cc9 100644 (file)
@@ -259,7 +259,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                /* adjust pm to dpms changes BEFORE enabling crtcs */
                radeon_pm_compute_clocks(rdev);
                /* disable crtc pair power gating before programming */
-               if (ASIC_IS_DCE6(rdev))
+               if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
                        atombios_powergate_crtc(crtc, ATOM_DISABLE);
                atombios_enable_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
@@ -279,7 +279,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                atombios_enable_crtc(crtc, ATOM_DISABLE);
                radeon_crtc->enabled = false;
                /* power gating is per-pair */
-               if (ASIC_IS_DCE6(rdev)) {
+               if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) {
                        struct drm_crtc *other_crtc;
                        struct radeon_crtc *other_radeon_crtc;
                        list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
@@ -1639,18 +1639,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
 
+       radeon_crtc->in_mode_set = true;
        /* pick pll */
        radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
 
+       /* disable crtc pair power gating before programming */
+       if (ASIC_IS_DCE6(rdev))
+               atombios_powergate_crtc(crtc, ATOM_DISABLE);
+
        atombios_lock_crtc(crtc, ATOM_ENABLE);
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void atombios_crtc_commit(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
        atombios_lock_crtc(crtc, ATOM_DISABLE);
+       radeon_crtc->in_mode_set = false;
 }
 
 static void atombios_crtc_disable(struct drm_crtc *crtc)
index 210317c7045ef11daf4565f66d471fa04043dbbf..9760e5addcc36234bb0125470f6215dfcdf689af 100644 (file)
@@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
 
 static void radeon_crtc_prepare(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
+       radeon_crtc->in_mode_set = true;
        /*
        * The hardware wedges sometimes if you reconfigure one CRTC
        * whilst another is running (see fdo bug #24611).
@@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc)
 
 static void radeon_crtc_commit(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
@@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc)
                if (crtci->enabled)
                        radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
        }
+       radeon_crtc->in_mode_set = false;
 }
 
 static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
index 5b10ffd7bb2fbae7519010749f9bf2ca67630537..ce32fa9bee4e3c10517181f056f33a4b724be0dc 100644 (file)
@@ -275,6 +275,7 @@ struct radeon_crtc {
        u16 lut_r[256], lut_g[256], lut_b[256];
        bool enabled;
        bool can_tile;
+       bool in_mode_set;
        uint32_t crtc_offset;
        struct drm_gem_object *cursor_bo;
        uint64_t cursor_addr;