Re: [Intel-gfx] [PATCH 1/2] drm/i915: Optimize HDMI EDID reads
Regards Shashank On 8/13/2014 5:44 PM, Daniel Vetter wrote: On Tue, Aug 12, 2014 at 06:08:20PM +0530, shashank.sha...@intel.com wrote: From: Shashank Sharma shashank.sha...@intel.com The current hdmi_detect() function is getting called from many places, few of these are: 1. HDMI hot plug interrupt bottom half 2. get_resources() IOCTL family 3. drm_helper_probe_single_connector_modes() family 4. output_poll_execute() 5. status_show() etc... Every time this function is called, it goes and reads HDMI EDID over DDC channel. Ideally, reading EDID is only required when there is a real hot plug, and then for all IOCTL and userspace detect functions can be answered using this same EDID. The current patch adds EDID caching for a finite duration (1 minute) This is how it works: 1. With in this caching duration, when usespace get_resource and other modeset_detect calls get called, we can use the cached EDID. 2. Even the get_mode function can use the cached EDID. 3. A delayed work will clear the cached EDID after the timeout. 4. If there is a real HDMI hotplug, within the caching duration, the cached EDID is updates, and a new delayed work is scheduled. Signed-off-by: Shashank Sharma shashank.sha...@intel.com This has a bunch of changes compared to what I've proposed, and so will not actually work. Also, keying off the source platform (with the gen6 checks) is useless if we're dealing with random brokeness in existing hdmi sinks here. -Daniel Can you please point out what is it, that's unexpected to you ? I think this is what we (you Shobhit) agreed on: 1. Timeout based EDID caching 2. Use of cached EDID within caching duration 3. Separate path for HDMI compliance, controllable in kernel, which doesn't affect current code flow. --- drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_hdmi.c | 92 --- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 28d185d..185a45a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -110,6 +110,8 @@ #define INTEL_DSI_VIDEO_MODE 0 #define INTEL_DSI_COMMAND_MODE1 +#define INTEL_HDMI_EDID_CACHING_SEC 60 + struct intel_framebuffer { struct drm_framebuffer base; struct drm_i915_gem_object *obj; @@ -507,6 +509,8 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct edid *edid; + struct delayed_work edid_work; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5f47d35..8dc3970 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -962,6 +962,22 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, return true; } +/* Work function to invalidate EDID caching */ +static void intel_hdmi_invalidate_edid(struct work_struct *work) +{ + struct intel_hdmi *intel_hdmi = container_of(to_delayed_work(work), + struct intel_hdmi, edid_work); + struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); + struct drm_mode_config *mode_config = dev-mode_config; + + mutex_lock(mode_config-mutex); + /* Checkpatch says kfree is NULL protected */ + kfree(intel_hdmi-edid); + intel_hdmi-edid = NULL; + mutex_unlock(mode_config-mutex); + DRM_DEBUG_DRIVER(cleaned up cached EDID\n); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { @@ -978,15 +994,58 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) DRM_DEBUG_KMS([CONNECTOR:%d:%s]\n, connector-base.id, connector-name); + /* + * hdmi_detect() gets called from both get_resource() + * and HDMI hpd bottom half work function. + * Its not required to read EDID for every detect call until it's is + * from a hot plug. Lets cache the EDID as soon as we get + * a HPD, and then try to re-use this for all the non hpd detact calls + * coming with in a finite duration. + */ + if (INTEL_INFO(dev)-gen 6) + /* Do not break old platforms */ + goto skip_optimization; + + /* If call is from HPD, do check real status by reading EDID */ + if (!force) + goto skip_optimization; + + /* This is a non-hpd call, lets see if we can optimize this */ + if (intel_hdmi-edid) { + /* + * So this is a non-hpd call, within the duration when + * EDID caching is valid. So previous status (valid) + * of connector is
Re: [Intel-gfx] [PATCH 1/5] drm/i915: Print captured bo for all VM in error state
On Wed, Aug 13, 2014 at 05:50:38PM +0300, Mika Kuoppala wrote: Chris Wilson ch...@chris-wilson.co.uk writes: The current error state harks back to the era of just a single VM. For full-ppgtt, we capture every bo on every VM. It behoves us to then print every bo for every VM, which we currently fail to do and so miss vital information in the error state. v2: Use the vma address rather than -1! Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Offsets can collide between different vm areas. If we add vm index also to the captured batchbuffer objects, we could print it part of the offset '%d:0x%x' that would easily identify vm and we would immediately see what vm was active on a ring. The offsets are printed out per-vm. You want to be more specific in your complaint. Based on earlier discussion, I think you just want to know the guilty vm. -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: Localise the fbdev console lock frobbing
On Wed, Aug 13, 2014 at 03:40:24PM +0200, Daniel Vetter wrote: On Wed, Aug 13, 2014 at 02:09:22PM +0100, Chris Wilson wrote: On Wed, Aug 13, 2014 at 03:04:02PM +0200, Daniel Vetter wrote: On Wed, Aug 13, 2014 at 01:58:30PM +0100, Chris Wilson wrote: On Wed, Aug 13, 2014 at 02:46:53PM +0200, Daniel Vetter wrote: On Wed, Aug 13, 2014 at 01:09:46PM +0100, Chris Wilson wrote: Rather than take and release the console_lock() around a non-existent DRM_I915_FBDEV, move the lock acquisation into the callee where it will be compiled out by the config option entirely. This includes moving the deferred fb_set_suspend() dance and encapsulating it entirely within intel_fbdev.c. v2: Use an integral work item so that we can explicitly flush the work upon suspend/unload. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c| 3 --- drivers/gpu/drm/i915/i915_drv.c| 28 ++--- drivers/gpu/drm/i915/i915_drv.h| 9 +--- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_fbdev.c | 42 +- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 860da759ae34..fbab9370cb5c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1339,8 +1339,6 @@ static int i915_load_modeset_init(struct drm_device *dev) if (ret) goto cleanup_irq; - INIT_WORK(dev_priv-console_resume_work, intel_console_resume); - intel_modeset_gem_init(dev); /* Always safe in the mode setting case. */ @@ -1857,7 +1855,6 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_fbdev_fini(dev); intel_modeset_cleanup(dev); - cancel_work_sync(dev_priv-console_resume_work); This one here seems to have been lost - shouldn't we move this to fbdev_fini instead? Otherwise this looks good imo, so I'll fix that up while merging if you're ok. Hmm, I counted on us calling suspend before intel_fbdev_fini() in unload. Is this not the case? Otherwise I think we should be suspending the console. We don't do any of that. Unregistering the fbdev emulation in fbdev_fini should be enough though to stop anyone from actually using the gpu, and we're careful to unregister other console drivers like vgacon to make sure no one else can grow stupid ideas. So I think the only concern really is that the work item completes before the text section disappears, and maybe (on multi-gpu systems) that we don't keep all fbdev devices disabled forever after a racy module unload. Ok, I followed the unload-fbdev_fini-unregister_console and concur that all you want is the flush_work() in fbdev_fini. Donemerged, thanks a lot for the patch - looks much better than my #ifdef hacks ;-) I disaggree with the conversion of the BUG_ON though, a WARN there is going to screw up unpredictably (well, a hard hang without any output is the predictable outcome). I'd like to have asserts for things that could and should be statically analyzed... -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 1/2] drm/i915: Optimize HDMI EDID reads
On Thu, Aug 14, 2014 at 8:15 AM, Sharma, Shashank shashank.sha...@intel.com wrote: Can you please point out what is it, that's unexpected to you ? I think this is what we (you Shobhit) agreed on: 1. Timeout based EDID caching 2. Use of cached EDID within caching duration 3. Separate path for HDMI compliance, controllable in kernel, which doesn't affect current code flow. - The timeout is 1 minute instead of 1s. That breaks interactions with the periodical probing we do when there's a storm. - There's a generation check in there. This is a generic problem, restricting platforms only means that fewer people will be able to test it and find issues with broken hdmi sinks. The problem here are _sink_ devices, not necessarily platforms. So testing for platforms is bogus. - Keying off the force parameter isn't actually precise enough. There's an encoder-hot_plug callback where you should invalidate the edid instead. - Adding the edid caching to the intel_hdmi struct is the wrong place, we already have an edid pointer in intel_connector, which is used for panels. Augmenting that to allow caching with time-based invalidation is the right solution instead of inventing a completely new wheel. Aside: You commit message is misleading since it's actually not required to do a full probe cycle for the get_connector ioctl. You can get at the current cached mode list without any probe calls at all. Please have a look at SNA for how to do that. And if you have userspace constantly probing sysfs files and other stuff instead of listening to uevents then you need to fix your userspace, not cache the edid in the kernel for a minute. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Localise the fbdev console lock frobbing
On Thu, Aug 14, 2014 at 8:54 AM, Chris Wilson ch...@chris-wilson.co.uk wrote: I disaggree with the conversion of the BUG_ON though, a WARN there is going to screw up unpredictably (well, a hard hang without any output is the predictable outcome). I'd like to have asserts for things that could and should be statically analyzed... Well I've put a zero-tolerance rule for BUG_ON into place with the only exception if the kernel will die anyway in the next few lines. Which means I trade in a limping (and potentially dangerous) kernel for the ability to be able to read the backtrace somewhere. I agree that any such extreme policy will end up looking stupid in some cases, but I've just decided that I wasted too much time on chasing lookups which would have been trivial to debug with a WARN_ON instead of a BUG_ON. Until I've wasted too much time with WARN_ON instead of BUG_ON I'll let it stick. And it's supported by my patch scripts, so small chance I'll miss one. Ofc I'll never change it without a notice in the commit message, so people can always blame me for it. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/6] drm/i915: Added support to allow change in FB pitch across flips
From: Akash Goel akash.g...@intel.com This patch removes the check for change in pitch of frame buffer across page flips. Since there is a support for MMIO based page flips, we can update the plane registers to update the FB pitch accordingly the offsets in LINOFF/TILEOFF registers. The plane registers are updated atomically, using the mechanism used for Sprite planes update. Doing so also requires deferring of MMIO flip, if issued in interrupt context. Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 51 +--- drivers/gpu/drm/i915/intel_drv.h | 5 drivers/gpu/drm/i915/intel_sprite.c | 4 +-- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 47a5424..a75d1a0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9542,6 +9542,29 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, return ring != obj-ring; } +static void intel_mmio_flip_work_fn(struct work_struct *work) +{ + struct intel_mmio_flip *mmio_flip = + container_of(work, struct intel_mmio_flip, work); + struct intel_crtc *intel_crtc = + container_of(mmio_flip, struct intel_crtc, mmio_flip); + struct drm_device *dev = intel_crtc-base.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_crtc *crtc = intel_crtc-base; + u32 start_vbl_count; + bool atomic_update; + + atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + + intel_mark_page_flip_active(intel_crtc); + + dev_priv-display.update_primary_plane(crtc, crtc-primary-fb, + crtc-x, crtc-y); + + if (atomic_update) + intel_pipe_update_end(intel_crtc, start_vbl_count); +} + static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc-base.dev; @@ -9552,6 +9575,17 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) u32 dspcntr; u32 reg; + /* if we are in interrupt context and there is a need to update + all the plane registers (atomically), then defer the flip to + a process context, as we can then wait for the next vblank boundary */ + if (intel_crtc-unpin_work-update_all_plane_reg) { + if (in_atomic()) + schedule_work(intel_crtc-mmio_flip.work); + else + intel_mmio_flip_work_fn(intel_crtc-mmio_flip.work); + return; + } + intel_mark_page_flip_active(intel_crtc); reg = DSPCNTR(intel_crtc-plane); @@ -9685,6 +9719,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct intel_unpin_work *work; struct intel_engine_cs *ring; unsigned long flags; + bool update_all_plane_reg = 0; int ret; /* @@ -9706,7 +9741,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (INTEL_INFO(dev)-gen 3 (fb-offsets[0] != crtc-primary-fb-offsets[0] || fb-pitches[0] != crtc-primary-fb-pitches[0])) - return -EINVAL; + update_all_plane_reg = 1; if (i915_terminally_wedged(dev_priv-gpu_error)) goto out_hang; @@ -9718,6 +9753,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work-event = event; work-crtc = crtc; work-old_fb_obj = intel_fb_obj(old_fb); + work-update_all_plane_reg = update_all_plane_reg; INIT_WORK(work-work, intel_unpin_work_fn); ret = drm_crtc_vblank_get(crtc); @@ -9785,9 +9821,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (use_mmio_flip(ring, obj)) ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring, page_flip_flags); - else - ret = dev_priv-display.queue_flip(dev, crtc, fb, obj, ring, - page_flip_flags); + else { + if (update_all_plane_reg) + ret = -EINVAL; + else + ret = dev_priv-display.queue_flip(dev, crtc, fb, obj, ring, + page_flip_flags); + } + if (ret) goto cleanup_unpin; @@ -11912,6 +11953,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc-cursor_cntl = ~0; intel_crtc-cursor_size = ~0; + INIT_WORK(intel_crtc-mmio_flip.work, intel_mmio_flip_work_fn); + BUG_ON(pipe = ARRAY_SIZE(dev_priv-plane_to_crtc_mapping) || dev_priv-plane_to_crtc_mapping[intel_crtc-plane] != NULL); dev_priv-plane_to_crtc_mapping[intel_crtc-plane] =
[Intel-gfx] [PATCH 1/6] drm/i915: Added a return type for panel fitter config functions
From: Akash Goel akash.g...@intel.com This patch changes the return type of panel fitter configuration functions from 'void', so that an error could be returned back to User space, either during the modeset time or when some property is being set, if the configuation is not valid. Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- drivers/gpu/drm/i915/intel_dp.c| 15 +-- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_lvds.c | 11 ++- drivers/gpu/drm/i915/intel_panel.c | 10 ++ 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e5ada4f..3273b77 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -859,12 +859,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (is_edp(intel_dp) intel_connector-panel.fixed_mode) { intel_fixed_panel_mode(intel_connector-panel.fixed_mode, adjusted_mode); - if (!HAS_PCH_SPLIT(dev)) - intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); - else - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); + if (!HAS_PCH_SPLIT(dev)) { + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } else { + if (!intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; + } } if (adjusted_mode-flags DRM_MODE_FLAG_DBLCLK) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3abc915..d1b5ded 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1016,10 +1016,10 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); -void intel_pch_panel_fitting(struct intel_crtc *crtc, +bool intel_pch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); -void intel_gmch_panel_fitting(struct intel_crtc *crtc, +bool intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); void intel_panel_set_backlight_acpi(struct intel_connector *connector, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 1987491..2a53768 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -317,12 +317,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, if (HAS_PCH_SPLIT(dev)) { pipe_config-has_pch_encoder = true; - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector-panel.fitting_mode); + if (!intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; } else { - intel_gmch_panel_fitting(intel_crtc, pipe_config, -intel_connector-panel.fitting_mode); - + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector-panel.fitting_mode)) + return false; } /* diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 59b028f..15f2979 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -96,7 +96,7 @@ intel_find_panel_downclock(struct drm_device *dev, } /* adjusted_mode has been preset to be the panel's fixed mode */ -void +bool intel_pch_panel_fitting(struct intel_crtc *intel_crtc, struct intel_crtc_config *pipe_config, int fitting_mode) @@ -158,13 +158,14 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, default: WARN(1, bad panel fit mode: %d\n, fitting_mode); - return; + return false; } done: pipe_config-pch_pfit.pos = (x 16) | y; pipe_config-pch_pfit.size = (width 16) | height;
[Intel-gfx] [PATCH 2/6] drm/i915: Added a return type for the restore crtc mode function
From: Akash Goel akash.g...@intel.com This patch changes the return type of 'crtc_restore_mode' function from 'void', so that an error could be returned back to User space, from the set property ioctl call, if the configuation is not valid. Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 ++-- drivers/gpu/drm/i915/intel_dp.c | 30 +++ drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_hdmi.c| 28 +++--- drivers/gpu/drm/i915/intel_lvds.c| 7 - drivers/gpu/drm/i915/intel_sdvo.c| 57 +--- drivers/gpu/drm/i915/intel_tv.c | 26 ++-- 7 files changed, 136 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5871efa..47a5424 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10964,9 +10964,10 @@ static int intel_set_mode(struct drm_crtc *crtc, return ret; } -void intel_crtc_restore_mode(struct drm_crtc *crtc) +int intel_crtc_restore_mode(struct drm_crtc *crtc) { - intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, crtc-primary-fb); + return intel_set_mode(crtc, crtc-mode, crtc-x, crtc-y, + crtc-primary-fb); } #undef for_each_intel_crtc_masked diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3273b77..4457a06 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3889,6 +3889,9 @@ intel_dp_set_property(struct drm_connector *connector, struct intel_encoder *intel_encoder = intel_attached_encoder(connector); struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder-base); int ret; + bool old_has_audio = 0, old_auto = 0; + uint32_t old_range = 0; + int old_force_audio = 0, old_fitting_mode = 0; ret = drm_object_property_set_value(connector-base, property, val); if (ret) @@ -3901,6 +3904,9 @@ intel_dp_set_property(struct drm_connector *connector, if (i == intel_dp-force_audio) return 0; + old_force_audio = intel_dp-force_audio; + old_has_audio = intel_dp-has_audio; + intel_dp-force_audio = i; if (i == HDMI_AUDIO_AUTO) @@ -3916,8 +3922,8 @@ 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; + old_auto = intel_dp-color_range_auto; + old_range = intel_dp-color_range; switch (val) { case INTEL_BROADCAST_RGB_AUTO: @@ -3953,6 +3959,7 @@ intel_dp_set_property(struct drm_connector *connector, /* the eDP scaling property is not changed */ return 0; } + old_fitting_mode = intel_connector-panel.fitting_mode; intel_connector-panel.fitting_mode = val; goto done; @@ -3961,9 +3968,22 @@ intel_dp_set_property(struct drm_connector *connector, return -EINVAL; done: - if (intel_encoder-base.crtc) - intel_crtc_restore_mode(intel_encoder-base.crtc); - + if (intel_encoder-base.crtc) { + ret = intel_crtc_restore_mode(intel_encoder-base.crtc); + if (ret) { + if (property == dev_priv-force_audio_property) { + intel_dp-force_audio = old_force_audio; + intel_dp-has_audio = old_has_audio; + } + else if (property == dev_priv-broadcast_rgb_property) { + intel_dp-color_range_auto = old_auto; + intel_dp-color_range = old_range; + } + else if (property == connector-dev-mode_config.scaling_mode_property) + intel_connector-panel.fitting_mode = old_fitting_mode; + } + return ret; + } return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d1b5ded..a30abd9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -802,7 +802,7 @@ void intel_frontbuffer_flip(struct drm_device *dev, void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); void intel_mark_idle(struct drm_device *dev); -void intel_crtc_restore_mode(struct drm_crtc *crtc); +int intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_control(struct drm_crtc *crtc, bool enable); void intel_crtc_update_dpms(struct drm_crtc *crtc); void
[Intel-gfx] [PATCH 5/6] Documentation/drm: Describing crtc size property
From: Akash Goel akash.g...@intel.com Updated drm documentation to include description of Crtc size property Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- Documentation/DocBook/drm.tmpl | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index c11ec6b..7c8441d 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2508,7 +2508,7 @@ void intel_crt_init(struct drm_device *dev) td valign=top Description/Restrictions/td /tr tr - td rowspan=21 valign=top DRM/td + td rowspan=22 valign=top DRM/td td rowspan=2 valign=top Generic/td td valign=top “EDID”/td td valign=top BLOB | IMMUTABLE/td @@ -2639,7 +2639,7 @@ void intel_crt_init(struct drm_device *dev) td valign=top TBD/td /tr tr - td rowspan=3 valign=top Optional/td + td rowspan=4 valign=top Optional/td td valign=top “scaling mode”/td td valign=top ENUM/td td valign=top { None, Full, Center, Full aspect }/td @@ -2663,6 +2663,15 @@ void intel_crt_init(struct drm_device *dev) td valign=top TBD/td /tr tr + td valign=top “crtc size”/td + td valign=top RANGE/td + td valign=top Min=0, Max=0x/td + td valign=top Crtc/td + td valign=top DRM property to change the Crtc size dynamically. + Height/Width are in packed(height in lower 16 bits) form so that both + can be updated in a single call./td + /tr + tr td rowspan=21 valign=top i915/td td rowspan=2 valign=top Generic/td td valign=top Broadcast RGB/td -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
From: Akash Goel akash.g...@intel.com This patch adds a new drm crtc property for varying the Pipe Src size or the Panel fitter input size. Pipe Src controls the size that is scaled from. This will allow to dynamically flip the frame buffers of different resolutions. For this Driver internally enables the Panel fitter or Hw scaler if its a Fixed mode panel new Pipe Src values differ from the Pipe timings Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- drivers/gpu/drm/drm_crtc.c | 7 drivers/gpu/drm/drm_fb_helper.c | 7 drivers/gpu/drm/i915/intel_display.c | 72 include/drm/drm_crtc.h | 7 4 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f09b752..328efac 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -5169,3 +5169,10 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, supported_rotations); } EXPORT_SYMBOL(drm_mode_create_rotation_property); + +struct drm_property *drm_mode_create_crtc_size_property(struct drm_device *dev) +{ + return drm_property_create_range(dev, 0, crtc size, + 0, UINT_MAX); +} +EXPORT_SYMBOL(drm_mode_create_crtc_size_property); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 63d7b8e..6eb1949 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -307,6 +307,13 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) struct drm_crtc *crtc = mode_set-crtc; int ret; + if (dev-mode_config.crtc_size_property) { + crtc-crtc_w = crtc-crtc_h = 0; + drm_object_property_set_value(crtc-base, + dev-mode_config.crtc_size_property, + 0); + } + if (crtc-funcs-cursor_set) { ret = crtc-funcs-cursor_set(crtc, NULL, 0, 0, 0); if (ret) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a75d1a0..7c417fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10183,6 +10183,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, pipe_config-pipe_src_w = pipe_config-requested_mode.crtc_hdisplay; pipe_config-pipe_src_h = pipe_config-requested_mode.crtc_vdisplay; + /* Set the Pipe Src values as per the crtc size property values */ + if (crtc-crtc_w crtc-crtc_h) { + pipe_config-pipe_src_w = crtc-crtc_w; + pipe_config-pipe_src_h = crtc-crtc_h; + } + encoder_retry: /* Ensure the port clock defaults are reset when retrying. */ pipe_config-port_clock = 0; @@ -11438,11 +11444,67 @@ out_config: return ret; } +static int intel_crtc_set_property(struct drm_crtc *crtc, + struct drm_property *prop, + uint64_t val) +{ + struct drm_device *dev = crtc-dev; + int ret = -ENOENT; + + if (prop == dev-mode_config.crtc_size_property) { + int old_width, old_height; + int new_width = (int)((val 16) 0x); + int new_height = (int)(val 0x); + const struct drm_framebuffer *fb = crtc-primary-fb; + + if ((new_width == crtc-crtc_w) + (new_height == crtc-crtc_h)) + return 0; + + /* Check if property is resetted, so just return */ + if ((new_width == 0) (new_height) == 0) { + crtc-crtc_w = crtc-crtc_h = 0; + /* FIXME, Is modeset required here ?. Actually the + current FB may not be compatible with the mode */ + return 0; + } else if ((new_width == 0) || (new_height == 0)) + return -EINVAL; + + /* Check if the current FB is compatible with new requested + Pipesrc values by the User */ + if (new_width fb-width || + new_height fb-height || + crtc-x fb-width - new_width || + crtc-y fb-height - new_height) { + DRM_DEBUG_KMS(New Pipe Src values %dx%d is incompatible with current fb size viewport %ux%u+%d+%d\n, + new_width, new_height, fb-width, fb-height, crtc-x, crtc-y); + return -EINVAL; + } + + old_width = crtc-crtc_w; + old_height = crtc-crtc_h; + + crtc-crtc_w = new_width; + crtc-crtc_h = new_height; + +
[Intel-gfx] [PATCH 0/6] New drm crtc property for varying the Crtc size
From: Akash Goel akash.g...@intel.com Added a new drm crtc property which provides control to vary the Pipe Src or Crtc size. With this, User can flip the frame buffers of resolution, which is different from the currently selected mode. For this Driver will appropriately enable the Panel fitter internally, for the required scaling. For this also removed the check of change in frame buffer pitch, from the crtc page flip function. Added a return type to panel fitter config crtc retsore mode functions, so that an error could be returned to User space for an invalid configuration. Also added Max downscale ratio checks when enbaling Panel fitter. Akash Goel (6): drm/i915: Added a return type for panel fitter config functions drm/i915: Added a return type for the restore crtc mode function drm/i915: Added Max down-scale ratio checks when enabling Panel fitter drm/i915: Added support to allow change in FB pitch across flips Documentation/drm: Describing crtc size property drm/i915: New drm crtc property for varying the Crtc size Documentation/DocBook/drm.tmpl | 13 +++- drivers/gpu/drm/drm_crtc.c | 7 ++ drivers/gpu/drm/drm_fb_helper.c | 7 ++ drivers/gpu/drm/i915/intel_display.c | 128 +-- drivers/gpu/drm/i915/intel_dp.c | 45 +--- drivers/gpu/drm/i915/intel_drv.h | 11 ++- drivers/gpu/drm/i915/intel_hdmi.c| 28 ++-- drivers/gpu/drm/i915/intel_lvds.c| 18 +++-- drivers/gpu/drm/i915/intel_panel.c | 123 ++--- drivers/gpu/drm/i915/intel_sdvo.c| 57 ++-- drivers/gpu/drm/i915/intel_sprite.c | 4 +- drivers/gpu/drm/i915/intel_tv.c | 26 ++- include/drm/drm_crtc.h | 7 ++ 13 files changed, 410 insertions(+), 64 deletions(-) -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/6] drm/i915: Added Max down-scale ratio checks when enabling Panel fitter
From: Akash Goel akash.g...@intel.com This patch adds a check on the Max down scale ratio supported by the Panel fitter. If Source width/height is too big, that the downscale ratio of more than 1.125 is needed to fit into the Output window, then that configuration will be rejected. Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com --- drivers/gpu/drm/i915/intel_panel.c | 113 ++--- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 15f2979..350e94d 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -33,6 +33,22 @@ #include linux/moduleparam.h #include intel_drv.h +/* Max Downscale ratio of 1.125, expressed in 1.12 fixed point format */ +#define MAX_DOWNSCALE_RATIO (0x9 9) + +static inline u32 panel_fitter_scaling(u32 source, u32 target) +{ + /* +* Floating point operation is not supported. So the FACTOR +* is defined, which can avoid the floating point computation +* when calculating the panel ratio. +*/ +#define ACCURACY 12 +#define FACTOR (1 ACCURACY) + u32 ratio = source * FACTOR / target; + return (FACTOR * ratio + FACTOR/2) / FACTOR; +} + void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) @@ -103,6 +119,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, { struct drm_display_mode *adjusted_mode; int x, y, width, height; + u32 pf_horizontal_ratio, pf_vertical_ratio; adjusted_mode = pipe_config-adjusted_mode; @@ -161,6 +178,19 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, return false; } + pf_horizontal_ratio = panel_fitter_scaling(pipe_config-pipe_src_w, + width); + pf_vertical_ratio = panel_fitter_scaling(pipe_config-pipe_src_h, + height); + + if (pf_horizontal_ratio MAX_DOWNSCALE_RATIO) { + DRM_DEBUG_KMS(Src width is too big to downscale\n); + return false; + } else if (pf_vertical_ratio MAX_DOWNSCALE_RATIO) { + DRM_DEBUG_KMS(Src height is too big to downscale\n); + return false; + } + done: pipe_config-pch_pfit.pos = (x 16) | y; pipe_config-pch_pfit.size = (width 16) | height; @@ -211,21 +241,9 @@ centre_vertically(struct drm_display_mode *mode, mode-crtc_vsync_end = mode-crtc_vsync_start + sync_width; } -static inline u32 panel_fitter_scaling(u32 source, u32 target) -{ - /* -* Floating point operation is not supported. So the FACTOR -* is defined, which can avoid the floating point computation -* when calculating the panel ratio. -*/ -#define ACCURACY 12 -#define FACTOR (1 ACCURACY) - u32 ratio = source * FACTOR / target; - return (FACTOR * ratio + FACTOR/2) / FACTOR; -} - static void i965_scale_aspect(struct intel_crtc_config *pipe_config, - u32 *pfit_control) + u32 *pfit_control, + u32 *pf_horizontal_ratio, u32 *pf_vertical_ratio) { struct drm_display_mode *adjusted_mode = pipe_config-adjusted_mode; u32 scaled_width = adjusted_mode-hdisplay * @@ -234,19 +252,39 @@ static void i965_scale_aspect(struct intel_crtc_config *pipe_config, adjusted_mode-vdisplay; /* 965+ is easy, it does everything in hw */ - if (scaled_width scaled_height) + if (scaled_width scaled_height) { *pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; - else if (scaled_width scaled_height) + *pf_horizontal_ratio = + panel_fitter_scaling(pipe_config-pipe_src_w, + scaled_height / pipe_config-pipe_src_h); + *pf_vertical_ratio = panel_fitter_scaling(pipe_config-pipe_src_h, + adjusted_mode-vdisplay); + } + else if (scaled_width scaled_height) { *pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; - else if (adjusted_mode-hdisplay != pipe_config-pipe_src_w) + *pf_vertical_ratio = + panel_fitter_scaling(pipe_config-pipe_src_h, + scaled_width / pipe_config-pipe_src_w); + *pf_horizontal_ratio = panel_fitter_scaling(pipe_config-pipe_src_w, + adjusted_mode-hdisplay); + } + else if (adjusted_mode-hdisplay != pipe_config-pipe_src_w) { *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; + *pf_horizontal_ratio = +
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Optimize HDMI EDID reads
Hi Daniel, I can do all the changes accordingly and upload a new patch. This is what I am going to do: 1. Change the EDID caching time to a second from a minute (probably there was a miscommunication). 2. Remove the gen_check 3. Use the connector-edid pointer to cache EDID. I have only few problems with these two suggestions: Keying off the force parameter isn't actually precise enough. It is. All the calls to HDMI detect, which come as a result of user space interaction keep force = 1, whereas all the hot plug event callers keep it force = 0. Please have a look: IOCTL / Sysfs calls, calling connector-funcs-detect() 1. drm_helper_probe_single_connector_modes_merge_bits = (force = 1) 2. status_show = (force = 1) Hot plug handlers / hot plug poll 1. drm_helper_hpd_irq_event = (force = 0) 2. output_poll_execute = (force = 0) So this should work all right. There's an encoder-hot_plug callback where you should invalidate the edid instead. In MCG branch, we are doing this in encoder-hot_plug only. But there the EDID stays, until there is one more next hotplug, and by that time, the detect code uses cached EDID only. As encoder-hot_plug function also gets called every time there is a hot_plug, from the hotplug_work_fn, I was afraid this might cause a race. Second, I still have to write a delayed_work wrapper, to call encoder-hot_plug from, after the timeout. If you feel that, its better to do it there, I can do changes accordingly. Regards Shashank On 8/14/2014 1:58 PM, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 8:15 AM, Sharma, Shashank shashank.sha...@intel.com wrote: Can you please point out what is it, that's unexpected to you ? I think this is what we (you Shobhit) agreed on: 1. Timeout based EDID caching 2. Use of cached EDID within caching duration 3. Separate path for HDMI compliance, controllable in kernel, which doesn't affect current code flow. - The timeout is 1 minute instead of 1s. That breaks interactions with the periodical probing we do when there's a storm. - There's a generation check in there. This is a generic problem, restricting platforms only means that fewer people will be able to test it and find issues with broken hdmi sinks. The problem here are _sink_ devices, not necessarily platforms. So testing for platforms is bogus. - Keying off the force parameter isn't actually precise enough. There's an encoder-hot_plug callback where you should invalidate the edid instead. - Adding the edid caching to the intel_hdmi struct is the wrong place, we already have an edid pointer in intel_connector, which is used for panels. Augmenting that to allow caching with time-based invalidation is the right solution instead of inventing a completely new wheel. Aside: You commit message is misleading since it's actually not required to do a full probe cycle for the get_connector ioctl. You can get at the current cached mode list without any probe calls at all. Please have a look at SNA for how to do that. And if you have userspace constantly probing sysfs files and other stuff instead of listening to uevents then you need to fix your userspace, not cache the edid in the kernel for a minute. -Daniel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] BUG_ON vs WARN_ON (was: Re: [PATCH] drm/i915: Localise the fbdev console lock frobbing)
On Thu, 14 Aug 2014, Daniel Vetter dan...@ffwll.ch wrote: On Thu, Aug 14, 2014 at 8:54 AM, Chris Wilson ch...@chris-wilson.co.uk wrote: I disaggree with the conversion of the BUG_ON though, a WARN there is going to screw up unpredictably (well, a hard hang without any output is the predictable outcome). I'd like to have asserts for things that could and should be statically analyzed... Well I've put a zero-tolerance rule for BUG_ON into place with the only exception if the kernel will die anyway in the next few lines. Which means I trade in a limping (and potentially dangerous) kernel for the ability to be able to read the backtrace somewhere. I agree that any such extreme policy will end up looking stupid in some cases, but I've just decided that I wasted too much time on chasing lookups which would have been trivial to debug with a WARN_ON instead of a BUG_ON. Until I've wasted too much time with WARN_ON instead of BUG_ON I'll let it stick. And it's supported by my patch scripts, so small chance I'll miss one. Ofc I'll never change it without a notice in the commit message, so people can always blame me for it. In other words, WARN_ON is the new BUG_ON. But what's the new WARN_ON? Now we're conflating two things (limp home mode and crashing) into one. When I see WARN_ON in code, it's no longer clear to me whether this is a condition that we're supposed to survive or not. For example, does the code below a WARN_ON need to properly handle errors due to the condition? To me, BUG_ON is a code reading aide that sets the absolute precondition for the following code. Something that absolutely must be fixed if someone hits it, while WARN_ON can sometimes be ignored, or even replaced with DRM_DEBUG. If we have zero-tolerance for BUG_ON, and replace all of those with WARN_ON, we'll need to start being *very* selective about adding WARN_ON as well. BR, Jani. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/5] drm/i915: Print captured bo for all VM in error state
Chris Wilson ch...@chris-wilson.co.uk writes: On Wed, Aug 13, 2014 at 05:50:38PM +0300, Mika Kuoppala wrote: Chris Wilson ch...@chris-wilson.co.uk writes: The current error state harks back to the era of just a single VM. For full-ppgtt, we capture every bo on every VM. It behoves us to then print every bo for every VM, which we currently fail to do and so miss vital information in the error state. v2: Use the vma address rather than -1! Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Offsets can collide between different vm areas. If we add vm index also to the captured batchbuffer objects, we could print it part of the offset '%d:0x%x' that would easily identify vm and we would immediately see what vm was active on a ring. The offsets are printed out per-vm. You want to be more specific in your complaint. Based on earlier discussion, I think you just want to know the guilty vm. -Chris Yes. And it can be done as a follow up too. 1/5: Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] linux: Automatically ShareVTs if the VT are already in graphics mode
On Wed, Aug 13, 2014 at 10:58:54AM +0100, Chris Wilson wrote: If the VT we are using is already in KD_GRAPHICS mode, calling SETACTIVE will silently fail. This leads to an indefinite hang as WAITACTIVE never returns causing lockups on boot. This issue becomes apparent when the kernel driver does not install a fbdev for kernel to use for consoles and plymouth leaves the VT in graphics mode. It stops the hang on boot, but it also leaves process control on the defunct VT (i.e. ^C kills Xorg). Can we do the console switch without WAITACTIVE? Also doesn't explain why it works the second time. -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 1/2] drm/i915: Created common handler for platform specific suspend/resume
On Wed, 2014-08-13 at 23:07 +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this change, intel_runtime_suspend and intel_runtime_resume functions become completely platform agnostic. Platform specific suspend/resume changes are moved to intel_suspend_complete and intel_resume_prepare. Cc: Imre Deak imre.d...@intel.com Cc: Paulo Zanoni paulo.r.zan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: Goel, Akash akash.g...@intel.com For the future: it's not necessary to CC the above people, they all read the mailing list anyway. Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com Both patches look fine to me: Reviewed-by: Imre Deak imre.d...@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 76 ++--- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ec96f9a..88464ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -494,6 +494,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return true; } + +static int intel_suspend_complete(struct drm_i915_private *dev_priv); +static int intel_resume_prepare(struct drm_i915_private *dev_priv); + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; @@ -983,14 +987,14 @@ static int i915_pm_poweroff(struct device *dev) return i915_drm_freeze(drm_dev); } -static int hsw_runtime_suspend(struct drm_i915_private *dev_priv) +static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); return 0; } -static int snb_runtime_resume(struct drm_i915_private *dev_priv) +static int snb_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv-dev; @@ -999,7 +1003,7 @@ static int snb_runtime_resume(struct drm_i915_private *dev_priv) return 0; } -static int hsw_runtime_resume(struct drm_i915_private *dev_priv) +static int hsw_resume_prepare(struct drm_i915_private *dev_priv) { hsw_disable_pc8(dev_priv); @@ -1295,7 +1299,7 @@ static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); } -static int vlv_runtime_suspend(struct drm_i915_private *dev_priv) +static int vlv_suspend_complete(struct drm_i915_private *dev_priv) { u32 mask; int err; @@ -1335,7 +1339,7 @@ err1: return err; } -static int vlv_runtime_resume(struct drm_i915_private *dev_priv) +static int vlv_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv-dev; int err; @@ -1413,17 +1417,7 @@ static int intel_runtime_suspend(struct device *device) cancel_work_sync(dev_priv-rps.work); intel_runtime_pm_disable_interrupts(dev); - if (IS_GEN6(dev)) { - ret = 0; - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_suspend(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_suspend(dev_priv); - } else { - ret = -ENODEV; - WARN_ON(1); - } - + ret = intel_suspend_complete(dev_priv); if (ret) { DRM_ERROR(Runtime suspend failed, disabling it (%d)\n, ret); intel_runtime_pm_restore_interrupts(dev); @@ -1461,17 +1455,7 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv-pm.suspended = false; - if (IS_GEN6(dev)) { - ret = snb_runtime_resume(dev_priv); - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_resume(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_resume(dev_priv); - } else { - WARN_ON(1); - ret = -ENODEV; - } - + ret = intel_resume_prepare(dev_priv); /* * No point of rolling back things in case of an error, as the best * we can do is to hope that things will still work (and disable RPM). @@ -1490,6 +1474,44 @@ static int intel_runtime_resume(struct device *device) return ret; } +static int intel_suspend_complete(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv-dev; + int ret; + + if (IS_GEN6(dev)) { + ret = 0; + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = hsw_suspend_complete(dev_priv); + } else if (IS_VALLEYVIEW(dev)) { + ret = vlv_suspend_complete(dev_priv); + } else { + ret = -ENODEV; + WARN_ON(1); + } + + return ret; +} + +static int intel_resume_prepare(struct drm_i915_private *dev_priv) +{ +
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Optimize HDMI EDID reads
On Thu, Aug 14, 2014 at 02:53:44PM +0530, Sharma, Shashank wrote: Hi Daniel, I can do all the changes accordingly and upload a new patch. This is what I am going to do: 1. Change the EDID caching time to a second from a minute (probably there was a miscommunication). 2. Remove the gen_check 3. Use the connector-edid pointer to cache EDID. I have only few problems with these two suggestions: Keying off the force parameter isn't actually precise enough. It is. All the calls to HDMI detect, which come as a result of user space interaction keep force = 1, whereas all the hot plug event callers keep it force = 0. Please have a look: IOCTL / Sysfs calls, calling connector-funcs-detect() 1. drm_helper_probe_single_connector_modes_merge_bits = (force = 1) 2. status_show = (force = 1) Hot plug handlers / hot plug poll 1. drm_helper_hpd_irq_event = (force = 0) 2. output_poll_execute = (force = 0) So this should work all right. Hm indeed, I've mixed up things with the output poll worker. My concern is mostly that force already has overloaded meaning. But I think if we polish the code-flow a bit it should work out. Quick draft: /* at the top of the detect function before anything else */ if (!force) intel_connector_invalidate_edid(conn); Then we replace all current calls to drm_get_edid with a new intel_connector_get_edid_cached, which first checks the conn-edid cache and only if that's empty call drm_edid_cache. btw for the edid cache itself I think Chris' idea to use errno pointers is great, so the state machine would be: connector-edid == NULL - cache expired IS_ERR(connector-edid) - negative cache entry with errno value, e.g. -ENXIO. this way we also speed up subsequent detect calls from userspace when nothing is connected. everything else - cached edid So in code this would look like void intel_connector_invalidate_edid(conn) { /* locking tbd */ if (!conn-edid) return; if (!IS_ERR(conn-edid)) kfree(conn-edid); conn-edid = NULL; } struct drm_edid *intel_connector_get_edid_cached(conn, ...) { /* locking tbd */ if (!conn-edid) { conn-edid = drm_get_edid(...); if (!conn-edid) conn-edid = ERR_PTR(-ENXIO); /* rearm invalidate timer */ } return IS_ERR(conn-edid) ? NULL : conn-edid; } btw for locking I'd just pick a spinlock, then you can use a simple timer to free the edid. Currently the drm modeset locking is a bit fuzzy around connectors (due to the dp mst introduction), so separate locking would simplify things. There's an encoder-hot_plug callback where you should invalidate the edid instead. In MCG branch, we are doing this in encoder-hot_plug only. But there the EDID stays, until there is one more next hotplug, and by that time, the detect code uses cached EDID only. As encoder-hot_plug function also gets called every time there is a hot_plug, from the hotplug_work_fn, I was afraid this might cause a race. Second, I still have to write a delayed_work wrapper, to call encoder-hot_plug from, after the timeout. I've thought about the hotplug work function when we invalidate the edid, and I think we can wait with that until there's demand. Currently if the sink is horribly broken and does only respond after a while we will also not detect it right away. And as long as we invalidate the edid soonish (before the user could poke his system to figure out where the screen went) we'll be good. If you feel that, its better to do it there, I can do changes accordingly. Nah, I think if we wrap the caching/invalidation up into the above suggested tiny helpers the code will be clear enough and your idea of using force indeed works. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Don't warn if we restore pm interrupts during reset
We lost the software state tracking due to reset, so don't complain if it doesn't match. Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..47d430a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_gem_reset_in_progress(dev_priv)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_gem_reset_in_progress(dev_priv)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2] drm/i915: Don't warn if we restore pm interrupts during reset
We lost the software state tracking due to reset, so don't complain if it doesn't match. v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Sysfs interface to get GFX shmem usage stats per process
From: Sourab Gupta sourab.gu...@intel.com Currently the Graphics Driver provides an interface through which one can get a snapshot of the overall Graphics memory consumption. Also there is an interface available, which provides information about the several memory related attributes of every single Graphics buffer created by the various clients. There is a requirement of a new interface for achieving below functionalities: 1) Need to provide Client based detailed information about the distribution of Graphics memory 2) Need to provide an interface which can provide info about the sharing of Graphics buffers between the clients. The client based interface would also aid in debugging of memory usage/consumption by each client debug memleak related issues. With this new interface, 1) In case of memleak scenarios, we can easily zero in on the culprit client which is unexpectedly holding on the Graphics buffers for an inordinate amount of time. 2) We can get an estimate of the instantaneous memory footprint of every Graphics client. 3) We can now trace all the processes sharing a particular Graphics buffer. By means of this patch we try to provide a sysfs interface to achieve the mentioned functionalities. There are two files created in sysfs: 'i915_gem_meminfo' will provide summary of the graphics resources used by each graphics client. 'i915_gem_objinfo' will provide detailed view of each object created by individual clients. Signed-off-by: Sourab Gupta sourab.gu...@intel.com Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_dma.c| 1 + drivers/gpu/drm/i915/i915_drv.c| 2 + drivers/gpu/drm/i915/i915_drv.h| 18 ++ drivers/gpu/drm/i915/i915_gem.c| 115 +++ drivers/gpu/drm/i915/i915_gem_debug.c | 366 + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 + drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 107 ++ 8 files changed, 612 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f676f9..7d599f1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1984,6 +1984,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file-driver_priv; + kfree(file_priv-process_name); if (file_priv file_priv-bsd_ring) file_priv-bsd_ring = NULL; kfree(file_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01de977..1c4cd6d7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1527,6 +1527,8 @@ static struct drm_driver driver = { .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, #endif + .gem_open_object = i915_gem_open_object, + .gem_close_object = i915_gem_close_object, .gem_free_object = i915_gem_free_object, .gem_vm_ops = i915_gem_vm_ops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 541fb6f..ccb3db3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1846,6 +1846,12 @@ struct drm_i915_gem_object { struct work_struct *work; } userptr; }; + +#define MAX_OPEN_HANDLE 20 + struct { + pid_t pid; + int open_handle_count; + } pid_array[MAX_OPEN_HANDLE]; }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) @@ -1896,6 +1902,7 @@ struct drm_i915_gem_request { struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; + char *process_name; struct { spinlock_t lock; @@ -2325,6 +2332,10 @@ void i915_init_vm(struct drm_i915_private *dev_priv, struct i915_address_space *vm); void i915_gem_free_object(struct drm_gem_object *obj); void i915_gem_vma_destroy(struct i915_vma *vma); +int i915_gem_open_object(struct drm_gem_object *gem_obj, + struct drm_file *file_priv); +int i915_gem_close_object(struct drm_gem_object *gem_obj, + struct drm_file *file_priv); #define PIN_MAPPABLE 0x1 #define PIN_NONBLOCK 0x2 @@ -2375,6 +2386,7 @@ int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_mode_create_dumb *args); int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset); +int i915_gem_obj_shmem_pages_alloced(struct drm_i915_gem_object *obj); /** * Returns true if seq1 is later than seq2. */ @@ -2643,6 +2655,10 @@ int i915_verify_lists(struct drm_device *dev); #else #define i915_verify_lists(dev) 0 #endif +int i915_get_drm_clients_info(struct drm_i915_error_state_buf *m, +
Re: [Intel-gfx] [PATCH] drm/i915: Sysfs interface to get GFX shmem usage stats per process
On Thu, 14 Aug 2014, sourab.gu...@intel.com wrote: From: Sourab Gupta sourab.gu...@intel.com Currently the Graphics Driver provides an interface through which one can get a snapshot of the overall Graphics memory consumption. Also there is an interface available, which provides information about the several memory related attributes of every single Graphics buffer created by the various clients. There is a requirement of a new interface for achieving below functionalities: 1) Need to provide Client based detailed information about the distribution of Graphics memory 2) Need to provide an interface which can provide info about the sharing of Graphics buffers between the clients. The client based interface would also aid in debugging of memory usage/consumption by each client debug memleak related issues. With this new interface, 1) In case of memleak scenarios, we can easily zero in on the culprit client which is unexpectedly holding on the Graphics buffers for an inordinate amount of time. 2) We can get an estimate of the instantaneous memory footprint of every Graphics client. 3) We can now trace all the processes sharing a particular Graphics buffer. By means of this patch we try to provide a sysfs interface to achieve the mentioned functionalities. There are two files created in sysfs: 'i915_gem_meminfo' will provide summary of the graphics resources used by each graphics client. 'i915_gem_objinfo' will provide detailed view of each object created by individual clients. Why sysfs instead of debugfs? Please run your patch through checkpatch and fix the issues before sending v2. BR, Jani. Signed-off-by: Sourab Gupta sourab.gu...@intel.com Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_dma.c| 1 + drivers/gpu/drm/i915/i915_drv.c| 2 + drivers/gpu/drm/i915/i915_drv.h| 18 ++ drivers/gpu/drm/i915/i915_gem.c| 115 +++ drivers/gpu/drm/i915/i915_gem_debug.c | 366 + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 + drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 107 ++ 8 files changed, 612 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f676f9..7d599f1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1984,6 +1984,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file-driver_priv; + kfree(file_priv-process_name); if (file_priv file_priv-bsd_ring) file_priv-bsd_ring = NULL; kfree(file_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01de977..1c4cd6d7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1527,6 +1527,8 @@ static struct drm_driver driver = { .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, #endif + .gem_open_object = i915_gem_open_object, + .gem_close_object = i915_gem_close_object, .gem_free_object = i915_gem_free_object, .gem_vm_ops = i915_gem_vm_ops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 541fb6f..ccb3db3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1846,6 +1846,12 @@ struct drm_i915_gem_object { struct work_struct *work; } userptr; }; + +#define MAX_OPEN_HANDLE 20 + struct { + pid_t pid; + int open_handle_count; + } pid_array[MAX_OPEN_HANDLE]; }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) @@ -1896,6 +1902,7 @@ struct drm_i915_gem_request { struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; + char *process_name; struct { spinlock_t lock; @@ -2325,6 +2332,10 @@ void i915_init_vm(struct drm_i915_private *dev_priv, struct i915_address_space *vm); void i915_gem_free_object(struct drm_gem_object *obj); void i915_gem_vma_destroy(struct i915_vma *vma); +int i915_gem_open_object(struct drm_gem_object *gem_obj, + struct drm_file *file_priv); +int i915_gem_close_object(struct drm_gem_object *gem_obj, + struct drm_file *file_priv); #define PIN_MAPPABLE 0x1 #define PIN_NONBLOCK 0x2 @@ -2375,6 +2386,7 @@ int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_mode_create_dumb *args); int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset); +int i915_gem_obj_shmem_pages_alloced(struct drm_i915_gem_object *obj); /** * Returns true if seq1 is later
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Created common handler for platform specific suspend/resume
On Thu, Aug 14, 2014 at 02:51:15PM +0300, Imre Deak wrote: On Wed, 2014-08-13 at 23:07 +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this change, intel_runtime_suspend and intel_runtime_resume functions become completely platform agnostic. Platform specific suspend/resume changes are moved to intel_suspend_complete and intel_resume_prepare. Cc: Imre Deak imre.d...@intel.com Cc: Paulo Zanoni paulo.r.zan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: Goel, Akash akash.g...@intel.com For the future: it's not necessary to CC the above people, they all read the mailing list anyway. Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com Both patches look fine to me: Reviewed-by: Imre Deak imre.d...@intel.com Both merged to dinq (soix for byt sounds like a new feature), thanks. -Daniel --- drivers/gpu/drm/i915/i915_drv.c | 76 ++--- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ec96f9a..88464ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -494,6 +494,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return true; } + +static int intel_suspend_complete(struct drm_i915_private *dev_priv); +static int intel_resume_prepare(struct drm_i915_private *dev_priv); + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; @@ -983,14 +987,14 @@ static int i915_pm_poweroff(struct device *dev) return i915_drm_freeze(drm_dev); } -static int hsw_runtime_suspend(struct drm_i915_private *dev_priv) +static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); return 0; } -static int snb_runtime_resume(struct drm_i915_private *dev_priv) +static int snb_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv-dev; @@ -999,7 +1003,7 @@ static int snb_runtime_resume(struct drm_i915_private *dev_priv) return 0; } -static int hsw_runtime_resume(struct drm_i915_private *dev_priv) +static int hsw_resume_prepare(struct drm_i915_private *dev_priv) { hsw_disable_pc8(dev_priv); @@ -1295,7 +1299,7 @@ static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); } -static int vlv_runtime_suspend(struct drm_i915_private *dev_priv) +static int vlv_suspend_complete(struct drm_i915_private *dev_priv) { u32 mask; int err; @@ -1335,7 +1339,7 @@ err1: return err; } -static int vlv_runtime_resume(struct drm_i915_private *dev_priv) +static int vlv_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv-dev; int err; @@ -1413,17 +1417,7 @@ static int intel_runtime_suspend(struct device *device) cancel_work_sync(dev_priv-rps.work); intel_runtime_pm_disable_interrupts(dev); - if (IS_GEN6(dev)) { - ret = 0; - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_suspend(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_suspend(dev_priv); - } else { - ret = -ENODEV; - WARN_ON(1); - } - + ret = intel_suspend_complete(dev_priv); if (ret) { DRM_ERROR(Runtime suspend failed, disabling it (%d)\n, ret); intel_runtime_pm_restore_interrupts(dev); @@ -1461,17 +1455,7 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv-pm.suspended = false; - if (IS_GEN6(dev)) { - ret = snb_runtime_resume(dev_priv); - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_resume(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_resume(dev_priv); - } else { - WARN_ON(1); - ret = -ENODEV; - } - + ret = intel_resume_prepare(dev_priv); /* * No point of rolling back things in case of an error, as the best * we can do is to hope that things will still work (and disable RPM). @@ -1490,6 +1474,44 @@ static int intel_runtime_resume(struct device *device) return ret; } +static int intel_suspend_complete(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv-dev; + int ret; + + if (IS_GEN6(dev)) { + ret = 0; + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = hsw_suspend_complete(dev_priv); + } else if (IS_VALLEYVIEW(dev)) { + ret = vlv_suspend_complete(dev_priv); + }
Re: [Intel-gfx] [PATCH] drm/i915: Sysfs interface to get GFX shmem usage stats per process
On Thu, 2014-08-14 at 16:50 +0300, Jani Nikula wrote: On Thu, 14 Aug 2014, sourab.gu...@intel.com wrote: From: Sourab Gupta sourab.gu...@intel.com Currently the Graphics Driver provides an interface through which one can get a snapshot of the overall Graphics memory consumption. Also there is an interface available, which provides information about the several memory related attributes of every single Graphics buffer created by the various clients. There is a requirement of a new interface for achieving below functionalities: 1) Need to provide Client based detailed information about the distribution of Graphics memory 2) Need to provide an interface which can provide info about the sharing of Graphics buffers between the clients. The client based interface would also aid in debugging of memory usage/consumption by each client debug memleak related issues. With this new interface, 1) In case of memleak scenarios, we can easily zero in on the culprit client which is unexpectedly holding on the Graphics buffers for an inordinate amount of time. 2) We can get an estimate of the instantaneous memory footprint of every Graphics client. 3) We can now trace all the processes sharing a particular Graphics buffer. By means of this patch we try to provide a sysfs interface to achieve the mentioned functionalities. There are two files created in sysfs: 'i915_gem_meminfo' will provide summary of the graphics resources used by each graphics client. 'i915_gem_objinfo' will provide detailed view of each object created by individual clients. Why sysfs instead of debugfs? Actually our understanding is that debugfs interface may not be available in the production kernel by default. But sysfs interface will be there always. The same case is there for 'error_state', its made available through syfs also apart from debugfs. If the approach is fine, will export this interface from debugfs also in the subsequent patch. Probably there would be some user space utility developed (like 'ps' or 'procrank' in Android) which will avail this interface to analyze GFX memory consumption. Please run your patch through checkpatch and fix the issues before sending v2. Fine, will fix the errors reported by checkpatch in the next version. Best regards Akash BR, Jani. Signed-off-by: Sourab Gupta sourab.gu...@intel.com Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_dma.c| 1 + drivers/gpu/drm/i915/i915_drv.c| 2 + drivers/gpu/drm/i915/i915_drv.h| 18 ++ drivers/gpu/drm/i915/i915_gem.c| 115 +++ drivers/gpu/drm/i915/i915_gem_debug.c | 366 + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 + drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 107 ++ 8 files changed, 612 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f676f9..7d599f1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1984,6 +1984,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file-driver_priv; + kfree(file_priv-process_name); if (file_priv file_priv-bsd_ring) file_priv-bsd_ring = NULL; kfree(file_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01de977..1c4cd6d7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1527,6 +1527,8 @@ static struct drm_driver driver = { .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, #endif + .gem_open_object = i915_gem_open_object, + .gem_close_object = i915_gem_close_object, .gem_free_object = i915_gem_free_object, .gem_vm_ops = i915_gem_vm_ops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 541fb6f..ccb3db3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1846,6 +1846,12 @@ struct drm_i915_gem_object { struct work_struct *work; } userptr; }; + +#define MAX_OPEN_HANDLE 20 + struct { + pid_t pid; + int open_handle_count; + } pid_array[MAX_OPEN_HANDLE]; }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) @@ -1896,6 +1902,7 @@ struct drm_i915_gem_request { struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; + char *process_name; struct { spinlock_t lock; @@ -2325,6 +2332,10 @@ void i915_init_vm(struct drm_i915_private *dev_priv, struct i915_address_space *vm); void i915_gem_free_object(struct
Re: [Intel-gfx] BUG_ON vs WARN_ON (was: Re: [PATCH] drm/i915: Localise the fbdev console lock frobbing)
On Thu, Aug 14, 2014 at 01:07:06PM +0300, Jani Nikula wrote: On Thu, 14 Aug 2014, Daniel Vetter dan...@ffwll.ch wrote: On Thu, Aug 14, 2014 at 8:54 AM, Chris Wilson ch...@chris-wilson.co.uk wrote: I disaggree with the conversion of the BUG_ON though, a WARN there is going to screw up unpredictably (well, a hard hang without any output is the predictable outcome). I'd like to have asserts for things that could and should be statically analyzed... Well I've put a zero-tolerance rule for BUG_ON into place with the only exception if the kernel will die anyway in the next few lines. Which means I trade in a limping (and potentially dangerous) kernel for the ability to be able to read the backtrace somewhere. I agree that any such extreme policy will end up looking stupid in some cases, but I've just decided that I wasted too much time on chasing lookups which would have been trivial to debug with a WARN_ON instead of a BUG_ON. Until I've wasted too much time with WARN_ON instead of BUG_ON I'll let it stick. And it's supported by my patch scripts, so small chance I'll miss one. Ofc I'll never change it without a notice in the commit message, so people can always blame me for it. In other words, WARN_ON is the new BUG_ON. But what's the new WARN_ON? Now we're conflating two things (limp home mode and crashing) into one. When I see WARN_ON in code, it's no longer clear to me whether this is a condition that we're supposed to survive or not. For example, does the code below a WARN_ON need to properly handle errors due to the condition? To me, BUG_ON is a code reading aide that sets the absolute precondition for the following code. Something that absolutely must be fixed if someone hits it, while WARN_ON can sometimes be ignored, or even replaced with DRM_DEBUG. WARN_ON is what userspace hackers usually put into asserts - pre/post conditions and invariants and stuff like that worth checking but not part of the main logic. Occasionally it makes sense to have special logic in a WARN_ON (e.g. when a refcount overflows it's better to leak it), but usually not worth it. A WARN_ON should never be on a level with DRM_DEBUG, but perhaps a DRM_ERROR is more adequate if the backtrace is useless. If we have zero-tolerance for BUG_ON, and replace all of those with WARN_ON, we'll need to start being *very* selective about adding WARN_ON as well. My rule of thumb for letting a BUG_ON survive is if I can see the kernel Oopsing in the diff context, it stays. I don't see why that suddenly means we have to sprinkle less of them, or of WARN_ONs. So maybe you need to elaborate on your concern here a bit? Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] linux: Automatically ShareVTs if the VT are already in graphics mode
On Thu, Aug 14, 2014 at 11:36:11AM +0100, Chris Wilson wrote: On Wed, Aug 13, 2014 at 10:58:54AM +0100, Chris Wilson wrote: If the VT we are using is already in KD_GRAPHICS mode, calling SETACTIVE will silently fail. This leads to an indefinite hang as WAITACTIVE never returns causing lockups on boot. This issue becomes apparent when the kernel driver does not install a fbdev for kernel to use for consoles and plymouth leaves the VT in graphics mode. It stops the hang on boot, but it also leaves process control on the defunct VT (i.e. ^C kills Xorg). Can we do the console switch without WAITACTIVE? Also doesn't explain why it works the second time. So this is the comment from the clueless guy who created this mess, but I've thought the entire point of the dummy console (which should still be there) is that all the VT switching still works as if there's a real console. At least my minimal testing with a few X servers seemed to indicate that that still worked ... Or did you manage to get rid of the dummy console, too? That would be a bug in the Kconfig logic we currently have. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2] drm/i915: Don't warn if we restore pm interrupts during reset
On Thu, Aug 14, 2014 at 03:46:43PM +0300, Mika Kuoppala wrote: We lost the software state tracking due to reset, so don't complain if it doesn't match. This sounds more like gpu reset should be a bit more careful (even more careful than we already are compared to earlier kernels) with making sure the irq state is still sane after a reset? Or what exactly is the failure mode here? The commit message lacks a bit details in form of a nice text or even better: A testcase ;-) Thanks, Daniel v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Sysfs interface to get GFX shmem usage stats per process
On Thu, Aug 14, 2014 at 04:50:19PM +0300, Jani Nikula wrote: On Thu, 14 Aug 2014, sourab.gu...@intel.com wrote: From: Sourab Gupta sourab.gu...@intel.com Currently the Graphics Driver provides an interface through which one can get a snapshot of the overall Graphics memory consumption. Also there is an interface available, which provides information about the several memory related attributes of every single Graphics buffer created by the various clients. There is a requirement of a new interface for achieving below functionalities: 1) Need to provide Client based detailed information about the distribution of Graphics memory 2) Need to provide an interface which can provide info about the sharing of Graphics buffers between the clients. The client based interface would also aid in debugging of memory usage/consumption by each client debug memleak related issues. With this new interface, 1) In case of memleak scenarios, we can easily zero in on the culprit client which is unexpectedly holding on the Graphics buffers for an inordinate amount of time. 2) We can get an estimate of the instantaneous memory footprint of every Graphics client. 3) We can now trace all the processes sharing a particular Graphics buffer. By means of this patch we try to provide a sysfs interface to achieve the mentioned functionalities. There are two files created in sysfs: 'i915_gem_meminfo' will provide summary of the graphics resources used by each graphics client. 'i915_gem_objinfo' will provide detailed view of each object created by individual clients. Why sysfs instead of debugfs? Please run your patch through checkpatch and fix the issues before sending v2. There's the general issue really that currently gem memory isn't accounted at all correctly. So I think if we want this for production usage (i.e. a real interface as you propose it here for sysfs) and not just something in debugfs, then I think we need to look at the entire picture. So not just a way to see how much gem/shmem memory is used, but also a way to limit it. And preferrably integrated into the core mm tracking. No, I haven't thought through the details yet - we might need to sit together with some core mm hackers for that. -Daniel BR, Jani. Signed-off-by: Sourab Gupta sourab.gu...@intel.com Signed-off-by: Akash Goel akash.g...@intel.com --- drivers/gpu/drm/i915/i915_dma.c| 1 + drivers/gpu/drm/i915/i915_drv.c| 2 + drivers/gpu/drm/i915/i915_drv.h| 18 ++ drivers/gpu/drm/i915/i915_gem.c| 115 +++ drivers/gpu/drm/i915/i915_gem_debug.c | 366 + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 + drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 107 ++ 8 files changed, 612 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f676f9..7d599f1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1984,6 +1984,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file-driver_priv; + kfree(file_priv-process_name); if (file_priv file_priv-bsd_ring) file_priv-bsd_ring = NULL; kfree(file_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01de977..1c4cd6d7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1527,6 +1527,8 @@ static struct drm_driver driver = { .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, #endif + .gem_open_object = i915_gem_open_object, + .gem_close_object = i915_gem_close_object, .gem_free_object = i915_gem_free_object, .gem_vm_ops = i915_gem_vm_ops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 541fb6f..ccb3db3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1846,6 +1846,12 @@ struct drm_i915_gem_object { struct work_struct *work; } userptr; }; + +#define MAX_OPEN_HANDLE 20 + struct { + pid_t pid; + int open_handle_count; + } pid_array[MAX_OPEN_HANDLE]; }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) @@ -1896,6 +1902,7 @@ struct drm_i915_gem_request { struct drm_i915_file_private { struct drm_i915_private *dev_priv; struct drm_file *file; + char *process_name; struct { spinlock_t lock; @@ -2325,6 +2332,10 @@ void i915_init_vm(struct drm_i915_private *dev_priv, struct i915_address_space *vm); void i915_gem_free_object(struct drm_gem_object *obj); void
Re: [Intel-gfx] [PATCH 4/6] drm/i915: Added support to allow change in FB pitch across flips
On Thu, Aug 14, 2014 at 02:54:25PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com This patch removes the check for change in pitch of frame buffer across page flips. Since there is a support for MMIO based page flips, we can update the plane registers to update the FB pitch accordingly the offsets in LINOFF/TILEOFF registers. The plane registers are updated atomically, using the mechanism used for Sprite planes update. Doing so also requires deferring of MMIO flip, if issued in interrupt context. Signed-off-by: Akash Goel akash.g...@intel.com Signed-off-by: Pallavi Gpallav...@intel.com This looks like a separate patch from the overall work in this series. It definitely needs an i-g-t testcase, preferrably one to check that the update is indeed atomic. -Daniel --- drivers/gpu/drm/i915/intel_display.c | 51 +--- drivers/gpu/drm/i915/intel_drv.h | 5 drivers/gpu/drm/i915/intel_sprite.c | 4 +-- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 47a5424..a75d1a0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9542,6 +9542,29 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, return ring != obj-ring; } +static void intel_mmio_flip_work_fn(struct work_struct *work) +{ + struct intel_mmio_flip *mmio_flip = + container_of(work, struct intel_mmio_flip, work); + struct intel_crtc *intel_crtc = + container_of(mmio_flip, struct intel_crtc, mmio_flip); + struct drm_device *dev = intel_crtc-base.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_crtc *crtc = intel_crtc-base; + u32 start_vbl_count; + bool atomic_update; + + atomic_update = intel_pipe_update_start(intel_crtc, start_vbl_count); + + intel_mark_page_flip_active(intel_crtc); + + dev_priv-display.update_primary_plane(crtc, crtc-primary-fb, + crtc-x, crtc-y); + + if (atomic_update) + intel_pipe_update_end(intel_crtc, start_vbl_count); +} + static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc-base.dev; @@ -9552,6 +9575,17 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) u32 dspcntr; u32 reg; + /* if we are in interrupt context and there is a need to update +all the plane registers (atomically), then defer the flip to +a process context, as we can then wait for the next vblank boundary */ + if (intel_crtc-unpin_work-update_all_plane_reg) { + if (in_atomic()) + schedule_work(intel_crtc-mmio_flip.work); + else + intel_mmio_flip_work_fn(intel_crtc-mmio_flip.work); + return; + } + intel_mark_page_flip_active(intel_crtc); reg = DSPCNTR(intel_crtc-plane); @@ -9685,6 +9719,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct intel_unpin_work *work; struct intel_engine_cs *ring; unsigned long flags; + bool update_all_plane_reg = 0; int ret; /* @@ -9706,7 +9741,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (INTEL_INFO(dev)-gen 3 (fb-offsets[0] != crtc-primary-fb-offsets[0] || fb-pitches[0] != crtc-primary-fb-pitches[0])) - return -EINVAL; + update_all_plane_reg = 1; if (i915_terminally_wedged(dev_priv-gpu_error)) goto out_hang; @@ -9718,6 +9753,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work-event = event; work-crtc = crtc; work-old_fb_obj = intel_fb_obj(old_fb); + work-update_all_plane_reg = update_all_plane_reg; INIT_WORK(work-work, intel_unpin_work_fn); ret = drm_crtc_vblank_get(crtc); @@ -9785,9 +9821,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (use_mmio_flip(ring, obj)) ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring, page_flip_flags); - else - ret = dev_priv-display.queue_flip(dev, crtc, fb, obj, ring, - page_flip_flags); + else { + if (update_all_plane_reg) + ret = -EINVAL; + else + ret = dev_priv-display.queue_flip(dev, crtc, fb, obj, ring, + page_flip_flags); + } + if (ret) goto cleanup_unpin; @@ -11912,6 +11953,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc-cursor_cntl = ~0; intel_crtc-cursor_size = ~0; + INIT_WORK(intel_crtc-mmio_flip.work,
Re: [Intel-gfx] [PATCH 1/4] drm/i915: Don't try to enable cursor from setplane when crtc is disabled
On Tue, 12 Aug 2014, Paulo Zanoni przan...@gmail.com wrote: 2014-08-12 13:39 GMT-03:00 ville.syrj...@linux.intel.com: From: Ville Syrjälä ville.syrj...@linux.intel.com Make sure the cursor gets fully clipped when enabling it on a disabled crtc via setplane. This will prevent the lower level code from attempting to enable the cursor in hardware. If this is going to replace part of the fix I recently submitted, it needs Cc: sta...@vger.kernel.org. Picked this up for -fixes. BR, Jani. I briefly smoke-tested it and it appears to properly replace the intel_crtc-active early return which you pointed. Cc: Paulo Zanoni przan...@gmail.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 511c8f4..123cbf1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11701,8 +11701,8 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, }; const struct drm_rect clip = { /* integer pixels */ - .x2 = intel_crtc-config.pipe_src_w, - .y2 = intel_crtc-config.pipe_src_h, + .x2 = intel_crtc-active ? intel_crtc-config.pipe_src_w : 0, + .y2 = intel_crtc-active ? intel_crtc-config.pipe_src_h : 0, }; bool visible; int ret; -- 1.8.5.5 -- Paulo Zanoni ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Fix locking for intel_enable_pipe_a()
On Mon, 11 Aug 2014, Daniel Vetter dan...@ffwll.ch wrote: On Mon, Aug 11, 2014 at 01:15:35PM +0300, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com intel_enable_pipe_a() gets called with all the modeset locks already held (by drm_modeset_lock_all()), so trying to grab the same locks using another drm_modeset_acquire_ctx is going to fail miserably. Move most of the drm_modeset_acquire_ctx handling (init/drop/fini) out from intel_{get,release}_load_detect_pipe() into the callers (intel_{crt,tv}_detect()). Only the actual locking and backoff handling is left in intel_get_load_detect_pipe(). And in intel_enable_pipe_a() we just share the mode_config.acquire_ctx from drm_modeset_lock_all() which is already holding all the relevant locks. It's perfectly legal to lock the same ww_mutex multiple times using the same ww_acquire_ctx. drm_modeset_lock() will convert the returned -EALREADY into 0, so the caller doesn't need to do antyhing special. Fixes a hang on resume on my 830. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch Cc: sta...@vger.kernel.org (for 3.16) Both patches picked up for -fixes, thanks for the patches and review. BR, Jani. --- drivers/gpu/drm/i915/intel_crt.c | 7 ++- drivers/gpu/drm/i915/intel_display.c | 21 - drivers/gpu/drm/i915/intel_drv.h | 3 +-- drivers/gpu/drm/i915/intel_tv.c | 7 ++- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 2efaf8e..e8abfce 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -699,16 +699,21 @@ intel_crt_detect(struct drm_connector *connector, bool force) goto out; } +drm_modeset_acquire_init(ctx, 0); + /* for pre-945g platforms use load detect */ if (intel_get_load_detect_pipe(connector, NULL, tmp, ctx)) { if (intel_crt_detect_ddc(connector)) status = connector_status_connected; else status = intel_crt_load_detect(crt); -intel_release_load_detect_pipe(connector, tmp, ctx); +intel_release_load_detect_pipe(connector, tmp); } else status = connector_status_unknown; +drm_modeset_drop_locks(ctx); +drm_modeset_acquire_fini(ctx); + out: intel_display_power_put(dev_priv, power_domain); return status; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 51f48d9..7953b46 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8440,8 +8440,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, connector-base.id, connector-name, encoder-base.id, encoder-name); -drm_modeset_acquire_init(ctx, 0); - retry: ret = drm_modeset_lock(config-connection_mutex, ctx); if (ret) @@ -8552,15 +8550,11 @@ fail_unlock: goto retry; } -drm_modeset_drop_locks(ctx); -drm_modeset_acquire_fini(ctx); - return false; } void intel_release_load_detect_pipe(struct drm_connector *connector, -struct intel_load_detect_pipe *old, -struct drm_modeset_acquire_ctx *ctx) +struct intel_load_detect_pipe *old) { struct intel_encoder *intel_encoder = intel_attached_encoder(connector); @@ -8584,17 +8578,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, drm_framebuffer_unreference(old-release_fb); } -goto unlock; return; } /* Switch crtc and encoder back off if necessary */ if (old-dpms_mode != DRM_MODE_DPMS_ON) connector-funcs-dpms(connector, old-dpms_mode); - -unlock: -drm_modeset_drop_locks(ctx); -drm_modeset_acquire_fini(ctx); } static int i9xx_pll_refclk(struct drm_device *dev, @@ -12652,7 +12641,7 @@ static void intel_enable_pipe_a(struct drm_device *dev) struct intel_connector *connector; struct drm_connector *crt = NULL; struct intel_load_detect_pipe load_detect_temp; -struct drm_modeset_acquire_ctx ctx; +struct drm_modeset_acquire_ctx *ctx = dev-mode_config.acquire_ctx; /* We can't just switch on the pipe A, we need to set things up with a * proper mode and output configuration. As a gross hack, enable pipe A @@ -12669,10 +12658,8 @@ static void intel_enable_pipe_a(struct drm_device *dev) if (!crt) return; -if (intel_get_load_detect_pipe(crt, NULL, load_detect_temp, ctx)) -intel_release_load_detect_pipe(crt, load_detect_temp, ctx); - - +
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 02:54:27PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com + /* Check if the current FB is compatible with new requested +Pipesrc values by the User */ + if (new_width fb-width || + new_height fb-height || + crtc-x fb-width - new_width || + crtc-y fb-height - new_height) { + DRM_DEBUG_KMS(New Pipe Src values %dx%d is incompatible with current fb size viewport %ux%u+%d+%d\n, + new_width, new_height, fb-width, fb-height, crtc-x, crtc-y); + return -EINVAL; + } I think this part here is the achilles heel of your approach. Right now we use crtc-mode.hdisplay/vdisplay in a lot of places both in i915 and the drm core to make sure that the primary plane fb, sprite fb and positioning and cursor placement all make sense. If my understanding of the pipe src rectangle is correct (please correct me if I'm wrong) we should switch _all_ these checks to instead look at the new crtc_w/h field. Even worse that we need to change drm core code and as a result of that all drm drivers. Awful lot of code to check, test and for i915 validate with i-g-t testcases. Now the solution thus far (for the normal panel fitter operation) is that the logical input mode for the crtc ends up in crtc-config.mode and as a copy in crtc-mode. And the actual output mode is in crtc-config.adjusted_mode. Our modeset code already takes care of copying crtc-config.mode to crtc-mode, so we only need to concern ourselfs with crtc-config.mode. If we'd copy the pipe_src_w/h values back into it the existing code would still be able to check all the sprite/cursor/fb constraints. So the flow on a modeset (and that's what we'll end up calling from the set_property function too) is: 1. Userspace requested mode goes into pipe_config-mode. 2. We make a copy into pipe_config-adjusted_mode and frob it more. 3. crtc compute_config code notices the special pipe src window, and adjusts pipe_config-mode plus computes the panel fitter configuration. If all that checks out we continue with the modeset sequence. 4. We store the new pipe_config into crtc-config. 5. Actual hw register writes for the modeset change happens. 6. We copy crtc-config.mode into crtc-mode so that drm core and helper functions can validate fb/sprite/cursors again. The result would be that the set_property function here would do _no_ argument checking, but would instead fully rely upon the modeset sequence to compute the desired configuration. And if it fails it would restore the old configuration like you already do. Now test coverage: I think we need a few i-g-ts that provoke this, i.e. which set the pipe_src != requested mode and then place cursor/sprite/fb to validate that the checking is still correct. Aside: In the shiny new world of atomic display updates we always need to have similar procedures i.e. 1. Store state without much checking. 2. Run full modeset machinery to compute the new resulting state. 3. Check that, and only if that checks out, commit it. If we duplicate special cases of these checks all over, then we'll have an unmaintainable mess in shorter order. C.f. compare the discussion about rotation properties. Thoughts, better ideas and issues with this plan? Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2] drm/i915: Don't warn if we restore pm interrupts during reset
On Thu, Aug 14, 2014 at 04:23:16PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 03:46:43PM +0300, Mika Kuoppala wrote: We lost the software state tracking due to reset, so don't complain if it doesn't match. This sounds more like gpu reset should be a bit more careful (even more careful than we already are compared to earlier kernels) with making sure the irq state is still sane after a reset? Or what exactly is the failure mode here? The commit message lacks a bit details in form of a nice text or even better: A testcase ;-) Killing the hpd irq and gt_powersave junk from i915_reset() would be my suggestion here. I don't even know why the hpd stuff is still there, we removed all the other irq frobbery from there a while back. And last I looked gpu reset didn't affect the rc6/rps stuff either, though more testing should be done to make sure I didn't just imagine it. Thanks, Daniel v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/5] drm/i915: Do not access stolen memory directly by the CPU, even for error capture
Chris Wilson ch...@chris-wilson.co.uk writes: For stolen pages, since it is verboten to access them directly on many architectures, we have to read them through the GTT aperture. If they are not accessible through the aperture, then we have to abort. This was complicated by commit 8b6124a633d8095b0c8364f585edff9c59568a96 Author: Chris Wilson ch...@chris-wilson.co.uk Date: Thu Jan 30 14:38:16 2014 + drm/i915: Don't access snooped pages through the GTT (even for error capture) and the desire to use stolen memory for ringbuffers, contexts and batches in the future. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gpu_error.c | 50 ++- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 35e70d5..6d280c07 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -561,10 +561,11 @@ static struct drm_i915_error_object * i915_error_object_create_sized(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *src, struct i915_address_space *vm, -const int num_pages) +int num_pages) { struct drm_i915_error_object *dst; - int i; + bool use_ggtt; + int i = 0; u32 reloc_offset; if (src == NULL || src-pages == NULL) @@ -574,8 +575,32 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, if (dst == NULL) return NULL; - reloc_offset = dst-gtt_offset = i915_gem_obj_offset(src, vm); - for (i = 0; i num_pages; i++) { + dst-gtt_offset = i915_gem_obj_offset(src, vm); + + reloc_offset = dst-gtt_offset; + use_ggtt = (src-cache_level == I915_CACHE_NONE + i915_is_ggtt(vm) + src-has_global_gtt_mapping + reloc_offset + num_pages * PAGE_SIZE = dev_priv-gtt.mappable_end); + + /* Cannot access stolen address directly, try to use the aperture */ + if (src-stolen) { + use_ggtt = true; + + if (!src-has_global_gtt_mapping) + goto unwind; + + reloc_offset = i915_gem_obj_ggtt_offset(src); + if (reloc_offset + num_pages * PAGE_SIZE dev_priv-gtt.mappable_end) + goto unwind; + } + + /* Cannot access snooped pages through the aperture */ + if (use_ggtt src-cache_level != I915_CACHE_NONE !HAS_LLC(dev_priv-dev)) + goto unwind; Why do we need to bail out if we dont have LLC ? + dst-page_count = num_pages; + while (num_pages--) { unsigned long flags; void *d; @@ -584,10 +609,7 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, goto unwind; local_irq_save(flags); - if (src-cache_level == I915_CACHE_NONE - reloc_offset dev_priv-gtt.mappable_end - src-has_global_gtt_mapping - i915_is_ggtt(vm)) { + if (use_ggtt) { void __iomem *s; /* Simply ignore tiling or any overlapping fence. @@ -599,14 +621,6 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, reloc_offset); memcpy_fromio(d, s, PAGE_SIZE); io_mapping_unmap_atomic(s); - } else if (src-stolen) { - unsigned long offset; - - offset = dev_priv-mm.stolen_base; - offset += src-stolen-start; - offset += i PAGE_SHIFT; - - memcpy_fromio(d, (void __iomem *) offset, PAGE_SIZE); } else { struct page *page; void *s; @@ -623,11 +637,9 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, } local_irq_restore(flags); - dst-pages[i] = d; - + dst-pages[i++] = d; reloc_offset += PAGE_SIZE; } - dst-page_count = num_pages; return dst; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2] drm/i915: Don't warn if we restore pm interrupts during reset
On Thu, Aug 14, 2014 at 05:45:59PM +0300, Ville Syrjälä wrote: On Thu, Aug 14, 2014 at 04:23:16PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 03:46:43PM +0300, Mika Kuoppala wrote: We lost the software state tracking due to reset, so don't complain if it doesn't match. This sounds more like gpu reset should be a bit more careful (even more careful than we already are compared to earlier kernels) with making sure the irq state is still sane after a reset? Or what exactly is the failure mode here? The commit message lacks a bit details in form of a nice text or even better: A testcase ;-) Killing the hpd irq and gt_powersave junk from i915_reset() would be my suggestion here. I don't even know why the hpd stuff is still there, we removed all the other irq frobbery from there a while back. And last I looked gpu reset didn't affect the rc6/rps stuff either, though more testing should be done to make sure I didn't just imagine it. No idea why the hpd_init is still in there. Could be a merge artifcat with removing the irq handling in one patch and adding hpd_init in another. I guess we could ditch it. The PM irq stuff is a bit more tricky since the ring init resets them ... -Daniel Thanks, Daniel v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/5] drm/i915: Print captured bo for all VM in error state
On Thu, Aug 14, 2014 at 01:18:46PM +0300, Mika Kuoppala wrote: Chris Wilson ch...@chris-wilson.co.uk writes: On Wed, Aug 13, 2014 at 05:50:38PM +0300, Mika Kuoppala wrote: Chris Wilson ch...@chris-wilson.co.uk writes: The current error state harks back to the era of just a single VM. For full-ppgtt, we capture every bo on every VM. It behoves us to then print every bo for every VM, which we currently fail to do and so miss vital information in the error state. v2: Use the vma address rather than -1! Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Offsets can collide between different vm areas. If we add vm index also to the captured batchbuffer objects, we could print it part of the offset '%d:0x%x' that would easily identify vm and we would immediately see what vm was active on a ring. The offsets are printed out per-vm. You want to be more specific in your complaint. Based on earlier discussion, I think you just want to know the guilty vm. -Chris Yes. And it can be done as a follow up too. 1/5: Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com Queued for -next, thanks for the patch. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: fix plane/cursor handling when runtime suspended
From: Paulo Zanoni paulo.r.zan...@intel.com If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. We need to get runtime PM references to pin the objects, and to change the fences. The pin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named drm/i915: Don't try to enable cursor from setplane when crtc is disabled. v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 Cc: sta...@vger.kernel.org Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 27 +++ 1 file changed, 27 insertions(+) I talked with Daniel and we agreed to leave any possible fixes related with the unpin functions to separate patches, possibly requiring separate IGT test cases. diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3813526..17bc661 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2149,6 +2149,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, if (need_vtd_wa(dev) alignment 256 * 1024) alignment = 256 * 1024; + /* +* Global gtt pte registers are special registers which actually forward +* writes to a chunk of system memory. Which means that there is no risk +* that the register values disappear as soon as we call +* intel_runtime_pm_put(), so it is correct to wrap only the +* pin/unpin/fence and not more. +*/ + intel_runtime_pm_get(dev_priv); + dev_priv-mm.interruptible = false; ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); if (ret) @@ -2166,12 +2175,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, i915_gem_object_pin_fence(obj); dev_priv-mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return 0; err_unpin: i915_gem_object_unpin_from_display_plane(obj); err_interruptible: dev_priv-mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return ret; } @@ -8201,6 +8212,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, uint32_t width, uint32_t height) { struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc-pipe; unsigned old_width, stride; @@ -8231,6 +8243,16 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(dev-struct_mutex); + + /* +* Global gtt pte registers are special registers which actually forward +* writes to a chunk of system memory. Which means that there is no risk +* that the register values disappear as soon as we call +* intel_runtime_pm_put(), so it is correct to wrap only the +* pin/unpin/fence and not more. +*/ + intel_runtime_pm_get(dev_priv); + if (!INTEL_INFO(dev)-cursor_needs_physical) { unsigned alignment; @@ -8280,6 +8302,10 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, i915_gem_track_fb(intel_crtc-cursor_bo, obj, INTEL_FRONTBUFFER_CURSOR(pipe)); + + if (obj) + intel_runtime_pm_put(dev_priv); + mutex_unlock(dev-struct_mutex); old_width = intel_crtc-cursor_width; @@ -8301,6 +8327,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, fail_unpin: i915_gem_object_unpin_from_display_plane(obj); fail_locked: + intel_runtime_pm_put(dev_priv); mutex_unlock(dev-struct_mutex); fail: drm_gem_object_unreference_unlocked(obj-base); -- 2.0.1 ___
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 04:42:01PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 02:54:27PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com + /* Check if the current FB is compatible with new requested + Pipesrc values by the User */ + if (new_width fb-width || + new_height fb-height || + crtc-x fb-width - new_width || + crtc-y fb-height - new_height) { + DRM_DEBUG_KMS(New Pipe Src values %dx%d is incompatible with current fb size viewport %ux%u+%d+%d\n, + new_width, new_height, fb-width, fb-height, crtc-x, crtc-y); + return -EINVAL; + } I think this part here is the achilles heel of your approach. Right now we use crtc-mode.hdisplay/vdisplay We don't use it in i915. If we do that's a bug. All the relevant places should be loooking at pipe_src_{w,h}. In the core the viewport check should be about the only place that cares about this stuff. in a lot of places both in i915 and the drm core to make sure that the primary plane fb, sprite fb and positioning and cursor placement all make sense. If my understanding of the pipe src rectangle is correct (please correct me if I'm wrong) we should switch _all_ these checks to instead look at the new crtc_w/h field. Even worse that we need to change drm core code and as a result of that all drm drivers. Awful lot of code to check, test and for i915 validate with i-g-t testcases. Now the solution thus far (for the normal panel fitter operation) is that the logical input mode for the crtc ends up in crtc-config.mode and as a copy in crtc-mode. And the actual output mode is in crtc-config.adjusted_mode. Our modeset code already takes care of copying crtc-config.mode to crtc-mode, so we only need to concern ourselfs with crtc-config.mode. If we'd copy the pipe_src_w/h values back into it the existing code would still be able to check all the sprite/cursor/fb constraints. So the flow on a modeset (and that's what we'll end up calling from the set_property function too) is: 1. Userspace requested mode goes into pipe_config-mode. 2. We make a copy into pipe_config-adjusted_mode and frob it more. 3. crtc compute_config code notices the special pipe src window, and adjusts pipe_config-mode plus computes the panel fitter configuration. If all that checks out we continue with the modeset sequence. 4. We store the new pipe_config into crtc-config. 5. Actual hw register writes for the modeset change happens. 6. We copy crtc-config.mode into crtc-mode so that drm core and helper functions can validate fb/sprite/cursors again. We shouldn't just magically change the user specified mode, we need it to stay intact for a subsequent modeset so that we can start the adjusted_mode frobbery fresh next time around. It also seems weird to report back a different mode to userspace than what the user provided. What you suggest was exactly the previous approach and I NAKed it. The result would be that the set_property function here would do _no_ argument checking, but would instead fully rely upon the modeset sequence to compute the desired configuration. We don't have sufficient checks in the modeset path. The drm_crtc_check_viewport() call is in drm_mode_setcrtc() which is too high up in the stack to affect modesets originating from property changes. That being said we should definitely use drm_crtc_check_viewport() here instead of hand rolling the exacty same thing in i915. And to avoid having to touch too much code, drm_crtc_check_viewport() should encapsulate the logic to fall back to mode-{h,v}display when crtc-{w,h} are zero. And if it fails it would restore the old configuration like you already do. Now test coverage: I think we need a few i-g-ts that provoke this, i.e. which set the pipe_src != requested mode and then place cursor/sprite/fb to validate that the checking is still correct. Aside: In the shiny new world of atomic display updates we always need to have similar procedures i.e. 1. Store state without much checking. 2. Run full modeset machinery to compute the new resulting state. 3. Check that, and only if that checks out, commit it. If we duplicate special cases of these checks all over, then we'll have an unmaintainable mess in shorter order. C.f. compare the discussion about rotation properties. Thoughts, better ideas and issues with this plan? Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org
Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer
-Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter Sent: Wednesday, August 13, 2014 4:16 PM To: Daniel, Thomas Cc: Daniel Vetter; intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer On Wed, Aug 13, 2014 at 01:34:15PM +, Daniel, Thomas wrote: -Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter Sent: Monday, August 11, 2014 3:21 PM To: Daniel, Thomas Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer On Mon, Aug 11, 2014 at 04:14:13PM +0200, Daniel Vetter wrote: On Thu, Jul 24, 2014 at 05:04:16PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com Any given ringbuffer is unequivocally tied to one context and one engine. By setting the appropriate pointers to them, the ringbuffer struct holds all the infromation you might need to submit a workload for processing, Execlists style. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c|2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c |2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h |3 +++ 3 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0a12b8c..2eb7db6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -132,6 +132,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return ret; } + ringbuf-ring = ring; + ringbuf-ctx = ctx; ringbuf-size = 32 * PAGE_SIZE; ringbuf-effective_size = ringbuf-size; ringbuf-head = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 01e9840..279dda4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1570,6 +1570,8 @@ static int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(ring-active_list); INIT_LIST_HEAD(ring-request_list); ringbuf-size = 32 * PAGE_SIZE; + ringbuf-ring = ring; + ringbuf-ctx = ring-default_context; That doesn't make a terribly lot of sense tbh. I fear it's one of these slight confusions which will take tons of patches to clean up. Why exactly do we need the ring-ctx pointer? If we only need this for lrc I want to name it accordingly, to make sure legacy code doesn't grow stupid ideas. And also we should only initialize this in the lrc ctx init then. All patches up to this one merged. Ok, I've discussed this quickly with Damien on irc. We decided to cut away the ring-ctx part of this patch for now to be able to move on. -Daniel As you've seen, removing ringbuffer-ctx causes serious problems with the plumbing later on. This can be renamed (perhaps to lrc) and removed from legacy init. Each ring buffer belongs to a specific context - it makes sense to me to keep this information within the ringbuffer structure so that we don't have to pass the context pointer around everywhere. I agree that it causes trouble with the follow-up patches, but I'm not sold on this being a terrible good idea. After all for ELSP we don't want to submit a ring, we want to submit the full context. So if the code that's supposed to do the execlist ctx submission only has the pointer to the ring object, the layer looks a bit wrong. When it comes to the execlist submission (actually as early as the execlist request queueing), the engine and context are indeed used and required. intel_logical_ring_advance_and_submit() is the lrc function analogous to __intel_ring_advance() and I believe the initial creation of intel_lrc.c was actually done by copying intel_ringbuffer.c. This explains why some of the lrc code is perhaps not as it would have been if this had been designed from scratch, and there is room for future improvement. advance_and_submit therefore only gets the ringbuffer struct and uses the context pointer in that struct to get the logical ring context itself. At that point the engine, context and new tail pointer are handed over to the execlist queue backend. Thomas. Same was iirc about the add_request part. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2] drm/i915: Don't warn if we restore pm interrupts during reset
Daniel Vetter dan...@ffwll.ch writes: On Thu, Aug 14, 2014 at 03:46:43PM +0300, Mika Kuoppala wrote: We lost the software state tracking due to reset, so don't complain if it doesn't match. This sounds more like gpu reset should be a bit more careful (even more careful than we already are compared to earlier kernels) with making sure the irq state is still sane after a reset? Or what exactly is the failure mode here? The commit message lacks a bit details in form of a nice text or even better: A testcase ;-) We have pm ref during reset. And then after reset, we kick intel_gt_reset_powersave to re-enable the rps. Countrary to suspend/thaw, we never disabled the interrupts. And the warn triggers. I tried to disable the interrupts during reset handling but the nonblocking __wait_seqno() triggered another state warning it was taking a pm ref during or right after reset recovery for hw access. -Mika Thanks, Daniel v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); -WARN_ON(dev_priv-rps.pm_iir); +if (!i915_reset_in_progress(dev_priv-gpu_error)) +WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); -WARN_ON(dev_priv-rps.pm_iir); +if (!i915_reset_in_progress(dev_priv-gpu_error)) +WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 06:06:58PM +0300, Ville Syrjälä wrote: On Thu, Aug 14, 2014 at 04:42:01PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 02:54:27PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com + /* Check if the current FB is compatible with new requested +Pipesrc values by the User */ + if (new_width fb-width || + new_height fb-height || + crtc-x fb-width - new_width || + crtc-y fb-height - new_height) { + DRM_DEBUG_KMS(New Pipe Src values %dx%d is incompatible with current fb size viewport %ux%u+%d+%d\n, + new_width, new_height, fb-width, fb-height, crtc-x, crtc-y); + return -EINVAL; + } I think this part here is the achilles heel of your approach. Right now we use crtc-mode.hdisplay/vdisplay We don't use it in i915. If we do that's a bug. All the relevant places should be loooking at pipe_src_{w,h}. In the core the viewport check should be about the only place that cares about this stuff. Well within i915, but not anywhere in the drm core or helper code since they're simply not aware of pipe_src_w/h. E.g. the plane helper code also uses crtc-mode.h/vdisplay. Changing that basic drm assumption is really invasive imo. in a lot of places both in i915 and the drm core to make sure that the primary plane fb, sprite fb and positioning and cursor placement all make sense. If my understanding of the pipe src rectangle is correct (please correct me if I'm wrong) we should switch _all_ these checks to instead look at the new crtc_w/h field. Even worse that we need to change drm core code and as a result of that all drm drivers. Awful lot of code to check, test and for i915 validate with i-g-t testcases. Now the solution thus far (for the normal panel fitter operation) is that the logical input mode for the crtc ends up in crtc-config.mode and as a copy in crtc-mode. And the actual output mode is in crtc-config.adjusted_mode. Our modeset code already takes care of copying crtc-config.mode to crtc-mode, so we only need to concern ourselfs with crtc-config.mode. If we'd copy the pipe_src_w/h values back into it the existing code would still be able to check all the sprite/cursor/fb constraints. So the flow on a modeset (and that's what we'll end up calling from the set_property function too) is: 1. Userspace requested mode goes into pipe_config-mode. 2. We make a copy into pipe_config-adjusted_mode and frob it more. 3. crtc compute_config code notices the special pipe src window, and adjusts pipe_config-mode plus computes the panel fitter configuration. If all that checks out we continue with the modeset sequence. 4. We store the new pipe_config into crtc-config. 5. Actual hw register writes for the modeset change happens. 6. We copy crtc-config.mode into crtc-mode so that drm core and helper functions can validate fb/sprite/cursors again. We shouldn't just magically change the user specified mode, we need it to stay intact for a subsequent modeset so that we can start the adjusted_mode frobbery fresh next time around. It also seems weird to report back a different mode to userspace than what the user provided. What you suggest was exactly the previous approach and I NAKed it. Oh I'm fully aware that it's in the leagues of cross hacks ;-) But doing the crtc-src_w/h thing correctly rolled out across the entire drm subsystem will be a big chunk more work than just adding new variables to struct drm_crtc which are only used in i915. The result would be that the set_property function here would do _no_ argument checking, but would instead fully rely upon the modeset sequence to compute the desired configuration. We don't have sufficient checks in the modeset path. The drm_crtc_check_viewport() call is in drm_mode_setcrtc() which is too high up in the stack to affect modesets originating from property changes. That being said we should definitely use drm_crtc_check_viewport() here instead of hand rolling the exacty same thing in i915. I guess then it needs to be moved down eventually. And to avoid having to touch too much code, drm_crtc_check_viewport() should encapsulate the logic to fall back to mode-{h,v}display when crtc-{w,h} are zero. Actually you get to do a full drm audit anyway, since there's more than check_viewport. They should all switch to crtc-src_w/h, and we should fill that out by default in the crtc helpers. Imo stuffing magic new stuff into the core only used by one driver isn't good, if we go this route we should do it properly. Or we ditch the struct drm_crtc change and pull it all into i915. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx
Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer
On Thu, Aug 14, 2014 at 05:32:28PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 03:09:45PM +, Daniel, Thomas wrote: When it comes to the execlist submission (actually as early as the execlist request queueing), the engine and context are indeed used and required. intel_logical_ring_advance_and_submit() is the lrc function analogous to __intel_ring_advance() and I believe the initial creation of intel_lrc.c was actually done by copying intel_ringbuffer.c. This explains why some of the lrc code is perhaps not as it would have been if this had been designed from scratch, and there is room for future improvement. advance_and_submit therefore only gets the ringbuffer struct and uses the context pointer in that struct to get the logical ring context itself. At that point the engine, context and new tail pointer are handed over to the execlist queue backend. I guess I need to clarify: Does it make sense to move the ELSP respectively the submission to the execlist scheduler queue out of there up a few levels into the execlist cmd submission function? Is it possible or is there some technical reason that I'm overlooking? I want to know what exactly I'm dealing with here before I sign up for it by merging the patches as-is and asking for a cleanup. I doesn't look bad really, but there's always a good chance that I've overlooked a bigger dragon. Since you have the patches and worked with them I'm asking you such explorative questions. Ofc I can do this checking myself, but that takes time ... This doesn't mean that you have to implement the changes, just be reasonable confident that it will work out as a cleanup on top. To clarify more the context: Currently you're replies sound like This is what it looks like and I don't really know why nor whether we can change that. That's not confidence instilling and that makes maintainers reluctant to merge patches for fear of needing to fix things themselves ;-) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 1/2] lib: add igt_restore_vt_mode
Add a function to restore the previous VT mode after igt_set_vt_graphics_mode is called. Signed-off-by: Thomas Wood thomas.w...@intel.com --- lib/igt_kms.c | 27 +-- lib/igt_kms.h | 1 + 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 11fd4e2..a414d96 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -269,17 +269,30 @@ err: static unsigned long orig_vt_mode = -1UL; -static void restore_vt_mode_at_exit(int sig) +/** + * kmstest_restore_vt_mode: + * + * Restore the VT mode in use before #kmstest_set_vt_graphics_mode was called. + */ +void kmstest_restore_vt_mode(void) { - if (orig_vt_mode != -1UL) - set_vt_mode(orig_vt_mode); + long ret; + + if (orig_vt_mode != -1UL) { + ret = set_vt_mode(orig_vt_mode); + orig_vt_mode = -1UL; + + igt_assert(ret = 0); + igt_debug(VT: original mode restored\n); + } } /** * kmstest_set_vt_graphics_mode: * - * Sets the controlling VT (if available) into graphics/raw mode and installs an - * igt exit handler to set the VT back to text mode on exit. + * Sets the controlling VT (if available) into graphics/raw mode and installs + * an igt exit handler to set the VT back to text mode on exit. Use + * #kmstest_restore_vt_mode to restore the previous VT mode manually. * * All kms tests must call this function to make sure that the fbcon doesn't * interfere by e.g. blanking the screen. @@ -288,7 +301,7 @@ void kmstest_set_vt_graphics_mode(void) { long ret; - igt_install_exit_handler(restore_vt_mode_at_exit); + igt_install_exit_handler((igt_exit_handler_t) kmstest_restore_vt_mode); igt_disable_exit_handler(); ret = set_vt_mode(KD_GRAPHICS); @@ -296,6 +309,8 @@ void kmstest_set_vt_graphics_mode(void) igt_assert(ret = 0); orig_vt_mode = ret; + + igt_debug(VT: graphics mode set\n); } static int get_card_number(int fd) diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 754d856..4263a01 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -102,6 +102,7 @@ void kmstest_dump_mode(drmModeModeInfo *mode); int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id); void kmstest_set_vt_graphics_mode(void); +void kmstest_restore_vt_mode(void); struct kmstest_connector_config { drmModeCrtc *crtc; -- 1.9.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 0/2] Check plane rotation is reset after VT mode is restored
The following patches allow the VT mode to be reset and then add a check in kms_rotation_crc to ensure the rotation has been restored. The test in kms_rotation_crc uses CRC values to determine this rather than just reading the property since the original issue exposed an inconsistency between the cached value for the rotation and the actual value. https://bugs.freedesktop.org/show_bug.cgi?id=82236 Thomas Wood (2): lib: add igt_restore_vt_mode tests: check plane rotation is reset after the VT mode is restored lib/igt_kms.c| 27 +-- lib/igt_kms.h| 1 + tests/kms_rotation_crc.c | 15 ++- 3 files changed, 36 insertions(+), 7 deletions(-) -- 1.9.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 2/2] tests: check plane rotation is reset after the VT mode is restored
Make sure the rotation is reset after the VT mode is restored by collecting the unrotated CRC and comparing with the CRC value after VT mode has been restored. The CRC is used to ensure the hardware state is checked, rather than any software state. References: https://bugs.freedesktop.org/show_bug.cgi?id=82236 Signed-off-by: Thomas Wood thomas.w...@intel.com --- tests/kms_rotation_crc.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index 9146b4f..9f272fa 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -153,7 +153,7 @@ static void test_plane_rotation(data_t *data, enum igt_plane plane_type) igt_output_t *output; enum pipe pipe; int valid_tests = 0; - igt_crc_t crc_output; + igt_crc_t crc_output, crc_unrotated; enum igt_commit_style commit = COMMIT_LEGACY; if (plane_type == IGT_PLANE_PRIMARY) { @@ -173,12 +173,25 @@ static void test_plane_rotation(data_t *data, enum igt_plane plane_type) if (!prepare_crtc(data, output, pipe, plane)) continue; + /* collect unrotated CRC */ + igt_display_commit2(display, commit); + igt_pipe_crc_collect_crc(data-pipe_crc, crc_unrotated); + igt_plane_set_rotation(plane, IGT_ROTATION_180); igt_display_commit2(display, commit); igt_pipe_crc_collect_crc(data-pipe_crc, crc_output); igt_assert(igt_crc_equal(data-ref_crc, crc_output)); + /* check the rotation state has been reset when the VT +* mode is restored */ + kmstest_restore_vt_mode(); + kmstest_set_vt_graphics_mode(); + prepare_crtc(data, output, pipe, plane); + igt_pipe_crc_collect_crc(data-pipe_crc, crc_output); + igt_assert(igt_crc_equal(crc_unrotated, crc_output)); + + valid_tests++; cleanup_crtc(data, output, plane); } -- 1.9.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 05:26:27PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 06:06:58PM +0300, Ville Syrjälä wrote: On Thu, Aug 14, 2014 at 04:42:01PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 02:54:27PM +0530, akash.g...@intel.com wrote: From: Akash Goel akash.g...@intel.com + /* Check if the current FB is compatible with new requested + Pipesrc values by the User */ + if (new_width fb-width || + new_height fb-height || + crtc-x fb-width - new_width || + crtc-y fb-height - new_height) { + DRM_DEBUG_KMS(New Pipe Src values %dx%d is incompatible with current fb size viewport %ux%u+%d+%d\n, + new_width, new_height, fb-width, fb-height, crtc-x, crtc-y); + return -EINVAL; + } I think this part here is the achilles heel of your approach. Right now we use crtc-mode.hdisplay/vdisplay We don't use it in i915. If we do that's a bug. All the relevant places should be loooking at pipe_src_{w,h}. In the core the viewport check should be about the only place that cares about this stuff. Well within i915, but not anywhere in the drm core or helper code since they're simply not aware of pipe_src_w/h. E.g. the plane helper code also uses crtc-mode.h/vdisplay. My quick grep audit tells me the viewport check and drm_primary_helper_update() are the only places in the core that care. The latter is rather dubious anyway since the clipping should be done against the adjusted mode and not the user specified mode, so anyone using that is already dancing on thin ice. The other drivers are something I would not touch. Given how many places we had to frob in i915 I'm somewhat sure I'd not like what I see there and then any patch I might cook up would be too half assed to satisfy my quality standards anyway. As far as always filling the crtc-w,h always goes, I'm not sure that's the best idea anyway since we still need the 0 is special handling. Well, we could fill them out, but then we definitely need a flag or something to indicate that they came from the mode and not the properties, so that we know whether we should overwrite them from with {h,v}display during a subsquent modeset or if they should keep their current value. -- 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 v2] drm/i915: Don't warn if we restore pm interrupts during reset
Mika Kuoppala mika.kuopp...@linux.intel.com writes: Daniel Vetter dan...@ffwll.ch writes: On Thu, Aug 14, 2014 at 03:46:43PM +0300, Mika Kuoppala wrote: We lost the software state tracking due to reset, so don't complain if it doesn't match. This sounds more like gpu reset should be a bit more careful (even more careful than we already are compared to earlier kernels) with making sure the irq state is still sane after a reset? Or what exactly is the failure mode here? The commit message lacks a bit details in form of a nice text or even better: A testcase ;-) We have pm ref during reset. And then after reset, we kick intel_gt_reset_powersave to re-enable the rps. Countrary to suspend/thaw, we never disabled the interrupts. And the warn triggers. I tried to disable the interrupts during reset handling but the nonblocking __wait_seqno() triggered another state warning it was taking a pm ref during or right after reset recovery for hw access. -Mika Pretty difficult to hit also. I needed multiple tries of ctrl-c the process that submitted the hang and have a another client running in background doing gpu access. Timing issue related that we enable the rps through delayed workqueue? Here is the trace: [ 635.478701] [drm] Simulated gpu hang, resetting stop_rings [ 637.457126] [ cut here ] [ 637.458711] WARNING: CPU: 5 PID: 3595 at drivers/gpu/drm/i915/intel_pm.c:3607 gen6_enable_rps_interrupts+0x72/0x80 [i915]() [ 637.460361] Modules linked in: i915 drm_kms_helper drm kvm_intel kvm snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_controller snd_hda_codec snd_hwdep snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq mxm_wmi snd_timer snd_seq_device psmouse snd serio_raw ehci_pci bnep ehci_hcd rfcomm soundcore bluetooth wmi mac_hid parport_pc ppdev lp parport dm_crypt usbhid firewire_ohci firewire_core crc_itu_t e1000e ptp pps_core xhci_hcd usbcore i2c_algo_bit video usb_common [last unloaded: drm] [ 637.468170] CPU: 5 PID: 3595 Comm: kworker/5:0 Tainted: GW 3.16.0+ #240 [ 637.469545] Workqueue: events intel_gen6_powersave_work [i915] [ 637.471042] ca0d3e54 c15adcca f8898260 ca0d3e84 c1047224 c17536b0 [ 637.472616] 0005 0e0b f8898260 0e17 f87ff852 f87ff852 f6ec8000 f6ecbe68 [ 637.474301] ee851c00 ca0d3e94 c1047262 0009 ca0d3ea8 f87ff852 f6ec8000 [ 637.475920] Call Trace: [ 637.477504] [c15adcca] dump_stack+0x48/0x60 [ 637.479060] [c1047224] warn_slowpath_common+0x84/0xa0 [ 637.480708] [f87ff852] ? gen6_enable_rps_interrupts+0x72/0x80 [i915] [ 637.481880] [f87ff852] ? gen6_enable_rps_interrupts+0x72/0x80 [i915] [ 637.483220] [c1047262] warn_slowpath_null+0x22/0x30 [ 637.484258] [f87ff852] gen6_enable_rps_interrupts+0x72/0x80 [i915] [ 637.485503] [f8808ecd] intel_gen6_powersave_work+0x57d/0x1020 [i915] [ 637.486516] [c105e8bc] process_one_work+0x10c/0x3c0 [ 637.487630] [c105f523] worker_thread+0xf3/0x470 [ 637.488618] [c105f430] ? create_and_start_worker+0x50/0x50 [ 637.489802] [c1064cdb] kthread+0x9b/0xb0 [ 637.490804] [c15b4e01] ret_from_kernel_thread+0x21/0x30 [ 637.491872] [c1064c40] ? flush_kthread_worker+0xb0/0xb0 [ 637.492862] ---[ end trace b31c16cec8a7abaa ]--- -Mika Thanks, Daniel v2: fix build error Signed-off-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..7a1309c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3593,7 +3593,8 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen8_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); @@ -3604,7 +3605,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; spin_lock_irq(dev_priv-irq_lock); - WARN_ON(dev_priv-rps.pm_iir); + if (!i915_reset_in_progress(dev_priv-gpu_error)) + WARN_ON(dev_priv-rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); I915_WRITE(GEN6_PMIIR, dev_priv-pm_rps_events); spin_unlock_irq(dev_priv-irq_lock); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___
Re: [Intel-gfx] [PATCH] drm: fix plane rotation when restoring fbdev configuration
On Thu, Aug 14, 2014 at 04:33:18PM +0100, Thomas Wood wrote: Make sure plane rotation is reset correctly when restoring the fbdev configuration by using drm_mode_plane_set_obj_prop. This calls the driver's set_property callback and ensures the rotation is actually changed. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236 Signed-off-by: Thomas Wood thomas.w...@intel.com Commit message is missing the citation of the offending commit that introduced this. With that addressed this is Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch And please cc all the people involved in the offending commit next time around, too. -Daniel --- drivers/gpu/drm/drm_crtc.c | 25 - drivers/gpu/drm/drm_fb_helper.c | 6 +++--- include/drm/drm_crtc.h | 3 +++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f09b752..95f330a 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4175,12 +4175,25 @@ static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, return ret; } -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +/** + * drm_mode_plane_set_obj_prop - set the value of a property + * @plane: drm plane object to set property value for + * @property: property to set + * @val: value the property should be set to + * + * This functions sets a given property on a given plane object. This function + * calls the driver's -set_property callback and changes the software state of + * the property if the callback succeeds. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_mode_plane_set_obj_prop(struct drm_plane *plane, + struct drm_property *property, + uint64_t value) { int ret = -EINVAL; - struct drm_plane *plane = obj_to_plane(obj); + struct drm_mode_object *obj = plane-base; if (plane-funcs-set_property) ret = plane-funcs-set_property(plane, property, value); @@ -4189,6 +4202,7 @@ static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj, return ret; } +EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); /** * drm_mode_getproperty_ioctl - get the current value of a object's property @@ -4327,7 +4341,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg-value); break; case DRM_MODE_OBJECT_PLANE: - ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg-value); + ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj), + property, arg-value); break; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 63d7b8e..0c0c39b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -296,9 +296,9 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) drm_plane_force_disable(plane); if (dev-mode_config.rotation_property) { - drm_object_property_set_value(plane-base, - dev-mode_config.rotation_property, - BIT(DRM_ROTATE_0)); + drm_mode_plane_set_obj_prop(plane, + dev-mode_config.rotation_property, + BIT(DRM_ROTATE_0)); } } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0375d75..31344bf 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1127,6 +1127,9 @@ extern int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, +struct drm_property *property, +uint64_t value); extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); -- 1.9.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org
Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer
-Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter Sent: Thursday, August 14, 2014 4:37 PM To: Daniel, Thomas Cc: Daniel Vetter; intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer On Thu, Aug 14, 2014 at 05:32:28PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 03:09:45PM +, Daniel, Thomas wrote: When it comes to the execlist submission (actually as early as the execlist request queueing), the engine and context are indeed used and required. intel_logical_ring_advance_and_submit() is the lrc function analogous to __intel_ring_advance() and I believe the initial creation of intel_lrc.c was actually done by copying intel_ringbuffer.c. This explains why some of the lrc code is perhaps not as it would have been if this had been designed from scratch, and there is room for future improvement. advance_and_submit therefore only gets the ringbuffer struct and uses the context pointer in that struct to get the logical ring context itself. At that point the engine, context and new tail pointer are handed over to the execlist queue backend. I guess I need to clarify: Does it make sense to move the ELSP respectively the submission to the execlist scheduler queue out of there up a few levels into the execlist cmd submission function? Is it possible or is there some technical reason that I'm overlooking? Yes this would make sense, and we already have a separate emit_request vfunc which is only used in lrc mode so we can for example change the signature to accept a drm_i915_gem_request* directly and take the ctx and engine from there. I want to know what exactly I'm dealing with here before I sign up for it by merging the patches as-is and asking for a cleanup. I doesn't look bad really, but there's always a good chance that I've overlooked a bigger dragon. Since you have the patches and worked with them I'm asking you such explorative questions. Ofc I can do this checking myself, but that takes time ... This doesn't mean that you have to implement the changes, just be reasonable confident that it will work out as a cleanup on top. Understood. To clarify more the context: Currently you're replies sound like This is what it looks like and I don't really know why nor whether we can change that. You're right, I don't know why it was done this way. But I can see that there is no problem to change it later - it's only a piece of code after all... That's not confidence instilling and that makes maintainers reluctant to merge patches for fear of needing to fix things themselves ;-) If it helps, I can tell you that several guys in our team are working with this code and we have a vested interest in making sure the quality is as high as possible. Cheers, Thomas. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 5:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: My quick grep audit tells me the viewport check and drm_primary_helper_update() are the only places in the core that care. The latter is rather dubious anyway since the clipping should be done against the adjusted mode and not the user specified mode, so anyone using that is already dancing on thin ice. My understanding has always been that the requested mode is what userspace plans to feed into the pipe, and the adjusted mode is what actually lands in the sink. Yeah there's some hilarity in the vblank code which somehow presumes that the vblank counter works with the adjusted mode because that's what i915 needs. It's that fundamental assumption that we break by making the pipe_src stuff official and which is the part that freaks me out a bit. The other drivers are something I would not touch. Given how many places we had to frob in i915 I'm somewhat sure I'd not like what I see there and then any patch I might cook up would be too half assed to satisfy my quality standards anyway. Yeah, other drivers only need to be audited I think once they start supporting the pipe_src stuff. But I think the core+helpers should be able to cope properly. As far as always filling the crtc-w,h always goes, I'm not sure that's the best idea anyway since we still need the 0 is special handling. Well, we could fill them out, but then we definitely need a flag or something to indicate that they came from the mode and not the properties, so that we know whether we should overwrite them from with {h,v}display during a subsquent modeset or if they should keep their current value. Hm, I guess we can keep that implicit meaning, but then we need a small helper to get at the crtc viewport, e.g. drm_crtc_viewport_rect or so. That would also be an excellent place to document this trickery properly. Oh and: Such drm changes _really_ must be split out into separate prep patches cc: dri-devel. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer
On Thu, Aug 14, 2014 at 03:56:20PM +, Daniel, Thomas wrote: -Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter Sent: Thursday, August 14, 2014 4:37 PM To: Daniel, Thomas Cc: Daniel Vetter; intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 08/43] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer On Thu, Aug 14, 2014 at 05:32:28PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 03:09:45PM +, Daniel, Thomas wrote: When it comes to the execlist submission (actually as early as the execlist request queueing), the engine and context are indeed used and required. intel_logical_ring_advance_and_submit() is the lrc function analogous to __intel_ring_advance() and I believe the initial creation of intel_lrc.c was actually done by copying intel_ringbuffer.c. This explains why some of the lrc code is perhaps not as it would have been if this had been designed from scratch, and there is room for future improvement. advance_and_submit therefore only gets the ringbuffer struct and uses the context pointer in that struct to get the logical ring context itself. At that point the engine, context and new tail pointer are handed over to the execlist queue backend. I guess I need to clarify: Does it make sense to move the ELSP respectively the submission to the execlist scheduler queue out of there up a few levels into the execlist cmd submission function? Is it possible or is there some technical reason that I'm overlooking? Yes this would make sense, and we already have a separate emit_request vfunc which is only used in lrc mode so we can for example change the signature to accept a drm_i915_gem_request* directly and take the ctx and engine from there. Hm, I didn't spot the emit_request vfunc yet. Probably another one that I'll ask you to fold in ;-) I want to know what exactly I'm dealing with here before I sign up for it by merging the patches as-is and asking for a cleanup. I doesn't look bad really, but there's always a good chance that I've overlooked a bigger dragon. Since you have the patches and worked with them I'm asking you such explorative questions. Ofc I can do this checking myself, but that takes time ... This doesn't mean that you have to implement the changes, just be reasonable confident that it will work out as a cleanup on top. Understood. To clarify more the context: Currently you're replies sound like This is what it looks like and I don't really know why nor whether we can change that. You're right, I don't know why it was done this way. But I can see that there is no problem to change it later - it's only a piece of code after all... That's not confidence instilling and that makes maintainers reluctant to merge patches for fear of needing to fix things themselves ;-) If it helps, I can tell you that several guys in our team are working with this code and we have a vested interest in making sure the quality is as high as possible. Ok, I think you get the hang of how this guide your maintainer into accepting stuff game works ;-) I'll take your word for it that there's no dragon hiding and that you'll bravely fight it anyway and will merge in a few more patches. And I'll do a JIRA to jot down the restructuring we need to do. Merging might be a bit slower since I'm heading to Chicago on Saturday already, so I might ask you to resend the remaining patches. Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Add temporary ring-ctx backpointer
From: Oscar Mateo oscar.ma...@intel.com The execlist patches have a bit a convoluted and long history and due to that have the actual submission still misplaced deeply burried in the low-level ringbuffer handling code. This design goes back to the legacy ringbuffer code with its tricky lazy request and simple work submissiion using ring tail writes. For that reason they need a ring-ctx backpointer. The goal is to unburry that code and move it up into a level where the full execlist context is available so that we can ditch this backpointer. Until that's done make it really obvious that there's work still to be done. Cc: Oscar Mateo oscar.ma...@intel.com Cc: Thomas Daniel thomas.dan...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch -- Thomas, please ack this patch and the general plan we've discussed. Then I'll start pulling in more patches and I'll do the s/ctx/FIXME_lrc_ctx/ on the fly. -Daniel --- drivers/gpu/drm/i915/intel_lrc.c| 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 7 +++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6b5f416b5c0d..c2352d1b23fa 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1086,6 +1086,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, } ringbuf-ring = ring; + ringbuf-FIXME_lrc_ctx = ctx; + ringbuf-size = 32 * PAGE_SIZE; ringbuf-effective_size = ringbuf-size; ringbuf-head = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 24437da91f77..26785ca72530 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -99,6 +99,13 @@ struct intel_ringbuffer { struct intel_engine_cs *ring; + /* +* FIXME: This backpointer is an artifact of the history of how the +* execlist patches came into being. It will get removed once the basic +* code has landed. +*/ + struct intel_context *FIXME_lrc_ctx; + u32 head; u32 tail; int space; -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Add temporary ring-ctx backpointer
-Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] Sent: Thursday, August 14, 2014 5:28 PM To: Intel Graphics Development Cc: Mateo Lozano, Oscar; Daniel, Thomas; Daniel Vetter Subject: [PATCH] drm/i915: Add temporary ring-ctx backpointer From: Oscar Mateo oscar.ma...@intel.com The execlist patches have a bit a convoluted and long history and due to that have the actual submission still misplaced deeply burried in the low-level ringbuffer handling code. This design goes back to the legacy ringbuffer code with its tricky lazy request and simple work submissiion using ring tail writes. For that reason they need a ring-ctx backpointer. The goal is to unburry that code and move it up into a level where the full execlist context is available so that we can ditch this backpointer. Until that's done make it really obvious that there's work still to be done. Cc: Oscar Mateo oscar.ma...@intel.com Cc: Thomas Daniel thomas.dan...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch -- Thomas, please ack this patch and the general plan we've discussed. Acked-by: Thomas Daniel thomas.dan...@intel.com Then I'll start pulling in more patches and I'll do the s/ctx/FIXME_lrc_ctx/ on the fly. -Daniel --- drivers/gpu/drm/i915/intel_lrc.c| 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 7 +++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6b5f416b5c0d..c2352d1b23fa 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1086,6 +1086,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, } ringbuf-ring = ring; + ringbuf-FIXME_lrc_ctx = ctx; + ringbuf-size = 32 * PAGE_SIZE; ringbuf-effective_size = ringbuf-size; ringbuf-head = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 24437da91f77..26785ca72530 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -99,6 +99,13 @@ struct intel_ringbuffer { struct intel_engine_cs *ring; + /* + * FIXME: This backpointer is an artifact of the history of how the + * execlist patches came into being. It will get removed once the basic + * code has landed. + */ + struct intel_context *FIXME_lrc_ctx; + u32 head; u32 tail; int space; -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 06:07:44PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 5:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: My quick grep audit tells me the viewport check and drm_primary_helper_update() are the only places in the core that care. The latter is rather dubious anyway since the clipping should be done against the adjusted mode and not the user specified mode, so anyone using that is already dancing on thin ice. My understanding has always been that the requested mode is what userspace plans to feed into the pipe, and the adjusted mode is what actually lands in the sink. Yeah there's some hilarity in the vblank code which somehow presumes that the vblank counter works with the adjusted mode because that's what i915 needs. The problem with clipping planes to the user size is that the driver is free to frob the mode a bit to line it up with hardware constraints. So what the user requested might be a few pixels off compared to what the hardware will end up using, and then if you configure the plane blindly using the coordinates clipped against the user size, the hardware may get somewhat upset. It's that fundamental assumption that we break by making the pipe_src stuff official and which is the part that freaks me out a bit. Yeah there's definitely some dangers with these properties. The biggest being when one master sets the properties, and then another master which doesn't know anything about these properties takes over. The result might be a failed modeset an then the user doesn't see anything. This is one reason why I'd prefer that we'd maintain the state per-master. For fbdev the reset everything to default trick seems sufficient but I'm not sure I'd like to that to actual users. The other drivers are something I would not touch. Given how many places we had to frob in i915 I'm somewhat sure I'd not like what I see there and then any patch I might cook up would be too half assed to satisfy my quality standards anyway. Yeah, other drivers only need to be audited I think once they start supporting the pipe_src stuff. But I think the core+helpers should be able to cope properly. As far as always filling the crtc-w,h always goes, I'm not sure that's the best idea anyway since we still need the 0 is special handling. Well, we could fill them out, but then we definitely need a flag or something to indicate that they came from the mode and not the properties, so that we know whether we should overwrite them from with {h,v}display during a subsquent modeset or if they should keep their current value. Hm, I guess we can keep that implicit meaning, but then we need a small helper to get at the crtc viewport, e.g. drm_crtc_viewport_rect or so. That would also be an excellent place to document this trickery properly. Yeah such small helpers is what I had in mind when suggesting this originally. Oh and: Such drm changes _really_ must be split out into separate prep patches cc: dri-devel. Indeed. -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bdw: Initialize workarounds in render ring init fn.
From: Arun Siluvery arun.siluv...@linux.intel.com The workarounds at the moment are initialized in init_clock_gating() but they are lost during reset, suspend/resume; this patch moves workarounds that are part of register state context to render ring init fn otherwise default context ends up with incorrect values as they don't get initialized until init_clock_gating fn. This should be ok as they are not related to display clock gating in the first place. v2: Add macro to generate w/a table (Daniel) Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 38 +++ drivers/gpu/drm/i915/i915_drv.h | 32 drivers/gpu/drm/i915/intel_pm.c | 50 - drivers/gpu/drm/i915/intel_ringbuffer.c | 66 + 4 files changed, 136 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9e737b7..fc28835 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2406,6 +2406,43 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) return 0; } +static int intel_wa_registers(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m-private; + struct drm_device *dev = node-minor-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + int i; + int ret; + + if (!dev_priv-num_wa) { + DRM_DEBUG_DRIVER(Workaround table not available\n); + return -EINVAL; + } + + if (dev_priv-num_wa I915_MAX_WA_REGS) + dev_priv-num_wa = I915_MAX_WA_REGS; + + ret = mutex_lock_interruptible(dev-struct_mutex); + if (ret) + return ret; + + intel_runtime_pm_get(dev_priv); + + seq_printf(m, Workarounds applied: %d\n, dev_priv-num_wa); + for (i = 0; i dev_priv-num_wa; ++i) { + if (dev_priv-wa_regs[i].addr) + seq_printf(m, 0x%X: 0x%08X, mask: 0x%08X\n, + dev_priv-wa_regs[i].addr, + I915_READ(dev_priv-wa_regs[i].addr), + dev_priv-wa_regs[i].mask); + } + + intel_runtime_pm_put(dev_priv); + mutex_unlock(dev-struct_mutex); + + return 0; +} + struct pipe_crc_info { const char *name; struct drm_device *dev; @@ -3936,6 +3973,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {i915_semaphore_status, i915_semaphore_status, 0}, {i915_shared_dplls_info, i915_shared_dplls_info, 0}, {i915_dp_mst_info, i915_dp_mst_info, 0}, + {intel_wa_registers, intel_wa_registers, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 18c9ad8..c4190a9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1222,6 +1222,24 @@ struct i915_gpu_error { unsigned int test_irq_rings; }; +/* + * workarounds are currently applied at different places and changes + * are being done to consolidate them at a single place hence the + * exact count is not clear at this point; replace this with accurate + * number based on gen later. + */ +#define I915_MAX_WA_REGS 16 + +/* + * structure to verify workarounds status + * mask: represent w/a bits + */ +struct intel_wa { + u32 addr; + u32 val; + u32 mask; +}; + enum modeset_restore { MODESET_ON_LID_OPEN, MODESET_DONE, @@ -1422,6 +1440,9 @@ struct drm_i915_private { struct drm_i915_gem_object *semaphore_obj; uint32_t last_seqno, next_seqno; + uint32_t num_wa; + struct intel_wa wa_regs[I915_MAX_WA_REGS]; + drm_dma_handle_t *status_page_dmah; struct resource mch_res; @@ -2803,6 +2824,17 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) #define POSTING_READ16(reg)(void)I915_READ16_NOTRACE(reg) +#define I915_WRITE_WA(reg, val) ({ \ + if (dev_priv-num_wa = 0 \ +dev_priv-num_wa I915_MAX_WA_REGS) { \ + dev_priv-wa_regs[dev_priv-num_wa].addr = reg; \ + dev_priv-wa_regs[dev_priv-num_wa].mask\ + = (val) 0x; \ + dev_priv-num_wa++; \ + I915_WRITE(reg, val); \ + } \ + }) + /* Broadcast RGB property */ #define INTEL_BROADCAST_RGB_AUTO 0 #define INTEL_BROADCAST_RGB_FULL 1 diff --git
[Intel-gfx] [PATCH] igt/gem_workaround: Add test to verify workarounds
From: Arun Siluvery arun.siluv...@linux.intel.com This patch adds a new test to verify applied workarounds before and after an operation such as gpu reset, suspend/resume. It is a simple test which captures w/a state at the beginning and compares their status with the state after the operation. v2: w/a table is removed from igt as driver exports it via debugfs file. Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- tests/Makefile.sources | 1 + tests/gem_workarounds.c | 252 2 files changed, 253 insertions(+) create mode 100644 tests/gem_workarounds.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 0eb9369..e16e22a 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -62,6 +62,7 @@ TESTS_progs_M = \ gem_tiled_partial_pwrite_pread \ gem_userptr_blits \ gem_write_read_ring_switch \ + gem_workarounds \ kms_addfb \ kms_cursor_crc \ kms_fbc_crc \ diff --git a/tests/gem_workarounds.c b/tests/gem_workarounds.c new file mode 100644 index 000..cac1027 --- /dev/null +++ b/tests/gem_workarounds.c @@ -0,0 +1,252 @@ +/* + * 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. + * + * Authors: + * Arun Siluvery arun.siluv...@linux.intel.com + * + */ + +#define _GNU_SOURCE +#include stdbool.h +#include unistd.h +#include stdlib.h +#include stdio.h +#include string.h +#include fcntl.h +#include inttypes.h +#include errno.h +#include sys/stat.h +#include sys/ioctl.h +#include sys/mman.h +#include time.h +#include signal.h + +#include ioctl_wrappers.h +#include drmtest.h +#include igt_debugfs.h +#include igt_aux.h +#include intel_chipset.h +#include intel_io.h + +enum operation { + GPU_RESET = 0x01, + SUSPEND_RESUME = 0x02, +}; + +struct intel_wa { + uint32_t addr; + uint32_t value; + uint32_t mask; +}; + +int drm_fd; +uint32_t devid; +static drm_intel_bufmgr *bufmgr; +struct intel_batchbuffer *batch; +int num_wa; +struct intel_wa *workarounds; + + +static void test_hang_gpu(void) +{ + int retry_count = 30; + enum stop_ring_flags flags; + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 gem_exec; + uint32_t b[2] = {MI_BATCH_BUFFER_END}; + + igt_assert(retry_count); + igt_set_stop_rings(STOP_RING_DEFAULTS); + + memset(gem_exec, 0, sizeof(gem_exec)); + gem_exec.handle = gem_create(drm_fd, 4096); + gem_write(drm_fd, gem_exec.handle, 0, b, sizeof(b)); + + memset(execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = (uintptr_t)gem_exec; + execbuf.buffer_count = 1; + execbuf.batch_len = sizeof(b); + + drmIoctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); + + while(retry_count--) { + flags = igt_get_stop_rings(); + if (flags == 0) + break; + printf(gpu hang not yet cleared, retries left %d\n, retry_count); + sleep(1); + } + + flags = igt_get_stop_rings(); + if (flags) + igt_set_stop_rings(STOP_RING_NONE); +} + +static void test_suspend_resume(void) +{ + printf(Suspending the device ...\n); + igt_system_suspend_autoresume(); +} + +static void capture_wa_state(const char *wa_reg_file, char *buf, int size) +{ + int fd; + int len = 0; + char data[512]; + + fd = igt_debugfs_open(wa_reg_file, O_RDONLY); + igt_assert(fd 0); + len = read(fd, data, size); + data[len - 1] = '\0'; + close(fd); + +} + +static void get_current_wa_data(struct intel_wa **curr, int num) +{ + int i; + struct intel_wa *ptr = NULL; + + ptr = *curr; + + intel_register_access_init(intel_get_pci_device(), 0); + + for (i = 0; i num; ++i) { + ptr[i].addr
Re: [Intel-gfx] [PATCH] igt/gem_workaround: Add test to verify workarounds
2014-08-14 13:51 GMT-03:00 arun.siluv...@linux.intel.com: From: Arun Siluvery arun.siluv...@linux.intel.com This patch adds a new test to verify applied workarounds before and after an operation such as gpu reset, suspend/resume. It is a simple test which captures w/a state at the beginning and compares their status with the state after the operation. v2: w/a table is removed from igt as driver exports it via debugfs file. It would be good if you could also add a test to check if the woarkarounds survive runtime PM. Signed-off-by: Arun Siluvery arun.siluv...@linux.intel.com --- tests/Makefile.sources | 1 + tests/gem_workarounds.c | 252 2 files changed, 253 insertions(+) create mode 100644 tests/gem_workarounds.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 0eb9369..e16e22a 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -62,6 +62,7 @@ TESTS_progs_M = \ gem_tiled_partial_pwrite_pread \ gem_userptr_blits \ gem_write_read_ring_switch \ + gem_workarounds \ kms_addfb \ kms_cursor_crc \ kms_fbc_crc \ diff --git a/tests/gem_workarounds.c b/tests/gem_workarounds.c new file mode 100644 index 000..cac1027 --- /dev/null +++ b/tests/gem_workarounds.c @@ -0,0 +1,252 @@ +/* + * 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. + * + * Authors: + * Arun Siluvery arun.siluv...@linux.intel.com + * + */ + +#define _GNU_SOURCE +#include stdbool.h +#include unistd.h +#include stdlib.h +#include stdio.h +#include string.h +#include fcntl.h +#include inttypes.h +#include errno.h +#include sys/stat.h +#include sys/ioctl.h +#include sys/mman.h +#include time.h +#include signal.h + +#include ioctl_wrappers.h +#include drmtest.h +#include igt_debugfs.h +#include igt_aux.h +#include intel_chipset.h +#include intel_io.h + +enum operation { + GPU_RESET = 0x01, + SUSPEND_RESUME = 0x02, +}; + +struct intel_wa { + uint32_t addr; + uint32_t value; + uint32_t mask; +}; + +int drm_fd; +uint32_t devid; +static drm_intel_bufmgr *bufmgr; +struct intel_batchbuffer *batch; +int num_wa; +struct intel_wa *workarounds; + + +static void test_hang_gpu(void) +{ + int retry_count = 30; + enum stop_ring_flags flags; + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 gem_exec; + uint32_t b[2] = {MI_BATCH_BUFFER_END}; + + igt_assert(retry_count); + igt_set_stop_rings(STOP_RING_DEFAULTS); + + memset(gem_exec, 0, sizeof(gem_exec)); + gem_exec.handle = gem_create(drm_fd, 4096); + gem_write(drm_fd, gem_exec.handle, 0, b, sizeof(b)); + + memset(execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = (uintptr_t)gem_exec; + execbuf.buffer_count = 1; + execbuf.batch_len = sizeof(b); + + drmIoctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); + + while(retry_count--) { + flags = igt_get_stop_rings(); + if (flags == 0) + break; + printf(gpu hang not yet cleared, retries left %d\n, retry_count); + sleep(1); + } + + flags = igt_get_stop_rings(); + if (flags) + igt_set_stop_rings(STOP_RING_NONE); +} + +static void test_suspend_resume(void) +{ + printf(Suspending the device ...\n); + igt_system_suspend_autoresume(); +} + +static void capture_wa_state(const char *wa_reg_file, char *buf, int size) +{ + int fd; + int len = 0; + char data[512]; + + fd = igt_debugfs_open(wa_reg_file, O_RDONLY); + igt_assert(fd 0); + len = read(fd, data, size); + data[len -
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 6:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: On Thu, Aug 14, 2014 at 06:07:44PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 5:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: My quick grep audit tells me the viewport check and drm_primary_helper_update() are the only places in the core that care. The latter is rather dubious anyway since the clipping should be done against the adjusted mode and not the user specified mode, so anyone using that is already dancing on thin ice. My understanding has always been that the requested mode is what userspace plans to feed into the pipe, and the adjusted mode is what actually lands in the sink. Yeah there's some hilarity in the vblank code which somehow presumes that the vblank counter works with the adjusted mode because that's what i915 needs. The problem with clipping planes to the user size is that the driver is free to frob the mode a bit to line it up with hardware constraints. So what the user requested might be a few pixels off compared to what the hardware will end up using, and then if you configure the plane blindly using the coordinates clipped against the user size, the hardware may get somewhat upset. Hm, I've thought we didn't do that yet, but only frobbed the adjusted mode to make it fit our requirements for e.g interlaced stuff. I don't think it would be good if we start doing that since there's no way for userspace to be aware of the resulting single-pixel border of garbage. _If_ we need to do that I think we should frob modes when adding them to the connector mode list. It's that fundamental assumption that we break by making the pipe_src stuff official and which is the part that freaks me out a bit. Yeah there's definitely some dangers with these properties. The biggest being when one master sets the properties, and then another master which doesn't know anything about these properties takes over. The result might be a failed modeset an then the user doesn't see anything. This is one reason why I'd prefer that we'd maintain the state per-master. For fbdev the reset everything to default trick seems sufficient but I'm not sure I'd like to that to actual users. Yeah, this is unsolved territory. Not sure whether attaching the state to the master should be helpful, or whether we should care at all. For a generic distro we should boot-up sane-ish, and userspace can always grab the full property picture and restore that if all else fails. The fbcon restoring is really just for developers imo. The other drivers are something I would not touch. Given how many places we had to frob in i915 I'm somewhat sure I'd not like what I see there and then any patch I might cook up would be too half assed to satisfy my quality standards anyway. Yeah, other drivers only need to be audited I think once they start supporting the pipe_src stuff. But I think the core+helpers should be able to cope properly. As far as always filling the crtc-w,h always goes, I'm not sure that's the best idea anyway since we still need the 0 is special handling. Well, we could fill them out, but then we definitely need a flag or something to indicate that they came from the mode and not the properties, so that we know whether we should overwrite them from with {h,v}display during a subsquent modeset or if they should keep their current value. Hm, I guess we can keep that implicit meaning, but then we need a small helper to get at the crtc viewport, e.g. drm_crtc_viewport_rect or so. That would also be an excellent place to document this trickery properly. Yeah such small helpers is what I had in mind when suggesting this originally. Oh and: Such drm changes _really_ must be split out into separate prep patches cc: dri-devel. Indeed. Sounds like we have a rough plan. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 07:36:13PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 6:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: On Thu, Aug 14, 2014 at 06:07:44PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 5:45 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: My quick grep audit tells me the viewport check and drm_primary_helper_update() are the only places in the core that care. The latter is rather dubious anyway since the clipping should be done against the adjusted mode and not the user specified mode, so anyone using that is already dancing on thin ice. My understanding has always been that the requested mode is what userspace plans to feed into the pipe, and the adjusted mode is what actually lands in the sink. Yeah there's some hilarity in the vblank code which somehow presumes that the vblank counter works with the adjusted mode because that's what i915 needs. The problem with clipping planes to the user size is that the driver is free to frob the mode a bit to line it up with hardware constraints. So what the user requested might be a few pixels off compared to what the hardware will end up using, and then if you configure the plane blindly using the coordinates clipped against the user size, the hardware may get somewhat upset. Hm, I've thought we didn't do that yet, but only frobbed the adjusted mode to make it fit our requirements for e.g interlaced stuff. I don't think it would be good if we start doing that since there's no way for userspace to be aware of the resulting single-pixel border of garbage. _If_ we need to do that I think we should frob modes when adding them to the connector mode list. Sure but the user can supply any mode, doesn't have to be on any list. And the only sane rule for the frobbing would be that you can (slightly) reduce hdisp/vdisp but never expand them so that there will never be any extra garbage exposed (and the FB might not be big enough anyway). But even reducing hdisp/vdisp by one pixel can be enough to anger the hardware if a plane then extends one pixel into the blanking. This isn't much of a problem for i915 though. The hardware is generally good enough to not need it. Double wide and (s)dvo/lvds gang mode are the only exception that comes to mind. Even there we just need to make pipe src width even, but still that's something we have to account when clipping planes. On older hardware there were generally more restrictions eg. some legacy baggage from VGA days which required horizontal timings to be multiples of 8. I also fondly remember much more magic timing restrictions in certain pieces hardware which were something close to if (foo*bar % this == that) frob else don't. IMO these kinds of restrictions are too magic to make rejecting the mode an option, so frobbing is the lesser of two evils. -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/edid: Reduce horizontal timings for pixel replicated modes
From: Clint Taylor clinton.a.tay...@intel.com Pixel replicated modes should be 720 horizontal pixel and pixel replicated by the HW across the HDMI cable at 2X pixel clock. Current horizontal resolution of 1440 does not allow pixel duplication to occur and scaling artifacts occur on the TV. HDMI certification 7-26 currently fails for all pixel replicated modes. This change fizes the HDMI certification issues with 480i/576i. Signed-off-by: Clint Taylor clinton.a.tay...@intel.com --- drivers/gpu/drm/drm_edid.c| 100 ++--- drivers/gpu/drm/i915/intel_hdmi.c | 14 +- 2 files changed, 63 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f905c63..c7a26a7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -632,27 +632,27 @@ static const struct drm_display_mode edid_cea_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 6 - 1440x480i@60Hz */ - { DRM_MODE(1440x480i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, + /* 6 - 720(1440)x480i@60Hz */ + { DRM_MODE(720x480i, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, + 801, 858, 0, 480, 488, 494, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 7 - 1440x480i@60Hz */ - { DRM_MODE(1440x480i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, + /* 7 - 720(1440)x480i@60Hz */ + { DRM_MODE(720x480i, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, + 801, 858, 0, 480, 488, 494, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 8 - 1440x240@60Hz */ - { DRM_MODE(1440x240, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 240, 244, 247, 262, 0, + /* 8 - 720(1440)x240@60Hz */ + { DRM_MODE(720x240, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, + 801, 858, 0, 240, 244, 247, 262, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 9 - 1440x240@60Hz */ - { DRM_MODE(1440x240, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 240, 244, 247, 262, 0, + /* 9 - 720(1440)x240@60Hz */ + { DRM_MODE(720x240, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, + 801, 858, 0, 240, 244, 247, 262, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, @@ -714,27 +714,27 @@ static const struct drm_display_mode edid_cea_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 21 - 1440x576i@50Hz */ - { DRM_MODE(1440x576i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, + /* 21 - 720(1440)x576i@50Hz */ + { DRM_MODE(720x576i, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, + 795, 864, 0, 576, 580, 586, 625, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 22 - 1440x576i@50Hz */ - { DRM_MODE(1440x576i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, + /* 22 - 720(1440)x576i@50Hz */ + { DRM_MODE(720x576i, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, + 795, 864, 0, 576, 580, 586, 625, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 23 - 1440x288@50Hz */ - { DRM_MODE(1440x288, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 288, 290, 293, 312, 0, + /* 23 - 720(1440)x288@50Hz */ + { DRM_MODE(720x288, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, + 795, 864, 0, 288, 290, 293, 312, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_DBLCLK),
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 7:58 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: Sure but the user can supply any mode, doesn't have to be on any list. And the only sane rule for the frobbing would be that you can (slightly) reduce hdisp/vdisp but never expand them so that there will never be any extra garbage exposed (and the FB might not be big enough anyway). But even reducing hdisp/vdisp by one pixel can be enough to anger the hardware if a plane then extends one pixel into the blanking. This isn't much of a problem for i915 though. The hardware is generally good enough to not need it. Double wide and (s)dvo/lvds gang mode are the only exception that comes to mind. Even there we just need to make pipe src width even, but still that's something we have to account when clipping planes. On older hardware there were generally more restrictions eg. some legacy baggage from VGA days which required horizontal timings to be multiples of 8. I also fondly remember much more magic timing restrictions in certain pieces hardware which were something close to if (foo*bar % this == that) frob else don't. IMO these kinds of restrictions are too magic to make rejecting the mode an option, so frobbing is the lesser of two evils. Imo the mode list we provide should be reasonable for everyone, and if you start to add your own modes then I expect the user to do that adjusting for us. Nowadays there should be very few cases where we don't provide decent mode lists and where it's not a super-special embedded thing where you need to configure everything yourself anyway. So I don't think we should ever adjust the input region for a crtc. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/edid: Reduce horizontal timings for pixel replicated modes
On Thu, Aug 14, 2014 at 11:09:25AM -0700, clinton.a.tay...@intel.com wrote: From: Clint Taylor clinton.a.tay...@intel.com Pixel replicated modes should be 720 horizontal pixel and pixel replicated by the HW across the HDMI cable at 2X pixel clock. Current horizontal resolution of 1440 does not allow pixel duplication to occur and scaling artifacts occur on the TV. HDMI certification 7-26 currently fails for all pixel replicated modes. This change fizes the HDMI certification issues with 480i/576i. Signed-off-by: Clint Taylor clinton.a.tay...@intel.com --- drivers/gpu/drm/drm_edid.c| 100 ++--- drivers/gpu/drm/i915/intel_hdmi.c | 14 +- 2 files changed, 63 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f905c63..c7a26a7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -632,27 +632,27 @@ static const struct drm_display_mode edid_cea_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 6 - 1440x480i@60Hz */ - { DRM_MODE(1440x480i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, -1602, 1716, 0, 480, 488, 494, 525, 0, + /* 6 - 720(1440)x480i@60Hz */ + { DRM_MODE(720x480i, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, +801, 858, 0, 480, 488, 494, 525, 0, As stated before I think I would have preferred explicit /2 here, but if you prefer to have it this way I can live with it. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 7 - 1440x480i@60Hz */ - { DRM_MODE(1440x480i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, -1602, 1716, 0, 480, 488, 494, 525, 0, + /* 7 - 720(1440)x480i@60Hz */ + { DRM_MODE(720x480i, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, +801, 858, 0, 480, 488, 494, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 8 - 1440x240@60Hz */ - { DRM_MODE(1440x240, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, -1602, 1716, 0, 240, 244, 247, 262, 0, + /* 8 - 720(1440)x240@60Hz */ + { DRM_MODE(720x240, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, +801, 858, 0, 240, 244, 247, 262, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 9 - 1440x240@60Hz */ - { DRM_MODE(1440x240, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, -1602, 1716, 0, 240, 244, 247, 262, 0, + /* 9 - 720(1440)x240@60Hz */ + { DRM_MODE(720x240, DRM_MODE_TYPE_DRIVER, 13500, 720, 739, +801, 858, 0, 240, 244, 247, 262, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_DBLCLK), .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, @@ -714,27 +714,27 @@ static const struct drm_display_mode edid_cea_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 21 - 1440x576i@50Hz */ - { DRM_MODE(1440x576i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, -1590, 1728, 0, 576, 580, 586, 625, 0, + /* 21 - 720(1440)x576i@50Hz */ + { DRM_MODE(720x576i, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, +795, 864, 0, 576, 580, 586, 625, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 22 - 1440x576i@50Hz */ - { DRM_MODE(1440x576i, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, -1590, 1728, 0, 576, 580, 586, 625, 0, + /* 22 - 720(1440)x576i@50Hz */ + { DRM_MODE(720x576i, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, +795, 864, 0, 576, 580, 586, 625, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 23 - 1440x288@50Hz */ - { DRM_MODE(1440x288, DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, -1590, 1728, 0, 288, 290, 293, 312, 0, + /* 23 - 720(1440)x288@50Hz */ + { DRM_MODE(720x288, DRM_MODE_TYPE_DRIVER, 13500, 720, 732, +
Re: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc size
On Thu, Aug 14, 2014 at 08:33:23PM +0200, Daniel Vetter wrote: On Thu, Aug 14, 2014 at 7:58 PM, Ville Syrjälä ville.syrj...@linux.intel.com wrote: Sure but the user can supply any mode, doesn't have to be on any list. And the only sane rule for the frobbing would be that you can (slightly) reduce hdisp/vdisp but never expand them so that there will never be any extra garbage exposed (and the FB might not be big enough anyway). But even reducing hdisp/vdisp by one pixel can be enough to anger the hardware if a plane then extends one pixel into the blanking. This isn't much of a problem for i915 though. The hardware is generally good enough to not need it. Double wide and (s)dvo/lvds gang mode are the only exception that comes to mind. Even there we just need to make pipe src width even, but still that's something we have to account when clipping planes. On older hardware there were generally more restrictions eg. some legacy baggage from VGA days which required horizontal timings to be multiples of 8. I also fondly remember much more magic timing restrictions in certain pieces hardware which were something close to if (foo*bar % this == that) frob else don't. IMO these kinds of restrictions are too magic to make rejecting the mode an option, so frobbing is the lesser of two evils. Imo the mode list we provide should be reasonable for everyone, and if you start to add your own modes then I expect the user to do that adjusting for us. Nowadays there should be very few cases where we don't provide decent mode lists and where it's not a super-special embedded thing where you need to configure everything yourself anyway. So I don't think we should ever adjust the input region for a crtc. That's fine for decent hardware. But if/when I write a driver for old junk I'm probably going to frob no matter what anyone says :) -- Ville Syrjälä Intel OTC ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Move vblank enable earlier and disable later
From: Ville Syrjälä ville.syrj...@linux.intel.com We changed to an interrupt based vblank wait (as opposed to polling) in: commit 44bd93a3d367913d883be6abba9a6e51a53c4e90 Author: Daniel Vetter daniel.vet...@ffwll.ch Date: Fri Jul 25 23:36:44 2014 +0200 drm/i915: Use generic vblank wait However we already had vblank waits on the wrong side of drm_vblank_{on,off}() calls due to various workarounds, so now we get a warning more or less every time we do a modeset, and we fail to wait for the vblank like we should. Move the drm_vblank_{on,off}() calls back out from intel_crtc_{enable,disable}_planes() so that all of these vblank waits return to proper operation. Also move the cxsr wait a bit earlier so that we can keep the encoder disable after we've turned off vblanks. Moving stuff out from the plane enable/disable functions seems preferrable to moving the workaround stuff in since the workarounds are required only on specific platforms. While at it switch over to the drm_crtc_ variants of the vblank on/off functions. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82525 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82490 Cc: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 35 --- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3813526..970c2ab 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3845,10 +3845,6 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc-pipe; - assert_vblank_disabled(crtc); - - drm_vblank_on(dev, pipe); - intel_enable_primary_hw_plane(crtc-primary, crtc); intel_enable_planes(crtc); intel_crtc_update_cursor(crtc, true); @@ -3894,10 +3890,6 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) * consider this a flip to a NULL plane. */ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe)); - - drm_vblank_off(dev, pipe); - - assert_vblank_disabled(crtc); } static void ironlake_crtc_enable(struct drm_crtc *crtc) @@ -3967,6 +3959,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (HAS_PCH_CPT(dev)) cpt_verify_modeset(dev, intel_crtc-pipe); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); } @@ -4074,6 +4069,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_opregion_notify_encoder(encoder, true); } + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + /* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ haswell_mode_set_planes_workaround(intel_crtc); @@ -4109,6 +4107,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) encoder-disable(encoder); @@ -4175,6 +4176,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) { intel_opregion_notify_encoder(encoder, false); encoder-disable(encoder); @@ -4638,6 +4642,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder-enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* Underruns don't raise interrupts, so check manually. */ @@ -4695,6 +4702,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder-enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* @@ -4758,9 +4768,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_set_memory_cxsr(dev_priv, false); intel_crtc_disable_planes(crtc); - for_each_encoder_on_crtc(dev, crtc, encoder) - encoder-disable(encoder); - /* * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. @@ -4769,6 +4776,12 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) */ intel_wait_for_vblank(dev, pipe); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + +
Re: [Intel-gfx] [PATCH] drm/i915: Move vblank enable earlier and disable later
On Thu, Aug 14, 2014 at 10:04:37PM +0300, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com We changed to an interrupt based vblank wait (as opposed to polling) in: commit 44bd93a3d367913d883be6abba9a6e51a53c4e90 Author: Daniel Vetter daniel.vet...@ffwll.ch Date: Fri Jul 25 23:36:44 2014 +0200 drm/i915: Use generic vblank wait However we already had vblank waits on the wrong side of drm_vblank_{on,off}() calls due to various workarounds, so now we get a warning more or less every time we do a modeset, and we fail to wait for the vblank like we should. Move the drm_vblank_{on,off}() calls back out from intel_crtc_{enable,disable}_planes() so that all of these vblank waits return to proper operation. Also move the cxsr wait a bit earlier so that we can keep the encoder disable after we've turned off vblanks. Moving stuff out from the plane enable/disable functions seems preferrable to moving the workaround stuff in since the workarounds are required only on specific platforms. While at it switch over to the drm_crtc_ variants of the vblank on/off functions. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82525 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82490 Cc: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com I've dropped the offending patch temporarily and picked up yours here into my atomic branch - currently there's too many things unmerged to get this in. Thanks anyway for the patch. --- drivers/gpu/drm/i915/intel_display.c | 35 --- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3813526..970c2ab 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3845,10 +3845,6 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc-pipe; - assert_vblank_disabled(crtc); - - drm_vblank_on(dev, pipe); - intel_enable_primary_hw_plane(crtc-primary, crtc); intel_enable_planes(crtc); intel_crtc_update_cursor(crtc, true); @@ -3894,10 +3890,6 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) * consider this a flip to a NULL plane. */ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe)); - - drm_vblank_off(dev, pipe); - - assert_vblank_disabled(crtc); } static void ironlake_crtc_enable(struct drm_crtc *crtc) @@ -3967,6 +3959,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (HAS_PCH_CPT(dev)) cpt_verify_modeset(dev, intel_crtc-pipe); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); } @@ -4074,6 +4069,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_opregion_notify_encoder(encoder, true); } + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + /* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ haswell_mode_set_planes_workaround(intel_crtc); @@ -4109,6 +4107,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) encoder-disable(encoder); @@ -4175,6 +4176,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) { intel_opregion_notify_encoder(encoder, false); encoder-disable(encoder); @@ -4638,6 +4642,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder-enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* Underruns don't raise interrupts, so check manually. */ @@ -4695,6 +4702,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder-enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* @@ -4758,9 +4768,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_set_memory_cxsr(dev_priv, false); intel_crtc_disable_planes(crtc); - for_each_encoder_on_crtc(dev, crtc, encoder) - encoder-disable(encoder); - /* * On gen2 planes are double buffered but the pipe isn't, so we
Re: [Intel-gfx] [PATCH 2/5] drm/i915: Do not access stolen memory directly by the CPU, even for error capture
On Thu, Aug 14, 2014 at 05:51:48PM +0300, Mika Kuoppala wrote: Chris Wilson ch...@chris-wilson.co.uk writes: For stolen pages, since it is verboten to access them directly on many architectures, we have to read them through the GTT aperture. If they are not accessible through the aperture, then we have to abort. This was complicated by commit 8b6124a633d8095b0c8364f585edff9c59568a96 Author: Chris Wilson ch...@chris-wilson.co.uk Date: Thu Jan 30 14:38:16 2014 + drm/i915: Don't access snooped pages through the GTT (even for error capture) and the desire to use stolen memory for ringbuffers, contexts and batches in the future. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gpu_error.c | 50 ++- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 35e70d5..6d280c07 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -561,10 +561,11 @@ static struct drm_i915_error_object * i915_error_object_create_sized(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *src, struct i915_address_space *vm, - const int num_pages) + int num_pages) { struct drm_i915_error_object *dst; - int i; + bool use_ggtt; + int i = 0; u32 reloc_offset; if (src == NULL || src-pages == NULL) @@ -574,8 +575,32 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, if (dst == NULL) return NULL; - reloc_offset = dst-gtt_offset = i915_gem_obj_offset(src, vm); - for (i = 0; i num_pages; i++) { + dst-gtt_offset = i915_gem_obj_offset(src, vm); + + reloc_offset = dst-gtt_offset; + use_ggtt = (src-cache_level == I915_CACHE_NONE + i915_is_ggtt(vm) + src-has_global_gtt_mapping + reloc_offset + num_pages * PAGE_SIZE = dev_priv-gtt.mappable_end); + + /* Cannot access stolen address directly, try to use the aperture */ + if (src-stolen) { + use_ggtt = true; + + if (!src-has_global_gtt_mapping) + goto unwind; + + reloc_offset = i915_gem_obj_ggtt_offset(src); + if (reloc_offset + num_pages * PAGE_SIZE dev_priv-gtt.mappable_end) + goto unwind; + } + + /* Cannot access snooped pages through the aperture */ + if (use_ggtt src-cache_level != I915_CACHE_NONE !HAS_LLC(dev_priv-dev)) + goto unwind; Why do we need to bail out if we dont have LLC ? It is verboten to access snooped PTEs through the GTT. (As in it will hang some machines.) -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 v3] drm/i915/bdw: BDW Software Turbo
On Mon, 11 Aug 2014 23:33:57 +0200 Daniel Vetter dan...@ffwll.ch wrote: On Mon, Aug 11, 2014 at 11:08:38AM -0700, Daisy Sun wrote: BDW supports GT C0 residency reporting in constant time unit. Driver calculates GT utilization based on C0 residency and adjusts RP frequency up/down accordingly. For offscreen workload specificly, set frequency to RP0. Offscreen task is not restricted by frame rate, it can be executed as soon as possible. Transcoding and serilized workload between CPU and GPU both need high GT performance, RP0 is a good option in this case. RC6 will kick in to compensate power consumption when GT is not active. v2: Rebase on recent drm-intel-nightly v3: Add flip timerout monitor, when no flip is deteced within 100ms, set frequency to RP0. Ok, let's make this really clear: If you wire this into the flip handling in any way, I will not merge your patch. The timer should be fully independant and tie into the gpu busy/idle handling we already have. Sounds like Daisy won't be able to spend any more time on this either. So we're left with this patch, which does improve things for most cases, or no patch, which leaves things universally bad. Unless someone wants to pick up the additional work and testing of using a timer scheme, making sure we don't have needless wakeups, and generally improve power/perf across even more cases than this patch. -- Jesse Barnes, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Track cursor changes as frontbuffer tracking flushes
Tested-by and Reviewed-by: Rodrigo Vivi rodrigo.v...@intel.com On Fri, Aug 8, 2014 at 11:27 AM, Daniel Vetter daniel.vet...@ffwll.ch wrote: We treat other plane updates in the same fashion. Spotted because Rodrigo kept reporting a bug in the PSR code where the frontbuffer was eternally stuck with a dirty cursor bit set. The psr testcase should have caught this, but that i-g-t is kaputt. Rodrigo is signed up to fix that. Cc: Rodrigo Vivi rodrigo.v...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fac7bdfe9ec8..91984710b841 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11677,6 +11677,10 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h); } else { intel_crtc_update_cursor(crtc, visible); + + intel_frontbuffer_flip(crtc-dev, + INTEL_FRONTBUFFER_CURSOR(intel_crtc-pipe)); + return 0; } } -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Rodrigo Vivi Blog: http://blog.vivi.eng.br ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [REGRESSION BISECTED] backlight control stops workin with 3.14 and later
Hi Jani, On 13-8-2014 3:43, Jani Nikula wrote: On Wed, 23 Jul 2014, Hans de Goede hdego...@redhat.com wrote: On 07/22/2014 08:52 AM, Daniel Vetter wrote: On Tue, Jul 22, 2014 at 8:42 AM, Hans de Goede hdego...@redhat.com wrote: snip Also please grab latest intel-gpu-tools and record a register dump with intel_reg_dump, again for both broken and working kernels. Bertrik, can you do this please (without the blacklisting or special kernel commandline options). Please attach dmesg with drm.debug=0xe module parameter set for some recent kernel. Attached is dmesg output from booting kernel 3.14-2 (debian unstable) with drm.debug=0xe and the samsung_laptop module enabled, from my Samsung N150plus netbook. If you need anything else, please let me know. Thanks for looking into this, Bertrik Sikken [0.00] CPU0 microcode updated early to revision 0x107, date = 2009-08-25 [0.00] Initializing cgroup subsys cpuset [0.00] Initializing cgroup subsys cpu [0.00] Initializing cgroup subsys cpuacct [0.00] Linux version 3.14-2-amd64 (debian-ker...@lists.debian.org) (gcc version 4.8.3 (Debian 4.8.3-7) ) #1 SMP Debian 3.14.15-2 (2014-08-09) [0.00] Command line: BOOT_IMAGE=/boot/vmlinuz-3.14-2-amd64 root=UUID=d72b9d1c-1e83-43c5-b5b9-e7ad03e8bd9d ro quiet init=/bin/systemd drm.debug=0xe [0.00] e820: BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x0009dbff] usable [0.00] BIOS-e820: [mem 0x0009dc00-0x0009] reserved [0.00] BIOS-e820: [mem 0x000ce000-0x000c] reserved [0.00] BIOS-e820: [mem 0x000dc000-0x000d] reserved [0.00] BIOS-e820: [mem 0x000e4000-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0x7f5a] usable [0.00] BIOS-e820: [mem 0x7f5b-0x7f5b] ACPI data [0.00] BIOS-e820: [mem 0x7f5c-0x7f5c2fff] ACPI NVS [0.00] BIOS-e820: [mem 0x7f5c3000-0x7fff] reserved [0.00] BIOS-e820: [mem 0xe000-0xefff] reserved [0.00] BIOS-e820: [mem 0xfec0-0xfec0] reserved [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved [0.00] BIOS-e820: [mem 0xff00-0x] reserved [0.00] NX (Execute Disable) protection: active [0.00] SMBIOS 2.5 present. [0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. N150P/N210P/N220P /N150P/N210P/N220P , BIOS 02KY.M021.20101217.RHU 12/17/2010 [0.00] e820: update [mem 0x-0x0fff] usable == reserved [0.00] e820: remove [mem 0x000a-0x000f] usable [0.00] No AGP bridge found [0.00] e820: last_pfn = 0x7f5b0 max_arch_pfn = 0x4 [0.00] MTRR default type: uncachable [0.00] MTRR fixed ranges enabled: [0.00] 0-9 write-back [0.00] A-B uncachable [0.00] C-C write-protect [0.00] D-D uncachable [0.00] E-F write-protect [0.00] MTRR variable ranges enabled: [0.00] 0 base 0 mask 08000 write-back [0.00] 1 base 07F60 mask 0FFE0 uncachable [0.00] 2 base 07F80 mask 0FF80 uncachable [0.00] 3 disabled [0.00] 4 disabled [0.00] 5 disabled [0.00] 6 disabled [0.00] 7 disabled [0.00] x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106 [0.00] found SMP MP-table at [mem 0x000f7d40-0x000f7d4f] mapped at [880f7d40] [0.00] Base memory trampoline at [88097000] 97000 size 24576 [0.00] init_memory_mapping: [mem 0x-0x000f] [0.00] [mem 0x-0x000f] page 4k [0.00] BRK [0x01aaf000, 0x01aa] PGTABLE [0.00] BRK [0x01ab, 0x01ab0fff] PGTABLE [0.00] BRK [0x01ab1000, 0x01ab1fff] PGTABLE [0.00] init_memory_mapping: [mem 0x7f20-0x7f3f] [0.00] [mem 0x7f20-0x7f3f] page 2M [0.00] BRK [0x01ab2000, 0x01ab2fff] PGTABLE [0.00] init_memory_mapping: [mem 0x7c00-0x7f1f] [0.00] [mem 0x7c00-0x7f1f] page 2M [0.00] init_memory_mapping: [mem 0x0010-0x7bff] [0.00] [mem 0x0010-0x001f] page 4k [0.00] [mem 0x0020-0x7bff] page 2M [0.00] init_memory_mapping: [mem 0x7f40-0x7f5a] [0.00] [mem 0x7f40-0x7f5a] page 4k [0.00] BRK [0x01ab3000, 0x01ab3fff] PGTABLE [0.00] RAMDISK: [mem 0x36548000-0x3729bfff] [0.00] ACPI: RSDP 000f7d10 24 (v02 PTLTD ) [0.00] ACPI: XSDT 7f5b8d8d 6C (v01 SECCSD LH43STAR 0604 LTP ) [0.00] ACPI: FACP 7f5bfc92 F4 (v03 INTEL 0604
Re: [Intel-gfx] [PATCH 27/43] drm/i915/bdw: Render state init for Execlists
On Wed, Aug 13, 2014 at 05:30:07PM +0200, Daniel Vetter wrote: On Wed, Aug 13, 2014 at 03:07:29PM +, Daniel, Thomas wrote: -Original Message- From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter Sent: Monday, August 11, 2014 10:25 PM To: Daniel, Thomas Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 27/43] drm/i915/bdw: Render state init for Execlists On Thu, Jul 24, 2014 at 05:04:35PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com index 9085ff1..0dc6992 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -513,8 +513,23 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ppgtt-enable(ppgtt); } - if (i915.enable_execlists) + if (i915.enable_execlists) { + struct intel_context *dctx; + + ring = dev_priv-ring[RCS]; + dctx = ring-default_context; + + if (!dctx-rcs_initialized) { + ret = intel_lr_context_render_state_init(ring, dctx); + if (ret) { + DRM_ERROR(Init render state failed: %d\n, ret); + return ret; + } + dctx-rcs_initialized = true; + } + return 0; + } This looks very much like the wrong place. We should init the render state when we create the context, or when we switch to it for the first time. The later is what the legacy contexts currently do in do_switch. But ctx_enable should do the switch to the default context and that's about Well, a side-effect of switching to the default context in legacy mode is that the render state gets initialized. I could move the lr render state init call into an enable_execlists branch in i915_switch_context() but that doen't seem like the right place. How about in i915_gem_init() after calling i915_gem_init_hw()? it. If there's some depency then I guess we should stall the creation of the default context a bit, maybe. In any case someone needs to explain this better and if there's not other wey this at least needs a bit comment. So I'll punt for now. When the default context is created the driver is not ready to execute a batch. That is why the render state init can't be done then. That sounds like the default context is created too early. Essentially I want to avoid needless divergence between the default context and normal contexts, because sooner or later that will means someone will creep in with a _really_ subtle bug. What about: - We create the default lrc contexs in context_init, but like with a normal context we don't do any of the deferred setup. - In context_enable (which since yesterday properly propagates errors to callers) we force the deferred lrc ctx setup for the default contexts on all engines. - The render state init is done as part of the deferred ctx setup for the render engine in all cases. Totally off the track or do you see a workable solution somewhere in that direction? I'd like to discuss this first a bit more, so will punt on this patch for now. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: fix plane/cursor handling when runtime suspended
2014-08-14 12:06 GMT-03:00 Paulo Zanoni przan...@gmail.com: From: Paulo Zanoni paulo.r.zan...@intel.com If we're runtime suspended and try to use the plane interfaces, we will get a lot of WARNs saying we did the wrong thing. We need to get runtime PM references to pin the objects, and to change the fences. The pin functions are the ideal places for this, but intel_crtc_cursor_set_obj() doesn't call them, so we also have to add get/put calls inside it. There is no problem if we runtime suspend right after these functions are finished, because the registers written are forwarded to system memory. Note: for a complete fix of the cursor-dpms test case, we also need the patch named drm/i915: Don't try to enable cursor from setplane when crtc is disabled. v2: - Narrow the put/get calls on intel_crtc_cursor_set_obj() (Daniel) v3: - Make get/put also surround the fence and unpin calls (Daniel and Ville). - Merge all the plane changes into a single patch since they're the same fix. - Add the comment requested by Daniel. v4: - Remove spurious whitespace (Ville). v5: - Remove intel_crtc_update_cursor() chunk since Ville did an equivalent fix in another patch (Ville). v6: - Remove unpin chunk: it will be on a separate patch (Ville, Chris, Daniel). Testcase: igt/pm_rpm/cursor Testcase: igt/pm_rpm/cursor-dpms Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81645 And now we also have a report from QA: Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82603 Cc: sta...@vger.kernel.org Signed-off-by: Paulo Zanoni paulo.r.zan...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 27 +++ 1 file changed, 27 insertions(+) I talked with Daniel and we agreed to leave any possible fixes related with the unpin functions to separate patches, possibly requiring separate IGT test cases. diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3813526..17bc661 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2149,6 +2149,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, if (need_vtd_wa(dev) alignment 256 * 1024) alignment = 256 * 1024; + /* +* Global gtt pte registers are special registers which actually forward +* writes to a chunk of system memory. Which means that there is no risk +* that the register values disappear as soon as we call +* intel_runtime_pm_put(), so it is correct to wrap only the +* pin/unpin/fence and not more. +*/ + intel_runtime_pm_get(dev_priv); + dev_priv-mm.interruptible = false; ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); if (ret) @@ -2166,12 +2175,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, i915_gem_object_pin_fence(obj); dev_priv-mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return 0; err_unpin: i915_gem_object_unpin_from_display_plane(obj); err_interruptible: dev_priv-mm.interruptible = true; + intel_runtime_pm_put(dev_priv); return ret; } @@ -8201,6 +8212,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, uint32_t width, uint32_t height) { struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc-pipe; unsigned old_width, stride; @@ -8231,6 +8243,16 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(dev-struct_mutex); + + /* +* Global gtt pte registers are special registers which actually forward +* writes to a chunk of system memory. Which means that there is no risk +* that the register values disappear as soon as we call +* intel_runtime_pm_put(), so it is correct to wrap only the +* pin/unpin/fence and not more. +*/ + intel_runtime_pm_get(dev_priv); + if (!INTEL_INFO(dev)-cursor_needs_physical) { unsigned alignment; @@ -8280,6 +8302,10 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, i915_gem_track_fb(intel_crtc-cursor_bo, obj, INTEL_FRONTBUFFER_CURSOR(pipe)); + + if (obj) + intel_runtime_pm_put(dev_priv); + mutex_unlock(dev-struct_mutex); old_width = intel_crtc-cursor_width; @@ -8301,6 +8327,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
Re: [Intel-gfx] [PATCH 30/43] drm/i915/bdw: Two-stage execlist submit process
On Thu, Jul 24, 2014 at 05:04:38PM +0100, Thomas Daniel wrote: From: Michel Thierry michel.thie...@intel.com Context switch (and execlist submission) should happen only when other contexts are not active, otherwise pre-emption occurs. To assure this, we place context switch requests in a queue and those request are later consumed when the right context switch interrupt is received (still TODO). v2: Use a spinlock, do not remove the requests on unqueue (wait for context switch completion). Signed-off-by: Thomas Daniel thomas.dan...@intel.com v3: Several rebases and code changes. Use unique ID. v4: - Move the queue/lock init to the late ring initialization. - Damien's kmalloc review comments: check return, use sizeof(*req), do not cast. v5: - Do not reuse drm_i915_gem_request. Instead, create our own. - New namespace. Signed-off-by: Michel Thierry michel.thie...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2-v5) --- drivers/gpu/drm/i915/intel_lrc.c| 63 ++- drivers/gpu/drm/i915/intel_lrc.h|8 drivers/gpu/drm/i915/intel_ringbuffer.h |2 + 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5b6f416..9e91169 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -217,6 +217,63 @@ static int execlists_submit_context(struct intel_engine_cs *ring, return 0; } +static void execlists_context_unqueue(struct intel_engine_cs *ring) +{ + struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL; + struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL; + + if (list_empty(ring-execlist_queue)) + return; + + /* Try to read in pairs */ + list_for_each_entry_safe(cursor, tmp, ring-execlist_queue, execlist_link) { + if (!req0) + req0 = cursor; + else if (req0-ctx == cursor-ctx) { + /* Same ctx: ignore first request, as second request + * will update tail past first request's workload */ + list_del(req0-execlist_link); + i915_gem_context_unreference(req0-ctx); + kfree(req0); + req0 = cursor; + } else { + req1 = cursor; + break; + } + } + + BUG_ON(execlists_submit_context(ring, req0-ctx, req0-tail, + req1? req1-ctx : NULL, req1? req1-tail : 0)); You don't get to hard-hang my driver just because you've done a programming mistake. Please remember my commandements ;-) Also checkpatch ... -Daniel +} + +static int execlists_context_queue(struct intel_engine_cs *ring, +struct intel_context *to, +u32 tail) +{ + struct intel_ctx_submit_request *req = NULL; + unsigned long flags; + bool was_empty; + + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (req == NULL) + return -ENOMEM; + req-ctx = to; + i915_gem_context_reference(req-ctx); + req-ring = ring; + req-tail = tail; + + spin_lock_irqsave(ring-execlist_lock, flags); + + was_empty = list_empty(ring-execlist_queue); + list_add_tail(req-execlist_link, ring-execlist_queue); + if (was_empty) + execlists_context_unqueue(ring); + + spin_unlock_irqrestore(ring-execlist_lock, flags); + + return 0; +} + static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) { struct intel_engine_cs *ring = ringbuf-ring; @@ -405,8 +462,7 @@ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) if (intel_ring_stopped(ring)) return; - /* FIXME: too cheeky, we don't even check if the ELSP is ready */ - execlists_submit_context(ring, ctx, ringbuf-tail, NULL, 0); + execlists_context_queue(ring, ctx, ringbuf-tail); } static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, @@ -850,6 +906,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin INIT_LIST_HEAD(ring-request_list); init_waitqueue_head(ring-irq_queue); + INIT_LIST_HEAD(ring-execlist_queue); + spin_lock_init(ring-execlist_lock); + ret = intel_lr_context_deferred_create(dctx, ring); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index b59965b..14492a9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -60,4 +60,12 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, u64 exec_start, u32 flags); u32 intel_execlists_ctx_id(struct
Re: [Intel-gfx] [PATCH 30/43] drm/i915/bdw: Two-stage execlist submit process
On Thu, Jul 24, 2014 at 05:04:38PM +0100, Thomas Daniel wrote: From: Michel Thierry michel.thie...@intel.com Context switch (and execlist submission) should happen only when other contexts are not active, otherwise pre-emption occurs. To assure this, we place context switch requests in a queue and those request are later consumed when the right context switch interrupt is received (still TODO). v2: Use a spinlock, do not remove the requests on unqueue (wait for context switch completion). Signed-off-by: Thomas Daniel thomas.dan...@intel.com v3: Several rebases and code changes. Use unique ID. v4: - Move the queue/lock init to the late ring initialization. - Damien's kmalloc review comments: check return, use sizeof(*req), do not cast. v5: - Do not reuse drm_i915_gem_request. Instead, create our own. - New namespace. Signed-off-by: Michel Thierry michel.thie...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2-v5) --- drivers/gpu/drm/i915/intel_lrc.c| 63 ++- drivers/gpu/drm/i915/intel_lrc.h|8 drivers/gpu/drm/i915/intel_ringbuffer.h |2 + 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5b6f416..9e91169 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -217,6 +217,63 @@ static int execlists_submit_context(struct intel_engine_cs *ring, return 0; } +static void execlists_context_unqueue(struct intel_engine_cs *ring) +{ + struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL; + struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL; + + if (list_empty(ring-execlist_queue)) + return; + + /* Try to read in pairs */ + list_for_each_entry_safe(cursor, tmp, ring-execlist_queue, execlist_link) { Ok, because checkpatch I've looked at this. Imo open-coding this would be much easier to read i.e. if (!list_empty) grabremove first item; if (!list_empty) grabremove 2nd item; Care to follow up with a patch for that? Thanks, Daniel + if (!req0) + req0 = cursor; + else if (req0-ctx == cursor-ctx) { + /* Same ctx: ignore first request, as second request + * will update tail past first request's workload */ + list_del(req0-execlist_link); + i915_gem_context_unreference(req0-ctx); + kfree(req0); + req0 = cursor; + } else { + req1 = cursor; + break; + } + } + + BUG_ON(execlists_submit_context(ring, req0-ctx, req0-tail, + req1? req1-ctx : NULL, req1? req1-tail : 0)); +} + +static int execlists_context_queue(struct intel_engine_cs *ring, +struct intel_context *to, +u32 tail) +{ + struct intel_ctx_submit_request *req = NULL; + unsigned long flags; + bool was_empty; + + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (req == NULL) + return -ENOMEM; + req-ctx = to; + i915_gem_context_reference(req-ctx); + req-ring = ring; + req-tail = tail; + + spin_lock_irqsave(ring-execlist_lock, flags); + + was_empty = list_empty(ring-execlist_queue); + list_add_tail(req-execlist_link, ring-execlist_queue); + if (was_empty) + execlists_context_unqueue(ring); + + spin_unlock_irqrestore(ring-execlist_lock, flags); + + return 0; +} + static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) { struct intel_engine_cs *ring = ringbuf-ring; @@ -405,8 +462,7 @@ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) if (intel_ring_stopped(ring)) return; - /* FIXME: too cheeky, we don't even check if the ELSP is ready */ - execlists_submit_context(ring, ctx, ringbuf-tail, NULL, 0); + execlists_context_queue(ring, ctx, ringbuf-tail); } static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, @@ -850,6 +906,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin INIT_LIST_HEAD(ring-request_list); init_waitqueue_head(ring-irq_queue); + INIT_LIST_HEAD(ring-execlist_queue); + spin_lock_init(ring-execlist_lock); + ret = intel_lr_context_deferred_create(dctx, ring); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index b59965b..14492a9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -60,4 +60,12 @@ int intel_execlists_submission(struct drm_device
Re: [Intel-gfx] [PATCH 31/43] drm/i915/bdw: Handle context switch events
On Thu, Jul 24, 2014 at 05:04:39PM +0100, Thomas Daniel wrote: Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel thomas.dan...@intel.com v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett robert.beck...@intel.com). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt, as suggested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 35 ++--- drivers/gpu/drm/i915/intel_lrc.c| 129 +-- drivers/gpu/drm/i915/intel_lrc.h|3 + drivers/gpu/drm/i915/intel_ringbuffer.h |1 + 4 files changed, 151 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f77a4ca..e4077d1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1628,6 +1628,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) { + struct intel_engine_cs *ring; u32 rcs, bcs, vcs; uint32_t tmp = 0; irqreturn_t ret = IRQ_NONE; @@ -1637,14 +1638,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(0), tmp); ret = IRQ_HANDLED; + rcs = tmp GEN8_RCS_IRQ_SHIFT; - bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[RCS]; if (rcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[RCS]); + notify_ring(dev, ring); + if (rcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); + + bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[BCS]; if (bcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[BCS]); - if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + notify_ring(dev, ring); + if (bcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1654,16 +1661,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(1), tmp); ret = IRQ_HANDLED; + vcs = tmp GEN8_VCS1_IRQ_SHIFT; + ring = dev_priv-ring[VCS]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); + vcs = tmp GEN8_VCS2_IRQ_SHIFT; + ring = dev_priv-ring[VCS2]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS2]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1684,11 +1695,13 @@ static irqreturn_t
Re: [Intel-gfx] [PATCH 31/43] drm/i915/bdw: Handle context switch events
On Thu, Jul 24, 2014 at 05:04:39PM +0100, Thomas Daniel wrote: Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel thomas.dan...@intel.com v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett robert.beck...@intel.com). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt, as suggested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 35 ++--- drivers/gpu/drm/i915/intel_lrc.c| 129 +-- drivers/gpu/drm/i915/intel_lrc.h|3 + drivers/gpu/drm/i915/intel_ringbuffer.h |1 + 4 files changed, 151 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f77a4ca..e4077d1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1628,6 +1628,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) { + struct intel_engine_cs *ring; u32 rcs, bcs, vcs; uint32_t tmp = 0; irqreturn_t ret = IRQ_NONE; @@ -1637,14 +1638,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(0), tmp); ret = IRQ_HANDLED; + rcs = tmp GEN8_RCS_IRQ_SHIFT; - bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[RCS]; if (rcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[RCS]); + notify_ring(dev, ring); + if (rcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); + + bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[BCS]; if (bcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[BCS]); - if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + notify_ring(dev, ring); + if (bcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); Also patch split fail here, the above two cases should have been in an earlier patch that added the basic irq handling. -Daniel } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1654,16 +1661,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(1), tmp); ret = IRQ_HANDLED; + vcs = tmp GEN8_VCS1_IRQ_SHIFT; + ring = dev_priv-ring[VCS]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); + vcs = tmp GEN8_VCS2_IRQ_SHIFT; + ring = dev_priv-ring[VCS2]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS2]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); } else
Re: [Intel-gfx] [PATCH 31/43] drm/i915/bdw: Handle context switch events
On Thu, Jul 24, 2014 at 05:04:39PM +0100, Thomas Daniel wrote: Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel thomas.dan...@intel.com v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett robert.beck...@intel.com). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt, as suggested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com +static void execlists_free_request_task(struct work_struct *work) +{ + struct intel_ctx_submit_request *req = + container_of(work, struct intel_ctx_submit_request, work); + struct drm_device *dev = req-ring-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + + intel_runtime_pm_put(dev_priv); + + mutex_lock(dev-struct_mutex); + i915_gem_context_unreference(req-ctx); + mutex_unlock(dev-struct_mutex); + + kfree(req); +} Latching a work item simply for the unference of the context looks very fishy. The context really can't possible disappear before the last request on it has completed, since the request already holds a reference. That you have this additional reference here makes it look a bit like the relationship and lifetime rules for the execlist queue item is misshapen. I'd have expected: - A given execlist queue item is responsible for a list of requests (one or more) - Each request already holds onto the context. The other thing that's strange here is the runtime pm handling. We already keep the device awake as long as it's busy, so I wonder why exactly we need this here in addition. In any case these kind of cleanup tasks are imo better done in the retire request handler that we already have. Imo needs some cleanup. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 32/43] drm/i915/bdw: Avoid non-lite-restore preemptions
On Thu, Jul 24, 2014 at 05:04:40PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com In the current Execlists feeding mechanism, full preemption is not supported yet: only lite-restores are allowed (this is: the GPU simply samples a new tail pointer for the context currently in execution). But we have identified an scenario in which a full preemption occurs: 1) We submit two contexts for execution (A B). 2) The GPU finishes with the first one (A), switches to the second one (B) and informs us. 3) We submit B again (hoping to cause a lite restore) together with C, but in the time we spend writing to the ELSP, the GPU finishes B. 4) The GPU start executing B again (since we told it so). 5) We receive a B finished interrupt and, mistakenly, we submit C (again) and D, causing a full preemption of B. The race is avoided by keeping track of how many times a context has been submitted to the hardware and by better discriminating the received context switch interrupts: in the example, when we have submitted B twice, we won´t submit C and D as soon as we receive the notification that B is completed because we were expecting to get a LITE_RESTORE and we didn´t, so we know a second completion will be received shortly. Without this explicit checking, somehow, the batch buffer execution order gets messed with. This can be verified with the IGT test I sent together with the series. I don´t know the exact mechanism by which the pre-emption messes with the execution order but, since other people is working on the Scheduler + Preemption on Execlists, I didn´t try to fix it. In these series, only Lite Restores are supported (other kind of preemptions WARN). Where's this igt patch? The kernel patch here is at least missing the Testcase: igt/foo tag. Please supply. -Daniel v2: elsp_submitted belongs in the new intel_ctx_submit_request. Several rebase changes. v3: Clarify how the race is avoided, as requested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 28 drivers/gpu/drm/i915/intel_lrc.h |2 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 65f4f26..895dbfc 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -264,6 +264,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) else if (req0-ctx == cursor-ctx) { /* Same ctx: ignore first request, as second request * will update tail past first request's workload */ + cursor-elsp_submitted = req0-elsp_submitted; list_del(req0-execlist_link); queue_work(dev_priv-wq, req0-work); req0 = cursor; @@ -273,8 +274,14 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) } } + WARN_ON(req1 req1-elsp_submitted); + BUG_ON(execlists_submit_context(ring, req0-ctx, req0-tail, req1? req1-ctx : NULL, req1? req1-tail : 0)); + + req0-elsp_submitted++; + if (req1) + req1-elsp_submitted++; } static bool execlists_check_remove_request(struct intel_engine_cs *ring, @@ -291,9 +298,13 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, struct drm_i915_gem_object *ctx_obj = head_req-ctx-engine[ring-id].state; if (intel_execlists_ctx_id(ctx_obj) == request_id) { - list_del(head_req-execlist_link); - queue_work(dev_priv-wq, head_req-work); - return true; + WARN(head_req-elsp_submitted == 0, + Never submitted head request\n); + if (--head_req-elsp_submitted = 0) { + list_del(head_req-execlist_link); + queue_work(dev_priv-wq, head_req-work); + return true; + } } } @@ -326,7 +337,16 @@ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + (read_pointer % 6) * 8 + 4); - if (status GEN8_CTX_STATUS_COMPLETE) { + if (status GEN8_CTX_STATUS_PREEMPTED) { + if (status GEN8_CTX_STATUS_LITE_RESTORE) { + if (execlists_check_remove_request(ring, status_id)) + WARN(1, Lite Restored request removed from queue\n); + } else + WARN(1, Preemption without Lite Restore\n); + } + + if
Re: [Intel-gfx] [PATCH 31/43] drm/i915/bdw: Handle context switch events
On Thu, Jul 24, 2014 at 05:04:39PM +0100, Thomas Daniel wrote: Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel thomas.dan...@intel.com v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett robert.beck...@intel.com). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt, as suggested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com One more ... +void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) Please rename this to intel_execlist_ctx_events_irq_handler or similar for consistency with all the other irq handler functions in a follow-up patch. That kind of consistency helps a lot when reviewing the locking of irq-save spinlocks. -Daniel +{ + struct drm_i915_private *dev_priv = ring-dev-dev_private; + u32 status_pointer; + u8 read_pointer; + u8 write_pointer; + u32 status; + u32 status_id; + u32 submit_contexts = 0; + + status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); + + read_pointer = ring-next_context_status_buffer; + write_pointer = status_pointer 0x07; + if (read_pointer write_pointer) + write_pointer += 6; + + spin_lock(ring-execlist_lock); + + while (read_pointer write_pointer) { + read_pointer++; + status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + + (read_pointer % 6) * 8); + status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + + (read_pointer % 6) * 8 + 4); + + if (status GEN8_CTX_STATUS_COMPLETE) { + if (execlists_check_remove_request(ring, status_id)) + submit_contexts++; + } + } + + if (submit_contexts != 0) + execlists_context_unqueue(ring); + + spin_unlock(ring-execlist_lock); + + WARN(submit_contexts 2, More than two context complete events?\n); + ring-next_context_status_buffer = write_pointer % 6; + + I915_WRITE(RING_CONTEXT_STATUS_PTR(ring), + ((u32)ring-next_context_status_buffer 0x07) 8); +} + +static void execlists_free_request_task(struct work_struct *work) +{ + struct intel_ctx_submit_request *req = + container_of(work, struct intel_ctx_submit_request, work); + struct drm_device *dev = req-ring-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + + intel_runtime_pm_put(dev_priv); + + mutex_lock(dev-struct_mutex); + i915_gem_context_unreference(req-ctx); + mutex_unlock(dev-struct_mutex); + + kfree(req); +} + static int execlists_context_queue(struct intel_engine_cs *ring, struct intel_context *to, u32 tail) @@ -261,6 +375,8 @@ static int execlists_context_queue(struct intel_engine_cs *ring, i915_gem_context_reference(req-ctx); req-ring = ring; req-tail = tail; + INIT_WORK(req-work, execlists_free_request_task); + intel_runtime_pm_get(dev_priv); spin_lock_irqsave(ring-execlist_lock, flags); @@ -908,6 +1024,7 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin INIT_LIST_HEAD(ring-execlist_queue); spin_lock_init(ring-execlist_lock); + ring-next_context_status_buffer = 0; ret = intel_lr_context_deferred_create(dctx, ring); if (ret) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 14492a9..2e8929f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -66,6 +66,9 @@ struct intel_ctx_submit_request { u32 tail; struct list_head execlist_link; + struct work_struct work; }; +void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring); + #endif /* _INTEL_LRC_H_ */ diff --git
Re: [Intel-gfx] [PATCH 33/43] drm/i915/bdw: Help out the ctx switch interrupt handler
On Thu, Jul 24, 2014 at 05:04:41PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com If we receive a storm of requests for the same context (see gem_storedw_loop_*) we might end up iterating over too many elements in interrupt time, looking for contexts to squash together. Instead, share the burden by giving more intelligence to the queue function. At most, the interrupt will iterate over three elements. Signed-off-by: Oscar Mateo oscar.ma...@intel.com I'll continue merging after this patch tomorrow. -Daniel --- drivers/gpu/drm/i915/intel_lrc.c | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 895dbfc..829b15d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -384,9 +384,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring, struct intel_context *to, u32 tail) { - struct intel_ctx_submit_request *req = NULL; + struct drm_i915_private *dev_priv = ring-dev-dev_private; + struct intel_ctx_submit_request *req = NULL, *cursor; unsigned long flags; - bool was_empty; + int num_elements = 0; req = kzalloc(sizeof(*req), GFP_KERNEL); if (req == NULL) @@ -400,9 +401,26 @@ static int execlists_context_queue(struct intel_engine_cs *ring, spin_lock_irqsave(ring-execlist_lock, flags); - was_empty = list_empty(ring-execlist_queue); + list_for_each_entry(cursor, ring-execlist_queue, execlist_link) + if (++num_elements 2) + break; + + if (num_elements 2) { + struct intel_ctx_submit_request *tail_req; + + tail_req = list_last_entry(ring-execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + if (to == tail_req-ctx) { + WARN(tail_req-elsp_submitted != 0, + More than 2 already-submitted reqs queued\n); + list_del(tail_req-execlist_link); + queue_work(dev_priv-wq, tail_req-work); + } + } + list_add_tail(req-execlist_link, ring-execlist_queue); - if (was_empty) + if (num_elements == 0) execlists_context_unqueue(ring); spin_unlock_irqrestore(ring-execlist_lock, flags); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Track cursor changes as frontbuffer tracking flushes
On Thu, Aug 14, 2014 at 12:49:06PM -0700, Rodrigo Vivi wrote: Tested-by and Reviewed-by: Rodrigo Vivi rodrigo.v...@intel.com Thanks a lot for testing and review, happy that we've tracked this one down. Patch merged to dinq (since psr is unfortunately already disabled again in 3.17 upstream). -Daniel On Fri, Aug 8, 2014 at 11:27 AM, Daniel Vetter daniel.vet...@ffwll.ch wrote: We treat other plane updates in the same fashion. Spotted because Rodrigo kept reporting a bug in the PSR code where the frontbuffer was eternally stuck with a dirty cursor bit set. The psr testcase should have caught this, but that i-g-t is kaputt. Rodrigo is signed up to fix that. Cc: Rodrigo Vivi rodrigo.v...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fac7bdfe9ec8..91984710b841 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11677,6 +11677,10 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h); } else { intel_crtc_update_cursor(crtc, visible); + + intel_frontbuffer_flip(crtc-dev, + INTEL_FRONTBUFFER_CURSOR(intel_crtc-pipe)); + return 0; } } -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Rodrigo Vivi Blog: http://blog.vivi.eng.br -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/16] drm/i915: 830M/ns201 fixes again
From: Ville Syrjälä ville.syrj...@linux.intel.com Thomas asked me to repost my 830/ns2501 patches. So here they are. I added a few more patches (trickle feed and unused ring init) to fix some post-resume issues. The primary plane rmw elimination patches and some locking/load detect fixes already got merged. Apart from these we still lack the minimum watermark check. I guess we could just take the patch Thomas posted [1]. Doesn't look like a more advanced solution is coming any time soon. Though the commit message of that patch needs work and it lacks a s-o-b. The VGACNTR patch might not be necessary any longer since Daniel's vga/dummycon stuff. I don't recall if I tested without it, but my gut feeling is that it's no longer needed. But I included the patch here anyway. [1] http://patchwork.freedesktop.org/patch/27318/ Ville Syrjälä (16): drm/i915: Fix gen2 planes B and C max watermark value drm/i915: Disable trickle feed for gen2/3 drm/i915: Idle unused rings on gen2/3 during init/resume drm/i915: Pass intel_crtc to intel_disable_pipe() and intel_wait_for_pipe_off() drm/i915: Disable double wide even when leaving the pipe on drm/i915: ns2501 is on DVOB drm/i915: Enable DVO between mode_set and dpms hooks drm/i915: Don't call DVO mode_set hook on DPMS changes drm/i915: Kill useless ns2501_dump_regs drm/i915: Rewrite ns2501 driver a bit drm/i915: Init important ns2501 registers drm/i915: Check pixel clock in ns2501 mode_valid hook drm/i915: Fix DVO 2x clock enable on 830M Revert drm/i915: Nuke pipe A quirk on i830M drm/i915: Add pipe B force quirk for 830M drm/i915: Preserve VGACNTR bits from the BIOS drivers/gpu/drm/i915/dvo_ns2501.c| 560 +-- drivers/gpu/drm/i915/i915_drv.h | 6 + drivers/gpu/drm/i915/i915_gem.c | 35 +++ drivers/gpu/drm/i915/i915_reg.h | 11 + drivers/gpu/drm/i915/intel_display.c | 150 +++--- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_dvo.c | 11 +- drivers/gpu/drm/i915/intel_pm.c | 34 ++- 8 files changed, 532 insertions(+), 276 deletions(-) -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/16] drm/i915: Idle unused rings on gen2/3 during init/resume
From: Ville Syrjälä ville.syrj...@linux.intel.com gen2/3 platforms have a boatload of rings we're not using. On my 830 the BIOS/hw can leave some of those active after resume which will prevent c3 entry. The ring is apparently considered active whenever head != tail even if the ring is disabled. Disable and clear all such unused ringbuffers on init/resume. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem.c | 35 +++ drivers/gpu/drm/i915/i915_reg.h | 7 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6c2f0b8..6cfa13e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4618,11 +4618,46 @@ intel_enable_blt(struct drm_device *dev) return true; } +static void init_unused_ring(struct drm_device *dev, u32 base) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + I915_WRITE(RING_CTL(base), 0); + I915_WRITE(RING_HEAD(base), 0); + I915_WRITE(RING_TAIL(base), 0); + I915_WRITE(RING_START(base), 0); +} + +static void init_unused_rings(struct drm_device *dev) +{ + if (IS_I830(dev)) { + init_unused_ring(dev, PRB1_BASE); + init_unused_ring(dev, SRB0_BASE); + init_unused_ring(dev, SRB1_BASE); + init_unused_ring(dev, SRB2_BASE); + init_unused_ring(dev, SRB3_BASE); + } else if (IS_GEN2(dev)) { + init_unused_ring(dev, SRB0_BASE); + init_unused_ring(dev, SRB1_BASE); + } else if (IS_GEN3(dev)) { + init_unused_ring(dev, PRB1_BASE); + init_unused_ring(dev, PRB2_BASE); + } +} + int i915_gem_init_rings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; int ret; + /* +* At least 830 can leave some of the unused rings +* active (ie. head != tail) after resume which +* will prevent c3 entry. Makes sure all unused rings +* are totally idle. +*/ + init_unused_rings(dev); + ret = intel_init_render_ring_buffer(dev); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b5fdffc..f80f9b0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1026,6 +1026,13 @@ enum punit_power_well { #define PGTBL_ADDRESS_LO_MASK0xf000 /* bits [31:12] */ #define PGTBL_ADDRESS_HI_MASK0x00f0 /* bits [35:32] (gen4) */ #define PGTBL_ER 0x02024 +#define PRB0_BASE (0x2030-0x30) +#define PRB1_BASE (0x2040-0x30) /* 830,gen3 */ +#define PRB2_BASE (0x2050-0x30) /* gen3 */ +#define SRB0_BASE (0x2100-0x30) /* gen2 */ +#define SRB1_BASE (0x2110-0x30) /* gen2 */ +#define SRB2_BASE (0x2120-0x30) /* 830 */ +#define SRB3_BASE (0x2130-0x30) /* 830 */ #define RENDER_RING_BASE 0x02000 #define BSD_RING_BASE 0x04000 #define GEN6_BSD_RING_BASE 0x12000 -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/16] drm/i915: Fix gen2 planes B and C max watermark value
From: Ville Syrjälä ville.syrj...@linux.intel.com The max watermark value for gen2 planes B and C is 0x1f, instead of the 0x3f that plane A uses. Also check against the max even if the pipe is disabled since the FIFO size exceeds the plane B and C max watermark value. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 24 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 12f4e14..f696b7f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -985,13 +985,20 @@ static const struct intel_watermark_params i915_wm_info = { .guard_size = 2, .cacheline_size = I915_FIFO_LINE_SIZE, }; -static const struct intel_watermark_params i830_wm_info = { +static const struct intel_watermark_params i830_a_wm_info = { .fifo_size = I855GM_FIFO_SIZE, .max_wm = I915_MAX_WM, .default_wm = 1, .guard_size = 2, .cacheline_size = I830_FIFO_LINE_SIZE, }; +static const struct intel_watermark_params i830_bc_wm_info = { + .fifo_size = I855GM_FIFO_SIZE, + .max_wm = I915_MAX_WM/2, + .default_wm = 1, + .guard_size = 2, + .cacheline_size = I830_FIFO_LINE_SIZE, +}; static const struct intel_watermark_params i845_wm_info = { .fifo_size = I830_FIFO_SIZE, .max_wm = I915_MAX_WM, @@ -1673,7 +1680,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) else if (!IS_GEN2(dev)) wm_info = i915_wm_info; else - wm_info = i830_wm_info; + wm_info = i830_a_wm_info; fifo_size = dev_priv-display.get_fifo_size(dev, 0); crtc = intel_get_crtc_for_plane(dev, 0); @@ -1688,8 +1695,14 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) wm_info, fifo_size, cpp, latency_ns); enabled = crtc; - } else + } else { planea_wm = fifo_size - wm_info-guard_size; + if (planea_wm (long)wm_info-max_wm) + planea_wm = wm_info-max_wm; + } + + if (IS_GEN2(dev)) + wm_info = i830_bc_wm_info; fifo_size = dev_priv-display.get_fifo_size(dev, 1); crtc = intel_get_crtc_for_plane(dev, 1); @@ -1707,8 +1720,11 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) enabled = crtc; else enabled = NULL; - } else + } else { planeb_wm = fifo_size - wm_info-guard_size; + if (planeb_wm (long)wm_info-max_wm) + planeb_wm = wm_info-max_wm; + } DRM_DEBUG_KMS(FIFO watermarks - A: %d, B: %d\n, planea_wm, planeb_wm); -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/16] drm/i915: Disable trickle feed for gen2/3
From: Ville Syrjälä ville.syrj...@linux.intel.com My 830 is unhappy with trickle feed enabled. The symptom is that the image on the screen shifts a bit to right occasionally. The BIOS initially disables trickle feed, but it gets reset during suspend, so we need to re-disable it ourselves. Juse disable it always. Also disable it for all other gen2/3 platforms since we disable it for all more recent platforms as well (until HSW that is). At least my 855 doesn't seem to mind us doing this. I don't have gen3 hardware to test that. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 drivers/gpu/drm/i915/intel_pm.c | 10 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 203062e..b5fdffc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1272,6 +1272,10 @@ enum punit_power_well { #define INSTPM_TLB_INVALIDATE(19) #define INSTPM_SYNC_FLUSH(15) #define ACTHD 0x020c8 +#define MEM_MODE 0x020cc +#define MEM_DISPLAY_B_TRICKLE_FEED_DISABLE (13) /* 830 only */ +#define MEM_DISPLAY_A_TRICKLE_FEED_DISABLE (12) /* 830/845 only */ +#define MEM_DISPLAY_TRICKLE_FEED_DISABLE (12) /* 85x only */ #define FW_BLC 0x020d8 #define FW_BLC20x020dc #define FW_BLC_SELF0x020e0 /* 915+ only */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f696b7f..2865948 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6020,6 +6020,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); + + I915_WRITE(MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } static void i85x_init_clock_gating(struct drm_device *dev) @@ -6031,6 +6034,9 @@ static void i85x_init_clock_gating(struct drm_device *dev) /* interrupts should cause a wake up from C3 */ I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); + + I915_WRITE(MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); } static void i830_init_clock_gating(struct drm_device *dev) @@ -6038,6 +6044,10 @@ static void i830_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); + + I915_WRITE(MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | + _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); } void intel_init_clock_gating(struct drm_device *dev) -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 06/16] drm/i915: ns2501 is on DVOB
From: Ville Syrjälä ville.syrj...@linux.intel.com On Fujitsu-Siememens S6010 the ns2501 chip is hooked up to DVOB instead of DVOC. FIXME: Maybe need to dig out the correct DVO port from VBT Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 56b47d2..d5ea393 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -85,7 +85,7 @@ static const struct intel_dvo_device intel_dvo_devices[] = { { .type = INTEL_DVO_CHIP_TMDS, .name = ns2501, - .dvo_reg = DVOC, + .dvo_reg = DVOB, .slave_addr = NS2501_ADDR, .dev_ops = ns2501_ops, } -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/16] drm/i915: Pass intel_crtc to intel_disable_pipe() and intel_wait_for_pipe_off()
From: Ville Syrjälä ville.syrj...@linux.intel.com Just pass the intel_crtc around instead of dev_priv+pipe. Also make intel_wait_for_pipe_off() static since it's only used in intel_display.c. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 37 +--- drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3813526..e7175ce 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -913,8 +913,7 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) /* * intel_wait_for_pipe_off - wait for pipe to turn off - * @dev: drm device - * @pipe: pipe to wait for + * @crtc: crtc whose pipe to wait for * * After disabling a pipe, we can't wait for vblank in the usual way, * spinning on the vblank interrupt status bit, since we won't actually @@ -928,11 +927,12 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) * ends up stopping at the start of the next frame). * */ -void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) +static void intel_wait_for_pipe_off(struct intel_crtc *crtc) { + struct drm_device *dev = crtc-base.dev; struct drm_i915_private *dev_priv = dev-dev_private; - enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, - pipe); + enum transcoder cpu_transcoder = crtc-config.cpu_transcoder; + enum pipe pipe = crtc-pipe; if (INTEL_INFO(dev)-gen = 4) { int reg = PIPECONF(cpu_transcoder); @@ -1981,21 +1981,19 @@ static void intel_enable_pipe(struct intel_crtc *crtc) /** * intel_disable_pipe - disable a pipe, asserting requirements - * @dev_priv: i915 private structure - * @pipe: pipe to disable - * - * Disable @pipe, making sure that various hardware specific requirements - * are met, if applicable, e.g. plane disabled, panel fitter off, etc. + * @crtc: crtc whose pipes is to be disabled * - * @pipe should be %PIPE_A or %PIPE_B. + * Disable the pipe of @crtc, making sure that various hardware + * specific requirements are met, if applicable, e.g. plane + * disabled, panel fitter off, etc. * * Will wait until the pipe has shut down before returning. */ -static void intel_disable_pipe(struct drm_i915_private *dev_priv, - enum pipe pipe) +static void intel_disable_pipe(struct intel_crtc *crtc) { - enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, - pipe); + struct drm_i915_private *dev_priv = crtc-base.dev-dev_private; + enum transcoder cpu_transcoder = crtc-config.cpu_transcoder; + enum pipe pipe = crtc-pipe; int reg; u32 val; @@ -2017,7 +2015,7 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, return; I915_WRITE(reg, val ~PIPECONF_ENABLE); - intel_wait_for_pipe_off(dev_priv-dev, pipe); + intel_wait_for_pipe_off(crtc); } /* @@ -4115,7 +4113,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) intel_set_pch_fifo_underrun_reporting(dev, pipe, false); - intel_disable_pipe(dev_priv, pipe); + intel_disable_pipe(intel_crtc); if (intel_crtc-config.dp_encoder_is_mst) intel_ddi_set_vc_payload_alloc(crtc, false); @@ -4167,7 +4165,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = dev-dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; - int pipe = intel_crtc-pipe; enum transcoder cpu_transcoder = intel_crtc-config.cpu_transcoder; if (!intel_crtc-active) @@ -4182,7 +4179,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); - intel_disable_pipe(dev_priv, pipe); + intel_disable_pipe(intel_crtc); intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); @@ -4769,7 +4766,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) */ intel_wait_for_vblank(dev, pipe); - intel_disable_pipe(dev_priv, pipe); + intel_disable_pipe(intel_crtc); i9xx_pfit_disable(intel_crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3abc915..6c8303e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -826,7 +826,6 @@ intel_wait_for_vblank(struct drm_device *dev, int pipe) { drm_wait_one_vblank(dev, pipe); } -void
[Intel-gfx] [PATCH 08/16] drm/i915: Don't call DVO mode_set hook on DPMS changes
From: Ville Syrjälä ville.syrj...@linux.intel.com Calling the mode_set hook on DPMS changes doesn't seem to be necessary for ns2501. Just drop it. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dvo.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 4f115c1..e40e3df 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -227,10 +227,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode) intel_crtc_update_dpms(crtc); - intel_dvo-dev.dev_ops-mode_set(intel_dvo-dev, -config-requested_mode, -config-adjusted_mode); - intel_dvo-dev.dev_ops-dpms(intel_dvo-dev, true); } else { intel_dvo-dev.dev_ops-dpms(intel_dvo-dev, false); -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/16] drm/i915: Enable DVO between mode_set and dpms hooks
From: Ville Syrjälä ville.syrj...@linux.intel.com To more closely match the IEGD ns2501 driver behaviour, call the mode_set hook while the DVO port is still disabled, then enable the DVO port, and finally call the dpms hook. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_dvo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index d5ea393..4f115c1 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -185,12 +185,13 @@ static void intel_enable_dvo(struct intel_encoder *encoder) u32 dvo_reg = intel_dvo-dev.dvo_reg; u32 temp = I915_READ(dvo_reg); - I915_WRITE(dvo_reg, temp | DVO_ENABLE); - I915_READ(dvo_reg); intel_dvo-dev.dev_ops-mode_set(intel_dvo-dev, crtc-config.requested_mode, crtc-config.adjusted_mode); + I915_WRITE(dvo_reg, temp | DVO_ENABLE); + I915_READ(dvo_reg); + intel_dvo-dev.dev_ops-dpms(intel_dvo-dev, true); } -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 05/16] drm/i915: Disable double wide even when leaving the pipe on
From: Ville Syrjälä ville.syrj...@linux.intel.com Disable double wide even if the pipe quirk compels us to leave the pipe running. Double wide has certain implications for the plane assignments so best keep it off. Also helps resuming from S3 on the Fujitsu-Siemens Lifebook S6010 when double wide was enabled prior to suspend. We do leave the pixel clock ticking at the original rate which would require double wide to be enabled. But since the planes are all disabled I'm hoping that the overly fast clock won't cause any problems. Seems to be fine so far. v2: Disable double wide also when turning the pipe off v3: Reorder wrt. force pipe B quirk Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e7175ce..3eeb5ce 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2005,17 +2005,25 @@ static void intel_disable_pipe(struct intel_crtc *crtc) assert_cursor_disabled(dev_priv, pipe); assert_sprites_disabled(dev_priv, pipe); - /* Don't disable pipe A or pipe A PLLs if needed */ - if (pipe == PIPE_A (dev_priv-quirks QUIRK_PIPEA_FORCE)) - return; - reg = PIPECONF(cpu_transcoder); val = I915_READ(reg); if ((val PIPECONF_ENABLE) == 0) return; - I915_WRITE(reg, val ~PIPECONF_ENABLE); - intel_wait_for_pipe_off(crtc); + /* +* Double wide has implications for planes +* so best keep it disabled when not needed. +*/ + if (crtc-config.double_wide) + val = ~PIPECONF_DOUBLE_WIDE; + + /* Don't disable pipe or pipe PLLs if needed */ + if (!(pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE)) + val = ~PIPECONF_ENABLE; + + I915_WRITE(reg, val); + if ((val PIPECONF_ENABLE) == 0) + intel_wait_for_pipe_off(crtc); } /* -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/16] drm/i915: Kill useless ns2501_dump_regs
From: Ville Syrjälä ville.syrj...@linux.intel.com Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/dvo_ns2501.c | 17 - 1 file changed, 17 deletions(-) diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index 74f2af7..85030d4 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c @@ -479,22 +479,6 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) } } -static void ns2501_dump_regs(struct intel_dvo_device *dvo) -{ - uint8_t val; - - ns2501_readb(dvo, NS2501_FREQ_LO, val); - DRM_DEBUG_KMS(NS2501_FREQ_LO: 0x%02x\n, val); - ns2501_readb(dvo, NS2501_FREQ_HI, val); - DRM_DEBUG_KMS(NS2501_FREQ_HI: 0x%02x\n, val); - ns2501_readb(dvo, NS2501_REG8, val); - DRM_DEBUG_KMS(NS2501_REG8: 0x%02x\n, val); - ns2501_readb(dvo, NS2501_REG9, val); - DRM_DEBUG_KMS(NS2501_REG9: 0x%02x\n, val); - ns2501_readb(dvo, NS2501_REGC, val); - DRM_DEBUG_KMS(NS2501_REGC: 0x%02x\n, val); -} - static void ns2501_destroy(struct intel_dvo_device *dvo) { struct ns2501_priv *ns = dvo-dev_priv; @@ -512,6 +496,5 @@ struct intel_dvo_dev_ops ns2501_ops = { .mode_set = ns2501_mode_set, .dpms = ns2501_dpms, .get_hw_state = ns2501_get_hw_state, - .dump_regs = ns2501_dump_regs, .destroy = ns2501_destroy, }; -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/16] drm/i915: Init important ns2501 registers
From: Ville Syrjälä ville.syrj...@linux.intel.com In my earlier rewrite I missed a few important registers. Thomas Richter noticed that they're needed to make his machine resume correctly. Looks like IEGD does a one time init of these three registers. We don't have a good one time init place in the ns2501 driver, so let's just stick them into the .mode_set() hook and see if that helps things along. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/dvo_ns2501.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index b278571..345235b 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c @@ -342,6 +342,12 @@ static const struct ns2501_reg regs_1024x768[][86] = { }, }; +static const struct ns2501_reg regs_init[] = { + [0] = { .offset = 0x35, .value = 0xff, }, + [1] = { .offset = 0x34, .value = 0x00, }, + [2] = { .offset = 0x08, .value = 0x30, }, +}; + struct ns2501_priv { bool quiet; const struct ns2501_reg *regs; @@ -544,6 +550,10 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, else return; + /* Hopefully doing it every time won't hurt... */ + for (i = 0; i ARRAY_SIZE(regs_init); i++) + ns2501_writeb(dvo, regs_init[i].offset, regs_init[i].value); + ns-regs = regs_1024x768[mode_idx]; for (i = 0; i 84; i++) -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/16] drm/i915: Rewrite ns2501 driver a bit
From: Ville Syrjälä ville.syrj...@linux.intel.com Try to use the same programming sequence as used by the IEGD driver. Also shovel the magic register values into a big static const array. The register values are actually the based on what the BIOS programs on the Fujitsu-Siemens Lifebook S6010. IEGD seemed to have hardcoded register values (which also enabled the scaler for 1024x768 mode). However those didn't actually work so well on the S6010. Possibly the pipe timings that got used didn't match the ns2501 configuration. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/dvo_ns2501.c | 529 +++--- 1 file changed, 325 insertions(+), 204 deletions(-) diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index 85030d4..b278571 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c @@ -60,16 +60,291 @@ #define NS2501_REGC 0x0c +enum { + MODE_640x480, + MODE_800x600, + MODE_1024x768, +}; + +struct ns2501_reg { +uint8_t offset; +uint8_t value; +}; + +/* + * Magic values based on what the BIOS on + * Fujitsu-Siemens Lifebook S6010 programs (1024x768 panel). + */ +static const struct ns2501_reg regs_1024x768[][86] = { + [MODE_640x480] = { + [0] = { .offset = 0x0a, .value = 0x81, }, + [1] = { .offset = 0x18, .value = 0x07, }, + [2] = { .offset = 0x19, .value = 0x00, }, + [3] = { .offset = 0x1a, .value = 0x00, }, + [4] = { .offset = 0x1b, .value = 0x11, }, + [5] = { .offset = 0x1c, .value = 0x54, }, + [6] = { .offset = 0x1d, .value = 0x03, }, + [7] = { .offset = 0x1e, .value = 0x02, }, + [8] = { .offset = 0xf3, .value = 0x90, }, + [9] = { .offset = 0xf9, .value = 0x00, }, + [10] = { .offset = 0xc1, .value = 0x90, }, + [11] = { .offset = 0xc2, .value = 0x00, }, + [12] = { .offset = 0xc3, .value = 0x0f, }, + [13] = { .offset = 0xc4, .value = 0x03, }, + [14] = { .offset = 0xc5, .value = 0x16, }, + [15] = { .offset = 0xc6, .value = 0x00, }, + [16] = { .offset = 0xc7, .value = 0x02, }, + [17] = { .offset = 0xc8, .value = 0x02, }, + [18] = { .offset = 0xf4, .value = 0x00, }, + [19] = { .offset = 0x80, .value = 0xff, }, + [20] = { .offset = 0x81, .value = 0x07, }, + [21] = { .offset = 0x82, .value = 0x3d, }, + [22] = { .offset = 0x83, .value = 0x05, }, + [23] = { .offset = 0x94, .value = 0x00, }, + [24] = { .offset = 0x95, .value = 0x00, }, + [25] = { .offset = 0x96, .value = 0x05, }, + [26] = { .offset = 0x97, .value = 0x00, }, + [27] = { .offset = 0x9a, .value = 0x88, }, + [28] = { .offset = 0x9b, .value = 0x00, }, + [29] = { .offset = 0x98, .value = 0x00, }, + [30] = { .offset = 0x99, .value = 0x00, }, + [31] = { .offset = 0xf7, .value = 0x88, }, + [32] = { .offset = 0xf8, .value = 0x0a, }, + [33] = { .offset = 0x9c, .value = 0x24, }, + [34] = { .offset = 0x9d, .value = 0x00, }, + [35] = { .offset = 0x9e, .value = 0x25, }, + [36] = { .offset = 0x9f, .value = 0x03, }, + [37] = { .offset = 0xa0, .value = 0x28, }, + [38] = { .offset = 0xa1, .value = 0x01, }, + [39] = { .offset = 0xa2, .value = 0x28, }, + [40] = { .offset = 0xa3, .value = 0x05, }, + [41] = { .offset = 0xb6, .value = 0x09, }, + [42] = { .offset = 0xb8, .value = 0x00, }, + [43] = { .offset = 0xb9, .value = 0xa0, }, + [44] = { .offset = 0xba, .value = 0x00, }, + [45] = { .offset = 0xbb, .value = 0x20, }, + [46] = { .offset = 0x10, .value = 0x00, }, + [47] = { .offset = 0x11, .value = 0xa0, }, + [48] = { .offset = 0x12, .value = 0x02, }, + [49] = { .offset = 0x20, .value = 0x00, }, + [50] = { .offset = 0x22, .value = 0x00, }, + [51] = { .offset = 0x23, .value = 0x00, }, + [52] = { .offset = 0x24, .value = 0x00, }, + [53] = { .offset = 0x25, .value = 0x00, }, + [54] = { .offset = 0x8c, .value = 0x10, }, + [55] = { .offset = 0x8d, .value = 0x02, }, + [56] = { .offset = 0x8e, .value = 0x10, }, + [57] = { .offset = 0x8f, .value = 0x00, }, + [58] = { .offset = 0x90, .value = 0xff, }, + [59] = { .offset = 0x91, .value = 0x07, }, + [60] = { .offset = 0x92, .value = 0xa0, }, + [61] = { .offset = 0x93, .value = 0x02, }, + [62]
[Intel-gfx] [PATCH 13/16] drm/i915: Fix DVO 2x clock enable on 830M
From: Ville Syrjälä ville.syrj...@linux.intel.com The spec says: For the correct operation of the muxed DVO pins (GDEVSELB/ I2Cdata, GIRDBY/I2CClk) and (GFRAMEB/DVI_Data, GTRDYB/DVI_Clk): Bit 31 (DPLL VCO Enable) and Bit 30 (2X Clock Enable) must be set to “1” in both the DPLL A Control Register (06014h-06017h) and DPLL B Control Register (06018h-0601Bh). The pipe A and B force quirks take care of DPLL_VCO_ENABLE, so we just need a bit of special care to handle DPLL_DVO_2X_MODE. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_display.c | 47 +--- 2 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 541fb6f..54895a6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1561,6 +1561,9 @@ struct drm_i915_private { u16 orig_clock; + /* used to control DVO 2x clock enable on 830M */ + uint8_t dvo_pipes; + bool mchbar_need_disable; struct intel_l3_parity l3_parity; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3eeb5ce..6462bcf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1548,6 +1548,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) { struct drm_device *dev = crtc-base.dev; struct drm_i915_private *dev_priv = dev-dev_private; + enum pipe pipe = crtc-pipe; int reg = DPLL(crtc-pipe); u32 dpll = crtc-config.dpll_hw_state.dpll; @@ -1560,7 +1561,16 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) if (IS_MOBILE(dev) !IS_I830(dev)) assert_panel_unlocked(dev_priv, crtc-pipe); - I915_WRITE(reg, dpll); + /* enable DVO 2x clock on both PLLs if necessary */ + if (IS_I830(dev)) { + if (intel_pipe_has_type(crtc-base, INTEL_OUTPUT_DVO)) + dev_priv-dvo_pipes |= 1 pipe; + + if (dev_priv-dvo_pipes) { + dpll |= DPLL_DVO_2X_MODE; + I915_WRITE(DPLL(!pipe), I915_READ(DPLL(!pipe)) | DPLL_DVO_2X_MODE); + } + } /* Wait for the clocks to stabilize. */ POSTING_READ(reg); @@ -1599,8 +1609,23 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) * * Note! This is for pre-ILK only. */ -static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) +static void i9xx_disable_pll(struct intel_crtc *crtc) { + struct drm_device *dev = crtc-base.dev; + struct drm_i915_private *dev_priv = dev-dev_private; + enum pipe pipe = crtc-pipe; + + /* disable DVO 2x clock on both PLLs if necessary */ + if (IS_I830(dev)) { + if (intel_pipe_has_type(crtc-base, INTEL_OUTPUT_DVO)) + dev_priv-dvo_pipes = ~(1 pipe); + + if (!dev_priv-dvo_pipes) { + I915_WRITE(DPLL(pipe), I915_READ(DPLL(pipe)) ~DPLL_DVO_2X_MODE); + I915_WRITE(DPLL(!pipe), I915_READ(DPLL(!pipe)) ~DPLL_DVO_2X_MODE); + } + } + /* Don't disable pipe A or pipe A PLLs if needed */ if (pipe == PIPE_A (dev_priv-quirks QUIRK_PIPEA_FORCE)) return; @@ -4788,7 +4813,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) else if (IS_VALLEYVIEW(dev)) vlv_disable_pll(dev_priv, pipe); else - i9xx_disable_pll(dev_priv, pipe); + i9xx_disable_pll(intel_crtc); } if (!IS_GEN2(dev)) @@ -5792,7 +5817,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc, dpll |= PLL_P2_DIVIDE_BY_4; } - if (intel_pipe_has_type(crtc-base, INTEL_OUTPUT_DVO)) + if (!IS_I830(dev) intel_pipe_has_type(crtc-base, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; if (intel_pipe_has_type(crtc-base, INTEL_OUTPUT_LVDS) @@ -6298,6 +6323,9 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, } pipe_config-dpll_hw_state.dpll = I915_READ(DPLL(crtc-pipe)); if (!IS_VALLEYVIEW(dev)) { + if (IS_I830(dev)) + pipe_config-dpll_hw_state.dpll = ~DPLL_DVO_2X_MODE; + pipe_config-dpll_hw_state.fp0 = I915_READ(FP0(crtc-pipe)); pipe_config-dpll_hw_state.fp1 = I915_READ(FP1(crtc-pipe)); } else { @@ -13021,6 +13049,17 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, } } + /* update dvo_pipes */ + if (IS_I830(dev)) { + dev_priv-dvo_pipes = 0; + + for_each_intel_crtc(dev, crtc) { + if (crtc-active + intel_pipe_has_type(crtc-base,
[Intel-gfx] [PATCH v2 15/16] drm/i915: Add pipe B force quirk for 830M
From: Ville Syrjälä ville.syrj...@linux.intel.com 830M has problems when some of the pipes are disabled. Namely if a plane, DVO port etc. is currently assigned to a disabled pipe, it can't moved to the other pipe until the current pipe is also enabled. To keep things simple just leave both pipes running all the time. Ideally I think should turn the pipes off if neither is active, and when either becomes active we enable both. But that would reuquire proper atomic modeset support, and probably a bit of extra care in the order things get enabled. v2: Reorder wrt. double wide handling changes Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 39 +--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54895a6..b1ed71e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -706,6 +706,7 @@ enum intel_sbi_destination { #define QUIRK_LVDS_SSC_DISABLE (11) #define QUIRK_INVERT_BRIGHTNESS (12) #define QUIRK_BACKLIGHT_PRESENT (13) +#define QUIRK_PIPEB_FORCE (14) struct intel_fbdev; struct intel_fbc_work; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e1c0c0b..92baf6f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1194,8 +1194,9 @@ void assert_pipe(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); - /* if we need the pipe A quirk it must be always on */ - if (pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) + /* if we need the pipe quirk it must be always on */ + if ((pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) || + (pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE)) state = true; if (!intel_display_power_enabled(dev_priv, @@ -1626,8 +1627,9 @@ static void i9xx_disable_pll(struct intel_crtc *crtc) } } - /* Don't disable pipe A or pipe A PLLs if needed */ - if (pipe == PIPE_A (dev_priv-quirks QUIRK_PIPEA_FORCE)) + /* Don't disable pipe or pipe PLLs if needed */ + if ((pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) || + (pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE)) return; /* Make sure the pipe isn't still relying on us */ @@ -1995,8 +1997,8 @@ static void intel_enable_pipe(struct intel_crtc *crtc) reg = PIPECONF(cpu_transcoder); val = I915_READ(reg); if (val PIPECONF_ENABLE) { - WARN_ON(!(pipe == PIPE_A - dev_priv-quirks QUIRK_PIPEA_FORCE)); + WARN_ON(!((pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) || + (pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE))); return; } @@ -2043,7 +2045,8 @@ static void intel_disable_pipe(struct intel_crtc *crtc) val = ~PIPECONF_DOUBLE_WIDE; /* Don't disable pipe or pipe PLLs if needed */ - if (!(pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE)) + if (!(pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) + !(pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE)) val = ~PIPECONF_ENABLE; I915_WRITE(reg, val); @@ -5968,9 +5971,9 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) pipeconf = 0; - if (dev_priv-quirks QUIRK_PIPEA_FORCE - I915_READ(PIPECONF(intel_crtc-pipe)) PIPECONF_ENABLE) - pipeconf |= PIPECONF_ENABLE; + if ((intel_crtc-pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) || + (intel_crtc-pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE)) + pipeconf |= I915_READ(PIPECONF(intel_crtc-pipe)) PIPECONF_ENABLE; if (intel_crtc-config.double_wide) pipeconf |= PIPECONF_DOUBLE_WIDE; @@ -10680,8 +10683,9 @@ check_crtc_state(struct drm_device *dev) active = dev_priv-display.get_pipe_config(crtc, pipe_config); - /* hw state is inconsistent with the pipe A quirk */ - if (crtc-pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) + /* hw state is inconsistent with the pipe quirk */ + if ((crtc-pipe == PIPE_A dev_priv-quirks QUIRK_PIPEA_FORCE) || + (crtc-pipe == PIPE_B dev_priv-quirks QUIRK_PIPEB_FORCE)) active = crtc-active; for_each_intel_encoder(dev, encoder) { @@ -12429,6 +12433,14 @@ static void quirk_pipea_force(struct drm_device *dev) DRM_INFO(applying pipe a force quirk\n); } +static
[Intel-gfx] [PATCH 14/16] Revert drm/i915: Nuke pipe A quirk on i830M
From: Ville Syrjälä ville.syrj...@linux.intel.com 830 really does want the pipe A quirk. The planes and ports don't react to any register writes unless the pipe currently attached to them is running, so it's impossible to move them to the other pipe unless both pipes are running. Also it's documented that the DPLL must be enabled on both pipes whenever it's needed. This reverts commit ac6696d3236bd61503f89a1a99680fd7894d5d53. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6462bcf..e1c0c0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12503,6 +12503,9 @@ static struct intel_quirk intel_quirks[] = { /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, + /* 830 needs to leave pipe A dpll A up */ + { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, + /* Lenovo U160 cannot use SSC on LVDS */ { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/16] drm/i915: Check pixel clock in ns2501 mode_valid hook
From: Ville Syrjälä ville.syrj...@linux.intel.com The vbt on my Fujitsu-Siemens Lifebook S6010 provides two 800x600 modes, 60Hz and 56Hz. The magic register values we have correspond to the 60Hz mode, and as I don't know how one would trick the VGA BIOS to set up the 56Hz mode we can't get the magic values for the orther mode. So when checking whether a mode is valid also check the pixel clock so that we filter out the 56Hz variant. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/dvo_ns2501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index 345235b..4416304 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c @@ -521,9 +521,9 @@ static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo, * of the panel in here so we could always accept it * by disabling the scaler. */ - if ((mode-hdisplay == 800 mode-vdisplay == 600) || - (mode-hdisplay == 640 mode-vdisplay == 480) || - (mode-hdisplay == 1024 mode-vdisplay == 768)) { + if ((mode-hdisplay == 640 mode-vdisplay == 480 mode-clock == 25175) || + (mode-hdisplay == 800 mode-vdisplay == 600 mode-clock == 4) || + (mode-hdisplay == 1024 mode-vdisplay == 768 mode-clock == 65000)) { return MODE_OK; } else { return MODE_ONE_SIZE; /* Is this a reasonable error? */ -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 16/16] drm/i915: Preserve VGACNTR bits from the BIOS
From: Ville Syrjälä ville.syrj...@linux.intel.com My Fujistsu-Siemens Lifebook S6010 doesn't like to resume from S3 unless VGACNTR has been restore to the original value. The BIOS value in this case was 0x0124008E. Setting the VGA disable bit doesn't interfere with the S3 resume fortunately. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 8 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b1ed71e..e0f64e4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1638,6 +1638,8 @@ struct drm_i915_private { */ struct workqueue_struct *dp_wq; + uint32_t bios_vgacntr; + /* Old dri1 support infrastructure, beware the dragons ya fools entering * here! */ struct i915_dri1_state dri1; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 92baf6f..f154993 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12591,7 +12591,11 @@ static void i915_disable_vga(struct drm_device *dev) vga_put(dev-pdev, VGA_RSRC_LEGACY_IO); udelay(300); - I915_WRITE(vga_reg, VGA_DISP_DISABLE); + /* +* Fujitsu-Siemens Lifebook S6010 (830) has problems resuming +* from S3 without preserving (some of?) the other bits. +*/ + I915_WRITE(vga_reg, dev_priv-bios_vgacntr | VGA_DISP_DISABLE); POSTING_READ(vga_reg); } @@ -12680,6 +12684,8 @@ void intel_modeset_init(struct drm_device *dev) intel_shared_dpll_init(dev); + /* save the BIOS value before clobbering it */ + dev_priv-bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev)); /* Just disable it once at startup */ i915_disable_vga(dev); intel_setup_outputs(dev); -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/dp: Backlight PWM enable before BL Enable assert
From: Clint Taylor clinton.a.tay...@intel.com Backlight on delay uses PWM enable time to seperate PWM to backlight enable assert. Previous time difference used timing from VDD enable which occur several seconds before resulting in PWM starting 5ms after backlight enable. Changes to backlight duty cycle take affect at the end of the current PWM cycle. Measured time for the PWM cycle is 5ms. 5 additional ms must be added to the backlight_on_delay to get correct VBT timing of PWM to backlight enable assert. Change-Id: I484999a597fd84dacf4cf99a168ec9ba4bb6ff11 Signed-off-by: Clint Taylor clinton.a.tay...@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 6 -- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e5ada4f..c59ccdb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1141,7 +1141,7 @@ static void wait_panel_power_cycle(struct intel_dp *intel_dp) static void wait_backlight_on(struct intel_dp *intel_dp) { - wait_remaining_ms_from_jiffies(intel_dp-last_power_on, + wait_remaining_ms_from_jiffies(intel_dp-last_backlight_on, intel_dp-backlight_on_delay); } @@ -1398,6 +1398,7 @@ void intel_edp_backlight_on(struct intel_dp *intel_dp) DRM_DEBUG_KMS(\n); intel_panel_enable_backlight(intel_dp-attached_connector); + intel_dp-last_backlight_on = jiffies; /* * If we enable the backlight right away following a panel power @@ -4243,9 +4244,10 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, assign_final(t11_t12); #undef assign_final +#define PWM_CYCLE_DELAY 5 #define get_delay(field) (DIV_ROUND_UP(final.field, 10)) intel_dp-panel_power_up_delay = get_delay(t1_t3); - intel_dp-backlight_on_delay = get_delay(t8); + intel_dp-backlight_on_delay = get_delay(t8) + PWM_CYCLE_DELAY; intel_dp-backlight_off_delay = get_delay(t9); intel_dp-panel_power_down_delay = get_delay(t10); intel_dp-panel_power_cycle_delay = get_delay(t11_t12); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3abc915..ad6fcc1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -556,6 +556,7 @@ struct intel_dp { bool want_panel_vdd; unsigned long last_power_cycle; unsigned long last_power_on; + unsigned long last_backlight_on; unsigned long last_backlight_off; struct notifier_block edp_notifier; -- 1.8.3.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] Responsiveness Changes to i915 Driver
Greetings, I am submitting the below changes to i915 Gfx driver to support resume time Responsiveness measurements. These changes parallel the work already done in the IVB Windows Gfx driver. These changes in addition to other OTS scripts (suspend_resume) allow tracking of what is referred to as the “B2I” or “Button To Image” time of the platform. The shorter this time, the more responsiveness the platform is viewed by the end user. Panel selection is an important factor in providing a more responsive system. Note there is no dependency on other scripts. The changes are standalone. * Display the current T1_T3 value. This is used to verify that the timing set in the VBT is correct. We have seen many instances where the value is not set correctly for the panel and the resume time is longer than necessary (e.g. 500ms T3 versus 200ms T3). * Print the time when the first page flip occurs. This is when the user first sees the desktop displayed from resume. While this measurement could be done by other methods, this is the actual time that the desktop manager/framebuffer makes the driver request and the Gfx driver performs the action. Thus any layering software added can be correlated to increases in this time. To support the latter (first page flip), I added a new ftrace called “trace_i915_resume”. I looked at the existing page flip trace message and that one is designed for every page flip. I did not want to convolute it with the one time flip trace on resume. I used a trace message instead of a printk to reduce any performance impacts of using a printk. Additionally printk is not reliable of when the message actually appears in the kernel log. The attached patch file for the 3.10 Linux Kernel (currently used by the Chromium/Chrome OS project for a BayTrail platform) has the small number of changes to a few files in the i915 directory. The changes are minimal and have no impact in performance (that I have seen). I can also make the changes to the 3.15 Linux Kernel if required. Let me know of any additional questions Regards, -martin PCCG GED Responsiveness Technologist i915.patch Description: i915.patch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx