diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-10-21 14:32:55 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-10-21 14:42:30 +0200 |
commit | a8cbd4597799ade2b8a656dac7768c352b58e43a (patch) | |
tree | e40a5ccc9fc808735f3426f5387e54e291ad4351 /drivers | |
parent | b727735732d5b2fde0a88911210215e03e190d11 (diff) | |
parent | 07c338ce98263a5af631b991dd8f96cff6ca2548 (diff) | |
download | linux-stable-a8cbd4597799ade2b8a656dac7768c352b58e43a.tar.gz linux-stable-a8cbd4597799ade2b8a656dac7768c352b58e43a.tar.bz2 linux-stable-a8cbd4597799ade2b8a656dac7768c352b58e43a.zip |
Merge branch 'drm-intel-next-fixes' into drm-intel-next
So I've sent the first pull request to Dave and I expect his request
for a merge tree any second now ;-)
More seriously I have some pending patches for 3.19 that depend upon
both trees, hence backmerge. Conflicts are all trivial.
Conflicts:
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_display.c
v2: Of course I've forgotten the fixup script for the silent conflict.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_userptr.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 243 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 15 |
9 files changed, 118 insertions, 300 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 821ba26438fb..9962da202456 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -968,23 +968,6 @@ struct intel_rps_ei { u32 media_c0; }; -struct intel_rps_bdw_cal { - u32 it_threshold_pct; /* interrupt, in percentage */ - u32 eval_interval; /* evaluation interval, in us */ - u32 last_ts; - u32 last_c0; - bool is_up; -}; - -struct intel_rps_bdw_turbo { - struct intel_rps_bdw_cal up; - struct intel_rps_bdw_cal down; - struct timer_list flip_timer; - u32 timeout; - atomic_t flip_received; - struct work_struct work_max_freq; -}; - struct intel_gen6_power_mgmt { /* work and pm_iir are protected by dev_priv->irq_lock */ struct work_struct work; @@ -1018,9 +1001,6 @@ struct intel_gen6_power_mgmt { bool enabled; struct delayed_work delayed_resume_work; - bool is_bdw_sw_turbo; /* Switch of BDW software turbo */ - struct intel_rps_bdw_turbo sw_turbo; /* Calculate RP interrupt timing */ - /* manual wa residency calculations */ struct intel_rps_ei up_ei, down_ei; @@ -2857,8 +2837,6 @@ extern void intel_disable_fbc(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_init_pch_refclk(struct drm_device *dev); extern void gen6_set_rps(struct drm_device *dev, u8 val); -extern void bdw_software_turbo(struct drm_device *dev); -extern void gen8_flip_interrupt(struct drm_device *dev); extern void valleyview_set_rps(struct drm_device *dev, u8 val); extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index d38413997379..d182058383a9 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -293,15 +293,23 @@ i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) static struct i915_mmu_notifier * i915_mmu_notifier_find(struct i915_mm_struct *mm) { - if (mm->mn == NULL) { - down_write(&mm->mm->mmap_sem); - mutex_lock(&to_i915(mm->dev)->mm_lock); - if (mm->mn == NULL) - mm->mn = i915_mmu_notifier_create(mm->mm); - mutex_unlock(&to_i915(mm->dev)->mm_lock); - up_write(&mm->mm->mmap_sem); + struct i915_mmu_notifier *mn = mm->mn; + + mn = mm->mn; + if (mn) + return mn; + + down_write(&mm->mm->mmap_sem); + mutex_lock(&to_i915(mm->dev)->mm_lock); + if ((mn = mm->mn) == NULL) { + mn = i915_mmu_notifier_create(mm->mm); + if (!IS_ERR(mn)) + mm->mn = mn; } - return mm->mn; + mutex_unlock(&to_i915(mm->dev)->mm_lock); + up_write(&mm->mm->mmap_sem); + + return mn; } static int @@ -681,16 +689,15 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) static void i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) { - struct scatterlist *sg; - int i; + struct sg_page_iter sg_iter; BUG_ON(obj->userptr.work != NULL); if (obj->madv != I915_MADV_WILLNEED) obj->dirty = 0; - for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) { - struct page *page = sg_page(sg); + for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { + struct page *page = sg_page_iter_page(&sg_iter); if (obj->dirty) set_page_dirty(page); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 737b23982b95..f17bbf3ac136 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1716,7 +1716,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, #define HPD_STORM_DETECT_PERIOD 1000 #define HPD_STORM_THRESHOLD 5 -static int ilk_port_to_hotplug_shift(enum port port) +static int pch_port_to_hotplug_shift(enum port port) { switch (port) { case PORT_A: @@ -1732,7 +1732,7 @@ static int ilk_port_to_hotplug_shift(enum port port) } } -static int g4x_port_to_hotplug_shift(enum port port) +static int i915_port_to_hotplug_shift(enum port port) { switch (port) { case PORT_A: @@ -1790,12 +1790,12 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, if (port && dev_priv->hpd_irq_port[port]) { bool long_hpd; - if (IS_G4X(dev)) { - dig_shift = g4x_port_to_hotplug_shift(port); - long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; - } else { - dig_shift = ilk_port_to_hotplug_shift(port); + if (HAS_PCH_SPLIT(dev)) { + dig_shift = pch_port_to_hotplug_shift(port); long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; + } else { + dig_shift = i915_port_to_hotplug_shift(port); + long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; } DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", @@ -1984,27 +1984,6 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) res1, res2); } -void gen8_flip_interrupt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!dev_priv->rps.is_bdw_sw_turbo) - return; - - if(atomic_read(&dev_priv->rps.sw_turbo.flip_received)) { - mod_timer(&dev_priv->rps.sw_turbo.flip_timer, - usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies); - } - else { - dev_priv->rps.sw_turbo.flip_timer.expires = - usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies; - add_timer(&dev_priv->rps.sw_turbo.flip_timer); - atomic_set(&dev_priv->rps.sw_turbo.flip_received, true); - } - - bdw_software_turbo(dev); -} - /* The RPS events need forcewake, so we add them to a work queue and mask their * IMR bits until the work is done. Other interrupts can be processed without * the work queue. */ @@ -3494,11 +3473,13 @@ static void gen8_irq_reset(struct drm_device *dev) void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) { + uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; + spin_lock_irq(&dev_priv->irq_lock); GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], - ~dev_priv->de_irq_mask[PIPE_B]); + ~dev_priv->de_irq_mask[PIPE_B] | extra_ier); GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], - ~dev_priv->de_irq_mask[PIPE_C]); + ~dev_priv->de_irq_mask[PIPE_C] | extra_ier); spin_unlock_irq(&dev_priv->irq_lock); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2ed02c391f3b..a56d9a7e7e0e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2474,6 +2474,7 @@ enum punit_power_well { #define _PIPEASRC 0x6001c #define _BCLRPAT_A 0x60020 #define _VSYNCSHIFT_A 0x60028 +#define _PIPE_MULT_A 0x6002c /* Pipe B timing regs */ #define _HTOTAL_B 0x61000 @@ -2485,6 +2486,7 @@ enum punit_power_well { #define _PIPEBSRC 0x6101c #define _BCLRPAT_B 0x61020 #define _VSYNCSHIFT_B 0x61028 +#define _PIPE_MULT_B 0x6102c #define TRANSCODER_A_OFFSET 0x60000 #define TRANSCODER_B_OFFSET 0x61000 @@ -2505,6 +2507,7 @@ enum punit_power_well { #define BCLRPAT(trans) _TRANSCODER2(trans, _BCLRPAT_A) #define VSYNCSHIFT(trans) _TRANSCODER2(trans, _VSYNCSHIFT_A) #define PIPESRC(trans) _TRANSCODER2(trans, _PIPEASRC) +#define PIPE_MULT(trans) _TRANSCODER2(trans, _PIPE_MULT_A) /* HSW+ eDP PSR registers */ #define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800) @@ -5766,10 +5769,6 @@ enum punit_power_well { #define GEN8_UCGCTL6 0x9430 #define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14) -#define TIMESTAMP_CTR 0x44070 -#define FREQ_1_28_US(us) (((us) * 100) >> 7) -#define MCHBAR_PCU_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5960) - #define GEN6_GFXPAUSE 0xA000 #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6fc77a100cc6..1fc05ffc4695 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -73,9 +73,6 @@ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB8888, }; -#define DIV_ROUND_CLOSEST_ULL(ll, d) \ -({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) - static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); static void i9xx_crtc_clock_get(struct intel_crtc *crtc, @@ -4265,6 +4262,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_set_pipe_timings(intel_crtc); + if (intel_crtc->config.cpu_transcoder != TRANSCODER_EDP) { + I915_WRITE(PIPE_MULT(intel_crtc->config.cpu_transcoder), + intel_crtc->config.pixel_multiplier - 1); + } + if (intel_crtc->config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, &intel_crtc->config.fdi_m_n, NULL); @@ -7937,7 +7939,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && (I915_READ(IPS_CTL) & IPS_ENABLE); - pipe_config->pixel_multiplier = 1; + if (pipe_config->cpu_transcoder != TRANSCODER_EDP) { + pipe_config->pixel_multiplier = + I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1; + } else { + pipe_config->pixel_multiplier = 1; + } return true; } @@ -9773,9 +9780,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct intel_engine_cs *ring; int ret; - //trigger software GT busyness calculation - gen8_flip_interrupt(dev); - /* * drm_mode_page_flip_ioctl() should already catch this, but double * check to be safe. In the future we may enable pageflipping from @@ -12223,27 +12227,36 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(PCH_DP_D) & DP_DETECTED) intel_dp_init(dev, PCH_DP_D, PORT_D); } else if (IS_VALLEYVIEW(dev)) { - if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) { + /* + * The DP_DETECTED bit is the latched state of the DDC + * SDA pin at boot. However since eDP doesn't require DDC + * (no way to plug in a DP->HDMI dongle) the DDC pins for + * eDP ports may have been muxed to an alternate function. + * Thus we can't rely on the DP_DETECTED bit alone to detect + * eDP ports. Consult the VBT as well as DP_DETECTED to + * detect eDP ports. + */ + if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, PORT_B); - if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED) - intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); - } + if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED || + intel_dp_is_edp(dev, PORT_B)) + intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); - if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) { + if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, PORT_C); - if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) - intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); - } + if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED || + intel_dp_is_edp(dev, PORT_C)) + intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); if (IS_CHERRYVIEW(dev)) { - if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) { + if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, PORT_D); - if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) - intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); - } + /* eDP not supported on port D, so don't check VBT */ + if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) + intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); } intel_dsi_init(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ffbf38d9b536..94993d23e547 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -36,6 +36,9 @@ #include <drm/drm_dp_mst_helper.h> #include <drm/drm_rect.h> +#define DIV_ROUND_CLOSEST_ULL(ll, d) \ +({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) + /** * _wait_for - magic (register) wait macro * diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 543e0f17ee62..e3def5ad4a77 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -419,9 +419,8 @@ static uint32_t scale(uint32_t source_val, source_val = clamp(source_val, source_min, source_max); /* avoid overflows */ - target_val = (uint64_t)(source_val - source_min) * - (target_max - target_min); - do_div(target_val, source_max - source_min); + target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) * + (target_max - target_min), source_max - source_min); target_val += target_min; return target_val; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 79108059b79b..a14be5d56c6b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2320,6 +2320,7 @@ int ilk_wm_max_level(const struct drm_device *dev) else return 2; } + static void intel_print_wm_latency(struct drm_device *dev, const char *name, const uint16_t wm[5]) @@ -3288,9 +3289,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) { int new_power; - if (dev_priv->rps.is_bdw_sw_turbo) - return; - new_power = dev_priv->rps.power; switch (dev_priv->rps.power) { case LOW_POWER: @@ -3498,11 +3496,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); else if (IS_VALLEYVIEW(dev)) vlv_set_rps_idle(dev_priv); - else if (!dev_priv->rps.is_bdw_sw_turbo - || atomic_read(&dev_priv->rps.sw_turbo.flip_received)){ + else gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); - } - dev_priv->rps.last_adj = 0; } mutex_unlock(&dev_priv->rps.hw_lock); @@ -3516,11 +3511,8 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv) if (dev_priv->rps.enabled) { if (IS_VALLEYVIEW(dev)) valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); - else if (!dev_priv->rps.is_bdw_sw_turbo - || atomic_read(&dev_priv->rps.sw_turbo.flip_received)){ + else gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); - } - dev_priv->rps.last_adj = 0; } mutex_unlock(&dev_priv->rps.hw_lock); @@ -3534,17 +3526,18 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) WARN_ON(val > dev_priv->rps.max_freq_softlimit); WARN_ON(val < dev_priv->rps.min_freq_softlimit); - DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", - vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), - dev_priv->rps.cur_freq, - vlv_gpu_freq(dev_priv, val), val); - if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), "Odd GPU freq value\n")) val &= ~1; - if (val != dev_priv->rps.cur_freq) + if (val != dev_priv->rps.cur_freq) { + DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", + vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), + dev_priv->rps.cur_freq, + vlv_gpu_freq(dev_priv, val), val); + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + } I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); @@ -3555,26 +3548,21 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) static void gen8_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_BROADWELL(dev) && dev_priv->rps.is_bdw_sw_turbo){ - if (atomic_read(&dev_priv->rps.sw_turbo.flip_received)) - del_timer(&dev_priv->rps.sw_turbo.flip_timer); - dev_priv-> rps.is_bdw_sw_turbo = false; - } else { - I915_WRITE(GEN6_PMINTRMSK, ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); - I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) & - ~dev_priv->pm_rps_events); - /* Complete PM interrupt masking here doesn't race with the rps work - * item again unmasking PM interrupts because that is using a different - * register (GEN8_GT_IMR(2)) to mask PM interrupts. The only risk is in - * leaving stale bits in GEN8_GT_IIR(2) and GEN8_GT_IMR(2) which - * gen8_enable_rps will clean up. */ - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->rps.pm_iir = 0; - spin_unlock_irq(&dev_priv->irq_lock); + I915_WRITE(GEN6_PMINTRMSK, ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); + I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) & + ~dev_priv->pm_rps_events); + /* Complete PM interrupt masking here doesn't race with the rps work + * item again unmasking PM interrupts because that is using a different + * register (GEN8_GT_IMR(2)) to mask PM interrupts. The only risk is in + * leaving stale bits in GEN8_GT_IIR(2) and GEN8_GT_IMR(2) which + * gen8_enable_rps will clean up. */ - I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); - } + spin_lock_irq(&dev_priv->irq_lock); + dev_priv->rps.pm_iir = 0; + spin_unlock_irq(&dev_priv->irq_lock); + + I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); } static void gen6_disable_rps_interrupts(struct drm_device *dev) @@ -3732,111 +3720,13 @@ static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_c dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; } -static void bdw_sw_calculate_freq(struct drm_device *dev, - struct intel_rps_bdw_cal *c, u32 *cur_time, u32 *c0) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u64 busy = 0; - u32 busyness_pct = 0; - u32 elapsed_time = 0; - u16 new_freq = 0; - - if (!c || !cur_time || !c0) - return; - - if (0 == c->last_c0) - goto out; - - /* Check Evaluation interval */ - elapsed_time = *cur_time - c->last_ts; - if (elapsed_time < c->eval_interval) - return; - - mutex_lock(&dev_priv->rps.hw_lock); - - /* - * c0 unit in 32*1.28 usec, elapsed_time unit in 1 usec. - * Whole busyness_pct calculation should be - * busy = ((u64)(*c0 - c->last_c0) << 5 << 7) / 100; - * busyness_pct = (u32)(busy * 100 / elapsed_time); - * The final formula is to simplify CPU calculation - */ - busy = (u64)(*c0 - c->last_c0) << 12; - do_div(busy, elapsed_time); - busyness_pct = (u32)busy; - - if (c->is_up && busyness_pct >= c->it_threshold_pct) - new_freq = (u16)dev_priv->rps.cur_freq + 3; - if (!c->is_up && busyness_pct <= c->it_threshold_pct) - new_freq = (u16)dev_priv->rps.cur_freq - 1; - - /* Adjust to new frequency busyness and compare with threshold */ - if (0 != new_freq) { - if (new_freq > dev_priv->rps.max_freq_softlimit) - new_freq = dev_priv->rps.max_freq_softlimit; - else if (new_freq < dev_priv->rps.min_freq_softlimit) - new_freq = dev_priv->rps.min_freq_softlimit; - - gen6_set_rps(dev, new_freq); - } - - mutex_unlock(&dev_priv->rps.hw_lock); - -out: - c->last_c0 = *c0; - c->last_ts = *cur_time; -} - -static void gen8_set_frequency_RP0(struct work_struct *work) -{ - struct intel_rps_bdw_turbo *p_bdw_turbo = - container_of(work, struct intel_rps_bdw_turbo, work_max_freq); - struct intel_gen6_power_mgmt *p_power_mgmt = - container_of(p_bdw_turbo, struct intel_gen6_power_mgmt, sw_turbo); - struct drm_i915_private *dev_priv = - container_of(p_power_mgmt, struct drm_i915_private, rps); - - mutex_lock(&dev_priv->rps.hw_lock); - gen6_set_rps(dev_priv->dev, dev_priv->rps.rp0_freq); - mutex_unlock(&dev_priv->rps.hw_lock); -} - -static void flip_active_timeout_handler(unsigned long var) -{ - struct drm_i915_private *dev_priv = (struct drm_i915_private *) var; - - del_timer(&dev_priv->rps.sw_turbo.flip_timer); - atomic_set(&dev_priv->rps.sw_turbo.flip_received, false); - - queue_work(dev_priv->wq, &dev_priv->rps.sw_turbo.work_max_freq); -} - -void bdw_software_turbo(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - u32 current_time = I915_READ(TIMESTAMP_CTR); /* unit in usec */ - u32 current_c0 = I915_READ(MCHBAR_PCU_C0); /* unit in 32*1.28 usec */ - - bdw_sw_calculate_freq(dev, &dev_priv->rps.sw_turbo.up, - ¤t_time, ¤t_c0); - bdw_sw_calculate_freq(dev, &dev_priv->rps.sw_turbo.down, - ¤t_time, ¤t_c0); -} - static void gen8_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; uint32_t rc6_mask = 0, rp_state_cap; - uint32_t threshold_up_pct, threshold_down_pct; - uint32_t ei_up, ei_down; /* up and down evaluation interval */ - u32 rp_ctl_flag; int unused; - /* Use software Turbo for BDW */ - dev_priv->rps.is_bdw_sw_turbo = IS_BROADWELL(dev); - /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); @@ -3880,74 +3770,35 @@ static void gen8_enable_rps(struct drm_device *dev) HSW_FREQUENCY(dev_priv->rps.rp1_freq)); I915_WRITE(GEN6_RC_VIDEO_FREQ, HSW_FREQUENCY(dev_priv->rps.rp1_freq)); - ei_up = 84480; /* 84.48ms */ - ei_down = 448000; - threshold_up_pct = 90; /* x percent busy */ - threshold_down_pct = 70; - - if (dev_priv->rps.is_bdw_sw_turbo) { - dev_priv->rps.sw_turbo.up.it_threshold_pct = threshold_up_pct; - dev_priv->rps.sw_turbo.up.eval_interval = ei_up; - dev_priv->rps.sw_turbo.up.is_up = true; - dev_priv->rps.sw_turbo.up.last_ts = 0; - dev_priv->rps.sw_turbo.up.last_c0 = 0; - - dev_priv->rps.sw_turbo.down.it_threshold_pct = threshold_down_pct; - dev_priv->rps.sw_turbo.down.eval_interval = ei_down; - dev_priv->rps.sw_turbo.down.is_up = false; - dev_priv->rps.sw_turbo.down.last_ts = 0; - dev_priv->rps.sw_turbo.down.last_c0 = 0; - - /* Start the timer to track if flip comes*/ - dev_priv->rps.sw_turbo.timeout = 200*1000; /* in us */ - - init_timer(&dev_priv->rps.sw_turbo.flip_timer); - dev_priv->rps.sw_turbo.flip_timer.function = flip_active_timeout_handler; - dev_priv->rps.sw_turbo.flip_timer.data = (unsigned long) dev_priv; - dev_priv->rps.sw_turbo.flip_timer.expires = - usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies; - add_timer(&dev_priv->rps.sw_turbo.flip_timer); - INIT_WORK(&dev_priv->rps.sw_turbo.work_max_freq, gen8_set_frequency_RP0); - - atomic_set(&dev_priv->rps.sw_turbo.flip_received, true); - } else { - /* NB: Docs say 1s, and 1000000 - which aren't equivalent - * 1 second timeout*/ - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, FREQ_1_28_US(1000000)); + /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ + I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ - /* Docs recommend 900MHz, and 300 MHz respectively */ - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - dev_priv->rps.max_freq_softlimit << 24 | - dev_priv->rps.min_freq_softlimit << 16); + /* Docs recommend 900MHz, and 300 MHz respectively */ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, + dev_priv->rps.max_freq_softlimit << 24 | + dev_priv->rps.min_freq_softlimit << 16); - I915_WRITE(GEN6_RP_UP_THRESHOLD, - FREQ_1_28_US(ei_up * threshold_up_pct / 100)); - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, - FREQ_1_28_US(ei_down * threshold_down_pct / 100)); - I915_WRITE(GEN6_RP_UP_EI, - FREQ_1_28_US(ei_up)); - I915_WRITE(GEN6_RP_DOWN_EI, - FREQ_1_28_US(ei_down)); + I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ + I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */ + I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */ - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - } + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); /* 5: Enable RPS */ - rp_ctl_flag = GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG; - if (!dev_priv->rps.is_bdw_sw_turbo) - rp_ctl_flag |= GEN6_RP_ENABLE; - - I915_WRITE(GEN6_RP_CONTROL, rp_ctl_flag); - - /* 6: Ring frequency + overclocking - * (our driver does this later */ + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_AVG); + + /* 6: Ring frequency + overclocking (our driver does this later */ + gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); - if (!dev_priv->rps.is_bdw_sw_turbo) - gen8_enable_rps_interrupts(dev); + + gen8_enable_rps_interrupts(dev); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } @@ -5421,8 +5272,6 @@ static void intel_gen6_powersave_work(struct work_struct *work) rps.delayed_resume_work.work); struct drm_device *dev = dev_priv->dev; - dev_priv->rps.is_bdw_sw_turbo = false; - mutex_lock(&dev_priv->rps.hw_lock); if (IS_CHERRYVIEW(dev)) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cc50bf65d35a..7c0c28c65cb4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -707,7 +707,7 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) * update the number of dwords required based on the * actual number of workarounds applied */ - ret = intel_ring_begin(ring, 24); + ret = intel_ring_begin(ring, 18); if (ret) return ret; @@ -722,19 +722,8 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - /* - * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for - * pre-production hardware - */ intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3, - _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS - | GEN8_SAMPLER_POWER_BYPASS_DIS)); - - intel_ring_emit_wa(ring, GEN7_HALF_SLICE_CHICKEN1, - _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE)); - - intel_ring_emit_wa(ring, COMMON_SLICE_CHICKEN2, - _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE)); + _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); /* Use Force Non-Coherent whenever executing a 3D context. This is a * workaround for for a possible hang in the unlikely event a TLB |