Re: [Intel-gfx] [PATCH v2] drm/i915: Debugfs disable RPS boost and idle
On Mon, Apr 28, 2014 at 07:20:17PM -0700, Ben Widawsky wrote: On Mon, Apr 28, 2014 at 01:53:52PM -0700, Daisy Sun wrote: RP frequency request is affected by 2 modules: normal turbo algorithm and RPS boost algorithm. By adding RPS boost algorithm to the mix, the final frequency becomes relatively unpredictable. Add a switch to enable/disable RPS boost functionality. When disabled, RP frequency will follow the normal turbo algorithm only. Intention: when boost and idle are disabled, we have a clear vision of turbo algorithm. It‘s very helpful to verify if the turbo algorithm is working as expected. Without debugfs hooks, the RPS boost or idle may kicks in at anytime and any circumstances. V1-V2: Follow Daniel's comment to explain the intention. Signed-off-by: Daisy Sun daisy@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 40 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 8 ++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1e83ae4..ff71214 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3486,6 +3486,45 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops, i915_drop_caches_get, i915_drop_caches_set, 0x%08llx\n); +static int i915_rps_disable_boost_get(void *data, u64 *val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev-dev_private; + + if (INTEL_INFO(dev)-gen 6) + return -ENODEV; + + *val = dev_priv-rps.debugfs_disable_boost; + + return 0; +} + +static int i915_rps_disable_boost_set(void *data, u64 val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev-dev_private; + int ret; + + flush_delayed_work(dev_priv-rps.delayed_resume_work); I'm not really sure why you feel it's necessary to flush the wq here. Note that you have no real safety since you cannot acquire the lock, and another event can get queued up after the flush. In other words, whatever you're trying to do probably can fail. Also note that without this, a simple atomic_t would suffice for debugfs_disable_boost. Simple? That puts another locked instruction on the common side as opposed to taking the mutex inside debugfs. Personally I'd complain much more about the lack of CODING_STYLE and good naming. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2] drm/i915: Debugfs disable RPS boost and idle
On Tue, Apr 29, 2014 at 07:48:41AM +0100, Chris Wilson wrote: On Mon, Apr 28, 2014 at 07:20:17PM -0700, Ben Widawsky wrote: On Mon, Apr 28, 2014 at 01:53:52PM -0700, Daisy Sun wrote: RP frequency request is affected by 2 modules: normal turbo algorithm and RPS boost algorithm. By adding RPS boost algorithm to the mix, the final frequency becomes relatively unpredictable. Add a switch to enable/disable RPS boost functionality. When disabled, RP frequency will follow the normal turbo algorithm only. Intention: when boost and idle are disabled, we have a clear vision of turbo algorithm. It‘s very helpful to verify if the turbo algorithm is working as expected. Without debugfs hooks, the RPS boost or idle may kicks in at anytime and any circumstances. V1-V2: Follow Daniel's comment to explain the intention. Signed-off-by: Daisy Sun daisy@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 40 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 8 ++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1e83ae4..ff71214 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3486,6 +3486,45 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops, i915_drop_caches_get, i915_drop_caches_set, 0x%08llx\n); +static int i915_rps_disable_boost_get(void *data, u64 *val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev-dev_private; + + if (INTEL_INFO(dev)-gen 6) + return -ENODEV; + + *val = dev_priv-rps.debugfs_disable_boost; + + return 0; +} + +static int i915_rps_disable_boost_set(void *data, u64 val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev-dev_private; + int ret; + + flush_delayed_work(dev_priv-rps.delayed_resume_work); I'm not really sure why you feel it's necessary to flush the wq here. Note that you have no real safety since you cannot acquire the lock, and another event can get queued up after the flush. In other words, whatever you're trying to do probably can fail. Also note that without this, a simple atomic_t would suffice for debugfs_disable_boost. Simple? That puts another locked instruction on the common side as opposed to taking the mutex inside debugfs. Personally I'd complain much more about the lack of CODING_STYLE and good naming. Also it's just a single bool and it doesn't matter if the value changes while someone is holding struct_mutex, so no atomic_t or struct_mutex necessary here. -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Print captured bo for all VM in error state
On Tue, Apr 29, 2014 at 3:10 AM, Ben Widawsky b...@bwidawsk.net wrote: On Sat, Jan 25, 2014 at 08:10:06PM +0100, Daniel Vetter wrote: On Fri, Jan 24, 2014 at 12:13:44PM -0800, Ben Widawsky wrote: ping Merged the first patch to topic/ppgtt, but punted on the 2nd - I think with Mika's improvement to the guilty batch detection we should be able to fix this better. Or what's the consensus here? Aside: I didn't spot your r-b burried way at the bottom of your mail, hence why I didn't apply them. -Daniel What happened to this patch or its equivalent? I still think with the guilty detection we could just dump the interesting ppgtt instead of all of them. Maybe poke Mika? -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 13/14] drm/i915/bdw: Disable idle DOP clock gating
On Mon, Apr 28, 2014 at 09:37:36AM -0700, Volkin, Bradley D wrote: Reviewed-by: Brad Volkin bradley.d.vol...@intel.com On Fri, Apr 18, 2014 at 02:04:29PM -0700, Rodrigo Vivi wrote: From: Ben Widawsky benjamin.widaw...@intel.com It seems we need this at least for the current platforms we have, but probably not later. In any event, it should cause too much harm as we do the same thing on several other platforms. Signed-off-by: Ben Widawsky b...@bwidawsk.net Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com All three patches from Ben merged, thanks. -Daniel --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a66000c..8d40786 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4924,6 +4924,10 @@ static void gen8_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE)); + /* WaDisableDopClockGating:bdw May not be needed for production */ + I915_WRITE(GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + /* WaSwitchSolVfFArbitrationPriority:bdw */ I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] intel_error_decode: use 64b gtt_offset
On Mon, Apr 28, 2014 at 06:45:50PM -0700, Ben Widawsky wrote: See the relevant kernel patch for the details. I guess this breaks support for older error state, I am not actually sure. Without versioning our error state though, I cannot think of a better way. Suggestions are welcome. Just drop the length qualifier and let scanf it the full number? -Daniel Signed-off-by: Ben Widawsky b...@bwidawsk.net --- tools/intel_error_decode.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/intel_error_decode.c b/tools/intel_error_decode.c index 1eeff07..d0028a1 100644 --- a/tools/intel_error_decode.c +++ b/tools/intel_error_decode.c @@ -311,17 +311,17 @@ print_fence(unsigned int devid, uint64_t fence) uint32_t head[MAX_RINGS]; int head_ndx = 0; int num_rings = 0; -static void print_batch(int is_batch, const char *ring_name, uint32_t gtt_offset) +static void print_batch(int is_batch, const char *ring_name, uint64_t gtt_offset) { const char *buffer_type[2] = { ringbuffer, batchbuffer }; if (is_batch || !num_rings) - printf(%s (%s) at 0x%08x\n, buffer_type[is_batch], ring_name, gtt_offset); + printf(%s (%s) at 0x%016lx\n, buffer_type[is_batch], ring_name, gtt_offset); else - printf(%s (%s) at 0x%08x; HEAD points to: 0x%08x\n, buffer_type[is_batch], ring_name, gtt_offset, head[head_ndx++ % num_rings] + gtt_offset); + printf(%s (%s) at 0x%016lx; HEAD points to: 0x%016lx\n, buffer_type[is_batch], ring_name, gtt_offset, head[head_ndx++ % num_rings] + gtt_offset); } static void decode(struct drm_intel_decode *ctx, bool is_batch, -const char *ring_name, uint32_t gtt_offset, uint32_t *data, +const char *ring_name, uint64_t gtt_offset, uint32_t *data, int *count) { if (!*count) @@ -344,7 +344,7 @@ read_data_file(FILE *file) char *line = NULL; size_t line_size; uint32_t offset, value, ring_length = 0; - uint32_t gtt_offset = 0, new_gtt_offset; + uint64_t gtt_offset = 0, new_gtt_offset; char *ring_name = NULL; int is_batch = 1; @@ -361,7 +361,7 @@ read_data_file(FILE *file) if (num_rings == -1) num_rings = head_ndx; - matched = sscanf(dashes, --- gtt_offset = 0x%08x\n, + matched = sscanf(dashes, --- gtt_offset = 0x%016lx\n, new_gtt_offset); if (matched == 1) { decode(decode_ctx, is_batch, ring_name, @@ -373,7 +373,7 @@ read_data_file(FILE *file) continue; } - matched = sscanf(dashes, --- ringbuffer = 0x%08x\n, + matched = sscanf(dashes, --- ringbuffer = 0x%08lx\n, new_gtt_offset); if (matched == 1) { decode(decode_ctx, is_batch, ring_name, -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] intel_error_decode: use 64b gtt_offset
On Tue, Apr 29, 2014 at 10:52:44AM +0200, Daniel Vetter wrote: On Mon, Apr 28, 2014 at 06:45:50PM -0700, Ben Widawsky wrote: See the relevant kernel patch for the details. I guess this breaks support for older error state, I am not actually sure. Without versioning our error state though, I cannot think of a better way. Suggestions are welcome. Just drop the length qualifier and let scanf it the full number? Also, you know the drill: Testcase, please. A copy of drv_hangman to also feed the captured error state into intel_error_decode and check that it doesn't fall overr (exitcode != 0 and nothing on stderr). Maybe call it drv_error_decode or something like that. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 0/9] drm/i915: Atomic sprites v4
From: Ville Syrjälä ville.syrj...@linux.intel.com Another posting of the atomic sprite series. Most things are reviewed, but there are a few patches in there for the scanline fixup that don't have r-bs. The HSW+ situation is also still unclear. The scanline counter behaviour depends on either the actual DDI port used (A vs. rest) or the encoder type (HDMI vs. DP). If someone wants to help me find out which, grab [1] and run the resulting intel_poller tool to figure out at which scanline the vblank irq triggers and/or live surface address gets updated. Examples from running the tool on my IVB: # intel_poller -t iir -p 0 -b 0 ... dsl / pipe A / DEIIR[0] (pch): 1078 - 1079 This tells me that the pipe A vblank bit in DEIIR is set when the scanline counter increments from 1078 to 1079. The display mode was 1920x1080, so this tells us we need a +1 adjustment for the scaline counter. # intel_poller -t surflive -p 0 ... dsl / pipe A / Surflive: 1078 - 1079 which tells me that SURFLIVE updates at the same time, as was expected. You can also run these tests: # ./intel_poller -t flip -p 0 -l 1078 # ./intel_poller -t pan -p 0 -l 1078 These write the DSPSURF/OFFSET register when the scanline counter reaches the target value, and overwrite it again with the original value on the next scanline. If the target scanline is correctly set the picture remains shifted for the duration of the test, and if you specify any another scanline the picture should remain in its original position the whole time. So if someone can run these on HSW and BDW systems with both DP and HDMI outputs on various ports we can try to figure out what the actual rule is. Ville Syrjälä (9): drm/i915: Fix scanout position for real drm/i915: Add intel_get_crtc_scanline() drm/i915: Make sprite updates atomic drm/i915: Perform primary enable/disable atomically with sprite updates drm/i915: Add pipe update trace points drm/i915: Add a small adjustment to the pixel counter on interlaced modes drm/i915: Improve gen3/4 frame counter drm/i915: Draw a picture about video timings drm/i915: Fix gen2 and hsw scanline counter drivers/gpu/drm/i915/i915_irq.c | 231 +-- drivers/gpu/drm/i915/i915_trace.h| 75 drivers/gpu/drm/i915/intel_display.c | 50 +++- drivers/gpu/drm/i915/intel_drv.h | 5 + drivers/gpu/drm/i915/intel_sprite.c | 231 +-- 5 files changed, 463 insertions(+), 129 deletions(-) -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 4/9] drm/i915: Perform primary enable/disable atomically with sprite updates
From: Ville Syrjälä ville.syrj...@linux.intel.com Move the primary plane enable/disable to occur atomically with the sprite update that caused the primary plane visibility to change. FBC and IPS enable/disable is left to happen well before or after the primary plane change. v2: Pass intel_crtc instead of drm_crtc (Daniel) Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org Reviewed-by: Sourab Gupta sourabgu...@gmail.com Reviewed-by: Akash Goel akash.go...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_sprite.c | 94 ++--- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a3ed840..6192e58 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -120,6 +120,17 @@ static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) pipe_name(pipe), start_vbl_count, end_vbl_count); } +static void intel_update_primary_plane(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc-base.dev-dev_private; + int reg = DSPCNTR(crtc-plane); + + if (crtc-primary_enabled) + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); + else + I915_WRITE(reg, I915_READ(reg) ~DISPLAY_PLANE_ENABLE); +} + static void vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -219,6 +230,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + intel_update_primary_plane(intel_crtc); + I915_WRITE(SPSTRIDE(pipe, plane), fb-pitches[0]); I915_WRITE(SPPOS(pipe, plane), (crtc_y 16) | crtc_x); @@ -231,7 +244,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, I915_WRITE(SPCNTR(pipe, plane), sprctl); I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); - POSTING_READ(SPSURF(pipe, plane)); + + intel_flush_primary_plane(dev_priv, intel_crtc-plane); if (atomic_update) intel_pipe_update_end(intel_crtc, start_vbl_count); @@ -251,11 +265,14 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + intel_update_primary_plane(intel_crtc); + I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) ~SP_ENABLE); /* Activate double buffered register update */ I915_WRITE(SPSURF(pipe, plane), 0); - POSTING_READ(SPSURF(pipe, plane)); + + intel_flush_primary_plane(dev_priv, intel_crtc-plane); if (atomic_update) intel_pipe_update_end(intel_crtc, start_vbl_count); @@ -403,6 +420,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + intel_update_primary_plane(intel_crtc); + I915_WRITE(SPRSTRIDE(pipe), fb-pitches[0]); I915_WRITE(SPRPOS(pipe), (crtc_y 16) | crtc_x); @@ -421,7 +440,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, I915_WRITE(SPRCTL(pipe), sprctl); I915_WRITE(SPRSURF(pipe), i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); - POSTING_READ(SPRSURF(pipe)); + + intel_flush_primary_plane(dev_priv, intel_crtc-plane); if (atomic_update) intel_pipe_update_end(intel_crtc, start_vbl_count); @@ -440,13 +460,16 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + intel_update_primary_plane(intel_crtc); + I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) ~SPRITE_ENABLE); /* Can't leave the scaler enabled... */ if (intel_plane-can_scale) I915_WRITE(SPRSCALE(pipe), 0); /* Activate double buffered register update */ I915_WRITE(SPRSURF(pipe), 0); - POSTING_READ(SPRSURF(pipe)); + + intel_flush_primary_plane(dev_priv, intel_crtc-plane); if (atomic_update) intel_pipe_update_end(intel_crtc, start_vbl_count); @@ -598,6 +621,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + intel_update_primary_plane(intel_crtc); + I915_WRITE(DVSSTRIDE(pipe), fb-pitches[0]); I915_WRITE(DVSPOS(pipe), (crtc_y 16) | crtc_x); @@ -611,7 +636,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, I915_WRITE(DVSCNTR(pipe), dvscntr); I915_WRITE(DVSSURF(pipe), i915_gem_obj_ggtt_offset(obj) +
[Intel-gfx] [PATCH v4 5/9] drm/i915: Add pipe update trace points
From: Ville Syrjälä ville.syrj...@linux.intel.com Add trace points for observing the atomic pipe update mechanism. v2: Rebased due to earlier changes v3: Pass intel_crtc instead of drm_crtc (Daniel) v4: Pass frame counter from the caller to evaded/end since the caller now always has that ready Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org Reviewed-by: Sourab Gupta sourabgu...@gmail.com Reviewed-by: Akash Goel akash.go...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_trace.h | 75 + drivers/gpu/drm/i915/intel_sprite.c | 6 +++ 2 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 23c26f1..b29d7b1 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -7,6 +7,7 @@ #include drm/drmP.h #include i915_drv.h +#include intel_drv.h #include intel_ringbuffer.h #undef TRACE_SYSTEM @@ -14,6 +15,80 @@ #define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) #define TRACE_INCLUDE_FILE i915_trace +/* pipe updates */ + +TRACE_EVENT(i915_pipe_update_start, + TP_PROTO(struct intel_crtc *crtc, u32 min, u32 max), + TP_ARGS(crtc, min, max), + + TP_STRUCT__entry( +__field(enum pipe, pipe) +__field(u32, frame) +__field(u32, scanline) +__field(u32, min) +__field(u32, max) +), + + TP_fast_assign( + __entry-pipe = crtc-pipe; + __entry-frame = crtc-base.dev-driver-get_vblank_counter(crtc-base.dev, + crtc-pipe); + __entry-scanline = intel_get_crtc_scanline(crtc); + __entry-min = min; + __entry-max = max; + ), + + TP_printk(pipe %c, frame=%u, scanline=%u, min=%u, max=%u, + pipe_name(__entry-pipe), __entry-frame, + __entry-scanline, __entry-min, __entry-max) +); + +TRACE_EVENT(i915_pipe_update_vblank_evaded, + TP_PROTO(struct intel_crtc *crtc, u32 min, u32 max, u32 frame), + TP_ARGS(crtc, min, max, frame), + + TP_STRUCT__entry( +__field(enum pipe, pipe) +__field(u32, frame) +__field(u32, scanline) +__field(u32, min) +__field(u32, max) +), + + TP_fast_assign( + __entry-pipe = crtc-pipe; + __entry-frame = frame; + __entry-scanline = intel_get_crtc_scanline(crtc); + __entry-min = min; + __entry-max = max; + ), + + TP_printk(pipe %c, frame=%u, scanline=%u, min=%u, max=%u, + pipe_name(__entry-pipe), __entry-frame, + __entry-scanline, __entry-min, __entry-max) +); + +TRACE_EVENT(i915_pipe_update_end, + TP_PROTO(struct intel_crtc *crtc, u32 frame), + TP_ARGS(crtc, frame), + + TP_STRUCT__entry( +__field(enum pipe, pipe) +__field(u32, frame) +__field(u32, scanline) +), + + TP_fast_assign( + __entry-pipe = crtc-pipe; + __entry-frame = frame; + __entry-scanline = intel_get_crtc_scanline(crtc); + ), + + TP_printk(pipe %c, frame=%u, scanline=%u, + pipe_name(__entry-pipe), __entry-frame, + __entry-scanline) +); + /* object tracking */ TRACE_EVENT(i915_gem_object_create, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 6192e58..213cd58 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -73,6 +73,8 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl local_irq_disable(); + trace_i915_pipe_update_start(crtc, min, max); + for (;;) { /* * prepare_to_wait() has a memory barrier, which guarantees @@ -104,6 +106,8 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl *start_vbl_count = dev-driver-get_vblank_counter(dev, pipe); + trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); + return true; } @@ -113,6 +117,8 @@ static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
[Intel-gfx] [PATCH 1/9] drm/i915: Fix scanout position for real
From: Ville Syrjälä ville.syrj...@linux.intel.com Seems I've been a bit dense with regards to the start of vblank vs. the scanline counter / pixel counter. After staring at the pixel counter on gen4 I came to the conclusion that the start of vblank interrupt and scanline counter increment happen at the same time. The scanline counter increment is documented to occur at start of hsync, which means that the start of vblank interrupt must also trigger there. Looking at the pixel counter value when the scanline wraps from vtotal-1 to 0 confirms that, as the pixel counter at that point reads hsync_start. This also clarifies why we see need the +1 adjustment to the scaline counter. The counter actually starts counting from vtotal-1 on the first active line. I also confirmed that the frame start interrupt happens ~1 line after the start of vblank, but the frame start occurs at hblank_start instead. We only use the frame start interrupt on gen2 where the start of vblank interrupt isn't available. The only important thing to note here is that frame start occurs after vblank start, so we don't have to play any additional tricks to fix up the scanline counter. The other thing to note is the fact that the pixel counter on gen3-4 starts counting from the start of horizontal active on the first active line. That means that when we get the start of vblank interrupt, the pixel counter reads (htotal*(vblank_start-1)+hsync_start). Since we consider vblank to start at (htotal*vblank_start) we need to add a constant (htotal-hsync_start) offset to the pixel counter, or else we risk misdetecting whether we're in vblank or not. I talked a bit with Art Runyan about these topics, and he confirmed my findings. And that the same rules should hold for platforms which don't have the pixel counter. That's good since without the pixel counter it's rather difficult to verify the timings to this accuracy. So the conclusion is that we can throw away all the ISR tricks I added, and just increment the scanline counter by one always. Reviewed-by: Sourab Gupta sourabgu...@gmail.com Reviewed-by: Akash Goel akash.go...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 102 +--- 1 file changed, 23 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2446e61..a72e635a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -751,26 +751,6 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) /* raw reads, only for fast reads of display block, no need for forcewake etc. */ #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)-regs + (reg__)) -static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev-dev_private; - uint32_t status; - int reg; - - if (INTEL_INFO(dev)-gen = 8) { - status = GEN8_PIPE_VBLANK; - reg = GEN8_DE_PIPE_ISR(pipe); - } else if (INTEL_INFO(dev)-gen = 7) { - status = DE_PIPE_VBLANK_IVB(pipe); - reg = DEISR; - } else { - status = DE_PIPE_VBLANK(pipe); - reg = DEISR; - } - - return __raw_i915_read32(dev_priv, reg) status; -} - static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) @@ -780,7 +760,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); const struct drm_display_mode *mode = intel_crtc-config.adjusted_mode; int position; - int vbl_start, vbl_end, htotal, vtotal; + int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; int ret = 0; unsigned long irqflags; @@ -792,6 +772,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, } htotal = mode-crtc_htotal; + hsync_start = mode-crtc_hsync_start; vtotal = mode-crtc_vtotal; vbl_start = mode-crtc_vblank_start; vbl_end = mode-crtc_vblank_end; @@ -810,7 +791,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, * following code must not block on uncore.lock. */ spin_lock_irqsave(dev_priv-uncore.lock, irqflags); - + /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ /* Get optional system timestamp before query. */ @@ -826,63 +807,15 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, else position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN3; - if (HAS_DDI(dev)) { - /* -
[Intel-gfx] [PATCH 7/9] drm/i915: Improve gen3/4 frame counter
From: Ville Syrjälä ville.syrj...@linux.intel.com Currently the logic to fix up the frame counter on gen3/4 assumes that start of vblank occurs at vblank_start*htotal pixels, when in fact it occurs htotal-hsync_start pixels earlier. Apply the appropriate adjustment to make the frame counter more accurate. Also fix the vblank start position for interlaced display modes. Reviewed-by: Imre Deak imre.d...@intel.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 64cd888..742f276 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -683,7 +683,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) struct drm_i915_private *dev_priv = dev-dev_private; unsigned long high_frame; unsigned long low_frame; - u32 high1, high2, low, pixel, vbl_start; + u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; if (!i915_pipe_enabled(dev, pipe)) { DRM_DEBUG_DRIVER(trying to get vblank count for disabled @@ -697,17 +697,28 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) const struct drm_display_mode *mode = intel_crtc-config.adjusted_mode; - vbl_start = mode-crtc_vblank_start * mode-crtc_htotal; + htotal = mode-crtc_htotal; + hsync_start = mode-crtc_hsync_start; + vbl_start = mode-crtc_vblank_start; + if (mode-flags DRM_MODE_FLAG_INTERLACE) + vbl_start = DIV_ROUND_UP(vbl_start, 2); } else { enum transcoder cpu_transcoder = (enum transcoder) pipe; - u32 htotal; htotal = ((I915_READ(HTOTAL(cpu_transcoder)) 16) 0x1fff) + 1; + hsync_start = (I915_READ(HSYNC(cpu_transcoder)) 0x1fff) + 1; vbl_start = (I915_READ(VBLANK(cpu_transcoder)) 0x1fff) + 1; - - vbl_start *= htotal; + if ((I915_READ(PIPECONF(cpu_transcoder)) +PIPECONF_INTERLACE_MASK) != PIPECONF_PROGRESSIVE) + vbl_start = DIV_ROUND_UP(vbl_start, 2); } + /* Convert to pixel count */ + vbl_start *= htotal; + + /* Start of vblank event occurs at start of hsync */ + vbl_start -= htotal - hsync_start; + high_frame = PIPEFRAME(pipe); low_frame = PIPEFRAMEPIXEL(pipe); -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 2/9] drm/i915: Add intel_get_crtc_scanline()
From: Ville Syrjälä ville.syrj...@linux.intel.com Add a new function intel_get_crtc_scanline() that returns the current scanline counter for the crtc. v2: Rebase after vblank timestamp changes. Use intel_ prefix instead of i915_ as is more customary for display related functions. Include DRM_SCANOUTPOS_INVBL in the return value even w/o adjustments, for a bit of extra consistency. v3: Change the implementation to be based on DSL on all gens, since that's enough for the needs of atomic updates, and it will avoid complicating the scanout position calculations for the vblank timestamps v4: Don't break scanline wraparound for interlaced modes Reviewed-by: Sourab Gupta sourabgu...@gmail.com Reviewed-by: Akash Goel akash.go...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 56 ++-- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a72e635a..ed30a5e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -751,6 +751,34 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) /* raw reads, only for fast reads of display block, no need for forcewake etc. */ #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)-regs + (reg__)) +static int __intel_get_crtc_scanline(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc-base.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + const struct drm_display_mode *mode = crtc-config.adjusted_mode; + enum pipe pipe = crtc-pipe; + int vtotal = mode-crtc_vtotal; + int position; + + if (mode-flags DRM_MODE_FLAG_INTERLACE) + vtotal /= 2; + + if (IS_GEN2(dev)) + position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN2; + else + position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN3; + + /* +* Scanline counter increments at leading edge of hsync, and +* it starts counting from vtotal-1 on the first active line. +* That means the scanline counter value is always one less +* than what we would expect. Ie. just after start of vblank, +* which also occurs at start of hsync (on the last active line), +* the scanline counter will read vblank_start-1. +*/ + return (position + 1) % vtotal; +} + static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) @@ -802,20 +830,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, /* No obvious pixelcount register. Only query vertical * scanout position from Display scan line register. */ - if (IS_GEN2(dev)) - position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN2; - else - position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN3; - - /* -* Scanline counter increments at leading edge of hsync, and -* it starts counting from vtotal-1 on the first active line. -* That means the scanline counter value is always one less -* than what we would expect. Ie. just after start of vblank, -* which also occurs at start of hsync (on the last active line), -* the scanline counter will read vblank_start-1. -*/ - position = (position + 1) % vtotal; + position = __intel_get_crtc_scanline(intel_crtc); } else { /* Have access to pixelcount since start of frame. * We can split this into vertical and horizontal @@ -876,6 +891,19 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, return ret; } +int intel_get_crtc_scanline(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc-base.dev-dev_private; + unsigned long irqflags; + int position; + + spin_lock_irqsave(dev_priv-uncore.lock, irqflags); + position = __intel_get_crtc_scanline(crtc); + spin_unlock_irqrestore(dev_priv-uncore.lock, irqflags); + + return position; +} + static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, int *max_error, struct timeval *vblank_time, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bc77705..96ae78d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -653,6 +653,7 @@ void snb_enable_pm_irq(struct
[Intel-gfx] [PATCH v2 8/9] drm/i915: Draw a picture about video timings
From: Ville Syrjälä ville.syrj...@linux.intel.com The docs are a bit lacking when it comes to describing when certain timing related events occur in the hardware. Draw a picture which tries to capture the most important ones. v2: Clarify a few details (Imre) Acked-by: Imre Deak imre.d...@intel.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 49 + 1 file changed, 49 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 742f276..bc4585b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -669,6 +669,55 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) } } +/* + * This timing diagram depicts the video signal in and + * around the vertical blanking period. + * + * Assumptions about the fictitious mode used in this example: + * vblank_start = 3 + * vsync_start = vblank_start + 1 + * vsync_end = vblank_start + 2 + * vtotal = vblank_start + 3 + * + * start of vblank: + * latch double buffered registers + * increment frame counter (ctg+) + * generate start of vblank interrupt (gen4+) + * | + * | frame start: + * | generate frame start interrupt (aka. vblank interrupt) (gmch) + * | may be shifted forward 1-3 extra lines via PIPECONF + * | | + * | | start of vsync: + * | | generate vsync interrupt + * | | | + * _________________________________ + * . \hs/ . \hs/ \hs/ \hs/ . \hs/ + * va--- -vb va- + * | | vs- | + * -vbs- ---vbs+1--- ---vbs+2--- -0- -1- ---2- (scanline counter gen2) + * -vbs-2--- ---vbs-1--- ---vbs- ---vbs+1--- ---vbs+2--- ---0- (scanline counter gen3+) + * | | | + * last visible pixel first visible pixel + * | increment frame counter (gen3/4) + * pixel counter = vblank_start * htotal pixel counter = 0 (gen3/4) + * + * x = horizontal active + * _ = horizontal blanking + * hs = horizontal sync + * va = vertical active + * vb = vertical blanking + * vs = vertical sync + * vbs = vblank_start (number) + * + * Summary: + * - most events happen at the start of horizontal sync + * - frame start happens at the start of horizontal blank, 1-4 lines + * (depending on PIPECONF settings) after the start of vblank + * - gen3/4 pixel and frame counter are synchronized with the start + * of horizontal active on the first line of vertical active + */ + static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe) { /* Gen2 doesn't have a hardware frame counter */ -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 9/9] drm/i915: Fix gen2 and hsw scanline counter
From: Ville Syrjälä ville.syrj...@linux.intel.com On gen2 the scanline counter behaves a bit differently from the later generations. Instead of adding one to the raw scanline counter value, we must subtract one. On HSW the scanline counter apparently requires a +2 adjustment on HDMI outputs. eDP on port A however wants the +1 adjustment. So far no one has tested DP/eDP on port != A, and also BDW behaviour is still a mystery. As the fixup we must apply to the hardware scanline counter depends on several factors, compute the desired offset at modeset time and tuck it away for when it's needed. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 14 --- drivers/gpu/drm/i915/intel_display.c | 48 +++- drivers/gpu/drm/i915/intel_drv.h | 2 ++ 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bc4585b..8e1b104 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -817,9 +817,9 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = dev-dev_private; const struct drm_display_mode *mode = crtc-config.adjusted_mode; enum pipe pipe = crtc-pipe; - int vtotal = mode-crtc_vtotal; - int position; + int position, vtotal; + vtotal = mode-crtc_vtotal; if (mode-flags DRM_MODE_FLAG_INTERLACE) vtotal /= 2; @@ -829,14 +829,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) DSL_LINEMASK_GEN3; /* -* Scanline counter increments at leading edge of hsync, and -* it starts counting from vtotal-1 on the first active line. -* That means the scanline counter value is always one less -* than what we would expect. Ie. just after start of vblank, -* which also occurs at start of hsync (on the last active line), -* the scanline counter will read vblank_start-1. +* See update_scanline_offset() for the details on the +* scanline_offset adjustment. */ - return (position + 1) % vtotal; + return (position + crtc-scanline_offset) % vtotal; } static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 993597b..93ef06b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9886,6 +9886,47 @@ void ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config pipe_config-adjusted_mode.crtc_clock, dotclock); } +static void update_scanline_offset(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc-base.dev; + + /* +* The scanline counter increments at the leading edge of hsync. +* +* On most platforms it starts counting from vtotal-1 on the +* first active line. That means the scanline counter value is +* always one less than what we would expect. Ie. just after +* start of vblank, which also occurs at start of hsync (on the +* last active line), the scanline counter will read vblank_start-1. +* +* On gen2 the scanline counter starts counting from 1 instead +* of vtotal-1, so we have to subtract one (or rather add vtotal-1 +* to keep the value positive), instead of adding one. +* +* On HSW the behaviour of the scanline counter depends either on +* the output type, or the DDI port used (so far it's unclear which). +* In certain cases we need to add 2 instead of 1 to the reported +* scanline counter value. +* FIXME: +2 seems to be correct for HDMI, but eDP on port A wants +1 +* instead. Not sure how DP on other ports behaves. +* FIXME: How does BDW behave? +*/ + if (IS_GEN2(dev)) { + const struct drm_display_mode *mode = crtc-config.adjusted_mode; + int vtotal; + + vtotal = mode-crtc_vtotal; + if (mode-flags DRM_MODE_FLAG_INTERLACE) + vtotal /= 2; + + crtc-scanline_offset = vtotal - 1; + } else if (HAS_DDI(dev) + intel_pipe_has_type(crtc-base, INTEL_OUTPUT_HDMI)) { + crtc-scanline_offset = 2; + } else + crtc-scanline_offset = 1; +} + static int __intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int x, int y, struct drm_framebuffer *fb) @@ -9984,8 +10025,11 @@ static int __intel_set_mode(struct drm_crtc *crtc, } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - for_each_intel_crtc_masked(dev,
[Intel-gfx] [PATCH v8 3/9] drm/i915: Make sprite updates atomic
From: Ville Syrjälä ville.syrj...@linux.intel.com Add a mechanism by which we can evade the leading edge of vblank. This guarantees that no two sprite register writes will straddle on either side of the vblank start, and that means all the writes will be latched together in one atomic operation. We do the vblank evade by checking the scanline counter, and if it's too close to the start of vblank (too close has been hardcoded to 100usec for now), we will wait for the vblank start to pass. In order to eliminate random delayes from the rest of the system, we operate with interrupts disabled, except when waiting for the vblank obviously. Note that we now go digging through pipe_to_crtc_mapping[] in the vblank interrupt handler, which is a bit dangerous since we set up interrupts before the crtcs. However in this case since it's the vblank interrupt, we don't actually unmask it until some piece of code requests it. v2: preempt_check_resched() calls after local_irq_enable() (Jesse) Hook up the vblank irq stuff on BDW as well v3: Pass intel_crtc instead of drm_crtc (Daniel) Warn if crtc.mutex isn't locked (Daniel) Add an explicit compiler barrier and document the barriers (Daniel) Note the irq vs. modeset setup madness in the commit message (Daniel) v4: Use prepare_to_wait() co. directly and eliminate vbl_received v5: Refactor intel_pipe_handle_vblank() vs. drm_handle_vblank() (Chris) Check for min/max scanline = 0 (Chris) Don't call intel_pipe_update_end() if start failed totally (Chris) Check that the vblank counters match on both sides of the critical section (Chris) v6: Fix atomic update for interlaced modes v7: Reorder code for better readability (Chris) v8: Drop preempt_check_resched(). It's not available to modules anymore and isn't even needed unless we ourselves cause a wakeup needing reschedule while interrupts are off Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org Reviewed-by: Sourab Gupta sourabgu...@gmail.com Reviewed-by: Akash Goel akash.go...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 25 +-- drivers/gpu/drm/i915/intel_display.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_sprite.c | 131 +++ 4 files changed, 154 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ed30a5e..7e0d577 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1556,6 +1556,19 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) } } +static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe) +{ + struct intel_crtc *crtc; + + if (!drm_handle_vblank(dev, pipe)) + return false; + + crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); + wake_up(crtc-vbl_wait); + + return true; +} + static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) { struct drm_i915_private *dev_priv = dev-dev_private; @@ -1607,7 +1620,7 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) for_each_pipe(pipe) { if (pipe_stats[pipe] PIPE_START_VBLANK_INTERRUPT_STATUS) - drm_handle_vblank(dev, pipe); + intel_pipe_handle_vblank(dev, pipe); if (pipe_stats[pipe] PLANE_FLIP_DONE_INT_STATUS_VLV) { intel_prepare_page_flip(dev, pipe); @@ -1850,7 +1863,7 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) for_each_pipe(pipe) { if (de_iir DE_PIPE_VBLANK(pipe)) - drm_handle_vblank(dev, pipe); + intel_pipe_handle_vblank(dev, pipe); if (de_iir DE_PIPE_FIFO_UNDERRUN(pipe)) if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) @@ -1900,7 +1913,7 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) for_each_pipe(pipe) { if (de_iir (DE_PIPE_VBLANK_IVB(pipe))) - drm_handle_vblank(dev, pipe); + intel_pipe_handle_vblank(dev, pipe); /* plane/pipes map 1:1 on ilk+ */ if (de_iir DE_PLANE_FLIP_DONE_IVB(pipe)) { @@ -2043,7 +2056,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); if (pipe_iir GEN8_PIPE_VBLANK) - drm_handle_vblank(dev, pipe); + intel_pipe_handle_vblank(dev, pipe); if (pipe_iir GEN8_PIPE_PRIMARY_FLIP_DONE) { intel_prepare_page_flip(dev, pipe); @@ -3391,7 +3404,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, struct drm_i915_private *dev_priv =
Re: [Intel-gfx] [PATCH] drm/i915: Sanitize the enable_ppgtt module option once
On Tue, Apr 29, 2014 at 11:53:58AM +0200, Daniel Vetter wrote: Otherwise we'll end up spamming dmesg on every context creation on snb with vt-d enabled. This regression was introduced in commit 246cbfb5fb9a1ca0997fbb135464c1ff5bb9c549 Author: Ben Widawsky benjamin.widaw...@intel.com Date: Fri Dec 6 14:11:14 2013 -0800 drm/i915: Reorganize intel_enable_ppgtt As the i915.enable_ppgtt is read-only it cannot be changed after the module is loaded and so we can perform an early sanitization of the values. v2: - Add comment and pimp commit message (Chris) - Use the param consistently (Jani) v3: - Fix init sequence on pre-gen6 by moving the sanitize_ppgtt call to gtt_init. Fixes boot hangs on pre-gen6. - Add a debug output for the sanitize ppgtt mode. References: https://lkml.org/lkml/2014/4/17/599 Rererences: https://bugs.freedesktop.org/show_bug.cgi?id=77916 Cc: Alessandro Suardi alessandro.sua...@gmail.com Cc: Ben Widawsky b...@bwidawsk.net Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch I am pretty sure we only call i915_gem_gtt_init() once during driver load... So let's try that r-b again. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] intel_error_decode: use 64b gtt_offset
On Tue, Apr 29, 2014 at 11:01:10AM +0200, Daniel Vetter wrote: On Tue, Apr 29, 2014 at 10:52:44AM +0200, Daniel Vetter wrote: On Mon, Apr 28, 2014 at 06:45:50PM -0700, Ben Widawsky wrote: See the relevant kernel patch for the details. I guess this breaks support for older error state, I am not actually sure. Without versioning our error state though, I cannot think of a better way. Suggestions are welcome. Just drop the length qualifier and let scanf it the full number? Also, you know the drill: Testcase, please. A copy of drv_hangman to also feed the captured error state into intel_error_decode and check that it doesn't fall overr (exitcode != 0 and nothing on stderr). Maybe call it drv_error_decode or something like that. Actually, I would have hoped you asked for uniformity in presenting and parsing 64bit values :) -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Print captured bo for all VM in error state
On Tue, Apr 29, 2014 at 10:33:00AM +0200, Daniel Vetter wrote: On Tue, Apr 29, 2014 at 3:10 AM, Ben Widawsky b...@bwidawsk.net wrote: On Sat, Jan 25, 2014 at 08:10:06PM +0100, Daniel Vetter wrote: On Fri, Jan 24, 2014 at 12:13:44PM -0800, Ben Widawsky wrote: ping Merged the first patch to topic/ppgtt, but punted on the 2nd - I think with Mika's improvement to the guilty batch detection we should be able to fix this better. Or what's the consensus here? Aside: I didn't spot your r-b burried way at the bottom of your mail, hence why I didn't apply them. -Daniel What happened to this patch or its equivalent? I still think with the guilty detection we could just dump the interesting ppgtt instead of all of them. Maybe poke Mika? Urm. Most of the time I contemplate patches to add all bound GTT objects as well i.e. there is a paucity of information here. (And currently *none* of value upstream. None.) -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/24] drm/i915: Add some more tracked state to intel_pipe_wm
On Mon, Apr 07, 2014 at 11:14:05AM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com intel_pipe_wm will be used to track the state in different stages of the watermark update process. For that we need to keep a bit more state in intel_pipe_wm. We also need to separate the multi-pipe intel_wm_config computation from ilk_compute_wm_parameters() as that one deals with the future state, and we need the intel_wm_config to match the current hardware state at the time we do the watermark merging for multiple pipes. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Needs minor rebase, but looks correct. Ok in my eyes this conflict looks a bit tricky, and since I lack the insight of you two for the watermark code I'd prefer a rebased version. -Daniel insert complaint about the fact that the watermarks code is pretty complex these days Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/intel_drv.h | 3 ++ drivers/gpu/drm/i915/intel_pm.c | 64 +++- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8c9892d..f022a78 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -333,6 +333,9 @@ struct intel_pipe_wm { struct intel_wm_level wm[5]; uint32_t linetime; bool fbc_wm_enabled; + bool pipe_enabled; + bool sprites_enabled; + bool sprites_scaled; }; struct intel_crtc { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 26c79ed..e0d1c8b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2105,38 +2105,52 @@ static void intel_setup_wm_latency(struct drm_device *dev) } static void ilk_compute_wm_parameters(struct drm_crtc *crtc, - struct ilk_pipe_wm_parameters *p, - struct intel_wm_config *config) + struct ilk_pipe_wm_parameters *p) { struct drm_device *dev = crtc-dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc-pipe; struct drm_plane *plane; - p-active = intel_crtc_active(crtc); - if (p-active) { - p-pipe_htotal = intel_crtc-config.adjusted_mode.crtc_htotal; - p-pixel_rate = ilk_pipe_pixel_rate(dev, crtc); - p-pri.bytes_per_pixel = crtc-fb-bits_per_pixel / 8; - p-cur.bytes_per_pixel = 4; - p-pri.horiz_pixels = intel_crtc-config.pipe_src_w; - p-cur.horiz_pixels = 64; - /* TODO: for now, assume primary and cursor planes are always enabled. */ - p-pri.enabled = true; - p-cur.enabled = true; - } + if (!intel_crtc_active(crtc)) + return; - list_for_each_entry(crtc, dev-mode_config.crtc_list, head) - config-num_pipes_active += intel_crtc_active(crtc); + p-active = true; + p-pipe_htotal = intel_crtc-config.adjusted_mode.crtc_htotal; + p-pixel_rate = ilk_pipe_pixel_rate(dev, crtc); + p-pri.bytes_per_pixel = crtc-fb-bits_per_pixel / 8; + p-cur.bytes_per_pixel = 4; + p-pri.horiz_pixels = intel_crtc-config.pipe_src_w; + p-cur.horiz_pixels = 64; + /* TODO: for now, assume primary and cursor planes are always enabled. */ + p-pri.enabled = true; + p-cur.enabled = true; list_for_each_entry(plane, dev-mode_config.plane_list, head) { struct intel_plane *intel_plane = to_intel_plane(plane); - if (intel_plane-pipe == pipe) + if (intel_plane-pipe == pipe) { p-spr = intel_plane-wm; + break; + } + } +} - config-sprites_enabled |= intel_plane-wm.enabled; - config-sprites_scaled |= intel_plane-wm.scaled; +static void ilk_compute_wm_config(struct drm_device *dev, + struct intel_wm_config *config) +{ + struct intel_crtc *intel_crtc; + + /* Compute the currently _active_ config */ + list_for_each_entry(intel_crtc, dev-mode_config.crtc_list, base.head) { + const struct intel_pipe_wm *wm = intel_crtc-wm.active; + + if (!wm-pipe_enabled) + continue; + + config-sprites_enabled |= wm-sprites_enabled; + config-sprites_scaled |= wm-sprites_scaled; + config-num_pipes_active++; } } @@ -2159,6 +2173,10 @@ static bool
Re: [Intel-gfx] [PATCH 02/24] drm/i915: Add some more tracked state to intel_pipe_wm
On Tue, Apr 29, 2014 at 01:18:50PM +0200, Daniel Vetter wrote: On Mon, Apr 07, 2014 at 11:14:05AM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com intel_pipe_wm will be used to track the state in different stages of the watermark update process. For that we need to keep a bit more state in intel_pipe_wm. We also need to separate the multi-pipe intel_wm_config computation from ilk_compute_wm_parameters() as that one deals with the future state, and we need the intel_wm_config to match the current hardware state at the time we do the watermark merging for multiple pipes. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Needs minor rebase, but looks correct. Ok in my eyes this conflict looks a bit tricky, and since I lack the insight of you two for the watermark code I'd prefer a rebased version. Or is this just because dinq is a bit out of sync with -nightly? In that case I'm stalling on Dave to open up drm-next so that I can rebase the entire shebang ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/24] drm/i915: Add some more tracked state to intel_pipe_wm
2014-04-29 8:20 GMT-03:00 Daniel Vetter dan...@ffwll.ch: On Tue, Apr 29, 2014 at 01:18:50PM +0200, Daniel Vetter wrote: On Mon, Apr 07, 2014 at 11:14:05AM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com intel_pipe_wm will be used to track the state in different stages of the watermark update process. For that we need to keep a bit more state in intel_pipe_wm. We also need to separate the multi-pipe intel_wm_config computation from ilk_compute_wm_parameters() as that one deals with the future state, and we need the intel_wm_config to match the current hardware state at the time we do the watermark merging for multiple pipes. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Needs minor rebase, but looks correct. Ok in my eyes this conflict looks a bit tricky, and since I lack the insight of you two for the watermark code I'd prefer a rebased version. Or is this just because dinq is a bit out of sync with -nightly? In that case I'm stalling on Dave to open up drm-next so that I can rebase the entire shebang ... I believe you have already applied patches 1-4 a few weeks ago. Maybe you're getting conflicts because you're applying already-applied patches? :) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch -- Paulo Zanoni ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 11/24] drm/i915: Check hw vs. sw watermark state after programming
On Wed, Apr 23, 2014 at 06:16:07PM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com Make sure we programmed the watermarks correctly, by reading out the hardware state again after programming and comparing it with the state we supposedly programmed into hardware. Dump the watermark registers after a mismatch, very much like we for the pipe config. The only difference is that we don't dump the entire watermark software tracking state since that's spread around a bit. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com This one could also have been split into more than one patch: first you extract the functions, then later you add the new callers. My only comment is: do we really want to check HW/SW state right after we write the register values? Shouldn't this be done at some other time, like the end of the modeset sequence? There's no guarantee that the WM update has finished there. I guess we could sprinkle such checks to a few places. The check would have to merge the active watermarks from all pipes and compare that with the register contents. So it would check that our hardware state matches the software active state at some point in time. But it can't really check that our idea of active watermarks is correct. This patch just checks that we actually wrote what we inteded into the registers. So it basically tests that ilk_compute_wm_dirty() works and that ilk_write_wm_values() didn't neglect to update something that was deemed dirty. Still, the patch seems correct, so: Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 117 1 file changed, 83 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ba4b23e..e519578a1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2524,15 +2524,84 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, return changed; } +static void _ilk_pipe_wm_get_hw_state(struct drm_device *dev, + enum pipe pipe, + struct ilk_wm_values *hw) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + static const unsigned int wm0_pipe_reg[] = { + [PIPE_A] = WM0_PIPEA_ILK, + [PIPE_B] = WM0_PIPEB_ILK, + [PIPE_C] = WM0_PIPEC_IVB, + }; + + hw-wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]); + + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + hw-wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); +} + +static void _ilk_wm_get_hw_state(struct drm_device *dev, +struct ilk_wm_values *hw) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + enum pipe pipe; + + for_each_pipe(pipe) + _ilk_pipe_wm_get_hw_state(dev, pipe, hw); + + hw-wm_lp[0] = I915_READ(WM1_LP_ILK); + hw-wm_lp[1] = I915_READ(WM2_LP_ILK); + hw-wm_lp[2] = I915_READ(WM3_LP_ILK); + + hw-wm_lp_spr[0] = I915_READ(WM1S_LP_ILK); + if (INTEL_INFO(dev)-gen = 7) { + hw-wm_lp_spr[1] = I915_READ(WM2S_LP_IVB); + hw-wm_lp_spr[2] = I915_READ(WM3S_LP_IVB); + } + + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + hw-partitioning = (I915_READ(WM_MISC) WM_MISC_DATA_PARTITION_5_6) ? + INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; + else if (IS_IVYBRIDGE(dev)) + hw-partitioning = (I915_READ(DISP_ARB_CTL2) DISP_DATA_PARTITION_5_6) ? + INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; + + hw-enable_fbc_wm = + !(I915_READ(DISP_ARB_CTL) DISP_FBC_WM_DIS); +} + +static void ilk_dump_wm_values(const struct ilk_wm_values *hw, + const char *context) +{ + DRM_DEBUG_KMS(%s watermark values\n, context); + DRM_DEBUG_KMS(WM_PIPE_A = 0x%08x\n, hw-wm_pipe[PIPE_A]); + DRM_DEBUG_KMS(WM_PIPE_B = 0x%08x\n, hw-wm_pipe[PIPE_B]); + DRM_DEBUG_KMS(WM_PIPE_C = 0x%08x\n, hw-wm_pipe[PIPE_C]); + DRM_DEBUG_KMS(WM_LP_1 = 0x%08x\n, hw-wm_lp[0]); + DRM_DEBUG_KMS(WM_LP_2 = 0x%08x\n, hw-wm_lp[1]); + DRM_DEBUG_KMS(WM_LP_3 = 0x%08x\n, hw-wm_lp[2]); + DRM_DEBUG_KMS(WM_LP_SPR_1 = 0x%08x\n, hw-wm_lp_spr[0]); + DRM_DEBUG_KMS(WM_LP_SPR_2 = 0x%08x\n, hw-wm_lp_spr[1]); + DRM_DEBUG_KMS(WM_LP_SPR_3 = 0x%08x\n, hw-wm_lp_spr[2]); + DRM_DEBUG_KMS(WM_LINETIME_A = 0x%08x\n, hw-wm_linetime[PIPE_A]); + DRM_DEBUG_KMS(WM_LINETIME_B = 0x%08x\n, hw-wm_linetime[PIPE_B]); + DRM_DEBUG_KMS(WM_LINETIME_C = 0x%08x\n, hw-wm_linetime[PIPE_C]);
Re: [Intel-gfx] [PATCH] drm/i915: Sanitize the enable_ppgtt module option once
On Tue, 29 Apr 2014, Chris Wilson ch...@chris-wilson.co.uk wrote: On Tue, Apr 29, 2014 at 11:53:58AM +0200, Daniel Vetter wrote: Otherwise we'll end up spamming dmesg on every context creation on snb with vt-d enabled. This regression was introduced in commit 246cbfb5fb9a1ca0997fbb135464c1ff5bb9c549 Author: Ben Widawsky benjamin.widaw...@intel.com Date: Fri Dec 6 14:11:14 2013 -0800 drm/i915: Reorganize intel_enable_ppgtt As the i915.enable_ppgtt is read-only it cannot be changed after the module is loaded and so we can perform an early sanitization of the values. v2: - Add comment and pimp commit message (Chris) - Use the param consistently (Jani) v3: - Fix init sequence on pre-gen6 by moving the sanitize_ppgtt call to gtt_init. Fixes boot hangs on pre-gen6. - Add a debug output for the sanitize ppgtt mode. References: https://lkml.org/lkml/2014/4/17/599 Rererences: https://bugs.freedesktop.org/show_bug.cgi?id=77916 Cc: Alessandro Suardi alessandro.sua...@gmail.com Cc: Ben Widawsky b...@bwidawsk.net Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch I am pretty sure we only call i915_gem_gtt_init() once during driver load... So let's try that r-b again. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Pushed to -fixes, thanks for the patch and review. BR, Jani. -- Jani Nikula, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/4] drm/i915: Changed the return type from 'void', so as to return an error
On Sun, Apr 20, 2014 at 04:22:48PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com This patch changes the return type of panel fitter configuration functions from 'void', so that an error could be returned back to User space, either during the modeset time or when the 'border' property is being set, if the configuation is not valid. This addresses the review comment from Ville, given on the previous patch. Signed-off-by: Akash Goel akash.g...@intel.com Please reorder the patches so that this patch comes before you add the manual panel fitting stuff. Otherwise it's hard to evaluate the error paths in the new code. --- drivers/gpu/drm/i915/intel_display.c | 5 +++-- drivers/gpu/drm/i915/intel_dp.c | 15 +-- drivers/gpu/drm/i915/intel_drv.h | 6 +++--- drivers/gpu/drm/i915/intel_lvds.c| 11 ++- drivers/gpu/drm/i915/intel_panel.c | 28 5 files changed, 37 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8ff99bf..d7303be 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10018,9 +10018,10 @@ static int intel_set_mode(struct drm_crtc *crtc, return ret; } -void intel_crtc_restore_mode(struct drm_crtc *crtc) +int intel_crtc_restore_mode(struct drm_crtc *crtc) { - intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, crtc-primary-fb); + return intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, + crtc-primary-fb); } #undef for_each_intel_crtc_masked diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b50b170..ad108e2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -778,12 +778,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (is_edp(intel_dp) intel_connector-panel.fixed_mode) { intel_fixed_panel_mode(intel_connector-panel.fixed_mode, adjusted_mode); - if (!HAS_PCH_SPLIT(dev)) - intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); - else - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); + if (!HAS_PCH_SPLIT(dev)) { + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } else { + if (!intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } } if (adjusted_mode-flags DRM_MODE_FLAG_DBLCLK) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f00d075..bed4941 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -704,7 +704,7 @@ void intel_mark_busy(struct drm_device *dev); void intel_mark_fb_busy(struct drm_i915_gem_object *obj, struct intel_ring_buffer *ring); void intel_mark_idle(struct drm_device *dev); -void intel_crtc_restore_mode(struct drm_crtc *crtc); +int intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_update_dpms(struct drm_crtc *crtc); void intel_encoder_destroy(struct drm_encoder *encoder); void intel_connector_dpms(struct drm_connector *, int mode); @@ -888,10 +888,10 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); -void intel_pch_panel_fitting(struct intel_crtc *crtc, +bool intel_pch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); -void intel_gmch_panel_fitting(struct intel_crtc *crtc, +bool intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); void intel_panel_set_backlight(struct intel_connector *connector, u32 level, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 1b1541d..e0ef79d 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -307,12 +307,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, if (HAS_PCH_SPLIT(dev)) { pipe_config-has_pch_encoder = true; -
Re: [Intel-gfx] [PATCH 02/24] drm/i915: Add some more tracked state to intel_pipe_wm
On Tue, Apr 29, 2014 at 09:34:28AM -0300, Paulo Zanoni wrote: 2014-04-29 8:20 GMT-03:00 Daniel Vetter dan...@ffwll.ch: On Tue, Apr 29, 2014 at 01:18:50PM +0200, Daniel Vetter wrote: On Mon, Apr 07, 2014 at 11:14:05AM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com intel_pipe_wm will be used to track the state in different stages of the watermark update process. For that we need to keep a bit more state in intel_pipe_wm. We also need to separate the multi-pipe intel_wm_config computation from ilk_compute_wm_parameters() as that one deals with the future state, and we need the intel_wm_config to match the current hardware state at the time we do the watermark merging for multiple pipes. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Needs minor rebase, but looks correct. Ok in my eyes this conflict looks a bit tricky, and since I lack the insight of you two for the watermark code I'd prefer a rebased version. Or is this just because dinq is a bit out of sync with -nightly? In that case I'm stalling on Dave to open up drm-next so that I can rebase the entire shebang ... I believe you have already applied patches 1-4 a few weeks ago. Maybe you're getting conflicts because you're applying already-applied patches? :) Ah, that might indeed explain why the conflict looks so funny ;-) /me puts on the idiot hat Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 08/24] drm/i915: Shuffle wait_for_vblank out of primary_enable/disable funcs
On Tue, Apr 08, 2014 at 09:55:45PM +0300, Ville Syrjälä wrote: On Mon, Apr 07, 2014 at 05:27:41PM -0300, Paulo Zanoni wrote: 2014-03-07 13:32 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com Rather than have a wait_for_vblank() in the primary plane enable/disable funcs, move the wait_for_vblank() to happen after enabling/disabling all planes. Why exactly? What is improved? Are we solving a bug? What are the risks? What's the problem with the current code? Did you check the modeset sequence documentation of every single platform (since you changed them all) to make sure this is safe? Just another step towards getting all the planes enabled/disabled atomically during a modeset. I should have probably yanked it from this series since it shouldn't be strictly needed for the watermark stuff. At least I can't think of a reason now. I guess I included it here just to make things a bit more difficult for the new watermark update mechanism. In any case there's nothing magical about the primary plane, so we shouldn't treat it as such. That's my excuse for this patch anyway. Please update the commit message with the answers. Also, we should probably update the first comment of hsw_enable_ips. It seems things have changed since it was written. I thought I had. Ah no, that's part of the mmio vs. cs flip race series. Looks like the wait for vblank changes there will conflict with this stuff anyway. I'll have to revisit that series, and hopefully get it merged before this series so that we can ignore this patch entirely. I'll ignore this one her for now ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: don't try DP_LINK_BW_5_4 on HSW ULX
From: Paulo Zanoni paulo.r.zan...@intel.com Because the docs say ULX doesn't support it on HSW. Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_dp.c | 3 ++- include/drm/i915_pciids.h | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) This patch is completely untested!!! diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e81feab..bdc612c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1816,6 +1816,9 @@ struct drm_i915_cmd_table { #define IS_ULT(dev)(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) #define IS_HSW_GT3(dev)(IS_HASWELL(dev) \ ((dev)-pdev-device 0x00F0) == 0x0020) +/* ULX machines are also considered ULT. */ +#define IS_HSW_ULX(dev)((dev)-pdev-device == 0x0A0E || \ +(dev)-pdev-device == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)-is_preliminary) /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 34ed143..87b0a51 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) case DP_LINK_BW_2_7: break; case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ - if ((IS_HASWELL(dev) || INTEL_INFO(dev)-gen = 8) + if (((IS_HASWELL(dev) !IS_HSW_ULX(dev)) || +INTEL_INFO(dev)-gen = 8) intel_dp-dpcd[DP_DPCD_REV] = 0x12) max_link_bw = DP_LINK_BW_5_4; else diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 24f3cad..5cd9165 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -191,8 +191,8 @@ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0A0E, info), /* ULT GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0A1E, info), /* ULT GT2 reserved */ \ + INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \ + INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 09/24] drm/i915: Keep vblank interrupts enabled while enabling/disabling planes
On Mon, Apr 28, 2014 at 06:42:50PM -0300, Paulo Zanoni wrote: 2014-04-28 9:58 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com Becasue of the upcoming vblank interrupt driven watermark update BecaUSe. Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com mechanism we will have use for vblank interrupts during plane enabling/disabling. So don't call drm_vblank_off() until planes are off, and call drm_vblank_on() just before we start to enable the planes. v2: Pimp commit message (Paulo) Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Argh, this depends upon the drm vblank rework in the core, which is still hanging tight in a topic branch waiting for me to polish it. I'll move that todo up on my priority list ... Previous patches should be merged to dinq now (except the one I've noted). -Daniel --- drivers/gpu/drm/i915/intel_display.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 88df4ea..8d2a31e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3547,6 +3547,8 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc) int pipe = intel_crtc-pipe; int plane = intel_crtc-plane; + drm_vblank_on(dev, pipe); + intel_enable_primary_plane(dev_priv, plane, pipe); intel_enable_planes(crtc); intel_crtc_update_cursor(crtc, true); @@ -3557,8 +3559,6 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc) mutex_lock(dev-struct_mutex); intel_update_fbc(dev); mutex_unlock(dev-struct_mutex); - - drm_vblank_on(dev, pipe); } static void ilk_crtc_disable_planes(struct drm_crtc *crtc) @@ -3570,7 +3570,6 @@ static void ilk_crtc_disable_planes(struct drm_crtc *crtc) int plane = intel_crtc-plane; intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe); if (dev_priv-fbc.plane == plane) intel_disable_fbc(dev); @@ -3581,6 +3580,8 @@ static void ilk_crtc_disable_planes(struct drm_crtc *crtc) intel_disable_planes(crtc); intel_disable_primary_plane(dev_priv, plane, pipe); intel_wait_for_vblank(dev, pipe); + + drm_vblank_off(dev, pipe); } static void ironlake_crtc_enable(struct drm_crtc *crtc) -- 1.8.3.2 -- Paulo Zanoni ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Sanitize the enable_ppgtt module option once
On Tue, Apr 29, 2014 at 02:23:56PM +0200, Alessandro Suardi wrote: On Tue, Apr 29, 2014 at 12:44 PM, Chris Wilson ch...@chris-wilson.co.uk wrote: On Tue, Apr 29, 2014 at 11:53:58AM +0200, Daniel Vetter wrote: Otherwise we'll end up spamming dmesg on every context creation on snb with vt-d enabled. This regression was introduced in commit 246cbfb5fb9a1ca0997fbb135464c1ff5bb9c549 Author: Ben Widawsky benjamin.widaw...@intel.com Date: Fri Dec 6 14:11:14 2013 -0800 drm/i915: Reorganize intel_enable_ppgtt As the i915.enable_ppgtt is read-only it cannot be changed after the module is loaded and so we can perform an early sanitization of the values. v2: - Add comment and pimp commit message (Chris) - Use the param consistently (Jani) v3: - Fix init sequence on pre-gen6 by moving the sanitize_ppgtt call to gtt_init. Fixes boot hangs on pre-gen6. - Add a debug output for the sanitize ppgtt mode. References: https://lkml.org/lkml/2014/4/17/599 Rererences: https://bugs.freedesktop.org/show_bug.cgi?id=77916 Cc: Alessandro Suardi alessandro.sua...@gmail.com Cc: Ben Widawsky b...@bwidawsk.net Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch I am pretty sure we only call i915_gem_gtt_init() once during driver load... So let's try that r-b again. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk -Chris I'd like to add my Tested-By, but this patch doesn't apply cleanly to 3.15-rc3 - is there any prerequisite patch on top of -rc3 or should I use a git tree to test this fix ? It needs one patch from drm-intel-fixes, probably easiest if you just grab that git tree. Or grab the relevant patch http://cgit.freedesktop.org/drm-intel/commit/?id=0f9dc59db6abc475dc23afc077fabbc606b8830f Offtopic, this email has a tiny typo (Rererences in the freedesktop bug ID line), just in case git actually stores that kind of metadata :) Jani, can you please rectify this? Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 2/4] drm/i915: New drm crtc property for varying the Pipe Src size
On Sun, Apr 20, 2014 at 04:14:18PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com This patch adds a new drm crtc property for varying the Pipe Src size or the Panel fitter input size. Pipe Src controls the size that is scaled from. This will allow to dynamically flip (without modeset) the frame buffers of different resolutions v2: Added a check to fail the set property call if Panel fitter is disabled new PIPESRC programming do not match with PIPE timings. Removed the pitch mismatch check on frame buffer, when being flipped. This is currently done only for VLV/HSW. v3: Modified the check, added in v2, to consider the platforms having Split PCH. v4: Refactored based on latest codebase. Used 'UINT_MAX' macro in place of constant. Testcase: igt/kms_panel_fitter_test Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/intel_display.c | 76 +++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7d6acb4..104a232 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1441,6 +1441,12 @@ struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + /* + * Property to dynamically vary the size of the + * PIPESRC or Panel fitter input size + */ + struct drm_property *input_size_property; + uint32_t hw_context_size; struct list_head context_list; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f26be4e..5484ae2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8902,8 +8902,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, * Note that pitch changes could also affect these register. */ if (INTEL_INFO(dev)-gen 3 - (fb-offsets[0] != crtc-primary-fb-offsets[0] || - fb-pitches[0] != crtc-primary-fb-pitches[0])) + (fb-offsets[0] != crtc-primary-fb-offsets[0])) + return -EINVAL; + + /* + * Bypassing the fb pitch check for VLV/HSW, as purportedly there + * is a dynamic flip support in VLV/HSW. This will allow to + * flip fbs of different resolutions without doing a modeset. + * TBD, confirm the same for other newer gen platforms also. + */ + if (INTEL_INFO(dev)-gen 3 + !IS_VALLEYVIEW(dev) !IS_HASWELL(dev) + (fb-pitches[0] != crtc-primary-fb-pitches[0])) NAK. Please read the comment above the check to understand why we can't just change the stride here. I guess on HSW+ it might be possible since it uses the x/y offsets even with linear FBs so stride changes don't affect the offset. Also such changes sould be in separate patches anyway. I guess one option would be update the linear offset with LRI, but since the offset register gets latched independently of the DSPSURF write the changes aren't guaranteed to happen atomically. Also on VLV LRI to display registers is apparently busted. If you do find a way to make this work on some platforms, then we need to have a test for it to make sure it does the right thing. return -EINVAL; if (i915_terminally_wedged(dev_priv-gpu_error)) @@ -10422,11 +10432,71 @@ out_config: return ret; } +static void intel_create_crtc_properties(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (!dev_priv-input_size_property) + dev_priv-input_size_property = + drm_property_create_range(dev, 0, input size, + 0, UINT_MAX); I think people would be happier with separate width/height properties instead of sticking both into one property. Also this sounds like a generally useful property for hardware any which has some kind of full crtc scaler. So maybe it should be in drm core. Also what ever happended to the property documentation effort. Did the patch get in, or was it rejected, or is it in limbo? + + if (dev_priv-input_size_property) + drm_object_attach_property(intel_crtc-base.base, +dev_priv-input_size_property, +0); +} + static int intel_crtc_set_property(struct drm_crtc *crtc, struct drm_property *property, uint64_t val) { + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int ret = -ENOENT; + if (property == dev_priv-input_size_property) { +
Re: [Intel-gfx] [PATCH] drm/i915: don't try DP_LINK_BW_5_4 on HSW ULX
Todd, can you please quickly review this one? Thanks, Daniel On Tue, Apr 29, 2014 at 4:00 PM, Paulo Zanoni przan...@gmail.com wrote: From: Paulo Zanoni paulo.r.zan...@intel.com Because the docs say ULX doesn't support it on HSW. Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_dp.c | 3 ++- include/drm/i915_pciids.h | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) This patch is completely untested!!! diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e81feab..bdc612c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1816,6 +1816,9 @@ struct drm_i915_cmd_table { #define IS_ULT(dev)(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) #define IS_HSW_GT3(dev)(IS_HASWELL(dev) \ ((dev)-pdev-device 0x00F0) == 0x0020) +/* ULX machines are also considered ULT. */ +#define IS_HSW_ULX(dev)((dev)-pdev-device == 0x0A0E || \ +(dev)-pdev-device == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)-is_preliminary) /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 34ed143..87b0a51 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) case DP_LINK_BW_2_7: break; case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ - if ((IS_HASWELL(dev) || INTEL_INFO(dev)-gen = 8) + if (((IS_HASWELL(dev) !IS_HSW_ULX(dev)) || +INTEL_INFO(dev)-gen = 8) intel_dp-dpcd[DP_DPCD_REV] = 0x12) max_link_bw = DP_LINK_BW_5_4; else diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 24f3cad..5cd9165 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -191,8 +191,8 @@ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0A0E, info), /* ULT GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0A1E, info), /* ULT GT2 reserved */ \ + INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \ + INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 2/4] drm/i915: New drm crtc property for varying the Pipe Src size
On Tue, Apr 29, 2014 at 05:06:59PM +0300, Ville Syrjälä wrote: On Sun, Apr 20, 2014 at 04:14:18PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com This patch adds a new drm crtc property for varying the Pipe Src size or the Panel fitter input size. Pipe Src controls the size that is scaled from. This will allow to dynamically flip (without modeset) the frame buffers of different resolutions v2: Added a check to fail the set property call if Panel fitter is disabled new PIPESRC programming do not match with PIPE timings. Removed the pitch mismatch check on frame buffer, when being flipped. This is currently done only for VLV/HSW. v3: Modified the check, added in v2, to consider the platforms having Split PCH. v4: Refactored based on latest codebase. Used 'UINT_MAX' macro in place of constant. Testcase: igt/kms_panel_fitter_test Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/intel_display.c | 76 +++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7d6acb4..104a232 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1441,6 +1441,12 @@ struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + /* +* Property to dynamically vary the size of the +* PIPESRC or Panel fitter input size +*/ + struct drm_property *input_size_property; + uint32_t hw_context_size; struct list_head context_list; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f26be4e..5484ae2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8902,8 +8902,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, * Note that pitch changes could also affect these register. */ if (INTEL_INFO(dev)-gen 3 - (fb-offsets[0] != crtc-primary-fb-offsets[0] || -fb-pitches[0] != crtc-primary-fb-pitches[0])) + (fb-offsets[0] != crtc-primary-fb-offsets[0])) + return -EINVAL; + + /* +* Bypassing the fb pitch check for VLV/HSW, as purportedly there +* is a dynamic flip support in VLV/HSW. This will allow to +* flip fbs of different resolutions without doing a modeset. +* TBD, confirm the same for other newer gen platforms also. +*/ + if (INTEL_INFO(dev)-gen 3 + !IS_VALLEYVIEW(dev) !IS_HASWELL(dev) + (fb-pitches[0] != crtc-primary-fb-pitches[0])) NAK. Please read the comment above the check to understand why we can't just change the stride here. I guess on HSW+ it might be possible since it uses the x/y offsets even with linear FBs so stride changes don't affect the offset. Also such changes sould be in separate patches anyway. I guess one option would be update the linear offset with LRI, but since the offset register gets latched independently of the DSPSURF write the changes aren't guaranteed to happen atomically. Also on VLV LRI to display registers is apparently busted. If you do find a way to make this work on some platforms, then we need to have a test for it to make sure it does the right thing. Note that even on hsw we update the linear offset if it's out of range for the x/y tiled offsets. Which can happen with very wide/high virtual desktops. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 20/71] drm/i915/chv: find the best divisor for the target clock v4
On Wed, 2014-04-09 at 13:28 +0300, ville.syrj...@linux.intel.com wrote: From: Chon Ming Lee chon.ming@intel.com Based on the chv clock limit, find the best divisor. The divisor data has been verified with this spreadsheet. P1273_DPLL_Programming Spreadsheet. v2: Rebase the code and change the chv_find_best_dpll based on new standard way to use intel_PLL_is_valid. Besides, clean up some extra variables. v3: Ville suggest better fixed point for m2 calculation. v4: -Add comment for the limit is compute using fast clock. (Ville) -Don't pass the request clock to chv_clock, as the same function will be use clock readout, which doens't have request clock. (Ville) -Add and use DIV_ROUND_CLOSEST_ULL to consistent with other clock calculation. (Ville) -Fix the dp m2 after m2 has stored fixed point. (Ville) Signed-off-by: Chon Ming Lee chon.ming@intel.com [vsyrjala: Avoid div-by-zero in chv_clock()] Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Took a while to understand all the different clock rates along the path, but it looks ok: Reviewed-by: Imre Deak imre.d...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 86 drivers/gpu/drm/i915/intel_dp.c | 21 + 2 files changed, 107 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e33667d..d73fec5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -41,6 +41,9 @@ #include drm/drm_crtc_helper.h #include linux/dma_remapping.h +#define DIV_ROUND_CLOSEST_ULL(ll, d) \ + ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) + static void intel_increase_pllclock(struct drm_crtc *crtc); static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); @@ -328,6 +331,22 @@ static const intel_limit_t intel_limits_vlv = { .p2 = { .p2_slow = 2, .p2_fast = 20 }, /* slow=min, fast=max */ }; +static const intel_limit_t intel_limits_chv = { + /* + * These are the data rate limits (measured in fast clocks) + * since those are the strictest limits we have. The fast + * clock and actual rate limits are more relaxed, so checking + * them would make no difference. + */ + .dot = { .min = 25000 * 5, .max = 54 * 5}, + .vco = { .min = 486, .max = 670 }, + .n = { .min = 1, .max = 1 }, + .m1 = { .min = 2, .max = 2 }, + .m2 = { .min = 24 22, .max = 175 22 }, + .p1 = { .min = 2, .max = 4 }, + .p2 = { .p2_slow = 1, .p2_fast = 14 }, +}; + static void vlv_clock(int refclk, intel_clock_t *clock) { clock-m = clock-m1 * clock-m2; @@ -412,6 +431,8 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) limit = intel_limits_pineview_lvds; else limit = intel_limits_pineview_sdvo; + } else if (IS_CHERRYVIEW(dev)) { + limit = intel_limits_chv; } else if (IS_VALLEYVIEW(dev)) { limit = intel_limits_vlv; } else if (!IS_GEN2(dev)) { @@ -456,6 +477,17 @@ static void i9xx_clock(int refclk, intel_clock_t *clock) clock-dot = DIV_ROUND_CLOSEST(clock-vco, clock-p); } +static void chv_clock(int refclk, intel_clock_t *clock) +{ + clock-m = clock-m1 * clock-m2; + clock-p = clock-p1 * clock-p2; + if (WARN_ON(clock-n == 0 || clock-p == 0)) + return; + clock-vco = DIV_ROUND_CLOSEST_ULL((uint64_t)refclk * clock-m, + clock-n 22); + clock-dot = DIV_ROUND_CLOSEST(clock-vco, clock-p); +} + #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) /** * Returns whether the given set of divisors are valid for a given refclk with @@ -731,6 +763,58 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, return found; } +static bool +chv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +int target, int refclk, intel_clock_t *match_clock, +intel_clock_t *best_clock) +{ + struct drm_device *dev = crtc-dev; + intel_clock_t clock; + uint64_t m2; + int found = false; + + memset(best_clock, 0, sizeof(*best_clock)); + + /* + * Based on hardware doc, the n always set to 1, and m1 always + * set to 2. If requires to support 200Mhz refclk, we need to + * revisit this because n may not 1 anymore. + */ + clock.n = 1, clock.m1 = 2; + target *= 5;/* fast clock */ + + for (clock.p1 = limit-p1.max; clock.p1 = limit-p1.min; clock.p1--) { + for (clock.p2 = limit-p2.p2_fast; + clock.p2 = limit-p2.p2_slow; + clock.p2 -= clock.p2 10 ? 2 : 1) { + + clock.p = clock.p1
Re: [Intel-gfx] [PATCH] drm/i915: Sanitize the enable_ppgtt module option once
On Tue, 29 Apr 2014, Daniel Vetter dan...@ffwll.ch wrote: On Tue, Apr 29, 2014 at 02:23:56PM +0200, Alessandro Suardi wrote: Offtopic, this email has a tiny typo (Rererences in the freedesktop bug ID line), just in case git actually stores that kind of metadata :) Jani, can you please rectify this? Done. -- Jani Nikula, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Try to stop rings before reset
This seems to make the hard machine hangs provoked by running gem_reset_stats tests a lot less likely. At least on my snb here. v2: Don't DRM_ERROR when a reset is in progress in the stop_ring function. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74100 Cc: Mika Kuoppala mika.kuopp...@linux.intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_ringbuffer.c | 13 - drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + drivers/gpu/drm/i915/intel_uncore.c | 7 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ab22d70733bf..e8ca1dcb6a45 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -448,14 +448,17 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) I915_WRITE(HWS_PGA, addr); } -static bool stop_ring(struct intel_ring_buffer *ring) +bool __intel_stop_ring_buffer(struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = to_i915(ring-dev); if (!IS_GEN2(ring-dev)) { I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); if (wait_for_atomic((I915_READ_MODE(ring) MODE_IDLE) != 0, 1000)) { - DRM_ERROR(%s :timed out trying to stop ring\n, ring-name); + if (!i915_reset_in_progress(dev_priv-gpu_error)) { + DRM_ERROR(%s :timed out trying to stop ring\n, + ring-name); + } return false; } } @@ -481,7 +484,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); - if (!stop_ring(ring)) { + if (!__intel_stop_ring_buffer(ring)) { /* G45 ring initialization often fails to reset head to zero */ DRM_DEBUG_KMS(%s head not reset to zero ctl %08x head %08x tail %08x start %08x\n, @@ -491,7 +494,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_READ_TAIL(ring), I915_READ_START(ring)); - if (!stop_ring(ring)) { + if (!__intel_stop_ring_buffer(ring)) { DRM_ERROR(failed to set %s head to zero ctl %08x head %08x tail %08x start %08x\n, ring-name, @@ -2338,5 +2341,5 @@ intel_stop_ring_buffer(struct intel_ring_buffer *ring) DRM_ERROR(failed to quiesce %s whilst cleaning up: %d\n, ring-name, ret); - stop_ring(ring); + __intel_stop_ring_buffer(ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 13e398f17fb2..f3c25bd5c68d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -266,6 +266,7 @@ intel_write_status_page(struct intel_ring_buffer *ring, #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX MI_STORE_DWORD_INDEX_SHIFT) void intel_stop_ring_buffer(struct intel_ring_buffer *ring); +bool __intel_stop_ring_buffer(struct intel_ring_buffer *ring); void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 76dc185793ce..18d41d04cbd8 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1034,6 +1034,13 @@ static int gen6_do_reset(struct drm_device *dev) int intel_gpu_reset(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ring_buffer *ring; + int i; + + for_each_ring(ring, dev_priv, i) + __intel_stop_ring_buffer(ring); + switch (INTEL_INFO(dev)-gen) { case 8: case 7: -- 1.8.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Try to stop rings before reset
On Tue, Apr 29, 2014 at 4:38 PM, Daniel Vetter daniel.vet...@ffwll.ch wrote: This seems to make the hard machine hangs provoked by running gem_reset_stats tests a lot less likely. At least on my snb here. v2: Don't DRM_ERROR when a reset is in progress in the stop_ring function. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74100 Cc: Mika Kuoppala mika.kuopp...@linux.intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch A bit a terse commit message ... The theory that lead me to this patch is that these hard hangs only started to show up with the endless batch chaining that gem_reset_stats does. All previous gpu reset testcase we have essentially reset the gpu while it is completely idle. If figured that trying to idle it first (by stopping the CS) can't hurt, and indeed it seems to help a lot. -Daniel --- drivers/gpu/drm/i915/intel_ringbuffer.c | 13 - drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + drivers/gpu/drm/i915/intel_uncore.c | 7 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ab22d70733bf..e8ca1dcb6a45 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -448,14 +448,17 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) I915_WRITE(HWS_PGA, addr); } -static bool stop_ring(struct intel_ring_buffer *ring) +bool __intel_stop_ring_buffer(struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = to_i915(ring-dev); if (!IS_GEN2(ring-dev)) { I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); if (wait_for_atomic((I915_READ_MODE(ring) MODE_IDLE) != 0, 1000)) { - DRM_ERROR(%s :timed out trying to stop ring\n, ring-name); + if (!i915_reset_in_progress(dev_priv-gpu_error)) { + DRM_ERROR(%s :timed out trying to stop ring\n, + ring-name); + } return false; } } @@ -481,7 +484,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); - if (!stop_ring(ring)) { + if (!__intel_stop_ring_buffer(ring)) { /* G45 ring initialization often fails to reset head to zero */ DRM_DEBUG_KMS(%s head not reset to zero ctl %08x head %08x tail %08x start %08x\n, @@ -491,7 +494,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_READ_TAIL(ring), I915_READ_START(ring)); - if (!stop_ring(ring)) { + if (!__intel_stop_ring_buffer(ring)) { DRM_ERROR(failed to set %s head to zero ctl %08x head %08x tail %08x start %08x\n, ring-name, @@ -2338,5 +2341,5 @@ intel_stop_ring_buffer(struct intel_ring_buffer *ring) DRM_ERROR(failed to quiesce %s whilst cleaning up: %d\n, ring-name, ret); - stop_ring(ring); + __intel_stop_ring_buffer(ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 13e398f17fb2..f3c25bd5c68d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -266,6 +266,7 @@ intel_write_status_page(struct intel_ring_buffer *ring, #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX MI_STORE_DWORD_INDEX_SHIFT) void intel_stop_ring_buffer(struct intel_ring_buffer *ring); +bool __intel_stop_ring_buffer(struct intel_ring_buffer *ring); void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 76dc185793ce..18d41d04cbd8 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1034,6 +1034,13 @@ static int gen6_do_reset(struct drm_device *dev) int intel_gpu_reset(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ring_buffer *ring; + int i; + + for_each_ring(ring, dev_priv, i) + __intel_stop_ring_buffer(ring); + switch (INTEL_INFO(dev)-gen) { case 8: case 7: -- 1.8.1.4 -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH for stable 3.14 only 1/1] drm/i915: restore QUIRK_NO_PCH_PWM_ENABLE
On Mon, 2014-04-28 at 13:10 +0300, Jani Nikula wrote: This reverts the bisected regressing commit bc0bb9fd1c7810407ab810d204bbaecb255fddde Author: Jani Nikula jani.nik...@intel.com Date: Thu Nov 14 12:14:29 2013 +0200 drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE restoring QUIRK_NO_PCH_PWM_ENABLE for a couple of Dell XPS models which broke in 3.14. Confirmed: This patch (restore QUIRK_NO_PCH_PWM_ENABLE) on top of 3.14.2 does fix it again for the two affected models. Tested-by: Kamal Mostafa ka...@canonical.com Thanks, Jani! -Kamal There is no such revert upstream. We have root caused and fixed the issue upstream, without the quirk, with: commit 39fbc9c8f6765959b55e0b127dd5c57df5a47d67 Author: Jani Nikula jani.nik...@intel.com Date: Wed Apr 9 11:22:06 2014 +0300 drm/i915: check VBT for supported backlight type and commit c675949ec58ca50d5a3ae3c757892f1560f6e896 Author: Jani Nikula jani.nik...@intel.com Date: Wed Apr 9 11:31:37 2014 +0300 drm/i915: do not setup backlight if not available according to VBT While the commits are within the stable rules otherwise, and fix more machines than just the regressed Dell XPS models, we feel backporting them to stable may be too risky. The revert is limited to the broken machines, and the impact should be effectively the same as what the upstream commits do more generally. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76276 Reported-by: Romain Francoise rom...@orebokech.com CC: Kamal Mostafa ka...@canonical.com CC: Daniel Vetter dan...@ffwll.ch CC: sta...@vger.kernel.org (3.14 only) Signed-off-by: Jani Nikula jani.nik...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 16 drivers/gpu/drm/i915/intel_panel.c | 4 3 files changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index df77e20e3c3d..697f2150a997 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -734,6 +734,7 @@ enum intel_sbi_destination { #define QUIRK_PIPEA_FORCE (10) #define QUIRK_LVDS_SSC_DISABLE (11) #define QUIRK_INVERT_BRIGHTNESS (12) +#define QUIRK_NO_PCH_PWM_ENABLE (13) struct intel_fbdev; struct intel_fbc_work; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9b8a7c7ea7fc..963639d9049b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10771,6 +10771,17 @@ static void quirk_invert_brightness(struct drm_device *dev) DRM_INFO(applying inverted panel brightness quirk\n); } +/* + * Some machines (Dell XPS13) suffer broken backlight controls if + * BLM_PCH_PWM_ENABLE is set. + */ +static void quirk_no_pcm_pwm_enable(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + dev_priv-quirks |= QUIRK_NO_PCH_PWM_ENABLE; + DRM_INFO(applying no-PCH_PWM_ENABLE quirk\n); +} + struct intel_quirk { int device; int subsystem_vendor; @@ -10839,6 +10850,11 @@ static struct intel_quirk intel_quirks[] = { /* Acer Aspire 4736Z */ { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, + + /* Dell XPS13 HD Sandy Bridge */ + { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, + /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */ + { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable }, }; static void intel_init_quirks(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 079ea38f14d9..9f1d7a9300e8 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -671,6 +671,10 @@ static void pch_enable_backlight(struct intel_connector *connector) pch_ctl2 = panel-backlight.max 16; I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); + /* XXX: transitional */ + if (dev_priv-quirks QUIRK_NO_PCH_PWM_ENABLE) + return; + pch_ctl1 = 0; if (panel-backlight.active_low_pwm) pch_ctl1 |= BLM_PCH_POLARITY; signature.asc Description: This is a digitally signed message part ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Try to stop rings before reset
On Tue, Apr 29, 2014 at 6:07 PM, Daniel Vetter daniel.vet...@ffwll.ch wrote: On Tue, Apr 29, 2014 at 4:38 PM, Daniel Vetter daniel.vet...@ffwll.ch wrote: This seems to make the hard machine hangs provoked by running gem_reset_stats tests a lot less likely. At least on my snb here. v2: Don't DRM_ERROR when a reset is in progress in the stop_ring function. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74100 Cc: Mika Kuoppala mika.kuopp...@linux.intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch A bit a terse commit message ... The theory that lead me to this patch is that these hard hangs only started to show up with the endless batch chaining that gem_reset_stats does. All previous gpu reset testcase we have essentially reset the gpu while it is completely idle. If figured that trying to idle it first (by stopping the CS) can't hurt, and indeed it seems to help a lot. Aside: This now survived about half a day of running piglit -t gem_reset_stats in a loop (since just running gem_reset_stats doesn't run the gpu_quiescent before/after each subtest using piglit is much more hang-happy). Didn't hang after 70+ loops, so seems really solid here. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 21/71] drm/i915/chv: Add update and enable pll for Cherryview
On Wed, 2014-04-09 at 13:28 +0300, ville.syrj...@linux.intel.com wrote: From: Chon Ming Lee chon.ming@intel.com Added programming PLL for CHV based on Application note for 1273 CHV Display phy. v2: -Break the common lane reset into another patch. -Break the clock calculation into another patch. -The changes are based on Ville review. -Rework based on DPIO register define naming convention change. -Break the dpio write into few lines to improve readability. -Correct the udelay during chv_enable_pll. -clean up some magic numbers with some new define. -program the afc recal bit which was missed. v3: Based on Ville review - minor correction of the bit defination - add deassert/propagate data lane reset v4: Corrected the udelay between dclkp enable and pll enable. Minor comment and better way to clear the TX lane reset. v5: Squash in fixup from Rafael Barbalho. Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com Signed-off-by: Chon Ming Lee chon.ming@intel.com A couple of nitpicks below, fixing any/all of those is optional. This patch is Reviewed-by: Imre Deak imre.d...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 70 ++ drivers/gpu/drm/i915/intel_display.c | 133 ++- 2 files changed, 201 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8fcf4ea..75f31f5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -668,6 +668,12 @@ enum punit_power_well { #define _VLV_PCS_DW9_CH1 0x8424 #define VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1) +#define _CHV_PCS_DW10_CH00x8228 +#define _CHV_PCS_DW10_CH10x8428 Note that these are atm unused (the code uses instead the single addressing versions), although these group addressing versions could be used too. +#define DPIO_PCS_SWING_CALC_TX0_TX2(130) +#define DPIO_PCS_SWING_CALC_TX1_TX3(131) +#define CHV_PCS_DW10(ch) _PORT(ch, _CHV_PCS_DW10_CH0, _CHV_PCS_DW10_CH1) + #define _VLV_PCS_DW11_CH00x822c #define _VLV_PCS_DW11_CH10x842c #define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1) @@ -686,14 +692,21 @@ enum punit_power_well { #define _VLV_TX_DW2_CH0 0x8288 #define _VLV_TX_DW2_CH1 0x8488 +#define DPIO_UNIQ_TRANS_SCALE_SHIFT8 +#define DPIO_SWING_MARGIN_SHIFT16 +#define DPIO_SWING_MARGIN_MASK (0xff DPIO_SWING_MARGIN_SHIFT) #define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1) #define _VLV_TX_DW3_CH0 0x828c #define _VLV_TX_DW3_CH1 0x848c +/* The following bit for CHV phy */ +#define DPIO_TX_UNIQ_TRANS_SCALE_EN(127) #define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1) #define _VLV_TX_DW4_CH0 0x8290 #define _VLV_TX_DW4_CH1 0x8490 +#define DPIO_SWING_DEEMPH9P5_SHIFT 24 +#define DPIO_SWING_DEEMPH9P5_MASK (0xff DPIO_SWING_DEEMPH9P5_SHIFT) #define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1) #define _VLV_TX3_DW4_CH0 0x690 @@ -713,6 +726,62 @@ enum punit_power_well { #define _VLV_TX_DW14_CH1 0x84b8 #define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1) +/* CHV dpPhy registers */ +#define _CHV_PLL_DW0_CH0 0x8000 +#define _CHV_PLL_DW0_CH1 0x8180 +#define CHV_PLL_DW0(ch) _PIPE(ch, _CHV_PLL_DW0_CH0, _CHV_PLL_DW0_CH1) + +#define _CHV_PLL_DW1_CH0 0x8004 +#define _CHV_PLL_DW1_CH1 0x8184 +#define DPIO_CHV_M1_DIV_BY_2 (0 0) +#define DPIO_CHV_N_DIV_SHIFT (8) Here and below for simple constants, no need for the (). +#define CHV_PLL_DW1(ch) _PIPE(ch, _CHV_PLL_DW1_CH0, _CHV_PLL_DW1_CH1) + +#define _CHV_PLL_DW2_CH0 0x8008 +#define _CHV_PLL_DW2_CH1 0x8188 +#define CHV_PLL_DW2(ch) _PIPE(ch, _CHV_PLL_DW2_CH0, _CHV_PLL_DW2_CH1) + +#define _CHV_PLL_DW3_CH0 0x800c +#define _CHV_PLL_DW3_CH1 0x818c +#define DPIO_CHV_FEEDFWD_GAIN 2 +#define DPIO_CHV_FIRST_MOD (0 8) +#define DPIO_CHV_SECOND_MOD (1 8) +#define DPIO_CHV_FRAC_DIV_EN(1 16) +#define CHV_PLL_DW3(ch) _PIPE(ch, _CHV_PLL_DW3_CH0, _CHV_PLL_DW3_CH1) + +#define _CHV_PLL_DW6_CH0 0x8018 +#define _CHV_PLL_DW6_CH1 0x8198 +#define DPIO_CHV_PROP_COEFF(5 0) +#define DPIO_CHV_GAIN_CTRL (2 16) These macros combine the field shift and field value, for consistency I'd define here only the field shift and use the field value inlined in the code. +#defineDPIO_CHV_INT_COEFF_SHIFT 8 +#define CHV_PLL_DW6(ch)
[Intel-gfx] [RFC PATCH 1/2] drm/i915: shuffle panel code
Somehow a few functions have been dropped in the middle of backlight code. Move them around. No functional changes. Signed-off-by: Jani Nikula jani.nik...@intel.com --- drivers/gpu/drm/i915/intel_panel.c | 150 ++--- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 44ad415e3706..776249bab488 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -42,6 +42,59 @@ intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, drm_mode_set_crtcinfo(adjusted_mode, 0); } +/** + * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID + * @dev: drm device + * @fixed_mode : panel native mode + * @connector: LVDS/eDP connector + * + * Return downclock_avail + * Find the reduced downclock for LVDS/eDP in EDID. + */ +struct drm_display_mode * +intel_find_panel_downclock(struct drm_device *dev, + struct drm_display_mode *fixed_mode, + struct drm_connector *connector) +{ + struct drm_display_mode *scan, *tmp_mode; + int temp_downclock; + + temp_downclock = fixed_mode-clock; + tmp_mode = NULL; + + list_for_each_entry(scan, connector-probed_modes, head) { + /* +* If one mode has the same resolution with the fixed_panel +* mode while they have the different refresh rate, it means +* that the reduced downclock is found. In such +* case we can set the different FPx0/1 to dynamically select +* between low and high frequency. +*/ + if (scan-hdisplay == fixed_mode-hdisplay + scan-hsync_start == fixed_mode-hsync_start + scan-hsync_end == fixed_mode-hsync_end + scan-htotal == fixed_mode-htotal + scan-vdisplay == fixed_mode-vdisplay + scan-vsync_start == fixed_mode-vsync_start + scan-vsync_end == fixed_mode-vsync_end + scan-vtotal == fixed_mode-vtotal) { + if (scan-clock temp_downclock) { + /* +* The downclock is already found. But we +* expect to find the lower downclock. +*/ + temp_downclock = scan-clock; + tmp_mode = scan; + } + } + } + + if (temp_downclock fixed_mode-clock) + return drm_mode_duplicate(dev, tmp_mode); + else + return NULL; +} + /* adjusted_mode has been preset to be the panel's fixed mode */ void intel_pch_panel_fitting(struct intel_crtc *intel_crtc, @@ -323,6 +376,28 @@ out: pipe_config-gmch_pfit.lvds_border_bits = border; } +enum drm_connector_status +intel_panel_detect(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + /* Assume that the BIOS does not lie through the OpRegion... */ + if (!i915.panel_ignore_lid dev_priv-opregion.lid_state) { + return ioread32(dev_priv-opregion.lid_state) 0x1 ? + connector_status_connected : + connector_status_disconnected; + } + + switch (i915.panel_ignore_lid) { + case -2: + return connector_status_connected; + case -1: + return connector_status_disconnected; + default: + return connector_status_unknown; + } +} + static u32 intel_panel_compute_brightness(struct intel_connector *connector, u32 val) { @@ -795,28 +870,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector) spin_unlock_irqrestore(dev_priv-backlight_lock, flags); } -enum drm_connector_status -intel_panel_detect(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev-dev_private; - - /* Assume that the BIOS does not lie through the OpRegion... */ - if (!i915.panel_ignore_lid dev_priv-opregion.lid_state) { - return ioread32(dev_priv-opregion.lid_state) 0x1 ? - connector_status_connected : - connector_status_disconnected; - } - - switch (i915.panel_ignore_lid) { - case -2: - return connector_status_connected; - case -1: - return connector_status_disconnected; - default: - return connector_status_unknown; - } -} - #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) static int intel_backlight_device_update_status(struct backlight_device *bd) { @@ -1103,59 +1156,6 @@ void intel_panel_destroy_backlight(struct drm_connector *connector)
[Intel-gfx] [RFC PATCH 2/2] drm/i915: respect the VBT minimum backlight brightness
Historically we've exposed the full backlight PWM duty cycle range to the userspace, in the name of mechanism, not policy. However, it turns out there are both panels and board designs where there is a minimum duty cycle that is required for proper operation. The minimum duty cycle is available in the VBT. The backlight class sysfs interface does not make any promises to the userspace about the physical meaning of the range 0..max_brightness. Specifically there is no guarantee that 0 means off; indeed for acpi_backlight 0 usually is not off, but the minimum acceptable value. Respect the minimum backlight, and expose the range acceptable to the hardware as 0..max_brightness to the userspace via the backlight class device; 0 means the minimum acceptable enabled value. To switch off the backlight, the user must disable the encoder. As a side effect, make the backlight class device max brightness and physical PWM modulation frequency (i.e. max duty cycle) independent. Signed-off-by: Jani Nikula jani.nik...@intel.com --- UNTESTED! --- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/intel_bios.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_panel.c | 97 +++--- 4 files changed, 85 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 50dfc3a1a9d1..d9dad3498b87 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1164,6 +1164,7 @@ struct intel_vbt_data { u16 pwm_freq_hz; bool present; bool active_low_pwm; + u8 min_brightness; /* min_brightness/255 of max */ } backlight; /* MIPI DSI */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2945f57c53ee..1a3e172029b3 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -339,11 +339,12 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) dev_priv-vbt.backlight.pwm_freq_hz = entry-pwm_freq_hz; dev_priv-vbt.backlight.active_low_pwm = entry-active_low_pwm; + dev_priv-vbt.backlight.min_brightness = entry-min_brightness; DRM_DEBUG_KMS(VBT backlight PWM modulation frequency %u Hz, active %s, min brightness %u, level %u\n, dev_priv-vbt.backlight.pwm_freq_hz, dev_priv-vbt.backlight.active_low_pwm ? low : high, - entry-min_brightness, + dev_priv-vbt.backlight.min_brightness, backlight_data-level[panel_type]); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d8b540b891d1..2af74dd03e31 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -165,6 +165,7 @@ struct intel_panel { struct { bool present; u32 level; + u32 min; u32 max; bool enabled; bool combination_mode; /* gen 2/4 only */ diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 776249bab488..360ae203aacb 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -398,6 +398,30 @@ intel_panel_detect(struct drm_device *dev) } } +/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ +static u32 scale_user_to_hw(struct intel_connector *connector, + u32 user_level, u32 user_max) +{ + struct intel_panel *panel = connector-panel; + + user_level = clamp(user_level, 0U, user_max); + + return panel-backlight.min + user_level * + (panel-backlight.max - panel-backlight.min) / user_max; +} + +/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ +static u32 scale_hw_to_user(struct intel_connector *connector, + u32 hw_level, u32 user_max) +{ + struct intel_panel *panel = connector-panel; + + hw_level = clamp(hw_level, panel-backlight.min, panel-backlight.max); + + return (hw_level - panel-backlight.min) * user_max / + (panel-backlight.max - panel-backlight.min); +} + static u32 intel_panel_compute_brightness(struct intel_connector *connector, u32 val) { @@ -558,14 +582,14 @@ intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) } /* set backlight brightness to level in range [0..max] */ -void intel_panel_set_backlight(struct intel_connector *connector, u32 level, - u32 max) +void intel_panel_set_backlight(struct intel_connector *connector, + u32 user_level, u32 user_max) { struct drm_device *dev = connector-base.dev; struct drm_i915_private *dev_priv =
Re: [Intel-gfx] [RFC PATCH 2/2] drm/i915: respect the VBT minimum backlight brightness
On Tue, 29 Apr 2014, Jani Nikula jani.nik...@intel.com wrote: Historically we've exposed the full backlight PWM duty cycle range to the userspace, in the name of mechanism, not policy. However, it turns out there are both panels and board designs where there is a minimum duty cycle that is required for proper operation. The minimum duty cycle is available in the VBT. The backlight class sysfs interface does not make any promises to the userspace about the physical meaning of the range 0..max_brightness. Specifically there is no guarantee that 0 means off; indeed for acpi_backlight 0 usually is not off, but the minimum acceptable value. Respect the minimum backlight, and expose the range acceptable to the hardware as 0..max_brightness to the userspace via the backlight class device; 0 means the minimum acceptable enabled value. To switch off the backlight, the user must disable the encoder. As a side effect, make the backlight class device max brightness and physical PWM modulation frequency (i.e. max duty cycle) independent. Signed-off-by: Jani Nikula jani.nik...@intel.com Acknowledgement that I meant to include: this is based on both Jesse's and Ben's earlier work. --- UNTESTED! --- drivers/gpu/drm/i915/i915_drv.h| 1 + drivers/gpu/drm/i915/intel_bios.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_panel.c | 97 +++--- 4 files changed, 85 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 50dfc3a1a9d1..d9dad3498b87 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1164,6 +1164,7 @@ struct intel_vbt_data { u16 pwm_freq_hz; bool present; bool active_low_pwm; + u8 min_brightness; /* min_brightness/255 of max */ } backlight; /* MIPI DSI */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2945f57c53ee..1a3e172029b3 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -339,11 +339,12 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) dev_priv-vbt.backlight.pwm_freq_hz = entry-pwm_freq_hz; dev_priv-vbt.backlight.active_low_pwm = entry-active_low_pwm; + dev_priv-vbt.backlight.min_brightness = entry-min_brightness; DRM_DEBUG_KMS(VBT backlight PWM modulation frequency %u Hz, active %s, min brightness %u, level %u\n, dev_priv-vbt.backlight.pwm_freq_hz, dev_priv-vbt.backlight.active_low_pwm ? low : high, - entry-min_brightness, + dev_priv-vbt.backlight.min_brightness, backlight_data-level[panel_type]); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d8b540b891d1..2af74dd03e31 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -165,6 +165,7 @@ struct intel_panel { struct { bool present; u32 level; + u32 min; u32 max; bool enabled; bool combination_mode; /* gen 2/4 only */ diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 776249bab488..360ae203aacb 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -398,6 +398,30 @@ intel_panel_detect(struct drm_device *dev) } } +/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ +static u32 scale_user_to_hw(struct intel_connector *connector, + u32 user_level, u32 user_max) +{ + struct intel_panel *panel = connector-panel; + + user_level = clamp(user_level, 0U, user_max); + + return panel-backlight.min + user_level * + (panel-backlight.max - panel-backlight.min) / user_max; +} + +/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ +static u32 scale_hw_to_user(struct intel_connector *connector, + u32 hw_level, u32 user_max) +{ + struct intel_panel *panel = connector-panel; + + hw_level = clamp(hw_level, panel-backlight.min, panel-backlight.max); + + return (hw_level - panel-backlight.min) * user_max / + (panel-backlight.max - panel-backlight.min); +} + static u32 intel_panel_compute_brightness(struct intel_connector *connector, u32 val) { @@ -558,14 +582,14 @@ intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) } /* set backlight brightness to level in range [0..max] */ -void intel_panel_set_backlight(struct intel_connector *connector, u32 level, -u32 max) +void
Re: [Intel-gfx] [PATCH] drm/i915: don't try DP_LINK_BW_5_4 on HSW ULX
On 30 April 2014 00:00, Paulo Zanoni przan...@gmail.com wrote: From: Paulo Zanoni paulo.r.zan...@intel.com Because the docs say ULX doesn't support it on HSW. i read the exact same thing, Reviewed-by: Dave Airlie airl...@redhat.com Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_dp.c | 3 ++- include/drm/i915_pciids.h | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) This patch is completely untested!!! diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e81feab..bdc612c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1816,6 +1816,9 @@ struct drm_i915_cmd_table { #define IS_ULT(dev)(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) #define IS_HSW_GT3(dev)(IS_HASWELL(dev) \ ((dev)-pdev-device 0x00F0) == 0x0020) +/* ULX machines are also considered ULT. */ +#define IS_HSW_ULX(dev)((dev)-pdev-device == 0x0A0E || \ +(dev)-pdev-device == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)-is_preliminary) /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 34ed143..87b0a51 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) case DP_LINK_BW_2_7: break; case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ - if ((IS_HASWELL(dev) || INTEL_INFO(dev)-gen = 8) + if (((IS_HASWELL(dev) !IS_HSW_ULX(dev)) || +INTEL_INFO(dev)-gen = 8) intel_dp-dpcd[DP_DPCD_REV] = 0x12) max_link_bw = DP_LINK_BW_5_4; else diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 24f3cad..5cd9165 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -191,8 +191,8 @@ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0A0E, info), /* ULT GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0A1E, info), /* ULT GT2 reserved */ \ + INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \ + INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 10/13] drm/i915/bdw: collect semaphore error state
On Mon, Feb 24, 2014 at 03:08:04PM +0200, Ville Syrjälä wrote: On Wed, Feb 19, 2014 at 10:19:23PM -0800, Ben Widawsky wrote: Since the semaphore information is in an object, just dump it, and let the user parse it later. NOTE: The page being used for the semaphores are incoherent with the CPU. No matter what I do, I cannot figure out a way to read anything but 0s. Note that the semaphore waits are indeed working. v2: Don't print signal, and wait (they should be the same). Instead, print sync_seqno (Chris) v3: Free the semaphore error object (Chris) v4: Fix semaphore offset calculation during error state collection (Ville) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gpu_error.c | 52 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 12 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 028ce5a..9b86874 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -322,6 +322,7 @@ struct drm_i915_error_state { u64 fence[I915_MAX_NUM_FENCES]; struct intel_overlay_error_state *overlay; struct intel_display_error_state *display; + struct drm_i915_error_object *semaphore_obj; struct drm_i915_error_ring { bool valid; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2b64493..25fc2ea 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -310,6 +310,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, struct drm_device *dev = error_priv-dev; drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_error_state *error = error_priv-error; + struct drm_i915_error_object *obj; int i, j, page, offset, elt; if (!error) { @@ -360,8 +361,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, error-pinned_bo_count[0]); for (i = 0; i ARRAY_SIZE(error-ring); i++) { - struct drm_i915_error_object *obj; - if ((obj = error-ring[i].batchbuffer)) { err_printf(m, %s --- gtt_offset = 0x%08x\n, dev_priv-ring[i].name, @@ -436,6 +435,19 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, } } + obj = error-semaphore_obj; + if (obj) { Still won't pass under Chris's consitency radar. + err_printf(m, Semaphore page = 0x%08x\n, obj-gtt_offset); + for (elt = 0; elt PAGE_SIZE/16; elt += 4) { + err_printf(m, [%04x] %08x %08x %08x %08x\n, + elt * 4, + obj-pages[0][elt], + obj-pages[0][elt+1], + obj-pages[0][elt+2], + obj-pages[0][elt+3]); + } + } + if (error-overlay) intel_overlay_print_error_state(m, error-overlay); @@ -506,6 +518,7 @@ static void i915_error_state_free(struct kref *error_ref) kfree(error-ring[i].requests); } + i915_error_object_free(error-semaphore_obj); kfree(error-active_bo); kfree(error-overlay); kfree(error-display); @@ -797,6 +810,33 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, return NULL; } +static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, + struct drm_i915_error_state *error, + struct intel_ring_buffer *ring, + struct drm_i915_error_ring *ering) +{ + struct intel_ring_buffer *useless; + int i; + + if (!i915_semaphore_is_enabled(dev_priv-dev)) + return; + + if (!error-semaphore_obj) + error-semaphore_obj = + i915_error_object_create(dev_priv, +dev_priv-semaphore_obj, +dev_priv-gtt.base); + + for_each_ring(useless, dev_priv, i) { + u16 signal_offset = + (GEN8_SIGNAL_OFFSET(ring, i) / 4) PAGE_MASK; (... PAGE_MASK) / 4; Nice catch. + u32 *tmp = error-semaphore_obj-pages[0]; + + ering-semaphore_mboxes[i] = tmp[signal_offset]; + ering-semaphore_seqno[i] = ring-semaphore.sync_seqno[i]; + } +} + static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, struct intel_ring_buffer *ring, struct drm_i915_error_ring *ering) @@
[Intel-gfx] [PATCH 12/13] drm/i915: semaphore debugfs
Simple debugfs file to display the current state of semaphores. This is useful if you want to see the state without hanging the GPU. NOTE: This patch is optional to the series. NOTE2: Like the GPU error state collection, the reads are currently incoherent. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c | 70 + 1 file changed, 70 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index cad175c..0e02901 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2332,6 +2332,75 @@ static int i915_display_info(struct seq_file *m, void *unused) return 0; } +static int i915_semaphore_status(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m-private; + struct drm_device *dev = node-minor-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ring_buffer *ring; + int i, j, ret; + + if (!i915_semaphore_is_enabled(dev)) { + seq_puts(m, Semaphores are disabled\n); + return 0; + } + + ret = mutex_lock_interruptible(dev-struct_mutex); + if (ret) + return ret; + + if (IS_BROADWELL(dev)) { + struct page *page; + uint64_t *seqno; + + page = i915_gem_object_get_page(dev_priv-semaphore_obj, 0); + + seqno = (uint64_t *)kmap_atomic(page); + for_each_ring(ring, dev_priv, i) { + uint64_t offset; + + seq_printf(m, %s\n, ring-name); + + seq_puts(m, Last signal:); + for (j = 0; j I915_NUM_RINGS; j++) { + offset = i * I915_NUM_RINGS + j; + seq_printf(m, 0x%08llx (0x%02llx) , + seqno[offset], offset * 8); + } + seq_putc(m, '\n'); + + seq_puts(m, Last wait: ); + for (j = 0; j I915_NUM_RINGS; j++) { + offset = i + (j * I915_NUM_RINGS); + seq_printf(m, 0x%08llx (0x%02llx) , + seqno[offset], offset * 8); + } + seq_putc(m, '\n'); + + } + kunmap_atomic(seqno); + } else { + seq_puts(m, Last signal:); + for_each_ring(ring, dev_priv, i) + for (j = 0; j I915_NUM_RINGS; j++) + seq_printf(m, 0x%08x\n, + I915_READ(ring-semaphore.mbox.signal[j])); + seq_putc(m, '\n'); + } + + seq_puts(m, \nSync seqno:\n); + for_each_ring(ring, dev_priv, i) { + for (j = 0; j I915_NUM_RINGS; j++) { + seq_printf(m, 0x%08x , ring-semaphore.sync_seqno[j]); + } + seq_putc(m, '\n'); + } + seq_putc(m, '\n'); + + mutex_unlock(dev-struct_mutex); + return 0; +} + struct pipe_crc_info { const char *name; struct drm_device *dev; @@ -3778,6 +3847,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {i915_pc8_status, i915_pc8_status, 0}, {i915_power_domain_info, i915_power_domain_info, 0}, {i915_display_info, i915_display_info, 0}, + {i915_semaphore_status, i915_semaphore_status, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/13] DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores
This appears to not actually be needed on the current code. Just putting it on the ML so we can point bug reports at it later. As pointed out by Ville, the current code is broken since we do FORCE_RESTORE, and RESTORE_INHIBIT on the same dword. Anecdotally, this seems fine. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem_context.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index f77b4c1..aa82fb4 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -661,6 +661,13 @@ static int do_switch(struct intel_ring_buffer *ring, if (!to-is_initialized || i915_gem_context_is_default(to)) hw_flags |= MI_RESTORE_INHIBIT; + /* When SW intends to use semaphore signaling between Command streamers, +* it must avoid lite restores in HW by programming Force Restore bit +* to ‘1’ in context descriptor during context submission +*/ + if (IS_GEN8(ring-dev) i915_semaphore_is_enabled(ring-dev)) + hw_flags |= MI_FORCE_RESTORE; + ret = mi_set_context(ring, to, hw_flags); if (ret) goto unpin_out; -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/13] drm/i915/bdw: implement semaphore wait
Semaphore waits use a new instruction, MI_SEMAPHORE_WAIT. The seqno to wait on is all well defined by the table in the previous patch. There is nothing else different from previous GEN's semaphore synchronization code. v2: Update macros to not require the other ring's ring-id (Chris) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 33 + drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8e6ec03..712ae05 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -257,6 +257,9 @@ #define MI_RESTORE_INHIBIT (10) #define MI_SEMAPHORE_SIGNALMI_INSTR(0x1b, 0) /* GEN8+ */ #define MI_SEMAPHORE_TARGET(engine) ((engine)15) +#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */ +#define MI_SEMAPHORE_POLL(115) +#define MI_SEMAPHORE_SAD_GTE_SDD (112) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 03324b2..31b1f3c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -827,6 +827,31 @@ static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev, * @signaller - ring which has, or will signal * @seqno - seqno which the waiter will block on */ + +static int +gen8_ring_sync(struct intel_ring_buffer *waiter, + struct intel_ring_buffer *signaller, + u32 seqno) +{ + struct drm_i915_private *dev_priv = waiter-dev-dev_private; + int ret; + + ret = intel_ring_begin(waiter, 4); + if (ret) + return ret; + + intel_ring_emit(waiter, MI_SEMAPHORE_WAIT | + MI_SEMAPHORE_GLOBAL_GTT | + MI_SEMAPHORE_SAD_GTE_SDD); + intel_ring_emit(waiter, seqno); + intel_ring_emit(waiter, + lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller-id))); + intel_ring_emit(waiter, + upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller-id))); + intel_ring_advance(waiter); + return 0; +} + static int gen6_ring_sync(struct intel_ring_buffer *waiter, struct intel_ring_buffer *signaller, @@ -2023,7 +2048,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring-set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev)) { BUG_ON(!dev_priv-semaphore_obj); - ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.sync_to = gen8_ring_sync; ring-semaphore.signal = gen8_rcs_signal; GEN8_RING_SEMAPHORE_INIT; } @@ -2217,7 +2242,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) ring-dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.sync_to = gen8_ring_sync; ring-semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; } @@ -2337,7 +2362,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) ring-irq_put = gen8_ring_put_irq; ring-dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.sync_to = gen8_ring_sync; ring-semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; } @@ -2395,7 +2420,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) ring-irq_put = gen8_ring_put_irq; ring-dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev)) { - ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.sync_to = gen8_ring_sync; ring-semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d7de09b..a7ff166 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -45,10 +45,10 @@ struct intel_hw_status_page { (ring-id * I915_NUM_RINGS *
[Intel-gfx] [PATCH 10/13] drm/i915: Extract semaphore error collection
Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gpu_error.c | 30 ++ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2d81985..a7eaab2 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -744,6 +744,23 @@ static void i915_gem_record_fences(struct drm_device *dev, } } + +static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring, + struct drm_i915_error_ring *ering) +{ + ering-semaphore_mboxes[0] = I915_READ(RING_SYNC_0(ring-mmio_base)); + ering-semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring-mmio_base)); + ering-semaphore_seqno[0] = ring-semaphore.sync_seqno[0]; + ering-semaphore_seqno[1] = ring-semaphore.sync_seqno[1]; + + if (HAS_VEBOX(dev_priv-dev)) { + ering-semaphore_mboxes[2] = + I915_READ(RING_SYNC_2(ring-mmio_base)); + ering-semaphore_seqno[2] = ring-semaphore.sync_seqno[2]; + } +} + static void i915_record_ring_state(struct drm_device *dev, struct intel_ring_buffer *ring, struct drm_i915_error_ring *ering) @@ -753,18 +770,7 @@ static void i915_record_ring_state(struct drm_device *dev, if (INTEL_INFO(dev)-gen = 6) { ering-rc_psmi = I915_READ(ring-mmio_base + 0x50); ering-fault_reg = I915_READ(RING_FAULT_REG(ring)); - ering-semaphore_mboxes[0] - = I915_READ(RING_SYNC_0(ring-mmio_base)); - ering-semaphore_mboxes[1] - = I915_READ(RING_SYNC_1(ring-mmio_base)); - ering-semaphore_seqno[0] = ring-semaphore.sync_seqno[0]; - ering-semaphore_seqno[1] = ring-semaphore.sync_seqno[1]; - } - - if (HAS_VEBOX(dev)) { - ering-semaphore_mboxes[2] = - I915_READ(RING_SYNC_2(ring-mmio_base)); - ering-semaphore_seqno[2] = ring-semaphore.sync_seqno[2]; + gen6_record_semaphore_state(dev_priv, ring, ering); } if (INTEL_INFO(dev)-gen = 4) { -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/13] drm/i915/bdw: collect semaphore error state
Since the semaphore information is in an object, just dump it, and let the user parse it later. NOTE: The page being used for the semaphores are incoherent with the CPU. No matter what I do, I cannot figure out a way to read anything but 0s. Note that the semaphore waits are indeed working. v2: Don't print signal, and wait (they should be the same). Instead, print sync_seqno (Chris) v3: Free the semaphore error object (Chris) v4: Fix semaphore offset calculation during error state collection (Ville) v5: VCS2 rebase Make semaphore object error capture coding style consistent (Ville) Do the proper math for the signal offset (Ville) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gpu_error.c | 51 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 14 - 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 44cb744..237faf3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -328,6 +328,7 @@ struct drm_i915_error_state { u64 fence[I915_MAX_NUM_FENCES]; struct intel_overlay_error_state *overlay; struct intel_display_error_state *display; + struct drm_i915_error_object *semaphore_obj; struct drm_i915_error_ring { bool valid; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a7eaab2..50d2af8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -326,6 +326,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, struct drm_device *dev = error_priv-dev; struct drm_i915_private *dev_priv = dev-dev_private; struct drm_i915_error_state *error = error_priv-error; + struct drm_i915_error_object *obj; int i, j, offset, elt; int max_hangcheck_score; @@ -394,8 +395,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, error-pinned_bo_count[0]); for (i = 0; i ARRAY_SIZE(error-ring); i++) { - struct drm_i915_error_object *obj; - obj = error-ring[i].batchbuffer; if (obj) { err_puts(m, dev_priv-ring[i].name); @@ -458,6 +457,18 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, } } + if ((obj = error-semaphore_obj)) { + err_printf(m, Semaphore page = 0x%08x\n, obj-gtt_offset); + for (elt = 0; elt PAGE_SIZE/16; elt += 4) { + err_printf(m, [%04x] %08x %08x %08x %08x\n, + elt * 4, + obj-pages[0][elt], + obj-pages[0][elt+1], + obj-pages[0][elt+2], + obj-pages[0][elt+3]); + } + } + if (error-overlay) intel_overlay_print_error_state(m, error-overlay); @@ -528,6 +539,7 @@ static void i915_error_state_free(struct kref *error_ref) kfree(error-ring[i].requests); } + i915_error_object_free(error-semaphore_obj); kfree(error-active_bo); kfree(error-overlay); kfree(error-display); @@ -745,6 +757,33 @@ static void i915_gem_record_fences(struct drm_device *dev, } +static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, + struct drm_i915_error_state *error, + struct intel_ring_buffer *ring, + struct drm_i915_error_ring *ering) +{ + struct intel_ring_buffer *useless; + int i; + + if (!i915_semaphore_is_enabled(dev_priv-dev)) + return; + + if (!error-semaphore_obj) + error-semaphore_obj = + i915_error_object_create(dev_priv, +dev_priv-semaphore_obj, +dev_priv-gtt.base); + + for_each_ring(useless, dev_priv, i) { + u16 signal_offset = + (GEN8_SIGNAL_OFFSET(ring, i) PAGE_MASK) / 4; + u32 *tmp = error-semaphore_obj-pages[0]; + + ering-semaphore_mboxes[i] = tmp[signal_offset]; + ering-semaphore_seqno[i] = ring-semaphore.sync_seqno[i]; + } +} + static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, struct intel_ring_buffer *ring, struct drm_i915_error_ring *ering) @@ -762,6 +801,7 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, } static void i915_record_ring_state(struct drm_device *dev, +
[Intel-gfx] [PATCH 09/13] drm/i915/bdw: poll semaphores
As Ville points out, it's possible/probable we don't actually need this. Potentially, this validates the letter of the spec, and not the spirit. Ville: I discussed this on irc w/ Ben, and I was suggesting we don't need to poll. Polling apparently can be used as a workaround for certain hardware issues, but it looks like those issues shouldn't affect us, for the momemnt at least. So my suggestion was to try w/o polling first (since there could be some power cost to polling) and add the poll bit if problems arise. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 31b1f3c..e7748ef 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -842,6 +842,7 @@ gen8_ring_sync(struct intel_ring_buffer *waiter, intel_ring_emit(waiter, MI_SEMAPHORE_WAIT | MI_SEMAPHORE_GLOBAL_GTT | + MI_SEMAPHORE_POLL | MI_SEMAPHORE_SAD_GTE_SDD); intel_ring_emit(waiter, seqno); intel_ring_emit(waiter, -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func
This abstraction again is in preparation for gen8. Gen8 will bring new semantics for doing this operation. While here, make the writes of MI_NOOPs explicit for non-existent rings. This should have been implicit before. NOTE: This is going to be removed in a few patches. Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 42 - drivers/gpu/drm/i915/intel_ringbuffer.h | 11 + 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3076a99..ea81b54 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -663,20 +663,32 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) ring-scratch.obj = NULL; } -static void -update_mboxes(struct intel_ring_buffer *ring, - u32 mmio_offset) +static void gen6_signal(struct intel_ring_buffer *signaller) { + struct drm_i915_private *dev_priv = signaller-dev-dev_private; + struct intel_ring_buffer *useless; + int i; + /* NB: In order to be able to do semaphore MBOX updates for varying number * of rings, it's easiest if we round up each individual update to a * multiple of 2 (since ring updates must always be a multiple of 2) * even though the actual update only requires 3 dwords. */ #define MBOX_UPDATE_DWORDS 4 - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, mmio_offset); - intel_ring_emit(ring, ring-outstanding_lazy_seqno); - intel_ring_emit(ring, MI_NOOP); + for_each_ring(useless, dev_priv, i) { + u32 mbox_reg = signaller-semaphore.mbox.signal[i]; + if (mbox_reg != GEN6_NOSYNC) { + intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(signaller, mbox_reg); + intel_ring_emit(signaller, signaller-outstanding_lazy_seqno); + intel_ring_emit(signaller, MI_NOOP); + } else { + intel_ring_emit(signaller, MI_NOOP); + intel_ring_emit(signaller, MI_NOOP); + intel_ring_emit(signaller, MI_NOOP); + intel_ring_emit(signaller, MI_NOOP); + } + } } /** @@ -692,9 +704,7 @@ static int gen6_add_request(struct intel_ring_buffer *ring) { struct drm_device *dev = ring-dev; - struct drm_i915_private *dev_priv = dev-dev_private; - struct intel_ring_buffer *useless; - int i, ret, num_dwords = 4; + int ret, num_dwords = 4; if (i915_semaphore_is_enabled(dev)) num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS); @@ -704,13 +714,7 @@ gen6_add_request(struct intel_ring_buffer *ring) if (ret) return ret; - if (i915_semaphore_is_enabled(dev)) { - for_each_ring(useless, dev_priv, i) { - u32 mbox_reg = ring-semaphore.mbox.signal[i]; - if (mbox_reg != GEN6_NOSYNC) - update_mboxes(ring, mbox_reg); - } - } + ring-semaphore.signal(ring); intel_ring_emit(ring, MI_STORE_DWORD_INDEX); intel_ring_emit(ring, I915_GEM_HWS_INDEX MI_STORE_DWORD_INDEX_SHIFT); @@ -1920,6 +1924,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring-get_seqno = gen6_ring_get_seqno; ring-set_seqno = ring_set_seqno; ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.signal = gen6_signal; /* * The current semaphore is only applied on pre-gen8 platform. * And there is no VCS2 ring on the pre-gen8 platform. So the @@ -2104,6 +2109,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) gen6_ring_dispatch_execbuffer; } ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.signal = gen6_signal; /* * The current semaphore is only applied on pre-gen8 platform. * And there is no VCS2 ring on the pre-gen8 platform. So the @@ -2221,6 +2227,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) ring-dispatch_execbuffer = gen6_ring_dispatch_execbuffer; } ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.signal = gen6_signal; /* * The current semaphore is only applied on pre-gen8 platform. And * there is no VCS2 ring on the pre-gen8 platform. So the semaphore @@ -2270,6 +2277,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) ring-dispatch_execbuffer = gen6_ring_dispatch_execbuffer; }
[Intel-gfx] [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct
This will be helpful in abstracting some of the code in preparation for gen8 semaphores. v2: Move mbox stuff to a separate struct v3: Rebased over VCS2 work Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com (v1) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 10 +-- drivers/gpu/drm/i915/i915_gpu_error.c | 6 +- drivers/gpu/drm/i915/i915_irq.c | 3 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 124 drivers/gpu/drm/i915/intel_ringbuffer.h | 19 +++-- 5 files changed, 82 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b00a77e..dae51c3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2119,8 +2119,8 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) for_each_ring(ring, dev_priv, i) { intel_ring_init_seqno(ring, seqno); - for (j = 0; j ARRAY_SIZE(ring-sync_seqno); j++) - ring-sync_seqno[j] = 0; + for (j = 0; j ARRAY_SIZE(ring-semaphore.sync_seqno); j++) + ring-semaphore.sync_seqno[j] = 0; } return 0; @@ -2692,7 +2692,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, idx = intel_ring_sync_index(from, to); seqno = obj-last_read_seqno; - if (seqno = from-sync_seqno[idx]) + if (seqno = from-semaphore.sync_seqno[idx]) return 0; ret = i915_gem_check_olr(obj-ring, seqno); @@ -2700,13 +2700,13 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, return ret; trace_i915_gem_ring_sync_to(from, to, seqno); - ret = to-sync_to(to, from, seqno); + ret = to-semaphore.sync_to(to, from, seqno); if (!ret) /* We use last_read_seqno because sync_to() * might have just caused seqno wrap under * the radar. */ - from-sync_seqno[idx] = obj-last_read_seqno; + from-semaphore.sync_seqno[idx] = obj-last_read_seqno; return ret; } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 51e9978..2d81985 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -757,14 +757,14 @@ static void i915_record_ring_state(struct drm_device *dev, = I915_READ(RING_SYNC_0(ring-mmio_base)); ering-semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring-mmio_base)); - ering-semaphore_seqno[0] = ring-sync_seqno[0]; - ering-semaphore_seqno[1] = ring-sync_seqno[1]; + ering-semaphore_seqno[0] = ring-semaphore.sync_seqno[0]; + ering-semaphore_seqno[1] = ring-semaphore.sync_seqno[1]; } if (HAS_VEBOX(dev)) { ering-semaphore_mboxes[2] = I915_READ(RING_SYNC_2(ring-mmio_base)); - ering-semaphore_seqno[2] = ring-sync_seqno[2]; + ering-semaphore_seqno[2] = ring-semaphore.sync_seqno[2]; } if (INTEL_INFO(dev)-gen = 4) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7e0d577..2d76183 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2595,8 +2595,7 @@ semaphore_wait_to_signaller_ring(struct intel_ring_buffer *ring, u32 ipehr) if(ring == signaller) continue; - if (sync_bits == - signaller-semaphore_register[ring-id]) + if (sync_bits == signaller-semaphore.mbox.wait[ring-id]) return signaller; } } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ab22d70..3076a99 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -706,7 +706,7 @@ gen6_add_request(struct intel_ring_buffer *ring) if (i915_semaphore_is_enabled(dev)) { for_each_ring(useless, dev_priv, i) { - u32 mbox_reg = ring-signal_mbox[i]; + u32 mbox_reg = ring-semaphore.mbox.signal[i]; if (mbox_reg != GEN6_NOSYNC) update_mboxes(ring, mbox_reg); } @@ -740,10 +740,11 @@ gen6_ring_sync(struct intel_ring_buffer *waiter, struct intel_ring_buffer *signaller, u32 seqno) { - int ret; u32 dw1 = MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER; + u32 wait_mbox = signaller-semaphore.mbox.wait[waiter-id]; + int ret; /* Throughout all of the GEM code, seqno passed implies our current
[Intel-gfx] [PATCH 06/13] drm/i915/bdw: implement semaphore signal
Semaphore signalling works similarly to previous GENs with the exception that the per ring mailboxes no longer exist. Instead you must define your own space, somewhere in the GTT. The comments in the code define the layout I've opted for, which should be fairly future proof. Ie. I tried to define offsets in abstract terms (NUM_RINGS, seqno size, etc). NOTE: If one wanted to move this to the HWSP they could. I've decided one 4k object would be easier to deal with, and provide potential wins with cache locality, but that's all speculative. v2: Update the macro to not need the other ring's ring-id (Chris) Update the comment to use the correct formula (Chris) v3: Move the macros the ringbuffer.h to prevent churn in next patch (Ville) v4: Fixed compilation rebase conflict commit 1ec9e26ddab06459e89a890431b2de064c5d1056 Author: Daniel Vetter daniel.vet...@ffwll.ch Date: Fri Feb 14 14:01:11 2014 +0100 drm/i915: Consolidate binding parameters into flags v5: VCS2 rebase Replace hweight_long with hweight32 Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 5 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 166 ++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 78 +-- 4 files changed, 190 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 50dfc3a..44cb744 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1293,6 +1293,7 @@ struct drm_i915_private { struct pci_dev *bridge_dev; struct intel_ring_buffer ring[I915_NUM_RINGS]; + struct drm_i915_gem_object *semaphore_obj; uint32_t last_seqno, next_seqno; drm_dma_handle_t *status_page_dmah; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0eff337..8e6ec03 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -229,7 +229,7 @@ #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 19) #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 19) #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 19) -#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ +#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */ #define MI_SEMAPHORE_GLOBAL_GTT(122) #define MI_SEMAPHORE_UPDATE (121) #define MI_SEMAPHORE_COMPARE (120) @@ -255,6 +255,8 @@ #define MI_RESTORE_EXT_STATE_EN (12) #define MI_FORCE_RESTORE (11) #define MI_RESTORE_INHIBIT (10) +#define MI_SEMAPHORE_SIGNALMI_INSTR(0x1b, 0) /* GEN8+ */ +#define MI_SEMAPHORE_TARGET(engine) ((engine)15) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) @@ -349,6 +351,7 @@ #define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE(110) /* GM45+ only */ #define PIPE_CONTROL_INDIRECT_STATE_DISABLE (19) #define PIPE_CONTROL_NOTIFY (18) +#define PIPE_CONTROL_FLUSH_ENABLE(17) /* gen7+ */ #define PIPE_CONTROL_VF_CACHE_INVALIDATE (14) #define PIPE_CONTROL_CONST_CACHE_INVALIDATE (13) #define PIPE_CONTROL_STATE_CACHE_INVALIDATE (12) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f2bae6f..03324b2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -650,6 +650,13 @@ static int init_render_ring(struct intel_ring_buffer *ring) static void render_ring_cleanup(struct intel_ring_buffer *ring) { struct drm_device *dev = ring-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + + if (dev_priv-semaphore_obj) { + i915_gem_object_ggtt_unpin(dev_priv-semaphore_obj); + drm_gem_object_unreference(dev_priv-semaphore_obj-base); + dev_priv-semaphore_obj = NULL; + } if (ring-scratch.obj == NULL) return; @@ -663,6 +670,85 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) ring-scratch.obj = NULL; } +static int gen8_rcs_signal(struct intel_ring_buffer *signaller, + unsigned int num_dwords) +{ +#define MBOX_UPDATE_DWORDS 8 + struct drm_device *dev = signaller-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ring_buffer *waiter; + int i, ret, num_rings; + + num_rings = hweight32(INTEL_INFO(dev)-ring_mask); + num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS; +#undef MBOX_UPDATE_DWORDS + + ret = intel_ring_begin(signaller, num_dwords); + if (ret) + return ret; + + for_each_ring(waiter, dev_priv, i) { + u64 gtt_offset = signaller-semaphore.signal_ggtt[i]; + if (gtt_offset ==
[Intel-gfx] [PATCH 04/13] drm/i915: Make semaphore updates more precise
With the ring mask we now have an easy way to know the number of rings in the system, and therefore can accurately predict the number of dwords to emit for semaphore signalling. This was not possible (easily) previously. There should be no functional impact, simply fewer instructions emitted. While we're here, simply do the round up to 2 instead of the fancier rounding we did before, which rounding up per mbox, ie 4. This also allows us to drop the unnecessary MI_NOOP, so not really 4, 3. v2: Use 3 dwords instead of 4 (Ville) Do the proper calculation to get the number of dwords to emit (Ville) Conditionally set .sync_to when semaphores are enabled (Ville) v3: Rebased on VCS2 Replace hweight_long with hweight32 (Ville) Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com (v1) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 173 +--- 1 file changed, 90 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e0c7bf2..7aedc0c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -666,24 +666,19 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) static int gen6_signal(struct intel_ring_buffer *signaller, unsigned int num_dwords) { +#define MBOX_UPDATE_DWORDS 3 struct drm_device *dev = signaller-dev; struct drm_i915_private *dev_priv = dev-dev_private; struct intel_ring_buffer *useless; - int i, ret; + int i, ret, num_rings; - /* NB: In order to be able to do semaphore MBOX updates for varying -* number of rings, it's easiest if we round up each individual update -* to a multiple of 2 (since ring updates must always be a multiple of -* 2) even though the actual update only requires 3 dwords. -*/ -#define MBOX_UPDATE_DWORDS 4 - if (i915_semaphore_is_enabled(dev)) - num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS); + num_rings = hweight32(INTEL_INFO(dev)-ring_mask); + num_dwords += round_up((num_rings-1) * MBOX_UPDATE_DWORDS, 2); +#undef MBOX_UPDATE_DWORDS ret = intel_ring_begin(signaller, num_dwords); if (ret) return ret; -#undef MBOX_UPDATE_DWORDS for_each_ring(useless, dev_priv, i) { u32 mbox_reg = signaller-semaphore.mbox.signal[i]; @@ -691,15 +686,13 @@ static int gen6_signal(struct intel_ring_buffer *signaller, intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1)); intel_ring_emit(signaller, mbox_reg); intel_ring_emit(signaller, signaller-outstanding_lazy_seqno); - intel_ring_emit(signaller, MI_NOOP); - } else { - intel_ring_emit(signaller, MI_NOOP); - intel_ring_emit(signaller, MI_NOOP); - intel_ring_emit(signaller, MI_NOOP); - intel_ring_emit(signaller, MI_NOOP); } } + /* If num_dwords was rounded, make sure the tail pointer is correct */ + if (num_rings % 2 == 0) + intel_ring_emit(signaller, MI_NOOP); + return 0; } @@ -717,7 +710,11 @@ gen6_add_request(struct intel_ring_buffer *ring) { int ret; - ret = ring-semaphore.signal(ring, 4); + if (ring-semaphore.signal) + ret = ring-semaphore.signal(ring, 4); + else + ret = intel_ring_begin(ring, 4); + if (ret) return ret; @@ -1928,24 +1925,27 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT; ring-get_seqno = gen6_ring_get_seqno; ring-set_seqno = ring_set_seqno; - ring-semaphore.sync_to = gen6_ring_sync; - ring-semaphore.signal = gen6_signal; - /* -* The current semaphore is only applied on pre-gen8 platform. -* And there is no VCS2 ring on the pre-gen8 platform. So the -* semaphore between RCS and VCS2 is initialized as INVALID. -* Gen8 will initialize the sema between VCS2 and RCS later. -*/ - ring-semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; - ring-semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV; - ring-semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB; - ring-semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE; - ring-semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - ring-semaphore.mbox.signal[RCS] = GEN6_NOSYNC; - ring-semaphore.mbox.signal[VCS] = GEN6_VRSYNC; - ring-semaphore.mbox.signal[BCS] = GEN6_BRSYNC; - ring-semaphore.mbox.signal[VECS]
[Intel-gfx] [PATCH 00/13] [REPOST] BDW Semaphores
Okay, trying this again after the somewhat painful VCS2 rebase. I think I got to all of Ville's comments, but I could have missed a few. I apologize if so. Daniel, even if you don't merge the whole series, the first few would really help rebase pain - though now that VCS2 is merged, there's probably not much other than execlists to be painful The series is completely untested since the last rebase. I also didn't look really closely to make sure the rebase was correct - I'm just totally short on time atm. It was tested before that. Ben Widawsky (13): drm/i915: Move semaphore specific ring members to struct drm/i915: Virtualize the ringbuffer signal func drm/i915: Move ring_begin to signal() drm/i915: Make semaphore updates more precise drm/i915: gen specific ring init drm/i915/bdw: implement semaphore signal drm/i915/bdw: implement semaphore wait drm/i915: Implement MI decode for gen8 drm/i915/bdw: poll semaphores drm/i915: Extract semaphore error collection drm/i915/bdw: collect semaphore error state drm/i915: semaphore debugfs DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores drivers/gpu/drm/i915/i915_debugfs.c | 70 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 10 +- drivers/gpu/drm/i915/i915_gem_context.c | 7 + drivers/gpu/drm/i915/i915_gpu_error.c | 79 +-- drivers/gpu/drm/i915/i915_irq.c | 14 +- drivers/gpu/drm/i915/i915_reg.h | 8 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 405 ++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 90 ++- 9 files changed, 528 insertions(+), 157 deletions(-) -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/13] drm/i915: gen specific ring init
Gen8 has already had some differentiation with how it handles rings. Semaphores bring yet more differences, and now is as good a time as any to do the split. Also, since gen8 doesn't actually use semaphores up until this point, put the proper NULL values in for the mbox info. v2: v1 had a stale commit message v3: Move everything in the is_semaphore_enabled() check v4: VCS2 rebase Remove double assignment of signal in render ring (Ville) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 187 +--- 1 file changed, 123 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7aedc0c..f2bae6f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1909,19 +1909,33 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring-id = RCS; ring-mmio_base = RENDER_RING_BASE; - if (INTEL_INFO(dev)-gen = 6) { + if (INTEL_INFO(dev)-gen = 8) { + ring-add_request = gen6_add_request; + ring-flush = gen8_render_ring_flush; + ring-irq_get = gen8_ring_get_irq; + ring-irq_put = gen8_ring_put_irq; + ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT; + ring-get_seqno = gen6_ring_get_seqno; + ring-set_seqno = ring_set_seqno; + if (i915_semaphore_is_enabled(dev)) { + ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.signal = gen6_signal; + ring-semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.signal[RCS] = GEN6_NOSYNC; + ring-semaphore.mbox.signal[VCS] = GEN6_NOSYNC; + ring-semaphore.mbox.signal[BCS] = GEN6_NOSYNC; + ring-semaphore.mbox.signal[VECS] = GEN6_NOSYNC; + } + } else if (INTEL_INFO(dev)-gen = 6) { ring-add_request = gen6_add_request; ring-flush = gen7_render_ring_flush; if (INTEL_INFO(dev)-gen == 6) ring-flush = gen6_render_ring_flush; - if (INTEL_INFO(dev)-gen = 8) { - ring-flush = gen8_render_ring_flush; - ring-irq_get = gen8_ring_get_irq; - ring-irq_put = gen8_ring_put_irq; - } else { - ring-irq_get = gen6_ring_get_irq; - ring-irq_put = gen6_ring_put_irq; - } + ring-irq_get = gen6_ring_get_irq; + ring-irq_put = gen6_ring_put_irq; ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT; ring-get_seqno = gen6_ring_get_seqno; ring-set_seqno = ring_set_seqno; @@ -1973,6 +1987,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring-irq_enable_mask = I915_USER_INTERRUPT; } ring-write_tail = ring_write_tail; + if (IS_HASWELL(dev)) ring-dispatch_execbuffer = hsw_ring_dispatch_execbuffer; else if (IS_GEN8(dev)) @@ -2106,33 +2121,48 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) ring-irq_put = gen8_ring_put_irq; ring-dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + if (i915_semaphore_is_enabled(dev)) { + ring-semaphore.sync_to = gen6_ring_sync; + ring-semaphore.signal = gen6_signal; + /* +* The current semaphore is only applied on +* pre-gen8 platform. And there is no VCS2 ring +* on the pre-gen8 platform. So the semaphore +* between VCS and VCS2 is initialized as +* INVALID. Gen8 will initialize the sema +* between VCS2 and VCS later. +*/ + ring-semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID; + ring-semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; +
[Intel-gfx] [PATCH 03/13] drm/i915: Move ring_begin to signal()
Add_request has always contained both the semaphore mailbox updates as well as the breadcrumb writes. Since the semaphore signal is the one which actually knows about the number of dwords it needs to emit to the ring, we move the ring_begin to that function. This allows us to remove the hideously shared #define On a related not, gen8 will use a different number of dwords for semaphores, but not for add request. v2: Make number of dwords an explicit part of signalling (via function argument). (Chris) v3: very slight comment change Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 39 +++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ea81b54..e0c7bf2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -663,18 +663,28 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) ring-scratch.obj = NULL; } -static void gen6_signal(struct intel_ring_buffer *signaller) +static int gen6_signal(struct intel_ring_buffer *signaller, + unsigned int num_dwords) { - struct drm_i915_private *dev_priv = signaller-dev-dev_private; + struct drm_device *dev = signaller-dev; + struct drm_i915_private *dev_priv = dev-dev_private; struct intel_ring_buffer *useless; - int i; + int i, ret; -/* NB: In order to be able to do semaphore MBOX updates for varying number - * of rings, it's easiest if we round up each individual update to a - * multiple of 2 (since ring updates must always be a multiple of 2) - * even though the actual update only requires 3 dwords. - */ + /* NB: In order to be able to do semaphore MBOX updates for varying +* number of rings, it's easiest if we round up each individual update +* to a multiple of 2 (since ring updates must always be a multiple of +* 2) even though the actual update only requires 3 dwords. +*/ #define MBOX_UPDATE_DWORDS 4 + if (i915_semaphore_is_enabled(dev)) + num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS); + + ret = intel_ring_begin(signaller, num_dwords); + if (ret) + return ret; +#undef MBOX_UPDATE_DWORDS + for_each_ring(useless, dev_priv, i) { u32 mbox_reg = signaller-semaphore.mbox.signal[i]; if (mbox_reg != GEN6_NOSYNC) { @@ -689,6 +699,8 @@ static void gen6_signal(struct intel_ring_buffer *signaller) intel_ring_emit(signaller, MI_NOOP); } } + + return 0; } /** @@ -703,19 +715,12 @@ static void gen6_signal(struct intel_ring_buffer *signaller) static int gen6_add_request(struct intel_ring_buffer *ring) { - struct drm_device *dev = ring-dev; - int ret, num_dwords = 4; - - if (i915_semaphore_is_enabled(dev)) - num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS); -#undef MBOX_UPDATE_DWORDS + int ret; - ret = intel_ring_begin(ring, num_dwords); + ret = ring-semaphore.signal(ring, 4); if (ret) return ret; - ring-semaphore.signal(ring); - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); intel_ring_emit(ring, I915_GEM_HWS_INDEX MI_STORE_DWORD_INDEX_SHIFT); intel_ring_emit(ring, ring-outstanding_lazy_seqno); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 830ff26..0fdf030 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -132,7 +132,9 @@ struct intel_ring_buffer { int (*sync_to)(struct intel_ring_buffer *ring, struct intel_ring_buffer *to, u32 seqno); - void(*signal)(struct intel_ring_buffer *signaller); + int (*signal)(struct intel_ring_buffer *signaller, + /* num_dwords needed by caller */ + unsigned int num_dwords); } semaphore; /** -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] intel_reg_dumper: add more details for DisplayPort MST regs
From: Dave Airlie airl...@redhat.com Signed-off-by: Dave Airlie airl...@redhat.com --- tools/intel_reg_dumper.c | 127 ++- 1 file changed, 115 insertions(+), 12 deletions(-) diff --git a/tools/intel_reg_dumper.c b/tools/intel_reg_dumper.c index 4bc299c..a482b5d 100644 --- a/tools/intel_reg_dumper.c +++ b/tools/intel_reg_dumper.c @@ -1685,7 +1685,7 @@ DEBUGSTRING(hsw_debug_sfuse_strap) DEBUGSTRING(hsw_debug_pipe_ddi_func_ctl) { const char *enable, *port, *mode, *bpc, *vsync, *hsync, *edp_input; - const char *width; + const char *width, *payload; enable = (val (131)) ? enabled : disabled; @@ -1771,6 +1771,7 @@ DEBUGSTRING(hsw_debug_pipe_ddi_func_ctl) break; } + payload = (val (1 8)) ? DP VC enable : DP VC disable; switch ((val 1) 7) { case 0: width = x1; @@ -1786,8 +1787,110 @@ DEBUGSTRING(hsw_debug_pipe_ddi_func_ctl) break; } - snprintf(result, len, %s, %s, %s, %s, %s, %s, %s, %s, enable, -port, mode, bpc, vsync, hsync, edp_input, width); + snprintf(result, len, %s, %s, %s, %s, %s, %s, %s, %s, %s, enable, +port, mode, bpc, vsync, hsync, edp_input, payload, width); +} + +DEBUGSTRING(hsw_debug_dp_tp_ctl) +{ + const char *enable, *mode, *force_act, *enh, *autotrain; + const char *linktrain; + enable = (val (131)) ? enabled : disabled; + mode = (val (127)) ? MST : SST; + force_act = (val (125)) ? , Force ACT : ; + enh = (val (118)) ? , ENH Framing : ; + autotrain = (val (115)) ? , Auto training : ; + + switch ((val 8) 7) { + case 0: + linktrain = TP1; + break; + case 1: + linktrain = TP2; + break; + case 2: + linktrain = Idle; + break; + case 3: + linktrain = Normal; + break; + case 4: + linktrain = TP3; + break; + default: + linktrain = Rsvd; + break; + } + + snprintf(result, len, %s, %s %s%s%s%s, enable, mode, force_act, enh, autotrain, linktrain); +} + +DEBUGSTRING(hsw_debug_dp_tp_status) +{ + const char *idle, *active, *mi, *act, *mode, *nstreams; + const char *pm_vc2, *pm_vc1, *pm_vc0; + idle = (val (127)) ? Idle sent, : ; + active = (val (126)) ? Active sent, : ; + mi = (val (125)) ? Min Idles sent, : ; + act = (val (124)) ? ACT sent, : ; + mode = (val (123)) ? MST : SST; + + switch ((val 16) 3) { + case 0: + default: + nstreams = 0 streams; + break; + case 1: + nstreams = 1 stream; + break; + case 2: + nstreams = 2 streams; + break; + case 3: + nstreams = 3 streams; + break; + } + + switch ((val 8) 3) { + case 0: + default: + pm_vc2 = VC2-A; + break; + case 1: + pm_vc2 = VC2-B; + break; + case 2: + pm_vc2 = VC2-C; + break; + } + + switch ((val 4) 3) { + case 0: + default: + pm_vc1 = VC1-A; + break; + case 1: + pm_vc1 = VC1-B; + break; + case 2: + pm_vc1 = VC1-C; + break; + } + + switch ((val) 3) { + case 0: + default: + pm_vc0 = VC0-A; + break; + case 1: + pm_vc0 = VC0-B; + break; + case 2: + pm_vc0 = VC0-C; + break; + } + + snprintf(result, len, %s%s%s%s%s %s %s %s %s, idle, active, mi, act, mode, nstreams, pm_vc2, pm_vc1, pm_vc0); } DEBUGSTRING(hsw_debug_wm_pipe) @@ -2285,17 +2388,17 @@ static struct reg_debug haswell_debug_regs[] = { DEFINEREG2(PIPE_DDI_FUNC_CTL_EDP, hsw_debug_pipe_ddi_func_ctl), /* DP transport control */ - DEFINEREG(DP_TP_CTL_A), - DEFINEREG(DP_TP_CTL_B), - DEFINEREG(DP_TP_CTL_C), - DEFINEREG(DP_TP_CTL_D), - DEFINEREG(DP_TP_CTL_E), + DEFINEREG2(DP_TP_CTL_A, hsw_debug_dp_tp_ctl), + DEFINEREG2(DP_TP_CTL_B, hsw_debug_dp_tp_ctl), + DEFINEREG2(DP_TP_CTL_C, hsw_debug_dp_tp_ctl), + DEFINEREG2(DP_TP_CTL_D, hsw_debug_dp_tp_ctl), + DEFINEREG2(DP_TP_CTL_E, hsw_debug_dp_tp_ctl), /* DP status */ - DEFINEREG(DP_TP_STATUS_B), - DEFINEREG(DP_TP_STATUS_C), - DEFINEREG(DP_TP_STATUS_D), - DEFINEREG(DP_TP_STATUS_E), + DEFINEREG2(DP_TP_STATUS_B, hsw_debug_dp_tp_status), + DEFINEREG2(DP_TP_STATUS_C, hsw_debug_dp_tp_status), + DEFINEREG2(DP_TP_STATUS_D, hsw_debug_dp_tp_status), + DEFINEREG2(DP_TP_STATUS_E,
Re: [Intel-gfx] [PATCH] intel_error_decode: use 64b gtt_offset
On Tue, Apr 29, 2014 at 11:01:10AM +0200, Daniel Vetter wrote: On Tue, Apr 29, 2014 at 10:52:44AM +0200, Daniel Vetter wrote: On Mon, Apr 28, 2014 at 06:45:50PM -0700, Ben Widawsky wrote: See the relevant kernel patch for the details. I guess this breaks support for older error state, I am not actually sure. Without versioning our error state though, I cannot think of a better way. Suggestions are welcome. Just drop the length qualifier and let scanf it the full number? Also, you know the drill: Testcase, please. A copy of drv_hangman to also feed the captured error state into intel_error_decode and check that it doesn't fall overr (exitcode != 0 and nothing on stderr). Maybe call it drv_error_decode or something like that. -Daniel You're not going to get it from me. If you don't take the patch, that's fine by me. -- Ben Widawsky, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree
Hi all, Today's linux-next merge of the drm-intel tree got a conflict in drivers/gpu/drm/i915/i915_gem_gtt.c between commitcfa7c862982b (drm/i915: Sanitize the enable_ppgtt module option once) from the drm-intel-fixes tree tree and commit 5db6c735ead5 (drm/i915: dmesg output for VT-d testing) from the drm-intel tree. I fixed it up (see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwells...@canb.auug.org.au diff --cc drivers/gpu/drm/i915/i915_gem_gtt.c index 154b0f8bb88d,496916298e8a.. --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@@ -62,62 -48,13 +62,9 @@@ static int sanitize_enable_ppgtt(struc } #endif - /* Full ppgtt disabled by default for now due to issues. */ - if (full) - return HAS_PPGTT(dev) (i915.enable_ppgtt == 2); - else - return HAS_ALIASING_PPGTT(dev); + return HAS_ALIASING_PPGTT(dev) ? 1 : 0; } - #define GEN6_PPGTT_PD_ENTRIES 512 - #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) - typedef uint64_t gen8_gtt_pte_t; - typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; - - /* PPGTT stuff */ - #define GEN6_GTT_ADDR_ENCODE(addr)((addr) | (((addr) 28) 0xff0)) - #define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) 28) 0x7f0)) - - #define GEN6_PDE_VALID(1 0) - /* gen6+ has bit 11-4 for physical addr bit 39-32 */ - #define GEN6_PDE_ADDR_ENCODE(addr)GEN6_GTT_ADDR_ENCODE(addr) - - #define GEN6_PTE_VALID(1 0) - #define GEN6_PTE_UNCACHED (1 1) - #define HSW_PTE_UNCACHED (0) - #define GEN6_PTE_CACHE_LLC(2 1) - #define GEN7_PTE_CACHE_L3_LLC (3 1) - #define GEN6_PTE_ADDR_ENCODE(addr)GEN6_GTT_ADDR_ENCODE(addr) - #define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) - - /* Cacheability Control is a 4-bit value. The low three bits are stored in * - * bits 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. - */ - #define HSW_CACHEABILITY_CONTROL(bits)bits) 0x7) 1) | \ -(((bits) 0x8) (11 - 3))) - #define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) - #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) - #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) - #define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8) - #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) - #define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7) - - #define GEN8_PTES_PER_PAGE(PAGE_SIZE / sizeof(gen8_gtt_pte_t)) - #define GEN8_PDES_PER_PAGE(PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) - - /* GEN8 legacy style addressis defined as a 3 level page table: - * 31:30 | 29:21 | 20:12 | 11:0 - * PDPE | PDE | PTE | offset - * The difference as compared to normal x86 3 level page table is the PDPEs are - * programmed via register. - */ - #define GEN8_PDPE_SHIFT 30 - #define GEN8_PDPE_MASK0x3 - #define GEN8_PDE_SHIFT21 - #define GEN8_PDE_MASK 0x1ff - #define GEN8_PTE_SHIFT12 - #define GEN8_PTE_MASK 0x1ff - - #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) - #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ - #define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */ - #define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */ static void ppgtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, @@@ -2041,14 -1971,10 +1981,18 @@@ int i915_gem_gtt_init(struct drm_devic gtt-base.total 20); DRM_DEBUG_DRIVER(GMADR size = %ldM\n, gtt-mappable_end 20); DRM_DEBUG_DRIVER(GTT stolen size = %zdM\n, gtt-stolen_size 20); + /* + * i915.enable_ppgtt is read-only, so do an early pass to validate the + * user's requested state against the hardware/driver capabilities. We + * do this now so that we can print out any log messages once rather + * than every time we check intel_enable_ppgtt(). + */ + i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt); + DRM_DEBUG_DRIVER(ppgtt mode: %i\n, i915.enable_ppgtt); + #ifdef CONFIG_INTEL_IOMMU + if (intel_iommu_gfx_mapped) + DRM_INFO(VT-d active for gfx access\n); + #endif return 0; } pgpZd0trjp2Fb.pgp Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] haswell's PIPE_CLK_SEL registers
The docs don't mention the regs PIPE_CLK_SEL_A-C at 0x46140-46148, is there any more info on these of if they exist? Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/bdw: Use timeout mode for RC6 on bdw
On Wed, Apr 09, 2014 at 11:44:06AM -0700, Tom O'Rourke wrote: Higher RC6 residency is observed using timeout mode instead of EI mode. This applies to Broadwell only. The difference is particularly noticeable with video playback. Issue: VIZ-3778 Change-Id: I62bb12e21caf19651034826b45cde7f73a80938d Signed-off-by: Tom O'Rourke Tom.O'rou...@intel.com I've merged this one to my bdw-rc6 branch, and therefore my broadwell branch. Hopefully Kristen will see some improvement. --- drivers/gpu/drm/i915/intel_pm.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 33b2592..0d63abf 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3335,15 +3335,23 @@ static void gen8_enable_rps(struct drm_device *dev) for_each_ring(ring, dev_priv, unused) I915_WRITE(RING_MAX_IDLE(ring-mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); - I915_WRITE(GEN6_RC6_THRESHOLD, 5); /* 50/125ms per EI */ + if (IS_BROADWELL(dev)) + I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ + else + I915_WRITE(GEN6_RC6_THRESHOLD, 5); /* 50/125ms per EI */ /* 3: Enable RC6 */ if (intel_enable_rc6(dev) INTEL_RC6_ENABLE) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; intel_print_rc6_info(dev, rc6_mask); - I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | - GEN6_RC_CTL_EI_MODE(1) | - rc6_mask); + if (IS_BROADWELL(dev)) + I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | + GEN7_RC_CTL_TO_MODE | + rc6_mask); + else + I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | + GEN6_RC_CTL_EI_MODE(1) | + rc6_mask); /* 4 Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RPNSWREQ, -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ben Widawsky, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] haswell's PIPE_CLK_SEL registers
On Wed, Apr 30, 2014 at 01:55:37PM +1000, Dave Airlie wrote: The docs don't mention the regs PIPE_CLK_SEL_A-C at 0x46140-46148, is there any more info on these of if they exist? Attached. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch Title: PIPE_CLK_SEL PIPE_CLK_SEL Register Space: MMIO: 0/2/0 Project: DevHSW Source: BSpec Default Value: 0x Access: R/W Size (in bits): 32 Address: 46140h-46143h Name: Pipe A Clock Select ShortName: PIPE_CLK_SEL_A Unit: dcpr Custom Display Category: NDE Clocks Custom Display FUB: dcpr Custom Display Partition: par1 Power: Always on Reset: soft Address: 46144h-46147h Name: Pipe B Clock Select ShortName: PIPE_CLK_SEL_B Unit: dcpr Custom Display Category: NDE Clocks Custom Display FUB: dcpr Custom Display Partition: par1 Power: Always on Reset: soft Address: 46148h-4614Bh Name: Pipe C Clock Select ShortName: PIPE_CLK_SEL_C Unit: dcpr Custom Display Category: NDE Clocks Custom Display FUB: dcpr Custom Display Partition: par1 Power: Always on Reset: soft This register maps the port clock to the pipe. There is one instance of this register format per pipe A/B/C. DWord Bit Description 0 31:29 Pipe Clock Select Select which PLL to use for this pipe. Pipe EDP always uses DDIA clock. Value Name Description Project 000b None No PLL selected. Clock is disabled for this transcoder. 010b DDIB Select DDIB clock 011b DDIC Select DDIC clock 100b DDID Select DDID clock DevHSW 100b Reserved Reserved. DDID is not supported for ULT and must not be selected. DevHSW:ULT 101b DDIE Select DDIE clock DevHSW, EXCLUDE(DevHSW:GT0:X0) Others Reserved Reserved Restriction Restriction : This must not be changed while the pipe is enabled. 28:0 Reserved ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] intel_reg_dumper: add PIPE_MULT
From: Dave Airlie airl...@redhat.com this is defined in the hsw docs, for the hdmi/dvi multiplier. Signed-off-by: Dave Airlie airl...@redhat.com --- lib/intel_reg.h | 3 +++ tools/intel_reg_dumper.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/intel_reg.h b/lib/intel_reg.h index 4b3a102..82ea85f 100644 --- a/lib/intel_reg.h +++ b/lib/intel_reg.h @@ -849,6 +849,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PIPEASRC 0x6001c #define BCLRPAT_A 0x60020 #define VSYNCSHIFT_A 0x60028 +#define MULT_A 0x6002C #define HTOTAL_B 0x61000 #define HBLANK_B 0x61004 @@ -859,6 +860,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PIPEBSRC 0x6101c #define BCLRPAT_B 0x61020 #define VSYNCSHIFT_B 0x61028 +#define MULT_B 0x6102C #define HTOTAL_C 0x62000 #define HBLANK_C 0x62004 @@ -869,6 +871,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PIPECSRC 0x6201c #define BCLRPAT_C 0x62020 #define VSYNCSHIFT_C 0x62028 +#define MULT_C 0x6202C #define HTOTAL_EDP 0x6F000 #define HBLANK_EDP 0x6F004 diff --git a/tools/intel_reg_dumper.c b/tools/intel_reg_dumper.c index a482b5d..c0a5f7a 100644 --- a/tools/intel_reg_dumper.c +++ b/tools/intel_reg_dumper.c @@ -2475,6 +2475,7 @@ static struct reg_debug haswell_debug_regs[] = { DEFINEREG2(VBLANK_A, i830_debug_hvsyncblank), DEFINEREG2(VSYNC_A, i830_debug_hvsyncblank), DEFINEREG(VSYNCSHIFT_A), + DEFINEREG(MULT_A), DEFINEREG2(PIPEA_DATA_M1, ironlake_debug_m_tu), DEFINEREG2(PIPEA_DATA_N1, ironlake_debug_n), DEFINEREG2(PIPEA_LINK_M1, ironlake_debug_n), @@ -2489,6 +2490,7 @@ static struct reg_debug haswell_debug_regs[] = { DEFINEREG2(VBLANK_B, i830_debug_hvsyncblank), DEFINEREG2(VSYNC_B, i830_debug_hvsyncblank), DEFINEREG(VSYNCSHIFT_B), + DEFINEREG(MULT_B), DEFINEREG2(PIPEB_DATA_M1, ironlake_debug_m_tu), DEFINEREG2(PIPEB_DATA_N1, ironlake_debug_n), DEFINEREG2(PIPEB_LINK_M1, ironlake_debug_n), @@ -2503,6 +2505,7 @@ static struct reg_debug haswell_debug_regs[] = { DEFINEREG2(VBLANK_C, i830_debug_hvsyncblank), DEFINEREG2(VSYNC_C, i830_debug_hvsyncblank), DEFINEREG(VSYNCSHIFT_C), + DEFINEREG(MULT_C), DEFINEREG2(PIPEC_DATA_M1, ironlake_debug_m_tu), DEFINEREG2(PIPEC_DATA_N1, ironlake_debug_n), DEFINEREG2(PIPEC_LINK_M1, ironlake_debug_n), -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx