We need to organize ips a bit in order to fix it initialization So let's start by following other features by moving all relted functions to its own file. Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/intel_display.c | 127 ++--------------------------- drivers/gpu/drm/i915/intel_dp.c | 6 +- drivers/gpu/drm/i915/intel_drv.h | 8 +- drivers/gpu/drm/i915/intel_ips.c | 151 +++++++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 127 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ips.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 0851de07..7c1a86e 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -60,6 +60,7 @@ i915-y += intel_audio.o \ intel_fifo_underrun.o \ intel_frontbuffer.o \ intel_hotplug.o \ + intel_ips.o \ intel_modes.o \ intel_overlay.o \ intel_psr.o \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5659d4c..391861d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4034,7 +4034,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, * user space can't make reliable use of the CRCs, so let's just * completely disable it. */ - hsw_disable_ips(crtc); + intel_ips_disable(crtc); spin_lock_irq(&pipe_crc->lock); kfree(pipe_crc->entries); @@ -4079,7 +4079,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, else if (IS_HASWELL(dev) && pipe == PIPE_A) hsw_trans_edp_pipe_A_crc_wa(dev, false); - hsw_enable_ips(crtc); + intel_ips_disable(crtc); } return 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 01da1c9..197c608 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1366,22 +1366,6 @@ void assert_pipe(struct drm_i915_private *dev_priv, pipe_name(pipe), state_string(state), state_string(cur_state)); } -static void assert_plane(struct drm_i915_private *dev_priv, - enum plane plane, bool state) -{ - u32 val; - bool cur_state; - - val = I915_READ(DSPCNTR(plane)); - cur_state = !!(val & DISPLAY_PLANE_ENABLE); - I915_STATE_WARN(cur_state != state, - "plane %c assertion failure (expected %s, current %s)\n", - plane_name(plane), state_string(state), state_string(cur_state)); -} - -#define assert_plane_enabled(d, p) assert_plane(d, p, true) -#define assert_plane_disabled(d, p) assert_plane(d, p, false) - static void assert_planes_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -4529,64 +4513,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) } } -void hsw_enable_ips(struct intel_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!crtc->config->ips_ready) - return; - - /* We can only enable IPS after we enable a plane and wait for a vblank */ - intel_wait_for_vblank(dev, crtc->pipe); - - assert_plane_enabled(dev_priv, crtc->plane); - if (IS_BROADWELL(dev)) { - mutex_lock(&dev_priv->rps.hw_lock); - WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000)); - mutex_unlock(&dev_priv->rps.hw_lock); - /* Quoting Art Runyan: "its not safe to expect any particular - * value in IPS_CTL bit 31 after enabling IPS through the - * mailbox." Moreover, the mailbox may return a bogus state, - * so we need to just enable it and continue on. - */ - } else { - I915_WRITE(IPS_CTL, IPS_ENABLE); - /* The bit only becomes 1 in the next vblank, so this wait here - * is essentially intel_wait_for_vblank. If we don't have this - * and don't wait for vblanks until the end of crtc_enable, then - * the HW state readout code will complain that the expected - * IPS_CTL value is not the one we read. */ - if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) - DRM_ERROR("Timed out waiting for IPS enable\n"); - } -} - -void hsw_disable_ips(struct intel_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!crtc->config->ips_ready) - return; - - assert_plane_enabled(dev_priv, crtc->plane); - if (IS_BROADWELL(dev)) { - mutex_lock(&dev_priv->rps.hw_lock); - WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); - mutex_unlock(&dev_priv->rps.hw_lock); - /* wait for pcode to finish disabling IPS, which may take up to 42ms */ - if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42)) - DRM_ERROR("Timed out waiting for IPS disable\n"); - } else { - I915_WRITE(IPS_CTL, 0); - POSTING_READ(IPS_CTL); - } - - /* We need to wait for a vblank before we can disable the plane. */ - intel_wait_for_vblank(dev, crtc->pipe); -} - /** Loads the palette/gamma unit for the CRTC with the prepared values */ static void intel_crtc_load_lut(struct drm_crtc *crtc) { @@ -4615,7 +4541,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) if (IS_HASWELL(dev) && intel_crtc->config->ips_ready && ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) == GAMMA_MODE_MODE_SPLIT)) { - hsw_disable_ips(intel_crtc); + intel_ips_disable(intel_crtc); reenable_ips = true; } @@ -4634,7 +4560,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) } if (reenable_ips) - hsw_enable_ips(intel_crtc); + intel_ips_enable(intel_crtc); } static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) @@ -4687,7 +4613,7 @@ intel_post_enable_primary(struct drm_crtc *crtc) * when going from primary only to sprite only and vice * versa. */ - hsw_enable_ips(intel_crtc); + intel_ips_enable(intel_crtc); /* * Gen2 reports pipe underruns whenever all planes are disabled. @@ -4752,7 +4678,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc) * when going from primary only to sprite only and vice * versa. */ - hsw_disable_ips(intel_crtc); + intel_ips_disable(intel_crtc); } static void intel_post_plane_update(struct intel_crtc *crtc) @@ -4791,7 +4717,7 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) intel_fbc_disable_crtc(crtc); if (crtc->atomic.disable_ips) - hsw_disable_ips(crtc); + intel_ips_disable(crtc); if (atomic->pre_disable_primary) intel_pre_disable_primary(&crtc->base); @@ -4891,12 +4817,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) cpt_verify_modeset(dev, intel_crtc->pipe); } -/* IPS only exists on ULT machines and is tied to pipe A. */ -static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) -{ - return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A; -} - static void haswell_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -6532,38 +6452,6 @@ retry: return ret; } -static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv, - struct intel_crtc_state *pipe_config) -{ - if (pipe_config->pipe_bpp > 24) - return false; - - /* HSW can handle pixel rate up to cdclk? */ - if (IS_HASWELL(dev_priv->dev)) - return true; - - /* - * We compare against max which means we must take - * the increased cdclk requirement into account when - * calculating the new cdclk. - * - * Should measure whether using a lower cdclk w/o IPS - */ - return ilk_pipe_pixel_rate(pipe_config) <= - dev_priv->max_cdclk_freq * 95 / 100; -} - -static void hsw_compute_ips_config(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - pipe_config->ips_ready = i915.enable_ips && - hsw_crtc_supports_ips(crtc) && - pipe_config_supports_ips(dev_priv, pipe_config); -} - static int intel_crtc_compute_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -6609,8 +6497,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay) return -EINVAL; - if (HAS_IPS(dev)) - hsw_compute_ips_config(crtc, pipe_config); + pipe_config->ips_ready = intel_ips_ready(crtc, pipe_config); if (pipe_config->has_pch_encoder) return ironlake_fdi_compute_config(crtc, pipe_config); @@ -9831,7 +9718,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, ironlake_get_pfit_config(crtc, pipe_config); } - pipe_config->ips_ready = hsw_crtc_supports_ips(crtc); + pipe_config->ips_ready = intel_ips_ready(crtc, pipe_config); if (pipe_config->cpu_transcoder != TRANSCODER_EDP) { pipe_config->pixel_multiplier = diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5264887..273e1ad 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3823,7 +3823,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) intel_dp->sink_crc.started = false; out: - hsw_enable_ips(intel_crtc); + intel_ips_enable(intel_crtc); return ret; } @@ -3851,11 +3851,11 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) return -EIO; - hsw_disable_ips(intel_crtc); + intel_ips_disable(intel_crtc); if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, buf | DP_TEST_SINK_START) < 0) { - hsw_enable_ips(intel_crtc); + intel_ips_enable(intel_crtc); return -EIO; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2aae219..41a88f7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1188,8 +1188,6 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock); bool intel_crtc_active(struct drm_crtc *crtc); -void hsw_enable_ips(struct intel_crtc *crtc); -void hsw_disable_ips(struct intel_crtc *crtc); enum intel_display_power_domain intel_display_port_power_domain(struct intel_encoder *intel_encoder); void intel_mode_from_pipe_config(struct drm_display_mode *mode, @@ -1207,6 +1205,12 @@ u32 skl_plane_ctl_format(uint32_t pixel_format); u32 skl_plane_ctl_tiling(uint64_t fb_modifier); u32 skl_plane_ctl_rotation(unsigned int rotation); +/* intel_ips.c */ +bool intel_ips_ready(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state); +void intel_ips_enable(struct intel_crtc *crtc); +void intel_ips_disable(struct intel_crtc *crtc); + /* intel_csr.c */ void intel_csr_ucode_init(struct drm_device *dev); enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_ips.c b/drivers/gpu/drm/i915/intel_ips.c new file mode 100644 index 0000000..5c659a3 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ips.c @@ -0,0 +1,151 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* IPS only exists on ULT machines and is tied to pipe A. */ + +#include "intel_drv.h" +#include "i915_drv.h" + + +static void assert_plane(struct drm_i915_private *dev_priv, + enum plane plane, bool state) +{ + u32 val; + bool cur_state; + + val = I915_READ(DSPCNTR(plane)); + cur_state = !!(val & DISPLAY_PLANE_ENABLE); + I915_STATE_WARN(cur_state != state, + "plane %c assertion failure (expected %s, current %s)\n", + plane_name(plane), state ? "on" : "off", + cur_state ? "on" : "off"); +} + +#define assert_plane_enabled(d, p) assert_plane(d, p, true) +#define assert_plane_disabled(d, p) assert_plane(d, p, false) + +static bool intel_ips_supported(struct intel_crtc *crtc) +{ + return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A; +} + +static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv, + struct intel_crtc_state *pipe_config) +{ + if (pipe_config->pipe_bpp > 24) + return false; + + /* HSW can handle pixel rate up to cdclk? */ + if (IS_HASWELL(dev_priv->dev)) + return true; + + /* + * We compare against max which means we must take + * the increased cdclk requirement into account when + * calculating the new cdclk. + * + * Should measure whether using a lower cdclk w/o IPS + */ + return ilk_pipe_pixel_rate(pipe_config) <= + dev_priv->max_cdclk_freq * 95 / 100; +} + +bool intel_ips_ready(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + return HAS_IPS(dev) && i915.enable_ips && + intel_ips_supported(crtc) && + pipe_config_supports_ips(dev_priv, pipe_config); +} + +void intel_ips_enable(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!crtc->config->ips_ready) + return; + + /* + * We can only enable IPS after we enable a plane + * and wait for a vblank. + */ + intel_wait_for_vblank(dev, crtc->pipe); + + assert_plane_enabled(dev_priv, crtc->plane); + if (IS_BROADWELL(dev)) { + mutex_lock(&dev_priv->rps.hw_lock); + WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, + 0xc0000000)); + mutex_unlock(&dev_priv->rps.hw_lock); + /* + * Quoting Art Runyan: "its not safe to expect any particular + * value in IPS_CTL bit 31 after enabling IPS through the + * mailbox." Moreover, the mailbox may return a bogus state, + * so we need to just enable it and continue on. + */ + } else { + I915_WRITE(IPS_CTL, IPS_ENABLE); + /* + * The bit only becomes 1 in the next vblank, so this wait here + * is essentially intel_wait_for_vblank. If we don't have this + * and don't wait for vblanks until the end of crtc_enable, then + * the HW state readout code will complain that the expected + * IPS_CTL value is not the one we read. + */ + if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) + DRM_ERROR("Timed out waiting for IPS enable\n"); + } +} + +void intel_ips_disable(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!crtc->config->ips_ready) + return; + + assert_plane_enabled(dev_priv, crtc->plane); + if (IS_BROADWELL(dev)) { + mutex_lock(&dev_priv->rps.hw_lock); + WARN_ON(sandybridge_pcode_write(dev_priv, + DISPLAY_IPS_CONTROL, 0)); + mutex_unlock(&dev_priv->rps.hw_lock); + /* + * Wait for pcode to finish disabling IPS, + * which may take up to 42ms. + */ + if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42)) + DRM_ERROR("Timed out waiting for IPS disable\n"); + } else { + I915_WRITE(IPS_CTL, 0); + POSTING_READ(IPS_CTL); + } + + /* We need to wait for a vblank before we can disable the plane. */ + intel_wait_for_vblank(dev, crtc->pipe); +} -- 2.4.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx