drm/i915: Track power reference taken for eDP VDD
authorImre Deak <imre.deak@intel.com>
Mon, 30 Nov 2020 21:21:57 +0000 (23:21 +0200)
committerImre Deak <imre.deak@intel.com>
Thu, 3 Dec 2020 13:31:55 +0000 (15:31 +0200)
Add wakeref tracking for the eDP encoders' AUX display power domain
references taken while the panel's VDD is enabled.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-7-imre.deak@intel.com
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dp.c

index fa7d36f1ad97b54b498713b458c3fe5aa39db9bd..1fa0246b3a8243777765533226e6e561882783d0 100644 (file)
@@ -1384,6 +1384,7 @@ struct intel_dp {
        unsigned long last_power_on;
        unsigned long last_backlight_off;
        ktime_t panel_power_off_time;
+       intel_wakeref_t vdd_wakeref;
 
        /*
         * Pipe whose power sequencer is currently locked into
index 21a0ca6ae2a656a9434fd3c99efac01426671a9b..2d4d5e95af84eb55a2ff8039f403d359f1195aa5 100644 (file)
@@ -3094,8 +3094,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
        if (edp_have_panel_vdd(intel_dp))
                return need_to_disable;
 
-       intel_display_power_get(dev_priv,
-                               intel_aux_power_domain(dig_port));
+       drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref);
+       intel_dp->vdd_wakeref = intel_display_power_get(dev_priv,
+                                                       intel_aux_power_domain(dig_port));
 
        drm_dbg_kms(&dev_priv->drm, "Turning [ENCODER:%d:%s] VDD on\n",
                    dig_port->base.base.base.id,
@@ -3188,8 +3189,9 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
        if ((pp & PANEL_POWER_ON) == 0)
                intel_dp->panel_power_off_time = ktime_get_boottime();
 
-       intel_display_power_put_unchecked(dev_priv,
-                                         intel_aux_power_domain(dig_port));
+       intel_display_power_put(dev_priv,
+                               intel_aux_power_domain(dig_port),
+                               fetch_and_zero(&intel_dp->vdd_wakeref));
 }
 
 static void edp_panel_vdd_work(struct work_struct *__work)
@@ -3341,7 +3343,9 @@ static void edp_panel_off(struct intel_dp *intel_dp)
        intel_dp->panel_power_off_time = ktime_get_boottime();
 
        /* We got a reference when we enabled the VDD. */
-       intel_display_power_put_unchecked(dev_priv, intel_aux_power_domain(dig_port));
+       intel_display_power_put(dev_priv,
+                               intel_aux_power_domain(dig_port),
+                               fetch_and_zero(&intel_dp->vdd_wakeref));
 }
 
 void intel_edp_panel_off(struct intel_dp *intel_dp)
@@ -6894,7 +6898,9 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
         */
        drm_dbg_kms(&dev_priv->drm,
                    "VDD left on by BIOS, adjusting state tracking\n");
-       intel_display_power_get(dev_priv, intel_aux_power_domain(dig_port));
+       drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref);
+       intel_dp->vdd_wakeref = intel_display_power_get(dev_priv,
+                                                       intel_aux_power_domain(dig_port));
 
        edp_panel_vdd_schedule_off(intel_dp);
 }