Re: [Intel-gfx] [PATCH v3] drm/i915/bxt: BUNs related to port PLL
Hi Daniel, Is there any other change required in this patch to consider before merge? Please let me know. - Vandana On 7/3/2015 10:23 AM, Kannan, Vandana wrote: Hi, Any other review comments on this patch? Do let me know. Siva and Sonika have given their R-b. Thanks, Vandana On 7/1/2015 4:41 PM, Sivakumar Thulasimani wrote: thanks for the changes. Reviewed-by: Sivakumar Thulasimani sivakumar.thulasim...@intel.com On 7/1/2015 5:02 PM, Vandana Kannan wrote: This patch contains changes based on 2 updates to the spec: Port PLL VCO restriction raised up to 6700. Port PLL now needs DCO amp override enable for all VCO frequencies. v2: Sonika's review comment addressed - dcoampovr_en_h variable not required Based on a discussion with Siva, the following changes have been made. - replace dco_amp var with #define BXT_DCO_AMPLITUDE - set pll10 in a single assignment v3: Move DCO amplitude default value to i915_reg.h. Suggested by Siva. Signed-off-by: Vandana Kannanvandana.kan...@intel.com Reviewed-by: Sonika Jindalsonika.jin...@intel.com [v2] --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ddi.c | 15 +-- drivers/gpu/drm/i915/intel_display.c | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ac985c5..d1b8928 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1211,6 +1211,7 @@ enum skl_disp_power_wells { #define PORT_PLL_LOCK_THRESHOLD_MASK0xe /* PORT_PLL_10_A */ #define PORT_PLL_DCO_AMP_OVR_EN_H(127) +#define PORT_PLL_DCO_AMP_DEFAULT15 #define PORT_PLL_DCO_AMP_MASK0x3c00 #define PORT_PLL_DCO_AMP(x)(x10) #define _PORT_PLL_BASE(port)_PORT3(port, _PORT_PLL_0_A,\ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 42c1487..9c05cc0 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1455,7 +1455,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, struct bxt_clk_div clk_div = {0}; int vco = 0; uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; -uint32_t dcoampovr_en_h, dco_amp, lanestagger; +uint32_t lanestagger; if (intel_encoder-type == INTEL_OUTPUT_HDMI) { intel_clock_t best_clock; @@ -1494,9 +1494,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; } -dco_amp = 15; -dcoampovr_en_h = 0; -if (vco = 620 vco = 648) { +if (vco = 620 vco = 670) { prop_coef = 4; int_coef = 9; gain_ctl = 3; @@ -1507,8 +1505,6 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, int_coef = 11; gain_ctl = 3; targ_cnt = 9; -if (vco = 480 vco 540) -dcoampovr_en_h = 1; } else if (vco == 540) { prop_coef = 3; int_coef = 8; @@ -1550,10 +1546,9 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state-dpll_hw_state.pll8 = targ_cnt; -if (dcoampovr_en_h) -crtc_state-dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H; - -crtc_state-dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp); +crtc_state-dpll_hw_state.pll10 = +PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT) +| PORT_PLL_DCO_AMP_OVR_EN_H; crtc_state-dpll_hw_state.pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eb665d7..e04be45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -409,7 +409,7 @@ static const intel_limit_t intel_limits_chv = { static const intel_limit_t intel_limits_bxt = { /* FIXME: find real dot limits */ .dot = { .min = 0, .max = INT_MAX }, -.vco = { .min = 480, .max = 648 }, +.vco = { .min = 480, .max = 670 }, .n = { .min = 1, .max = 1 }, .m1 = { .min = 2, .max = 2 }, /* FIXME: find real m2 limits */ -- regards, Sivakumar ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/7] drm/i915: move FBC code out of i915_gem_stolen.c
On Thu, Jul 02, 2015 at 10:39:05AM -0300, Paulo Zanoni wrote: 2015-07-01 17:44 GMT-03:00 Chris Wilson ch...@chris-wilson.co.uk: On Wed, Jul 01, 2015 at 05:15:21PM -0300, Paulo Zanoni wrote: Looks much cleaner with the split. +void intel_fbc_cleanup_cfb(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + if (dev_priv-fbc.uncompressed_size == 0) + return; + + i915_gem_stolen_remove_node(dev_priv-fbc.compressed_fb); + + if (dev_priv-fbc.compressed_llb) { + i915_gem_stolen_remove_node(dev_priv-fbc.compressed_llb); + kfree(dev_priv-fbc.compressed_llb); + } Any reason why one node is embedded and the other allocated? Just feels a little inconsistent, so lacks an explanation. Just that one is always used, and the other on rare gen would probably suffice. I really didn't stop to pay attention to the ancient FBC pieces. IMHO reasoning/explanation/change about this should be on a separate patch, since this one is just moving the code around. I only think about the gen2-4 FBC code when I remember it has the disable FBC when more than one pipe is visible restriction which I can't even find on the documentation I have. I wish we could either remove it or just remove the whole gen2-4 FBC support (will we ever have the courage to enable it by default?). Yeah I think killing gen2-4 fbc would be ok. Same for g4x fbc (hw too broken) and ilk fbc (same really according to Art). Then we'd only need to deal with fbc on gen6+, which is reasonably sane and consistent. But we can rip the code out whenever you want, no hurry. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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] [RFC] drm/i915: Handle HPD when it has actually occurred
On 7/6/2015 2:06 PM, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Nice find, this sounds really intrigueing, at least for cpt/ibx platforms. I'm not sure whether what will happen with atom/i9xx platforms though since the irq bits are different there. But at least bxt has a FIXME comment that suggest we do need to save the sticky bits on those platforms too. If we can fix this up for all platforms then I think a subsequent patch could try to re-enable the hpd checks in the hdmi -detect function and make use spec compliant. Then after maybe 1-2 kernel releases of testing we'll know whether it really works. But I'd really want to enable this everywhere just to have maximal test coverage - we did have reports on all platforms so it seems a generic issue. I think only cpt/ibx suffer from this. Bxt already set port_hotplug_stat only when hpd occurs. Is there a process to get this checked on all platforms, which the fix I suggested? I can only test on SKL as of now. Regards, Sonika Thanks, Daniel Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir SDE_AUDIO_POWER_MASK_CPT) -- 1.7.10.4 ___ 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] [RFC 8/8] drm/i915: Add two-stage ILK-style watermark programming (v2)
On Wed, Jul 01, 2015 at 07:26:01PM -0700, Matt Roper wrote: From: Matt Roper m...@mattrope.com In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 9 + drivers/gpu/drm/i915/i915_irq.c | 7 drivers/gpu/drm/i915/intel_display.c | 34 +++- drivers/gpu/drm/i915/intel_drv.h | 26 + drivers/gpu/drm/i915/intel_pm.c | 75 ++-- 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5ad942e..42397e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,6 +623,9 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct drm_crtc *crtc, struct drm_atomic_state *state); + void (*compute_intermediate_wm)(struct drm_device *dev, + struct intel_crtc_state *newstate, + const struct intel_crtc_state *oldstate); void (*update_wm)(struct drm_crtc *crtc); void (*update_sprite_wm)(struct drm_plane *plane, struct drm_crtc *crtc, @@ -2574,6 +2577,12 @@ struct drm_i915_cmd_table { */ #define HAS_ATOMIC_WM(dev_priv) (dev_priv-display.program_watermarks != NULL) +/* + * Newer platforms have doublebuffered watermark registers and do not need + * the two-step watermark programming used by older platforms. + */ +#define HAS_DBLBUF_WM(dev_priv) (INTEL_INFO(dev_priv)-gen = 9) Just move need_vblank_wm_update into crtc_state and compute it in the compute_pipe_wm functions? + #define GT_FREQUENCY_MULTIPLIER 50 #define GEN9_FREQ_SCALER 3 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 20c7260..627c56f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1455,8 +1455,15 @@ static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe) struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dev_priv-pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-state); if (intel_crtc-need_vblank_wm_update) { + WARN_ON(HAS_DBLBUF_WM(dev_priv)); + + /* Latch final watermarks now that vblank is past */ + cstate-wm.active = cstate-wm.target; + + /* Queue work to actually program them asynchronously */ queue_work(dev_priv-wq, intel_crtc-wm_work); intel_crtc-need_vblank_wm_update = false; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fa4373e..1616d7f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4737,7 +4737,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) struct drm_device *dev = crtc-base.dev; struct drm_plane *plane; - if (HAS_ATOMIC_WM(to_i915(dev))) + if (HAS_ATOMIC_WM(to_i915(dev)) !HAS_DBLBUF_WM(to_i915(dev))) /* vblank handler will kick off workqueue task to update wm's */ crtc-need_vblank_wm_update = true; @@ -11833,6 +11833,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state); + struct intel_crtc_state *old_pipe_config = + to_intel_crtc_state(crtc-state); struct drm_atomic_state *state = crtc_state-state; int ret, idx = crtc-base.id; bool mode_changed = needs_modeset(crtc_state); @@ -11863,9 +11865,20 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, } if (dev_priv-display.compute_pipe_wm) { + if (WARN_ON(!dev_priv-display.compute_intermediate_wm)) + return 0; skl won't need this, right? + ret = dev_priv-display.compute_pipe_wm(crtc, state); if (ret) return ret; + + /* + * Calculate 'intermediate' watermarks that satisfy both the old state + *
Re: [Intel-gfx] [RFC] drm/i915: Add sync framework support to execbuff IOCTL
On Fri, Jul 03, 2015 at 12:17:33PM +0100, Tvrtko Ursulin wrote: On 07/02/2015 04:55 PM, Chris Wilson wrote: It would be nice if we could reuse one seqno both for internal/external fences. If you need to expose a fence ordering within a timeline that is based on the creation stamp rather than execution stamp, it seems like we could just add such a stamp when creating the sync_pt and not worry about its relationship to the execution seqno. Doing so does expose that requests are reordered to userspace since the signalling timeline is not the same as userspace's ordered timeline. Not sure if that is a problem or not. Afaict the sync uapi is based on waiting for all of a set of fences to retire. It doesn't seem to rely on fence ordering (that is knowing that fence A will signal before fence B so it need only wait on fence B). Here's hoping that we can have both simplicity and efficiency... Jumping in with not even perfect understanding of everything here - but timeline business has always been confusing me. There is nothing in the uapi which needs it afaics and iirc there was some discussion at the time Jesse floated his patches that it can be removed. Based on that when I squashed his patches and ported them on top of John's request to fence conversion it ended up something like the below (manually edited a bit to be less noisy and some prep patches omitted): This implements the ioctl based uapi and indeed seqnos are not actually used in waits. So is this insufficient for some reason? (Other that it does not implement the input fence side of things.) Yeah android syncpt on top of struct fence embedded int i915 request is what I'd have expected. diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 74acca9..07f6ad9 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -71,3 +71,17 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT option changes the default for that module option. If in doubt, say N. + +config DRM_I915_SYNC + bool Enable explicit sync support + depends on DRM_I915 + default y if STAGING + depends on STAGING + select ANDROID + select SYNC + help No Kconfig for userspace ABI please. Yes this means we need to destage android syncpts first. The problem I see there is that apparently google is still changing the uabi a lot, and that's a no-go for upstream. And it needs to be cleaned up to work more seamlessly with struct fence (i.e. anything that's missing there should be moved to struct fence, drivers should only use fd_to_fence and fenct_to_fd functions similar to dma-buf). And we don't have anyone except android using syncpts, so a bit a trouble with finding userspace vehicles for this. We probably need agreement from google to be happy with a frozen abi for syncpts first ... -Daniel + Choose this option to enable Android native sync support and the + corresponding i915 driver code to expose it. Slightly increases + driver size and pulls in sync support from staging. + + If in doubt, say Y. diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index db21c93..93a3bc0 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -91,6 +91,9 @@ i915-y += i915_vgpu.o # legacy horrors i915-y += i915_dma.o +# sync points +i915-$(CONFIG_DRM_I915_SYNC) += i915_sync.o + obj-$(CONFIG_DRM_I915) += i915.o CFLAGS_i915_trace_points.o := -I$(src) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3ef3997..2cf4d3f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2753,6 +2753,26 @@ void i915_init_vm(struct drm_i915_private *dev_priv, void i915_gem_free_object(struct drm_gem_object *obj); void i915_gem_vma_destroy(struct i915_vma *vma); +/* i915_sync.c */ +struct sync_fence; + +#ifdef CONFIG_DRM_I915_SYNC +int i915_fence_ring_fill_driver_data(struct fence *fence, void *data, int size); +void i915_fence_ring_value_str(struct fence *fence, char *str, int size); +void i915_fence_ring_timeline_value_str(struct fence *fence, char *str, + int size); + +int i915_create_sync_fence_ring(struct drm_i915_gem_request *req, + struct sync_fence **sync_fence, int *fence_fd); +#else +static inline +int i915_create_sync_fence_ring(struct drm_i915_gem_request *req, + struct sync_fence **sync_fence, int *fence_fd) +{ + return -ENODEV; +} +#endif + #define PIN_MAPPABLE 0x1 #define PIN_NONBLOCK 0x2 #define PIN_GLOBAL 0x4 diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 560d244..a04853c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2633,7 +2633,7 @@ static const char
Re: [Intel-gfx] [PATCH 7/7] drm/i915: Mark elsps submitted when they are pushed to hw
On Mon, Jul 06, 2015 at 11:09:25AM +0300, Mika Kuoppala wrote: Now when we have requests this deep on call chain, we can mark the elsp being submitted when it actually is. Remove temp variable and readjust commenting to more closely fit to the code. v2: Avoid tmp variable and reduce number of writes (Chris) Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com Looks cleaner to me, 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] [RFC] drm/i915: Handle HPD when it has actually occurred
Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang...@intel.com) Task id: 6723 -Summary- Platform Delta drm-intel-nightly Series Applied ILK 302/302 302/302 SNB 312/316 312/316 IVB 343/343 343/343 BYT -2 287/287 285/287 HSW 380/380 380/380 -Detailed- Platform Testdrm-intel-nightly Series Applied *BYT igt@gem_partial_pwrite_pread@reads PASS(1) FAIL(1) *BYT igt@gem_tiled_partial_pwrite_pread@reads PASS(1) FAIL(1) Note: You need to pay more attention to line start with '*' ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Handle HPD when it has actually occurred
Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. v2: Make few variables local to if block (Ville) Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..cd504dc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1757,14 +1757,16 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev-dev_private; int pipe; u32 hotplug_trigger = pch_iir SDE_HOTPLUG_MASK_CPT; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, + dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir SDE_AUDIO_POWER_MASK_CPT) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 4/5] drm: Add decoding of i915 ioctls
On Fri, Jul 03, 2015 at 03:36:09AM +0300, Dmitry V. Levin wrote: On Wed, Jul 01, 2015 at 02:52:47PM +0200, Patrik Jakobsson wrote: [...] --- a/drm.c +++ b/drm.c @@ -35,6 +35,9 @@ #define DRM_MAX_NAME_LEN 128 +extern int drm_i915_decode_number(struct tcb *tcp, unsigned int arg); Please rename arg to code, and ... +extern int drm_i915_ioctl(struct tcb *tcp, const unsigned int code, long arg); ... move both declarations to defs.h to make them visible also in the file where these functions are defined. [...] +static int i915_setparam(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_i915_setparam param; + + if (entering(tcp)) { + if (umove(tcp, arg, param)) + return 0; + + tprints(, {param=); + printxval(drm_i915_setparams, param.param, I915_PARAM_???); + tprintf(, value=%d}, param.value); + } + + return 1; +} In this and most of other parsers of _IOC_WRITE ioctls added by this and the next patches, any error in parser that leads to return 0 will result to disabled arg decoding, including the fallback decoding performed by sys_ioctl. Maybe it's time to deal with this issue in a more generic way. Yes, I'm thinking SYS_FUNC(ioctl) could be improved. But on the other hand how likely is it that we fail in umove and what chance do we have to recover from that anyway? All I can think of is OOM. -- ldv ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: set FDI translations to NULL on SKL
On Fri, Jul 03, 2015 at 12:31:30PM -0300, Paulo Zanoni wrote: From: Paulo Zanoni paulo.r.zan...@intel.com drivers/gpu/drm/i915/intel_ddi.c: In function ‘intel_prepare_ddi’: drivers/gpu/drm/i915/intel_ddi.c:517:6: warning: ‘ddi_translations_fdi’ may be used uninitialized in this function [-Wmaybe-uninitialized] if (ddi_translations_fdi) ^ drivers/gpu/drm/i915/intel_ddi.c:446:30: note: ‘ddi_translations_fdi’ was declared here const struct ddi_buf_trans *ddi_translations_fdi; Thanks for noticing! Weird -- and embarassing -- that I missed this :S Kind regards, David ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Parsing LFP brightness control from VBT
From: Deepak M m.dee...@intel.com LFP brighness control from the VBT block 43 indicates which controller is used for brightness. LFP1 brightness control method: Bit 7-4 = This field controller number of the brightnes controller. 0 = Controller 0 1 = Controller 1 2 = Controller 2 3 = Controller 3 Others = Reserved Bits 3-0 are for Control pin 0 = PMIC pin is used for brightness control 1 = LPSS PWM is used for brightness control 2 = Display DDI is used for brightness control 3 = CABC method to control brightness Others = Reserved History: This patch was submitted earlier including a check for control pin. http://lists.freedesktop.org/archives/intel-gfx/2014-December/057530.html Since it caused the issue, https://bugs.freedesktop.org/show_bug.cgi?id=87671, it was reverted in http://lists.freedesktop.org/archives/intel-gfx/2015-January/058110.html The current patch reads controller and control pin from VBT (version = 191) From VBT version = 197, default value of control pin is set to DDI, so the corresponding check during backlight setup will be made in a future patch Signed-off-by: Deepak M m.dee...@intel.com Signed-off-by: Vandana Kannan vandana.kan...@intel.com Cc: Jani Nikula jani.nik...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_bios.c | 9 + drivers/gpu/drm/i915/intel_bios.h | 11 +++ 3 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 950a981..a89e9a9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1461,6 +1461,8 @@ struct intel_vbt_data { bool present; bool active_low_pwm; u8 min_brightness; /* min_brightness/255 of max */ + u8 controller; /* brightness controller number */ + u8 control_pin; /* brightness control pin */ } backlight; /* MIPI DSI */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2ff9eb0..32c1ef2 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -256,6 +256,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, { const struct bdb_lfp_backlight_data *backlight_data; const struct bdb_lfp_backlight_data_entry *entry; + const struct bdb_lfp_backlight_control_data *bl_ctrl_data; backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); if (!backlight_data) @@ -268,6 +269,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, } entry = backlight_data-data[panel_type]; + bl_ctrl_data = backlight_data-blc_ctl[panel_type]; dev_priv-vbt.backlight.present = entry-type == BDB_BACKLIGHT_TYPE_PWM; if (!dev_priv-vbt.backlight.present) { @@ -279,12 +281,19 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, 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; + dev_priv-vbt.backlight.controller = bl_ctrl_data-controller; + dev_priv-vbt.backlight.control_pin = bl_ctrl_data-pin; + 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, dev_priv-vbt.backlight.min_brightness, backlight_data-level[panel_type]); + + DRM_DEBUG_KMS(VBT BL controller %u, BL control pin %u\n, + dev_priv-vbt.backlight.controller, + dev_priv-vbt.backlight.control_pin); } /* Try to find sdvo panel data */ diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index af0b476..e97c1c0 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -402,10 +402,21 @@ struct bdb_lfp_backlight_data_entry { u8 obsolete3; } __packed; +#define BLC_CONTROL_PIN_PMIC 0 +#define BLC_CONTROL_PIN_LPSS_PWM 1 +#define BLC_CONTROL_PIN_DDI2 +#define BLC_CONTROL_PIN_CABC 3 + +struct bdb_lfp_backlight_control_data { + u8 controller:4; + u8 pin:4; +} __packed; + struct bdb_lfp_backlight_data { u8 entry_size; struct bdb_lfp_backlight_data_entry data[16]; u8 level[16]; + struct bdb_lfp_backlight_control_data blc_ctl[16]; } __packed; struct aimdb_header { -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] [RFC] drm/i915: Handle HPD when it has actually occurred
On Mon, Jul 06, 2015 at 02:31:56PM +0530, Jindal, Sonika wrote: On 7/6/2015 2:19 PM, Ville Syrjälä wrote: On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } Deja vu. I think I have the same patch (also for IBX) in my stalled (and never posted) port A HPD branch. So yeah, I think this makes sense. You can also move the dig_hotplug_reg, pin_mask, and long_mask declarations into the if block since they're not needed elsewhere. Sure. Do you think I should add this for ibx as well? Yes. -- 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 3/3] drm/i915: Read HDMI EDID only when required
On Thu, Jul 02, 2015 at 08:24:12AM +0530, Sharma, Shashank wrote: Regards Shashank On 7/1/2015 6:26 PM, Daniel Vetter wrote: On Tue, Jun 30, 2015 at 09:49:57PM +0530, Shashank Sharma wrote: Userspace always sets force. Are you sure this actually improves anything? Yes we do. We have had this code for commercial projects, and that's really important to have proper interrupt handling as well as to avoid race condition between multiple HDMI detects from interrupt handler and userspace detect calls. This is a must for HDMI compliance also. There's no race, we have locks for this. And we already have a little bit of edid caching, and you're code won't add more caching for the force = true case. Which is why I wondered whether you've really seen improvements with this on latest upstream, and not just an older android tree. This caching is not useful, as in every detect call, we are doing a unset EDID, and doing a set EDID again. The actual reason behind multiple HDMI EDID reads is detect() getting called from user space only.So every time there is a detect call, there is HDMI EDID read. We should read EDID only on hotplug, cache it, and reuse it until hot unplug. But that's not what your patch is doing. You drop the cache when force is set in -detect, which is always the case when called on userspace's behalf. That's why I wondered whether you've managed to measure any real improvement here. Actually the plan is to use this force for GEN 6 HW only, where the hotplug doesn't work reliably (I remember our last conversation on some old HW which doesn't support HPD properly). For vlv+, we can (will) use only the cached EDID. Ok, once more: HDMI hpd is unreliable everywhere. I have a gen7 here which is half-busted it seems, and we've found examples for every single platform that supports hdmi out there. The problem isn't necessarily spec compliant HDMI sinks, but all the other crap ppl like to plug in. Yes this means we'll not be spec compliant, but if we have reality vs. spec, reality wins. At least in upstream. We have tested HPD with several HDMI monitors for VLV, CHV SKL and now for BXT also. We are getting reliable hotplugs and unplugs across these platforms, with accurate information on long/short pulses. Can you please give some details about what is your observation ? Its very important for the Android projects to comply with the spec due to certification pressure from customers. And we can get a common path for us, if we know what exactly is the problem. But for sure we cant ignore this factor that compliance is essential. Well we've tried this a few years back and had to revert on all machines because somehow hdp signalling isn't reliable. It might have been trouble with non-spec compliant sinks, but people where still annoyed about them no longer working. And I have a HP LP2475w here which is affected it seems: When unpluggint the hpd irq sometimes doesn't happen. And yes this is with a hdmi sink connector, not some hdmi-dvi cable or some other horror show. Last time I looked at it the hpd status bits where also unreliable (i.e. hpd indicated disconnected when the screen was clearly connected and working). Another hdmi screen I have here works. So yeah it's a sink problem, it's probably shitty/broken hw, but it means that it's completely independant of the platform. This means we _have_ to be spec incompliant to make real world hw word, and for upstream real world hw always beats specs. Which means I really can't merge any patch which assumes that hdmi hpd works. Or we figure out what has been broken with these screens and try to re-enable, but then we need to try this on every platfrom we support hdmi on since it's a clearly a sink problem. Also the goal should be to keep things cache for a few calls from userspace (since often it pokes a few times in a row unfortuantely), for which we need a proper timeout to clear the edid again. Can you please let us know why ? Why do we need to clear this EDID caching ? We should clear it only in the next hot-unplug, and maintain this cached EDID for all userspace detect operations. I believe as long as we have the state machine maintained, we need not to clear it. hotplug is not reliable, at least not outside of labs and validation testers. And your code here throws the cached edid away every time force = true is set, which is pretty much always. At least on upstream. The only place where we don't set force is in the poll worker, and that's only run when we have a hpd storm. -Daniel The new code doesn't throw away cached EDID for platform's GEN6 but the current code does that, in every detect call. Hm, I didn't see that gen6 check in your patches, where is it? Thanks, Daniel The current state machine is: = 1. Hotplug - Unset EDID, Read EDID, Set edid 2. all detect calls - Unset EDID, read EDID, Set EDID 3. Hotunplug - Unset EDID The state
Re: [Intel-gfx] [PATCH 2/2 i-g-t] lib/igt.cocci: Add 64-bit and float compare functions
On Fri, Jul 03, 2015 at 01:52:04PM -0300, Paulo Zanoni wrote: 2015-07-03 6:23 GMT-03:00 Dave Gordon david.s.gor...@intel.com: On 01/07/15 14:02, Daniel Vetter wrote: On Tue, Jun 30, 2015 at 11:14:54AM -0300, Paulo Zanoni wrote: 2015-06-30 10:54 GMT-03:00 Chris Wilson ch...@chris-wilson.co.uk: On Tue, Jun 30, 2015 at 02:41:09PM +0100, Michel Thierry wrote: @@ -1109,7 +1109,7 @@ static void setup_sink_crc(void) set_mode_for_params(prim_mode_params); sink_crc.fd = igt_debugfs_open(i915_sink_crc_eDP1, O_RDONLY); - igt_assert(sink_crc.fd = 0); + igt_assert_lte(0, sink_crc.fd); This one is wrong, and similar transformations. Maybe I'm not intelligent enough, but I _really_ think these inequality comparison macros are very hard to read, and the value they add does not compensate the readability problem they bring, especially since, as you pointed, in a lot of cases, the errno is what's important. I'd love to _not_ have that on IGT. The fact that you and Michel are discussing whether the macro is correct or not kinda proves my point on readability. I don't really want to check which one of you is correct because it's going to take some time reading the macro definition, and I've done it before and didn't like it. Reading the plain original assertion is always easy and instantaneous. Also, most of the assertions on IGT are just in case assertions that should probably never happen. I'm in favor of the idea that we should only instrument the important assertions that are likely to fail, while all the others should just be readable. Imo igt_assert_cmpint was definitely useful for all the did the right value land testcase. Many of those run in a loop and it's really useful to see what the expected vs. real value is imo. It has gotten a bit out of hand though, and some of the igt.cocci transforms that have been added where plain wrong. But ignoring those hiccups I still think this is somewhat useful. -Daniel At another company where we were trying to do pretty much this, we defined the assert-comparison macro to take the comparison operator as one of the arguments, thus not destroying readability quite as much: thusassert(a = b); was transformed to insist(a, =, b); So the order of operands and the specific comparator remain clearly visible, rather than being interchanged or logically inverted, but the macro can still report both the expected and actual values, and the text of the expressions used for each of them and the comparator. I like the idea, so I decided to look at how to implement that. I discovered that igt_assert_cmpint() used to be exactly what you described. Later we added the ncmp argument and started favoring the usage of _lte everywhere... Well I was the one who added igt_assert_cmpint, but I didn't add all the _lte/gte/eq variants. I don't have a personal opinion about this so I'm totally open to going back to only igt_assert_cmpint everywhere (with cocci this is easy). But we'd need someone to push the discussion and get acks from everyone who seems to care (you have mine already). Matt Roper and Thomas Wood are probably the ones to poke. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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 v3 5/5] drm/i915: Expose I915_EXEC_RESOURCE_STREAMER flag
On Thu, Jul 02, 2015 at 11:15:40AM +0100, Chris Wilson wrote: On Wed, Jul 01, 2015 at 10:12:23AM +0300, Abdiel Janulgue wrote: Ensures that the batch buffer is executed by the resource streamer v2: Don't skip 115 for the exec flags (Jani Nikula) v3: Use HAS_RESOURCE_STREAMER macro for execbuf validation (Chris Wilson) Testcase: igt/gem_exec_params Cc: Jani Nikula jani.nik...@intel.com Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Abdiel Janulgue abdiel.janul...@linux.intel.com This no longer applies (unrecognised base). Honestly, I would prefer 45 squashed together, or 4 after 5 so that we do not declare HAS_RESOURCE_STREAMER before we accept the RS execbuf. Minor bit of patch reordering, but the code in 4 looks ok, so Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk # for 4/5 Yeah I just reordered 5 to go before 4. Series merged to dinq, thanks. Abdiel can you pls push the corresponding igts (or ask Thomas to do it for you)? -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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] [RFC] drm/i915: Handle HPD when it has actually occurred
On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Nice find, this sounds really intrigueing, at least for cpt/ibx platforms. I'm not sure whether what will happen with atom/i9xx platforms though since the irq bits are different there. But at least bxt has a FIXME comment that suggest we do need to save the sticky bits on those platforms too. If we can fix this up for all platforms then I think a subsequent patch could try to re-enable the hpd checks in the hdmi -detect function and make use spec compliant. Then after maybe 1-2 kernel releases of testing we'll know whether it really works. But I'd really want to enable this everywhere just to have maximal test coverage - we did have reports on all platforms so it seems a generic issue. Thanks, Daniel Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir SDE_AUDIO_POWER_MASK_CPT) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation 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] [RFC] drm/i915: Handle HPD when it has actually occurred
On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } Deja vu. I think I have the same patch (also for IBX) in my stalled (and never posted) port A HPD branch. So yeah, I think this makes sense. You can also move the dig_hotplug_reg, pin_mask, and long_mask declarations into the if block since they're not needed elsewhere. if (pch_iir SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir SDE_AUDIO_POWER_MASK_CPT) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- 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] [RFC] drm/i915: Handle HPD when it has actually occurred
On 7/6/2015 2:19 PM, Ville Syrjälä wrote: On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(pin_mask, long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } Deja vu. I think I have the same patch (also for IBX) in my stalled (and never posted) port A HPD branch. So yeah, I think this makes sense. You can also move the dig_hotplug_reg, pin_mask, and long_mask declarations into the if block since they're not needed elsewhere. Sure. Do you think I should add this for ibx as well? if (pch_iir SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir SDE_AUDIO_POWER_MASK_CPT) -- 1.7.10.4 ___ 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] [RFC 6/8] drm/i915: Calculate ILK-style watermarks during atomic check (v2)
On Wed, Jul 01, 2015 at 07:25:59PM -0700, Matt Roper wrote: Calculate pipe watermarks during atomic calculation phase, based on the contents of the atomic transaction's state structure. We still program the watermarks at the same time we did before, but the computation now happens much earlier. While this patch isn't too exciting by itself, it paves the way for future patches. The eventual goal (which will be realized in future patches in this series) is to calculate multiple sets up watermark values up front, and then program them at different times (pre- vs post-vblank) on the platforms that need a two-step watermark update. While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since this function only applies to ILK-style watermarks and we have a completely different function for SKL-style watermarks. Note that the original code had a memcmp() in ilk_update_wm() to avoid calling ilk_program_watermarks() if the watermarks hadn't changed. This memcmp vanishes here, which means we may do some unnecessary result generation and merging in cases where watermarks didn't change, but the lower-level function ilk_write_wm_values already makes sure that we don't actually try to program the watermark registers again. v2: Squash a few commits from the original series together; no longer leave pre-calculated wm's in a separate temporary structure since it's easier to follow the logic if we just cut over to using the pre-calculated values directly. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 6 +++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_pm.c | 87 ++-- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6aa8083..2774976 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -621,6 +621,8 @@ struct drm_i915_display_funcs { int target, int refclk, struct dpll *match_clock, struct dpll *best_clock); + int (*compute_pipe_wm)(struct drm_crtc *crtc, +struct drm_atomic_state *state); All the new callbacks you add here are per-crtc, but we might want to rebalance the fifo space on some platforms where that's not perfectly per-crtc. Otoh that can wait until someone actually writes that code, maybe we'll decide to only rebalance wm when we need to do a modeset anyway. I think we can stick with this for now. -Daniel void (*update_wm)(struct drm_crtc *crtc); void (*update_sprite_wm)(struct drm_plane *plane, struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 36ae3f7..46b62cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11857,6 +11857,12 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, return ret; } + if (dev_priv-display.compute_pipe_wm) { + ret = dev_priv-display.compute_pipe_wm(crtc, state); + if (ret) + return ret; + } + return intel_atomic_setup_scalers(dev, intel_crtc, pipe_config); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c23cf7d..335b24b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1445,6 +1445,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state, int intel_atomic_setup_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); +int intel_check_crtc(struct drm_crtc *crtc, + struct drm_crtc_state *state); /* intel_atomic_plane.c */ struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0e28806..c6e735f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2039,9 +2039,11 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, const struct intel_crtc *intel_crtc, int level, struct intel_crtc_state *cstate, + struct intel_plane_state *pristate, + struct intel_plane_state *sprstate, + struct intel_plane_state *curstate, struct intel_wm_level *result) { - struct intel_plane *intel_plane; uint16_t pri_latency = dev_priv-wm.pri_latency[level]; uint16_t spr_latency = dev_priv-wm.spr_latency[level];
Re: [Intel-gfx] [PATCH 1/9] drm/i915: Check pixel clock when setting mode for DP
On Mon, Jul 06, 2015 at 12:15:25PM +0530, Sivakumar Thulasimani wrote: On 7/3/2015 6:27 PM, Ville Syrjälä wrote: On Fri, Jul 03, 2015 at 02:35:49PM +0300, Mika Kahola wrote: It is possible the we request to have a mode that has higher pixel clock than our HW can support. This patch checks if requested pixel clock is lower than the one supported by the HW. The requested mode is discarded if we cannot support the requested pixel clock. This patch applies to DisplayPort. Signed-off-by: Mika Kahola mika.kah...@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 25 - 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fcc64e5..2e55dff 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -197,6 +197,26 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; } +static int +intel_dp_max_pixclk(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = intel_dig_port-base; + struct drm_device *dev = encoder-base.dev; + struct drm_crtc *crtc = intel_dig_port-base.base.crtc; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (IS_CHERRYVIEW(dev)) + return DIV_ROUND_UP(dev_priv-max_cdclk_freq * 100, 95); Maybe we should precompute this stuff and store as max_dotclock into dev_priv? It has really nothing to do with DP. + else if (IS_VALLEYVIEW(dev)) + return DIV_ROUND_UP(dev_priv-max_cdclk_freq * 100, 90); + else if (IS_BROADWELL(dev) intel_crtc-config-ips_enabled) You can't look at the current crtc config at this point. Here we just need to consider the max we can support under any conditions and filter the modes based on that. That does mean that under some circumstances not all of the validated modes will actually work, but there's really nothing sensible we can do about that. In the specific case of IPS, we can always choose to disable it at modeset time if the mode would otherwise exceed the limit. So IPS is never a good reason for rejecting a mode. + return DIV_ROUND_UP(dev_priv-max_cdclk_freq * 100, 95); + else + return dev_priv-max_cdclk_freq; 90% is the correct limit for all older platforms. Exceptions are CHV which has the 95% limit, and starting from HSW+ we should be able to handle 100%. For gen2/3 we also have the option of using double wide mode which means the limit there should be 2 * cdclk * 9 / 10. +} + static enum drm_mode_status intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -206,6 +226,7 @@ intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *fixed_mode = intel_connector-panel.fixed_mode; int target_clock = mode-clock; int max_rate, mode_rate, max_lanes, max_link_clock; + int max_pixclk; if (is_edp(intel_dp) fixed_mode) { if (mode-hdisplay fixed_mode-hdisplay) @@ -223,7 +244,9 @@ intel_dp_mode_valid(struct drm_connector *connector, max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); mode_rate = intel_dp_link_required(target_clock, 18); - if (mode_rate max_rate) + max_pixclk = intel_dp_max_pixclk(intel_dp); + + if ((mode_rate max_rate) || (target_clock max_pixclk)) return MODE_CLOCK_HIGH; if (mode-clock 1) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx shouldn't we expect that only modes that were returned as valid through appropriate calls will be received as part of set_mode ? i.e in case of dp through the intel_dp_mode_valid through the .mode_valid callback ? No, the user is free to supply a totally custom mode. -- 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] drm/i915: set FDI translations to NULL on SKL
On Fri, Jul 03, 2015 at 12:31:30PM -0300, Paulo Zanoni wrote: From: Paulo Zanoni paulo.r.zan...@intel.com drivers/gpu/drm/i915/intel_ddi.c: In function ‘intel_prepare_ddi’: drivers/gpu/drm/i915/intel_ddi.c:517:6: warning: ‘ddi_translations_fdi’ may be used uninitialized in this function [-Wmaybe-uninitialized] if (ddi_translations_fdi) ^ drivers/gpu/drm/i915/intel_ddi.c:446:30: note: ‘ddi_translations_fdi’ was declared here const struct ddi_buf_trans *ddi_translations_fdi; ^ This line used to be there, but was removed by: commit f8896f5d58e64bfd3c2b5f7c5ba5c3f3967e93c7 Author: David Weinehall david.weineh...@linux.intel.com Date: Thu Jun 25 11:11:03 2015 +030 drm/i915/skl: Buffer translation improvements Cc: David Weinehall david.weineh...@linux.intel.com Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com Queued for -next, thanks for the patch. -Daniel --- drivers/gpu/drm/i915/intel_ddi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 15fc66a..782310f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -458,6 +458,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, INTEL_OUTPUT_HDMI); return; } else if (IS_SKYLAKE(dev)) { + ddi_translations_fdi = NULL; ddi_translations_dp = skl_get_buf_trans_dp(dev, n_dp_entries); ddi_translations_edp = -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation 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 2/2] drm/i915/hotplug: document the hotplug handling in the driver
On Mon, Jul 06, 2015 at 12:26:15PM +0530, Sivakumar Thulasimani wrote: On 7/2/2015 6:35 PM, Jani Nikula wrote: Add an overview of the drm/i915 hotplug handling. Signed-off-by: Jani Nikula jani.nik...@intel.com --- Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/i915/intel_hotplug.c | 39 2 files changed, 44 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index c0312cbd023d..e82205ee3d5f 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -4045,6 +4045,11 @@ int num_ioctls;/synopsis /para /sect2 sect2 +titleHotplug/title +!Pdrivers/gpu/drm/i915/intel_hotplug.c Hotplug +!Idrivers/gpu/drm/i915/intel_hotplug.c + /sect2 + sect2 titleHigh Definition Audio/title !Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port !Idrivers/gpu/drm/i915/intel_audio.c diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 3c53aac71d98..bac91a158ca2 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -29,6 +29,45 @@ #include i915_drv.h #include intel_drv.h +/** + * DOC: Hotplug + * + * Simply put, hotplug occurs when a display is connected to or disconnected + * from the system. However, there may be adapters and docking stations and + * Display Port short pulses and MST devices involved, complicating matters. + * + * Hotplug in i915 is handled in many different levels of abstraction. + * + * The platform dependent interrupt handling code in i915_irq.c enables, + * disables, and does preliminary handling of the interrupts. The interrupt + * handlers gather the hotplug detect (HPD) information from relevant registers + * into a platform independent mask of hotplug pins that have fired. + * + * The platform independent interrupt handler intel_hpd_irq_handler() in + * intel_hotplug.c does hotplug irq storm detection and mitigation, and passes + * further processing to appropriate bottom halves (Display Port specific and + * regular hotplug). + * + * The Display Port work function i915_digport_work_func() calls into + * intel_dp_hpd_pulse() via hooks, which handles DP short pulses and DP MST long + * pulses, with failures and non-MST long pulses triggering regular hotplug + * processing on the connector. + * + * The regular hotplug work function i915_hotplug_work_func() calls connector + * detect hooks, and, if connector status changes, triggers sending of hotplug + * uevent to userspace via drm_kms_helper_hotplug_event(). + * + * Finally, the userspace is responsible for triggering a modeset upon receiving + * the hotplug uevent, disabling or enabling the crtc as needed. + * + * The hotplug interrupt storm detection and mitigation code keeps track of the + * number of interrupts per hotplug pin per a period of time, and if the number + * of interrupts exceeds a certain threshold, the interrupt is disabled for a + * while before being re-enabled. The intention is to mitigate issues raising + * from broken hardware triggering massive amounts of interrupts and grinding + * the system to a halt. + */ + enum port intel_hpd_pin_to_port(enum hpd_pin pin) { switch (pin) { can we add that HPD storm is not expected in case of Displayport as discussed in other thread and so is not handled in i915_digport_work_func ? Good suggestion, but Jani's on vacation now for a few weeks. Can you pls submit a follow-up patch to add that? I've merged these two meanwhile. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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 RESEND FOR THE Nth AND LAST TIME 1/5] drm/i915/opregion: use BUILD_BUG_ON to verify mailbox struct sizes
On Thu, Jul 02, 2015 at 03:48:50PM +0100, Chris Wilson wrote: On Thu, Jul 02, 2015 at 05:43:21PM +0300, Jani Nikula wrote: Signed-off-by: Jani Nikula jani.nik...@intel.com 25 code looks correct, but haven't crosschecked with the new OpRegion spec, so Acked-by: Chris Wilson ch...@chris-wilson.co.uk The others are just small cleanups, so Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk All queued for -next, thanks for the patch. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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/2] drm/i915: On fb alloc failure, unref gem object where it gets refed
On Sat, Jul 04, 2015 at 11:50:58AM +0200, Lukas Wunner wrote: Currently when allocating a framebuffer fails, the gem object gets unrefed at the bottom of the call chain in __intel_framebuffer_create, not where it gets refed, which is in intel_framebuffer_create_for_mode (via i915_gem_alloc_object) and in intel_user_framebuffer_create (via drm_gem_object_lookup). This invites mistakes: As discovered by Tvrtko Ursulin, a double unref has sneaked into intelfb_alloc (which calls __intel_framebuffer_create). As suggested by Ville Syrjälä, improve code clarity by moving the unref away from __intel_framebuffer_create to where the gem object gets refed. Signed-off-by: Lukas Wunner lu...@wunner.de Fixes: a8bb6818270c (drm/i915: Fix error path leak in fbdev fb allocation) Cc: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@intel.com Cc: Ville Syrjälä ville.syrj...@linux.intel.com Cc: Daniel Vetter dan...@ffwll.ch Please keep a record of the changes you do to the patch so I know what to look out for. Just reving the patch revision alone doesn't add much information for reviewers/maintainers. Thanks, Daniel --- drivers/gpu/drm/i915/intel_display.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9079fcd..d597afa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8876,20 +8876,17 @@ __intel_framebuffer_create(struct drm_device *dev, int ret; intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); - if (!intel_fb) { - drm_gem_object_unreference(obj-base); + if (!intel_fb) return ERR_PTR(-ENOMEM); - } ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); if (ret) goto err; return intel_fb-base; + err: - drm_gem_object_unreference(obj-base); kfree(intel_fb); - return ERR_PTR(ret); } @@ -8929,6 +8926,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, struct drm_display_mode *mode, int depth, int bpp) { + struct drm_framebuffer *fb; struct drm_i915_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = { 0 }; @@ -8943,7 +8941,11 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, bpp); mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); - return intel_framebuffer_create(dev, mode_cmd, obj); + fb = intel_framebuffer_create(dev, mode_cmd, obj); + if (IS_ERR(fb)) + drm_gem_object_unreference_unlocked(obj-base); + + return fb; } static struct drm_framebuffer * @@ -13379,6 +13381,7 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, struct drm_mode_fb_cmd2 *mode_cmd) { + struct drm_framebuffer *fb; struct drm_i915_gem_object *obj; obj = to_intel_bo(drm_gem_object_lookup(dev, filp, @@ -13386,7 +13389,11 @@ intel_user_framebuffer_create(struct drm_device *dev, if (obj-base == NULL) return ERR_PTR(-ENOENT); - return intel_framebuffer_create(dev, mode_cmd, obj); + fb = intel_framebuffer_create(dev, mode_cmd, obj); + if (IS_ERR(fb)) + drm_gem_object_unreference_unlocked(obj-base); + + return fb; } static void intel_output_poll_changed(struct drm_device *dev) -- 2.1.0 -- Daniel Vetter Software Engineer, Intel Corporation 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 3/3] drm/i915: Read HDMI EDID only when required
On 7/6/2015 1:08 PM, Daniel Vetter wrote: On Thu, Jul 02, 2015 at 08:24:12AM +0530, Sharma, Shashank wrote: Regards Shashank On 7/1/2015 6:26 PM, Daniel Vetter wrote: On Tue, Jun 30, 2015 at 09:49:57PM +0530, Shashank Sharma wrote: Userspace always sets force. Are you sure this actually improves anything? Yes we do. We have had this code for commercial projects, and that's really important to have proper interrupt handling as well as to avoid race condition between multiple HDMI detects from interrupt handler and userspace detect calls. This is a must for HDMI compliance also. There's no race, we have locks for this. And we already have a little bit of edid caching, and you're code won't add more caching for the force = true case. Which is why I wondered whether you've really seen improvements with this on latest upstream, and not just an older android tree. This caching is not useful, as in every detect call, we are doing a unset EDID, and doing a set EDID again. The actual reason behind multiple HDMI EDID reads is detect() getting called from user space only.So every time there is a detect call, there is HDMI EDID read. We should read EDID only on hotplug, cache it, and reuse it until hot unplug. But that's not what your patch is doing. You drop the cache when force is set in -detect, which is always the case when called on userspace's behalf. That's why I wondered whether you've managed to measure any real improvement here. Actually the plan is to use this force for GEN 6 HW only, where the hotplug doesn't work reliably (I remember our last conversation on some old HW which doesn't support HPD properly). For vlv+, we can (will) use only the cached EDID. Ok, once more: HDMI hpd is unreliable everywhere. I have a gen7 here which is half-busted it seems, and we've found examples for every single platform that supports hdmi out there. The problem isn't necessarily spec compliant HDMI sinks, but all the other crap ppl like to plug in. Yes this means we'll not be spec compliant, but if we have reality vs. spec, reality wins. At least in upstream. We have tested HPD with several HDMI monitors for VLV, CHV SKL and now for BXT also. We are getting reliable hotplugs and unplugs across these platforms, with accurate information on long/short pulses. Can you please give some details about what is your observation ? Its very important for the Android projects to comply with the spec due to certification pressure from customers. And we can get a common path for us, if we know what exactly is the problem. But for sure we cant ignore this factor that compliance is essential. Well we've tried this a few years back and had to revert on all machines because somehow hdp signalling isn't reliable. It might have been trouble with non-spec compliant sinks, but people where still annoyed about them no longer working. And I have a HP LP2475w here which is affected it seems: When unpluggint the hpd irq sometimes doesn't happen. And yes this is with a hdmi sink connector, not some hdmi-dvi cable or some other horror show. Last time I looked at it the hpd status bits where also unreliable (i.e. hpd indicated disconnected when the screen was clearly connected and working). Another hdmi screen I have here works. So yeah it's a sink problem, it's probably shitty/broken hw, but it means that it's completely independant of the platform. I see this problem with SKL HPD also.. and I figured out writing again and again to the port_hpd_hotplug stat somehow screws the state of hotplug. Currently we update to that reg for any interrupt. After putting a check to write to that reg only if a real hpd is triggered, it works good. Please check: [PATCH] [RFC] drm/i915: Handle HPD when it has actually occurred This means we _have_ to be spec incompliant to make real world hw word, and for upstream real world hw always beats specs. Which means I really can't merge any patch which assumes that hdmi hpd works. Or we figure out what has been broken with these screens and try to re-enable, but then we need to try this on every platfrom we support hdmi on since it's a clearly a sink problem. Also the goal should be to keep things cache for a few calls from userspace (since often it pokes a few times in a row unfortuantely), for which we need a proper timeout to clear the edid again. Can you please let us know why ? Why do we need to clear this EDID caching ? We should clear it only in the next hot-unplug, and maintain this cached EDID for all userspace detect operations. I believe as long as we have the state machine maintained, we need not to clear it. hotplug is not reliable, at least not outside of labs and validation testers. And your code here throws the cached edid away every time force = true is set, which is pretty much always. At least on upstream. The only place where we don't set force is in the poll worker, and that's only run when we have a hpd storm. -Daniel The new code doesn't throw away cached
Re: [Intel-gfx] [PATCH v3 2/5] drm: Add private data field to trace control block
On Fri, Jul 03, 2015 at 03:33:31AM +0300, Dmitry V. Levin wrote: On Wed, Jul 01, 2015 at 02:52:45PM +0200, Patrik Jakobsson wrote: [...] --- a/defs.h +++ b/defs.h @@ -266,6 +266,13 @@ struct tcb { int u_error;/* Error code */ long scno; /* System call number */ long u_arg[MAX_ARGS]; /* System call arguments */ + + /* +* Private data for the decoding functions of the syscall. TCB core does +* _not_ handle allocation / deallocation of this data. +*/ + void *priv_data; + This will result to memory leaks if droptcb() is called before the syscall parser that allocated memory had a chance to deallocate it. As this data is no longer relevant after leaving trace_syscall_exiting(), I suggest to perform deallocation directly from trace_syscall_exiting. This API could be made more flexible by adding another pointer - the function to be called to deallocate memory, e.g. struct tcb { ... void *priv_data; void (*free_priv_data)(void *); ... }; ... void free_priv_data(struct tcb *tcp) { if (tcp-priv_data) { if (tcp-free_priv_data) { tcp-free_priv_data(tcp-priv_data); tcp-free_priv_data = NULL; } tcp-priv_data = NULL; } } ... droptcb(struct tcb *tcp) { ... free_priv_data(tcp); ... } ... trace_syscall_exiting(struct tcb *tcp) { ... ret: free_priv_data(tcp); ... } [...] On Wed, Jul 01, 2015 at 02:52:46PM +0200, Patrik Jakobsson wrote: Yes, that's more robust. I was afraid it would be too intrusive. * Makefile.am: Add compilation of drm.c * defs.h: Declarations of drm functions * drm.c: Utility functions for drm driver detection * io.c: Dispatch drm ioctls * ioctl.c: Distpatch generic and driver specific ioctls This is not quite a GNU style changelog entry. Please have a look at http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html and examples in strace.git history. [...] I'll get that sorted out. +#include defs.h + +#include drm.h +#include linux/limits.h Please include sys/param.h instead of linux/limits.h. Yup +#define DRM_MAX_NAME_LEN 128 + +struct drm_ioctl_priv { + char name[DRM_MAX_NAME_LEN]; +}; + +inline int drm_is_priv(const unsigned int num) +{ + return (_IOC_NR(num) = DRM_COMMAND_BASE + _IOC_NR(num) DRM_COMMAND_END); +} + +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t bufsize) +{ + char path[PATH_MAX]; + char link[PATH_MAX]; + int ret; + + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1); + if (ret 0) + return ret; + + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver, +basename(path)); + + ret = readlink(link, path, PATH_MAX - 1); + if (ret 0) + return ret; + + path[ret] = '\0'; + strncpy(name, basename(path), bufsize); + + return 0; +} I think this is getting too complicated. This function could just return strdup(basename(path)) or NULL in case of any error: static char * drm_get_driver_name(struct tcb *tcp, const char *name) { char path[PATH_MAX]; char link[PATH_MAX]; int ret; if (getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1) 0) return NULL; if (snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver, basename(path)) = PATH_MAX) return NULL; ret = readlink(link, path, PATH_MAX - 1); if (ret 0) return NULL; path[ret] = '\0'; return strdup(basename(path)); } That's nicer + +int drm_is_driver(struct tcb *tcp, const char *name) +{ + struct drm_ioctl_priv *priv; + int ret; + + /* +* If no private data is allocated we are detecting the driver name for +* the first time and must resolve it. +*/ + if (tcp-priv_data == NULL) { + tcp-priv_data = xcalloc(1, sizeof(struct drm_ioctl_priv)); xcalloc shouldn't be used if a potential memory allocation error is not fatal. In a parser that performs verbose syscall decoding no memory allocation error is fatal. Ok + priv = tcp-priv_data; + + ret = drm_get_driver_name(tcp, priv-name, DRM_MAX_NAME_LEN); + if (ret) + return 0; + } + + priv = tcp-priv_data; + + return strncmp(name, priv-name, DRM_MAX_NAME_LEN) == 0; Then with priv_data+free_priv_data interface this would looks smth like ... if (!tcp-priv_data) { tcp-priv_data = drm_get_driver_name(tcp, name); if (tcp-priv_data) { tcp-free_priv_data = free; } else { tcp-priv_data = (void *) ; tcp-free_priv_data
[Intel-gfx] [PATCH 3/7] drm/i915: Assign request ringbuf before pin
In preparation to make intel_lr_context_pin|unpin to accept requests, assign ringbuf into request before we call the pinning. v2: No need to unset ringbuf on error path (Chris) Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4139eb6..ace3a98 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -633,14 +633,14 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request { int ret; + request-ringbuf = request-ctx-engine[request-ring-id].ringbuf; + if (request-ctx != request-ring-default_context) { ret = intel_lr_context_pin(request-ring, request-ctx); if (ret) return ret; } - request-ringbuf = request-ctx-engine[request-ring-id].ringbuf; - return 0; } -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 7/7] drm/i915: Mark elsps submitted when they are pushed to hw
Now when we have requests this deep on call chain, we can mark the elsp being submitted when it actually is. Remove temp variable and readjust commenting to more closely fit to the code. v2: Avoid tmp variable and reduce number of writes (Chris) Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 36 +++- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 468f569..de35db6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -300,31 +300,29 @@ static void execlists_elsp_write(struct drm_i915_gem_request *rq0, struct intel_engine_cs *ring = rq0-ring; struct drm_device *dev = ring-dev; struct drm_i915_private *dev_priv = dev-dev_private; - uint64_t temp = 0; - uint32_t desc[4]; + uint64_t desc[2]; - /* XXX: You must always write both descriptors in the order below. */ - if (rq1) - temp = execlists_ctx_descriptor(rq1); - else - temp = 0; - desc[1] = (u32)(temp 32); - desc[0] = (u32)temp; + if (rq1) { + desc[1] = execlists_ctx_descriptor(rq1); + rq1-elsp_submitted++; + } else { + desc[1] = 0; + } - temp = execlists_ctx_descriptor(rq0); - desc[3] = (u32)(temp 32); - desc[2] = (u32)temp; + desc[0] = execlists_ctx_descriptor(rq0); + rq0-elsp_submitted++; + /* You must always write both descriptors in the order below. */ spin_lock(dev_priv-uncore.lock); intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); - I915_WRITE_FW(RING_ELSP(ring), desc[1]); - I915_WRITE_FW(RING_ELSP(ring), desc[0]); - I915_WRITE_FW(RING_ELSP(ring), desc[3]); + I915_WRITE_FW(RING_ELSP(ring), upper_32_bits(desc[1])); + I915_WRITE_FW(RING_ELSP(ring), lower_32_bits(desc[1])); + I915_WRITE_FW(RING_ELSP(ring), upper_32_bits(desc[0])); /* The context is automatically loaded after the following */ - I915_WRITE_FW(RING_ELSP(ring), desc[2]); + I915_WRITE_FW(RING_ELSP(ring), lower_32_bits(desc[0])); - /* ELSP is a wo register, so use another nearby reg for posting instead */ + /* ELSP is a wo register, use another nearby reg for posting */ POSTING_READ_FW(RING_EXECLIST_STATUS(ring)); intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); spin_unlock(dev_priv-uncore.lock); @@ -433,10 +431,6 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) WARN_ON(req1 req1-elsp_submitted); execlists_submit_requests(req0, req1); - - req0-elsp_submitted++; - if (req1) - req1-elsp_submitted++; } static bool execlists_check_remove_request(struct intel_engine_cs *ring, -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3] drm/i915/bxt: BUNs related to port PLL
On Mon, Jul 06, 2015 at 01:38:44PM +0530, Kannan, Vandana wrote: Hi Daniel, Is there any other change required in this patch to consider before merge? Please let me know. Oh I was kinda waiting for an ack from Imre. Merged now anyway. Btw for next time around please spell out BUN - not everyone knows what this means, especially outside of intel gfx teams (product teams, integration, customers, ...). And we write changelogs also for those external people. Maybe Implement latest Bspec updates for ... or similar. I've changed the summary for this patch. -Daniel - Vandana On 7/3/2015 10:23 AM, Kannan, Vandana wrote: Hi, Any other review comments on this patch? Do let me know. Siva and Sonika have given their R-b. Thanks, Vandana On 7/1/2015 4:41 PM, Sivakumar Thulasimani wrote: thanks for the changes. Reviewed-by: Sivakumar Thulasimani sivakumar.thulasim...@intel.com On 7/1/2015 5:02 PM, Vandana Kannan wrote: This patch contains changes based on 2 updates to the spec: Port PLL VCO restriction raised up to 6700. Port PLL now needs DCO amp override enable for all VCO frequencies. v2: Sonika's review comment addressed - dcoampovr_en_h variable not required Based on a discussion with Siva, the following changes have been made. - replace dco_amp var with #define BXT_DCO_AMPLITUDE - set pll10 in a single assignment v3: Move DCO amplitude default value to i915_reg.h. Suggested by Siva. Signed-off-by: Vandana Kannanvandana.kan...@intel.com Reviewed-by: Sonika Jindalsonika.jin...@intel.com [v2] --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ddi.c | 15 +-- drivers/gpu/drm/i915/intel_display.c | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ac985c5..d1b8928 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1211,6 +1211,7 @@ enum skl_disp_power_wells { #define PORT_PLL_LOCK_THRESHOLD_MASK0xe /* PORT_PLL_10_A */ #define PORT_PLL_DCO_AMP_OVR_EN_H(127) +#define PORT_PLL_DCO_AMP_DEFAULT15 #define PORT_PLL_DCO_AMP_MASK0x3c00 #define PORT_PLL_DCO_AMP(x)(x10) #define _PORT_PLL_BASE(port)_PORT3(port, _PORT_PLL_0_A,\ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 42c1487..9c05cc0 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1455,7 +1455,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, struct bxt_clk_div clk_div = {0}; int vco = 0; uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; -uint32_t dcoampovr_en_h, dco_amp, lanestagger; +uint32_t lanestagger; if (intel_encoder-type == INTEL_OUTPUT_HDMI) { intel_clock_t best_clock; @@ -1494,9 +1494,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; } -dco_amp = 15; -dcoampovr_en_h = 0; -if (vco = 620 vco = 648) { +if (vco = 620 vco = 670) { prop_coef = 4; int_coef = 9; gain_ctl = 3; @@ -1507,8 +1505,6 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, int_coef = 11; gain_ctl = 3; targ_cnt = 9; -if (vco = 480 vco 540) -dcoampovr_en_h = 1; } else if (vco == 540) { prop_coef = 3; int_coef = 8; @@ -1550,10 +1546,9 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state-dpll_hw_state.pll8 = targ_cnt; -if (dcoampovr_en_h) -crtc_state-dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H; - -crtc_state-dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp); +crtc_state-dpll_hw_state.pll10 = +PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT) +| PORT_PLL_DCO_AMP_OVR_EN_H; crtc_state-dpll_hw_state.pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eb665d7..e04be45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -409,7 +409,7 @@ static const intel_limit_t intel_limits_chv = { static const intel_limit_t intel_limits_bxt = { /* FIXME: find real dot limits */ .dot = { .min = 0, .max = INT_MAX }, -.vco = { .min = 480, .max = 648 }, +.vco = { .min = 480, .max = 670 }, .n = { .min = 1, .max = 1 }, .m1 = { .min = 2, .max = 2 }, /* FIXME: find real m2 limits */ -- regards, Sivakumar ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [Intel-gfx] [PATCH v2 0/4] drm/i915: Re-enable HDMI 12bpc
On Wed, Jul 01, 2015 at 09:08:15PM +0300, Imre Deak wrote: On Tue, 2015-06-30 at 15:33 +0300, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com Here's my second attempt at flipping HDMI 12bpc back on. In my last attempt [1] Imre found that lots of standard CEA modes (1080p60 etc.) no longer work on BXT due to the 12bpc port clock landing in a range that the DPLL can't generate. CHV has the same limitation but it doesn't do 12bpc so the situation there isn't as bad. This series attempts to work around this problem by falling back to 8bpc when the 1.5x port clock frequency turns out to be bad. Additionally we will from now on filter out any mode where both 8bpc and 12bpc port clock is bad. [1] http://lists.freedesktop.org/archives/intel-gfx/2015-June/068988.html Ville Syrjälä (4): drm/i915: Fix HDMI 12bpc and pixel repeat clock readout for DDI platforms drm/i915: Bump HDMI min port clock to 25 MHz drm/i915: Account for CHV/BXT DPLL clock limittions Revert drm/i915: Disable 12bpc hdmi for now drivers/gpu/drm/i915/intel_ddi.c | 49 +- drivers/gpu/drm/i915/intel_hdmi.c | 55 +++ 2 files changed, 63 insertions(+), 41 deletions(-) Looks ok to me. 12bpc modesets and the fall-back logic seems to work fine on BXT. On the series: Reviewed-and-tested-by: Imre Deak imre.d...@intel.com All merged to dinq, thanks. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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 1/7] drm/i915: add simple wrappers for stolen node insertion/removal
On Wed, Jul 01, 2015 at 05:15:20PM -0300, Paulo Zanoni wrote: From: Paulo Zanoni paulo.r.zan...@intel.com We want to move the FBC code out of i915_gem_stolen.c, but that code directly adds/removes stolen memory nodes. Let's create this abstraction, so i915_gme_stolen.c is still in control of all the stolen memory handling. These abstractions will also allow us to add locking assertions later. Requested-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com I guess you'll follow up with a nice kerneldoc patch for i915_gem_stolen? You're the expert on this code now ;-) Cheers, Daniel --- drivers/gpu/drm/i915/i915_drv.h| 4 drivers/gpu/drm/i915/i915_gem_stolen.c | 44 +- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1dbd957..b9de374 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3109,6 +3109,10 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev) } /* i915_gem_stolen.c */ +int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv, + struct drm_mm_node *node, u64 size, + unsigned alignment); +void i915_gem_stolen_remove_node(struct drm_mm_node *node); int i915_gem_init_stolen(struct drm_device *dev); int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp); void i915_gem_stolen_cleanup_compression(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 348ed5a..6b43234 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -42,6 +42,22 @@ * for is a boon. */ +int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv, + struct drm_mm_node *node, u64 size, + unsigned alignment) +{ + if (!drm_mm_initialized(dev_priv-mm.stolen)) + return -ENODEV; + + return drm_mm_insert_node(dev_priv-mm.stolen, node, size, alignment, + DRM_MM_SEARCH_DEFAULT); +} + +void i915_gem_stolen_remove_node(struct drm_mm_node *node) +{ + drm_mm_remove_node(node); +} + static unsigned long i915_stolen_to_physical(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; @@ -168,8 +184,7 @@ static int find_compression_threshold(struct drm_device *dev, */ /* Try to over-allocate to reduce reallocations and fragmentation. */ - ret = drm_mm_insert_node(dev_priv-mm.stolen, node, - size = 1, 4096, DRM_MM_SEARCH_DEFAULT); + ret = i915_gem_stolen_insert_node(dev_priv, node, size = 1, 4096); if (ret == 0) return compression_threshold; @@ -179,9 +194,7 @@ again: (fb_cpp == 2 compression_threshold == 2)) return 0; - ret = drm_mm_insert_node(dev_priv-mm.stolen, node, - size = 1, 4096, - DRM_MM_SEARCH_DEFAULT); + ret = i915_gem_stolen_insert_node(dev_priv, node, size = 1, 4096); if (ret INTEL_INFO(dev)-gen = 4) { return 0; } else if (ret) { @@ -218,8 +231,8 @@ static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp) if (!compressed_llb) goto err_fb; - ret = drm_mm_insert_node(dev_priv-mm.stolen, compressed_llb, - 4096, 4096, DRM_MM_SEARCH_DEFAULT); + ret = i915_gem_stolen_insert_node(dev_priv, compressed_llb, + 4096, 4096); if (ret) goto err_fb; @@ -240,7 +253,7 @@ static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp) err_fb: kfree(compressed_llb); - drm_mm_remove_node(dev_priv-fbc.compressed_fb); + i915_gem_stolen_remove_node(dev_priv-fbc.compressed_fb); err_llb: pr_info_once(drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n, size); return -ENOSPC; @@ -269,10 +282,10 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) if (dev_priv-fbc.uncompressed_size == 0) return; - drm_mm_remove_node(dev_priv-fbc.compressed_fb); + i915_gem_stolen_remove_node(dev_priv-fbc.compressed_fb); if (dev_priv-fbc.compressed_llb) { - drm_mm_remove_node(dev_priv-fbc.compressed_llb); + i915_gem_stolen_remove_node(dev_priv-fbc.compressed_llb); kfree(dev_priv-fbc.compressed_llb); } @@ -387,7 +400,7
Re: [Intel-gfx] [RFC 7/8] drm/i915: Allow final wm programming to be scheduled after next vblank (v2)
On Wed, Jul 01, 2015 at 07:26:00PM -0700, Matt Roper wrote: Add a simple mechanism to trigger final watermark updates in an asynchronous manner once the next vblank occurs. No platform types actually support atomic watermark programming until a future patch, so there should be no functional change yet; individual platforms will be converted to use this mechanism one-by-one in future patches. Note that we'll probably expand this to cover other post-vblank async tasks (like unpinning) at some point in the future. v2: Much simpler vblank mechanism than was used in the previous series; no need to allocate new heap structures. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 7 +++ drivers/gpu/drm/i915/i915_irq.c | 9 + drivers/gpu/drm/i915/intel_display.c | 30 ++ drivers/gpu/drm/i915/intel_drv.h | 4 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2774976..5ad942e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -628,6 +628,7 @@ struct drm_i915_display_funcs { struct drm_crtc *crtc, uint32_t sprite_width, uint32_t sprite_height, int pixel_size, bool enable, bool scaled); + void (*program_watermarks)(struct drm_i915_private *dev_priv); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); /* Returns the active state of the crtc, and if the crtc is active, @@ -2567,6 +2568,12 @@ struct drm_i915_cmd_table { #define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) #define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev)) +/* + * FIXME: Not all platforms have been transitioned to atomic watermark + * updates yet. + */ +#define HAS_ATOMIC_WM(dev_priv) (dev_priv-display.program_watermarks != NULL) HAS_FOO is generally hw features. I think especially for just this vfunc check is clearer to inline it. + #define GT_FREQUENCY_MULTIPLIER 50 #define GEN9_FREQ_SCALER 3 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..20c7260 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1452,6 +1452,15 @@ 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 drm_i915_private *dev_priv = to_i915(dev); + struct drm_crtc *crtc = dev_priv-pipe_to_crtc_mapping[pipe]; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (intel_crtc-need_vblank_wm_update) { + queue_work(dev_priv-wq, intel_crtc-wm_work); + intel_crtc-need_vblank_wm_update = false; We need some lock or some other means of sync to be able to cancel such an update if userspace submits the next atomic update. Otherwise this work might overwrite the intermediate wm values. Imo best would be if we createa a cancel_work_sync-like interface which ensures the work will be cancelled (when it's already scheduled) or won't ever get scheduled through our vblank handler. That would mirror the interface I have in mind for generic vblank workers, which imo should closely resemble the interface we have for delayed_work (for vblank work run in process context) and timers (for vblank run from hardirq context). + } + if (!drm_handle_vblank(dev, pipe)) return false; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 46b62cc..fa4373e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4737,6 +4737,10 @@ static void intel_post_plane_update(struct intel_crtc *crtc) struct drm_device *dev = crtc-base.dev; struct drm_plane *plane; + if (HAS_ATOMIC_WM(to_i915(dev))) + /* vblank handler will kick off workqueue task to update wm's */ + crtc-need_vblank_wm_update = true; + if (atomic-wait_vblank) intel_wait_for_vblank(dev, crtc-pipe); @@ -4745,7 +4749,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) if (atomic-disable_cxsr) cstate-wm.cxsr_allowed = true; - if (crtc-atomic.update_wm_post) + if (!HAS_ATOMIC_WM(to_i915(dev)) crtc-atomic.update_wm_post) intel_update_watermarks(crtc-base); if (atomic-update_fbc) { @@ -4757,9 +4761,10 @@ static void intel_post_plane_update(struct intel_crtc *crtc) if (atomic-post_enable_primary) intel_post_enable_primary(crtc-base); - drm_for_each_plane_mask(plane, dev, atomic-update_sprite_watermarks) -
Re: [Intel-gfx] [PATCH v3 5/5] drm/i915: Expose I915_EXEC_RESOURCE_STREAMER flag
On 6 July 2015 at 09:46, Abdiel Janulgue abdiel.janul...@linux.intel.com wrote: On 07/06/2015 11:28 AM, Daniel Vetter wrote: On Thu, Jul 02, 2015 at 11:15:40AM +0100, Chris Wilson wrote: On Wed, Jul 01, 2015 at 10:12:23AM +0300, Abdiel Janulgue wrote: Ensures that the batch buffer is executed by the resource streamer v2: Don't skip 115 for the exec flags (Jani Nikula) v3: Use HAS_RESOURCE_STREAMER macro for execbuf validation (Chris Wilson) Testcase: igt/gem_exec_params Cc: Jani Nikula jani.nik...@intel.com Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Abdiel Janulgue abdiel.janul...@linux.intel.com This no longer applies (unrecognised base). Honestly, I would prefer 45 squashed together, or 4 after 5 so that we do not declare HAS_RESOURCE_STREAMER before we accept the RS execbuf. Minor bit of patch reordering, but the code in 4 looks ok, so Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk # for 4/5 Yeah I just reordered 5 to go before 4. Series merged to dinq, thanks. Abdiel can you pls push the corresponding igts (or ask Thomas to do it for you)? Thank you! I don't have commit rights in igt, but here is the patch: http://lists.freedesktop.org/archives/intel-gfx/2015-June/068799.html Pushed, thanks. -Abdiel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/chv: fix HW readout of the port PLL fractional divider
On Thu, Jul 02, 2015 at 04:33:42PM +0300, Ville Syrjälä wrote: On Thu, Jul 02, 2015 at 02:29:58PM +0300, Imre Deak wrote: Ville noticed that the PLL HW readout code parsed the fractional divider value as if the fractional divider was always enabled. This may result in a port clock state check mismatch if the preceeding modeset disabled the fractional divider, but left a non-zero divider value in the register. Signed-off-by: Imre Deak imre.d...@intel.com Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com Queued for -fixes (with cc: stable), thanks for the patch. -Daniel --- drivers/gpu/drm/i915/intel_display.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5cc405d..2b7ebf1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8021,7 +8021,7 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc, int pipe = pipe_config-cpu_transcoder; enum dpio_channel port = vlv_pipe_to_channel(pipe); intel_clock_t clock; - u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2; + u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3; int refclk = 10; mutex_lock(dev_priv-sb_lock); @@ -8029,10 +8029,13 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc, pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port)); pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port)); pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port)); + pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port)); mutex_unlock(dev_priv-sb_lock); clock.m1 = (pll_dw1 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0; - clock.m2 = ((pll_dw0 0xff) 22) | (pll_dw2 0x3f); + clock.m2 = (pll_dw0 0xff) 22; + if (pll_dw3 DPIO_CHV_FRAC_DIV_EN) + clock.m2 |= pll_dw2 0x3f; clock.n = (pll_dw1 DPIO_CHV_N_DIV_SHIFT) 0xf; clock.p1 = (cmn_dw13 DPIO_CHV_P1_DIV_SHIFT) 0x7; clock.p2 = (cmn_dw13 DPIO_CHV_P2_DIV_SHIFT) 0x1f; -- 2.1.4 -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation 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 v3 5/5] drm/i915: Expose I915_EXEC_RESOURCE_STREAMER flag
On 07/06/2015 11:28 AM, Daniel Vetter wrote: On Thu, Jul 02, 2015 at 11:15:40AM +0100, Chris Wilson wrote: On Wed, Jul 01, 2015 at 10:12:23AM +0300, Abdiel Janulgue wrote: Ensures that the batch buffer is executed by the resource streamer v2: Don't skip 115 for the exec flags (Jani Nikula) v3: Use HAS_RESOURCE_STREAMER macro for execbuf validation (Chris Wilson) Testcase: igt/gem_exec_params Cc: Jani Nikula jani.nik...@intel.com Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Abdiel Janulgue abdiel.janul...@linux.intel.com This no longer applies (unrecognised base). Honestly, I would prefer 45 squashed together, or 4 after 5 so that we do not declare HAS_RESOURCE_STREAMER before we accept the RS execbuf. Minor bit of patch reordering, but the code in 4 looks ok, so Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk # for 4/5 Yeah I just reordered 5 to go before 4. Series merged to dinq, thanks. Abdiel can you pls push the corresponding igts (or ask Thomas to do it for you)? Thank you! I don't have commit rights in igt, but here is the patch: http://lists.freedesktop.org/archives/intel-gfx/2015-June/068799.html -Abdiel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 7/7] drm/i915: Mark elsps submitted when they are pushed to hw
On Mon, Jul 06, 2015 at 10:25:17AM +0100, Chris Wilson wrote: On Mon, Jul 06, 2015 at 11:09:25AM +0300, Mika Kuoppala wrote: Now when we have requests this deep on call chain, we can mark the elsp being submitted when it actually is. Remove temp variable and readjust commenting to more closely fit to the code. v2: Avoid tmp variable and reduce number of writes (Chris) Cc: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com Looks cleaner to me, Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk In fact, nothing in the series scared me and with the two minor changes, might as well apply that r-b to the whole series. For the benefit of others, can you repost the contracted series with my r-b applied? -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] drm/i915/chv: fix HW readout of the port PLL fractional divider
On Mon, Jul 06, 2015 at 11:32:47AM +0200, Daniel Vetter wrote: On Thu, Jul 02, 2015 at 04:33:42PM +0300, Ville Syrjälä wrote: On Thu, Jul 02, 2015 at 02:29:58PM +0300, Imre Deak wrote: Ville noticed that the PLL HW readout code parsed the fractional divider value as if the fractional divider was always enabled. This may result in a port clock state check mismatch if the preceeding modeset disabled the fractional divider, but left a non-zero divider value in the register. Signed-off-by: Imre Deak imre.d...@intel.com Reviewed-by: Ville Syrjälä ville.syrj...@linux.intel.com Queued for -fixes (with cc: stable), thanks for the patch. Maybe doesn't justify stable, so dropped that again. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/7] drm/i915: Don't pass clock to DDI PLL select functions
From: Ville Syrjälä ville.syrj...@linux.intel.com All the *_ddi_pll_select() functions get passed the port_clock and pipe config as parameters. We only need to pass the pipe config, and the functions can dig up the port_clock themselves. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 0d3cc98..96fb472 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1262,9 +1262,10 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */, static bool hsw_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, - struct intel_encoder *intel_encoder, - int clock) + struct intel_encoder *intel_encoder) { + int clock = crtc_state-port_clock; + if (intel_encoder-type == INTEL_OUTPUT_HDMI) { struct intel_shared_dpll *pll; uint32_t val; @@ -1543,11 +1544,11 @@ skip_remaining_dividers: static bool skl_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, - struct intel_encoder *intel_encoder, - int clock) + struct intel_encoder *intel_encoder) { struct intel_shared_dpll *pll; uint32_t ctrl1, cfgcr1, cfgcr2; + int clock = crtc_state-port_clock; /* * See comment in intel_dpll_hw_state to understand why we always use 0 @@ -1635,14 +1636,14 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = { static bool bxt_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, - struct intel_encoder *intel_encoder, - int clock) + struct intel_encoder *intel_encoder) { struct intel_shared_dpll *pll; struct bxt_clk_div clk_div = {0}; int vco = 0; uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; uint32_t lanestagger; + int clock = crtc_state-port_clock; if (intel_encoder-type == INTEL_OUTPUT_HDMI) { intel_clock_t best_clock; @@ -1770,17 +1771,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, struct drm_device *dev = intel_crtc-base.dev; struct intel_encoder *intel_encoder = intel_ddi_get_crtc_new_encoder(crtc_state); - int clock = crtc_state-port_clock; if (IS_SKYLAKE(dev)) return skl_ddi_pll_select(intel_crtc, crtc_state, - intel_encoder, clock); + intel_encoder); else if (IS_BROXTON(dev)) return bxt_ddi_pll_select(intel_crtc, crtc_state, - intel_encoder, clock); + intel_encoder); else return hsw_ddi_pll_select(intel_crtc, crtc_state, - intel_encoder, clock); + intel_encoder); } void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 7/7] drm/i915: Kill intel_dp-{link_bw, rate_select}
From: Ville Syrjälä ville.syrj...@linux.intel.com We only need the link_bw/rate_select parameters when starting link training, and they should be computed based on the currently active config, so throw them out from intel_dp and just compute on demand. Toss in an extra debug print to see rate_select in addition to link_bw, as the latter may be 0 for eDP 1.4. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 39 - drivers/gpu/drm/i915/intel_dp_mst.c | 13 ++--- drivers/gpu/drm/i915/intel_drv.h| 2 -- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 46b734b..e88cec2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1342,6 +1342,19 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) return rate_to_index(rate, intel_dp-sink_rates); } +static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, + uint8_t *link_bw, uint8_t *rate_select) +{ + if (intel_dp-num_sink_rates) { + *link_bw = 0; + *rate_select = + intel_dp_rate_select(intel_dp, port_clock); + } else { + *link_bw = drm_dp_link_rate_to_bw_code(port_clock); + *rate_select = 0; + } +} + bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) @@ -1363,6 +1376,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, int link_avail, link_clock; int common_rates[DP_MAX_SUPPORTED_RATES] = {}; int common_len; + uint8_t link_bw, rate_select; common_len = intel_dp_common_rates(intel_dp, common_rates); @@ -1464,21 +1478,14 @@ found: pipe_config-lane_count = lane_count; - if (intel_dp-num_sink_rates) { - intel_dp-link_bw = 0; - intel_dp-rate_select = - intel_dp_rate_select(intel_dp, common_rates[clock]); - } else { - intel_dp-link_bw = - drm_dp_link_rate_to_bw_code(common_rates[clock]); - intel_dp-rate_select = 0; - } - pipe_config-pipe_bpp = bpp; pipe_config-port_clock = common_rates[clock]; - DRM_DEBUG_KMS(DP link bw %02x lane count %d clock %d bpp %d\n, - intel_dp-link_bw, pipe_config-lane_count, + intel_dp_compute_rate(intel_dp, pipe_config-port_clock, + link_bw, rate_select); + + DRM_DEBUG_KMS(DP link bw %02x rate select %02x lane count %d clock %d bpp %d\n, + link_bw, rate_select, pipe_config-lane_count, pipe_config-port_clock, bpp); DRM_DEBUG_KMS(DP link bw required %i available %i\n, mode_rate, link_avail); @@ -3587,19 +3594,23 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) int voltage_tries, loop_tries; uint32_t DP = intel_dp-DP; uint8_t link_config[2]; + uint8_t link_bw, rate_select; if (HAS_DDI(dev)) intel_ddi_prepare_link_retrain(encoder); + intel_dp_compute_rate(intel_dp, crtc-config-port_clock, + link_bw, rate_select); + /* Write the link configuration data */ - link_config[0] = intel_dp-link_bw; + link_config[0] = link_bw; link_config[1] = crtc-config-lane_count; if (drm_dp_enhanced_frame_cap(intel_dp-dpcd)) link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; drm_dp_dpcd_write(intel_dp-aux, DP_LINK_BW_SET, link_config, 2); if (intel_dp-num_sink_rates) drm_dp_dpcd_write(intel_dp-aux, DP_LINK_RATE_SET, - intel_dp-rate_select, 1); + rate_select, 1); link_config[0] = 0; link_config[1] = DP_SET_ANSI_8B10B; diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index eeda730..3dc08da 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -38,7 +38,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_dp *intel_dp = intel_dig_port-dp; struct drm_atomic_state *state; int bpp, i; - int lane_count, slots, rate; + int lane_count, slots; struct drm_display_mode *adjusted_mode = pipe_config-base.adjusted_mode; struct drm_connector *drm_connector; struct intel_connector *connector, *found = NULL; @@ -55,20 +55,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, */ lane_count = drm_dp_max_lane_count(intel_dp-dpcd); - rate = intel_dp_max_link_rate(intel_dp); - - if (intel_dp-num_sink_rates) { -
[Intel-gfx] [PATCH 0/7] drm/i915: Move DP link parameters out from intel_dp
From: Ville Syrjälä ville.syrj...@linux.intel.com While working on CHV DPIO powergating I relized DP .compute_config() was clobbering lane_count etc. stored in intel_dp. This could cause problems if we do the .compute_config() but later fail the modeset for some reason. Any subsequent link re-training might then fail if intel_dp-lane_count etc. got changed. The reason I ran into this during the DPIO powergating work was that I may need to know which lanes he active when shutting down the link. However .compute_config() already clobbered that information by the time I need it. By moving it to the pipe config we avoid that problem as well. I also cleaned up the limited color range handling a bit while I was in the neighborhood. Ville Syrjälä (7): drm/i915: Clean up DP/HDMI limited color range handling drm/i915: Don't use link_bw for PLL setup drm/i915: Don't pass clock to DDI PLL select functions drm/i915: Avoid confusion between DP and TRANS_DP_CTL in DP .get_config() drm/i915: Move intel_dp-lane_count into pipe_config drm/i915: Don't use link_bw to select between TP1 and TP3 drm/i915: Kill intel_dp-{link_bw,rate_select} drivers/gpu/drm/i915/i915_reg.h | 3 + drivers/gpu/drm/i915/intel_ddi.c | 41 drivers/gpu/drm/i915/intel_display.c | 7 +- drivers/gpu/drm/i915/intel_dp.c | 177 --- drivers/gpu/drm/i915/intel_dp_mst.c | 19 ++-- drivers/gpu/drm/i915/intel_drv.h | 9 +- drivers/gpu/drm/i915/intel_hdmi.c| 26 +++-- 7 files changed, 155 insertions(+), 127 deletions(-) -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/7] drm/i915: Don't use link_bw for PLL setup
From: Ville Syrjälä ville.syrj...@linux.intel.com Use port_clock instead of link_bw when picking the PLL parameters for DP. link_bw may be zero with an eDP 1.4 sink that supports DP_LINK_RATE_SET so we shouln't use it for anything other than feed it to the sink appropriately. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 11 -- drivers/gpu/drm/i915/intel_dp.c | 44 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9a40bfb..0d3cc98 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1574,17 +1574,14 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | wrpll_params.central_freq; } else if (intel_encoder-type == INTEL_OUTPUT_DISPLAYPORT) { - struct drm_encoder *encoder = intel_encoder-base; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - switch (intel_dp-link_bw) { - case DP_LINK_BW_1_62: + switch (crtc_state-port_clock / 2) { + case 81000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0); break; - case DP_LINK_BW_2_7: + case 135000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0); break; - case DP_LINK_BW_5_4: + case 27: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0); break; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index decefa1..3dd4342 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -48,28 +48,28 @@ #define INTEL_DP_RESOLUTION_FAILSAFE (3 INTEL_DP_RESOLUTION_SHIFT_MASK) struct dp_link_dpll { - int link_bw; + int clock; struct dpll dpll; }; static const struct dp_link_dpll gen4_dpll[] = { - { DP_LINK_BW_1_62, + { 162000, { .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } }, - { DP_LINK_BW_2_7, + { 27, { .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } } }; static const struct dp_link_dpll pch_dpll[] = { - { DP_LINK_BW_1_62, + { 162000, { .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } }, - { DP_LINK_BW_2_7, + { 27, { .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } } }; static const struct dp_link_dpll vlv_dpll[] = { - { DP_LINK_BW_1_62, + { 162000, { .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } }, - { DP_LINK_BW_2_7, + { 27, { .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } } }; @@ -83,11 +83,11 @@ static const struct dp_link_dpll chv_dpll[] = { * m2 is stored in fixed point format using formula below * (m2_int 22) | m2_fraction */ - { DP_LINK_BW_1_62, /* m2_int = 32, m2_fraction = 1677722 */ + { 162000, /* m2_int = 32, m2_fraction = 1677722 */ { .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x81a } }, - { DP_LINK_BW_2_7, /* m2_int = 27, m2_fraction = 0 */ + { 27, /* m2_int = 27, m2_fraction = 0 */ { .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } }, - { DP_LINK_BW_5_4, /* m2_int = 27, m2_fraction = 0 */ + { 54, /* m2_int = 27, m2_fraction = 0 */ { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; @@ -1099,7 +1099,7 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector) } static void -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock) +skl_edp_set_pll_config(struct intel_crtc_state *pipe_config) { u32 ctrl1; @@ -,7 +,7 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock) pipe_config-dpll_hw_state.cfgcr2 = 0; ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0); - switch (link_clock / 2) { + switch (pipe_config-port_clock / 2) { case 81000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0); @@ -1145,19 +1145,19 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock) } static void -hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config, int link_bw) +hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config) { memset(pipe_config-dpll_hw_state, 0, sizeof(pipe_config-dpll_hw_state)); - switch (link_bw) { - case DP_LINK_BW_1_62: + switch (pipe_config-port_clock / 2) { + case 81000:
[Intel-gfx] [PATCH 4/7] drm/i915: Avoid confusion between DP and TRANS_DP_CTL in DP .get_config()
From: Ville Syrjälä ville.syrj...@linux.intel.com Use a separate variable for the TRANS_DP_CTL value instead of reusing 'tmp' that otherwise contains the DP port register value. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3dd4342..b6ba02e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2245,13 +2245,14 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config-has_audio = tmp DP_AUDIO_OUTPUT_ENABLE port != PORT_A; if (HAS_PCH_CPT(dev) port != PORT_A) { - tmp = I915_READ(TRANS_DP_CTL(crtc-pipe)); - if (tmp TRANS_DP_HSYNC_ACTIVE_HIGH) + u32 trans_dp = I915_READ(TRANS_DP_CTL(crtc-pipe)); + + if (trans_dp TRANS_DP_HSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PHSYNC; else flags |= DRM_MODE_FLAG_NHSYNC; - if (tmp TRANS_DP_VSYNC_ACTIVE_HIGH) + if (trans_dp TRANS_DP_VSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PVSYNC; else flags |= DRM_MODE_FLAG_NVSYNC; -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] NULL pointer deferences in drm_mode_copy() and drm_crtc_index()
I few days ago I built a kernel from git (commit 6aaf0da872), and noticed a couple of NULL pointer deferences. These seem to be regressions as they aren't present in v4.1. I did a bisect between v4.1 and 6aaf0da872, and came up with the following commit as the first bad one: d5432a9d drm/i915: Stage new modeset state straight into atomic state My laptop is a Thinkpad T540p. The bug manifests itself specifically when I'm connected to my dock. Starting with this commit, when I plug an external monitor into the dock and then unplug it, I get the NULL pointer dereference in drm_mode_copy (see kernel trace #1 below). The bug happens during unplug. Plugging/unplugging the same monitor directly into my laptop doesn't seem tickle the bug. It also doesn't seem to matter which connector I plug/unplug into on the dock (VGA, DP, etc.). This laptop/dock uses DP MST, so wonder if that's the problem. An external VGA monitor connected directly to my laptop shows up as output VGA1, but when that same monitor is hooked up to the dock's VGA port, it shows up as output DP2-3 (for example). That commit the first place where things seem to go wrong, but later commits actually show a different, but possibly related NULL pointer dereference in drm_crtc_index (see kernel trace #2 below). In these kernels, I don't even get to the point where I can unplug the monitor. Instead, as soon as I connect two external monitors to my dock, a NULL dereference occurs. My initial tests show that it seems to happen specifically with 2 external monitors, not 1, and when they are connected to the dock, not the laptop itself. This bug occurs in commit 6aaf0da872 (my starting point), and I noticed it during my bisect in at least commit 27a1b688, though it might first start occurring earlier. I know that 0f63cca already has the first bug above (unplugging monitor problem). I suspect that the new problem probably starts between those two commits, but I haven't had the chance to pinpoint it--perhaps this info will be enough to identify the source of both problems, but if not, I can try to dig deeper. Michael Here are the two kernel traces: === #1 === BUG: unable to handle kernel NULL pointer dereference at (null) IP: [a03de078] drm_mode_copy+0x18/0x30 [drm] PGD 0 Oops: [#1] SMP Modules linked in: fuse btrfs xor raid6_pq ufs qnx4 hfsplus hfs minix ntfs msdos jfs xfs libcrc32c dm_mod cpuid hid_generic usbhid hid rfcomm cpufreq_stats cpufreq_conservative cpufreq_userspace cpufreq_powersave bnep binfmt_misc joydev ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 xt_hl ip6t_rt nf_conntrack_ipv6 nf_defrag_ipv6 ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG xt_limit xt_tcpudp xt_addrtype nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack ip6table_filter ip6_tables nf_conntrack_netbios_ns nf_conntrack_broadcast nf_nat_ftp nf_nat nf_conntrack_ftp nf_conntrack iptable_filter ip_tables x_tables nls_utf8 nls_cp437 vfat fat arc4 snd_hda_codec_hdmi x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi kvm_intel kvm uvcvideo crct10dif_pclmul videobuf2_vmalloc snd_hda_codec_realtek snd_hda_codec_generic iwlmvm crc32_pclmul videobuf2_memops ghash_clmulni_intel videobuf2_core v4l2_common snd_hda_intel aesni_intel iTCO_wdt i915 videod! ev mac8021 1 iTCO_vendor_support aes_x86_ 64 snd_hda_controller lrw rtsx_pci_ms btusb media snd_hda_codec gf128mul btbcm snd_hda_core iwlwifi memstick btintel glue_helper snd_hwdep bluetooth thinkpad_acpi ablk_helper drm_kms_helper mei_me snd_pcm nvram ie31200_edac cryptd pcspkr evdev cfg80211 sg drm psmouse snd_timer i2c_i801 edac_core mei lpc_ich i2c_algo_bit shpchp snd serio_raw efivars soundcore rfkill wmi ac tpm_tis battery tpm video processor button coretemp parport_pc ppdev lp parport efivarfs autofs4 ext4 crc16 mbcache jbd2 sr_mod cdrom sd_mod rtsx_pci_sdmmc mmc_core crc32c_intel ahci libahci libata xhci_pci scsi_mod ehci_pci xhci_hcd ehci_hcd rtsx_pci e1000e mfd_core ptp usbcore pps_core usb_common thermal thermal_sys CPU: 0 PID: 1007 Comm: Xorg Not tainted 4.1.0-rc2-kaminsky+ #9 Hardware name: LENOVO 20BECTO1WW/20BECTO1WW, BIOS GMET66WW (2.14 ) 07/01/2014 task: 880231890290 ti: 8800b5df4000 task.ti: 8800b5df4000 RIP: 0010:[a03de078] [a03de078] drm_mode_copy+0x18/0x30 [drm] RSP: 0018:8800b5df7c10 EFLAGS: 00010292 RAX: 880231535018 RBX: 880230601e40 RCX: 001a RDX: RSI: RDI: 880231535018 RBP: 880231969000 R08: R09: R10: R11: R12: 880231535000 R13: 880231535018 R14: 8802315350e8 R15: FS: 7f30e84ba980() GS:88023e20() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: CR3: 36a33000 CR4: 001407f0 Stack: a07e3a70 880230601e40
[Intel-gfx] [PATCH i-g-t 06/16] plot: Add a way to color plots
It can look pretty and allows to differenciate between several plots drawn on the same canvas. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 24 lib/igt_plot.h | 3 +++ lib/tests/igt_plot.c | 1 + 3 files changed, 28 insertions(+) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index f7187f6..3f3c2fe 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -231,6 +231,8 @@ static void igt_plot_ctx_init(igt_plot_ctx_t *ctx) memset(ctx, 0, sizeof(*ctx)); ctx-line_width = 1.5; + ctx-r = ctx-g = ctx-b = 0.0; + ctx-a = 1.0; } static void igt_plot_ctx_fini(igt_plot_ctx_t *ctx) @@ -287,6 +289,27 @@ void igt_plot_fini(igt_plot_t *plot) } /** + * igt_plot_set_color: + * @plot: An #igt_plot_t instance + * @r: Red component in the [0, 1] range + * @g: Green component in the [0, 1] range + * @b: Blue component in the [0, 1] range + * @a: Alpha component in the [0, 1] range + * + * Set the color to use when drawing plots. + */ +void igt_plot_set_color(igt_plot_t *plot, + double r, double g, double b, double a) +{ + igt_plot_ctx_t *ctx = plot-ctx; + + ctx-r = r; + ctx-g = g; + ctx-b = b; + ctx-a = a; +} + +/* * igt_plot_set_line_width: * @plot: An #igt_plot_t instance * @width: The new line width to use @@ -442,6 +465,7 @@ igt_plot_draw_one(igt_plot_t *plot, igt_plot_ctx_t *ctx, flush_t *flush) cairo_line_to(plot-cr, fit(x-values[i], area-x1, x_range, x_scale), fit(y-values[i], area-y2, y_range, -y_scale)); + cairo_set_source_rgba(plot-cr, ctx-r, ctx-g, ctx-b, ctx-a); cairo_set_line_cap(plot-cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_width(plot-cr, ctx-line_width); cairo_stroke(plot-cr); diff --git a/lib/igt_plot.h b/lib/igt_plot.h index 82ad10a..2e00c60 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@ -76,6 +76,7 @@ typedef struct { igt_vector_t *x, *y; double x_range, y_range; double line_width; + double r, g, b, a; } igt_plot_ctx_t; /** @@ -115,6 +116,8 @@ typedef enum { void igt_plot_init(igt_plot_t *plot, unsigned int width, unsigned int height); void igt_plot_fini(igt_plot_t *plot); +void igt_plot_set_color(igt_plot_t *plot, + double r, double g, double b, double a); void igt_plot_set_line_width(igt_plot_t *plot, double width); void igt_plot_draw(igt_plot_t *plot, igt_vector_t *x, igt_vector_t *y); void igt_plot_write(igt_plot_t *plot, const char *filename); diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c index be0e132..cb7f022 100644 --- a/lib/tests/igt_plot.c +++ b/lib/tests/igt_plot.c @@ -82,6 +82,7 @@ static void test_simple_plot(void) y-values[i] = sin(2 * M_PI * x-values[i]); igt_plot_init(plot, 800, 600); + igt_plot_set_color(plot, 0.0, 0.0, 1.0, 1.0); igt_plot_draw(plot, x, y); igt_plot_write(plot, test_simple_plot.png); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 12/16] plot: Add a way to draw debug hints to help layouting
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 16 +++- lib/igt_plot.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 2ca005e..763c000 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -443,7 +443,12 @@ static double plot_length(igt_plot_t *plot, double percent) static void igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) { - /* XXX: bearings? */ + if (plot-debug) { + cairo_set_source_rgb(plot-cr, 1.0, 0.0, 0.0); + cairo_move_to(plot-cr, x, y); + cairo_arc(plot-cr, x, y, 2.0, 0, 2 * M_PI); + cairo_fill(plot-cr); + } switch (label-halign) { case IGT_ALIGN_LEFT: @@ -469,6 +474,15 @@ igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) break; } + if (plot-debug) { + cairo_set_source_rgb(plot-cr, 1.0, 0.0, 0.0); + cairo_move_to(plot-cr, x, y); + cairo_rectangle(plot-cr, x, y, + label-extents.width, -label-extents.height); + cairo_stroke(plot-cr); + } + + cairo_set_source_rgb(plot-cr, 0.0, 0.0, 0.0); cairo_move_to(plot-cr, x, y); cairo_show_text(plot-cr, label-text); } diff --git a/lib/igt_plot.h b/lib/igt_plot.h index cca498a..49d5819 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@ -102,6 +102,7 @@ typedef struct { cairo_t *cr; /* plot-wide states */ + int debug; unsigned int width, height; char *title; igt_trbl_t margin; -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 15/16] plot: Test we can draw more than one graph
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/tests/igt_plot.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c index 7091cef..1706912 100644 --- a/lib/tests/igt_plot.c +++ b/lib/tests/igt_plot.c @@ -74,6 +74,11 @@ static double f(double x) return sin(2 * M_PI * x); } +static double g(double x) +{ + return 0.2 * cos(10 * M_PI * x); +} + static void test_simple_plot(void) { igt_vector_t *x, *y; @@ -98,9 +103,34 @@ static void test_simple_plot(void) igt_vector_unref(y); } +static void test_two_plots(void) +{ + igt_vector_t *x, *y, *y2; + igt_plot_t plot; + + x = igt_vector_linear(-1.0, 1.0, 200); + y = igt_vector_map(x, f); + y2 = igt_vector_map(x, g); + + igt_plot_init(plot, 800, 600); + igt_plot_set_title(plot, f(x) g(x)); + igt_plot_set_color(plot, 0.0, 0.0, 1.0, 1.0); + igt_plot_draw(plot, x, y2); + igt_plot_set_color(plot, 1.0, 0.0, 0.0, 1.0); + igt_plot_draw(plot, x, y); + igt_plot_write(plot, test_two_plots.png); + + igt_plot_fini(plot); + igt_vector_unref(x); + igt_vector_unref(y); + igt_vector_unref(y2); + +} + igt_simple_main { test_snap_to_pixel(); test_min_max(); test_simple_plot(); + test_two_plots(); } -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 09/16] plot: Draw a grid in the background
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 126f160..c8d6dcb 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -452,6 +452,37 @@ igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) cairo_show_text(plot-cr, label-text); } +static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush) +{ + unsigned int i, n_ticks; + igt_box_t *area = flush-plot_area; + double area_width, area_height; + + area_width = area-x2 - area-x1; + area_height = area-y2 - area-y1; + + cairo_set_source_rgb(plot-cr, 0.9, 0.9, 0.9); + cairo_set_line_width(plot-cr, 1.0); + + n_ticks = plot-x_axis.n_ticks; + for (i = 0; i n_ticks; i++) { + double x = area-x1 + i * area_width / (n_ticks - 1); + + cairo_move_to(plot-cr, SNAP(x), area-y2); + cairo_line_to(plot-cr, SNAP(x), area-y1); + cairo_stroke(plot-cr); + } + + n_ticks = plot-y_axis.n_ticks; + for (i = 0; i n_ticks; i++) { + double y = area-y2 - i * area_height / (n_ticks - 1); + + cairo_move_to(plot-cr, area-x1, SNAP(y)); + cairo_line_to(plot-cr, area-x2, SNAP(y)); + cairo_stroke(plot-cr); + } +} + static double fit(double p, double start, double range, double scale) { return start + (range / 2 + p) * scale; @@ -508,6 +539,7 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis, area_height = area-y2 - area-y1; cairo_set_font_size(plot-cr, flush-tick_label_font_size); + cairo_set_source_rgb(plot-cr, 0.0, 0.0, 0.0); cairo_set_line_cap(plot-cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_width(plot-cr, 1.0); @@ -560,6 +592,8 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush) igt_box_t *area = flush-plot_area; const double tick_length = plot_length(plot, 0.01); + igt_plot_draw_grid(plot, flush); + /* X-axis */ cairo_move_to(plot-cr, area-x1, area-y2); cairo_line_to(plot-cr, area-x2, area-y2); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 14/16] plot: Write simple plot with debug rectangles as well
Not only useful for inspection but also to check we can re-start a drawing just fine. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/tests/igt_plot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c index a178fbf..7091cef 100644 --- a/lib/tests/igt_plot.c +++ b/lib/tests/igt_plot.c @@ -90,6 +90,9 @@ static void test_simple_plot(void) igt_plot_draw(plot, x, y); igt_plot_write(plot, test_simple_plot.png); + plot.debug = true; + igt_plot_write(plot, test_simple_plot_debug.png); + igt_plot_fini(plot); igt_vector_unref(x); igt_vector_unref(y); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: set FDI translations to NULL on SKL
On Mon, Jul 06, 2015 at 01:47:44PM +0300, David Weinehall wrote: On Fri, Jul 03, 2015 at 12:31:30PM -0300, Paulo Zanoni wrote: From: Paulo Zanoni paulo.r.zan...@intel.com drivers/gpu/drm/i915/intel_ddi.c: In function ‘intel_prepare_ddi’: drivers/gpu/drm/i915/intel_ddi.c:517:6: warning: ‘ddi_translations_fdi’ may be used uninitialized in this function [-Wmaybe-uninitialized] if (ddi_translations_fdi) ^ drivers/gpu/drm/i915/intel_ddi.c:446:30: note: ‘ddi_translations_fdi’ was declared here const struct ddi_buf_trans *ddi_translations_fdi; Thanks for noticing! Weird -- and embarassing -- that I missed this :S Create a personal public git repo somewhere, tell the 0-day folks about it and just wait a few hours before hitting send. You _will_ reliable get reports about this stuff before I get them when I apply the patch ;-) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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: Adjust BXT HDMI port clock limits
From: Ville Syrjälä ville.syrj...@linux.intel.com Since commit e62925567c7926e78bc8ca976cde5c28ea265a49 Author: Vandana Kannan vandana.kan...@intel.com Date: Wed Jul 1 17:02:57 2015 +0530 drm/i915/bxt: BUNs related to port PLL BXT DPLL can now generate frequencies in the 216-223 MHz range. Adjust the HDMI port clock checks to account for the reduced range of invalid frequencies. Cc: Vandana Kannan vandana.kan...@intel.com Cc: Imre Deak imre.d...@intel.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_hdmi.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c7e912b..70bad5b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1174,9 +1174,12 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, if (clock hdmi_port_clock_limit(hdmi, respect_dvi_limit)) return MODE_CLOCK_HIGH; - /* CHV/BXT DPLL can't generate 216-240 MHz */ - if ((IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) - clock 216000 clock 24) + /* BXT DPLL can't generate 223-240 MHz */ + if (IS_BROXTON(dev) clock 22 clock 24) + return MODE_CLOCK_RANGE; + + /* CHV DPLL can't generate 216-240 MHz */ + if (IS_CHERRYVIEW(dev) clock 216000 clock 24) return MODE_CLOCK_RANGE; return MODE_OK; -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Improve DP downstream HPD handling
From: Ville Syrjälä ville.syrj...@linux.intel.com DP dongles may signal downstream HPD via short HPD pulses. If we know the device has a HPD capable downstream port, make sure we kick off the full hotplug processing even for short HPDs. Additonally setting the sink to DPMS off kills the downstream HPD (at least on my DP-VGA dongle), so skip the DPMS off for such dongles when we turn off the port. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e88cec2..f424833 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2324,6 +2324,13 @@ static void intel_dp_get_config(struct intel_encoder *encoder, } } +static bool intel_dp_has_downstream_hpd(struct intel_dp *intel_dp) +{ + return intel_dp-dpcd[DP_DOWNSTREAMPORT_PRESENT] DP_DWN_STRM_PORT_PRESENT + intel_dp-dpcd[DP_DPCD_REV] = 0x11 + intel_dp-downstream_ports[0] DP_DS_PORT_HPD; +} + static void intel_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base); @@ -2340,7 +2347,9 @@ static void intel_disable_dp(struct intel_encoder *encoder) * ensure that we have vdd while we switch off the panel. */ intel_edp_panel_vdd_on(intel_dp); intel_edp_backlight_off(intel_dp); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); + /* Skip power down to keep downstream HPD working */ + if (!intel_dp_has_downstream_hpd(intel_dp)) + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_edp_panel_off(intel_dp); /* disable the port before the pipe on g4x */ @@ -4944,6 +4953,13 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) drm_modeset_lock(dev-mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(dev-mode_config.connection_mutex); + + /* +* Downstream HPD will generate a short HPD, +* so we want full hotplug processing here. +*/ + if (intel_dp_has_downstream_hpd(intel_dp)) + goto put_power; } } -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] [RFC] drm/i915: Handle HPD when it has actually occurred
On Mon, Jul 06, 2015 at 02:11:12PM +0530, Jindal, Sonika wrote: On 7/6/2015 2:06 PM, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 11:23:53AM +0530, Sonika Jindal wrote: Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal sonika.jin...@intel.com --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Nice find, this sounds really intrigueing, at least for cpt/ibx platforms. I'm not sure whether what will happen with atom/i9xx platforms though since the irq bits are different there. But at least bxt has a FIXME comment that suggest we do need to save the sticky bits on those platforms too. If we can fix this up for all platforms then I think a subsequent patch could try to re-enable the hpd checks in the hdmi -detect function and make use spec compliant. Then after maybe 1-2 kernel releases of testing we'll know whether it really works. But I'd really want to enable this everywhere just to have maximal test coverage - we did have reports on all platforms so it seems a generic issue. I think only cpt/ibx suffer from this. Bxt already set port_hotplug_stat only when hpd occurs. Is there a process to get this checked on all platforms, which the fix I suggested? I can only test on SKL as of now. Right I was looking at an older version of the bxt hpd handler which still had a FIXME. But we probably still have an issue on bxt/i9xx interrupt handlers since when we've done the original revert to stop looking at the hpd live status bits in commit 202adf4b9f5957b26a1cb97267d78e0edb319c5e Author: Daniel Vetter daniel.vet...@ffwll.ch Date: Fri Feb 22 00:53:04 2013 +0100 drm/i915: Revert hdmi HDP pin checks we had reports from both ibx/cpt systems and g4x. And vlv/chv/bxt hpd seems derived from that (with live status, enable and status all smashed into one register). Therefore I guess that we need a similar fix of only carefully clearing status bits on these platforms too. I have no idea what it is though, might be good to check how exactly windows is handling hpd on these atom platfroms. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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: RMW register cycles considered evil
Especially for workarounds which is stuff that's almost impossible to verify: The initial state from the firmware on boot-up and after resume could be different, which will hide bugs when we do an RMW cycle. Hence never do them, and if it's required we need a special mask. Cc: Damien Lespiau damien.lesp...@intel.com Cc: Imre Deak imre.d...@intel.com Cc: Nick Hoath nicholas.ho...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 166ae51f5a5b..565f78d6a21d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -57,7 +57,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; /* WaEnableLbsSlaRetryTimerDecrement:skl */ - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | + I915_WRITE(BDW_SCRATCH1, GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); } @@ -72,18 +72,18 @@ static void skl_init_clock_gating(struct drm_device *dev) * WaDisableSDEUnitClockGating:skl * WaSetGAPSunitClckGateDisable:skl */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableVFUnitClockGating:skl */ - I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | + I915_WRITE(GEN6_UCGCTL2, GEN6_VFUNIT_CLOCK_GATE_DISABLE); } if (INTEL_REVID(dev) = SKL_REVID_D0) { /* WaDisableHDCInvalidation:skl */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + I915_WRITE(GAM_ECOCHK, BDW_DISABLE_HDC_INVALIDATION); /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ @@ -93,7 +93,7 @@ static void skl_init_clock_gating(struct drm_device *dev) if (INTEL_REVID(dev) = SKL_REVID_E0) /* WaDisableLSQCROPERFforOCL:skl */ - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | + I915_WRITE(GEN8_L3SQCREG4, GEN8_LQSC_RO_PERF_DIS); } @@ -109,12 +109,12 @@ static void bxt_init_clock_gating(struct drm_device *dev) * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ /* WaDisableSDEUnitClockGating:bxt */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_SDEUNIT_CLOCK_GATE_DISABLE | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* FIXME: apply on A0 only */ - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); + I915_WRITE(TILECTL, TILECTL_TLBPF); } static void i915_pineview_get_mem_freq(struct drm_device *dev) -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/15] drm/i915: Embedded microcontroller (uC) firmware loading support
On 24/06/15 11:29, Daniel Vetter wrote: On Fri, Jun 19, 2015 at 09:43:11AM +0100, Dave Gordon wrote: On 18/06/15 15:49, Daniel Vetter wrote: On Thu, Jun 18, 2015 at 01:11:34PM +0100, Dave Gordon wrote: On 17/06/15 13:05, Daniel Vetter wrote: On Mon, Jun 15, 2015 at 07:36:20PM +0100, Dave Gordon wrote: Current devices may contain one or more programmable microcontrollers that need to have a firmware image (aka binary blob) loaded from an external medium and transferred to the device's memory. This file provides generic support functions for doing this; they can then be used by each uC-specific loader, thus reducing code duplication and testing effort. Signed-off-by: Dave Gordon david.s.gor...@intel.com Signed-off-by: Alex Dai yu@intel.com Given that I'm just shredding the synchronization used by the dmc loader I'm not convinced this is a good idea. Abstraction has cost, and a bit of copy-paste for similar sounding but slightly different things doesn't sound awful to me. And the critical bit in all the firmware loading I've seen thus far is in synchronizing the loading with other operations, hiding that isn't a good idea. Worse if we enforce stuff like requiring dev-struct_mutex. -Daniel It's precisely because it's in some sense trivial-but-tricky that we should write it once, get it right, and use it everywhere. Copypaste /does/ sound awful; I've seen how the code this was derived from had already been cloned into three flavours, all different and all wrong. It's a very simple abstraction: one early call to kick things off as early as possible, no locking required. One late call with the struct_mutex held to complete the synchronisation and actually do the work, thus guaranteeing that the transfer to the target uC is done in a controlled fashion, at a time of the caller's choice, and by the driver's mainline thread, NOT by an asynchronous thread racing with other activity (which was one of the things wrong with the original version). Yeah I've seen the origins of this in the display code, and that code gets the syncing wrong. The only thing that one has do to is grab a runtime pm reference for the appropriate power well to prevent dc5 entry, and release it when the firmware is loaded and initialized. Agreed. Which means any kind of firmware loader which requires/uses dev-struct_mutex get stuff wrong and is not appropriate everywhere. BUT, the loading of the firmware into any uC MUST be done in a controlled manner i.e. at a time when no other thread is touching the h/w. Otherwise the f/w load and whatever else is concurrently accessing the h/w could in some cases interfere disastrously. Examples of interference might be: * interleaved accesses to the ELSP (in the case of the GuC) * incorrect handover of power management (DMC, GuC) * erroneous management of forcewake state In general the f/w that is just starting on the uC may have certain expectations about the initial state of the h/w, which may not be met if other threads are accessing various bits of h/w while the uC is booting up. So we absolutely need to guarantee that the f/w load is done by a thread which has exclusive ownership of any bit of the h/w that the f/w is going to make assumptions about. With the current locking structure of the driver, that means holding the struct_mutex (it shouldn't really, there should be a separate mutex for h/w register access vs. driver-private data structures, but there isn't). If you really need this guarantee (and I seriously hope not) then the only option is a synchronous firmware load at driver init _before_ we launch any of the asynchronous setup code. And there is already a lot of that, and we're adding more all the time. What I expect we need is synchronization of just the revelant part with the firmware loading, which necessarily needs to be somewhat async to be able to support cros/android requirements. And yes that needs to be done in a controlled manner, but most likely we need very specific solutions for the problem at hand. Unconditionally holding dev-struct_mutex isn't that solution. The other problem with dev-struct_mutex is that it's a giantic lock with ill defined coverage and semantics. It's imo the biggest piece of technical debt we carry around in i915.ko, and we pay the price for that dearlydaily. Which means that since a few years any kind of code which extended dev-struct_mutex to anything not clearly core gem data structures was rejected. Oh, I quite agree that the struct_mutex is an abomination and would certainly like to eliminate it. But at the moment it's the only sufficiently large-scale synchronisation operation available to ensure that (for example) we don't try to load the f/w at the same time that another thread is trying to reset the h/w. None of this loader code really needs the struct_mutex specifically; the WARN_ON macros were just there to help callers know what degree of synchronisation they need to organise before calling these
Re: [Intel-gfx] [RFC 7/8] drm/i915: Allow final wm programming to be scheduled after next vblank (v2)
On Mon, Jul 06, 2015 at 11:07:52AM +0200, Daniel Vetter wrote: On Wed, Jul 01, 2015 at 07:26:00PM -0700, Matt Roper wrote: Add a simple mechanism to trigger final watermark updates in an asynchronous manner once the next vblank occurs. No platform types actually support atomic watermark programming until a future patch, so there should be no functional change yet; individual platforms will be converted to use this mechanism one-by-one in future patches. Note that we'll probably expand this to cover other post-vblank async tasks (like unpinning) at some point in the future. v2: Much simpler vblank mechanism than was used in the previous series; no need to allocate new heap structures. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 7 +++ drivers/gpu/drm/i915/i915_irq.c | 9 + drivers/gpu/drm/i915/intel_display.c | 30 ++ drivers/gpu/drm/i915/intel_drv.h | 4 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2774976..5ad942e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -628,6 +628,7 @@ struct drm_i915_display_funcs { struct drm_crtc *crtc, uint32_t sprite_width, uint32_t sprite_height, int pixel_size, bool enable, bool scaled); + void (*program_watermarks)(struct drm_i915_private *dev_priv); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); /* Returns the active state of the crtc, and if the crtc is active, @@ -2567,6 +2568,12 @@ struct drm_i915_cmd_table { #define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) #define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev)) +/* + * FIXME: Not all platforms have been transitioned to atomic watermark + * updates yet. + */ +#define HAS_ATOMIC_WM(dev_priv) (dev_priv-display.program_watermarks != NULL) HAS_FOO is generally hw features. I think especially for just this vfunc check is clearer to inline it. + #define GT_FREQUENCY_MULTIPLIER 50 #define GEN9_FREQ_SCALER 3 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..20c7260 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1452,6 +1452,15 @@ 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 drm_i915_private *dev_priv = to_i915(dev); + struct drm_crtc *crtc = dev_priv-pipe_to_crtc_mapping[pipe]; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (intel_crtc-need_vblank_wm_update) { + queue_work(dev_priv-wq, intel_crtc-wm_work); + intel_crtc-need_vblank_wm_update = false; We need some lock or some other means of sync to be able to cancel such an update if userspace submits the next atomic update. Otherwise this work might overwrite the intermediate wm values. This series seems to be missing a bunch of stuff from my ILK wm rework, including the wm.mutex. -- 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] drm/i915: Update WaFlushCoherentL3CacheLinesAtContextSwitch
On 03/07/15 16:42, Chris Wilson wrote: On Fri, Jul 03, 2015 at 02:27:31PM +0100, Arun Siluvery wrote: In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after PIPE_CONTROL instruction but there is a slight complication as this is applied in WA batch where the values are only initialized once. Dave identified an issue with the current implementation where the register value is read once at the beginning and it is reused; this patch corrects this by saving the register value to memory, update register with the bit of our interest and restore it back with original value. This implementation uses MI_LOAD_REGISTER_MEM which is currently only used by command parser and was using a default length of 0. This is now updated with correct length and moved to appropriate place. Cc: Chris Wilson ch...@chris-wilson.co.uk Cc: Dave Gordon david.s.gor...@intel.com Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 6 +-- drivers/gpu/drm/i915/i915_reg.h| 3 +- drivers/gpu/drm/i915/intel_lrc.c | 72 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 306d9e4..430571b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -131,7 +131,7 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { .mask = MI_GLOBAL_GTT, .expected = 0, }}, ), - CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W | B, + CMD( MI_LOAD_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, .reg = { .offset = 1, .mask = 0x007C }, .bits = {{ .offset = 0, @@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * only MI_LOAD_REGISTER_IMM commands. */ if (reg_addr == OACONTROL) { - if (desc-cmd.value == MI_LOAD_REGISTER_MEM) { + if (desc-cmd.value == MI_LOAD_REGISTER_MEM(1)) { I had a double take here, but it all comes out in the wash. For one moment, I thought the cmd matching had changed, but that has the length masked out. Reviewed-by: Chris Wilson ch...@cris-wilson.co.uk Who will start to complain about all the extra frequent register writes, probably into common power wells -Chris Hmm ... that is quite confusing, especially as the actual opcode in the instruction stream will be MI_LOAD_REGISTER_MEM(2) on GEN8+. It might almost be better to use MI_LOAD_REGISTER_MEM(0) to emphasise that the length field is a wildcard and not something that will be matched exactly. .Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 6/7] drm/i915: Don't use link_bw to select between TP1 and TP3
From: Ville Syrjälä ville.syrj...@linux.intel.com intel_dp-link_bw is going away, so consul the port_clock instead when choosing between TP1 and TP3. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index da036e8..46b734b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3697,8 +3697,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) uint32_t DP = intel_dp-DP; uint32_t training_pattern = DP_TRAINING_PATTERN_2; - /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/ - if (intel_dp-link_bw == DP_LINK_BW_5_4 || intel_dp-use_tps3) + /* Training Pattern 3 for HBR2 or 1.2 devices that support it*/ + if (crtc-config-port_clock == 54 || intel_dp-use_tps3) training_pattern = DP_TRAINING_PATTERN_3; /* channel equalization */ -- 2.3.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 5/7] drm/i915: Move intel_dp-lane_count into pipe_config
From: Ville Syrjälä ville.syrj...@linux.intel.com Currently we clobber intel_dp-lane_count in compute config, which means after a rejected modeset we may no longer be able to retrain the current link. Move lane_count into pipe_config to avoid that. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 3 ++ drivers/gpu/drm/i915/intel_ddi.c | 10 +++--- drivers/gpu/drm/i915/intel_display.c | 7 +++-- drivers/gpu/drm/i915/intel_dp.c | 60 drivers/gpu/drm/i915/intel_dp_mst.c | 6 +++- drivers/gpu/drm/i915/intel_drv.h | 3 +- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d5c794a..f5dc75c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4096,6 +4096,7 @@ enum skl_disp_power_wells { /* How many wires to use. I guess 3 was too hard */ #define DP_PORT_WIDTH(width) (((width) - 1) 19) #define DP_PORT_WIDTH_MASK (7 19) +#define DP_PORT_WIDTH_SHIFT 19 /* Mystic DPCD version 1.1 special mode */ #define DP_ENHANCED_FRAMING (1 18) @@ -7128,6 +7129,8 @@ enum skl_disp_power_wells { #define DDI_BUF_IS_IDLE (17) #define DDI_A_4_LANES (14) #define DDI_PORT_WIDTH(width) (((width) - 1) 1) +#define DDI_PORT_WIDTH_MASK (7 1) +#define DDI_PORT_WIDTH_SHIFT 1 #define DDI_INIT_DISPLAY_DETECTED (10) /* DDI Buffer Translations */ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 96fb472..8df596d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -723,11 +723,11 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base); struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder-base); + struct intel_crtc *crtc = to_intel_crtc(encoder-base.crtc); intel_dp-DP = intel_dig_port-saved_port_bits | DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); - intel_dp-DP |= DDI_PORT_WIDTH(intel_dp-lane_count); - + intel_dp-DP |= DDI_PORT_WIDTH(crtc-config-lane_count); } static struct intel_encoder * @@ -1913,7 +1913,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) } else temp |= TRANS_DDI_MODE_SELECT_DP_SST; - temp |= DDI_PORT_WIDTH(intel_dp-lane_count); + temp |= DDI_PORT_WIDTH(intel_crtc-config-lane_count); } else if (type == INTEL_OUTPUT_DP_MST) { struct intel_dp *intel_dp = enc_to_mst(encoder)-primary-dp; @@ -1922,7 +1922,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) } else temp |= TRANS_DDI_MODE_SELECT_DP_SST; - temp |= DDI_PORT_WIDTH(intel_dp-lane_count); + temp |= DDI_PORT_WIDTH(intel_crtc-config-lane_count); } else { WARN(1, Invalid encoder type %d for pipe %c\n, intel_encoder-type, pipe_name(pipe)); @@ -3072,6 +3072,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder, case TRANS_DDI_MODE_SELECT_DP_SST: case TRANS_DDI_MODE_SELECT_DP_MST: pipe_config-has_dp_encoder = true; + pipe_config-lane_count = + ((temp DDI_PORT_WIDTH_MASK) DDI_PORT_WIDTH_SHIFT) + 1; intel_dp_get_m_n(intel_crtc, pipe_config); break; default: diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 136b533..fe7e6d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11981,14 +11981,16 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config-fdi_m_n.gmch_m, pipe_config-fdi_m_n.gmch_n, pipe_config-fdi_m_n.link_m, pipe_config-fdi_m_n.link_n, pipe_config-fdi_m_n.tu); - DRM_DEBUG_KMS(dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n, + DRM_DEBUG_KMS(dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n, pipe_config-has_dp_encoder, + pipe_config-lane_count, pipe_config-dp_m_n.gmch_m, pipe_config-dp_m_n.gmch_n, pipe_config-dp_m_n.link_m, pipe_config-dp_m_n.link_n, pipe_config-dp_m_n.tu); - DRM_DEBUG_KMS(dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n, + DRM_DEBUG_KMS(dp: %i, lanes %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n, pipe_config-has_dp_encoder, +
[Intel-gfx] [PATCH 1/7] drm/i915: Clean up DP/HDMI limited color range handling
From: Ville Syrjälä ville.syrj...@linux.intel.com Currently we treat intel_{dp,hdmi}-color_range as partly user controller value (via the property) but we also change it during .compute_config() when using the Automatic mode. That is a bit confusing, so let's just change things so that we store the user property values in intel_dp, and only change what's stored in pipe_config during .compute_config(). There should be no functional change. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 25 - drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_hdmi.c | 26 -- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fcc64e5..decefa1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1455,15 +1455,13 @@ found: * CEA-861-E - 5.1 Default Encoding Parameters * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry */ - if (bpp != 18 drm_match_cea_mode(adjusted_mode) 1) - intel_dp-color_range = DP_COLOR_RANGE_16_235; - else - intel_dp-color_range = 0; + pipe_config-limited_color_range = + bpp != 18 drm_match_cea_mode(adjusted_mode) 1; + } else { + pipe_config-limited_color_range = + intel_dp-limited_color_range; } - if (intel_dp-color_range) - pipe_config-limited_color_range = true; - intel_dp-lane_count = lane_count; if (intel_dp-num_sink_rates) { @@ -1605,8 +1603,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder) trans_dp = ~TRANS_DP_ENH_FRAMING; I915_WRITE(TRANS_DP_CTL(crtc-pipe), trans_dp); } else { - if (!HAS_PCH_SPLIT(dev) !IS_VALLEYVIEW(dev)) - intel_dp-DP |= intel_dp-color_range; + if (!HAS_PCH_SPLIT(dev) !IS_VALLEYVIEW(dev) + crtc-config-limited_color_range) + intel_dp-DP |= DP_COLOR_RANGE_16_235; if (adjusted_mode-flags DRM_MODE_FLAG_PHSYNC) intel_dp-DP |= DP_SYNC_HS_HIGH; @@ -4663,7 +4662,7 @@ intel_dp_set_property(struct drm_connector *connector, if (property == dev_priv-broadcast_rgb_property) { bool old_auto = intel_dp-color_range_auto; - uint32_t old_range = intel_dp-color_range; + bool old_range = intel_dp-limited_color_range; switch (val) { case INTEL_BROADCAST_RGB_AUTO: @@ -4671,18 +4670,18 @@ intel_dp_set_property(struct drm_connector *connector, break; case INTEL_BROADCAST_RGB_FULL: intel_dp-color_range_auto = false; - intel_dp-color_range = 0; + intel_dp-limited_color_range = false; break; case INTEL_BROADCAST_RGB_LIMITED: intel_dp-color_range_auto = false; - intel_dp-color_range = DP_COLOR_RANGE_16_235; + intel_dp-limited_color_range = true; break; default: return -EINVAL; } if (old_auto == intel_dp-color_range_auto - old_range == intel_dp-color_range) + old_range == intel_dp-limited_color_range) return 0; goto done; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3f0a890..983a7a7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -669,7 +669,7 @@ struct cxsr_latency { struct intel_hdmi { u32 hdmi_reg; int ddc_bus; - uint32_t color_range; + bool limited_color_range; bool color_range_auto; bool has_hdmi_sink; bool has_audio; @@ -714,7 +714,7 @@ struct intel_dp { uint32_t DP; bool has_audio; enum hdmi_force_audio force_audio; - uint32_t color_range; + bool limited_color_range; bool color_range_auto; uint8_t link_bw; uint8_t rate_select; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c7e912b..ba845f7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -848,8 +848,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) u32 hdmi_val; hdmi_val = SDVO_ENCODING_HDMI; - if (!HAS_PCH_SPLIT(dev)) - hdmi_val |= intel_hdmi-color_range; + if (!HAS_PCH_SPLIT(dev) crtc-config-limited_color_range) + hdmi_val |=
Re: [Intel-gfx] [RFC 8/8] drm/i915: Add two-stage ILK-style watermark programming (v2)
Op 02-07-15 om 04:26 schreef Matt Roper: From: Matt Roper m...@mattrope.com In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 9 + drivers/gpu/drm/i915/i915_irq.c | 7 drivers/gpu/drm/i915/intel_display.c | 34 +++- drivers/gpu/drm/i915/intel_drv.h | 26 + drivers/gpu/drm/i915/intel_pm.c | 75 ++-- 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5ad942e..42397e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,6 +623,9 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct drm_crtc *crtc, struct drm_atomic_state *state); + void (*compute_intermediate_wm)(struct drm_device *dev, + struct intel_crtc_state *newstate, + const struct intel_crtc_state *oldstate); If this is can't fail anyway could we please do this at runtime instead of precalculating? Something like this: commit_intermediate_wm vblank_evade plane_update vblank_end (wait for vblank) commit_final_wm Of course for skylake just hammer in the final wm during vblank evasion. :-) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Update WaFlushCoherentL3CacheLinesAtContextSwitch
On 06/07/2015 12:52, Dave Gordon wrote: On 03/07/15 16:42, Chris Wilson wrote: On Fri, Jul 03, 2015 at 02:27:31PM +0100, Arun Siluvery wrote: In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after PIPE_CONTROL instruction but there is a slight complication as this is applied in WA batch where the values are only initialized once. Dave identified an issue with the current implementation where the register value is read once at the beginning and it is reused; this patch corrects this by saving the register value to memory, update register with the bit of our interest and restore it back with original value. This implementation uses MI_LOAD_REGISTER_MEM which is currently only used by command parser and was using a default length of 0. This is now updated with correct length and moved to appropriate place. Cc: Chris Wilson ch...@chris-wilson.co.uk Cc: Dave Gordon david.s.gor...@intel.com Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 6 +-- drivers/gpu/drm/i915/i915_reg.h| 3 +- drivers/gpu/drm/i915/intel_lrc.c | 72 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 306d9e4..430571b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -131,7 +131,7 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { .mask = MI_GLOBAL_GTT, .expected = 0, }}, ), - CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W | B, + CMD( MI_LOAD_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, .reg = { .offset = 1, .mask = 0x007C }, .bits = {{ .offset = 0, @@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * only MI_LOAD_REGISTER_IMM commands. */ if (reg_addr == OACONTROL) { - if (desc-cmd.value == MI_LOAD_REGISTER_MEM) { + if (desc-cmd.value == MI_LOAD_REGISTER_MEM(1)) { I had a double take here, but it all comes out in the wash. For one moment, I thought the cmd matching had changed, but that has the length masked out. Reviewed-by: Chris Wilson ch...@cris-wilson.co.uk Who will start to complain about all the extra frequent register writes, probably into common power wells -Chris Hmm ... that is quite confusing, especially as the actual opcode in the instruction stream will be MI_LOAD_REGISTER_MEM(2) on GEN8+. It might true, but cmd parser is only upto GEN7. regards Arun almost be better to use MI_LOAD_REGISTER_MEM(0) to emphasise that the length field is a wildcard and not something that will be matched exactly. .Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 8/8] drm/i915: Add two-stage ILK-style watermark programming (v2)
On Mon, Jul 06, 2015 at 02:20:00PM +0200, Maarten Lankhorst wrote: Op 02-07-15 om 04:26 schreef Matt Roper: From: Matt Roper m...@mattrope.com In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. Signed-off-by: Matt Roper matthew.d.ro...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 9 + drivers/gpu/drm/i915/i915_irq.c | 7 drivers/gpu/drm/i915/intel_display.c | 34 +++- drivers/gpu/drm/i915/intel_drv.h | 26 + drivers/gpu/drm/i915/intel_pm.c | 75 ++-- 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5ad942e..42397e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,6 +623,9 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct drm_crtc *crtc, struct drm_atomic_state *state); + void (*compute_intermediate_wm)(struct drm_device *dev, + struct intel_crtc_state *newstate, + const struct intel_crtc_state *oldstate); If this is can't fail anyway could we please do this at runtime instead of precalculating? Hm, this is possible to fail, we might not be able to get valid intermediate wms. And therefore it needs to be in the compute phase. -Daniel Something like this: commit_intermediate_wm vblank_evade plane_update vblank_end (wait for vblank) commit_final_wm Of course for skylake just hammer in the final wm during vblank evasion. :-) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation 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 8/8] drm/i915: protect FBC functions with FBC checks
On Fri, Jul 03, 2015 at 07:50:31PM +0100, Chris Wilson wrote: On Fri, Jul 03, 2015 at 03:40:54PM -0300, Paulo Zanoni wrote: From: Paulo Zanoni paulo.r.zan...@intel.com Now all the functions called by other files check whether FBC has been initialized. This allows us to drop the checks on the static functions. v2: - s/HAS_FBC/dev_priv-display.enable_fbc/ everywhere but the init function (Chris). Suggested-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 27 ++- 1 file changed, 18 insertions(+), 9 deletions(-) I'm not 100% sure this is what Chris was asking for v2, so please clarify if this is not what we want. Does the trick for me, Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Entire series merged to dinq, thanks. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 02/16] stats: Add an igt_stats_init_from_array() variant
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_stats.c | 22 ++ lib/igt_stats.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/lib/igt_stats.c b/lib/igt_stats.c index 37fcc23..1103a7b 100644 --- a/lib/igt_stats.c +++ b/lib/igt_stats.c @@ -133,6 +133,28 @@ void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity) stats-max = 0; } +/** + * igt_stats_init_from_array: + * @stats: An #igt_stats_t instance + * @array: (array length=n): Array of uint64_t + * @n: Length of @array + * + * Short hand for: + * |[ + * static const uint64_t s[] = { 10, 12, 14, 16, 87, 53, 90, 72 }; + * igt_stats_t stats; + * + * igt_stats_init(stats); + * igt_stats_push_array(stats, s, ARRAY_SIZE(s)); + * ]| + */ +void igt_stats_init_from_array(igt_stats_t *stats, + const uint64_t *array, unsigned int n) +{ + igt_stats_init(stats); + igt_stats_push_array(stats, array, n); +} + /* https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform */ static double rand_normal(double mean, double stddev) { diff --git a/lib/igt_stats.h b/lib/igt_stats.h index e1757b7..d6eb48f 100644 --- a/lib/igt_stats.h +++ b/lib/igt_stats.h @@ -49,6 +49,8 @@ typedef struct { void igt_stats_init(igt_stats_t *stats); void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity); +void igt_stats_init_from_array(igt_stats_t *stats, + const uint64_t *array, unsigned int n); void igt_stats_init_normal(igt_stats_t *stats, double mean, double std_deviation, unsigned int n_values); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 05/16] plot: Draw nice plots!
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- .../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 + lib/Makefile.sources | 2 + lib/igt_plot.c | 607 + lib/igt_plot.h | 122 + lib/tests/.gitignore | 4 + lib/tests/Makefile.sources | 1 + lib/tests/igt_plot.c | 98 7 files changed, 835 insertions(+) create mode 100644 lib/igt_plot.c create mode 100644 lib/igt_plot.h create mode 100644 lib/tests/igt_plot.c diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml index 0992308..83f7d29 100644 --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml @@ -19,6 +19,7 @@ xi:include href=xml/igt_core.xml/ xi:include href=xml/igt_types.xml/ xi:include href=xml/igt_stats.xml/ +xi:include href=xml/igt_plot.xml/ xi:include href=xml/igt_debugfs.xml/ xi:include href=xml/igt_draw.xml/ xi:include href=xml/igt_kms.xml/ diff --git a/lib/Makefile.sources b/lib/Makefile.sources index 205a9aa..9fabd44 100644 --- a/lib/Makefile.sources +++ b/lib/Makefile.sources @@ -12,6 +12,8 @@ libintel_tools_la_SOURCES = \ igt_aux.h \ igt_gt.c\ igt_gt.h\ + igt_plot.c \ + igt_plot.h \ igt_stats.c \ igt_stats.h \ igt_types.h \ diff --git a/lib/igt_plot.c b/lib/igt_plot.c new file mode 100644 index 000..f7187f6 --- /dev/null +++ b/lib/igt_plot.c @@ -0,0 +1,607 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#define _GNU_SOURCE + +#include assert.h +#include float.h +#include math.h +#include string.h +#include stdint.h +#include stdio.h +#include stdlib.h +#include string.h + +#include igt_plot.h +#include igt_aux.h /* min() */ + +/** + * SECTION:igt_plot + * @short_description: Draw various plots + * @title: Plots + * @include: igt_plots.h + * + * A drawing is better than a long speech. Plotting data can reveal surprises + * and the igt_plot_t object let you do just that. + */ + +/* snap to pixel */ +#define SNAP(d)((uint64_t)(d) + 0.5) + +static igt_vector_t *igt_vector_new_internal(unsigned int n) +{ + igt_vector_t *v; + + /* single allocation for both the vector and data */ + v = malloc(sizeof(igt_vector_t) + n * sizeof(double)); + v-ref = 1; + v-n = n; + + return v; +} + +/** + * igt_vector_new: + * @n: Number of samples + * + * Creates a zeroed vector of size @n. + */ +igt_vector_t *igt_vector_new(unsigned int n) +{ + igt_vector_t *v; + + v = igt_vector_new_internal(n); + memset(v-values, 0, n * sizeof(double)); + + return v; +} + +/** + * igt_vector_new_from_array: + * @array: (array length=n): C array of doubles + * @n: Size of the array + * + * Creates a new vector from @array, copying the data. + */ +igt_vector_t *igt_vector_new_from_array(const double *array, unsigned int n) +{ + igt_vector_t *v; + + v = igt_vector_new_internal(n); + memcpy(v-values, array, n * sizeof(double)); + + return v; +} + +/** + * igt_vector_new_from_array_64: + * @array: (array length=n): C array of doubles + * @n: Size of the array + * + * Like igt_vector_new_from_array() but for uint64_t. + */ +igt_vector_t *igt_vector_new_from_array_u64(const uint64_t *array, + unsigned int n) +{ + igt_vector_t *v; + unsigned int i; + + v = igt_vector_new_internal(n); + for (i = 0; i n; i++) + v-values[i] =
Re: [Intel-gfx] [PATCH] drm/i915: Update WaFlushCoherentL3CacheLinesAtContextSwitch
On Mon, Jul 06, 2015 at 12:52:51PM +0100, Dave Gordon wrote: On 03/07/15 16:42, Chris Wilson wrote: On Fri, Jul 03, 2015 at 02:27:31PM +0100, Arun Siluvery wrote: In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after PIPE_CONTROL instruction but there is a slight complication as this is applied in WA batch where the values are only initialized once. Dave identified an issue with the current implementation where the register value is read once at the beginning and it is reused; this patch corrects this by saving the register value to memory, update register with the bit of our interest and restore it back with original value. This implementation uses MI_LOAD_REGISTER_MEM which is currently only used by command parser and was using a default length of 0. This is now updated with correct length and moved to appropriate place. Cc: Chris Wilson ch...@chris-wilson.co.uk Cc: Dave Gordon david.s.gor...@intel.com Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 6 +-- drivers/gpu/drm/i915/i915_reg.h| 3 +- drivers/gpu/drm/i915/intel_lrc.c | 72 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 306d9e4..430571b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -131,7 +131,7 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { .mask = MI_GLOBAL_GTT, .expected = 0, }}, ), - CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W | B, + CMD( MI_LOAD_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, .reg = { .offset = 1, .mask = 0x007C }, .bits = {{ .offset = 0, @@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * only MI_LOAD_REGISTER_IMM commands. */ if (reg_addr == OACONTROL) { - if (desc-cmd.value == MI_LOAD_REGISTER_MEM) { + if (desc-cmd.value == MI_LOAD_REGISTER_MEM(1)) { I had a double take here, but it all comes out in the wash. For one moment, I thought the cmd matching had changed, but that has the length masked out. Reviewed-by: Chris Wilson ch...@cris-wilson.co.uk Queued for -next, thanks for the patch. Who will start to complain about all the extra frequent register writes, probably into common power wells -Chris Hmm ... that is quite confusing, especially as the actual opcode in the instruction stream will be MI_LOAD_REGISTER_MEM(2) on GEN8+. It might almost be better to use MI_LOAD_REGISTER_MEM(0) to emphasise that the length field is a wildcard and not something that will be matched exactly. There's a separate _GEN8 #define to accomodate the differences, so I don't fully understand your concern. We also don't do any decoding in the kernel ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 01/16] stats: Add a way to generate values following a normal distribution
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_stats.c | 68 + lib/igt_stats.h | 3 +++ 2 files changed, 71 insertions(+) diff --git a/lib/igt_stats.c b/lib/igt_stats.c index 70650ec..37fcc23 100644 --- a/lib/igt_stats.c +++ b/lib/igt_stats.c @@ -25,6 +25,7 @@ #include math.h #include stdlib.h #include string.h +#include time.h #include igt_core.h #include igt_stats.h @@ -132,6 +133,73 @@ void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity) stats-max = 0; } +/* https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform */ +static double rand_normal(double mean, double stddev) +{ + static double n2 = 0.0; + static bool n2_cached = 0; + double d, n1; + + if (!n2_cached) { + double x, y, r; + + do { + x = 2.0 * rand() / RAND_MAX - 1; + y = 2.0 * rand() / RAND_MAX - 1; + + r = x * x + y * y; + } while (r == 0.0 || r 1.0); + + d = sqrt(-2.0 * log(r) / r); + n1 = x * d; + n2 = y * d; + + n2_cached = 1; + return n1 * stddev + mean; + } else { + n2_cached = 0; + return n2 * stddev + mean; + } +} + +static double * +igt_vector_normal(double mean, double sigma, unsigned int n_values) +{ + double *v; + unsigned int i; + + v = malloc(n_values * sizeof(double)); + srand(time(NULL)); + for (i = 0; i n_values; i++) + v[i] = rand_normal(mean, sigma); + + return v; +} + +/** + * igt_stats_init_normal: + * @stats: An #igt_stats_t instance + * @mean: Mean of the distribution + * @std_deviation: Standard deviation of the distribution + * @n_values: Number of values to generate + * + * Generates @n_values numbers following a normal distribution defined by + * (@mean, @std_deviation). + */ +void igt_stats_init_normal(igt_stats_t *stats, + double mean, double std_deviation, + unsigned int n_values) +{ + double *v; + unsigned int i; + + v = igt_vector_normal(mean, std_deviation, n_values); + igt_stats_init_with_size(stats, n_values); + for (i = 0; i n_values; i++) + igt_stats_push(stats, v[i]); + free(v); +} + /** * igt_stats_fini: * @stats: An #igt_stats_t instance diff --git a/lib/igt_stats.h b/lib/igt_stats.h index 554ab15..e1757b7 100644 --- a/lib/igt_stats.h +++ b/lib/igt_stats.h @@ -49,6 +49,9 @@ typedef struct { void igt_stats_init(igt_stats_t *stats); void igt_stats_init_with_size(igt_stats_t *stats, unsigned int capacity); +void igt_stats_init_normal(igt_stats_t *stats, + double mean, double std_deviation, + unsigned int n_values); void igt_stats_fini(igt_stats_t *stats); bool igt_stats_is_population(igt_stats_t *stats); void igt_stats_set_population(igt_stats_t *stats, bool full_population); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 07/16] plot: Add a map() to igt_vector_t
Can use to reduce typing a bit, at the expense of a function call. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 21 - lib/igt_plot.h | 9 + lib/tests/igt_plot.c | 11 ++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 3f3c2fe..9a1bea2 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -139,6 +139,25 @@ void igt_vector_unref(igt_vector_t *v) } /** + * igt_vector_map: + * @v: An #igt_vector_t + * @func: Map function + * + * igt_vector_map() creates a new array cycling through @v and applying @func + * to all @v's elements. + */ +igt_vector_t *igt_vector_map(igt_vector_t *v, igt_vector_map_func_t func) +{ + igt_vector_t *ret; + unsigned int i; + + ret = igt_vector_new_internal(v-n); + for (i = 0; i v-n; i++) + ret-values[i] = func(v-values[i]); + return ret; +} + +/** * igt_vector_get_min_max: * @v: An #igt_vector_t * @min: (out): The minimum value in @v @@ -547,7 +566,7 @@ static void igt_plot_layout_tick_labels(igt_plot_t *plot, double v = axis-min + (axis-max - axis-min) * i / (axis-n_ticks - 1); - asprintf(label-text, %.02lf, v); + asprintf(label-text, %.2lf, v); cairo_text_extents(plot-cr, label-text, label-extents); if (axis-orientation == IGT_ORIENTATION_HORIZONTAL) { diff --git a/lib/igt_plot.h b/lib/igt_plot.h index 2e00c60..2af035e 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@ -48,6 +48,14 @@ typedef struct { double values[]; } igt_vector_t; +/** + * igt_vector_map_func_t: + * @value: a double to act on + * + * Type of functions to use with igt_vector_map(). + */ +typedef double (*igt_vector_map_func_t)(double value); + igt_vector_t *igt_vector_new(unsigned int n); igt_vector_t *igt_vector_new_from_array(const double *array, unsigned int n); igt_vector_t *igt_vector_new_from_array_u64(const uint64_t *array, @@ -55,6 +63,7 @@ igt_vector_t *igt_vector_new_from_array_u64(const uint64_t *array, igt_vector_t *igt_vector_linear(double min, double max, unsigned n); igt_vector_t *igt_vector_ref(igt_vector_t *v); void igt_vector_unref(igt_vector_t *v); +igt_vector_t *igt_vector_map(igt_vector_t *v, igt_vector_map_func_t func); void igt_vector_get_min_max(const igt_vector_t *v, double *min, double *max); /** diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c index cb7f022..2f5ad27 100644 --- a/lib/tests/igt_plot.c +++ b/lib/tests/igt_plot.c @@ -69,17 +69,18 @@ static void test_min_max(void) igt_vector_unref(v2); } +static double f(double x) +{ + return sin(2 * M_PI * x); +} + static void test_simple_plot(void) { igt_vector_t *x, *y; - unsigned int i; igt_plot_t plot; x = igt_vector_linear(-1.0, 1.0, 200); - - y = igt_vector_new(200); - for (i = 0; i y-n; i++) - y-values[i] = sin(2 * M_PI * x-values[i]); + y = igt_vector_map(x, f); igt_plot_init(plot, 800, 600); igt_plot_set_color(plot, 0.0, 0.0, 1.0, 1.0); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 03/16] stats: Add an histogram object
Histograms are a great way to have a look at a dataset to understand how the values are distributed. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_stats.c | 105 ++ lib/igt_stats.h | 23 +++ lib/tests/igt_stats.c | 24 3 files changed, 152 insertions(+) diff --git a/lib/igt_stats.c b/lib/igt_stats.c index 1103a7b..d757fc6 100644 --- a/lib/igt_stats.c +++ b/lib/igt_stats.c @@ -639,3 +639,108 @@ double igt_stats_get_trimean(igt_stats_t *stats) igt_stats_get_quartiles(stats, q1, q2, q3); return (q1 + 2*q2 + q3) / 4; } + +/** + * igt_histogram_init: + * @hist: An #igt_histogram_t instance + * @stats: Input data + * + * Initializes an igt_histogram_t object. Use igt_histogram_fini() when finished + * with it. + */ +void igt_histogram_init(igt_histogram_t *hist, igt_stats_t *stats) +{ + memset(hist, 0, sizeof(*hist)); + hist-stats = stats; + hist-n_bins = 10; +} + +/** + * igt_histogram_fini: + * @hist: An #igt_histogram_t instance + * + * Frees resources allocated during the life time of @hist. + */ +void igt_histogram_fini(igt_histogram_t *hist) +{ + free(hist-frequencies); +} + +/* XXX: we should probably use an automatic binning algorithm */ + +/** + * igt_histogram_set_n_bins: + * @hist: An #igt_histogram_t instance + * @n_bins: Number of bins + * + * Set how many bins should be use to classify the input data. + * + * The default is 10. + */ +void igt_histogram_set_n_bins(igt_histogram_t *hist, unsigned int n_bins) +{ + if (hist-n_bins == n_bins) + return; + + hist-n_bins = n_bins; + free(hist-frequencies); + hist-frequencies = NULL; +} + +/** + * igt_histogram_set_density: + * @hist: An #igt_histogram_t instance + * @density: The new density setting + * + * Whether the histogram should represent a density distribution (integral over + * the range of the input data is 1) or simply contain the number of data + * points in each bin. + * + * By default density is #false. + * + */ +void igt_histogram_set_density(igt_histogram_t *hist, bool density) +{ + if (hist-compute_density == density) + return; + + hist-compute_density = density; + free(hist-frequencies); + hist-frequencies = NULL; +} + +double *igt_histogram_get_frequencies(igt_histogram_t *hist) +{ + igt_stats_t *stats = hist-stats; + unsigned int i; + uint64_t min, max; + double bin_length; + + /* +* XXX: we could cache frequencies with a way to know if stats has +* changed since the last time. +*/ + free(hist-frequencies); + hist-frequencies = calloc(hist-n_bins, sizeof(double)); + + min = igt_stats_get_min(stats); + max = igt_stats_get_max(stats); + bin_length = (max - min) / (double)hist-n_bins; + + for (i = 0; i stats-n_values; i++) { + unsigned int bin; + + bin = (stats-values[i] - min) / bin_length; + if (bin = hist-n_bins) + bin--; + hist-frequencies[bin]++; + } + + if (!hist-compute_density) + return hist-frequencies; + + for (i = 0; i hist-n_bins; i++) + hist-frequencies[i] /= stats-n_values; + + return hist-frequencies; +} diff --git a/lib/igt_stats.h b/lib/igt_stats.h index d6eb48f..46b7019 100644 --- a/lib/igt_stats.h +++ b/lib/igt_stats.h @@ -73,4 +73,27 @@ double igt_stats_get_median(igt_stats_t *stats); double igt_stats_get_variance(igt_stats_t *stats); double igt_stats_get_std_deviation(igt_stats_t *stats); +/** + * igt_histogram_t: + * + * An histogram will split the input data containted in an #igt_stats_t object + * in a number of bins and, depending on the density property, either: + * - Compute the number of data points in each bin, + * - Normalize the data such as the histogram represents a density function, + * the integral over the range is 1. + */ +typedef struct { + /* private */ + igt_stats_t *stats; + unsigned int n_bins; + double *frequencies; + bool compute_density; +} igt_histogram_t; + +void igt_histogram_init(igt_histogram_t *hist, igt_stats_t *stats); +void igt_histogram_fini(igt_histogram_t *hist); +void igt_histogram_set_n_bins(igt_histogram_t *hist, unsigned int n_bins); +void igt_histogram_set_density(igt_histogram_t *hist, bool density); +double *igt_histogram_get_frequencies(igt_histogram_t *hist); + #endif /* __IGT_STATS_H__ */ diff --git a/lib/tests/igt_stats.c b/lib/tests/igt_stats.c index 12778e2..480321f 100644 --- a/lib/tests/igt_stats.c +++ b/lib/tests/igt_stats.c @@ -227,6 +227,29 @@ static void test_reallocation(void) igt_stats_fini(stats); } +static void test_histogram(void) +{ + static const uint64_t s1[] = { 10, 12, 14, 16, 87, 53, 90, 72 }; + igt_stats_t stats; + igt_histogram_t hist; +
[Intel-gfx] [PATCH i-g-t 11/16] plot: Add a title to plots
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 59 lib/igt_plot.h | 2 ++ lib/tests/igt_plot.c | 1 + 3 files changed, 62 insertions(+) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index afe4a1c..2ca005e 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -303,6 +303,8 @@ void igt_plot_fini(igt_plot_t *plot) { unsigned int i; + free(plot-title); + for (i = 0; i plot-n_valid_contexts; i++) igt_plot_ctx_fini(plot-contexts[i]); @@ -314,6 +316,22 @@ void igt_plot_fini(igt_plot_t *plot) } /** + * igt_plot_set_title: + * @plot: An #igt_plot_t instance + * @title: An UTF-8 string + * + * Set a title for the plot. + */ +void igt_plot_set_title(igt_plot_t *plot, const char *title) +{ + free(plot-title); + plot-title = NULL; + if (!title) + return; + plot-title = strndup(title, 64); +} + +/** * igt_plot_set_color: * @plot: An #igt_plot_t instance * @r: Red component in the [0, 1] range @@ -407,9 +425,12 @@ typedef struct { } igt_label_t; typedef struct { + double inner_padding; /* padding for most things */ double tick_label_padding; /* padding between label and axis */ + double title_font_size; double tick_label_font_size; igt_box_t plot_area; + igt_label_t title; igt_label_t *x_tick_labels; igt_label_t *y_tick_labels; } flush_t; @@ -470,6 +491,22 @@ static void igt_plot_draw_background(igt_plot_t *plot, flush_t *flush) cairo_fill(plot-cr); } +static void igt_plot_draw_title(igt_plot_t *plot, flush_t *flush) +{ + igt_box_t *area = flush-plot_area; + double x, y; + + if (!plot-title) + return; + + cairo_set_font_size(plot-cr, flush-title_font_size); + cairo_set_source_rgb(plot-cr, 0.0, 0.0, 0.0); + + x = area-x1 + (area-x2 - area-x1 ) / 2.0; + y = flush-plot_area.y1 - flush-inner_padding; + igt_plot_draw_text(plot, SNAP(x), SNAP(y), flush-title); +} + static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush) { unsigned int i, n_ticks; @@ -632,6 +669,20 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush) } +static void igt_plot_layout_title(igt_plot_t *plot, flush_t *flush) +{ + igt_label_t *label = flush-title; + + if (!plot-title) + return; + + label-text = plot-title; + label-halign = IGT_ALIGN_CENTER; + label-valign = IGT_ALIGN_BOTTOM; + cairo_set_font_size(plot-cr, flush-title_font_size); + cairo_text_extents(plot-cr, label-text, label-extents); +} + static void igt_plot_layout_tick_labels(igt_plot_t *plot, igt_plot_axis_t *axis, igt_label_t *labels, @@ -668,7 +719,9 @@ static void igt_plot_layout(igt_plot_t *plot, flush_t *flush) const double outer_padding = 0.10; double max_width, max_height; + flush-inner_padding = plot_length(plot, 0.05); flush-tick_label_padding = plot_length(plot, 0.02); + flush-title_font_size = round(0.025 * plot-width); flush-tick_label_font_size = round(0.015 * plot-width); /* outer padding */ @@ -677,6 +730,11 @@ static void igt_plot_layout(igt_plot_t *plot, flush_t *flush) flush-plot_area.x2 = SNAP(plot-width * (1.0 - outer_padding)); flush-plot_area.y2 = SNAP(plot-height * (1.0 - outer_padding)); + /* plot title */ + igt_plot_layout_title(plot, flush); + flush-plot_area.y1 += flush-title.extents.height + + flush-inner_padding; + /* measure tick labels and adjust the plot area */ cairo_set_font_size(plot-cr, flush-tick_label_font_size); igt_plot_layout_tick_labels(plot, plot-x_axis, flush-x_tick_labels, @@ -720,6 +778,7 @@ void igt_plot_write(igt_plot_t *plot, const char *filename) igt_plot_layout(plot, flush); igt_plot_draw_background(plot, flush); + igt_plot_draw_title(plot, flush); igt_plot_draw_axis(plot, flush); for (i = 0; i plot-n_valid_contexts; i++) igt_plot_draw_one(plot, plot-contexts[i], flush); diff --git a/lib/igt_plot.h b/lib/igt_plot.h index c8b031f..cca498a 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@ -103,6 +103,7 @@ typedef struct { /* plot-wide states */ unsigned int width, height; + char *title; igt_trbl_t margin; igt_plot_axis_t x_axis, y_axis; igt_plot_axis_t x_axis_top, y_axis_right; @@ -127,6 +128,7 @@ typedef enum { void igt_plot_init(igt_plot_t *plot, unsigned int width, unsigned int height); void igt_plot_fini(igt_plot_t *plot); +void igt_plot_set_title(igt_plot_t *plot, const char *title); void igt_plot_set_color(igt_plot_t *plot, double r, double g, double b,
[Intel-gfx] [PATCH i-g-t 08/16] plot: Add top and right axes
This frames a bit more the plot will look nice with a background grid. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 46 +- lib/igt_plot.h | 2 ++ lib/igt_types.h | 14 ++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 9a1bea2..126f160 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -221,12 +221,16 @@ igt_vector_t *igt_vector_linear(double min, double max, unsigned int n) } static void igt_plot_axis_init(igt_plot_axis_t *axis, - igt_orientation_t orientation) + igt_side_t side) { memset(axis, 0, sizeof(*axis)); axis-n_ticks = 5; - axis-orientation = orientation; + axis-side = side; + if (side == IGT_SIDE_TOP || side == IGT_SIDE_BOTTOM) + axis-orientation = IGT_ORIENTATION_HORIZONTAL; + else + axis-orientation = IGT_ORIENTATION_VERTICAL; axis-min = DBL_MAX; axis-max = -DBL_MAX; } @@ -280,8 +284,10 @@ void igt_plot_init(igt_plot_t *plot, unsigned int width, unsigned int height) plot-height = height; plot-cr = cairo_create(plot-surface); - igt_plot_axis_init(plot-x_axis, IGT_ORIENTATION_HORIZONTAL); - igt_plot_axis_init(plot-y_axis, IGT_ORIENTATION_VERTICAL); + igt_plot_axis_init(plot-x_axis, IGT_SIDE_BOTTOM); + igt_plot_axis_init(plot-y_axis, IGT_SIDE_LEFT); + igt_plot_axis_init(plot-x_axis_top, IGT_SIDE_TOP); + igt_plot_axis_init(plot-y_axis_right, IGT_SIDE_RIGHT); plot-ctx = plot-contexts[0]; igt_plot_ctx_init(plot-ctx); @@ -501,6 +507,7 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis, area_width = area-x2 - area-x1; area_height = area-y2 - area-y1; + cairo_set_font_size(plot-cr, flush-tick_label_font_size); cairo_set_line_cap(plot-cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_width(plot-cr, 1.0); @@ -508,7 +515,7 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis, double x, y; igt_label_t *label; - if (axis-orientation == IGT_ORIENTATION_HORIZONTAL) { + if (axis-side == IGT_SIDE_BOTTOM) { x = area-x1 + i * area_width / (axis-n_ticks - 1); y = area-y2; @@ -518,7 +525,8 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis, label = flush-x_tick_labels[i]; y += flush-tick_label_padding; - } else { + igt_plot_draw_text(plot, x, y, label); + } else if (axis-side == IGT_SIDE_LEFT) { x = area-x1; y = area-y2 - i * area_height / (axis-n_ticks - 1); @@ -528,10 +536,22 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis, label = flush-y_tick_labels[i]; x -= flush-tick_label_padding; - } + igt_plot_draw_text(plot, x, y, label); + } else if (axis-side == IGT_SIDE_TOP) { + x = area-x1 + i * area_width / (axis-n_ticks - 1); + y = area-y1; - cairo_set_font_size(plot-cr, flush-tick_label_font_size); - igt_plot_draw_text(plot, x, y, label); + cairo_move_to(plot-cr, SNAP(x), y); + cairo_line_to(plot-cr, SNAP(x), SNAP(y + tick_length)); + cairo_stroke(plot-cr); + } else { + x = area-x2; + y = area-y1 + i * area_height / (axis-n_ticks - 1); + + cairo_move_to(plot-cr, x, SNAP(y)); + cairo_line_to(plot-cr, SNAP(x - tick_length), SNAP(y)); + cairo_stroke(plot-cr); + } } } @@ -545,11 +565,19 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush) cairo_line_to(plot-cr, area-x2, area-y2); igt_plot_draw_ticks(plot, plot-x_axis, tick_length, flush); + cairo_move_to(plot-cr, area-x1, area-y1); + cairo_line_to(plot-cr, area-x2, area-y1); + igt_plot_draw_ticks(plot, plot-x_axis_top, tick_length, flush); + /* Y-axis */ cairo_move_to(plot-cr, area-x1, area-y2); cairo_line_to(plot-cr, area-x1, area-y1); igt_plot_draw_ticks(plot, plot-y_axis, tick_length, flush); + cairo_move_to(plot-cr, area-x2, area-y1); + cairo_line_to(plot-cr, area-x2, area-y2); + igt_plot_draw_ticks(plot, plot-y_axis_right, tick_length, flush); + } static void igt_plot_layout_tick_labels(igt_plot_t *plot, diff --git a/lib/igt_plot.h b/lib/igt_plot.h index 2af035e..c8b031f 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@
[Intel-gfx] [PATCH i-g-t 04/16] lib: Add some basic types
Might as well start to define some igt wide types. I'll need them for igt_plot, but other things belong here, like a color type. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- .../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 + lib/Makefile.sources | 1 + lib/igt_types.h| 99 ++ 3 files changed, 101 insertions(+) create mode 100644 lib/igt_types.h diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml index 618dc5f..0992308 100644 --- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml +++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml @@ -17,6 +17,7 @@ titleAPI Reference/title xi:include href=xml/drmtest.xml/ xi:include href=xml/igt_core.xml/ +xi:include href=xml/igt_types.xml/ xi:include href=xml/igt_stats.xml/ xi:include href=xml/igt_debugfs.xml/ xi:include href=xml/igt_draw.xml/ diff --git a/lib/Makefile.sources b/lib/Makefile.sources index 7f88b65..205a9aa 100644 --- a/lib/Makefile.sources +++ b/lib/Makefile.sources @@ -14,6 +14,7 @@ libintel_tools_la_SOURCES = \ igt_gt.h\ igt_stats.c \ igt_stats.h \ + igt_types.h \ instdone.c \ instdone.h \ intel_batchbuffer.c \ diff --git a/lib/igt_types.h b/lib/igt_types.h new file mode 100644 index 000..3d7f1d6 --- /dev/null +++ b/lib/igt_types.h @@ -0,0 +1,99 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __IGT_TYPES_H__ +#define __IGT_TYPES_H__ + +/** + * SECTION:igt_types + * @short_description: Some handy types + * @title: Basic Types + * @include: igt_types.h + */ + +/** + * igt_orientation_t: + * @IGT_ORIENTATION_HORIZONTAL: Horizontal + * @IGT_ORIENTATION_VERTICAL: Vertical + */ +typedef enum { + IGT_ORIENTATION_HORIZONTAL, + IGT_ORIENTATION_VERTICAL, +} igt_orientation_t; + +/** + * igt_point_t: + * @x: X coordinate + * @y: Y coordinate + * + * A point on a plane. + */ +typedef struct { + double x, y; +} igt_point_t; + +/** + * igt_box_t: + * @x1: X-coordinate of the top left corner + * @y1: Y-coordinate of the top left corner + * @x2: X-coordinate of the bottom right corner + * @y2: Y-coordinate of the bottom right corner + * + * A rectangle defined by two points. + */ +typedef struct { + double x1, y1, x2, y2; +} igt_box_t; + +/** + * igt_trbl_t: + * @top: Top value + * @right: Right value + * @bottom: Bottom value + * @left: Left value + * + * Useful to store margin, padding, ... with a CSS-like feeling. + */ +typedef struct { + double top, right, bottom, left; +} igt_trbl_t; + +/** + * igt_align_t: + * @IGT_ALIGN_LEFT: Align left + * @IGT_ALIGN_RIGHT: Align right + * @IGT_ALIGN_TOP: Align top + * @IGT_ALIGN_BOTTOM: Align bottom + * @IGT_ALIGN_CENTER: Align center + * + * An alignment type, to give to text drawing functions for instance. + */ +typedef enum { + IGT_ALIGN_LEFT, + IGT_ALIGN_RIGHT, + IGT_ALIGN_TOP, + IGT_ALIGN_BOTTOM, + IGT_ALIGN_CENTER, +} igt_align_t; + +#endif /* __IGT_TYPES_H__ */ -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 10/16] plot: Make sure to have a color in the background
Until now we had transparent black. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index c8d6dcb..afe4a1c 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -452,6 +452,24 @@ igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) cairo_show_text(plot-cr, label-text); } +static void igt_plot_draw_background(igt_plot_t *plot, flush_t *flush) +{ + igt_box_t *area = flush-plot_area; + double area_width, area_height; + + area_width = area-x2 - area-x1; + area_height = area-y2 - area-y1; + + cairo_set_source_rgb(plot-cr, 1.0, 1.0, 1.0); + cairo_rectangle(plot-cr, 0.0, 0.0, plot-width, plot-height); + cairo_fill(plot-cr); + + cairo_set_source_rgb(plot-cr, 0.99, 0.99, 0.99); + cairo_rectangle(plot-cr, SNAP(area-x1), SNAP(area-y1), + area_width, area_height); + cairo_fill(plot-cr); +} + static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush) { unsigned int i, n_ticks; @@ -701,8 +719,8 @@ void igt_plot_write(igt_plot_t *plot, const char *filename) igt_plot_layout(plot, flush); + igt_plot_draw_background(plot, flush); igt_plot_draw_axis(plot, flush); - for (i = 0; i plot-n_valid_contexts; i++) igt_plot_draw_one(plot, plot-contexts[i], flush); -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 13/16] plot: Add axis titles
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 100 +-- lib/igt_plot.h | 9 - lib/tests/igt_plot.c | 2 ++ 3 files changed, 100 insertions(+), 11 deletions(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 763c000..b3d4bc7 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -422,6 +422,7 @@ typedef struct { char *text; cairo_text_extents_t extents; igt_align_t halign, valign; + double rotation; } igt_label_t; typedef struct { @@ -430,9 +431,10 @@ typedef struct { double title_font_size; double tick_label_font_size; igt_box_t plot_area; - igt_label_t title; + igt_label_t title, x_title, y_title; igt_label_t *x_tick_labels; igt_label_t *y_tick_labels; + double y_tick_width, x_tick_height; } flush_t; static double plot_length(igt_plot_t *plot, double percent) @@ -476,15 +478,22 @@ igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) if (plot-debug) { cairo_set_source_rgb(plot-cr, 1.0, 0.0, 0.0); - cairo_move_to(plot-cr, x, y); - cairo_rectangle(plot-cr, x, y, + cairo_translate(plot-cr, x, y); + if (label-rotation) + cairo_rotate(plot-cr, label-rotation); + cairo_rectangle(plot-cr, 0, 0, label-extents.width, -label-extents.height); cairo_stroke(plot-cr); + cairo_identity_matrix(plot-cr); } cairo_set_source_rgb(plot-cr, 0.0, 0.0, 0.0); cairo_move_to(plot-cr, x, y); + if (label-rotation) + cairo_rotate(plot-cr, label-rotation); cairo_show_text(plot-cr, label-text); + if (label-rotation) + cairo_identity_matrix(plot-cr); } static void igt_plot_draw_background(igt_plot_t *plot, flush_t *flush) @@ -521,6 +530,30 @@ static void igt_plot_draw_title(igt_plot_t *plot, flush_t *flush) igt_plot_draw_text(plot, SNAP(x), SNAP(y), flush-title); } +static void igt_plot_draw_axis_title(igt_plot_t *plot, igt_plot_axis_t *axis, +igt_label_t *label, flush_t *flush) +{ + igt_box_t *area = flush-plot_area; + double x, y; + + if (!plot-title) + return; + + cairo_set_font_size(plot-cr, flush-title_font_size); + cairo_set_source_rgb(plot-cr, 0.0, 0.0, 0.0); + + if (axis-side == IGT_SIDE_BOTTOM) { + x = area-x1 + (area-x2 - area-x1 ) / 2.0; + y = area-y2 + flush-x_tick_height + flush-inner_padding; + igt_plot_draw_text(plot, SNAP(x), SNAP(y), label); + } else { + x = area-x1 - 2 * flush-tick_label_padding - + flush-y_tick_width; + y = area-y1 + (area-y2 - area-y1) / 2.0; + igt_plot_draw_text(plot, SNAP(x), SNAP(y), label); + } +} + static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush) { unsigned int i, n_ticks; @@ -661,6 +694,9 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush) igt_box_t *area = flush-plot_area; const double tick_length = plot_length(plot, 0.01); + igt_plot_draw_axis_title(plot, plot-x_axis, flush-x_title, flush); + igt_plot_draw_axis_title(plot, plot-y_axis, flush-y_title, flush); + igt_plot_draw_grid(plot, flush); /* X-axis */ @@ -695,6 +731,33 @@ static void igt_plot_layout_title(igt_plot_t *plot, flush_t *flush) label-valign = IGT_ALIGN_BOTTOM; cairo_set_font_size(plot-cr, flush-title_font_size); cairo_text_extents(plot-cr, label-text, label-extents); + + flush-plot_area.y1 += flush-title.extents.height + + flush-inner_padding; +} + +static void igt_plot_layout_axis_title(igt_plot_t *plot, igt_plot_axis_t *axis, + igt_label_t *label, flush_t *flush) +{ + if (!axis-title) + return; + + label-text = axis-title; + cairo_set_font_size(plot-cr, flush-title_font_size); + cairo_text_extents(plot-cr, label-text, label-extents); + + if (axis-side == IGT_SIDE_BOTTOM) { + label-halign = IGT_ALIGN_CENTER; + label-valign = IGT_ALIGN_TOP; + flush-plot_area.y2 -= flush-x_title.extents.height + + flush-inner_padding; + } else { + label-halign = IGT_ALIGN_LEFT; + label-valign = IGT_ALIGN_CENTER; + label-rotation = -M_PI / 2; + flush-plot_area.x1 += flush-y_title.extents.height + + flush-inner_padding; + } } static void igt_plot_layout_tick_labels(igt_plot_t *plot, @@ -731,7 +794,6 @@ static void igt_plot_layout_tick_labels(igt_plot_t *plot,
[Intel-gfx] [PATCH i-g-t 16/16] plot: Add an example of the plotting API
Unfortunately, I didn't manage to make the image inclusion work... Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_plot.c | 29 - 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index b3d4bc7..bc7bce1 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -43,7 +43,34 @@ * @include: igt_plots.h * * A drawing is better than a long speech. Plotting data can reveal surprises - * and the igt_plot_t object let you do just that. + * and igt_plot_t lets you do just that. + * + * To draw a plot, one needs to populate 2 #igt_vector_t for the X and Y axis + * and draw the result. + * + * |[ + * static double f(double x) + * { + *return sin(2 * M_PI * x); + * } + * + * void draw_plot(void) + * { + *igt_vector_t *x, *y; + *igt_plot_t plot; + * + *x = igt_vector_linear(-1.0, 1.0, 200); + *y = igt_vector_map(x, f); + * + *igt_plot_init(plot, 800, 600); + *igt_plot_set_title(plot, f(x) = sin(2πx)); + *igt_plot_axis_set_title(plot.x_axis, x); + *igt_plot_axis_set_title(plot.y_axis, f(x)); + *igt_plot_set_color(plot, 0.0, 0.0, 1.0, 1.0); + *igt_plot_draw(plot, x, y); + *igt_plot_write(plot, test_simple_plot.png); + * } + * ]| */ /* snap to pixel */ -- 2.1.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: RMW register cycles considered evil
On Mon, Jul 06, 2015 at 02:42:02PM +0200, Daniel Vetter wrote: Especially for workarounds which is stuff that's almost impossible to verify: The initial state from the firmware on boot-up and after resume could be different, which will hide bugs when we do an RMW cycle. Hence never do them, and if it's required we need a special mask. Cc: Damien Lespiau damien.lesp...@intel.com Cc: Imre Deak imre.d...@intel.com Cc: Nick Hoath nicholas.ho...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@intel.com Eeek. Let's take the problem the other way around: have you verified it's OK to zero all those other fields? -- Damien --- drivers/gpu/drm/i915/intel_pm.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 166ae51f5a5b..565f78d6a21d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -57,7 +57,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; /* WaEnableLbsSlaRetryTimerDecrement:skl */ - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | + I915_WRITE(BDW_SCRATCH1, GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); } @@ -72,18 +72,18 @@ static void skl_init_clock_gating(struct drm_device *dev) * WaDisableSDEUnitClockGating:skl * WaSetGAPSunitClckGateDisable:skl */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableVFUnitClockGating:skl */ - I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | + I915_WRITE(GEN6_UCGCTL2, GEN6_VFUNIT_CLOCK_GATE_DISABLE); } if (INTEL_REVID(dev) = SKL_REVID_D0) { /* WaDisableHDCInvalidation:skl */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + I915_WRITE(GAM_ECOCHK, BDW_DISABLE_HDC_INVALIDATION); /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ @@ -93,7 +93,7 @@ static void skl_init_clock_gating(struct drm_device *dev) if (INTEL_REVID(dev) = SKL_REVID_E0) /* WaDisableLSQCROPERFforOCL:skl */ - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | + I915_WRITE(GEN8_L3SQCREG4, GEN8_LQSC_RO_PERF_DIS); } @@ -109,12 +109,12 @@ static void bxt_init_clock_gating(struct drm_device *dev) * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ /* WaDisableSDEUnitClockGating:bxt */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_SDEUNIT_CLOCK_GATE_DISABLE | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* FIXME: apply on A0 only */ - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); + I915_WRITE(TILECTL, TILECTL_TLBPF); } static void i915_pineview_get_mem_freq(struct drm_device *dev) -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [CABC PATCH v1 3/3][RFC] drm/i915: CABC support for backlight control
On Mon, Jul 06, 2015 at 09:46:07AM +0530, Deepak M wrote: In CABC (Content Adaptive Brightness Control) content grey level scale can be increased while simultaneously decreasing brightness of the backlight to achieve same perceived brightness. The CABC is not standardized and panel vendors are free to follow their implementation. The CABC implementaion here assumes that the panels use standard SW register for control. In this design there will be no PWM signal from the SoC and DCS commands are sent to enable and control the backlight brightness. Signed-off-by: Deepak M m.dee...@intel.com --- drivers/gpu/drm/i915/intel_dsi.h | 13 +++ drivers/gpu/drm/i915/intel_panel.c | 226 +++- include/video/mipi_display.h |8 ++ 3 files changed, 242 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index c39e39d..1f33cb2 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -34,6 +34,19 @@ #define DSI_DUAL_LINK_FRONT_BACK 1 #define DSI_DUAL_LINK_PIXEL_ALT 2 +#define CABC_OFF (0 0) +#define CABC_USER_INTERFACE_IMAGE(1 0) +#define CABC_STILL_PICTURE (2 0) +#define CABC_VIDEO_MODE (3 0) + +#define CABC_BACKLIGHT (1 2) +#define CABC_DIMMING_DISPLAY (1 3) +#define CABC_BCTRL (1 5) + +#define CABC_PORT_A 0x00 +#define CABC_PORT_C 0x01 +#define CABC_PORT_A_AND_C0x02 + struct intel_dsi_host; struct intel_dsi { diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 55aad23..7aa211e 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -32,7 +32,10 @@ #include linux/kernel.h #include linux/moduleparam.h +#include video/mipi_display.h +#include drm/drm_mipi_dsi.h #include intel_drv.h +#include intel_dsi.h void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, @@ -536,6 +539,37 @@ static u32 vlv_get_backlight(struct intel_connector *connector) return _vlv_get_backlight(dev, pipe); } +static u32 cabc_get_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector-base.dev; + struct intel_dsi *intel_dsi = NULL; + struct drm_crtc *crtc = NULL; + struct intel_encoder *encoder = NULL; + struct mipi_dsi_device *dsi_device; + u8 data[2] = {0}; + enum port port = PORT_A; + + list_for_each_entry(crtc, dev-mode_config.crtc_list, head) { + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder-type == INTEL_OUTPUT_DSI) + intel_dsi = enc_to_intel_dsi(encoder-base); + } + } We seem to have a bit a layering violation going on here: The dev_priv-display.*_backlight functions are for the device global backlight. But this here controls a sink-specific backlight. Another example of a sink-specific backlight control would be the optional backlight stuff for eDP. In linux we have a few backlight classes like firmware, platform or raw. The i915 backlight is a raw one and last in the priority chain userspace uses to figure out which backlight to use. I think the right approach here for the CABC dsi sink backlight is to register a new dsi backlight driver (if and only if the panel supports it of course) of type firmware (or something else suitable). Then it will automatically take precendence over the i915 raw backlight. It would also be good to have an explicit link from the sysfs connector to this connector-specific backlight so that userspace knows about it. Or something along those lines, linux backlight control is one giant mess. At least with that approach we don't need to have any interaction with the panel backlight code and this should all more-or-less cleanly integrate. -Daniel + + if (intel_dsi-dual_link) { + if (intel_dsi-dl_cabc_port == CABC_PORT_A || + intel_dsi-dl_cabc_port == CABC_PORT_A_AND_C) + port = PORT_A; + else if (intel_dsi-dl_cabc_port == CABC_PORT_C) + port = PORT_C; + } + + dsi_device = intel_dsi-dsi_hosts[port]-device; + mipi_dsi_dcs_read(dsi_device, MIPI_DCS_CABC_LEVEL_RD, data, 2); + + return data[1]; +} + static u32 bxt_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector-base.dev; @@ -624,6 +658,47 @@ static void vlv_set_backlight(struct intel_connector *connector, u32 level) I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); } +static void cabc_set_backlight(struct intel_connector *connector, u32 level) +{ + struct drm_device *dev = connector-base.dev; + struct intel_dsi
Re: [Intel-gfx] [PATCH] drm/i915: RMW register cycles considered evil
On Mon, Jul 06, 2015 at 02:42:02PM +0200, Daniel Vetter wrote: Especially for workarounds which is stuff that's almost impossible to verify: The initial state from the firmware on boot-up and after resume could be different, which will hide bugs when we do an RMW cycle. If you're really worried about that then we should then explicitly initialize all the registers that might affect stuff. For a bunch of GT registers we could just do a GPU reset at driver init. That that won't help with UCGCTL and such. I'm also worried that if we don't use RMWs for early parts, the hardware folks may still change the default for some ofhte other bits, and then we end up clobbering those. Hence never do them, and if it's required we need a special mask. Cc: Damien Lespiau damien.lesp...@intel.com Cc: Imre Deak imre.d...@intel.com Cc: Nick Hoath nicholas.ho...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 166ae51f5a5b..565f78d6a21d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -57,7 +57,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; /* WaEnableLbsSlaRetryTimerDecrement:skl */ - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | + I915_WRITE(BDW_SCRATCH1, GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); } @@ -72,18 +72,18 @@ static void skl_init_clock_gating(struct drm_device *dev) * WaDisableSDEUnitClockGating:skl * WaSetGAPSunitClckGateDisable:skl */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableVFUnitClockGating:skl */ - I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | + I915_WRITE(GEN6_UCGCTL2, GEN6_VFUNIT_CLOCK_GATE_DISABLE); } if (INTEL_REVID(dev) = SKL_REVID_D0) { /* WaDisableHDCInvalidation:skl */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + I915_WRITE(GAM_ECOCHK, BDW_DISABLE_HDC_INVALIDATION); /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ @@ -93,7 +93,7 @@ static void skl_init_clock_gating(struct drm_device *dev) if (INTEL_REVID(dev) = SKL_REVID_E0) /* WaDisableLSQCROPERFforOCL:skl */ - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | + I915_WRITE(GEN8_L3SQCREG4, GEN8_LQSC_RO_PERF_DIS); } @@ -109,12 +109,12 @@ static void bxt_init_clock_gating(struct drm_device *dev) * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ /* WaDisableSDEUnitClockGating:bxt */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_SDEUNIT_CLOCK_GATE_DISABLE | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* FIXME: apply on A0 only */ - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); + I915_WRITE(TILECTL, TILECTL_TLBPF); } static void i915_pineview_get_mem_freq(struct drm_device *dev) -- 2.1.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- 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 v4 2/2] drm/i915: On fb alloc failure, unref gem object where it gets refed
Hi Daniel, On Mon, Jul 06, 2015 at 09:41:51AM +0200, Daniel Vetter wrote: Please keep a record of the changes you do to the patch so I know what to look out for. Just reving the patch revision alone doesn't add much information for reviewers/maintainers. There's a changelog in the first patch of this 2 patch series (subject [PATCH v4 1/2] drm/i915: Fix failure paths around initial fbdev allocation), it says: v4: * Lock struct mutex on unref. (Chris Wilson) Best regards, Lukas ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC] drm/i915: Add sync framework support to execbuff IOCTL
On 06/07/2015 10:29, Daniel Vetter wrote: On Fri, Jul 03, 2015 at 12:17:33PM +0100, Tvrtko Ursulin wrote: On 07/02/2015 04:55 PM, Chris Wilson wrote: It would be nice if we could reuse one seqno both for internal/external fences. If you need to expose a fence ordering within a timeline that is based on the creation stamp rather than execution stamp, it seems like we could just add such a stamp when creating the sync_pt and not worry about its relationship to the execution seqno. Doing so does expose that requests are reordered to userspace since the signalling timeline is not the same as userspace's ordered timeline. Not sure if that is a problem or not. Afaict the sync uapi is based on waiting for all of a set of fences to retire. It doesn't seem to rely on fence ordering (that is knowing that fence A will signal before fence B so it need only wait on fence B). Here's hoping that we can have both simplicity and efficiency... Jumping in with not even perfect understanding of everything here - but timeline business has always been confusing me. There is nothing in the uapi which needs it afaics and iirc there was some discussion at the time Jesse floated his patches that it can be removed. Based on that when I squashed his patches and ported them on top of John's request to fence conversion it ended up something like the below (manually edited a bit to be less noisy and some prep patches omitted): This implements the ioctl based uapi and indeed seqnos are not actually used in waits. So is this insufficient for some reason? (Other that it does not implement the input fence side of things.) Yeah android syncpt on top of struct fence embedded int i915 request is what I'd have expected. The thing I'm not happy with in that plan is that it leaves the kernel driver at the mercy of user land applications. If we return a fence object to user land via a file descriptor (or indeed any other mechanism) then that fence object must be locked until user land closes the file. If the fence object is the one embedded within our request structure then that means user land is effectively locking our request structure. Given that more and more stuff is being attached to the request, that could be a fair bit of memory tied up that we can do nothing about. E.g. if a rogue/buggy application requests a fence be returned for every batch buffer submitted but never closes them. Whereas, if we go the route of a separate fence object specifically for user land then they can leak them like a sieve and we won't really care so much. diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 74acca9..07f6ad9 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -71,3 +71,17 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT option changes the default for that module option. If in doubt, say N. + +config DRM_I915_SYNC + bool Enable explicit sync support + depends on DRM_I915 + default y if STAGING + depends on STAGING + select ANDROID + select SYNC + help No Kconfig for userspace ABI please. Yes this means we need to destage android syncpts first. There is already a CONFIG_SYNC flag that wraps up all the existing sync code in the staging branch. There's not a lot we can do about that is there? We have to at least wrap the sync specific code in the i915 driver with '#if CONFIG_SYNC' otherwise it won't compile. The problem I see there is that apparently google is still changing the uabi a lot, and that's a no-go for upstream. And it needs to be cleaned up to work more seamlessly with struct fence (i.e. anything that's missing there should be moved to struct fence, drivers should only use fd_to_fence and fenct_to_fd functions similar to dma-buf). Are Google changing it or is it upstream that are changing it? The only changes to android/staging/sync.c have been a few minor bug fixes and Maarten Lankhorst's conversion to use struct fence which was back in July last year. And we don't have anyone except android using syncpts, so a bit a trouble with finding userspace vehicles for this. We probably need agreement from google to be happy with a frozen abi for syncpts first ... -Daniel I believe Jesse is wanting to use it for his work. John. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Update WaFlushCoherentL3CacheLinesAtContextSwitch
On 06/07/15 13:38, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 12:52:51PM +0100, Dave Gordon wrote: On 03/07/15 16:42, Chris Wilson wrote: On Fri, Jul 03, 2015 at 02:27:31PM +0100, Arun Siluvery wrote: In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after PIPE_CONTROL instruction but there is a slight complication as this is applied in WA batch where the values are only initialized once. Dave identified an issue with the current implementation where the register value is read once at the beginning and it is reused; this patch corrects this by saving the register value to memory, update register with the bit of our interest and restore it back with original value. This implementation uses MI_LOAD_REGISTER_MEM which is currently only used by command parser and was using a default length of 0. This is now updated with correct length and moved to appropriate place. Cc: Chris Wilson ch...@chris-wilson.co.uk Cc: Dave Gordon david.s.gor...@intel.com Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- drivers/gpu/drm/i915/i915_cmd_parser.c | 6 +-- drivers/gpu/drm/i915/i915_reg.h| 3 +- drivers/gpu/drm/i915/intel_lrc.c | 72 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 306d9e4..430571b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, * only MI_LOAD_REGISTER_IMM commands. */ if (reg_addr == OACONTROL) { - if (desc-cmd.value == MI_LOAD_REGISTER_MEM) { + if (desc-cmd.value == MI_LOAD_REGISTER_MEM(1)) { I had a double take here, but it all comes out in the wash. For one moment, I thought the cmd matching had changed, but that has the length masked out. Reviewed-by: Chris Wilson ch...@cris-wilson.co.uk Queued for -next, thanks for the patch. Who will start to complain about all the extra frequent register writes, probably into common power wells -Chris Hmm ... that is quite confusing, especially as the actual opcode in the instruction stream will be MI_LOAD_REGISTER_MEM(2) on GEN8+. It might almost be better to use MI_LOAD_REGISTER_MEM(0) to emphasise that the length field is a wildcard and not something that will be matched exactly. There's a separate _GEN8 #define to accomodate the differences, so I don't fully understand your concern. We also don't do any decoding in the kernel ... -Daniel In the snippet: - CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W | B, + CMD( MI_LOAD_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, the (1) goes in the table but is ignored when matching instructions in the stream being parsed. It could just as well be (2) or (0) or (255). Then, in the test: - if (desc-cmd.value == MI_LOAD_REGISTER_MEM) { + if (desc-cmd.value == MI_LOAD_REGISTER_MEM(1)) { the thing on the left of the == is not the instruction being examined, but the entry in the table that matched that instruction. So here also we're not really using the length field, EXCEPT that it MUST be the same as the (arbitrary) value in the table. So my concern here was not about correctness but comprehensibility and hence maintainability -- after all, if Chris had to look twice it obviously isn't as clear as one would like! My suggestion was that maybe the ignored length field should be 0 to make it less likely that a reader would think this matches exactly (and only) an opcode of 0xa41. Or maybe (255) would be even more obviously not-a-literal-match? .Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/15] drm/i915: Embedded microcontroller (uC) firmware loading support
On Mon, Jul 06, 2015 at 01:44:10PM +0100, Dave Gordon wrote: On 24/06/15 11:29, Daniel Vetter wrote: On Fri, Jun 19, 2015 at 09:43:11AM +0100, Dave Gordon wrote: On 18/06/15 15:49, Daniel Vetter wrote: On Thu, Jun 18, 2015 at 01:11:34PM +0100, Dave Gordon wrote: On 17/06/15 13:05, Daniel Vetter wrote: On Mon, Jun 15, 2015 at 07:36:20PM +0100, Dave Gordon wrote: Current devices may contain one or more programmable microcontrollers that need to have a firmware image (aka binary blob) loaded from an external medium and transferred to the device's memory. This file provides generic support functions for doing this; they can then be used by each uC-specific loader, thus reducing code duplication and testing effort. Signed-off-by: Dave Gordon david.s.gor...@intel.com Signed-off-by: Alex Dai yu@intel.com Given that I'm just shredding the synchronization used by the dmc loader I'm not convinced this is a good idea. Abstraction has cost, and a bit of copy-paste for similar sounding but slightly different things doesn't sound awful to me. And the critical bit in all the firmware loading I've seen thus far is in synchronizing the loading with other operations, hiding that isn't a good idea. Worse if we enforce stuff like requiring dev-struct_mutex. -Daniel It's precisely because it's in some sense trivial-but-tricky that we should write it once, get it right, and use it everywhere. Copypaste /does/ sound awful; I've seen how the code this was derived from had already been cloned into three flavours, all different and all wrong. It's a very simple abstraction: one early call to kick things off as early as possible, no locking required. One late call with the struct_mutex held to complete the synchronisation and actually do the work, thus guaranteeing that the transfer to the target uC is done in a controlled fashion, at a time of the caller's choice, and by the driver's mainline thread, NOT by an asynchronous thread racing with other activity (which was one of the things wrong with the original version). Yeah I've seen the origins of this in the display code, and that code gets the syncing wrong. The only thing that one has do to is grab a runtime pm reference for the appropriate power well to prevent dc5 entry, and release it when the firmware is loaded and initialized. Agreed. Which means any kind of firmware loader which requires/uses dev-struct_mutex get stuff wrong and is not appropriate everywhere. BUT, the loading of the firmware into any uC MUST be done in a controlled manner i.e. at a time when no other thread is touching the h/w. Otherwise the f/w load and whatever else is concurrently accessing the h/w could in some cases interfere disastrously. Examples of interference might be: * interleaved accesses to the ELSP (in the case of the GuC) * incorrect handover of power management (DMC, GuC) * erroneous management of forcewake state In general the f/w that is just starting on the uC may have certain expectations about the initial state of the h/w, which may not be met if other threads are accessing various bits of h/w while the uC is booting up. So we absolutely need to guarantee that the f/w load is done by a thread which has exclusive ownership of any bit of the h/w that the f/w is going to make assumptions about. With the current locking structure of the driver, that means holding the struct_mutex (it shouldn't really, there should be a separate mutex for h/w register access vs. driver-private data structures, but there isn't). If you really need this guarantee (and I seriously hope not) then the only option is a synchronous firmware load at driver init _before_ we launch any of the asynchronous setup code. And there is already a lot of that, and we're adding more all the time. What I expect we need is synchronization of just the revelant part with the firmware loading, which necessarily needs to be somewhat async to be able to support cros/android requirements. And yes that needs to be done in a controlled manner, but most likely we need very specific solutions for the problem at hand. Unconditionally holding dev-struct_mutex isn't that solution. The other problem with dev-struct_mutex is that it's a giantic lock with ill defined coverage and semantics. It's imo the biggest piece of technical debt we carry around in i915.ko, and we pay the price for that dearlydaily. Which means that since a few years any kind of code which extended dev-struct_mutex to anything not clearly core gem data structures was rejected. Oh, I quite agree that the struct_mutex is an abomination and would certainly like to eliminate it. But at the moment it's the only sufficiently large-scale synchronisation operation available to ensure that (for example) we don't try to load the f/w at the same time that another thread is trying to reset the h/w. I guess this is the crux here - for me part of the big problems around
Re: [Intel-gfx] [PATCH v2] drm/i915: Per-DDI I_boost override
On Fri, Jul 03, 2015 at 06:35:55PM +0300, Ville Syrjälä wrote: On Fri, Jul 03, 2015 at 04:25:15PM +0100, Damien Lespiau wrote: On Fri, Jul 03, 2015 at 06:21:58PM +0300, Ville Syrjälä wrote: In the old VBT spec I have, each child_dev_config is supposed to have only 33 bytes. But in this patch you're increasing it to 38. I believe this is what's causing the errors I see when I boot my BDW. Are you sure they increased the VBT's ChildDevInfo to more than 33 bytes? I don't have access to your VBT spec right now, so I can't do a proper review or a suggestion on how to fix the problem. The size depends on the version. On BSW last I looked it was maybe 36 or 37 bytes. I'm not sure we want to change common_child_dev_config since it's meant to be some kind of common stuff. So maybe add another member into the union for this stuff. Of course that still incrases the size of the union so other changes are required to make it work. Fortunately we copy these things out from the VBT, so I think just making sure the memcpy() doesn't try to copy too much and fixing the size check should be all that's needed. That would leave any extra we didn't fill with the copy zeroed, and if having it zeroed isn't good enough we can of course sprinkle more version checks around. And I guess we should still check that the size is at least 33 bytes since that was the official size for the longest time. So child_dev_size lies to us? No, it's correct. But we require it to be at least as big as our union child_device_config, which the patch changes from 33 to 37 bytes. Tbh I'd like us to be more paranoid about vbt, i.e. if they change struct sizes I think we should have an if ladder (checking vbt versions/platforms) to make sure that our expectation of the size matches reality in all cases. Ofc that should be a separate patch to start this series. Given the state of vbt revisions handling and documentation I don't think we can opt for too much safety checks here, sadly. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 5/7] drm/i915: Move intel_dp-lane_count into pipe_config
From: Ville Syrjälä ville.syrj...@linux.intel.com Currently we clobber intel_dp-lane_count in compute config, which means after a rejected modeset we may no longer be able to retrain the current link. Move lane_count into pipe_config to avoid that. v2: Add missing ':' to the pipe config debug dump Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 3 ++ drivers/gpu/drm/i915/intel_ddi.c | 10 +++--- drivers/gpu/drm/i915/intel_display.c | 7 +++-- drivers/gpu/drm/i915/intel_dp.c | 60 drivers/gpu/drm/i915/intel_dp_mst.c | 6 +++- drivers/gpu/drm/i915/intel_drv.h | 3 +- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d5c794a..f5dc75c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4096,6 +4096,7 @@ enum skl_disp_power_wells { /* How many wires to use. I guess 3 was too hard */ #define DP_PORT_WIDTH(width) (((width) - 1) 19) #define DP_PORT_WIDTH_MASK (7 19) +#define DP_PORT_WIDTH_SHIFT 19 /* Mystic DPCD version 1.1 special mode */ #define DP_ENHANCED_FRAMING (1 18) @@ -7128,6 +7129,8 @@ enum skl_disp_power_wells { #define DDI_BUF_IS_IDLE (17) #define DDI_A_4_LANES (14) #define DDI_PORT_WIDTH(width) (((width) - 1) 1) +#define DDI_PORT_WIDTH_MASK (7 1) +#define DDI_PORT_WIDTH_SHIFT 1 #define DDI_INIT_DISPLAY_DETECTED (10) /* DDI Buffer Translations */ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 96fb472..8df596d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -723,11 +723,11 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(encoder-base); struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder-base); + struct intel_crtc *crtc = to_intel_crtc(encoder-base.crtc); intel_dp-DP = intel_dig_port-saved_port_bits | DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); - intel_dp-DP |= DDI_PORT_WIDTH(intel_dp-lane_count); - + intel_dp-DP |= DDI_PORT_WIDTH(crtc-config-lane_count); } static struct intel_encoder * @@ -1913,7 +1913,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) } else temp |= TRANS_DDI_MODE_SELECT_DP_SST; - temp |= DDI_PORT_WIDTH(intel_dp-lane_count); + temp |= DDI_PORT_WIDTH(intel_crtc-config-lane_count); } else if (type == INTEL_OUTPUT_DP_MST) { struct intel_dp *intel_dp = enc_to_mst(encoder)-primary-dp; @@ -1922,7 +1922,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) } else temp |= TRANS_DDI_MODE_SELECT_DP_SST; - temp |= DDI_PORT_WIDTH(intel_dp-lane_count); + temp |= DDI_PORT_WIDTH(intel_crtc-config-lane_count); } else { WARN(1, Invalid encoder type %d for pipe %c\n, intel_encoder-type, pipe_name(pipe)); @@ -3072,6 +3072,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder, case TRANS_DDI_MODE_SELECT_DP_SST: case TRANS_DDI_MODE_SELECT_DP_MST: pipe_config-has_dp_encoder = true; + pipe_config-lane_count = + ((temp DDI_PORT_WIDTH_MASK) DDI_PORT_WIDTH_SHIFT) + 1; intel_dp_get_m_n(intel_crtc, pipe_config); break; default: diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 136b533..d56973f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11981,14 +11981,16 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config-fdi_m_n.gmch_m, pipe_config-fdi_m_n.gmch_n, pipe_config-fdi_m_n.link_m, pipe_config-fdi_m_n.link_n, pipe_config-fdi_m_n.tu); - DRM_DEBUG_KMS(dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n, + DRM_DEBUG_KMS(dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n, pipe_config-has_dp_encoder, + pipe_config-lane_count, pipe_config-dp_m_n.gmch_m, pipe_config-dp_m_n.gmch_n, pipe_config-dp_m_n.link_m, pipe_config-dp_m_n.link_n, pipe_config-dp_m_n.tu); - DRM_DEBUG_KMS(dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n, + DRM_DEBUG_KMS(dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n,
Re: [Intel-gfx] [PATCH v4 2/2] drm/i915: On fb alloc failure, unref gem object where it gets refed
On Mon, Jul 06, 2015 at 02:59:02PM +0200, Lukas Wunner wrote: Hi Daniel, On Mon, Jul 06, 2015 at 09:41:51AM +0200, Daniel Vetter wrote: Please keep a record of the changes you do to the patch so I know what to look out for. Just reving the patch revision alone doesn't add much information for reviewers/maintainers. There's a changelog in the first patch of this 2 patch series (subject [PATCH v4 1/2] drm/i915: Fix failure paths around initial fbdev allocation), it says: v4: * Lock struct mutex on unref. (Chris Wilson) Ah, I was looking for the v4 changelog for patch 2. Either make a small v4: rebased note or just don't call patch 2 v4 to avoid confusion in the future. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC] drm/i915: Add sync framework support to execbuff IOCTL
On Mon, Jul 06, 2015 at 01:58:25PM +0100, John Harrison wrote: On 06/07/2015 10:29, Daniel Vetter wrote: On Fri, Jul 03, 2015 at 12:17:33PM +0100, Tvrtko Ursulin wrote: On 07/02/2015 04:55 PM, Chris Wilson wrote: It would be nice if we could reuse one seqno both for internal/external fences. If you need to expose a fence ordering within a timeline that is based on the creation stamp rather than execution stamp, it seems like we could just add such a stamp when creating the sync_pt and not worry about its relationship to the execution seqno. Doing so does expose that requests are reordered to userspace since the signalling timeline is not the same as userspace's ordered timeline. Not sure if that is a problem or not. Afaict the sync uapi is based on waiting for all of a set of fences to retire. It doesn't seem to rely on fence ordering (that is knowing that fence A will signal before fence B so it need only wait on fence B). Here's hoping that we can have both simplicity and efficiency... Jumping in with not even perfect understanding of everything here - but timeline business has always been confusing me. There is nothing in the uapi which needs it afaics and iirc there was some discussion at the time Jesse floated his patches that it can be removed. Based on that when I squashed his patches and ported them on top of John's request to fence conversion it ended up something like the below (manually edited a bit to be less noisy and some prep patches omitted): This implements the ioctl based uapi and indeed seqnos are not actually used in waits. So is this insufficient for some reason? (Other that it does not implement the input fence side of things.) Yeah android syncpt on top of struct fence embedded int i915 request is what I'd have expected. The thing I'm not happy with in that plan is that it leaves the kernel driver at the mercy of user land applications. If we return a fence object to user land via a file descriptor (or indeed any other mechanism) then that fence object must be locked until user land closes the file. If the fence object is the one embedded within our request structure then that means user land is effectively locking our request structure. Given that more and more stuff is being attached to the request, that could be a fair bit of memory tied up that we can do nothing about. E.g. if a rogue/buggy application requests a fence be returned for every batch buffer submitted but never closes them. Whereas, if we go the route of a separate fence object specifically for user land then they can leak them like a sieve and we won't really care so much. Userspace can exhaust kernel allocations, that's nothing new. And if we keep it userspace simply needs to leak a few more fence fds than if there's a bit more data attached to it. The solution to this problem is to have a mem cgroup limit set. No need to complicate our kernel code. diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 74acca9..07f6ad9 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -71,3 +71,17 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT option changes the default for that module option. If in doubt, say N. + +config DRM_I915_SYNC + bool Enable explicit sync support + depends on DRM_I915 + default y if STAGING + depends on STAGING + select ANDROID + select SYNC + help No Kconfig for userspace ABI please. Yes this means we need to destage android syncpts first. There is already a CONFIG_SYNC flag that wraps up all the existing sync code in the staging branch. There's not a lot we can do about that is there? We have to at least wrap the sync specific code in the i915 driver with '#if CONFIG_SYNC' otherwise it won't compile. User-settable CONFIG_SYNC is one of these bits we need to fix up when de-staging - it should be an internal variable which is selected by i915, like all the other optional kernel services we use. The problem I see there is that apparently google is still changing the uabi a lot, and that's a no-go for upstream. And it needs to be cleaned up to work more seamlessly with struct fence (i.e. anything that's missing there should be moved to struct fence, drivers should only use fd_to_fence and fenct_to_fd functions similar to dma-buf). Are Google changing it or is it upstream that are changing it? The only changes to android/staging/sync.c have been a few minor bug fixes and Maarten Lankhorst's conversion to use struct fence which was back in July last year. destaging android syncpt will probably require a few changes, but more so it will freeze the abi. If we do that effort and google ignores it it's fairly pointless (as long as android is the only serious user of syncpts). And we don't have anyone except android using syncpts, so a bit a trouble with finding userspace vehicles for this. We probably need agreement from google to be happy with a
Re: [Intel-gfx] [PATCH 03/15] drm/i915: Add GuC-related module parameters
On Fri, Jul 03, 2015 at 01:30:25PM +0100, Dave Gordon wrote: From: Alex Dai yu@intel.com Two new module parameters: enable_guc_submission which will turn on submission of batchbuffers via the GuC (when implemented), and guc_log_level which controls the level of debugging logged by the GuC and captured by the host. Signed-off-by: Alex Dai yu@intel.com Signed-off-by: Dave Gordon david.s.gor...@intel.com --- drivers/gpu/drm/i915/i915_drv.h| 2 ++ drivers/gpu/drm/i915/i915_params.c | 9 + 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b0bb07d..9618f57 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2599,6 +2599,8 @@ struct i915_params { bool reset; bool disable_display; bool disable_vtd_wa; + bool enable_guc_submission; + int guc_log_level; int use_mmio_flip; int mmio_debug; bool verbose_state_checks; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 7983fe4..a8f48dd 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -53,6 +53,8 @@ struct i915_params i915 __read_mostly = { .verbose_state_checks = 1, .nuclear_pageflip = 0, .edp_vswing = 0, + .enable_guc_submission = false, + .guc_log_level = -1, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -186,3 +188,10 @@ MODULE_PARM_DESC(edp_vswing, Ignore/Override vswing pre-emph table selection from VBT (0=use value from vbt [default], 1=low power swing(200mV), 2=default swing(400mV))); + +module_param_named(enable_guc_submission, i915.enable_guc_submission, bool, 0400); Please mark this as _unsave, this isn't anything end-users should fiddle with. +MODULE_PARM_DESC(enable_guc_submission, Enable GuC submission (default:false)); + +module_param_named(guc_log_level, i915.guc_log_level, int, 0400); I think this one is ok without _unsave, we want users to be able to collect logfiles without panicking because it taints their kernel ;-) -Daniel +MODULE_PARM_DESC(guc_log_level, + GuC firmware logging level (-1:disabled (default), 0-3:enabled)); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation 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 10/15] drm/i915: Implementation of GuC client
On Fri, Jul 03, 2015 at 01:30:32PM +0100, Dave Gordon wrote: A GuC client has its own doorbell and workqueue. It maintains the doorbell cache line, process description object and work queue item. A default guc_client is created for the i915 driver to use for normal-priority in-order submission. Note that the created client is not yet ready for use; doorbell allocation will fail as we haven't yet linked the GuC's context descriptor to the default contexts for each ring (see later patch). However the driver will still be usable, automatically falling back to execlist mode. v2: Defer adding structure members until needed [Chris Wilson] Rationalise type declarations [Chris Wilson] Issue: VIZ-4884 Signed-off-by: Alex Dai yu@intel.com Signed-off-by: Dave Gordon david.s.gor...@intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 661 + drivers/gpu/drm/i915/intel_guc.h | 43 ++ drivers/gpu/drm/i915/intel_guc_loader.c| 10 + 3 files changed, 714 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index e9d46d6..3c28c8b 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -27,6 +27,524 @@ #include intel_guc.h /** + * DOC: GuC Client You need to pull all your shiny new kerneldoc into the drm.tmpl, otherwise it won't show up. You can build the drm/i915 docbook with $ make htmldocs Looking at what we have right now for gem a section next to the execlist one would fit best I think. Thanks, Daniel + * + * i915_guc_client: + * We use the term client to avoid confusion with contexts. A i915_guc_client is + * equivalent to GuC object guc_context_desc. This context descriptor is + * allocated from a pool of 1024 entries. Kernel driver will allocate doorbell + * and workqueue for it. Also the process descriptor (guc_process_desc), which + * is mapped to client space. So the client can write Work Item then ring the + * doorbell. + * + * To simplify the implementation, we allocate one gem object that contains all + * pages for doorbell, process descriptor and workqueue. + * + * The Scratch registers: + * There are 16 MMIO-based registers start from 0xC180. The kernel driver writes + * a value to the action register (SOFT_SCRATCH_0) along with any data. It then + * triggers an interrupt on the GuC via another register write (0xC4C8). + * Firmware writes a success/fail code back to the action register after + * processes the request. The kernel driver polls waiting for this update and + * then proceeds. + * See host2guc_action() + * + * Doorbells: + * Doorbells are interrupts to uKernel. A doorbell is a single cache line (QW) + * mapped into process space. + * + * Work Items: + * There are several types of work items that the host may place into a + * workqueue, each with its own requirements and limitations. Currently only + * WQ_TYPE_INORDER is needed to support legacy submission via GuC, which + * represents in-order queue. The kernel driver packs ring tail pointer and an + * ELSP context descriptor dword into Work Item. + * See guc_add_workqueue_item() + * + */ + +/* + * Read GuC command/status register (SOFT_SCRATCH_0) + * Return true if it contains a response rather than a command + */ +static inline bool host2guc_action_response(struct drm_i915_private *dev_priv, + u32 *status) +{ + u32 val = I915_READ(SOFT_SCRATCH(0)); + *status = val; + return GUC2HOST_IS_RESPONSE(val); +} + +static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + u32 status; + int i; + int ret; + + if (WARN_ON(len 1 || len 15)) + return -EINVAL; + + spin_lock(dev_priv-guc.host2guc_lock); + + dev_priv-guc.action_count += 1; + dev_priv-guc.action_cmd = data[0]; + + for (i = 0; i len; i++) + I915_WRITE(SOFT_SCRATCH(i), data[i]); + + POSTING_READ(SOFT_SCRATCH(i - 1)); + + I915_WRITE(HOST2GUC_INTERRUPT, HOST2GUC_TRIGGER); + + ret = wait_for_atomic(host2guc_action_response(dev_priv, status), 10); + if (status != GUC2HOST_STATUS_SUCCESS) { + /* either GuC doesn't respond, which is a TIMEOUT, + * or a failure code is returned. */ + if (ret != -ETIMEDOUT) + ret = -EIO; + + DRM_ERROR(GUC: host2guc action 0x%X failed. ret=%d + status=0x%08X response=0x%08X\n, + data[0], ret, status, + I915_READ(SOFT_SCRATCH(15))); + + dev_priv-guc.action_fail += 1; + dev_priv-guc.action_err = ret; + } + dev_priv-guc.action_status = status; + +
Re: [Intel-gfx] [PATCH] drm/i915: RMW register cycles considered evil
On 06/07/15 13:50, Ville Syrjälä wrote: On Mon, Jul 06, 2015 at 02:42:02PM +0200, Daniel Vetter wrote: Especially for workarounds which is stuff that's almost impossible to verify: The initial state from the firmware on boot-up and after resume could be different, which will hide bugs when we do an RMW cycle. If you're really worried about that then we should then explicitly initialize all the registers that might affect stuff. For a bunch of GT registers we could just do a GPU reset at driver init. That that won't help with UCGCTL and such. I'm also worried that if we don't use RMWs for early parts, the hardware folks may still change the default for some ofhte other bits, and then we end up clobbering those. In other drivers, I've found a good pattern to be: 1. during driver load, snapshot (just once) anything that the BIOS may have programmed that we may need later 2. then reset the h/w and reprogram it totally to our preferred values, which may to a greater or lesser degree be derived from the saved BIOS settings 3. during unload, reset the h/w again and reprogram it with the BIOS settings 2a. resume is just like load, except we don't need or want to capture the BIOS settings first 3a. suspend is like unload, except in some cases the BIOS values might need to be tweaked when writing them back in order to ensure the device doesn't generate further activity. Step 1 ensures that we don't lose useful settings where the BIOS knows better than the driver what the good values are. Step 2/2a. ensures that the device starts out in a well-defined state, regardless of how comprehensively (or badly) the BIOS has set it up. It seems a reasonable compromise between taking advantage of good BIOSes while not getting too much hassle from broken ones. .Dave. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/15] drm/i915: Embedded microcontroller (uC) firmware loading support
On Fri, Jul 03, 2015 at 01:30:24PM +0100, Dave Gordon wrote: Current devices may contain one or more programmable microcontrollers that need to have a firmware image (aka binary blob) loaded from an external medium and transferred to the device's memory. This file provides common support functions for doing this; they can then be used by each uC-specific loader, thus reducing code duplication and testing effort. v2: Local functions should pass dev_priv rather than dev [Chris Wilson] Various other improvements per Chris Wilson's review comments v3: Defeatured version without async prefetch [Daniel Vetter] Signed-off-by: Dave Gordon david.s.gor...@intel.com Signed-off-by: Alex Dai yu@intel.com --- drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/intel_uc_loader.c | 310 + drivers/gpu/drm/i915/intel_uc_loader.h | 92 ++ 3 files changed, 405 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_uc_loader.c create mode 100644 drivers/gpu/drm/i915/intel_uc_loader.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index de21965..f1f80fc 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -39,6 +39,9 @@ i915-y += i915_cmd_parser.o \ intel_ringbuffer.o \ intel_uncore.o +# generic ancilliary microcontroller support +i915-y += intel_uc_loader.o + # autogenerated null render state i915-y += intel_renderstate_gen6.o \ intel_renderstate_gen7.o \ diff --git a/drivers/gpu/drm/i915/intel_uc_loader.c b/drivers/gpu/drm/i915/intel_uc_loader.c new file mode 100644 index 000..a8fc1dd --- /dev/null +++ b/drivers/gpu/drm/i915/intel_uc_loader.c @@ -0,0 +1,310 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Author: + * Dave Gordon david.s.gor...@intel.com + */ +#include linux/firmware.h +#include i915_drv.h +#include intel_uc_loader.h + +/** + * DOC: Common functions for embedded microcontroller (uC) firmware loading + * + * The functions in this file provide common support code for loading the + * firmware that may be required by an embedded microcontroller (uC). + * + * The function intel_uc_fw_init() should be called first; it requires no + * locking, and can be called even before GEM has been initialised. It just + * initialises the tracking data and stores its parameters for the subsequent + * call to intel_uc_fw_fetch(). + * + * At some convenient point after GEM initialisation, the driver should call + * intel_uc_fw_fetch(). The first time, this will use the Linux kernel's + * request_firmware() call to open and read the firmware image into memory. + * (On subsequent calls, this is skipped, as either the firmware has already + * been fetched into memory, or it is already known that no valid firmware + * image could be found). + * + * The callback() function passed to intel_uc_fw_fetch() can further check + * the firmware image before it is saved. This function can reject the image + * by returning a negative error code (e.g. -ENOEXEC), or accept it. In the + * latter case, it can return INTEL_UC_FW_GOOD (which is also the default if + * no callback() is supplied), and the common code here will save the whole + * of the firmware image in a (pageable, shmfs-backed) GEM object. + * + * If saving the whole image unmodified is not appropriate (for example, if + * only a small part of the image is needed later, or the data needs to be + * reorganised before saving), the callback() function can instead make its + * own arrangements for saving the required data in a GEM object or otherwise + * and then return INTEL_UC_FW_SAVED. + * + * (If such a callback does stash (some of) the image data in a GEM object, + * it can use the
Re: [Intel-gfx] [PATCH 11/15] drm/i915: Interrupt routing for GuC submission
On Fri, Jul 03, 2015 at 01:30:33PM +0100, Dave Gordon wrote: Turn on interrupt steering to route necessary interrupts to GuC. Issue: VIZ-4884 Signed-off-by: Alex Dai yu@intel.com Signed-off-by: Dave Gordon david.s.gor...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 11 +-- drivers/gpu/drm/i915/intel_guc_loader.c | 51 + 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index eefb847..9f32c6c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1659,12 +1659,18 @@ enum skl_disp_power_wells { #define GFX_MODE_GEN70x0229c #define RING_MODE_GEN7(ring) ((ring)-mmio_base+0x29c) #define GFX_RUN_LIST_ENABLE(115) +#define GFX_INTERRUPT_STEERING (114) #define GFX_TLB_INVALIDATE_EXPLICIT(113) #define GFX_SURFACE_FAULT_ENABLE (112) #define GFX_REPLAY_MODE(111) #define GFX_PSMI_GRANULARITY (110) #define GFX_PPGTT_ENABLE (19) +#define GFX_FORWARD_VBLANK_MASK(35) +#define GFX_FORWARD_VBLANK_NEVER (05) +#define GFX_FORWARD_VBLANK_ALWAYS (15) +#define GFX_FORWARD_VBLANK_COND(25) + #define VLV_DISPLAY_BASE 0x18 #define VLV_MIPI_BASE VLV_DISPLAY_BASE @@ -5677,11 +5683,12 @@ enum skl_disp_power_wells { #define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) #define GEN8_GT_IER(which) (0x4430c + (0x10 * (which))) -#define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_RCS_IRQ_SHIFT 0 -#define GEN8_VCS2_IRQ_SHIFT 16 +#define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_VCS1_IRQ_SHIFT 0 +#define GEN8_VCS2_IRQ_SHIFT 16 #define GEN8_VECS_IRQ_SHIFT 0 +#define GEN8_WD_IRQ_SHIFT 16 #define GEN8_DE_PIPE_ISR(pipe) (0x44400 + (0x10 * (pipe))) #define GEN8_DE_PIPE_IMR(pipe) (0x44404 + (0x10 * (pipe))) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index eb76c34..ef5f3d5 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -62,6 +62,53 @@ #define I915_SKL_GUC_UCODE i915/skl_guc_ver3.bin MODULE_FIRMWARE(I915_SKL_GUC_UCODE); +static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *ring; + int i, irqs; + + /* tell all command streamers NOT to forward interrupts and vblank to GuC */ + irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); + irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); + for_each_ring(ring, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(ring), irqs); + + /* tell DE to send nothing to GuC */ + I915_WRITE(DE_GUCRMR, ~0); + + /* route all GT interrupts to the host */ + I915_WRITE(GUC_BCS_RCS_IER, 0); + I915_WRITE(GUC_VCS2_VCS1_IER, 0); + I915_WRITE(GUC_WD_VECS_IER, 0); +} + +static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *ring; + int i, irqs; + + /* tell all command streamers to forward interrupts and vblank to GuC */ + irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); + irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); + for_each_ring(ring, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(ring), irqs); + + /* tell DE to send (all) flip_done to GuC */ + irqs = DERRMR_PIPEA_PRI_FLIP_DONE | DERRMR_PIPEA_SPR_FLIP_DONE | +DERRMR_PIPEB_PRI_FLIP_DONE | DERRMR_PIPEB_SPR_FLIP_DONE | +DERRMR_PIPEC_PRI_FLIP_DONE | DERRMR_PIPEC_SPR_FLIP_DONE; + /* Unmasked bits will cause GuC response message to be sent */ + I915_WRITE(DE_GUCRMR, ~irqs); + + /* route USER_INTERRUPT to Host, all others are sent to GuC. */ + irqs = GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | +GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT; + /* These three registers have the same bit definitions */ + I915_WRITE(GUC_BCS_RCS_IER, ~irqs); + I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs); + I915_WRITE(GUC_WD_VECS_IER, ~irqs); +} + static u32 get_gttype(struct drm_i915_private *dev_priv) { /* XXX: GT type based on PCI device ID? field seems unused by fw */ @@ -417,6 +464,7 @@ int intel_guc_ucode_load(struct drm_device *dev) intel_uc_fw_status_repr(guc_fw-uc_fw_fetch_status), intel_uc_fw_status_repr(guc_fw-uc_fw_load_status)); + direct_interrupts_to_host(dev_priv); i915_guc_submission_disable(dev); if (guc_fw-uc_fw_fetch_status == INTEL_UC_FIRMWARE_NONE) @@ -450,6 +498,7 @@ int intel_guc_ucode_load(struct drm_device *dev) err = i915_guc_submission_enable(dev); if (err) goto fail; + direct_interrupts_to_guc(dev_priv); This looks like still some remnants from when guc
Re: [Intel-gfx] [PATCH i-g-t 00/16] Introduction of plotting support
On Mon, Jul 06, 2015 at 08:58:31PM +0100, Damien Lespiau wrote: On Mon, Jul 06, 2015 at 08:25:56PM +0200, Daniel Vetter wrote: atm QA rolls their own thing, developers on mesa side have ministat, and it looks like you want to create something in igt. I know it's easier, but I'd like to share as much tooling between QA and devs as possible. And that kinda means we should have the same tooling across different gfx components because otherwise QA gets pissed. Unfortunately we're not even there yet with just running testcases, so microbenchmarks are really far off. Just a word of warning really that we could end up running into a valley here that we'll regret 2 years down the road (when QA is solid and we have a problem with piles of different benchmarking suites). But really this is is just grumpy maintainer fearing another long-term headache, I don't want to stop your enthusiasm (too much at least). I'd be wary of tooling outside of igt or piglit. I asked on #intel-gfx and there's nothing like a base set of tools for mirco-benchmarking. Actually there are fairly few micro benchmarks at all (it's debatable that micro-benchmarks make people focus on details that aren't relevant in the big picture, the hope here is that they can help mesa to make performance trade offs). - Just to be clear, I don't care about anything closed source :) - ministat.c is definitely useful but also limited to what it can do. It's also external to benchmarks, needs wrapper scripts to be fully operational (and several all those exists). - Do you know if QA doing anything on benchmarking low level stuff today? if so I'd love to talk to them. No external things please (like the test blacklist being external to i-g-t). They have a few metrics they chase in manual tests, like suspend/resume time or driver load. If we'd have some tiny little benchmarking for small tests we could move that into igt too. - If your objection is being able to have benchmark results unified between piglit and i-g-t, we can always generate a similar format for the key metric we want to monitor. More detailed analysis will require more than just that though. I also don't think anything like this exists in piglit today. Yeah nothing there yet. - It's not just about stats and plots. It's also about: * collecting metrics (CPU and GPU side), which mean integration with perf. * collecting other interesting data like memory bandwith available to the CPU and GPU and compare them against theoritical maxima. * Generating useful reports Yeah if you use this for intel-gpu-tools then I think it's all justified and lets move on. But it sounded like you wanted to use this for tests, and there I see a bit of duplication going on ... So I'm not finished :) You forgot the Finland perf team in your tour of people looking around that area. I think I need to talk to them. I did think of them, they have their own tooling. Why don't we have some of those benchmarks they have in i-g-t? (using OpenGL? they are not open source?) I have the feeling we should at least have a single point of contribution, let's make sure it's i-g-t when it's about low level tests? Do we want to start accepting tests written in OpenGL in i-g-t? Atm I think it's just the various *marks and other stuff they have and run. But the idea would be that if we have wrappers it'd be easier to run them all for developers. Anyway really just wanted to start a bit a discussion here. It's imo a gap we have in the open source gfx testing world, and thus far random pile of scripts somewhere seems to be the best we managed. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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: RMW register cycles considered evil
On Mon, Jul 06, 2015 at 01:46:19PM +0100, Damien Lespiau wrote: On Mon, Jul 06, 2015 at 02:42:02PM +0200, Daniel Vetter wrote: Especially for workarounds which is stuff that's almost impossible to verify: The initial state from the firmware on boot-up and after resume could be different, which will hide bugs when we do an RMW cycle. Hence never do them, and if it's required we need a special mask. Cc: Damien Lespiau damien.lesp...@intel.com Cc: Imre Deak imre.d...@intel.com Cc: Nick Hoath nicholas.ho...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@intel.com Eeek. Let's take the problem the other way around: have you verified it's OK to zero all those other fields? Nope, but it's what we do for other workarounds (e.g. the ones we load through the rings except for one case in the cxt switch wa) and on other platforms. And in general we've moved away from RMW wherever we can since it had too much surprises. It's really just something I spotted while stumbling over a w/a patch for hsw that we never merged - I don't like the inconsistency. And it has bitten us in the past. And yes I haven't done the audit here, but the fact that you suggest we need one kind proves my point ;-) -Daniel -- Damien --- drivers/gpu/drm/i915/intel_pm.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 166ae51f5a5b..565f78d6a21d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -57,7 +57,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; /* WaEnableLbsSlaRetryTimerDecrement:skl */ - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | + I915_WRITE(BDW_SCRATCH1, GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); } @@ -72,18 +72,18 @@ static void skl_init_clock_gating(struct drm_device *dev) * WaDisableSDEUnitClockGating:skl * WaSetGAPSunitClckGateDisable:skl */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableVFUnitClockGating:skl */ - I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | + I915_WRITE(GEN6_UCGCTL2, GEN6_VFUNIT_CLOCK_GATE_DISABLE); } if (INTEL_REVID(dev) = SKL_REVID_D0) { /* WaDisableHDCInvalidation:skl */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + I915_WRITE(GAM_ECOCHK, BDW_DISABLE_HDC_INVALIDATION); /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ @@ -93,7 +93,7 @@ static void skl_init_clock_gating(struct drm_device *dev) if (INTEL_REVID(dev) = SKL_REVID_E0) /* WaDisableLSQCROPERFforOCL:skl */ - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | + I915_WRITE(GEN8_L3SQCREG4, GEN8_LQSC_RO_PERF_DIS); } @@ -109,12 +109,12 @@ static void bxt_init_clock_gating(struct drm_device *dev) * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ /* WaDisableSDEUnitClockGating:bxt */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + I915_WRITE(GEN8_UCGCTL6, GEN8_SDEUNIT_CLOCK_GATE_DISABLE | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* FIXME: apply on A0 only */ - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); + I915_WRITE(TILECTL, TILECTL_TLBPF); } static void i915_pineview_get_mem_freq(struct drm_device *dev) -- 2.1.4 -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC] drm/i915: Add sync framework support to execbuff IOCTL
On 07/06/2015 04:12 PM, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 03:46:49PM +0100, Tvrtko Ursulin wrote: On 07/06/2015 03:26 PM, John Harrison wrote: On 06/07/2015 14:59, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 01:58:25PM +0100, John Harrison wrote: On 06/07/2015 10:29, Daniel Vetter wrote: On Fri, Jul 03, 2015 at 12:17:33PM +0100, Tvrtko Ursulin wrote: On 07/02/2015 04:55 PM, Chris Wilson wrote: It would be nice if we could reuse one seqno both for internal/external fences. If you need to expose a fence ordering within a timeline that is based on the creation stamp rather than execution stamp, it seems like we could just add such a stamp when creating the sync_pt and not worry about its relationship to the execution seqno. Doing so does expose that requests are reordered to userspace since the signalling timeline is not the same as userspace's ordered timeline. Not sure if that is a problem or not. Afaict the sync uapi is based on waiting for all of a set of fences to retire. It doesn't seem to rely on fence ordering (that is knowing that fence A will signal before fence B so it need only wait on fence B). Here's hoping that we can have both simplicity and efficiency... Jumping in with not even perfect understanding of everything here - but timeline business has always been confusing me. There is nothing in the uapi which needs it afaics and iirc there was some discussion at the time Jesse floated his patches that it can be removed. Based on that when I squashed his patches and ported them on top of John's request to fence conversion it ended up something like the below (manually edited a bit to be less noisy and some prep patches omitted): This implements the ioctl based uapi and indeed seqnos are not actually used in waits. So is this insufficient for some reason? (Other that it does not implement the input fence side of things.) Yeah android syncpt on top of struct fence embedded int i915 request is what I'd have expected. The thing I'm not happy with in that plan is that it leaves the kernel driver at the mercy of user land applications. If we return a fence object to user land via a file descriptor (or indeed any other mechanism) then that fence object must be locked until user land closes the file. If the fence object is the one embedded within our request structure then that means user land is effectively locking our request structure. Given that more and more stuff is being attached to the request, that could be a fair bit of memory tied up that we can do nothing about. E.g. if a rogue/buggy application requests a fence be returned for every batch buffer submitted but never closes them. Whereas, if we go the route of a separate fence object specifically for user land then they can leak them like a sieve and we won't really care so much. Userspace can exhaust kernel allocations, that's nothing new. And if we keep it userspace simply needs to leak a few more fence fds than if there's a bit more data attached to it. The solution to this problem is to have a mem cgroup limit set. No need to complicate our kernel code. There is still the extra complication that request unreferencing cannot require any kind of mutex lock if we are allowing it to happen from outside of the driver. That means the unreference callback must move the request to a 'please clean me later' list, schedule a worker thread to run, and thus do the clean up asynchronously. For this particular issue my solution was to extend the sync_fence constructor to take a mutex and store it inside the object. Then at destruction time, which happens at sync_fd-f_ops-release() time, it is just a matter of calling kref_put_mutex instead of kref_put. Seemed to work under some quick testing but that is as much as I did back then. The problem is that it doesn't scale since everyone wants some other kind of mutex to serialize the final kref_put. If something is supposed to be cross-subsystem/driver (which is the case for fences) then we really can't do that kind of leaky locking design. Imo we should have a kref_put_mutex considered harmful sign somewhere ... I get the argument about everything wanting to add their own not scaling, but don't tie with the leaky comment? Also mutex is a pretty standard thing, especially since kref_put_mutex. :D If you look at it from that angle it kind of just exposes to the super class what the base class can do. If you have weak references somewhere and need to prevent the object from disappearing untimely while chasing that weak reference then imo the better design pattern is to use kref_get_unless_zero. If you need the serialization the mutex provides for some other reason (someone is only hodling the mutex instead of grabbing a proper refernce when they really should grab one) then your refcounting scheme probably needs another kind of fixup patch. I don't see how weak references can work since if the request goes information is lost, unless stored somewhere else.
Re: [Intel-gfx] [PATCH] drm/i915: avoid leaking DMA mappings
On Mon, Jul 06, 2015 at 03:57:44PM +0100, Chris Wilson wrote: On Mon, Jul 06, 2015 at 05:50:37PM +0300, Imre Deak wrote: We have 3 types of DMA mappings for GEM objects: 1. physically contiguous for stolen and for objects needing contiguous memory 2. DMA-buf mappings imported via a DMA-buf attach operation 3. SG DMA mappings for shmem backed and userptr objects For 1. and 2. the lifetime of the DMA mapping matches the lifetime of the corresponding backing pages and so in practice we create/release the mapping in the object's get_pages/put_pages callback. For 3. the lifetime of the mapping matches that of any existing GPU binding of the object, so we'll create the mapping when the object is bound to the first vma and release the mapping when the object is unbound from its last vma. Since the object can be bound to multiple vmas, we can end up creating a new DMA mapping in the 3. case even if the object already had one. This is not allowed by the DMA API and can lead to leaked mapping data and IOMMU memory space starvation in certain cases. For example HW IOMMU drivers (intel_iommu) allocate a new range from their memory space whenever a mapping is created, silently overriding a pre-existing mapping. How does this happen? Essentially list_empty(obj-vmas) == !dma_mapping_exists should hold for objects of the 3rd type. I don't understand how this is broken in the current code. There was definitely versions of the ppgtt code where this wasn't working properly, but I thought we've fixed that up again. Fix this by adding new callbacks to create/release the DMA mapping. This way we can use the has_dma_mapping flag for objects of the 3. case also (so far the flag was only used for the 1. and 2. case) and skip creating a new mapping if one exists already. Note that I also thought about simply creating/releasing the mapping when get_pages/put_pages is called. However since creating a DMA mapping may have associated resources (at least in case of HW IOMMU) it does make sense to release these resources as early as possible. We can release the DMA mapping as soon as the object is unbound from the last vma, before we drop the backing pages, hence it's worth keeping the two operations separate. I noticed this issue by enabling DMA debugging, which got disabled after a while due to its internal mapping tables getting full. It also reported errors in connection to random other drivers that did a DMA mapping for an address that was previously mapped by i915 but was never released. Besides these diagnostic messages and the memory space starvation problem for IOMMUs, I'm not aware of this causing a real issue. Nope, it is much much simpler. Since we only do the dma prepare/finish from inside get_pages/put_pages, we can put the calls there. The only caveat there is userptr worker, but that can be easily fixed up. I do kinda like the distinction between just grabbing the backing storage and making it accessible to the hw. Small one, but I think it does help if we keep these two maps separate. Now the function names otoh are super-confusing, that I agree with. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation 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 11/15] drm/i915: Interrupt routing for GuC submission
On 06/07/15 15:14, Daniel Vetter wrote: On Fri, Jul 03, 2015 at 01:30:33PM +0100, Dave Gordon wrote: Turn on interrupt steering to route necessary interrupts to GuC. Issue: VIZ-4884 Signed-off-by: Alex Dai yu@intel.com Signed-off-by: Dave Gordon david.s.gor...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 11 +-- drivers/gpu/drm/i915/intel_guc_loader.c | 51 + 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index eefb847..9f32c6c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1659,12 +1659,18 @@ enum skl_disp_power_wells { #define GFX_MODE_GEN7 0x0229c #define RING_MODE_GEN7(ring) ((ring)-mmio_base+0x29c) #define GFX_RUN_LIST_ENABLE (115) +#define GFX_INTERRUPT_STEERING (114) #define GFX_TLB_INVALIDATE_EXPLICIT (113) #define GFX_SURFACE_FAULT_ENABLE(112) #define GFX_REPLAY_MODE (111) #define GFX_PSMI_GRANULARITY(110) #define GFX_PPGTT_ENABLE(19) +#define GFX_FORWARD_VBLANK_MASK (35) +#define GFX_FORWARD_VBLANK_NEVER (05) +#define GFX_FORWARD_VBLANK_ALWAYS(15) +#define GFX_FORWARD_VBLANK_COND (25) + #define VLV_DISPLAY_BASE 0x18 #define VLV_MIPI_BASE VLV_DISPLAY_BASE @@ -5677,11 +5683,12 @@ enum skl_disp_power_wells { #define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) #define GEN8_GT_IER(which) (0x4430c + (0x10 * (which))) -#define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_RCS_IRQ_SHIFT 0 -#define GEN8_VCS2_IRQ_SHIFT 16 +#define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_VCS1_IRQ_SHIFT 0 +#define GEN8_VCS2_IRQ_SHIFT 16 #define GEN8_VECS_IRQ_SHIFT 0 +#define GEN8_WD_IRQ_SHIFT 16 #define GEN8_DE_PIPE_ISR(pipe) (0x44400 + (0x10 * (pipe))) #define GEN8_DE_PIPE_IMR(pipe) (0x44404 + (0x10 * (pipe))) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index eb76c34..ef5f3d5 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -62,6 +62,53 @@ #define I915_SKL_GUC_UCODE i915/skl_guc_ver3.bin MODULE_FIRMWARE(I915_SKL_GUC_UCODE); +static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *ring; + int i, irqs; + + /* tell all command streamers NOT to forward interrupts and vblank to GuC */ + irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); + irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); + for_each_ring(ring, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(ring), irqs); + + /* tell DE to send nothing to GuC */ + I915_WRITE(DE_GUCRMR, ~0); + + /* route all GT interrupts to the host */ + I915_WRITE(GUC_BCS_RCS_IER, 0); + I915_WRITE(GUC_VCS2_VCS1_IER, 0); + I915_WRITE(GUC_WD_VECS_IER, 0); +} + +static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *ring; + int i, irqs; + + /* tell all command streamers to forward interrupts and vblank to GuC */ + irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); + irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); + for_each_ring(ring, dev_priv, i) + I915_WRITE(RING_MODE_GEN7(ring), irqs); + + /* tell DE to send (all) flip_done to GuC */ + irqs = DERRMR_PIPEA_PRI_FLIP_DONE | DERRMR_PIPEA_SPR_FLIP_DONE | + DERRMR_PIPEB_PRI_FLIP_DONE | DERRMR_PIPEB_SPR_FLIP_DONE | + DERRMR_PIPEC_PRI_FLIP_DONE | DERRMR_PIPEC_SPR_FLIP_DONE; + /* Unmasked bits will cause GuC response message to be sent */ + I915_WRITE(DE_GUCRMR, ~irqs); + + /* route USER_INTERRUPT to Host, all others are sent to GuC. */ + irqs = GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT; + /* These three registers have the same bit definitions */ + I915_WRITE(GUC_BCS_RCS_IER, ~irqs); + I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs); + I915_WRITE(GUC_WD_VECS_IER, ~irqs); +} + static u32 get_gttype(struct drm_i915_private *dev_priv) { /* XXX: GT type based on PCI device ID? field seems unused by fw */ @@ -417,6 +464,7 @@ int intel_guc_ucode_load(struct drm_device *dev) intel_uc_fw_status_repr(guc_fw-uc_fw_fetch_status), intel_uc_fw_status_repr(guc_fw-uc_fw_load_status)); + direct_interrupts_to_host(dev_priv); i915_guc_submission_disable(dev); if (guc_fw-uc_fw_fetch_status == INTEL_UC_FIRMWARE_NONE) @@ -450,6 +498,7 @@ int intel_guc_ucode_load(struct drm_device *dev) err = i915_guc_submission_enable(dev); if (err) goto fail; + direct_interrupts_to_guc(dev_priv); This looks like still some remnants
Re: [Intel-gfx] [PATCH] drm/i915: avoid leaking DMA mappings
On ma, 2015-07-06 at 17:04 +0100, Chris Wilson wrote: On Mon, Jul 06, 2015 at 06:56:00PM +0300, Imre Deak wrote: On ma, 2015-07-06 at 16:33 +0100, Chris Wilson wrote: On Mon, Jul 06, 2015 at 05:29:39PM +0200, Daniel Vetter wrote: On Mon, Jul 06, 2015 at 03:57:44PM +0100, Chris Wilson wrote: On Mon, Jul 06, 2015 at 05:50:37PM +0300, Imre Deak wrote: We have 3 types of DMA mappings for GEM objects: 1. physically contiguous for stolen and for objects needing contiguous memory 2. DMA-buf mappings imported via a DMA-buf attach operation 3. SG DMA mappings for shmem backed and userptr objects For 1. and 2. the lifetime of the DMA mapping matches the lifetime of the corresponding backing pages and so in practice we create/release the mapping in the object's get_pages/put_pages callback. For 3. the lifetime of the mapping matches that of any existing GPU binding of the object, so we'll create the mapping when the object is bound to the first vma and release the mapping when the object is unbound from its last vma. Since the object can be bound to multiple vmas, we can end up creating a new DMA mapping in the 3. case even if the object already had one. This is not allowed by the DMA API and can lead to leaked mapping data and IOMMU memory space starvation in certain cases. For example HW IOMMU drivers (intel_iommu) allocate a new range from their memory space whenever a mapping is created, silently overriding a pre-existing mapping. How does this happen? Essentially list_empty(obj-vmas) == !dma_mapping_exists should hold for objects of the 3rd type. I don't understand how this is broken in the current code. There was definitely versions of the ppgtt code where this wasn't working properly, but I thought we've fixed that up again. Every g/ppgtt binding remapped the obj-pages through the iommu. Even with the DMAR disabled, we still pay the cpu cost of sw iommu (which is itself an annoying kernel bug that you can't disable). Fix this by adding new callbacks to create/release the DMA mapping. This way we can use the has_dma_mapping flag for objects of the 3. case also (so far the flag was only used for the 1. and 2. case) and skip creating a new mapping if one exists already. Note that I also thought about simply creating/releasing the mapping when get_pages/put_pages is called. However since creating a DMA mapping may have associated resources (at least in case of HW IOMMU) it does make sense to release these resources as early as possible. We can release the DMA mapping as soon as the object is unbound from the last vma, before we drop the backing pages, hence it's worth keeping the two operations separate. I noticed this issue by enabling DMA debugging, which got disabled after a while due to its internal mapping tables getting full. It also reported errors in connection to random other drivers that did a DMA mapping for an address that was previously mapped by i915 but was never released. Besides these diagnostic messages and the memory space starvation problem for IOMMUs, I'm not aware of this causing a real issue. Nope, it is much much simpler. Since we only do the dma prepare/finish from inside get_pages/put_pages, we can put the calls there. The only caveat there is userptr worker, but that can be easily fixed up. I do kinda like the distinction between just grabbing the backing storage and making it accessible to the hw. Small one, but I think it does help if we keep these two maps separate. Now the function names otoh are super-confusing, that I agree with. But that is the raison-d'etre of get_pages(). We call it preciselly when we want the backing storage available to the hw. We relaxed that for set-domain to avoid one type of bug, and stolen/dma-buf have their own notion of dma mapping. userptr is the odd one out due to its worker asynchronously grabbing the pages. Isn't the DMA mapping operation more tied to binding the object to a VMA? As far as I can see we call put_pages only when destroying the object (or attaching a physically contiguous mapping to it) and that's because at that point we also give up on the content of the buffer. Otherwise we just do unbinding when reclaiming memory. At this point it make sense to release the DMA mapping independently of releasing the buffer contents. No. As proved above, it is not about each VMA, it about preparing the object for access by the hw - i.e. a natural fit for the get_pages/put_pages() greedy scheme, and if you look at the workloads
Re: [Intel-gfx] [PATCH 05/15] drm/i915: GuC-specific firmware loader
On 06/07/15 15:28, Daniel Vetter wrote: On Fri, Jul 03, 2015 at 01:30:27PM +0100, Dave Gordon wrote: From: Alex Dai yu@intel.com This uses the common firmware loader to fetch the firmware image, then loads it into the GuC's memory via a dedicated DMA engine. This patch is derived from GuC loading work originally done by Vinit Azad and Ben Widawsky. It has been reconstructed to accord with the common firmware loading mechanism by Dave Gordon as well as new firmware layout etc. v2: Various improvements per review comments by Chris Wilson v3: Removed 'wait' parameter to intel_guc_ucode_load() as prefetch is no longer supported in the common firmware loader, per Daniel Vetter's request. F/w checker callback fn now returns errno rather than bool. Issue: VIZ-4884 Signed-off-by: Alex Dai yu@intel.com Signed-off-by: Dave Gordon david.s.gor...@intel.com --- drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/i915_dma.c | 4 + drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/i915_gem.c | 8 + drivers/gpu/drm/i915/i915_reg.h | 4 +- drivers/gpu/drm/i915/intel_guc.h| 49 drivers/gpu/drm/i915/intel_guc_loader.c | 448 7 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/intel_guc.h create mode 100644 drivers/gpu/drm/i915/intel_guc_loader.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f1f80fc..62a8c83 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -42,6 +42,9 @@ i915-y += i915_cmd_parser.o \ # generic ancilliary microcontroller support i915-y += intel_uc_loader.o +# general-purpose microcontroller (GuC) support +i915-y += intel_guc_loader.o + # autogenerated null render state i915-y += intel_renderstate_gen6.o \ intel_renderstate_gen7.o \ diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c5349fa..730d91b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -469,6 +469,7 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(dev-struct_mutex); + intel_guc_ucode_fini(dev); i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(dev-struct_mutex); @@ -866,6 +867,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_uncore_init(dev); + intel_guc_ucode_init(dev); + /* Load CSR Firmware for SKL */ intel_csr_ucode_init(dev); @@ -1117,6 +1120,7 @@ int i915_driver_unload(struct drm_device *dev) flush_workqueue(dev_priv-wq); mutex_lock(dev-struct_mutex); + intel_guc_ucode_fini(dev); i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(dev-struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9618f57..a7ccac5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -50,6 +50,7 @@ #include linux/intel-iommu.h #include linux/kref.h #include linux/pm_qos.h +#include intel_guc.h /* General customization: */ @@ -1687,6 +1688,8 @@ struct drm_i915_private { struct i915_virtual_gpu vgpu; + struct intel_guc guc; + struct intel_csr csr; /* Display CSR-related protection */ @@ -1931,6 +1934,11 @@ static inline struct drm_i915_private *dev_to_i915(struct device *dev) return to_i915(dev_get_drvdata(dev)); } +static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc) +{ + return container_of(guc, struct drm_i915_private, guc); +} + /* Iterate over initialised rings */ #define for_each_ring(ring__, dev_priv__, i__) \ for ((i__) = 0; (i__) I915_NUM_RINGS; (i__)++) \ @@ -2539,6 +2547,9 @@ struct drm_i915_cmd_table { #define HAS_CSR(dev) (IS_SKYLAKE(dev)) +#define HAS_GUC_UCODE(dev) (IS_GEN9(dev)) +#define HAS_GUC_SCHED(dev) (IS_GEN9(dev)) + #define INTEL_PCH_DEVICE_ID_MASK 0xff00 #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index aa8f4c3..80d7890 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5076,6 +5076,14 @@ i915_gem_init_hw(struct drm_device *dev) goto out; } + /* +* We can't enable contexts until all firmware is loaded; if this +* fails, disable GuC submissions and fall back to execlist mode +*/ + ret = intel_guc_ucode_load(dev); + if (ret) + i915.enable_guc_submission = false; I want an -EIO or similar here since runtime fallbacks to other modes really aren't great from a maintainance perspective, see
Re: [Intel-gfx] [PATCH 1/3] drm/i915: Make fb user dirty operation to invalidate frontbuffer
On Mon, Jul 06, 2015 at 02:11:55PM -0300, Paulo Zanoni wrote: 2015-07-06 13:43 GMT-03:00 Vivi, Rodrigo rodrigo.v...@intel.com: On Fri, 2015-07-03 at 09:10 +0200, Daniel Vetter wrote: On Thu, Jul 02, 2015 at 04:41:32PM +, Vivi, Rodrigo wrote: On Thu, 2015-07-02 at 13:03 -0300, Paulo Zanoni wrote: 2015-06-30 20:42 GMT-03:00 Rodrigo Vivi rodrigo.v...@intel.com: Let's do a frontbuffer invalidation on dirty fb. To be used for DIRTYFB drm ioctl. This patch solves the biggest PSR known issue, that is missed screen updates during boot, mainly when there is a splash screen involved like plymouth. Plymoth will do a modeset over ioctl that flushes frontbuffer tracking and PSR gets back to work while it cannot track the screen updates and exit properly. However plymouth also uses a dirtyfb ioctl whenever updating the screen. So let's use it to invalidate PSR back again. v2: Remove ORIGIN_FB_DIRTY and use ORIGIN_GTT instead since dirty callback is just called after few screen updates and not on everyone as pointed by Daniel. Cc: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Rodrigo Vivi rodrigo.v...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 724b0e3..b55b1b6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14393,9 +14393,27 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, return drm_gem_handle_create(file, obj-base, handle); } +static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) You don't need the white space on the lines above, just the tabs. +{ + struct drm_device *dev = fb-dev; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj = intel_fb-obj; + + mutex_lock(dev-struct_mutex); + intel_fb_obj_invalidate(obj, ORIGIN_GTT); As far as I understood from my brief investigation, the dirty IOCTL just says hey, I'm done writing on the memory, you can flush things now, and if the user writes on the buffer again later, it will need to call the dirty IOCTL again. So shouldn't we call intel_fb_obj_flush(obj, false) here? It seems this was also pointed by Daniel on the first review. It would be better because it would allow us to actually keep PSR/FBC enabled. The flush caused by the dumb modeset ioctl is exactly what I want to revert here. Well, I just tested to double check here and flush makes me to miss screen updates. (triple checked with retired = true as well just in case) fbdev comes to place and invalidated frontbuffer, then plymouth does a flush that makes psr start working when it should continue disabled. Continue flushing it doesn't solve the problem, just ratify it. But beside the issue that it is solving I don't believe we want is a flush anyway. There is something writing directly to frontbuffer with no invalidation. The dirty call is supposed to be a damage call that actually tells something on the screen got written and needs to be updated if it hasn't still. In our cause this is exactly the frontbuffer invalidate, not the flush. The flush place would be after it really stopped doing something, but since I don't trust it I prefer to let it invalidated until next flip. See my review on the first round of this patch: dirtyfb _is_ a flush. If it's not enough then there's some other problems still around. Well, the flush itself in the way it is defined is to flush frontbuffer bits and put power saving features back to work. PSR flush for instance doesn't exit on every flush. Only in the cases that we know HW tracking doesn't work. One possibility would be change PSR to respect that all flush always is invalidate (exit) + flush fb_bits. But I'm against this since PSR on core platforms doesn't have SW trackking ext and it wasn't implemented to be fully enabled/disabled every time. Another idea on this line is to make flushs know origins or at least a boolean to separate cases where flush must be handled as flush bits + continue working or invalidate + flush bits + start working again Please let me know what you think. But putting flushs on this dirty callback is currently useless
Re: [Intel-gfx] [PATCH i-g-t 00/16] Introduction of plotting support
On Mon, Jul 06, 2015 at 08:25:56PM +0200, Daniel Vetter wrote: atm QA rolls their own thing, developers on mesa side have ministat, and it looks like you want to create something in igt. I know it's easier, but I'd like to share as much tooling between QA and devs as possible. And that kinda means we should have the same tooling across different gfx components because otherwise QA gets pissed. Unfortunately we're not even there yet with just running testcases, so microbenchmarks are really far off. Just a word of warning really that we could end up running into a valley here that we'll regret 2 years down the road (when QA is solid and we have a problem with piles of different benchmarking suites). But really this is is just grumpy maintainer fearing another long-term headache, I don't want to stop your enthusiasm (too much at least). I'd be wary of tooling outside of igt or piglit. I asked on #intel-gfx and there's nothing like a base set of tools for mirco-benchmarking. Actually there are fairly few micro benchmarks at all (it's debatable that micro-benchmarks make people focus on details that aren't relevant in the big picture, the hope here is that they can help mesa to make performance trade offs). - Just to be clear, I don't care about anything closed source :) - ministat.c is definitely useful but also limited to what it can do. It's also external to benchmarks, needs wrapper scripts to be fully operational (and several all those exists). - Do you know if QA doing anything on benchmarking low level stuff today? if so I'd love to talk to them. No external things please (like the test blacklist being external to i-g-t). - If your objection is being able to have benchmark results unified between piglit and i-g-t, we can always generate a similar format for the key metric we want to monitor. More detailed analysis will require more than just that though. I also don't think anything like this exists in piglit today. - It's not just about stats and plots. It's also about: * collecting metrics (CPU and GPU side), which mean integration with perf. * collecting other interesting data like memory bandwith available to the CPU and GPU and compare them against theoritical maxima. * Generating useful reports So I'm not finished :) You forgot the Finland perf team in your tour of people looking around that area. I think I need to talk to them. Why don't we have some of those benchmarks they have in i-g-t? (using OpenGL? they are not open source?) I have the feeling we should at least have a single point of contribution, let's make sure it's i-g-t when it's about low level tests? Do we want to start accepting tests written in OpenGL in i-g-t? So many '?'s! -- Damien ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx