diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_pipe_crc.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_pipe_crc.c | 199 |
1 files changed, 101 insertions, 98 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c index a9a5df2fee4d..1f27643412f1 100644 --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c @@ -24,14 +24,21 @@ * */ -#include <linux/circ_buf.h> #include <linux/ctype.h> #include <linux/debugfs.h> #include <linux/seq_file.h> +#include <drm/drm_print.h> + +#include "i915_drv.h" +#include "i915_irq.h" #include "intel_atomic.h" +#include "intel_de.h" +#include "intel_display_irq.h" +#include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_pipe_crc.h" +#include "intel_pipe_crc_regs.h" static const char * const pipe_crc_sources[] = { [INTEL_PIPE_CRC_SOURCE_NONE] = "none", @@ -70,20 +77,18 @@ static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, return 0; } -static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, - enum pipe pipe, - enum intel_pipe_crc_source *source) +static void i9xx_pipe_crc_auto_source(struct intel_display *display, + enum pipe pipe, + enum intel_pipe_crc_source *source) { - struct drm_device *dev = &dev_priv->drm; struct intel_encoder *encoder; struct intel_crtc *crtc; struct intel_digital_port *dig_port; - int ret = 0; *source = INTEL_PIPE_CRC_SOURCE_PIPE; - drm_modeset_lock_all(dev); - for_each_intel_encoder(dev, encoder) { + drm_modeset_lock_all(display->drm); + for_each_intel_encoder(display->drm, encoder) { if (!encoder->base.crtc) continue; @@ -110,7 +115,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, *source = INTEL_PIPE_CRC_SOURCE_DP_D; break; default: - drm_WARN(dev, 1, "nonexisting DP port %c\n", + drm_WARN(display->drm, 1, "nonexisting DP port %c\n", port_name(dig_port->base.port)); break; } @@ -119,23 +124,18 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, break; } } - drm_modeset_unlock_all(dev); - - return ret; + drm_modeset_unlock_all(display->drm); } -static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int vlv_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { bool need_stable_symbols = false; - if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { - int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source); - if (ret) - return ret; - } + if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) + i9xx_pipe_crc_auto_source(display, pipe, source); switch (*source) { case INTEL_PIPE_CRC_SOURCE_PIPE: @@ -150,7 +150,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, need_stable_symbols = true; break; case INTEL_PIPE_CRC_SOURCE_DP_D: - if (!IS_CHERRYVIEW(dev_priv)) + if (!display->platform.cherryview) return -EINVAL; *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV; need_stable_symbols = true; @@ -172,7 +172,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, * - DisplayPort scrambling: used for EMI reduction */ if (need_stable_symbols) { - u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X); + u32 tmp = intel_de_read(display, PORT_DFT2_G4X(display)); tmp |= DC_BALANCE_RESET_VLV; switch (pipe) { @@ -188,29 +188,26 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, default: return -EINVAL; } - intel_de_write(dev_priv, PORT_DFT2_G4X, tmp); + intel_de_write(display, PORT_DFT2_G4X(display), tmp); } return 0; } -static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int i9xx_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { - if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { - int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source); - if (ret) - return ret; - } + if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) + i9xx_pipe_crc_auto_source(display, pipe, source); switch (*source) { case INTEL_PIPE_CRC_SOURCE_PIPE: *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX; break; case INTEL_PIPE_CRC_SOURCE_TV: - if (!SUPPORTS_TV(dev_priv)) + if (!SUPPORTS_TV(display)) return -EINVAL; *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE; break; @@ -234,10 +231,10 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv, +static void vlv_undo_pipe_scramble_reset(struct intel_display *display, enum pipe pipe) { - u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X); + u32 tmp = intel_de_read(display, PORT_DFT2_G4X(display)); switch (pipe) { case PIPE_A: @@ -254,7 +251,7 @@ static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv, } if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) tmp &= ~DC_BALANCE_RESET_VLV; - intel_de_write(dev_priv, PORT_DFT2_G4X, tmp); + intel_de_write(display, PORT_DFT2_G4X(display), tmp); } static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, @@ -286,21 +283,25 @@ static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, static void intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *pipe_config; struct drm_atomic_state *state; struct drm_modeset_acquire_ctx ctx; int ret; + if (display->platform.i945gm || display->platform.i915gm) + i915gm_irq_cstate_wa(display, enable); + drm_modeset_acquire_init(&ctx, 0); - state = drm_atomic_state_alloc(&dev_priv->drm); + state = drm_atomic_state_alloc(display->drm); if (!state) { ret = -ENOMEM; goto unlock; } state->acquire_ctx = &ctx; + to_intel_atomic_state(state)->internal = true; retry: pipe_config = intel_atomic_get_crtc_state(state, crtc); @@ -312,7 +313,7 @@ retry: pipe_config->uapi.mode_changed = pipe_config->has_psr; pipe_config->crc_enabled = enable; - if (IS_HASWELL(dev_priv) && + if (display->platform.haswell && pipe_config->hw.active && crtc->pipe == PIPE_A && pipe_config->cpu_transcoder == TRANSCODER_EDP) pipe_config->uapi.mode_changed = true; @@ -328,13 +329,13 @@ put_state: drm_atomic_state_put(state); unlock: - drm_WARN(&dev_priv->drm, ret, + drm_WARN(display->drm, ret, "Toggling workaround to %i returns %i\n", enable, ret); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); } -static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int ivb_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) @@ -362,7 +363,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int skl_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) @@ -405,22 +406,22 @@ static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int get_new_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { - if (IS_GEN(dev_priv, 2)) + if (DISPLAY_VER(display) == 2) return i8xx_pipe_crc_ctl_reg(source, val); - else if (INTEL_GEN(dev_priv) < 5) - return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val); - else if (IS_GEN_RANGE(dev_priv, 5, 6)) + else if (DISPLAY_VER(display) < 5) + return i9xx_pipe_crc_ctl_reg(display, pipe, source, val); + else if (display->platform.valleyview || display->platform.cherryview) + return vlv_pipe_crc_ctl_reg(display, pipe, source, val); + else if (display->platform.ironlake || display->platform.sandybridge) return ilk_pipe_crc_ctl_reg(source, val); - else if (INTEL_GEN(dev_priv) < 9) - return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val); + else if (DISPLAY_VER(display) < 9) + return ivb_pipe_crc_ctl_reg(display, pipe, source, val); else - return skl_pipe_crc_ctl_reg(dev_priv, pipe, source, val); + return skl_pipe_crc_ctl_reg(display, pipe, source, val); } static int @@ -448,7 +449,7 @@ void intel_crtc_crc_init(struct intel_crtc *crtc) spin_lock_init(&pipe_crc->lock); } -static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv, +static int i8xx_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -460,7 +461,7 @@ static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv, +static int i9xx_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -473,7 +474,7 @@ static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int vlv_crc_source_valid(struct drm_i915_private *dev_priv, +static int vlv_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -488,7 +489,7 @@ static int vlv_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int ilk_crc_source_valid(struct drm_i915_private *dev_priv, +static int ilk_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -502,7 +503,7 @@ static int ilk_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int ivb_crc_source_valid(struct drm_i915_private *dev_priv, +static int ivb_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -516,7 +517,7 @@ static int ivb_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int skl_crc_source_valid(struct drm_i915_private *dev_priv, +static int skl_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -536,21 +537,21 @@ static int skl_crc_source_valid(struct drm_i915_private *dev_priv, } static int -intel_is_valid_crc_source(struct drm_i915_private *dev_priv, +intel_is_valid_crc_source(struct intel_display *display, const enum intel_pipe_crc_source source) { - if (IS_GEN(dev_priv, 2)) - return i8xx_crc_source_valid(dev_priv, source); - else if (INTEL_GEN(dev_priv) < 5) - return i9xx_crc_source_valid(dev_priv, source); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - return vlv_crc_source_valid(dev_priv, source); - else if (IS_GEN_RANGE(dev_priv, 5, 6)) - return ilk_crc_source_valid(dev_priv, source); - else if (INTEL_GEN(dev_priv) < 9) - return ivb_crc_source_valid(dev_priv, source); + if (DISPLAY_VER(display) == 2) + return i8xx_crc_source_valid(display, source); + else if (DISPLAY_VER(display) < 5) + return i9xx_crc_source_valid(display, source); + else if (display->platform.valleyview || display->platform.cherryview) + return vlv_crc_source_valid(display, source); + else if (display->platform.ironlake || display->platform.sandybridge) + return ilk_crc_source_valid(display, source); + else if (DISPLAY_VER(display) < 9) + return ivb_crc_source_valid(display, source); else - return skl_crc_source_valid(dev_priv, source); + return skl_crc_source_valid(display, source); } const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, @@ -563,16 +564,16 @@ const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name, size_t *values_cnt) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum intel_pipe_crc_source source; if (display_crc_ctl_parse_source(source_name, &source) < 0) { - drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name); + drm_dbg_kms(display->drm, "unknown source %s\n", source_name); return -EINVAL; } if (source == INTEL_PIPE_CRC_SOURCE_AUTO || - intel_is_valid_crc_source(dev_priv, source) == 0) { + intel_is_valid_crc_source(display, source) == 0) { *values_cnt = 5; return 0; } @@ -580,91 +581,93 @@ int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name, return -EINVAL; } -int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name) +int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; + struct intel_crtc *crtc = to_intel_crtc(_crtc); + struct intel_display *display = to_intel_display(crtc); + struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; enum intel_display_power_domain power_domain; enum intel_pipe_crc_source source; + enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; u32 val = 0; /* shut up gcc */ int ret = 0; bool enable; if (display_crc_ctl_parse_source(source_name, &source) < 0) { - drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name); + drm_dbg_kms(display->drm, "unknown source %s\n", source_name); return -EINVAL; } - power_domain = POWER_DOMAIN_PIPE(crtc->index); - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); + power_domain = POWER_DOMAIN_PIPE(pipe); + wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Trying to capture CRC while pipe is off\n"); return -EIO; } enable = source != INTEL_PIPE_CRC_SOURCE_NONE; if (enable) - intel_crtc_crc_setup_workarounds(to_intel_crtc(crtc), true); + intel_crtc_crc_setup_workarounds(crtc, true); - ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val); + ret = get_new_crc_ctl_reg(display, pipe, &source, &val); if (ret != 0) goto out; pipe_crc->source = source; - intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), val); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), val); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); if (!source) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - vlv_undo_pipe_scramble_reset(dev_priv, crtc->index); + if (display->platform.valleyview || display->platform.cherryview) + vlv_undo_pipe_scramble_reset(display, pipe); } pipe_crc->skipped = 0; out: if (!enable) - intel_crtc_crc_setup_workarounds(to_intel_crtc(crtc), false); + intel_crtc_crc_setup_workarounds(crtc, false); - intel_display_power_put(dev_priv, power_domain, wakeref); + intel_display_power_put(display, power_domain, wakeref); return ret; } -void intel_crtc_enable_pipe_crc(struct intel_crtc *intel_crtc) +void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc) { - struct drm_crtc *crtc = &intel_crtc->base; - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; + struct intel_display *display = to_intel_display(crtc); + struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; + enum pipe pipe = crtc->pipe; u32 val = 0; - if (!crtc->crc.opened) + if (!crtc->base.crc.opened) return; - if (get_new_crc_ctl_reg(dev_priv, crtc->index, &pipe_crc->source, &val) < 0) + if (get_new_crc_ctl_reg(display, pipe, &pipe_crc->source, &val) < 0) return; /* Don't need pipe_crc->lock here, IRQs are not generated. */ pipe_crc->skipped = 0; - intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), val); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), val); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); } -void intel_crtc_disable_pipe_crc(struct intel_crtc *intel_crtc) +void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc) { - struct drm_crtc *crtc = &intel_crtc->base; - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; + struct intel_display *display = to_intel_display(crtc); + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; + enum pipe pipe = crtc->pipe; /* Swallow crc's until we stop generating them. */ spin_lock_irq(&pipe_crc->lock); pipe_crc->skipped = INT_MIN; spin_unlock_irq(&pipe_crc->lock); - intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), 0); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), 0); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); intel_synchronize_irq(dev_priv); } |
