From: Paulo Zanoni <paulo.r.zanoni at intel.com> This should replace intel_using_power_well. The idea is that we're adding the requested power domain as an argument, so this might enable the code to look less platform-specific and also allows us to easily add new domains in case we need. v2: Add more domains to enum intel_display_power_domain Requested-by: Daniel Vetter <daniel.vetter at ffwll.ch> Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com> --- drivers/gpu/drm/i915/i915_drv.h | 14 ++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 16 +++++++++++----- drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_pm.c | 27 ++++++++++++++++++++++----- 4 files changed, 49 insertions(+), 11 deletions(-) I hope this reflects the discussions both via email and IRC. diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bd2d7f1..c79622a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -88,6 +88,20 @@ enum port { }; #define port_name(p) ((p) + 'A') +enum intel_display_power_domain { + POWER_DOMAIN_PIPE_A_PANEL_FITTER, + POWER_DOMAIN_PIPE_A, + POWER_DOMAIN_PIPE_B, + POWER_DOMAIN_PIPE_C, + POWER_DOMAIN_TRANSCODER_A, + POWER_DOMAIN_TRANSCODER_B, + POWER_DOMAIN_TRANSCODER_C, + POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF, +}; + +#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) +#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A) + enum hpd_pin { HPD_NONE = 0, HPD_PORT_A = HPD_NONE, /* PORT_A is internal */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3c90605..bf80942 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1215,8 +1215,8 @@ void assert_pipe(struct drm_i915_private *dev_priv, if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) state = true; - if (!intel_using_power_well(dev_priv->dev) && - cpu_transcoder != TRANSCODER_EDP) { + if (!intel_display_power_enabled(dev_priv->dev, + POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { cur_state = false; } else { reg = PIPECONF(cpu_transcoder); @@ -3597,6 +3597,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + enum intel_display_power_domain domain; if (!intel_crtc->active) return; @@ -3622,7 +3623,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) /* XXX: Once we have proper panel fitter state tracking implemented with * hardware state read/check support we should switch to only disable * the panel fitter when we know it's used. */ - if (intel_using_power_well(dev)) { + if (pipe == PIPE_A) + domain = POWER_DOMAIN_PIPE_A_PANEL_FITTER; + else + domain = POWER_DOMAIN_PIPE(pipe); + + if (intel_display_power_enabled(dev, domain)) { I915_WRITE(PF_CTL(pipe), 0); I915_WRITE(PF_WIN_SZ(pipe), 0); } @@ -5981,8 +5987,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; uint32_t tmp; - if (!intel_using_power_well(dev_priv->dev) && - cpu_transcoder != TRANSCODER_EDP) + if (!intel_display_power_enabled(dev, + POWER_DOMAIN_TRANSCODER(cpu_transcoder))) return false; tmp = I915_READ(PIPECONF(cpu_transcoder)); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c20201d..d82cef8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -721,7 +721,8 @@ extern void intel_update_fbc(struct drm_device *dev); extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); extern void intel_gpu_ips_teardown(void); -extern bool intel_using_power_well(struct drm_device *dev); +extern bool intel_display_power_enabled(struct drm_device *dev, + enum intel_display_power_domain domain); extern void intel_init_power_well(struct drm_device *dev); extern void intel_set_power_well(struct drm_device *dev, bool enable); extern void intel_enable_gt_powersave(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2557926..4e20ba7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4287,15 +4287,32 @@ void intel_init_clock_gating(struct drm_device *dev) * enable it, so check if it's enabled and also check if we've requested it to * be enabled. */ -bool intel_using_power_well(struct drm_device *dev) +bool intel_display_power_enabled(struct drm_device *dev, + enum intel_display_power_domain domain) { struct drm_i915_private *dev_priv = dev->dev_private; + bool power_well_enabled; - if (IS_HASWELL(dev)) - return I915_READ(HSW_PWR_WELL_DRIVER) == - (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE); - else + if (!HAS_POWER_WELL(dev)) + return true; + + power_well_enabled = I915_READ(HSW_PWR_WELL_DRIVER) == + (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE); + + switch (domain) { + case POWER_DOMAIN_PIPE_A: + case POWER_DOMAIN_TRANSCODER_EDP: return true; + case POWER_DOMAIN_PIPE_A_PANEL_FITTER: + case POWER_DOMAIN_PIPE_B: + case POWER_DOMAIN_PIPE_C: + case POWER_DOMAIN_TRANSCODER_A: + case POWER_DOMAIN_TRANSCODER_B: + case POWER_DOMAIN_TRANSCODER_C: + return power_well_enabled; + default: + BUG(); + } } void intel_set_power_well(struct drm_device *dev, bool enable) -- 1.7.10.4