Re: [Intel-gfx] [PATCH] drm/i915: skl_update_scaler() wants a rotation bitmask instead of bit number
On Mon, Jan 18, 2016 at 04:21:40PM +0200, Ville Syrjälä wrote: > On Fri, Jan 15, 2016 at 03:15:00PM -0800, Matt Roper wrote: > > On Fri, Jan 15, 2016 at 08:48:26PM +0200, Ville Syrjälä wrote: > > > On Thu, Oct 15, 2015 at 05:01:58PM +0300, ville.syrj...@linux.intel.com > > > wrote: > > > > From: Ville Syrjälä > > > > > > > > Pass BIT(DRM_ROTATE_0) instead of DRM_ROTATE_0 to skl_update_scaler(). > > > > The former is a mask, the latter just the bit number. > > > > > > > > Fortunately the only thing skl_update_scaler() does with the rotation > > > > is check if it's 90/270 degrees or not, and so in this case it would > > > > still do the right thing. > > > > > > > > Cc: Chandra Konduru > > > > Signed-off-by: Ville Syrjälä > > > > > > Ping, anyone care to r-b this one? > > > > Reviewed-by: Matt Roper > > > > Looks like this bug has been present since scalers were first added in > > 6156a45602f9 ("drm/i915: skylake primary plane scaling using shared > > scalers") > > Pushed to dinq an appropriate Fixes: comment added. Thanks for the review. Do we have an igt for this? If not need to capture it and make it something we must fixe before more scaler stuff lands. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 5/6] drm/i915: read sink_count dpcd always
On Monday 18 January 2016 06:30 PM, Ander Conselvan De Oliveira wrote: On Mon, 2016-01-18 at 18:14 +0530, Shubhangi Shrivastava wrote: On Thursday 14 January 2016 06:34 PM, Ander Conselvan De Oliveira wrote: On Tue, 2016-01-05 at 18:20 +0530, Shubhangi Shrivastava wrote: This patch reads sink_count dpcd always and removes its read operation based on values in downstream port dpcd. SINK_COUNT dpcd is not dependent on DOWNSTREAM_PORT_PRESENT dpcd. SINK_COUNT denotes if a display is attached, while DOWNSTREAM_PORT_PRESET indicates how many ports are available in the dongle where display can be attached. so it is possible for sink count to change irrespective of value in downstream port dpcd. Here is a table of possible values and scenarios sink_count downstream_port present 0 0 no display is attached 0 1 dongle is connected without display 1 0 display connected directly 1 1 display connected through dongle Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c2e8516..0d58bfd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3865,6 +3865,13 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] == 0) return false; /* DPCD not present */ + if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, + &intel_dp->sink_count, 1) < 0) + return false; + + if (!DP_GET_SINK_COUNT(intel_dp->sink_count)) + return false; + My understanding is that this function should only read the DPCD data while detection based on that data is done in intel_dp_detect_dpcd(). With the return on sink_count == 0 here, we skip the end of the function, which updates the cached downstream port information. Is there a reason why we need this early return here? Also, I think this could be squashed with the previous patch. Ander As described in the commit message, if sink_count is 0, then there is no display present. So, irrespective of value of downstream port, we should terminate the function and thus, an early return is present here. You wrote that "SINK_COUNT dpcd is not dependent on DOWNSTREAM_PORT_PRESENT dpcd". Now, the get_dpcd() function is called from different places with the purpose of retrieving information stored in dpcd. By adding the early return, the downstream port information, which you claimed is independent from sink count, is not updated. The way I see it, you should terminate detection when sink count is 0, not the reading of DPCD. That way the logical split between intel_dp_get_dpcd() and intel_dp_detect_dpcd() is maintained. The former reads DPCD and the latter reasons about it. Ander Yes, that's how it is.. But, SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that a dongle is present but no display. Unless we require to know if a dongle is present or not, we don't need to update downstream port information. So, an early return here saves time from performing other operations which are not required. /* Check if the panel supports PSR */ memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd)); if (is_edp(intel_dp)) { @@ -4386,10 +4393,6 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) { - if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, - &intel_dp->sink_count, 1) < 0) - return connector_status_unknown; - return DP_GET_SINK_COUNT(intel_dp->sink_count) ? connector_status_connected : connector_status_disconnected; } ___ 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: force full detect on sink count change
On Thursday 14 January 2016 07:20 PM, Ander Conselvan De Oliveira wrote: On Tue, 2016-01-05 at 18:20 +0530, Shubhangi Shrivastava wrote: This patch checks for changes in sink count between short pulse hpds and forces full detect when there is a change. This will allow both detection of hotplug and unplug of panels through dongles that give only short pulse for such events. v2: changed variable type from u8 to bool (Jani) return immediately if perform_full_detect is set(Siva) v3: changed method of determining full detection from using pointer to return code (Siva) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0d58bfd..8a659ee 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4331,12 +4331,14 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 * 4. Check link status on receipt of hot-plug interrupt */ -static void +static bool Please expand the comment above to indicate what the return value of this function is supposed to mean. Sure.. Will add.. intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); u8 sink_irq_vector; u8 link_status[DP_LINK_STATUS_SIZE]; + u8 old_sink_count = intel_dp->sink_count; + bool ret; /* * Clearing compliance test variables to allow capturing @@ -4348,12 +4350,20 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) /* Try to read receiver status if the link appears to be up */ if (!intel_dp_get_link_status(intel_dp, link_status)) { - return; + return false; } - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { - return; + /* +* Now read the DPCD to see if it's actually running +* Don't return immediately if dpcd read failed, +* if sink count was 1 and dpcd read failed we need +* to do full detection +*/ + ret = intel_dp_get_dpcd(intel_dp); + + if ((old_sink_count != intel_dp->sink_count) || !ret) { I don't see the connection of the comment above with this. If the dpcd read fails, the 'return false' will be reached regardless of the previous value of intel_dp->sink_count. Did you intend to do something different or did I miss something? The code was changed but comment was not updated.. Will change the comment to explain correctly. + /* No need to proceed if we are going to do full detect */ + return false; } /* Try to read the source of the interrupt */ @@ -4373,6 +4383,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return true; } /* XXX this is probably wrong for multiple downstream ports */ @@ -5095,8 +5107,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) - intel_dp_short_pulse(intel_dp); + if (!intel_dp->is_mst) { + if (!intel_dp_short_pulse(intel_dp)) { + intel_dp_long_pulse(intel_dp ->attached_connector); + goto put_power; It could be in a follow up patch, but I think its a good moment to get rid of the goto put_power. The only thing they do is skip the 'ret = IRQ_HANDLED' assignment now. Ander Sure.. Will remove the goto put_power in follow up patch. + } + } } ret = IRQ_HANDLED; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 10/11] acpi: Export acpi_bus_type
On Mon, 2016-01-18 at 19:26 +0100, Lukas Wunner wrote: Hi, > Hi, > > On Mon, Jan 18, 2016 at 03:57:29PM +0100, Rafael J. Wysocki wrote: > > On Monday, January 18, 2016 02:31:00 PM Ankitprasad Sharma wrote: > > > On Fri, 2016-01-15 at 15:51 +0100, Rafael J. Wysocki wrote: > > > > On Thursday, January 14, 2016 11:46:46 AM > > > > ankitprasad.r.sha...@intel.com wrote: > > > > > From: Ankitprasad Sharma > > > > > > > > > > Some modules, like i915.ko, needs to detect when certain ACPI features > > > > > are active inorder to prevent corruption on contended resources. > > > > > In particular, use of BIOS RapidStart Technology may corrupt the > > > > > contents > > > > > of the reserved graphics memory, due to unalarmed hibernation. In > > > > > which > > > > > case i915.ko cannot assume that it (reserved gfx memory) remains > > > > > unmodified and must recreate teh contents and importantly not use it > > > > > to > > > > > store unrecoverable user data. > > > > > > > > > > Signed-off-by: Ankitprasad Sharma > > > > > Cc: "Rafael J. Wysocki" > > > > > Cc: Len Brown > > > > > Cc: linux-a...@vger.kernel.org > > > > > Cc: linux-ker...@vger.kernel.org > > > > > --- > > > > > drivers/acpi/bus.c | 1 + > > > > > 1 file changed, 1 insertion(+) > > > > > > > > > > diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c > > > > > index a212cef..69509c7 100644 > > > > > --- a/drivers/acpi/bus.c > > > > > +++ b/drivers/acpi/bus.c > > > > > @@ -814,6 +814,7 @@ struct bus_type acpi_bus_type = { > > > > > .remove = acpi_device_remove, > > > > > .uevent = acpi_device_uevent, > > > > > }; > > > > > +EXPORT_SYMBOL_GPL(acpi_bus_type); > > > > > > > > > > /* > > > > > -- > > > > > Initialization/Cleanup > > > > > > > > > > > > > No. > > > > > > > > I see no reason whatsoever for doing this. > > > > > > > > Thanks, > > > > Rafael > > > Hi Rafael, > > > > > > Thanks for the response. > > > > > > Can you please help me with, how to detect the presence of a certain > > > acpi device using its id (for example, INT3392 for Intel RST device)? > > > > If you want to check if the device ir present at all, you cen use > > acpi_device_is_present() introduced recently (although that would need > > to be exported if you want to use it from a driver). > > acpi_dev_present() is exported, so can be used in drivers just fine: > https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=2d12b6b381ba059d5f92798f5ea739672a2f5fcf > > > > > As you might have seen (in the next patch in this series), that we use > > > this symbol (acpi_bus_type) to iterate over all the devices registered > > > on acpi bus, to check if there is a device with id INT3392 present or > > > not. > > Ankitprasad, just change your patch [11/11] thusly: > > - if (intel_detect_acpi_rst()) { > + if (acpi_dev_present("INT3392")) { > > > Using bus_for_each_dev() was the wrong approach, most drivers call > acpi_get_devices() to detect the presence of a particular HID, > however that necessitates the definition of a callback in each driver, > leading to lots of duplicate code. Hence the introduction of > acpi_dev_present() which is also faster because it just iterates over > a list instead of walking the namespace. > > This new API landed in Linus' tree last Tuesday (PST), so you need > to merge Linus' tree back into yours or wait until it gets merged > into drm-intel-nightly. > > Best regards, > > Lukas Thank you, Lukas/Rafael. -Ankit ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Splitting intel_dp_check_link_status
On Tue, Jan 19, 2016 at 10:14:30AM +0530, Thulasimani, Sivakumar wrote: > > > On 1/19/2016 2:35 AM, Lukas Wunner wrote: > >Hi, > > > >On Mon, Jan 18, 2016 at 04:22:19PM +0530, Shubhangi Shrivastava wrote: > >>When created originally intel_dp_check_link_status() > >>was supposed to handle only link training for short > >>pulse but has grown into handler for short pulse itself. > >>This patch cleans up this function by splitting it into > >>two halves. First intel_dp_short_pulse() is called, > >>which will be entry point and handle all logic for > >>short pulse handling while intel_dp_check_link_status() > >>will retain its original purpose of only doing link > >>status related work. > >>The link retraining part when EQ is not correct is > >>retained to intel_dp_check_link_status whereas other > >>operations are handled as part of intel_dp_short_pulse. > >>This change is required to avoid performing all DPCD > >>related operations on performing link retraining. > >> > >>v2: Added WARN_ON to intel_dp_check_link_status() > >> Removed a call to intel_dp_get_link_status() (Ander) > >> > >>Tested-by: Nathan D Ciobanu > >>Signed-off-by: Sivakumar Thulasimani > >>Signed-off-by: Shubhangi Shrivastava > >>--- > >> drivers/gpu/drm/i915/intel_dp.c | 65 > >> +++-- > >> 1 file changed, 36 insertions(+), 29 deletions(-) > >> > >>diff --git a/drivers/gpu/drm/i915/intel_dp.c > >>b/drivers/gpu/drm/i915/intel_dp.c > >>index 82ee18d..f8d9611 100644 > >>--- a/drivers/gpu/drm/i915/intel_dp.c > >>+++ b/drivers/gpu/drm/i915/intel_dp.c > >>@@ -4279,6 +4279,36 @@ go_again: > >>return -EINVAL; > >> } > >>+static void > >>+intel_dp_check_link_status(struct intel_dp *intel_dp) > >>+{ > >>+ struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; > >>+ struct drm_device *dev = intel_dp_to_dev(intel_dp); > >>+ u8 link_status[DP_LINK_STATUS_SIZE]; > >>+ > >>+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); > >>+ > >>+ if (!intel_dp_get_link_status(intel_dp, link_status)) { > >>+ DRM_ERROR("Failed to get link status\n"); > >>+ return; > >>+ } > >>+ > >>+ if (!intel_encoder->base.crtc) > >>+ return; > >>+ > >>+ if (!to_intel_crtc(intel_encoder->base.crtc)->active) > >>+ return; > >Why do you change the order of the three if-clauses above? > >The original order seems to make more sense. (Checking for > >->base.crtc and ->active is cheap, whereas accessing AUX to > >get the link status is time consuming. You don't want to > >spend that time only to bail out, should one of the other two > >if-clauses fail.) > > > >Best regards, > > > >Lukas > Actually it is expected to read link status whenever we receive short pulse > interrupt > irrespective of the panel being enabled or not. So this change is with > respect to > that rather than any performance based. As a general rule please don't make functional changes like these in a patch that just splits stuff up. Your patch summary sounds like simple refactoring, which this doesn't seem to be. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/6] drm/i915: Splitting intel_dp_detect
On Friday 15 January 2016 03:37 PM, Ander Conselvan De Oliveira wrote: On Thu, 2016-01-14 at 19:20 +0530, Shubhangi Shrivastava wrote: On Wednesday 13 January 2016 07:03 PM, Ander Conselvan De Oliveira wrote: On Wed, 2016-01-13 at 13:20 +0200, Ander Conselvan De Oliveira wrote: On Tue, 2016-01-05 at 18:20 +0530, Shubhangi Shrivastava wrote: intel_dp_detect() is called for not just detection but during modes enumeration as well. Repeating the whole sequence during each of these calls is wasteful and time consuming. This patch moves probing for panel, DPCD read etc done in intel_dp_detect() to a new function intel_dp_long_pulse(). Note that the behavior of intel_dp_detect() is changed to report connected or disconnected depending on whether the EDID is available or not. This change will be required by further patches in the series to avoid performing duplicated DPCD operations on hotplug. v2: Moved a hunk to next patch of the series. Moved intel_dp_unset_edid to out. (Ander) v3: Rephrased commit message and intel_dp_unset_dp() is called within intel_dp_set_dp() to free the previous EDID. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 56 + - -- - 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 796e3d3..e3b4208 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -129,6 +129,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); +static void intel_dp_unset_edid(struct intel_dp *intel_dp); static unsigned int intel_dp_unused_lane_mask(int lane_count) { @@ -4587,6 +4588,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp) struct intel_connector *intel_connector = intel_dp ->attached_connector; struct edid *edid; + intel_dp_unset_edid(intel_dp); edid = intel_dp_get_edid(intel_dp); intel_connector->detect_edid = edid; @@ -4607,9 +4609,10 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) intel_dp->has_audio = false; } -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, bool force) +static void +intel_dp_long_pulse(struct intel_connector *intel_connector) { + struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -4619,17 +4622,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) bool ret; u8 sink_irq_vector; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_dp_unset_edid(intel_dp); - - if (intel_dp->is_mst) { - /* MST devices are disconnected from a monitor POV */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - return connector_status_disconnected; - } - power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(to_i915(dev), power_domain); @@ -4653,14 +4645,8 @@ intel_dp_detect(struct drm_connector *connector, bool force) intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); - if (ret) { - /* if we are in MST mode then this connector - won't appear connected or have anything with EDID on it */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; This deletion is new in this version of the patch. I think we still need the hunk above, otherwise we might not properly update the encoder type when we switch from an HDMI sink connected through a level shifter to an MST sink. Ander Encoder type setting for MST is being done in intel_dp_detect(). So, don't find a need to add it here. Yes, but that one only covers the case where the device was already previously identified as MST. For a device identified as MST by the call to intel_dp_probe_mst() in intel_dp_long_pulse(), the encoder type override will not be done. Hopefully, Ville's patch that splits the encoder types and makes this unnecessary will land soon, but for now just leave the override there. Ander Alright.. Moved the overriding of encoder type to be done before probing.. - status = connector_status_disconnected; + if (ret) goto out; Also, there is no call to intel_dp_unset_edid() for this
Re: [Intel-gfx] [PATCH v2] drm/i915/guc: Fix a memory leak where guc->execbuf_client is not freed
On Mon, Jan 18, 2016 at 10:01:24AM +, Tvrtko Ursulin wrote: > > On 13/01/16 19:11, Dave Gordon wrote: > >On 13/01/16 19:01, yu@intel.com wrote: > >>From: Alex Dai > >> > >>During driver unloading, the guc_client created for command submission > >>needs to be released to avoid memory leak. > >> > >>The struct_mutex needs to be held before tearing down GuC. > >> > >>v1: Move i915_guc_submission_disable out of i915_guc_submission_fini and > >> take struct_mutex lock before release GuC client. (Dave Gordon) > >>v2: Add the locking for failure case in guc_fw_fetch. (Dave Gordon) > >> Add i915_guc_submission_fini for failure case in > >>intel_guc_ucode_load. > >> > >>Signed-off-by: Alex Dai > > > >LGTM. > > > >Reviewed-by: Dave Gordon > > Patch merged, thanks! CI resulted in warnings for this patch. Per our latest discussion in Jesse's meeting please reply to the CI mail with your analysis of why these are all preexisting failures and with links to bugzilla. Otherwise this patch can't go in. I'll paste you the link to the internally wiki with the BKM. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/6] drm/i915: Splitting intel_dp_check_link_status
On Wednesday 13 January 2016 08:34 PM, Ander Conselvan De Oliveira wrote: On Tue, 2016-01-05 at 18:20 +0530, Shubhangi Shrivastava wrote: When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. The link retraining part when EQ is not correct is retained to intel_dp_check_link_status whereas other operations are handled as part of intel_dp_short_pulse. This change is required to avoid performing all DPCD related operations on performing link retraining. Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 56 - 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 137757b..842790e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4289,6 +4289,33 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp) ->base; + u8 link_status[DP_LINK_STATUS_SIZE]; + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; + + /* if link training is requested we should perform it always */ + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || + (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } +} + /* * According to DP spec * 5.1.2: @@ -4298,15 +4325,12 @@ go_again: * 4. Check link status on receipt of hot-plug interrupt */ static void -intel_dp_check_link_status(struct intel_dp *intel_dp) +intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp) ->base; u8 sink_irq_vector; u8 link_status[DP_LINK_STATUS_SIZE]; - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - I think it's better to move this WARN to the new intel_dp_check_link_status(). Sure.. Done.. /* * Clearing compliance test variables to allow capturing * of values for next automated test request. @@ -4315,12 +4339,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - if (!intel_encoder->base.crtc) - return; - - if (!to_intel_crtc(intel_encoder->base.crtc)->active) - return; - /* Try to read receiver status if the link appears to be up */ if (!intel_dp_get_link_status(intel_dp, link_status)) { return; There is now two calls to intel_dp_get_link_status()and the value of link_status is not used in this function, so maybe just remove it from here. Looks good otherwise. Ander Sure.. Done.. @@ -4345,14 +4363,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); } /* XXX this is probably wrong for multiple downstream ports */ @@ -5080,11 +5093,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) { - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - intel_dp_check_link_status(intel_dp); -
Re: [Intel-gfx] [PATCH 4/6] drm/i915: Save sink_count for tracking changes to it
On Thursday 14 January 2016 06:30 PM, Ander Conselvan De Oliveira wrote: On Tue, 2016-01-05 at 18:20 +0530, Shubhangi Shrivastava wrote: Sink count can change between short pulse hpd hence this patch adds a member variable to intel_dp so we can track any changes between short pulse interrupts. Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 7 +++ drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 842790e..c2e8516 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4385,14 +4385,13 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) /* If we're HPD-aware, SINK_COUNT changes dynamically */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) { - uint8_t reg; if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, - ®, 1) < 0) + &intel_dp->sink_count, 1) < 0) return connector_status_unknown; - return DP_GET_SINK_COUNT(reg) ? connector_status_connected - : connector_status_disconnected; + return DP_GET_SINK_COUNT(intel_dp->sink_count) ? + connector_status_connected : connector_status_disconnected; I think it would be better to have the value of intel_dp->sink_count ready for consumption, i.e., store the result of DP_GET_SINK_COUNT(). Ander Sure.. Done.. } /* If no HPD, poke DDC gently */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0438b57..88b05ba 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -757,6 +757,7 @@ struct intel_dp { uint32_t DP; int link_rate; uint8_t lane_count; + uint8_t sink_count; bool has_audio; enum hdmi_force_audio force_audio; bool limited_color_range; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 2/3] drm/i915: abolish separate per-ring default_context pointers
On Mon, Jan 18, 2016 at 04:16:39PM +, Nick Hoath wrote: > On 07/01/2016 10:20, Dave Gordon wrote: > >Now that we've eliminated a lot of uses of ring->default_context, > >we can eliminate the pointer itself. > > > >All the engines share the same default intel_context, so we can just > >keep a single reference to it in the dev_priv structure rather than one > >in each of the engine[] elements. This make refcounting more sensible > >too, as we now have a refcount of one for the one pointer, rather than > >a refcount of one but multiple pointers. > > > > From an idea by Chris Wilson. > > > >Signed-off-by: Dave Gordon > > Reviewed-by: Nick Hoath In the interest of hampering my popularity I wanted to to merge the first two patches in this series, but this one here conflicts with patches Tvrtko just merged. Also this seems to have fallen into a period where CI was down, so lacking bat results too. Can you pls resend? Thanks, Daniel > > >--- > > drivers/gpu/drm/i915/i915_debugfs.c| 4 ++-- > > drivers/gpu/drm/i915/i915_drv.h| 2 ++ > > drivers/gpu/drm/i915/i915_gem.c| 6 +++--- > > drivers/gpu/drm/i915/i915_gem_context.c| 22 -- > > drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- > > drivers/gpu/drm/i915/i915_guc_submission.c | 6 +++--- > > drivers/gpu/drm/i915/intel_lrc.c | 24 +--- > > drivers/gpu/drm/i915/intel_ringbuffer.h| 1 - > > 8 files changed, 32 insertions(+), 35 deletions(-) > > > >diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > >b/drivers/gpu/drm/i915/i915_debugfs.c > >index 0fc38bb..2613708 100644 > >--- a/drivers/gpu/drm/i915/i915_debugfs.c > >+++ b/drivers/gpu/drm/i915/i915_debugfs.c > >@@ -1943,7 +1943,7 @@ static int i915_context_status(struct seq_file *m, > >void *unused) > > seq_puts(m, "HW context "); > > describe_ctx(m, ctx); > > for_each_ring(ring, dev_priv, i) { > >-if (ring->default_context == ctx) > >+if (dev_priv->kernel_context == ctx) > > seq_printf(m, "(default context %s) ", > >ring->name); > > } > >@@ -2039,7 +2039,7 @@ static int i915_dump_lrc(struct seq_file *m, void > >*unused) > > > > list_for_each_entry(ctx, &dev_priv->context_list, link) { > > for_each_ring(ring, dev_priv, i) { > >-if (ring->default_context != ctx) > >+if (dev_priv->kernel_context != ctx) > > i915_dump_lrc_obj(m, ring, > > ctx->engine[i].state); > > } > >diff --git a/drivers/gpu/drm/i915/i915_drv.h > >b/drivers/gpu/drm/i915/i915_drv.h > >index c2b000a..aef86a8 100644 > >--- a/drivers/gpu/drm/i915/i915_drv.h > >+++ b/drivers/gpu/drm/i915/i915_drv.h > >@@ -1940,6 +1940,8 @@ struct drm_i915_private { > > void (*stop_ring)(struct intel_engine_cs *ring); > > } gt; > > > >+struct intel_context *kernel_context; > >+ > > bool edp_low_vswing; > > > > /* perform PHY state sanity checks? */ > >diff --git a/drivers/gpu/drm/i915/i915_gem.c > >b/drivers/gpu/drm/i915/i915_gem.c > >index c908ed1..8f101121 100644 > >--- a/drivers/gpu/drm/i915/i915_gem.c > >+++ b/drivers/gpu/drm/i915/i915_gem.c > >@@ -2678,7 +2678,7 @@ void i915_gem_request_free(struct kref *req_ref) > > > > if (ctx) { > > if (i915.enable_execlists) { > >-if (ctx != req->ring->default_context) > >+if (ctx != req->i915->kernel_context) > > intel_lr_context_unpin(req); > > } > > > >@@ -2774,7 +2774,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, > > int err; > > > > if (ctx == NULL) > >-ctx = engine->default_context; > >+ctx = to_i915(engine->dev)->kernel_context; > > err = __i915_gem_request_alloc(engine, ctx, &req); > > return err ? ERR_PTR(err) : req; > > } > >@@ -4862,7 +4862,7 @@ i915_gem_init_hw(struct drm_device *dev) > > */ > > init_unused_rings(dev); > > > >-BUG_ON(!dev_priv->ring[RCS].default_context); > >+BUG_ON(!dev_priv->kernel_context); > > > > ret = i915_ppgtt_init_hw(dev); > > if (ret) { > >diff --git a/drivers/gpu/drm/i915/i915_gem_context.c > >b/drivers/gpu/drm/i915/i915_gem_context.c > >index 900ffd0..e1d767e 100644 > >--- a/drivers/gpu/drm/i915/i915_gem_context.c > >+++ b/drivers/gpu/drm/i915/i915_gem_context.c > >@@ -354,11 +354,10 @@ int i915_gem_context_init(struct drm_device *dev) > > { > > struct drm_i915_private *dev_priv = dev->dev_private; > > struct intel_context *ctx; > >-int i; > > > > /* Init should only be called once per module load. Eventually the > > * restriction on the context_disabled check can be loosened. */ > >-if (WARN_ON(dev_priv->ring[RCS].default_context)) > >+if (WARN_ON(dev_priv
Re: [Intel-gfx] [PATCH] drm/i915: Splitting intel_dp_check_link_status
On 1/19/2016 2:14 PM, Daniel Vetter wrote: On Tue, Jan 19, 2016 at 10:14:30AM +0530, Thulasimani, Sivakumar wrote: On 1/19/2016 2:35 AM, Lukas Wunner wrote: Hi, On Mon, Jan 18, 2016 at 04:22:19PM +0530, Shubhangi Shrivastava wrote: When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. The link retraining part when EQ is not correct is retained to intel_dp_check_link_status whereas other operations are handled as part of intel_dp_short_pulse. This change is required to avoid performing all DPCD related operations on performing link retraining. v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 65 +++-- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82ee18d..f8d9611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4279,6 +4279,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; Why do you change the order of the three if-clauses above? The original order seems to make more sense. (Checking for ->base.crtc and ->active is cheap, whereas accessing AUX to get the link status is time consuming. You don't want to spend that time only to bail out, should one of the other two if-clauses fail.) Best regards, Lukas Actually it is expected to read link status whenever we receive short pulse interrupt irrespective of the panel being enabled or not. So this change is with respect to that rather than any performance based. As a general rule please don't make functional changes like these in a patch that just splits stuff up. Your patch summary sounds like simple refactoring, which this doesn't seem to be. -Daniel Understood, will make the appropriate changes and move that to separate patch. regards, Sivakumar ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 1/8] drm/i915/gen9: Add framework to whitelist specific GPU registers
On Thu, Jan 14, 2016 at 03:27:35PM +, Arun Siluvery wrote: > Some of the HW registers are privileged and cannot be written to from > non-privileged batch buffers coming from userspace unless they are added to > the HW whitelist. This whitelist is maintained by HW and it is different from > SW whitelist. Userspace need write access to them to implement preemption > related WA. > > The reason for using this approach is, the register bits that control > preemption granularity at the HW level are not context save/restored; so even > if we set these bits always in kernel they are going to change once the > context is switched out. We can consider making them non-privileged by > default but these registers also contain other chicken bits which should not > be allowed to be modified. > > In the later revisions controlling bits are save/restored at context level but > in the existing revisions these are exported via other debug registers and > should be on the whitelist. This patch adds changes to provide HW with a list > of registers to be whitelisted. HW checks this list during execution and > provides access accordingly. > > HW imposes a limit on the number of registers on whitelist and it is > per-engine. At this point we are only enabling whitelist for RCS and we don't > foresee any requirement for other engines. > > The registers to be whitelisted are added using generic workaround list > mechanism, even these are only enablers for userspace workarounds. But by > sharing this mechanism we get some test assets without additional cost (Mika). > > v2: rebase > > v3: parameterize RING_FORCE_TO_NONPRIV() as _MMIO() should be limited to > i915_reg.h (Ville), drop inline for wa_ring_whitelist_reg (Mika). > > v4: improvements suggested by Chris Wilson. > Clarify that this is HW whitelist and different from the one maintained in > driver. This list is engine specific but it gets initialized along with other > WA which is RCS specific thing, so make it clear that we are not doing any > cross engine setup during initialization. > Make HW whitelist count of each engine available in debugfs. > > Reviewed-by: Chris Wilson > Reviewed-by: Mika Kuoppala > Cc: Mika Kuoppala > Cc: Chris Wilson > Signed-off-by: Arun Siluvery If you resend just single patches to a series you must --in-reply-to the individual patch, not the cover letter. Otherwise patchwork won't pick it up, which means we don't have CI results for this. Since it's been a while probably best to just resend the entire pile. Also we seem to be missing r-b tags for the actual w/a changes. -Daniel > --- > drivers/gpu/drm/i915/i915_debugfs.c | 15 ++- > drivers/gpu/drm/i915/i915_drv.h | 9 - > drivers/gpu/drm/i915/i915_reg.h | 3 +++ > drivers/gpu/drm/i915/intel_ringbuffer.c | 17 + > 4 files changed, 38 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index e3377ab..7eb002c 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -3229,9 +3229,11 @@ static int i915_wa_registers(struct seq_file *m, void > *unused) > { > int i; > int ret; > + struct intel_engine_cs *ring; > struct drm_info_node *node = (struct drm_info_node *) m->private; > struct drm_device *dev = node->minor->dev; > struct drm_i915_private *dev_priv = dev->dev_private; > + struct i915_workarounds *workarounds = &dev_priv->workarounds; > > ret = mutex_lock_interruptible(&dev->struct_mutex); > if (ret) > @@ -3239,15 +3241,18 @@ static int i915_wa_registers(struct seq_file *m, void > *unused) > > intel_runtime_pm_get(dev_priv); > > - seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count); > - for (i = 0; i < dev_priv->workarounds.count; ++i) { > + seq_printf(m, "Workarounds applied: %d\n", workarounds->count); > + for_each_ring(ring, dev_priv, i) > + seq_printf(m, "HW whitelist count for %s: %d\n", > +ring->name, workarounds->hw_whitelist_count[i]); > + for (i = 0; i < workarounds->count; ++i) { > i915_reg_t addr; > u32 mask, value, read; > bool ok; > > - addr = dev_priv->workarounds.reg[i].addr; > - mask = dev_priv->workarounds.reg[i].mask; > - value = dev_priv->workarounds.reg[i].value; > + addr = workarounds->reg[i].addr; > + mask = workarounds->reg[i].mask; > + value = workarounds->reg[i].value; > read = I915_READ(addr); > ok = (value & mask) == (read & mask); > seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, > status: %s\n", > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 104bd18..83fccc0 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/
Re: [Intel-gfx] [PATCH] drm/i915: Splitting intel_dp_check_link_status
On Tue, Jan 19, 2016 at 02:29:22PM +0530, Thulasimani, Sivakumar wrote: > > > On 1/19/2016 2:14 PM, Daniel Vetter wrote: > >On Tue, Jan 19, 2016 at 10:14:30AM +0530, Thulasimani, Sivakumar wrote: > >> > >>On 1/19/2016 2:35 AM, Lukas Wunner wrote: > >>>Hi, > >>> > >>>On Mon, Jan 18, 2016 at 04:22:19PM +0530, Shubhangi Shrivastava wrote: > When created originally intel_dp_check_link_status() > was supposed to handle only link training for short > pulse but has grown into handler for short pulse itself. > This patch cleans up this function by splitting it into > two halves. First intel_dp_short_pulse() is called, > which will be entry point and handle all logic for > short pulse handling while intel_dp_check_link_status() > will retain its original purpose of only doing link > status related work. > The link retraining part when EQ is not correct is > retained to intel_dp_check_link_status whereas other > operations are handled as part of intel_dp_short_pulse. > This change is required to avoid performing all DPCD > related operations on performing link retraining. > > v2: Added WARN_ON to intel_dp_check_link_status() > Removed a call to intel_dp_get_link_status() (Ander) > > Tested-by: Nathan D Ciobanu > Signed-off-by: Sivakumar Thulasimani > Signed-off-by: Shubhangi Shrivastava > --- > drivers/gpu/drm/i915/intel_dp.c | 65 > +++-- > 1 file changed, 36 insertions(+), 29 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c > b/drivers/gpu/drm/i915/intel_dp.c > index 82ee18d..f8d9611 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4279,6 +4279,36 @@ go_again: > return -EINVAL; > } > +static void > +intel_dp_check_link_status(struct intel_dp *intel_dp) > +{ > + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; > + struct drm_device *dev = intel_dp_to_dev(intel_dp); > + u8 link_status[DP_LINK_STATUS_SIZE]; > + > + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); > + > + if (!intel_dp_get_link_status(intel_dp, link_status)) { > + DRM_ERROR("Failed to get link status\n"); > + return; > + } > + > + if (!intel_encoder->base.crtc) > + return; > + > + if (!to_intel_crtc(intel_encoder->base.crtc)->active) > + return; > >>>Why do you change the order of the three if-clauses above? > >>>The original order seems to make more sense. (Checking for > >>>->base.crtc and ->active is cheap, whereas accessing AUX to > >>>get the link status is time consuming. You don't want to > >>>spend that time only to bail out, should one of the other two > >>>if-clauses fail.) > >>> > >>>Best regards, > >>> > >>>Lukas > >>Actually it is expected to read link status whenever we receive short pulse > >>interrupt > >>irrespective of the panel being enabled or not. So this change is with > >>respect to > >>that rather than any performance based. > >As a general rule please don't make functional changes like these in a > >patch that just splits stuff up. Your patch summary sounds like simple > >refactoring, which this doesn't seem to be. > >-Daniel > Understood, will make the appropriate changes and move that to separate > patch. btw you don't have to split it since really this is a small change. Changing the subject to something that makes is clearer that it's not just refactoring is also ok, e.g. "reorganize intel_dp_detect" Then explain in the commit message why and what changes, like you do already. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✗ failure: Fi.CI.BAT
On Thu, Jan 14, 2016 at 11:31:07AM +, Nick Hoath wrote: > On 14/01/2016 07:20, Patchwork wrote: > >== Summary == Our BKM is to link to bugzilla entries to make sure these are all real failures which are tracked already. Otherwise stuff falls through the cracks. > > > >Built on 058740f8fced6851aeda34f366f5330322cd585f drm-intel-nightly: > >2016y-01m-13d-17h-07m-44s UTC integration manifest > > > >Test gem_ctx_basic: > > pass -> FAIL (bdw-ultra) > > Test failed to load - not patch related > > >Test gem_ctx_param_basic: > > Subgroup non-root-set: > > pass -> DMESG-WARN (bsw-nuc-2) > > gem driver allocated a poisoned slab - not patch related > > >Test kms_flip: > > Subgroup basic-flip-vs-dpms: > > pass -> SKIP (bsw-nuc-2) > > test reqs not met - not patch related basic-flip-vs-dpms MUST always work. Well except if you have a chip with GT only where the display is fused off. I expect more serious analysis instead of casually shrugging issues away as "not my problem". Same sloppy analysis with the others imo. -Daniel > > > dmesg-warn -> PASS (ilk-hp8440p) > > warn to PASS > > > > >bdw-nuci7total:138 pass:128 dwarn:1 dfail:0 fail:0 skip:9 > >bdw-ultratotal:138 pass:131 dwarn:0 dfail:0 fail:1 skip:6 > >bsw-nuc-2total:141 pass:113 dwarn:3 dfail:0 fail:0 skip:25 > >hsw-brixbox total:141 pass:134 dwarn:0 dfail:0 fail:0 skip:7 > >hsw-gt2 total:141 pass:137 dwarn:0 dfail:0 fail:0 skip:4 > >ilk-hp8440p total:141 pass:101 dwarn:3 dfail:0 fail:0 skip:37 > >ivb-t430stotal:135 pass:122 dwarn:3 dfail:4 fail:0 skip:6 > >skl-i5k-2total:141 pass:131 dwarn:2 dfail:0 fail:0 skip:8 > >skl-i7k-2total:141 pass:131 dwarn:2 dfail:0 fail:0 skip:8 > >snb-dellxps total:141 pass:122 dwarn:5 dfail:0 fail:0 skip:14 > >snb-x220ttotal:141 pass:122 dwarn:5 dfail:0 fail:1 skip:13 > > > >Results at /archive/results/CI_IGT_test/Patchwork_1174/ > > > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Dump power well states on unclaimed trace
On Wed, Jan 13, 2016 at 06:33:10PM +0200, Mika Kuoppala wrote: > It is beneficial to know the exact sw states of power wells > at the moment when unclaimed register access is detect. > > When the backtrace has been printed to dmesg, it is > followed by a power well states, for example: > > > --[power wells, wakeref_count 2] -- > Name sw statecount > display off 0 > dpio-tx-b-01 off 0 > dpio-tx-b-23 off 0 > dpio-tx-c-01 off 0 > dpio-tx-c-23 off 0 > dpio-common off 0 > - [power wells end] > > This helps bug triaging as it is immediately obvious that the > unclaimed access trace is not a fluke and not about out of bounds access. > Rather the call chain shown by above warn on trace have failed > to enable required power well. > > Cc: Ville Syrjälä > Cc: Imre Deak > Signed-off-by: Mika Kuoppala > --- > drivers/gpu/drm/i915/intel_drv.h| 1 + > drivers/gpu/drm/i915/intel_runtime_pm.c | 26 ++ > drivers/gpu/drm/i915/intel_uncore.c | 4 +++- > 3 files changed, 30 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index e27954d2edad..b83faec2d526 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1445,6 +1445,7 @@ int intel_power_domains_init(struct drm_i915_private *); > void intel_power_domains_fini(struct drm_i915_private *); > void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool > resume); > void intel_power_domains_suspend(struct drm_i915_private *dev_priv); > +void intel_power_domains_dump_wells(struct drm_i915_private *dev_priv); > void skl_pw1_misc_io_init(struct drm_i915_private *dev_priv); > void skl_pw1_misc_io_fini(struct drm_i915_private *dev_priv); > void intel_runtime_pm_enable(struct drm_i915_private *dev_priv); > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c > b/drivers/gpu/drm/i915/intel_runtime_pm.c > index bbca527184d0..43af603aebe6 100644 > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c > @@ -2217,6 +2217,32 @@ void intel_power_domains_suspend(struct > drm_i915_private *dev_priv) > intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > } > > +void intel_power_domains_dump_wells(struct drm_i915_private *dev_priv) > +{ > + struct i915_power_domains *power_domains; > + struct i915_power_well *power_well; > + int i; > + > + power_domains = &dev_priv->power_domains; > + > + /* Intentionally omitting power domain lock */ > + > + pr_info("--[power wells, wakeref_count %d] --\n", > +atomic_read(&dev_priv->pm.wakeref_count)); > + pr_info("%-20s %-11s %-6s\n", "Name", "sw state", "count"); > + > + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { > + if (power_well->always_on) > + continue; > + > + pr_info("%-20s %-11s %-6d\n", > + power_well->name, > + power_well->hw_enabled ? "on" : "off", > + power_well->count); > + } > + pr_info("- [power wells end] \n"); pr_info is a bit heavy, imo this should be debug level at most. Otherwise sounds like a good idea, with that changed Reviewed-by: Daniel Vetter -Daniel > +} > + > /** > * intel_runtime_pm_get - grab a runtime pm reference > * @dev_priv: i915 device instance > diff --git a/drivers/gpu/drm/i915/intel_uncore.c > b/drivers/gpu/drm/i915/intel_uncore.c > index c3c13dc929cb..90875009f789 100644 > --- a/drivers/gpu/drm/i915/intel_uncore.c > +++ b/drivers/gpu/drm/i915/intel_uncore.c > @@ -635,8 +635,10 @@ __unclaimed_reg_debug(struct drm_i915_private *dev_priv, >"Unclaimed register detected %s %s register 0x%x\n", >before ? "before" : "after", >read ? "reading" : "writing to", > - i915_mmio_reg_offset(reg))) > + i915_mmio_reg_offset(reg))) { > i915.mmio_debug--; /* Only report the first N failures */ > + intel_power_domains_dump_wells(dev_priv); > + } > } > > static inline void > -- > 2.5.0 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Splitting intel_dp_check_link_status
On 1/19/2016 2:35 PM, Daniel Vetter wrote: On Tue, Jan 19, 2016 at 02:29:22PM +0530, Thulasimani, Sivakumar wrote: On 1/19/2016 2:14 PM, Daniel Vetter wrote: On Tue, Jan 19, 2016 at 10:14:30AM +0530, Thulasimani, Sivakumar wrote: On 1/19/2016 2:35 AM, Lukas Wunner wrote: Hi, On Mon, Jan 18, 2016 at 04:22:19PM +0530, Shubhangi Shrivastava wrote: When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. The link retraining part when EQ is not correct is retained to intel_dp_check_link_status whereas other operations are handled as part of intel_dp_short_pulse. This change is required to avoid performing all DPCD related operations on performing link retraining. v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 65 +++-- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82ee18d..f8d9611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4279,6 +4279,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; Why do you change the order of the three if-clauses above? The original order seems to make more sense. (Checking for ->base.crtc and ->active is cheap, whereas accessing AUX to get the link status is time consuming. You don't want to spend that time only to bail out, should one of the other two if-clauses fail.) Best regards, Lukas Actually it is expected to read link status whenever we receive short pulse interrupt irrespective of the panel being enabled or not. So this change is with respect to that rather than any performance based. As a general rule please don't make functional changes like these in a patch that just splits stuff up. Your patch summary sounds like simple refactoring, which this doesn't seem to be. -Daniel Understood, will make the appropriate changes and move that to separate patch. btw you don't have to split it since really this is a small change. Changing the subject to something that makes is clearer that it's not just refactoring is also ok, e.g. "reorganize intel_dp_detect" Then explain in the commit message why and what changes, like you do already. -Daniel Sure, that will save some time in redoing ULT+upstreaming :). to give some background, the movement was supposed to be a separate patch but got merged during this cleanup. Will make sure that gets documented and split clearly as required hence forth. regards, Sivakumar ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for Fixing sink count related detection over (rev8)
Hi Shubhangi, On Mon, 2016-01-18 at 13:01 +, Patchwork wrote: > == Summary == > > HEAD is now at 2dd73be drm-intel-nightly: 2016y-01m-18d-09h-59m-27s UTC > integration manifest > Applying: drm/i915: Splitting intel_dp_detect > Applying: drm/i915: Cleaning up intel_dp_hpd_pulse > Applying: drm/i915: Splitting intel_dp_check_link_status > Applying: drm/i915: Save sink_count for tracking changes to it > Applying: drm/i915: Save sink_count for tracking changes to it and read > sink_count dpcd always It seems patchwork got confused about the order of the new patches in this series. When you change multiple patches at once, it is common to resend the entire series without --in-reply-to. It makes it easier for humans and patchwork to figure out which are the new patches. Can you please resend the series as a new thread so we can have the patches go through CI run? Thanks, Ander > Using index info to reconstruct a base tree... > M drivers/gpu/drm/i915/intel_dp.c > M drivers/gpu/drm/i915/intel_drv.h > Falling back to patching base and 3-way merge... > Auto-merging drivers/gpu/drm/i915/intel_dp.c > CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_dp.c > Patch failed at 0005 drm/i915: Save sink_count for tracking changes to it and > read sink_count dpcd always > > ___ > 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
[Intel-gfx] [PATCH] drm/i915: Reorganizing intel_dp_check_link_status
When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. intel_dp_short_pulse: All existing code other than link status read and link training upon error status. intel_dp_check_link_status: The link status should be read on short pulse irrespective of panel being enabled or not so intel_dp_get_link_status() performs dpcd read first then based on crtc active / enabled it will perform the link training. v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) v3: Changed commit message to explain need of link status being read before performing encoder checks (Daniel) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 65 +++-- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82ee18d..f8d9611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4279,6 +4279,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; + + /* if link training is requested we should perform it always */ + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || + (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } +} + /* * According to DP spec * 5.1.2: @@ -4288,14 +4318,10 @@ go_again: * 4. Check link status on receipt of hot-plug interrupt */ static void -intel_dp_check_link_status(struct intel_dp *intel_dp) +intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; - - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); /* * Clearing compliance test variables to allow capturing @@ -4305,17 +4331,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - if (!intel_encoder->base.crtc) - return; - - if (!to_intel_crtc(intel_encoder->base.crtc)->active) - return; - - /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { - return; - } - /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { return; @@ -4335,14 +4350,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); } /* XXX this is probably wrong for multiple downstream ports */ @@ -5072,11 +5082,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) { - drm_modeset_lock(&dev->mo
Re: [Intel-gfx] [PATCH 1/7] drm/i915/skl+: Use proper bytes_per_pixel during WM calculation
On 01/15/2016 12:37 AM, Matt Roper wrote: On Thu, Jan 14, 2016 at 05:32:42PM +0530, Shobhit Kumar wrote: From: "Kumar, Mahesh" Don't always use bytes_per_pixel using y_plane=0, instead use it according to pixel format. If NV12 use y_plane eqal to 1 Signed-off-by: Kumar, Mahesh The second parameter to drm_format_plane_cpp() is the plane index (0 => Y = 1bpp, 1 => UV = 2bpp), so I think passing 0 actually was what we wanted, right? Yes, I guess it was an oversight. Might have to test again for NV12 but for now we can drop this patch. Regards Shobhit Matt --- drivers/gpu/drm/i915/intel_pm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9df9e9a..68f21b9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3185,7 +3185,9 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, if (latency == 0 || !cstate->base.active || !fb) return false; - bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0); + bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ? + drm_format_plane_cpp(fb->pixel_format, 1) : + drm_format_plane_cpp(fb->pixel_format, 0); method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), bytes_per_pixel, latency); -- 2.4.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: failure for Fixing sink count related detection over (rev9)
== Summary == HEAD is now at 00a0c7d drm-intel-nightly: 2016y-01m-18d-16h-50m-37s UTC integration manifest Applying: drm/i915: Splitting intel_dp_detect Applying: drm/i915: Cleaning up intel_dp_hpd_pulse Applying: drm/i915: Reorganizing intel_dp_check_link_status Applying: drm/i915: Save sink_count for tracking changes to it Applying: drm/i915: Save sink_count for tracking changes to it and read sink_count dpcd always Using index info to reconstruct a base tree... M drivers/gpu/drm/i915/intel_dp.c M drivers/gpu/drm/i915/intel_drv.h Falling back to patching base and 3-way merge... Auto-merging drivers/gpu/drm/i915/intel_dp.c CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_dp.c Patch failed at 0005 drm/i915: Save sink_count for tracking changes to it and read sink_count dpcd always ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✗ warning: Fi.CI.BAT
On 14/01/16 09:49, Patchwork wrote: == Summary == Built on 058740f8fced6851aeda34f366f5330322cd585f drm-intel-nightly: 2016y-01m-13d-17h-07m-44s UTC integration manifest Test gem_storedw_loop: Subgroup basic-render: dmesg-warn -> PASS (bdw-nuci7) Test kms_force_connector_basic: Subgroup force-connector-state: pass -> SKIP (ivb-t430s) Unrelated, apparently new so filed: https://bugs.freedesktop.org/show_bug.cgi?id=93769 Test pm_rpm: Subgroup basic-pci-d3-state: pass -> DMESG-WARN (skl-i7k-2) Known unrelated issue: https://bugs.freedesktop.org/show_bug.cgi?id=93768 Please do this type of analysis in the future every time CI result is not a success, or I am not merging things to avoid getting spanked by the maintainer. :) Regards, Tvrtko bdw-nuci7total:138 pass:129 dwarn:0 dfail:0 fail:0 skip:9 bdw-ultratotal:138 pass:132 dwarn:0 dfail:0 fail:0 skip:6 bsw-nuc-2total:141 pass:115 dwarn:2 dfail:0 fail:0 skip:24 hsw-brixbox total:141 pass:134 dwarn:0 dfail:0 fail:0 skip:7 ilk-hp8440p total:141 pass:100 dwarn:4 dfail:0 fail:0 skip:37 ivb-t430stotal:135 pass:121 dwarn:3 dfail:4 fail:0 skip:7 skl-i5k-2total:141 pass:131 dwarn:2 dfail:0 fail:0 skip:8 skl-i7k-2total:141 pass:130 dwarn:3 dfail:0 fail:0 skip:8 snb-dellxps total:141 pass:122 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:141 pass:122 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1179/ ___ 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] drm/i915: Demote user facing DMC firmware load failure message
On Wed, Jan 13, 2016 at 05:41:44PM +, Damien Lespiau wrote: > On Wed, Jan 13, 2016 at 05:38:15PM +, Chris Wilson wrote: > > This is an expected error given the lack of the firmware so emit it at > > KERN_NOTICE and not KERN_ERROR. Also include the firmware URL in the > > user facing message so that the user can investigate and fix the issue > > on their own, and also explain the consequence in plain language. > > > > The complete failure message, including the first line from the firmware > > loader, becomes > > > > i915 :00:02.0: Direct firmware load for i915/skl_dmc_ver1.bin failed > > with error -2 > > i915 :00:02.0: Failed to load DMC firmware > > [https://01.org/linuxgraphics/intel-linux-graphics-firmwares], disabling > > runtime power management. > > > > Signed-off-by: Chris Wilson > > Cc: Damien Lespiau > > Cc: Imre Deak > > Cc: Sunil Kamath > > Cc: Daniel Vetter > > Cc: Animesh Manna > > Cc: Jani Nikula > > Reviewed-by: Damien Lespiau Queued for -next, thanks for the patch. -Daniel > > -- > Damien > > > --- > > drivers/gpu/drm/i915/intel_csr.c | 9 +++-- > > 1 file changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_csr.c > > b/drivers/gpu/drm/i915/intel_csr.c > > index 3f2850029c17..5c2f9a40c81b 100644 > > --- a/drivers/gpu/drm/i915/intel_csr.c > > +++ b/drivers/gpu/drm/i915/intel_csr.c > > @@ -44,6 +44,8 @@ > > #define I915_CSR_SKL "i915/skl_dmc_ver1.bin" > > #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin" > > > > +#define FIRMWARE_URL > > "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"; > > + > > MODULE_FIRMWARE(I915_CSR_SKL); > > MODULE_FIRMWARE(I915_CSR_BXT); > > > > @@ -282,7 +284,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private > > *dev_priv, > > csr->version < SKL_CSR_VERSION_REQUIRED) { > > DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," > > " please upgrade to v%u.%u or later" > > -" > > [https://01.org/linuxgraphics/intel-linux-graphics-firmwares].\n";, > > + " [" FIRMWARE_URL "].\n", > > CSR_VERSION_MAJOR(csr->version), > > CSR_VERSION_MINOR(csr->version), > > CSR_VERSION_MAJOR(SKL_CSR_VERSION_REQUIRED), > > @@ -400,7 +402,10 @@ out: > > CSR_VERSION_MAJOR(csr->version), > > CSR_VERSION_MINOR(csr->version)); > > } else { > > - DRM_ERROR("Failed to load DMC firmware, disabling rpm\n"); > > + dev_notice(dev_priv->dev->dev, > > + "Failed to load DMC firmware" > > + " [" FIRMWARE_URL "]," > > + " disabling runtime power management.\n"); > > } > > > > release_firmware(fw); > > -- > > 2.7.0.rc3 > > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Sink CRC: tune down error message at stop to debug_kms.
On Wed, Jan 13, 2016 at 02:05:04PM -0800, Rodrigo Vivi wrote: > When we stop the sink CRC calculation we wait a while until the counter > is reset to zero and return -ETIMEDOUT. However the sink crc was > calculated already by this point so we just ignore this return at > the main function. > > So, let's also ignore the message and put it as a debug message instead > of an error one. The message might still be useful when debuging > test failures so we could be able to know something was not going so > well with sink crc stop. > > Reference: https://bugs.freedesktop.org/show_bug.cgi?id=93694 > Cc: Daniel Vetter > Cc: Paulo Zanoni > Signed-off-by: Rodrigo Vivi > --- > drivers/gpu/drm/i915/intel_dp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index c8f58ab..22f6887 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -4009,7 +4009,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp > *intel_dp) > } while (--attempts && count); > > if (attempts == 0) { > - DRM_ERROR("TIMEOUT: Sink CRC counter is not zeroed\n"); > + DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed\n"); > ret = -ETIMEDOUT; Iirc the real problem is that we even try to run the testcase with no eDP panel present. I think fixing up the igt_require logic to correctly skip is the right fix here, not just shutting up the kernel about it. Or maybe the bug is that we register an edp connector when there is none? -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/5] drm/i915: Splitting intel_dp_detect
intel_dp_detect() is called for not just detection but during modes enumeration as well. Repeating the whole sequence during each of these calls is wasteful and time consuming. This patch moves probing for panel, DPCD read etc done in intel_dp_detect() to a new function intel_dp_long_pulse(). Note that the behavior of intel_dp_detect() is changed to report connected or disconnected depending on whether the EDID is available or not. This change will be required by further patches in the series to avoid performing duplicated DPCD operations on hotplug. v2: Moved a hunk to next patch of the series. Moved intel_dp_unset_edid to out. (Ander) v3: Rephrased commit message and intel_dp_unset_dp() is called within intel_dp_set_dp() to free the previous EDID. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 62 ++--- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1761254..8969ff9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -129,6 +129,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); +static void intel_dp_unset_edid(struct intel_dp *intel_dp); static unsigned int intel_dp_unused_lane_mask(int lane_count) { @@ -4577,6 +4578,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp) struct intel_connector *intel_connector = intel_dp->attached_connector; struct edid *edid; + intel_dp_unset_edid(intel_dp); edid = intel_dp_get_edid(intel_dp); intel_connector->detect_edid = edid; @@ -4597,9 +4599,10 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) intel_dp->has_audio = false; } -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, bool force) +static void +intel_dp_long_pulse(struct intel_connector *intel_connector) { + struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -4609,17 +4612,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) bool ret; u8 sink_irq_vector; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_dp_unset_edid(intel_dp); - - if (intel_dp->is_mst) { - /* MST devices are disconnected from a monitor POV */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - return connector_status_disconnected; - } - power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(to_i915(dev), power_domain); @@ -4640,17 +4632,14 @@ intel_dp_detect(struct drm_connector *connector, bool force) goto out; } + if (intel_encoder->type != INTEL_OUTPUT_EDP) + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); - if (ret) { - /* if we are in MST mode then this connector - won't appear connected or have anything with EDID on it */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - status = connector_status_disconnected; + if (ret) goto out; - } /* * Clearing NACK and defer counts to get their exact values @@ -4662,8 +4651,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) intel_dp_set_edid(intel_dp); - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; status = connector_status_connected; /* Try to read the source of the interrupt */ @@ -4681,8 +4668,37 @@ intel_dp_detect(struct drm_connector *connector, bool force) } out: + if (status != connector_status_connected) + intel_dp_unset_edid(intel_dp); intel_display_power_put(to_i915(dev), power_domain); - return status; + return; +} + +static enum drm_connector_status +intel_dp_detect(struct drm_connector *connector, bool force) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &intel_dig_port->base; + struct intel_connecto
Re: [Intel-gfx] [PATCH v4 1/8] drm/i915/gen9: Add framework to whitelist specific GPU registers
On 19/01/2016 09:00, Daniel Vetter wrote: On Thu, Jan 14, 2016 at 03:27:35PM +, Arun Siluvery wrote: Some of the HW registers are privileged and cannot be written to from non-privileged batch buffers coming from userspace unless they are added to the HW whitelist. This whitelist is maintained by HW and it is different from SW whitelist. Userspace need write access to them to implement preemption related WA. The reason for using this approach is, the register bits that control preemption granularity at the HW level are not context save/restored; so even if we set these bits always in kernel they are going to change once the context is switched out. We can consider making them non-privileged by default but these registers also contain other chicken bits which should not be allowed to be modified. In the later revisions controlling bits are save/restored at context level but in the existing revisions these are exported via other debug registers and should be on the whitelist. This patch adds changes to provide HW with a list of registers to be whitelisted. HW checks this list during execution and provides access accordingly. HW imposes a limit on the number of registers on whitelist and it is per-engine. At this point we are only enabling whitelist for RCS and we don't foresee any requirement for other engines. The registers to be whitelisted are added using generic workaround list mechanism, even these are only enablers for userspace workarounds. But by sharing this mechanism we get some test assets without additional cost (Mika). v2: rebase v3: parameterize RING_FORCE_TO_NONPRIV() as _MMIO() should be limited to i915_reg.h (Ville), drop inline for wa_ring_whitelist_reg (Mika). v4: improvements suggested by Chris Wilson. Clarify that this is HW whitelist and different from the one maintained in driver. This list is engine specific but it gets initialized along with other WA which is RCS specific thing, so make it clear that we are not doing any cross engine setup during initialization. Make HW whitelist count of each engine available in debugfs. Reviewed-by: Chris Wilson Reviewed-by: Mika Kuoppala Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Arun Siluvery If you resend just single patches to a series you must --in-reply-to the individual patch, not the cover letter. Otherwise patchwork won't pick it up, which means we don't have CI results for this. Hi Daniel, Yes I did use --in-reply-to but probably not the correct message-id, will keep this in mind. Since it's been a while probably best to just resend the entire pile. Also we seem to be missing r-b tags for the actual w/a changes. yes, actual w/a are yet to be reviewed, I can resend all of them once they are reviewed or you want me to send it now? regards Arun -Daniel --- drivers/gpu/drm/i915/i915_debugfs.c | 15 ++- drivers/gpu/drm/i915/i915_drv.h | 9 - drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 17 + 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e3377ab..7eb002c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3229,9 +3229,11 @@ static int i915_wa_registers(struct seq_file *m, void *unused) { int i; int ret; + struct intel_engine_cs *ring; struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_workarounds *workarounds = &dev_priv->workarounds; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) @@ -3239,15 +3241,18 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count); - for (i = 0; i < dev_priv->workarounds.count; ++i) { + seq_printf(m, "Workarounds applied: %d\n", workarounds->count); + for_each_ring(ring, dev_priv, i) + seq_printf(m, "HW whitelist count for %s: %d\n", + ring->name, workarounds->hw_whitelist_count[i]); + for (i = 0; i < workarounds->count; ++i) { i915_reg_t addr; u32 mask, value, read; bool ok; - addr = dev_priv->workarounds.reg[i].addr; - mask = dev_priv->workarounds.reg[i].mask; - value = dev_priv->workarounds.reg[i].value; + addr = workarounds->reg[i].addr; + mask = workarounds->reg[i].mask; + value = workarounds->reg[i].value; read = I915_READ(addr); ok = (value & mask) == (read & mask); seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, status: %s\n", diff --git a
[Intel-gfx] [PATCH 2/5] drm/i915: Cleaning up intel_dp_hpd_pulse
Current DP detection has DPCD operations split across intel_dp_hpd_pulse and intel_dp_detect which contains duplicates as well. Also intel_dp_detect is called during modes enumeration as well which will result in multiple dpcd operations. So this patch tries to solve both these by bringing all DPCD operations in one single function and make intel_dp_detect use existing values instead of repeating same steps. v2: Pulled in a hunk from last patch of the series to this patch. (Ander) v3: Added MST hotplug handling. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 71 + 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8969ff9..82ee18d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4638,8 +4638,19 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); - if (ret) + if (ret) { + goto out; + } else if (connector->status == connector_status_connected) { + /* +* If display was connected already and is still connected +* check links status, there has been known issues of +* link loss triggerring long pulse +*/ + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); goto out; + } /* * Clearing NACK and defer counts to get their exact values @@ -4668,8 +4679,21 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) } out: - if (status != connector_status_connected) + if (status != connector_status_connected) { intel_dp_unset_edid(intel_dp); + /* +* If we were in MST mode, and device is not there, +* get out of MST mode +*/ + if (intel_dp->is_mst) { + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + intel_dp->is_mst); + } + } + intel_display_power_put(to_i915(dev), power_domain); return; } @@ -4693,7 +4717,8 @@ intel_dp_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - intel_dp_long_pulse(intel_dp->attached_connector); + if (force) + intel_dp_long_pulse(intel_dp->attached_connector); if (intel_connector->detect_edid) return connector_status_connected; @@ -5026,25 +5051,25 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) /* indicate that we need to restart link training */ intel_dp->train_set_valid = false; - if (!intel_digital_port_connected(dev_priv, intel_dig_port)) - goto mst_fail; - - if (!intel_dp_get_dpcd(intel_dp)) { - goto mst_fail; - } - - intel_dp_probe_oui(intel_dp); + intel_dp_long_pulse(intel_dp->attached_connector); + if (intel_dp->is_mst) + ret = IRQ_HANDLED; + goto put_power; - if (!intel_dp_probe_mst(intel_dp)) { - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - intel_dp_check_link_status(intel_dp); - drm_modeset_unlock(&dev->mode_config.connection_mutex); - goto mst_fail; - } } else { if (intel_dp->is_mst) { - if (intel_dp_check_mst_status(intel_dp) == -EINVAL) - goto mst_fail; + if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { + /* +* If we were in MST mode, and device is not +* there, get out of MST mode +*/ + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + i
[Intel-gfx] [PATCH 4/5] drm/i915: Save sink_count for tracking changes to it and read sink_count dpcd always
Sink count can change between short pulse hpd hence this patch adds a member variable to intel_dp so we can track any changes between short pulse interrupts. This patch reads sink_count dpcd always and removes its read operation based on values in downstream port dpcd. SINK_COUNT dpcd is not dependent on DOWNSTREAM_PORT_PRESENT dpcd. SINK_COUNT denotes if a display is attached, while DOWNSTREAM_PORT_PRESET indicates how many ports are available in the dongle where display can be attached. so it is possible for sink count to change irrespective of value in downstream port dpcd. Here is a table of possible values and scenarios sink_count downstream_port present 0 0 no display is attached 0 1 dongle is connected without display 1 0 display connected directly 1 1 display connected through dongle v2: Storing value of intel_dp->sink_count that is ready for consumption. (Ander) Squashing two commits into one. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 18 +++--- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f8d9611..cdf4919 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3855,6 +3855,15 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] == 0) return false; /* DPCD not present */ + if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, + &intel_dp->sink_count, 1) < 0) + return false; + + intel_dp->sink_count = DP_GET_SINK_COUNT(intel_dp->sink_count); + + if (!intel_dp->sink_count) + return false; + /* Check if the panel supports PSR */ memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd)); if (is_edp(intel_dp)) { @@ -4372,14 +4381,9 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) /* If we're HPD-aware, SINK_COUNT changes dynamically */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) { - uint8_t reg; - - if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, - ®, 1) < 0) - return connector_status_unknown; - return DP_GET_SINK_COUNT(reg) ? connector_status_connected - : connector_status_disconnected; + return intel_dp->sink_count ? + connector_status_connected : connector_status_disconnected; } /* If no HPD, poke DDC gently */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 059b46e..0879466 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -774,6 +774,7 @@ struct intel_dp { uint32_t DP; int link_rate; uint8_t lane_count; + uint8_t sink_count; bool has_audio; enum hdmi_force_audio force_audio; bool limited_color_range; -- 2.6.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 5/5] drm/i915: force full detect on sink count change
This patch checks for changes in sink count between short pulse hpds and forces full detect when there is a change. This will allow both detection of hotplug and unplug of panels through dongles that give only short pulse for such events. v2: changed variable type from u8 to bool (Jani) return immediately if perform_full_detect is set(Siva) v3: changed method of determining full detection from using pointer to return code (Siva) v4: changed comments to indicate meaning of return value of intel_dp_short_pulse and explain the use of return value from intel_dp_get_dpcd in intel_dp_short_pulse (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 33 +++-- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cdf4919..120d263 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4325,12 +4325,19 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) * 2. Configure link according to Receiver Capabilities * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 * 4. Check link status on receipt of hot-plug interrupt + * + * intel_dp_short_pulse - handles short pulse interrupts + * when full detection is not required. + * Returns %true if short pulse is handled and full detection + * is NOT required and %false otherwise. */ -static void +static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); u8 sink_irq_vector; + u8 old_sink_count = intel_dp->sink_count; + bool ret; /* * Clearing compliance test variables to allow capturing @@ -4340,9 +4347,17 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { - return; + /* +* Now read the DPCD to see if it's actually running +* If the current value of sink count doesn't match with +* the value that was stored earlier or dpcd read failed +* we need to do full detection +*/ + ret = intel_dp_get_dpcd(intel_dp); + + if ((old_sink_count != intel_dp->sink_count) || !ret) { + /* No need to proceed if we are going to do full detect */ + return false; } /* Try to read the source of the interrupt */ @@ -4362,6 +4377,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return true; } /* XXX this is probably wrong for multiple downstream ports */ @@ -5086,8 +5103,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) - intel_dp_short_pulse(intel_dp); + if (!intel_dp->is_mst) { + if (!intel_dp_short_pulse(intel_dp)) { + intel_dp_long_pulse(intel_dp->attached_connector); + goto put_power; + } + } } ret = IRQ_HANDLED; -- 2.6.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/5] drm/i915: Reorganizing intel_dp_check_link_status
When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. intel_dp_short_pulse: All existing code other than link status read and link training upon error status. intel_dp_check_link_status: The link status should be read on short pulse irrespective of panel being enabled or not so intel_dp_get_link_status() performs dpcd read first then based on crtc active / enabled it will perform the link training. v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) v3: Changed commit message to explain need of link status being read before performing encoder checks (Daniel) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 65 +++-- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82ee18d..f8d9611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4279,6 +4279,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; + + /* if link training is requested we should perform it always */ + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || + (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } +} + /* * According to DP spec * 5.1.2: @@ -4288,14 +4318,10 @@ go_again: * 4. Check link status on receipt of hot-plug interrupt */ static void -intel_dp_check_link_status(struct intel_dp *intel_dp) +intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; - - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); /* * Clearing compliance test variables to allow capturing @@ -4305,17 +4331,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - if (!intel_encoder->base.crtc) - return; - - if (!to_intel_crtc(intel_encoder->base.crtc)->active) - return; - - /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { - return; - } - /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { return; @@ -4335,14 +4350,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); } /* XXX this is probably wrong for multiple downstream ports */ @@ -5072,11 +5082,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) { - drm_modeset_lock(&dev->mo
Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for Fixing sink count related detection over (rev8)
Sure Ander.. Have resent this series of patches.. Will ensure to resend the series for multiple patch changes.. :) Thanks and Regards, Shubhangi Shrivastava. -Original Message- From: Ander Conselvan De Oliveira [mailto:conselv...@gmail.com] Sent: Tuesday, January 19, 2016 3:09 PM To: Patchwork ; Shrivastava, Shubhangi Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for Fixing sink count related detection over (rev8) Hi Shubhangi, On Mon, 2016-01-18 at 13:01 +, Patchwork wrote: > == Summary == > > HEAD is now at 2dd73be drm-intel-nightly: 2016y-01m-18d-09h-59m-27s > UTC integration manifest > Applying: drm/i915: Splitting intel_dp_detect > Applying: drm/i915: Cleaning up intel_dp_hpd_pulse > Applying: drm/i915: Splitting intel_dp_check_link_status > Applying: drm/i915: Save sink_count for tracking changes to it > Applying: drm/i915: Save sink_count for tracking changes to it and > read sink_count dpcd always It seems patchwork got confused about the order of the new patches in this series. When you change multiple patches at once, it is common to resend the entire series without --in-reply-to. It makes it easier for humans and patchwork to figure out which are the new patches. Can you please resend the series as a new thread so we can have the patches go through CI run? Thanks, Ander > Using index info to reconstruct a base tree... > M drivers/gpu/drm/i915/intel_dp.c > M drivers/gpu/drm/i915/intel_drv.h > Falling back to patching base and 3-way merge... > Auto-merging drivers/gpu/drm/i915/intel_dp.c CONFLICT (content): Merge > conflict in drivers/gpu/drm/i915/intel_dp.c Patch failed at 0005 > drm/i915: Save sink_count for tracking changes to it and read > sink_count dpcd always > > ___ > 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 v10] drm/i915: Extend LRC pinning to cover GPU context writeback
On 18/01/16 20:47, Chris Wilson wrote: On Mon, Jan 18, 2016 at 05:14:26PM +, Tvrtko Ursulin wrote: On 18/01/16 16:53, Chris Wilson wrote: On Mon, Jan 18, 2016 at 03:02:25PM +, Tvrtko Ursulin wrote: - while (!list_empty(&ring->request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&ring->request_list, - struct drm_i915_gem_request, - list); - - if (!i915_gem_request_completed(request, true)) + list_for_each_entry_safe(req, next, &ring->request_list, list) { + if (!i915_gem_request_completed(req, true)) break; - i915_gem_request_retire(request); + if (!i915.enable_execlists || !i915.enable_guc_submission) { + i915_gem_request_retire(req); + } else { + prev_req = list_prev_entry(req, list); + if (prev_req) + i915_gem_request_retire(prev_req); + } } To explain, this attempts to ensure that in GuC mode requests are only unreferenced if there is a *following* *completed* request. This way, regardless of whether they are using the same or different contexts, we can be sure that the GPU has either completed the context writing, or that the unreference will not cause the final unpin of the context. This is the first bogus step. contexts have to be unreferenced from request retire, not request free. As it stands today, this forces us to hold the struct_mutex for the free (causing many foul ups along the line). The only reason why it is like that is because of execlists not decoupling its context pinning inside request cancel. What is the first bogus step? My idea of how to fix the GuC issue, or the mention of final unreference in relation to GPU completing the submission? That we want to want to actually unreference the request. We want to unpin the context at the appropriate juncture. At the moment, it looks What would be the appropriate juncture? With GuC we don't have the equivalent of context complete irq. like that you are conflating those two steps: "requests are only unreferenced". Using the retirement mechanism would mean coupling the context unpinning into a subsequent request rather than defer retiring a completed request, for example legacy uses active vma tracking to accomplish the same thing. Aiui, the current claim is that we couldn't do that since the guc may reorder contexts - except that we currently use a global seqno so that would be bad on many levels. I don't know legacy. :( I can see that request/context lifetime is coupled there and associated with request creation to retirement. Does it have the same problem of seqno signaling completion before the GPU is done with writing out the context image and how does it solve that? Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC] drm/i915: Render decompression support for Gen9 and above
Hi, On 10 September 2015 at 16:02, Daniel Vetter wrote: > On Wed, Sep 09, 2015 at 10:04:23AM -0700, Jesse Barnes wrote: >> On 09/09/2015 09:36 AM, Smith, Gary K wrote: >> > I don't understand why this is an issue. Surely the fb is to describe >> > static state about the buffer, not dynamic state. The fb should be >> > created with the compressed modifier. The compressed property is just >> > a hint to the kernel that the buffer has been completely resolved, >> > hence currently it can be treated as an uncompressed fb (and the aux >> > buffer can be ignored). This is dynamic state that may well change >> > very regularly over the lifetime of the buffer. > > There's fb modifier at all in this patch set, not just a static modifier > to be able to check the compression data fits plus a "ignore compression" > runtime knob. > >> > It's still a compressed fb, it contains a aux buffer and had to be >> > created with the compressed fb modifier. However, once the userspace >> > has fully resolved the buffer, the aux buffer can be ignored and the >> > compressed fb can be used in any situation where an uncompressed fb >> > would normally be required. This is dynamic state that may well change >> > very regularly over the lifetime of the buffer. >> > >> > I could allocate two fbs always, and use the appropriate one. We >> > already do this in order to indicate whether a RGBA buffer currently >> > needs to be considered as opaque (RGBX) or blended. Experience has >> > shown that it makes it very complex to debug when the fb keeps on >> > changing its value. However, because we now have 4 different states >> > (Blended/Opaque and Compressed or Resolved), we will now end up with >> > up to 4 fbs per buffer. >> > >> > We aren't just talking about a few fbs here, we already see more than >> > 100 fbs active during complex situations. Potentially doubling this >> > number is surely a significant increase in memory usage, both from the >> > management side in userspace and the kernel side. > > 8kb kernel memory for the additional 2 copies of drm_framebuffer structs > for 100 buffers. That's about as much as the minimal overhead for just 1 > underlying gem object (counting the sg table, vma, gtt pte tracking, gem > object and shmem backing node and pagecache entries). 2 integers in userspace. > > Do you have some data to show that overhead? I agree with this view as well, and it does seem to be the way chosen for generic userspace on other drivers. For context, the way ChromeOS and Wayland compositors (Weston, Mutter, Enlightenment) work is that a userspace library called GBM is distributed as part of EGL, which is the native EGL platform/winsys for rendering on KMS. The major difference with GBM, however, is that it does _not_ do presentation: presentation is explicitly controlled by the compositor itself. In order to use this new property, we would have to add API to EGL/GBM to extract a list of property names to set, which wouldn't really make for great API. It'd be much cleaner for these users to stick with FB modifiers, especially as they destroy and recreate the FB objects (something we've not seen have any performance impact) for every flip anyway. From my side, I'd be much happier using generically-applicable FB modifiers, than continuing along the property explosion. The other sticking point is that if I go from flipping GPU buffers with render compression enabled to software buffers, from userspace that means I then need to explicitly go unset the render decompression flag before I can display software buffers, else the flips just get rejected; something which isn't the case with FB modifiers. One more thing to go wrong ... Cheers, Daniel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/5] drm/i915: Splitting intel_dp_detect
intel_dp_detect() is called for not just detection but during modes enumeration as well. Repeating the whole sequence during each of these calls is wasteful and time consuming. This patch moves probing for panel, DPCD read etc done in intel_dp_detect() to a new function intel_dp_long_pulse(). Note that the behavior of intel_dp_detect() is changed to report connected or disconnected depending on whether the EDID is available or not. This change will be required by further patches in the series to avoid performing duplicated DPCD operations on hotplug. v2: Moved a hunk to next patch of the series. Moved intel_dp_unset_edid to out. (Ander) v3: Rephrased commit message and intel_dp_unset_dp() is called within intel_dp_set_dp() to free the previous EDID. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 62 ++--- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1761254..8969ff9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -129,6 +129,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); +static void intel_dp_unset_edid(struct intel_dp *intel_dp); static unsigned int intel_dp_unused_lane_mask(int lane_count) { @@ -4577,6 +4578,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp) struct intel_connector *intel_connector = intel_dp->attached_connector; struct edid *edid; + intel_dp_unset_edid(intel_dp); edid = intel_dp_get_edid(intel_dp); intel_connector->detect_edid = edid; @@ -4597,9 +4599,10 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) intel_dp->has_audio = false; } -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, bool force) +static void +intel_dp_long_pulse(struct intel_connector *intel_connector) { + struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -4609,17 +4612,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) bool ret; u8 sink_irq_vector; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_dp_unset_edid(intel_dp); - - if (intel_dp->is_mst) { - /* MST devices are disconnected from a monitor POV */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - return connector_status_disconnected; - } - power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(to_i915(dev), power_domain); @@ -4640,17 +4632,14 @@ intel_dp_detect(struct drm_connector *connector, bool force) goto out; } + if (intel_encoder->type != INTEL_OUTPUT_EDP) + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); - if (ret) { - /* if we are in MST mode then this connector - won't appear connected or have anything with EDID on it */ - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - status = connector_status_disconnected; + if (ret) goto out; - } /* * Clearing NACK and defer counts to get their exact values @@ -4662,8 +4651,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) intel_dp_set_edid(intel_dp); - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; status = connector_status_connected; /* Try to read the source of the interrupt */ @@ -4681,8 +4668,37 @@ intel_dp_detect(struct drm_connector *connector, bool force) } out: + if (status != connector_status_connected) + intel_dp_unset_edid(intel_dp); intel_display_power_put(to_i915(dev), power_domain); - return status; + return; +} + +static enum drm_connector_status +intel_dp_detect(struct drm_connector *connector, bool force) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &intel_dig_port->base; + struct intel_connecto
[Intel-gfx] [PATCH 4/5] drm/i915: Save sink_count for tracking changes to it and read sink_count dpcd always
Sink count can change between short pulse hpd hence this patch adds a member variable to intel_dp so we can track any changes between short pulse interrupts. This patch reads sink_count dpcd always and removes its read operation based on values in downstream port dpcd. SINK_COUNT dpcd is not dependent on DOWNSTREAM_PORT_PRESENT dpcd. SINK_COUNT denotes if a display is attached, while DOWNSTREAM_PORT_PRESET indicates how many ports are available in the dongle where display can be attached. so it is possible for sink count to change irrespective of value in downstream port dpcd. Here is a table of possible values and scenarios sink_count downstream_port present 0 0 no display is attached 0 1 dongle is connected without display 1 0 display connected directly 1 1 display connected through dongle v2: Storing value of intel_dp->sink_count that is ready for consumption. (Ander) Squashing two commits into one. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 18 +++--- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f8d9611..cdf4919 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3855,6 +3855,15 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] == 0) return false; /* DPCD not present */ + if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, + &intel_dp->sink_count, 1) < 0) + return false; + + intel_dp->sink_count = DP_GET_SINK_COUNT(intel_dp->sink_count); + + if (!intel_dp->sink_count) + return false; + /* Check if the panel supports PSR */ memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd)); if (is_edp(intel_dp)) { @@ -4372,14 +4381,9 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) /* If we're HPD-aware, SINK_COUNT changes dynamically */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) { - uint8_t reg; - - if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_COUNT, - ®, 1) < 0) - return connector_status_unknown; - return DP_GET_SINK_COUNT(reg) ? connector_status_connected - : connector_status_disconnected; + return intel_dp->sink_count ? + connector_status_connected : connector_status_disconnected; } /* If no HPD, poke DDC gently */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 059b46e..0879466 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -774,6 +774,7 @@ struct intel_dp { uint32_t DP; int link_rate; uint8_t lane_count; + uint8_t sink_count; bool has_audio; enum hdmi_force_audio force_audio; bool limited_color_range; -- 2.6.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/5] drm/i915: Reorganizing intel_dp_check_link_status
When created originally intel_dp_check_link_status() was supposed to handle only link training for short pulse but has grown into handler for short pulse itself. This patch cleans up this function by splitting it into two halves. First intel_dp_short_pulse() is called, which will be entry point and handle all logic for short pulse handling while intel_dp_check_link_status() will retain its original purpose of only doing link status related work. intel_dp_short_pulse: All existing code other than link status read and link training upon error status. intel_dp_check_link_status: The link status should be read on short pulse irrespective of panel being enabled or not so intel_dp_get_link_status() performs dpcd read first then based on crtc active / enabled it will perform the link training. v2: Added WARN_ON to intel_dp_check_link_status() Removed a call to intel_dp_get_link_status() (Ander) v3: Changed commit message to explain need of link status being read before performing encoder checks (Daniel) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 65 +++-- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 82ee18d..f8d9611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4279,6 +4279,36 @@ go_again: return -EINVAL; } +static void +intel_dp_check_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_dp_to_dev(intel_dp); + u8 link_status[DP_LINK_STATUS_SIZE]; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (!intel_dp_get_link_status(intel_dp, link_status)) { + DRM_ERROR("Failed to get link status\n"); + return; + } + + if (!intel_encoder->base.crtc) + return; + + if (!to_intel_crtc(intel_encoder->base.crtc)->active) + return; + + /* if link training is requested we should perform it always */ + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || + (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", + intel_encoder->base.name); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } +} + /* * According to DP spec * 5.1.2: @@ -4288,14 +4318,10 @@ go_again: * 4. Check link status on receipt of hot-plug interrupt */ static void -intel_dp_check_link_status(struct intel_dp *intel_dp) +intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; - - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); /* * Clearing compliance test variables to allow capturing @@ -4305,17 +4331,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - if (!intel_encoder->base.crtc) - return; - - if (!to_intel_crtc(intel_encoder->base.crtc)->active) - return; - - /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { - return; - } - /* Now read the DPCD to see if it's actually running */ if (!intel_dp_get_dpcd(intel_dp)) { return; @@ -4335,14 +4350,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - intel_encoder->base.name); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); } /* XXX this is probably wrong for multiple downstream ports */ @@ -5072,11 +5082,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) { - drm_modeset_lock(&dev->mo
[Intel-gfx] [PATCH 2/5] drm/i915: Cleaning up intel_dp_hpd_pulse
Current DP detection has DPCD operations split across intel_dp_hpd_pulse and intel_dp_detect which contains duplicates as well. Also intel_dp_detect is called during modes enumeration as well which will result in multiple dpcd operations. So this patch tries to solve both these by bringing all DPCD operations in one single function and make intel_dp_detect use existing values instead of repeating same steps. v2: Pulled in a hunk from last patch of the series to this patch. (Ander) v3: Added MST hotplug handling. (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 71 + 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8969ff9..82ee18d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4638,8 +4638,19 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) intel_dp_probe_oui(intel_dp); ret = intel_dp_probe_mst(intel_dp); - if (ret) + if (ret) { + goto out; + } else if (connector->status == connector_status_connected) { + /* +* If display was connected already and is still connected +* check links status, there has been known issues of +* link loss triggerring long pulse +*/ + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + intel_dp_check_link_status(intel_dp); + drm_modeset_unlock(&dev->mode_config.connection_mutex); goto out; + } /* * Clearing NACK and defer counts to get their exact values @@ -4668,8 +4679,21 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) } out: - if (status != connector_status_connected) + if (status != connector_status_connected) { intel_dp_unset_edid(intel_dp); + /* +* If we were in MST mode, and device is not there, +* get out of MST mode +*/ + if (intel_dp->is_mst) { + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + intel_dp->is_mst); + } + } + intel_display_power_put(to_i915(dev), power_domain); return; } @@ -4693,7 +4717,8 @@ intel_dp_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - intel_dp_long_pulse(intel_dp->attached_connector); + if (force) + intel_dp_long_pulse(intel_dp->attached_connector); if (intel_connector->detect_edid) return connector_status_connected; @@ -5026,25 +5051,25 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) /* indicate that we need to restart link training */ intel_dp->train_set_valid = false; - if (!intel_digital_port_connected(dev_priv, intel_dig_port)) - goto mst_fail; - - if (!intel_dp_get_dpcd(intel_dp)) { - goto mst_fail; - } - - intel_dp_probe_oui(intel_dp); + intel_dp_long_pulse(intel_dp->attached_connector); + if (intel_dp->is_mst) + ret = IRQ_HANDLED; + goto put_power; - if (!intel_dp_probe_mst(intel_dp)) { - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - intel_dp_check_link_status(intel_dp); - drm_modeset_unlock(&dev->mode_config.connection_mutex); - goto mst_fail; - } } else { if (intel_dp->is_mst) { - if (intel_dp_check_mst_status(intel_dp) == -EINVAL) - goto mst_fail; + if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { + /* +* If we were in MST mode, and device is not +* there, get out of MST mode +*/ + DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", + intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst = false; + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, + i
[Intel-gfx] [PATCH 5/5] drm/i915: force full detect on sink count change
This patch checks for changes in sink count between short pulse hpds and forces full detect when there is a change. This will allow both detection of hotplug and unplug of panels through dongles that give only short pulse for such events. v2: changed variable type from u8 to bool (Jani) return immediately if perform_full_detect is set(Siva) v3: changed method of determining full detection from using pointer to return code (Siva) v4: changed comments to indicate meaning of return value of intel_dp_short_pulse and explain the use of return value from intel_dp_get_dpcd in intel_dp_short_pulse (Ander) Tested-by: Nathan D Ciobanu Signed-off-by: Sivakumar Thulasimani Signed-off-by: Shubhangi Shrivastava --- drivers/gpu/drm/i915/intel_dp.c | 33 +++-- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cdf4919..120d263 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4325,12 +4325,19 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) * 2. Configure link according to Receiver Capabilities * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 * 4. Check link status on receipt of hot-plug interrupt + * + * intel_dp_short_pulse - handles short pulse interrupts + * when full detection is not required. + * Returns %true if short pulse is handled and full detection + * is NOT required and %false otherwise. */ -static void +static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); u8 sink_irq_vector; + u8 old_sink_count = intel_dp->sink_count; + bool ret; /* * Clearing compliance test variables to allow capturing @@ -4340,9 +4347,17 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_dp->compliance_test_type = 0; intel_dp->compliance_test_data = 0; - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { - return; + /* +* Now read the DPCD to see if it's actually running +* If the current value of sink count doesn't match with +* the value that was stored earlier or dpcd read failed +* we need to do full detection +*/ + ret = intel_dp_get_dpcd(intel_dp); + + if ((old_sink_count != intel_dp->sink_count) || !ret) { + /* No need to proceed if we are going to do full detect */ + return false; } /* Try to read the source of the interrupt */ @@ -4362,6 +4377,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return true; } /* XXX this is probably wrong for multiple downstream ports */ @@ -5086,8 +5103,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) } } - if (!intel_dp->is_mst) - intel_dp_short_pulse(intel_dp); + if (!intel_dp->is_mst) { + if (!intel_dp_short_pulse(intel_dp)) { + intel_dp_long_pulse(intel_dp->attached_connector); + goto put_power; + } + } } ret = IRQ_HANDLED; -- 2.6.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: warning for series starting with [1/5] drm/i915: Splitting intel_dp_detect
== Summary == Built on 00a0c7d1ae09b1259c7af8e5a088b0b225d805df drm-intel-nightly: 2016y-01m-18d-16h-50m-37s UTC integration manifest Test kms_flip: Subgroup basic-flip-vs-dpms: dmesg-warn -> PASS (skl-i5k-2) Test kms_pipe_crc_basic: Subgroup read-crc-pipe-b: pass -> DMESG-WARN (ilk-hp8440p) bdw-nuci7total:140 pass:131 dwarn:0 dfail:0 fail:0 skip:9 bdw-ultratotal:140 pass:133 dwarn:0 dfail:1 fail:0 skip:6 byt-nuc total:143 pass:125 dwarn:3 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:101 dwarn:4 dfail:0 fail:0 skip:38 ivb-t430stotal:137 pass:124 dwarn:3 dfail:4 fail:0 skip:6 skl-i5k-2total:143 pass:134 dwarn:1 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1217/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: warning for series starting with [1/5] drm/i915: Splitting intel_dp_detect
== Summary == Built on 00a0c7d1ae09b1259c7af8e5a088b0b225d805df drm-intel-nightly: 2016y-01m-18d-16h-50m-37s UTC integration manifest Test gem_storedw_loop: Subgroup basic-render: pass -> DMESG-WARN (skl-i5k-2) UNSTABLE pass -> DMESG-WARN (bdw-nuci7) UNSTABLE pass -> DMESG-WARN (bdw-ultra) UNSTABLE Test kms_flip: Subgroup basic-flip-vs-dpms: dmesg-warn -> PASS (skl-i5k-2) Test kms_pipe_crc_basic: Subgroup read-crc-pipe-b: pass -> DMESG-WARN (ilk-hp8440p) bdw-nuci7total:140 pass:130 dwarn:1 dfail:0 fail:0 skip:9 bdw-ultratotal:140 pass:132 dwarn:1 dfail:1 fail:0 skip:6 byt-nuc total:143 pass:125 dwarn:3 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:101 dwarn:4 dfail:0 fail:0 skip:38 ivb-t430stotal:137 pass:124 dwarn:3 dfail:4 fail:0 skip:6 skl-i5k-2total:143 pass:133 dwarn:2 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1218/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v11] drm/i915: Extend LRC pinning to cover GPU context writeback
Use the first retired request on a new context to unpin the old context. This ensures that the hw context remains bound until it has been written back to by the GPU. Now that the context is pinned until later in the request/context lifecycle, it no longer needs to be pinned from context_queue to retire_requests. This fixes an issue with GuC submission where the GPU might not have finished writing back the context before it is unpinned. This results in a GPU hang. v2: Moved the new pin to cover GuC submission (Alex Dai) Moved the new unpin to request_retire to fix coverage leak v3: Added switch to default context if freeing a still pinned context just in case the hw was actually still using it v4: Unwrapped context unpin to allow calling without a request v5: Only create a switch to idle context if the ring doesn't already have a request pending on it (Alex Dai) Rename unsaved to dirty to avoid double negatives (Dave Gordon) Changed _no_req postfix to __ prefix for consistency (Dave Gordon) Split out per engine cleanup from context_free as it was getting unwieldy Corrected locking (Dave Gordon) v6: Removed some bikeshedding (Mika Kuoppala) Added explanation of the GuC hang that this fixes (Daniel Vetter) v7: Removed extra per request pinning from ring reset code (Alex Dai) Added forced ring unpin/clean in error case in context free (Alex Dai) v8: Renamed lrc specific last_context to lrc_last_context as there were some reset cases where the codepaths leaked (Mika Kuoppala) NULL'd last_context in reset case - there was a pointer leak if someone did reset->close context. v9: Rebase over "Fix context/engine cleanup order" v10: Rebase over nightly, remove WARN_ON which caused the dependency on dev. v11: Kick BAT rerun Signed-off-by: Nick Hoath Issue: VIZ-4277 Cc: Daniel Vetter Cc: David Gordon Cc: Chris Wilson Cc: Alex Dai Cc: Mika Kuoppala --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 3 + drivers/gpu/drm/i915/intel_lrc.c| 138 ++-- drivers/gpu/drm/i915/intel_lrc.h| 1 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 5 files changed, 121 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 104bd18..d28e10a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -882,6 +882,7 @@ struct intel_context { struct { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; + bool dirty; int pin_count; } engine[I915_NUM_RINGS]; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ddc21d4..7b79405 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1413,6 +1413,9 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) { trace_i915_gem_request_retire(request); + if (i915.enable_execlists) + intel_lr_context_complete_check(request); + /* We know the GPU must have read the request to have * sent us the seqno + interrupt, so use the position * of tail of the request to update the last known position diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5027699..b661058 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -585,9 +585,6 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) struct drm_i915_gem_request *cursor; int num_elements = 0; - if (request->ctx != ring->default_context) - intel_lr_context_pin(request); - i915_gem_request_reference(request); spin_lock_irq(&ring->execlist_lock); @@ -763,6 +760,13 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) if (intel_ring_stopped(ring)) return; + if (request->ctx != ring->default_context) { + if (!request->ctx->engine[ring->id].dirty) { + intel_lr_context_pin(request); + request->ctx->engine[ring->id].dirty = true; + } + } + if (dev_priv->guc.execbuf_client) i915_guc_submit(dev_priv->guc.execbuf_client, request); else @@ -989,12 +993,6 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring) spin_unlock_irq(&ring->execlist_lock); list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { - struct intel_context *ctx = req->ctx; - struct drm_i915_gem_object *ctx_obj = - ctx->engine[ring->id].state; - - if (ctx_obj && (ctx != ring->default_context)) - intel_lr_context_unpin(req); list_del(&req->execlist_link);
[Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: Extend LRC pinning to cover GPU context writeback (rev6)
== Summary == HEAD is now at 00a0c7d drm-intel-nightly: 2016y-01m-18d-16h-50m-37s UTC integration manifest Applying: drm/i915: Extend LRC pinning to cover GPU context writeback Using index info to reconstruct a base tree... M drivers/gpu/drm/i915/i915_drv.h M drivers/gpu/drm/i915/i915_gem.c M drivers/gpu/drm/i915/intel_lrc.c M drivers/gpu/drm/i915/intel_lrc.h M drivers/gpu/drm/i915/intel_ringbuffer.h Falling back to patching base and 3-way merge... Auto-merging drivers/gpu/drm/i915/intel_ringbuffer.h Auto-merging drivers/gpu/drm/i915/intel_lrc.h Auto-merging drivers/gpu/drm/i915/intel_lrc.c CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_lrc.c Auto-merging drivers/gpu/drm/i915/i915_gem.c Auto-merging drivers/gpu/drm/i915/i915_drv.h Patch failed at 0001 drm/i915: Extend LRC pinning to cover GPU context writeback ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 1/8] drm/i915/gen9: Add framework to whitelist specific GPU registers
On Tue, Jan 19, 2016 at 10:16:52AM +, Arun Siluvery wrote: > On 19/01/2016 09:00, Daniel Vetter wrote: > >On Thu, Jan 14, 2016 at 03:27:35PM +, Arun Siluvery wrote: > >>Some of the HW registers are privileged and cannot be written to from > >>non-privileged batch buffers coming from userspace unless they are added to > >>the HW whitelist. This whitelist is maintained by HW and it is different > >>from > >>SW whitelist. Userspace need write access to them to implement preemption > >>related WA. > >> > >>The reason for using this approach is, the register bits that control > >>preemption granularity at the HW level are not context save/restored; so > >>even > >>if we set these bits always in kernel they are going to change once the > >>context is switched out. We can consider making them non-privileged by > >>default but these registers also contain other chicken bits which should not > >>be allowed to be modified. > >> > >>In the later revisions controlling bits are save/restored at context level > >>but > >>in the existing revisions these are exported via other debug registers and > >>should be on the whitelist. This patch adds changes to provide HW with a > >>list > >>of registers to be whitelisted. HW checks this list during execution and > >>provides access accordingly. > >> > >>HW imposes a limit on the number of registers on whitelist and it is > >>per-engine. At this point we are only enabling whitelist for RCS and we > >>don't > >>foresee any requirement for other engines. > >> > >>The registers to be whitelisted are added using generic workaround list > >>mechanism, even these are only enablers for userspace workarounds. But by > >>sharing this mechanism we get some test assets without additional cost > >>(Mika). > >> > >>v2: rebase > >> > >>v3: parameterize RING_FORCE_TO_NONPRIV() as _MMIO() should be limited to > >>i915_reg.h (Ville), drop inline for wa_ring_whitelist_reg (Mika). > >> > >>v4: improvements suggested by Chris Wilson. > >>Clarify that this is HW whitelist and different from the one maintained in > >>driver. This list is engine specific but it gets initialized along with > >>other > >>WA which is RCS specific thing, so make it clear that we are not doing any > >>cross engine setup during initialization. > >>Make HW whitelist count of each engine available in debugfs. > >> > >>Reviewed-by: Chris Wilson > >>Reviewed-by: Mika Kuoppala > >>Cc: Mika Kuoppala > >>Cc: Chris Wilson > >>Signed-off-by: Arun Siluvery > > > >If you resend just single patches to a series you must --in-reply-to the > >individual patch, not the cover letter. Otherwise patchwork won't pick it > >up, which means we don't have CI results for this. > > Hi Daniel, > > Yes I did use --in-reply-to but probably not the correct message-id, will > keep this in mind. > > > > >Since it's been a while probably best to just resend the entire pile. > > > >Also we seem to be missing r-b tags for the actual w/a changes. > yes, actual w/a are yet to be reviewed, I can resend all of them once they > are reviewed or you want me to send it now? Either way is fine I think. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear pending reset requests during suspend
On Thu, Jan 14, 2016 at 10:49:45AM +, Arun Siluvery wrote: > Pending reset requests are cleared before suspending, they should be picked up > after resume when new work is submitted. > > This is originally added as part of TDR patches for Gen8 from Tomas Elf which > are under review, as suggested by Chris this is extracted as a separate patch > as it can be useful now. > > Cc: Mika Kuoppala > Cc: Chris Wilson > Signed-off-by: Arun Siluvery Pulling in the discussion we had from irc: Imo the right approach is to simply wait for gpu reset to finish it's job. Since that could in turn lead to a dead gpu (if we're unlucky and init_hw failed) we'd need to do that in a loop around gem_idle. And drop dev->struct_mutex in-between. E.g. while (busy) { mutex_lock(); gpu_idle(); mutex_unlock(); flush_work(reset_work); } Cheers, Daniel > --- > drivers/gpu/drm/i915/i915_drv.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index f17a2b0..09ed83e 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -594,6 +594,13 @@ static int i915_drm_suspend(struct drm_device *dev) > goto out; > } > > + /* > + * Clear any pending reset requests. They should be picked up > + * after resume when new work is submitted > + */ > + atomic_clear_mask(I915_RESET_IN_PROGRESS_FLAG, > + &dev_priv->gpu_error.reset_counter); > + > intel_guc_suspend(dev); > > intel_suspend_gt_powersave(dev); > -- > 1.9.1 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: skl_update_scaler() wants a rotation bitmask instead of bit number
On Tue, Jan 19, 2016 at 09:03:13AM +0100, Daniel Vetter wrote: > On Mon, Jan 18, 2016 at 04:21:40PM +0200, Ville Syrjälä wrote: > > On Fri, Jan 15, 2016 at 03:15:00PM -0800, Matt Roper wrote: > > > On Fri, Jan 15, 2016 at 08:48:26PM +0200, Ville Syrjälä wrote: > > > > On Thu, Oct 15, 2015 at 05:01:58PM +0300, ville.syrj...@linux.intel.com > > > > wrote: > > > > > From: Ville Syrjälä > > > > > > > > > > Pass BIT(DRM_ROTATE_0) instead of DRM_ROTATE_0 to skl_update_scaler(). > > > > > The former is a mask, the latter just the bit number. > > > > > > > > > > Fortunately the only thing skl_update_scaler() does with the rotation > > > > > is check if it's 90/270 degrees or not, and so in this case it would > > > > > still do the right thing. > > > > > > > > > > Cc: Chandra Konduru > > > > > Signed-off-by: Ville Syrjälä > > > > > > > > Ping, anyone care to r-b this one? > > > > > > Reviewed-by: Matt Roper > > > > > > Looks like this bug has been present since scalers were first added in > > > 6156a45602f9 ("drm/i915: skylake primary plane scaling using shared > > > scalers") > > > > Pushed to dinq an appropriate Fixes: comment added. Thanks for the review. > > Do we have an igt for this? If not need to capture it and make it > something we must fixe before more scaler stuff lands. There's no change in behavior from this fix, so there's nothing to test. -- 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 5/7] drm/i915: Move allocation of various workqueues earlier during init
Workqueue initalization doesn't depend on any other device specific resource, so move it close to the beginning, so we don't need to consider them when thinking about dependencies for other resources. Also factor out things to separate init/cleanup functions to make i915_driver_load()/unload() clearer, atm it's somewhat difficult to follow there in what order resources are inited/cleaned-up. Suggested-by: Chris Wilson Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 101 ++-- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b931dad..7934611 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -856,6 +856,54 @@ static void intel_init_dpio(struct drm_i915_private *dev_priv) } } +static int i915_workqueues_init(struct drm_i915_private *dev_priv) +{ + /* +* The i915 workqueue is primarily used for batched retirement of +* requests (and thus managing bo) once the task has been completed +* by the GPU. i915_gem_retire_requests() is called directly when we +* need high-priority retirement, such as waiting for an explicit +* bo. +* +* It is also used for periodic low-priority events, such as +* idle-timers and recording error state. +* +* All tasks on the workqueue are expected to acquire the dev mutex +* so there is no point in running more than one instance of the +* workqueue at any time. Use an ordered one. +*/ + dev_priv->wq = alloc_ordered_workqueue("i915", 0); + if (dev_priv->wq == NULL) + goto out_err; + + dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); + if (dev_priv->hotplug.dp_wq == NULL) + goto out_free_wq; + + dev_priv->gpu_error.hangcheck_wq = + alloc_ordered_workqueue("i915-hangcheck", 0); + if (dev_priv->gpu_error.hangcheck_wq == NULL) + goto out_free_dp_wq; + + return 0; + +out_free_dp_wq: + destroy_workqueue(dev_priv->hotplug.dp_wq); +out_free_wq: + destroy_workqueue(dev_priv->wq); +out_err: + DRM_ERROR("Failed to allocate workqueues.\n"); + + return -ENOMEM; +} + +static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) +{ + destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); + destroy_workqueue(dev_priv->hotplug.dp_wq); + destroy_workqueue(dev_priv->wq); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -899,6 +947,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->av_mutex); mutex_init(&dev_priv->wm.wm_mutex); + ret = i915_workqueues_init(dev_priv); + if (ret < 0) + goto out_free_priv; + intel_pm_setup(dev); intel_runtime_pm_get(dev_priv); @@ -993,41 +1045,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, aperture_size); - /* The i915 workqueue is primarily used for batched retirement of -* requests (and thus managing bo) once the task has been completed -* by the GPU. i915_gem_retire_requests() is called directly when we -* need high-priority retirement, such as waiting for an explicit -* bo. -* -* It is also used for periodic low-priority events, such as -* idle-timers and recording error state. -* -* All tasks on the workqueue are expected to acquire the dev mutex -* so there is no point in running more than one instance of the -* workqueue at any time. Use an ordered one. -*/ - dev_priv->wq = alloc_ordered_workqueue("i915", 0); - if (dev_priv->wq == NULL) { - DRM_ERROR("Failed to create our workqueue.\n"); - ret = -ENOMEM; - goto out_mtrrfree; - } - - dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); - if (dev_priv->hotplug.dp_wq == NULL) { - DRM_ERROR("Failed to create our dp workqueue.\n"); - ret = -ENOMEM; - goto out_freewq; - } - - dev_priv->gpu_error.hangcheck_wq = - alloc_ordered_workqueue("i915-hangcheck", 0); - if (dev_priv->gpu_error.hangcheck_wq == NULL) { - DRM_ERROR("Failed to create our hangcheck workqueue.\n"); - ret = -ENOMEM; - goto out_freedpwq; - } - intel_irq_init(dev_priv); intel_uncore_sanitize(dev); @@ -1107,12 +1124,6 @@ out_gem_unload: intel_teardown_mchbar(dev); pm_qos_remove_request(&dev_priv->pm_qos); - destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); -out_fr
[Intel-gfx] [PATCH 2/7] drm/i915: Sanitize i915_get_bridge_dev() error path
Clarify the name of the label on the error path, making it clear what's being cleaned up. The kmem_cache_destroy() calls are NOPs on the corresponding error path. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7dd8ec5..48ce972 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -917,7 +917,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (i915_get_bridge_dev(dev)) { ret = -EIO; - goto free_priv; + goto out_runtime_pm_put; } mmio_bar = IS_GEN2(dev) ? 1 : 0; @@ -1122,11 +1122,10 @@ out_uncore_fini: pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); -free_priv: kmem_cache_destroy(dev_priv->requests); kmem_cache_destroy(dev_priv->vmas); kmem_cache_destroy(dev_priv->objects); - +out_runtime_pm_put: intel_runtime_pm_put(dev_priv); kfree(dev_priv); -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/7] drm/i915: Move load time stolen memory init earlier
For Sagar's BXT RC6 setup sanitization patch [1], we'll need the details about the GTT/stolen memory reservation early during driver loading, so this patchset moves the required init calls earlier accordingly. It also sanitizes a few MMIO/GEM init/clean-up steps on the way. [1] http://lists.freedesktop.org/archives/intel-gfx/2016-January/085440.html Imre Deak (7): drm/i915: Sanitize up DMC/CSR ucode cleanup code drm/i915: Sanitize i915_get_bridge_dev() error path drm/i915: Sanitize GEM shrinker init and clean-up drm/i915: Sanitize i915_gem_load() init and clean-up drm/i915: Move allocation of various workqueues earlier during init drm/i915: Move MCHBAR setup earlier during init drm/i915: Move stolen memory initialization earlier during loading drivers/gpu/drm/i915/i915_dma.c | 218 --- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_gem.c | 13 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +++ drivers/gpu/drm/i915/i915_gem_shrinker.c | 16 ++- 5 files changed, 158 insertions(+), 108 deletions(-) -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/7] drm/i915: Sanitize GEM shrinker init and clean-up
Factor out the common GEM shrinker clean-up code and call the shrinker init function from the same function from where the corresponding shrinker clean-up function is called. Also add sanity checking to the shrinker and OOM registration calls. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 7 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 2 -- drivers/gpu/drm/i915/i915_gem_shrinker.c | 16 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 48ce972..6f9988f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1036,6 +1036,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_opregion_setup(dev); i915_gem_load(dev); + i915_gem_shrinker_init(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there @@ -1099,8 +1100,7 @@ out_power_well: intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); out_gem_unload: - WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); - unregister_shrinker(&dev_priv->mm.shrinker); + i915_gem_shrinker_cleanup(dev_priv); if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); @@ -1153,8 +1153,7 @@ int i915_driver_unload(struct drm_device *dev) i915_teardown_sysfs(dev); - WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); - unregister_shrinker(&dev_priv->mm.shrinker); + i915_gem_shrinker_cleanup(dev_priv); io_mapping_free(dev_priv->gtt.mappable); arch_phys_wc_del(dev_priv->gtt.mtrr); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af30148..21ea132 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3263,6 +3263,7 @@ unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, #define I915_SHRINK_ACTIVE 0x8 unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); void i915_gem_shrinker_init(struct drm_i915_private *dev_priv); +void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv); /* i915_gem_tiling.c */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6b0102d..bf7f741 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5063,8 +5063,6 @@ i915_gem_load(struct drm_device *dev) dev_priv->mm.interruptible = true; - i915_gem_shrinker_init(dev_priv); - mutex_init(&dev_priv->fb_tracking.lock); } diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 16da9c1..58c1e59 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -367,8 +367,20 @@ void i915_gem_shrinker_init(struct drm_i915_private *dev_priv) dev_priv->mm.shrinker.scan_objects = i915_gem_shrinker_scan; dev_priv->mm.shrinker.count_objects = i915_gem_shrinker_count; dev_priv->mm.shrinker.seeks = DEFAULT_SEEKS; - register_shrinker(&dev_priv->mm.shrinker); + WARN_ON(register_shrinker(&dev_priv->mm.shrinker)); dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom; - register_oom_notifier(&dev_priv->mm.oom_notifier); + WARN_ON(register_oom_notifier(&dev_priv->mm.oom_notifier)); +} + +/** + * i915_gem_shrinker_cleanup - Clean up i915 shrinker + * @dev_priv: i915 device + * + * This function unregisters the i915 shrinker and OOM handler. + */ +void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv) +{ + WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); + unregister_shrinker(&dev_priv->mm.shrinker); } -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/7] drm/i915: Sanitize i915_gem_load() init and clean-up
Factor out common clean-up code for the GEM load time init function. Also rename i915_gem_load() to i915_gem_load_init() to have a better match with its new clean-up function. No functional change. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 10 +++--- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 11 ++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6f9988f..b931dad 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1035,7 +1035,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_setup_mchbar(dev); intel_opregion_setup(dev); - i915_gem_load(dev); + i915_gem_load_init(dev); i915_gem_shrinker_init(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the @@ -1122,9 +1122,7 @@ out_uncore_fini: pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); - kmem_cache_destroy(dev_priv->requests); - kmem_cache_destroy(dev_priv->vmas); - kmem_cache_destroy(dev_priv->objects); + i915_gem_load_cleanup(dev); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); @@ -1216,9 +1214,7 @@ int i915_driver_unload(struct drm_device *dev) if (dev_priv->regs != NULL) pci_iounmap(dev->pdev, dev_priv->regs); - kmem_cache_destroy(dev_priv->requests); - kmem_cache_destroy(dev_priv->vmas); - kmem_cache_destroy(dev_priv->objects); + i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); kfree(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 21ea132..e3dfc05 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2850,7 +2850,8 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -void i915_gem_load(struct drm_device *dev); +void i915_gem_load_init(struct drm_device *dev); +void i915_gem_load_cleanup(struct drm_device *dev); void *i915_gem_object_alloc(struct drm_device *dev); void i915_gem_object_free(struct drm_i915_gem_object *obj); void i915_gem_object_init(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf7f741..989ff22 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4997,7 +4997,7 @@ init_ring_lists(struct intel_engine_cs *ring) } void -i915_gem_load(struct drm_device *dev) +i915_gem_load_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; @@ -5066,6 +5066,15 @@ i915_gem_load(struct drm_device *dev) mutex_init(&dev_priv->fb_tracking.lock); } +void i915_gem_load_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + kmem_cache_destroy(dev_priv->requests); + kmem_cache_destroy(dev_priv->vmas); + kmem_cache_destroy(dev_priv->objects); +} + void i915_gem_release(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 7/7] drm/i915: Move stolen memory initialization earlier during loading
The only device specific dependency of the stolen memory setup is the MMIO mapping and the stolen memory size. Both are already available in i915_gtt_init(), so move the stolen initialization to there. The clean-up code for i915_gtt_init() is in i915_global_gtt_cleanup(), so move the stolen memory clean-up code there too. This will be needed by an upcoming patch that needs the details of the memory we reserve, but the change is also part of our generic goal to move the initialization of resources with no or little dependencies on other device specific resources towards the beginning of the init sequence. Suggested-by: Chris Wilson Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 10 -- drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a054169..d23cf01 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -391,13 +391,6 @@ static int i915_load_modeset_init(struct drm_device *dev) if (ret) goto cleanup_vga_client; - /* Initialise stolen first so that we may reserve preallocated -* objects for the BIOS to KMS transition. -*/ - ret = i915_gem_init_stolen(dev); - if (ret) - goto cleanup_vga_switcheroo; - intel_power_domains_init_hw(dev_priv, false); intel_csr_ucode_init(dev_priv); @@ -460,8 +453,6 @@ cleanup_irq: intel_teardown_gmbus(dev); cleanup_csr: intel_csr_ucode_fini(dev_priv); - i915_gem_cleanup_stolen(dev); -cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); @@ -1234,7 +1225,6 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); - i915_gem_cleanup_stolen(dev); pm_qos_remove_request(&dev_priv->pm_qos); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7377b67..2ccb2b5 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2809,6 +2809,8 @@ void i915_global_gtt_cleanup(struct drm_device *dev) ppgtt->base.cleanup(&ppgtt->base); } + i915_gem_cleanup_stolen(dev); + if (drm_mm_initialized(&vm->mm)) { if (intel_vgpu_active(dev)) intel_vgt_deballoon(); @@ -3181,6 +3183,14 @@ int i915_gem_gtt_init(struct drm_device *dev) if (ret) return ret; + /* +* Initialise stolen early so that we may reserve preallocated +* objects for the BIOS to KMS transition. +*/ + ret = i915_gem_init_stolen(dev); + if (ret) + goto out_gtt_cleanup; + /* GMADR is the PCI mmio aperture into the global GTT. */ DRM_INFO("Memory usable by graphics device = %lluM\n", gtt->base.total >> 20); @@ -3200,6 +3210,11 @@ int i915_gem_gtt_init(struct drm_device *dev) DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); return 0; + +out_gtt_cleanup: + gtt->base.cleanup(&dev_priv->gtt.base); + + return ret; } void i915_gem_restore_gtt_mappings(struct drm_device *dev) -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/7] drm/i915: Sanitize up DMC/CSR ucode cleanup code
commit ebae38d061df3deffa7c17b030ea14a5216ee55f Author: Animesh Manna Date: Wed Oct 28 23:58:55 2015 +0200 drm/i915/gen9: csr_init after runtime pm enable moved the DMC/CSR initialization later during driver loading, but didn't move the cleanup earlier correspondingly during unloading. Fix this up. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a0f5659..7dd8ec5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -404,7 +404,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ret = intel_irq_install(dev_priv); if (ret) - goto cleanup_gem_stolen; + goto cleanup_csr; intel_setup_gmbus(dev); @@ -458,7 +458,8 @@ cleanup_irq: intel_guc_ucode_fini(dev); drm_irq_uninstall(dev); intel_teardown_gmbus(dev); -cleanup_gem_stolen: +cleanup_csr: + intel_csr_ucode_fini(dev_priv); i915_gem_cleanup_stolen(dev); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); @@ -946,7 +947,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = i915_gem_gtt_init(dev); if (ret) - goto out_freecsr; + goto out_uncore_fini; /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ @@ -1116,8 +1117,7 @@ out_mtrrfree: io_mapping_free(dev_priv->gtt.mappable); out_gtt: i915_global_gtt_cleanup(dev); -out_freecsr: - intel_csr_ucode_fini(dev_priv); +out_uncore_fini: intel_uncore_fini(dev); pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: @@ -1183,6 +1183,8 @@ int i915_driver_unload(struct drm_device *dev) vga_switcheroo_unregister_client(dev->pdev); vga_client_register(dev->pdev, NULL, NULL, NULL); + intel_csr_ucode_fini(dev_priv); + /* Free error state after interrupts are fully disabled. */ cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); i915_destroy_error_state(dev); @@ -1203,8 +1205,6 @@ int i915_driver_unload(struct drm_device *dev) intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); - intel_csr_ucode_fini(dev_priv); - intel_teardown_mchbar(dev); destroy_workqueue(dev_priv->hotplug.dp_wq); -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 6/7] drm/i915: Move MCHBAR setup earlier during init
Move the MCHBAR setup right after the MMIO setup, since the two things are logically related and the MCHBAR setup code doesn't depend on any other device specific resource. We'll also need MCHBAR to be ready earlier in an upcoming patch, so this is also a preparation for that. Factor out the init/clean-up code to separate functions to make things clearer in the i915_driver_load()/unload() functions. Suggested-by: Chris Wilson Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/i915_dma.c | 71 ++--- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7934611..a054169 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -904,6 +904,46 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) destroy_workqueue(dev_priv->wq); } +static int i915_mmio_setup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + int mmio_bar; + int mmio_size; + + mmio_bar = IS_GEN2(dev) ? 1 : 0; + /* +* Before gen4, the registers and the GTT are behind different BARs. +* However, from gen4 onwards, the registers and the GTT are shared +* in the same BAR, so we want to restrict this ioremap from +* clobbering the GTT which we want ioremap_wc instead. Fortunately, +* the register BAR remains the same size for all the earlier +* generations up to Ironlake. +*/ + if (INTEL_INFO(dev)->gen < 5) + mmio_size = 512 * 1024; + else + mmio_size = 2 * 1024 * 1024; + dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); + if (dev_priv->regs == NULL) { + DRM_ERROR("failed to map registers\n"); + + return -EIO; + } + + /* Try to make sure MCHBAR is enabled before poking at it */ + intel_setup_mchbar(dev); + + return 0; +} + +static void i915_mmio_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + intel_teardown_mchbar(dev); + pci_iounmap(dev->pdev, dev_priv->regs); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -919,7 +959,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; struct intel_device_info *info, *device_info; - int ret = 0, mmio_bar, mmio_size; + int ret = 0; uint32_t aperture_size; info = (struct intel_device_info *) flags; @@ -972,25 +1012,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_runtime_pm_put; } - mmio_bar = IS_GEN2(dev) ? 1 : 0; - /* Before gen4, the registers and the GTT are behind different BARs. -* However, from gen4 onwards, the registers and the GTT are shared -* in the same BAR, so we want to restrict this ioremap from -* clobbering the GTT which we want ioremap_wc instead. Fortunately, -* the register BAR remains the same size for all the earlier -* generations up to Ironlake. -*/ - if (info->gen < 5) - mmio_size = 512*1024; - else - mmio_size = 2*1024*1024; - - dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); - if (!dev_priv->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -EIO; + ret = i915_mmio_setup(dev); + if (ret < 0) goto put_bridge; - } /* This must be called before any calls to HAS_PCH_* */ intel_detect_pch(dev); @@ -1048,8 +1072,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_irq_init(dev_priv); intel_uncore_sanitize(dev); - /* Try to make sure MCHBAR is enabled before poking at it */ - intel_setup_mchbar(dev); intel_opregion_setup(dev); i915_gem_load_init(dev); @@ -1130,7 +1152,7 @@ out_gtt: i915_global_gtt_cleanup(dev); out_uncore_fini: intel_uncore_fini(dev); - pci_iounmap(dev->pdev, dev_priv->regs); + i915_mmio_cleanup(dev); put_bridge: pci_dev_put(dev_priv->bridge_dev); i915_gem_load_cleanup(dev); @@ -1214,15 +1236,12 @@ int i915_driver_unload(struct drm_device *dev) intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); - intel_teardown_mchbar(dev); - pm_qos_remove_request(&dev_priv->pm_qos); i915_global_gtt_cleanup(dev); intel_uncore_fini(dev); - if (dev_priv->regs != NULL) - pci_iounmap(dev->pdev, dev_priv->regs); + i915_mmio_cleanup(dev); i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); -- 2.5.0 ___ Intel-gfx mailing list Intel-gfx@lists.free
[Intel-gfx] [PATCH 00/25] FBC crtc/fb locking + smaller fixes
Hi Here's yet another patch series randomly modifying the FBC code. We start by refactoring things in order to fix the locking problems, then fix a few other smaller problems and apply some polishing. Just to keep the tradition of the past 10 cover letters, I guess I should say that this series is the last one and that we may consider enabling FBC on HSW/BDW/SKL after it is merged :) For SKL specifically, I tested this series on a two-weeks old version of drm-intel-nightly since today's version is giving me a BUG() even without my patches applied. Thanks, Paulo Paulo Zanoni (25): drm/i915/fbc: wait for a vblank instead of 50ms when enabling drm/i915/fbc: extract intel_fbc_can_activate() drm/i915/fbc: extract intel_fbc_can_enable() drm/i915/fbc: introduce struct intel_fbc_reg_params drm/i915/fbc: replace frequent dev_priv->fbc.x with fbc->x drm/i915/fbc: don't use the frontbuffer tracking subsystem for flips drm/i915/fbc: don't flush for operations on the wrong frontbuffer drm/i915/fbc: unconditionally update FBC during atomic commits drm/i915/fbc: introduce struct intel_fbc_state_cache drm/i915/fbc: split intel_fbc_update into pre and post update drm/i915/fbc: fix the FBC state checking code drm/i915/fbc: unexport intel_fbc_deactivate drm/i915/fbc: rename the FBC disable functions drm/i915/fbc: make sure we cancel the work function at fbc_disable drm/i915/fbc: rewrite the multiple_pipes_ok() code for locking drm/i915: simplify struct drm_device access at intel_atomic_check() drm/i915/fbc: choose the new FBC CRTC during atomic check drm/i915/fbc: move intel_fbc_{enable,disable} call one level up drm/i915/fbc: make FBC work with fastboot drm/i915/fbc: don't try to deactivate FBC if it's not enabled drm/i915/fbc: don't print no_fbc_reason to dmesg drm/i915/fbc: don't store the fb_id on reg_params drm/i915/fbc: call intel_fbc_pre_update earlier during page flips drm/i915/fbc: don't store/check a pointer to the FB drm/i915/fbc: refactor some small functions called only once drivers/gpu/drm/i915/i915_drv.h | 51 +- drivers/gpu/drm/i915/i915_suspend.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 59 +-- drivers/gpu/drm/i915/intel_drv.h | 18 +- drivers/gpu/drm/i915/intel_fbc.c | 901 --- 5 files changed, 589 insertions(+), 442 deletions(-) -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/25] drm/i915/fbc: introduce struct intel_fbc_reg_params
The early return inside __intel_fbc_update does not completely check all the parameters that affect the FBC register values. For example, we currently lack looking at crtc->adjusted_y (for the fence Y offset) and all the parameters that affect the CFB size (for i8xx). Instead of just adding the missing parameters to the check and hoping that any changes to the fbc_activate functions also come with a matching change to the __intel_fbc_update check, introduce a new structure where we store these parameters and use the structure at the fbc_activate function. Of course, it's still possible to access everything from dev_priv in those functions, but IMHO the new code will be harder to break. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 22 ++- drivers/gpu/drm/i915/intel_fbc.c | 131 ++- 2 files changed, 93 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 33217a4..aa9c35e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -909,11 +909,9 @@ struct i915_fbc { * it's the outer lock when overlapping with stolen_lock. */ struct mutex lock; unsigned threshold; - unsigned int fb_id; unsigned int possible_framebuffer_bits; unsigned int busy_bits; struct intel_crtc *crtc; - int y; struct drm_mm_node compressed_fb; struct drm_mm_node *compressed_llb; @@ -923,6 +921,24 @@ struct i915_fbc { bool enabled; bool active; + struct intel_fbc_reg_params { + struct { + enum pipe pipe; + enum plane plane; + unsigned int fence_y_offset; + } crtc; + + struct { + u64 ggtt_offset; + uint32_t id; + uint32_t pixel_format; + unsigned int stride; + int fence_reg; + } fb; + + int cfb_size; + } params; + struct intel_fbc_work { bool scheduled; u32 scheduled_vblank; @@ -933,7 +949,7 @@ struct i915_fbc { const char *no_fbc_reason; bool (*is_active)(struct drm_i915_private *dev_priv); - void (*activate)(struct intel_crtc *crtc); + void (*activate)(struct drm_i915_private *dev_priv); void (*deactivate)(struct drm_i915_private *dev_priv); }; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index f3cc6a3..f4ed2b3 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -130,11 +130,9 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) } } -static void i8xx_fbc_activate(struct intel_crtc *crtc) +static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; int cfb_pitch; int i; u32 fbc_ctl; @@ -142,9 +140,9 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) dev_priv->fbc.active = true; /* Note: fbc.threshold == 1 for i8xx */ - cfb_pitch = intel_fbc_calculate_cfb_size(crtc, fb) / FBC_LL_SIZE; - if (fb->pitches[0] < cfb_pitch) - cfb_pitch = fb->pitches[0]; + cfb_pitch = params->cfb_size / FBC_LL_SIZE; + if (params->fb.stride < cfb_pitch) + cfb_pitch = params->fb.stride; /* FBC_CTL wants 32B or 64B units */ if (IS_GEN2(dev_priv)) @@ -161,9 +159,9 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) /* Set it up... */ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; - fbc_ctl2 |= FBC_CTL_PLANE(crtc->plane); + fbc_ctl2 |= FBC_CTL_PLANE(params->crtc.plane); I915_WRITE(FBC_CONTROL2, fbc_ctl2); - I915_WRITE(FBC_FENCE_OFF, get_crtc_fence_y_offset(crtc)); + I915_WRITE(FBC_FENCE_OFF, params->crtc.fence_y_offset); } /* enable it... */ @@ -173,7 +171,7 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) if (IS_I945GM(dev_priv)) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; - fbc_ctl |= obj->fence_reg; + fbc_ctl |= params->fb.fence_reg; I915_WRITE(FBC_CONTROL, fbc_ctl); } @@ -182,23 +180,21 @@ static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv) return I915_READ(FBC_CONTROL) & FBC_CTL_EN; } -static void g4x_fbc_activate(struct intel_crtc *crtc) +static void g4x_fbc_activate(struct drm_i915_priva
[Intel-gfx] [PATCH 05/25] drm/i915/fbc: replace frequent dev_priv->fbc.x with fbc->x
We say "dev_priv->fbc.something" way too many times in our code while we could be saying just "fbc->something" with a previous declaration of fbc. This has been bothering me for a while but I didn't want to patch it since I wanted to fix the real problems first. But as I add more code I keep thinking about it, especially since it makes the code easier to read and it can make us fit 80 columns easier, so let's just do the change now. While at it, also rename from i915_fbc to intel_fbc because the whole FBC code uses intel_fbc. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/intel_fbc.c | 237 +-- 2 files changed, 132 insertions(+), 109 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aa9c35e..6d11575 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -904,7 +904,7 @@ enum fb_op_origin { ORIGIN_DIRTYFB, }; -struct i915_fbc { +struct intel_fbc { /* This is always the inner lock when overlapping with struct_mutex and * it's the outer lock when overlapping with stolen_lock. */ struct mutex lock; @@ -1778,7 +1778,7 @@ struct drm_i915_private { u32 pipestat_irq_mask[I915_MAX_PIPES]; struct i915_hotplug hotplug; - struct i915_fbc fbc; + struct intel_fbc fbc; struct i915_drrs drrs; struct intel_opregion opregion; struct intel_vbt_data vbt; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index f4ed2b3..b4a4191 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -358,17 +358,18 @@ static void intel_fbc_work_fn(struct work_struct *__work) { struct drm_i915_private *dev_priv = container_of(__work, struct drm_i915_private, fbc.work.work); - struct intel_fbc_work *work = &dev_priv->fbc.work; - struct intel_crtc *crtc = dev_priv->fbc.crtc; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_work *work = &fbc->work; + struct intel_crtc *crtc = fbc->crtc; struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); if (drm_crtc_vblank_get(&crtc->base)) { DRM_ERROR("vblank not available for FBC on pipe %c\n", pipe_name(crtc->pipe)); goto out; } - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); retry: /* Delay the actual enabling to let pageflipping cease and the @@ -388,7 +389,7 @@ retry: drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank, msecs_to_jiffies(50)); - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); /* Were we cancelled? */ if (!work->scheduled) @@ -396,32 +397,35 @@ retry: /* Were we delayed again while this function was sleeping? */ if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) { - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); goto retry; } if (crtc->base.primary->fb == work->fb) - dev_priv->fbc.activate(dev_priv); + fbc->activate(dev_priv); out_put: drm_crtc_vblank_put(&crtc->base); out: work->scheduled = false; - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - dev_priv->fbc.work.scheduled = false; + struct intel_fbc *fbc = &dev_priv->fbc; + + WARN_ON(!mutex_is_locked(&fbc->lock)); + fbc->work.scheduled = false; } static void intel_fbc_schedule_activation(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_fbc_work *work = &dev_priv->fbc.work; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_work *work = &fbc->work; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + WARN_ON(!mutex_is_locked(&fbc->lock)); if (drm_crtc_vblank_get(&crtc->base)) { DRM_ERROR("vblank not available for FBC on pipe %c\n", @@ -443,12 +447,14 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + struct intel_fbc *fbc = &dev_priv->fbc; + + WARN_ON(!mutex_is_locked(&fbc->lock)); intel_fbc_cancel_work(dev_priv); - if (dev_priv->fbc.active) - dev_priv->fbc.deactivate(dev_priv); + if (fbc->active) + fbc->deactivate(dev_priv); } /* @@ -460,23 +466,26 @@ static void __intel_fb
[Intel-gfx] [PATCH 02/25] drm/i915/fbc: extract intel_fbc_can_activate()
Extract all the code that checks if the FBC configuration is valid to its own function, making __intel_fbc_update() much simpler. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 92 ++-- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 6b43ec3..dff30e1 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -514,17 +514,6 @@ static bool crtc_can_fbc(struct intel_crtc *crtc) return true; } -static bool crtc_is_valid(struct intel_crtc *crtc) -{ - if (!intel_crtc_active(&crtc->base)) - return false; - - if (!to_intel_plane_state(crtc->base.primary->state)->visible) - return false; - - return true; -} - static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -750,48 +739,40 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) return effective_w <= max_w && effective_h <= max_h; } -/** - * __intel_fbc_update - activate/deactivate FBC as needed, unlocked - * @crtc: the CRTC that triggered the update - * - * This function completely reevaluates the status of FBC, then activates, - * deactivates or maintains it on the same state. - */ -static void __intel_fbc_update(struct intel_crtc *crtc) +static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_plane *primary; struct drm_framebuffer *fb; + struct intel_plane_state *plane_state; struct drm_i915_gem_object *obj; const struct drm_display_mode *adjusted_mode; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - - if (!multiple_pipes_ok(dev_priv)) { - set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; - } - - if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) - return; - - if (!crtc_is_valid(crtc)) { - set_no_fbc_reason(dev_priv, "no output"); - goto out_disable; + if (!intel_crtc_active(&crtc->base)) { + set_no_fbc_reason(dev_priv, "CRTC not active"); + return false; } - fb = crtc->base.primary->fb; + primary = crtc->base.primary; + fb = primary->fb; obj = intel_fb_obj(fb); adjusted_mode = &crtc->config->base.adjusted_mode; + plane_state = to_intel_plane_state(primary->state); + + if (!plane_state->visible) { + set_no_fbc_reason(dev_priv, "primary plane not visible"); + return false; + } if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { set_no_fbc_reason(dev_priv, "incompatible mode"); - goto out_disable; + return false; } if (!intel_fbc_hw_tracking_covers_screen(crtc)) { set_no_fbc_reason(dev_priv, "mode too large for compression"); - goto out_disable; + return false; } /* The use of a CPU fence is mandatory in order to detect writes @@ -800,22 +781,22 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (obj->tiling_mode != I915_TILING_X || obj->fence_reg == I915_FENCE_REG_NONE) { set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); - goto out_disable; + return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && - crtc->base.primary->state->rotation != BIT(DRM_ROTATE_0)) { + plane_state->base.rotation != BIT(DRM_ROTATE_0)) { set_no_fbc_reason(dev_priv, "rotation unsupported"); - goto out_disable; + return false; } if (!stride_is_valid(dev_priv, fb->pitches[0])) { set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); - goto out_disable; + return false; } if (!pixel_format_is_valid(fb)) { set_no_fbc_reason(dev_priv, "pixel format is invalid"); - goto out_disable; + return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ @@ -823,7 +804,7 @@ static void __intel_fbc_update(struct intel_crtc *crtc) ilk_pipe_pixel_rate(crtc->config) >= dev_priv->cdclk_freq * 95 / 100) { set_no_fbc_reason(dev_priv, "pixel rate is too big"); - goto out_disable; + return false; } /* It is possible for the required CFB size change without a @@ -839,16 +820,43 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (intel_fbc_calculate_cfb_size(crtc, fb) > dev_priv->fbc.
[Intel-gfx] [PATCH 01/25] drm/i915/fbc: wait for a vblank instead of 50ms when enabling
Instead of waiting for 50ms, just wait until the next vblank, since it's the minimum requirement. The whole infrastructure of FBC is based on vblanks, so waiting for X vblanks instead of X milliseconds sounds like the correct way to go. Besides, 50ms may be less than a vblank on super slow modes that may or may not exist. There are some small improvements in PC state residency (due to the fact that we're now using 16ms for the common modes instead of 50ms), but the biggest advantage is still the correctness of being vblank-based instead of time-based. v2: - Rebase after changing the patch order. - Update the commit message. v3: - Fix bogus vblank_get() instead of vblank_count() (Ville). - Don't forget to call drm_crtc_vblank_{get,put} (Chris, Ville) - Adjust the performance details on the commit message. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_fbc.c | 43 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af30148..33217a4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -925,9 +925,9 @@ struct i915_fbc { struct intel_fbc_work { bool scheduled; + u32 scheduled_vblank; struct work_struct work; struct drm_framebuffer *fb; - unsigned long enable_jiffies; } work; const char *no_fbc_reason; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a1988a4..6b43ec3 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -381,7 +381,15 @@ static void intel_fbc_work_fn(struct work_struct *__work) container_of(__work, struct drm_i915_private, fbc.work.work); struct intel_fbc_work *work = &dev_priv->fbc.work; struct intel_crtc *crtc = dev_priv->fbc.crtc; - int delay_ms = 50; + struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; + + mutex_lock(&dev_priv->fbc.lock); + if (drm_crtc_vblank_get(&crtc->base)) { + DRM_ERROR("vblank not available for FBC on pipe %c\n", + pipe_name(crtc->pipe)); + goto out; + } + mutex_unlock(&dev_priv->fbc.lock); retry: /* Delay the actual enabling to let pageflipping cease and the @@ -390,24 +398,25 @@ retry: * vblank to pass after disabling the FBC before we attempt * to modify the control registers. * -* A more complicated solution would involve tracking vblanks -* following the termination of the page-flipping sequence -* and indeed performing the enable as a co-routine and not -* waiting synchronously upon the vblank. -* * WaFbcWaitForVBlankBeforeEnable:ilk,snb +* +* It is also worth mentioning that since work->scheduled_vblank can be +* updated multiple times by the other threads, hitting the timeout is +* not an error condition. We'll just end up hitting the "goto retry" +* case below. */ - wait_remaining_ms_from_jiffies(work->enable_jiffies, delay_ms); + wait_event_timeout(vblank->queue, + drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank, + msecs_to_jiffies(50)); mutex_lock(&dev_priv->fbc.lock); /* Were we cancelled? */ if (!work->scheduled) - goto out; + goto out_put; /* Were we delayed again while this function was sleeping? */ - if (time_after(work->enable_jiffies + msecs_to_jiffies(delay_ms), - jiffies)) { + if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) { mutex_unlock(&dev_priv->fbc.lock); goto retry; } @@ -415,9 +424,10 @@ retry: if (crtc->base.primary->fb == work->fb) intel_fbc_activate(work->fb); - work->scheduled = false; - +out_put: + drm_crtc_vblank_put(&crtc->base); out: + work->scheduled = false; mutex_unlock(&dev_priv->fbc.lock); } @@ -434,13 +444,20 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + if (drm_crtc_vblank_get(&crtc->base)) { + DRM_ERROR("vblank not available for FBC on pipe %c\n", + pipe_name(crtc->pipe)); + return; + } + /* It is useless to call intel_fbc_cancel_work() in this function since * we're not releasing fbc.lock, so it won't have an opportunity to grab * it to discover that it was cancelled. So we just update the expected * jiffy count. */ work->fb = crtc->base.primary->fb; work->scheduled = true; - work->enable_jiffies
[Intel-gfx] [PATCH 07/25] drm/i915/fbc: don't flush for operations on the wrong frontbuffer
If frontbuffer_bits doesn't match the current frontbuffer, there's no reason to recompress or update FBC. There was a plan to make the FBC test suite catch this type of problem, but it never got implemented due to being low priority. While at it, also implement Ville's suggestion and use plane->frontbuffer_bit instead of INTEL_FRONTBUFFER_PRIMARY. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index dad4c6e..2f25a45 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -977,12 +977,19 @@ void intel_fbc_update(struct intel_crtc *crtc) mutex_unlock(&fbc->lock); } +static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc) +{ + if (fbc->enabled) + return to_intel_plane(fbc->crtc->base.primary)->frontbuffer_bit; + else + return fbc->possible_framebuffer_bits; +} + void intel_fbc_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin) { struct intel_fbc *fbc = &dev_priv->fbc; - unsigned int fbc_bits; if (!fbc_supported(dev_priv)) return; @@ -992,12 +999,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, mutex_lock(&fbc->lock); - if (fbc->enabled) - fbc_bits = INTEL_FRONTBUFFER_PRIMARY(fbc->crtc->pipe); - else - fbc_bits = fbc->possible_framebuffer_bits; - - fbc->busy_bits |= (fbc_bits & frontbuffer_bits); + fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; if (fbc->busy_bits) __intel_fbc_deactivate(dev_priv); @@ -1020,7 +1022,8 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, fbc->busy_bits &= ~frontbuffer_bits; - if (!fbc->busy_bits && fbc->enabled) { + if (!fbc->busy_bits && fbc->enabled && + (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { if (fbc->active) intel_fbc_recompress(dev_priv); else -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/25] drm/i915/fbc: unconditionally update FBC during atomic commits
We unconditionally disable/update FBC even during the page flip IOCTLs, and an unconditional disable/update at every atomic commit touching the primary plane shouldn't impact PC state residency noticeably. Besides, the code that checks for rotation is a good hint that we may be forgetting something else, so let's leave all the decisions to intel_fbc.c, making the code much safer. Once we have the code to properly make FBC enable/update decisions based on atomic states, with proper locking, then we'll be able to evaluate whether it will be worth trying to optimize the cases where a disable isn't needed. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 22 ++ 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f026ade..baab41046 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11928,6 +11928,8 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, case DRM_PLANE_TYPE_PRIMARY: intel_crtc->atomic.pre_disable_primary = turn_off; intel_crtc->atomic.post_enable_primary = turn_on; + intel_crtc->atomic.disable_fbc = true; + intel_crtc->atomic.update_fbc = true; if (turn_off) { /* @@ -11939,28 +11941,9 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, * disable. */ intel_crtc->atomic.disable_ips = true; - - intel_crtc->atomic.disable_fbc = true; } /* -* FBC does not work on some platforms for rotated -* planes, so disable it when rotation is not 0 and -* update it when rotation is set back to 0. -* -* FIXME: This is redundant with the fbc update done in -* the primary plane enable function except that that -* one is done too late. We eventually need to unify -* this. -*/ - - if (visible && - INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && - dev_priv->fbc.crtc == intel_crtc && - plane_state->rotation != BIT(DRM_ROTATE_0)) - intel_crtc->atomic.disable_fbc = true; - - /* * BDW signals flip done immediately if the plane * is disabled, even if the plane enable is already * armed to occur at the next vblank :( @@ -11968,7 +11951,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, if (turn_on && IS_BROADWELL(dev)) intel_crtc->atomic.wait_vblank = true; - intel_crtc->atomic.update_fbc |= visible || mode_changed; break; case DRM_PLANE_TYPE_CURSOR: break; -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/25] drm/i915/fbc: unexport intel_fbc_deactivate
With the addition and usage of intel_fbc_pre_update, intel_fbc_deactivate is not used anymore outside intel_fbc.c, so kill the exported function and rename __intel_fbc_deactivate. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_fbc.c | 28 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 986644d..a53784e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1353,7 +1353,6 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) /* intel_fbc.c */ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); -void intel_fbc_deactivate(struct intel_crtc *crtc); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 4f2133e..3b002d2 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -442,7 +442,7 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) schedule_work(&work->work); } -static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) +static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; @@ -454,26 +454,6 @@ static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) fbc->deactivate(dev_priv); } -/* - * intel_fbc_deactivate - deactivate FBC if it's associated with crtc - * @crtc: the CRTC - * - * This function deactivates FBC if it's associated with the provided CRTC. - */ -void intel_fbc_deactivate(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_fbc *fbc = &dev_priv->fbc; - - if (!fbc_supported(dev_priv)) - return; - - mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) - __intel_fbc_deactivate(dev_priv); - mutex_unlock(&fbc->lock); -} - static void set_no_fbc_reason(struct drm_i915_private *dev_priv, const char *reason) { @@ -920,7 +900,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) intel_fbc_update_state_cache(crtc); deactivate: - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); unlock: mutex_unlock(&fbc->lock); } @@ -953,7 +933,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc) intel_fbc_reg_params_equal(&old_params, &fbc->params)) return; - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); intel_fbc_schedule_activation(crtc); fbc->no_fbc_reason = "FBC enabled (active or scheduled)"; } @@ -996,7 +976,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; if (fbc->busy_bits) - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); mutex_unlock(&fbc->lock); } -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/25] drm/i915/fbc: fix the FBC state checking code
We'll now call intel_fbc_pre_update instead of intel_fbc_deactivate during atomic commits. This will continue to guarantee that we deactivate FBC and it will also update the state checking structures at the correct time. Then, later, at the point where we were calling intel_fbc_update, we'll only need to call intel_fbc_post_update. Also add the proper warnings in case we don't have the appropriate locks. Daniel mentioned the warnings will have to be removed for async commits, but let's keep them here while we can. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 11 +-- drivers/gpu/drm/i915/intel_drv.h | 8 +--- drivers/gpu/drm/i915/intel_fbc.c | 33 ++--- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index baab41046..baa4cc9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4803,7 +4803,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) intel_update_watermarks(&crtc->base); if (atomic->update_fbc) - intel_fbc_update(crtc); + intel_fbc_post_update(crtc); if (atomic->post_enable_primary) intel_post_enable_primary(&crtc->base); @@ -4819,8 +4819,8 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); - if (atomic->disable_fbc) - intel_fbc_deactivate(crtc); + if (atomic->update_fbc) + intel_fbc_pre_update(crtc); if (crtc->atomic.disable_ips) hsw_disable_ips(crtc); @@ -10935,7 +10935,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) mutex_unlock(&dev->struct_mutex); intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit); - intel_fbc_update(crtc); + intel_fbc_post_update(crtc); drm_framebuffer_unreference(work->old_fb); BUG_ON(atomic_read(&crtc->unpin_work_count) == 0); @@ -11733,7 +11733,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, to_intel_plane(primary)->frontbuffer_bit); mutex_unlock(&dev->struct_mutex); - intel_fbc_deactivate(intel_crtc); + intel_fbc_pre_update(intel_crtc); intel_frontbuffer_flip_prepare(dev, to_intel_plane(primary)->frontbuffer_bit); @@ -11928,7 +11928,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, case DRM_PLANE_TYPE_PRIMARY: intel_crtc->atomic.pre_disable_primary = turn_off; intel_crtc->atomic.post_enable_primary = turn_on; - intel_crtc->atomic.disable_fbc = true; intel_crtc->atomic.update_fbc = true; if (turn_off) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 059b46e..986644d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -564,16 +564,17 @@ struct intel_mmio_flip { */ struct intel_crtc_atomic_commit { /* Sleepable operations to perform before commit */ - bool disable_fbc; bool disable_ips; bool pre_disable_primary; /* Sleepable operations to perform after commit */ unsigned fb_bits; bool wait_vblank; - bool update_fbc; bool post_enable_primary; unsigned update_sprite_watermarks; + + /* Sleepable operations to perform before and after commit */ + bool update_fbc; }; struct intel_crtc { @@ -1353,7 +1354,8 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) /* intel_fbc.c */ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_deactivate(struct intel_crtc *crtc); -void intel_fbc_update(struct intel_crtc *crtc); +void intel_fbc_pre_update(struct intel_crtc *crtc); +void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); void intel_fbc_disable(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 2983bcd..4f2133e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -508,6 +508,7 @@ static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) if (INTEL_INFO(dev_priv)->gen > 4) return true; + /* FIXME: we don't have the appropriate state locks to do this here. */ for_each_pipe(dev_priv, pipe) { crtc = dev_priv->pipe_to_crtc_mapping[pipe]; @@ -730,12 +731,16 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; s
[Intel-gfx] [PATCH 16/25] drm/i915: simplify struct drm_device access at intel_atomic_check()
We already have a dev variable, there's no need to access state->dev. Also, I plan to add another dev_priv user here, so declare one for the current user. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bfd5336..c7b0580 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13375,6 +13375,7 @@ static void calc_watermark_data(struct drm_atomic_state *state) static int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; @@ -13417,7 +13418,7 @@ static int intel_atomic_check(struct drm_device *dev, return ret; if (i915.fastboot && - intel_pipe_config_compare(state->dev, + intel_pipe_config_compare(dev, to_intel_crtc_state(crtc->state), pipe_config, true)) { crtc_state->mode_changed = false; @@ -13443,9 +13444,9 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; } else - intel_state->cdclk = to_i915(state->dev)->cdclk_freq; + intel_state->cdclk = dev_priv->cdclk_freq; - ret = drm_atomic_helper_check_planes(state->dev, state); + ret = drm_atomic_helper_check_planes(dev, state); if (ret) return ret; -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/25] drm/i915/fbc: make sure we cancel the work function at fbc_disable
Just to be sure nothing will survive a module unload. We need to do this after the unlock in order to make sure the function won't get stuck trying to grab the lock we already own while we wait for it to finish. Reported-by: Reported-by: Daniel Vetter Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 9995cfc..1977176 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1096,6 +1096,8 @@ void intel_fbc_disable(struct intel_crtc *crtc) __intel_fbc_disable(dev_priv); } mutex_unlock(&fbc->lock); + + cancel_work_sync(&fbc->work.work); } /** @@ -1115,6 +1117,8 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv) if (fbc->enabled) __intel_fbc_disable(dev_priv); mutex_unlock(&fbc->lock); + + cancel_work_sync(&fbc->work.work); } /** -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/25] drm/i915/fbc: rename the FBC disable functions
Instead of: - intel_fbc_disable_crtc(crtc) - intel_fbc_disable(dev_priv) we now have: - intel_fbc_disable(crtc) - intel_fbc_global_disable(dev_priv) This is because all the other functions that take a CRTC are called - intel_fbc_something(crtc) Instead of: - intel_fbc_something_crtc(crtc) And I also hope that the word "global" is going to help make it more explicit that "global" is the unusual case, not the opposite. Reported-by: Daniel Vetter Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_suspend.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 8 drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_fbc.c | 8 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a2aa09c..6c6bedf 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -92,7 +92,7 @@ static void i915_restore_display(struct drm_device *dev) } /* only restore FBC info on the platform that supports FBC*/ - intel_fbc_disable(dev_priv); + intel_fbc_global_disable(dev_priv); /* restore FBC interval */ if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index baa4cc9..b7c0707 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5163,7 +5163,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void haswell_crtc_disable(struct drm_crtc *crtc) @@ -5215,7 +5215,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) true); } - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void i9xx_pfit_enable(struct intel_crtc *crtc) @@ -6391,7 +6391,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (!IS_GEN2(dev)) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) @@ -16110,7 +16110,7 @@ void intel_modeset_cleanup(struct drm_device *dev) intel_unregister_dsm_handler(); - intel_fbc_disable(dev_priv); + intel_fbc_global_disable(dev_priv); /* flush any delayed tasks or pending work */ flush_scheduled_work(); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a53784e..f227bf1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1357,8 +1357,8 @@ void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); -void intel_fbc_disable(struct drm_i915_private *dev_priv); -void intel_fbc_disable_crtc(struct intel_crtc *crtc); +void intel_fbc_disable(struct intel_crtc *crtc); +void intel_fbc_global_disable(struct drm_i915_private *dev_priv); void intel_fbc_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 3b002d2..9995cfc 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1076,12 +1076,12 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) } /** - * intel_fbc_disable_crtc - disable FBC if it's associated with crtc + * intel_fbc_disable - disable FBC if it's associated with crtc * @crtc: the CRTC * * This function disables FBC if it's associated with the provided CRTC. */ -void intel_fbc_disable_crtc(struct intel_crtc *crtc) +void intel_fbc_disable(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; @@ -1099,12 +1099,12 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc) } /** - * intel_fbc_disable - globally disable FBC + * intel_fbc_global_disable - globally disable FBC * @dev_priv: i915 device instance * * This function disables FBC regardless of which CRTC is associated with it. */ -void intel_fbc_disable(struct drm_i915_private *dev_priv) +void intel_fbc_global_disable(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 20/25] drm/i915/fbc: don't try to deactivate FBC if it's not enabled
During FBC invalidation, don't call intel_fbc_deactivate if it's not enabled. This doesn't fix any bug, but helps making the interface saner. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a1c1dd5..7564f1e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -980,7 +980,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; - if (fbc->busy_bits) + if (fbc->enabled && fbc->busy_bits) intel_fbc_deactivate(dev_priv); mutex_unlock(&fbc->lock); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 25/25] drm/i915/fbc: refactor some small functions called only once
The FBC fixes we've been doing in the last months required a lot of refactor, so functions that were once big and called from different spots are now small and called only once. IMHO now it's better to just move the contents of these functions to their only callers since this reduces the number of indirections while reading the code. While at it, also improve the related comments a little bit. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 41 ++-- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 6a4fe0e..3abbeec 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -412,14 +412,6 @@ out: mutex_unlock(&fbc->lock); } -static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv) -{ - struct intel_fbc *fbc = &dev_priv->fbc; - - WARN_ON(!mutex_is_locked(&fbc->lock)); - fbc->work.scheduled = false; -} - static void intel_fbc_schedule_activation(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -434,10 +426,10 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) return; } - /* It is useless to call intel_fbc_cancel_work() in this function since -* we're not releasing fbc.lock, so it won't have an opportunity to grab -* it to discover that it was cancelled. So we just update the expected -* jiffy count. */ + /* It is useless to call intel_fbc_cancel_work() or cancel_work() in +* this function since we're not releasing fbc.lock, so it won't have an +* opportunity to grab it to discover that it was cancelled. So we just +* update the expected jiffy count. */ work->scheduled = true; work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); drm_crtc_vblank_put(&crtc->base); @@ -451,25 +443,15 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) WARN_ON(!mutex_is_locked(&fbc->lock)); - intel_fbc_cancel_work(dev_priv); + /* Calling cancel_work() here won't help due to the fact that the work +* function grabs fbc->lock. Just set scheduled to false so the work +* function can know it was cancelled. */ + fbc->work.scheduled = false; if (fbc->active) fbc->deactivate(dev_priv); } -static bool crtc_can_fbc(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - - if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) - return false; - - if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) - return false; - - return true; -} - static bool multiple_pipes_ok(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -829,11 +811,16 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) return false; } - if (!crtc_can_fbc(crtc)) { + if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) { fbc->no_fbc_reason = "no enabled pipes can have FBC"; return false; } + if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) { + fbc->no_fbc_reason = "no enabled planes can have FBC"; + return false; + } + return true; } -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 23/25] drm/i915/fbc: call intel_fbc_pre_update earlier during page flips
Make sure we do the pre_update - which also deactivates FBC - before we actually schedule the page flip, just to make sure we don't flip to the new FB with FBC still activated for the previous FB. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5263233..37f43aa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11640,6 +11640,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; update_state_fb(crtc->primary); + intel_fbc_pre_update(intel_crtc); work->pending_flip_obj = obj; @@ -11722,7 +11723,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, to_intel_plane(primary)->frontbuffer_bit); mutex_unlock(&dev->struct_mutex); - intel_fbc_pre_update(intel_crtc); intel_frontbuffer_flip_prepare(dev, to_intel_plane(primary)->frontbuffer_bit); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 17/25] drm/i915/fbc: choose the new FBC CRTC during atomic check
This opens the possibility of implementing nicer schemes to choose the CRTC, such as checking the amount of stolen memory available, or choosing the best pipe on platforms that don't die FBC to pipe or plane A. This code was written for another refactor that I ended up discarding, so I don't actually need it, but I figured this patch would be an improvement on its own so I kept it on the series. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_fbc.c | 77 +--- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c7b0580..3ee3f98 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13450,6 +13450,7 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; + intel_fbc_choose_crtc(dev_priv, state); calc_watermark_data(state); return 0; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 62a25c3..89be9d0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -498,6 +498,8 @@ struct intel_crtc_state { bool ips_enabled; + bool enable_fbc; + bool double_wide; bool dp_encoder_is_mst; @@ -1352,6 +1354,8 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) #endif /* intel_fbc.c */ +void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, + struct drm_atomic_state *state); bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index fe0754c..e3d8ace 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -824,7 +824,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return true; } -static bool intel_fbc_can_enable(struct intel_crtc *crtc) +static bool intel_fbc_can_choose(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -1013,11 +1013,76 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, } /** + * intel_fbc_choose_crtc - select a CRTC to enable FBC on + * @dev_priv: i915 device instance + * @state: the atomic state structure + * + * This function looks at the proposed state for CRTCs and planes, then chooses + * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to + * true. + * + * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe + * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc. + */ +void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, + struct drm_atomic_state *state) +{ + struct intel_fbc *fbc = &dev_priv->fbc; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_plane *plane; + struct drm_plane_state *plane_state; + bool fbc_crtc_present = false; + int i, j; + + mutex_lock(&fbc->lock); + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (fbc->crtc == to_intel_crtc(crtc)) { + fbc_crtc_present = true; + break; + } + } + /* This atomic commit doesn't involve the CRTC currently tied to FBC. */ + if (!fbc_crtc_present && fbc->crtc != NULL) + goto out; + + /* Simply choose the first CRTC that is compatible and has a visible +* plane. We could go for fancier schemes such as checking the plane +* size, but this would just affect the few platforms that don't tie FBC +* to pipe or plane A. */ + for_each_plane_in_state(state, plane, plane_state, i) { + struct intel_plane_state *intel_plane_state = + to_intel_plane_state(plane_state); + + if (!intel_plane_state->visible) + continue; + + for_each_crtc_in_state(state, crtc, crtc_state, j) { + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc_state); + + if (plane_state->crtc != crtc) + continue; + + if (!intel_fbc_can_choose(to_intel_crtc(crtc))) + break; + + intel_crtc_state->enable_fbc = true; + goto out; + } + } + +out: + mutex_unlock(&fbc->lock); +} + +/** * intel_fbc_enable: tries to enable FBC on the CRTC * @crtc: the CRTC * - * This function checks if it's possible to enable FBC on the follo
[Intel-gfx] [PATCH 09/25] drm/i915/fbc: introduce struct intel_fbc_state_cache
Per the new atomic locking rules, we need to cache the CRTC, plane and FB state structures we use so we can access them later without needing more locks. So do this. Notice that there are some pieces of the FBC code that look at things that are only computed during the modeset, so we can't just can't precompute whether FBC can be activated during the update_state_cache stage. We may be able to do this later. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 23 +++ drivers/gpu/drm/i915/intel_fbc.c | 133 ++- 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6d11575..02e6869 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -921,6 +921,29 @@ struct intel_fbc { bool enabled; bool active; + struct intel_fbc_state_cache { + struct { + unsigned int mode_flags; + uint32_t hsw_bdw_pixel_rate; + } crtc; + + struct { + unsigned int rotation; + int src_w; + int src_h; + bool visible; + } plane; + + struct { + u64 ilk_ggtt_offset; + uint32_t id; + uint32_t pixel_format; + unsigned int stride; + int fence_reg; + unsigned int tiling_mode; + } fb; + } state_cache; + struct intel_fbc_reg_params { struct { enum pipe pipe; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 2f25a45..7396287 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -74,19 +74,17 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc) * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value * we wrote to PIPESRC. */ -static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc, +static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache, int *width, int *height) { - struct intel_plane_state *plane_state = - to_intel_plane_state(crtc->base.primary->state); int w, h; - if (intel_rotation_90_or_270(plane_state->base.rotation)) { - w = drm_rect_height(&plane_state->src) >> 16; - h = drm_rect_width(&plane_state->src) >> 16; + if (intel_rotation_90_or_270(cache->plane.rotation)) { + w = cache->plane.src_h; + h = cache->plane.src_w; } else { - w = drm_rect_width(&plane_state->src) >> 16; - h = drm_rect_height(&plane_state->src) >> 16; + w = cache->plane.src_w; + h = cache->plane.src_h; } if (width) @@ -95,18 +93,17 @@ static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc, *height = h; } -static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc, - struct drm_framebuffer *fb) +static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv, + struct intel_fbc_state_cache *cache) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; int lines; - intel_fbc_get_plane_source_size(crtc, NULL, &lines); + intel_fbc_get_plane_source_size(cache, NULL, &lines); if (INTEL_INFO(dev_priv)->gen >= 7) lines = min(lines, 2048); /* Hardware needs the full buffer stride, not just the active area. */ - return lines * fb->pitches[0]; + return lines * cache->fb.stride; } static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) @@ -576,14 +573,13 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - struct drm_framebuffer *fb = crtc->base.primary->state->fb; struct drm_mm_node *uninitialized_var(compressed_llb); int size, fb_cpp, ret; WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb)); - size = intel_fbc_calculate_cfb_size(crtc, fb); - fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0); + size = intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache); + fb_cpp = drm_format_plane_cpp(fbc->state_cache.fb.pixel_format, 0); ret = find_compression_threshold(dev_priv, &fbc->compressed_fb, size, fb_cpp); @@ -677,19 +673,17 @@ static bool stride_is_valid(struct drm_i915_private *dev_priv, return true; } -static bool pixel_format_is_valid(st
[Intel-gfx] [PATCH 18/25] drm/i915/fbc: move intel_fbc_{enable, disable} call one level up
Instead of duplicating the calls for every platform, let's just put them in the correct places inside intel_atomic_commit. This will also make it easier for us to move the enable call in order to support fasbtoot. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 15 +++ drivers/gpu/drm/i915/intel_fbc.c | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3ee3f98..c74dfd3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4966,8 +4966,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->has_pch_encoder) intel_wait_for_vblank(dev, pipe); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - - intel_fbc_enable(intel_crtc); } /* IPS only exists on ULT machines and is tied to pipe A. */ @@ -5080,8 +5078,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_wait_for_vblank(dev, hsw_workaround_pipe); intel_wait_for_vblank(dev, hsw_workaround_pipe); } - - intel_fbc_enable(intel_crtc); } static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force) @@ -5162,8 +5158,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) } intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - - intel_fbc_disable(intel_crtc); } static void haswell_crtc_disable(struct drm_crtc *crtc) @@ -5214,8 +5208,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, true); } - - intel_fbc_disable(intel_crtc); } static void i9xx_pfit_enable(struct intel_crtc *crtc) @@ -6326,8 +6318,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); - - intel_fbc_enable(intel_crtc); } static void i9xx_pfit_disable(struct intel_crtc *crtc) @@ -6390,8 +6380,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (!IS_GEN2(dev)) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - - intel_fbc_disable(intel_crtc); } static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) @@ -6415,6 +6403,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) dev_priv->display.crtc_disable(crtc); intel_crtc->active = false; + intel_fbc_disable(intel_crtc); intel_update_watermarks(crtc); intel_disable_shared_dpll(intel_crtc); @@ -13578,6 +13567,7 @@ static int intel_atomic_commit(struct drm_device *dev, intel_crtc_disable_planes(crtc, crtc_state->plane_mask); dev_priv->display.crtc_disable(crtc); intel_crtc->active = false; + intel_fbc_disable(intel_crtc); intel_disable_shared_dpll(intel_crtc); /* @@ -13617,6 +13607,7 @@ static int intel_atomic_commit(struct drm_device *dev, if (modeset && crtc->state->active) { update_scanline_offset(to_intel_crtc(crtc)); dev_priv->display.crtc_enable(crtc); + intel_fbc_enable(intel_crtc); } if (update_pipe) { diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index e3d8ace..22195cb 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1135,7 +1135,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) WARN_ON(!mutex_is_locked(&fbc->lock)); WARN_ON(!fbc->enabled); WARN_ON(fbc->active); - assert_pipe_disabled(dev_priv, crtc->pipe); + WARN_ON(crtc->active); DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe)); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 24/25] drm/i915/fbc: don't store/check a pointer to the FB
We already make sure we run intel_fbc_update_update during modesets and page flips, and this function takes care of deactivating FBC, so it shouldn't be possible for us to reach the condition we check at intel_fbc_work_fn. So instead of grabbing framebuffer references and adding a lot of code to track when we need to free them, just don't track anything at all since we shouldn't need to. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_fbc.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4763627..624faeb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -965,7 +965,6 @@ struct intel_fbc { bool scheduled; u32 scheduled_vblank; struct work_struct work; - struct drm_framebuffer *fb; } work; const char *no_fbc_reason; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 1485356..6a4fe0e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -403,8 +403,7 @@ retry: goto retry; } - if (crtc->base.primary->fb == work->fb) - fbc->activate(dev_priv); + fbc->activate(dev_priv); out_put: drm_crtc_vblank_put(&crtc->base); @@ -439,7 +438,6 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) * we're not releasing fbc.lock, so it won't have an opportunity to grab * it to discover that it was cancelled. So we just update the expected * jiffy count. */ - work->fb = crtc->base.primary->fb; work->scheduled = true; work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); drm_crtc_vblank_put(&crtc->base); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 22/25] drm/i915/fbc: don't store the fb_id on reg_params
We don't actually use fb_id anywhere. We already compare all parameters that matter to the hardware: pixel format, stride, fence_reg and ggtt_offset. The ID shouldn't make a difference. Besides, we already update the FBC data at every modeset/flip, so this can't change behind our backs. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_fbc.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65e5771..4763627 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -937,7 +937,6 @@ struct intel_fbc { struct { u64 ilk_ggtt_offset; - uint32_t id; uint32_t pixel_format; unsigned int stride; int fence_reg; @@ -954,7 +953,6 @@ struct intel_fbc { struct { u64 ggtt_offset; - uint32_t id; uint32_t pixel_format; unsigned int stride; int fence_reg; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 67dfffc..1485356 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -733,7 +733,6 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc) * platforms that need. */ if (dev_priv->fbc.activate == ilk_fbc_activate) cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); - cache->fb.id = fb->base.id; cache->fb.pixel_format = fb->pixel_format; cache->fb.stride = fb->pitches[0]; cache->fb.fence_reg = obj->fence_reg; @@ -856,7 +855,6 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->crtc.plane = crtc->plane; params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); - params->fb.id = cache->fb.id; params->fb.pixel_format = cache->fb.pixel_format; params->fb.stride = cache->fb.stride; params->fb.fence_reg = cache->fb.fence_reg; -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/25] drm/i915/fbc: split intel_fbc_update into pre and post update
So now pre_update will be responsible for unconditionally deactivating FBC and updating the state cache, while post_update will be responsible for checking if it can be enabled, then enabling it. This is one more step into proper locking. Notice that intel_fbc_flush now calls post_update directly. The FBC flush can only happen for drawing operations - since we explicitly ignore the flips -, so the FBC state is not expected to have changed at this point. With this we can just run post_update, which will make sure we won't deactivate+reactivate FBC as would be the case now if we called pre_update + post_update. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 77 ++-- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 7396287..2983bcd 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -894,24 +894,16 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, return memcmp(params1, params2, sizeof(*params1)) == 0; } -/** - * __intel_fbc_update - activate/deactivate FBC as needed, unlocked - * @crtc: the CRTC that triggered the update - * - * This function completely reevaluates the status of FBC, then activates, - * deactivates or maintains it on the same state. - */ -static void __intel_fbc_update(struct intel_crtc *crtc) +static void intel_fbc_pre_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - struct intel_fbc_reg_params old_params; WARN_ON(!mutex_is_locked(&fbc->lock)); if (!multiple_pipes_ok(dev_priv)) { set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; + goto deactivate; } if (!fbc->enabled || fbc->crtc != crtc) @@ -919,8 +911,25 @@ static void __intel_fbc_update(struct intel_crtc *crtc) intel_fbc_update_state_cache(crtc); - if (!intel_fbc_can_activate(crtc)) - goto out_disable; +deactivate: + __intel_fbc_deactivate(dev_priv); +} + +static void intel_fbc_post_update(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_reg_params old_params; + + WARN_ON(!mutex_is_locked(&fbc->lock)); + + if (!fbc->enabled || fbc->crtc != crtc) + return; + + if (!intel_fbc_can_activate(crtc)) { + WARN_ON(fbc->active); + return; + } old_params = fbc->params; intel_fbc_get_reg_params(crtc, &fbc->params); @@ -934,44 +943,9 @@ static void __intel_fbc_update(struct intel_crtc *crtc) intel_fbc_reg_params_equal(&old_params, &fbc->params)) return; - if (intel_fbc_is_active(dev_priv)) { - /* We update FBC along two paths, after changing fb/crtc -* configuration (modeswitching) and after page-flipping -* finishes. For the latter, we know that not only did -* we disable the FBC at the start of the page-flip -* sequence, but also more than one vblank has passed. -* -* For the former case of modeswitching, it is possible -* to switch between two FBC valid configurations -* instantaneously so we do need to disable the FBC -* before we can modify its control registers. We also -* have to wait for the next vblank for that to take -* effect. However, since we delay enabling FBC we can -* assume that a vblank has passed since disabling and -* that we can safely alter the registers in the deferred -* callback. -* -* In the scenario that we go from a valid to invalid -* and then back to valid FBC configuration we have -* no strict enforcement that a vblank occurred since -* disabling the FBC. However, along all current pipe -* disabling paths we do need to wait for a vblank at -* some point. And we wait before enabling FBC anyway. -*/ - DRM_DEBUG_KMS("deactivating FBC for update\n"); - __intel_fbc_deactivate(dev_priv); - } - + __intel_fbc_deactivate(dev_priv); intel_fbc_schedule_activation(crtc); - fbc->no_fbc_reason = "FBC enabled (not necessarily active)"; - return; - -out_disable: - /* Multiple disables should be harmless */ - if (intel_fbc_is_active(dev_priv)) { - DRM_DEBUG_KMS("unsupported config, deactivating FBC\n"); - __intel_fbc_deactivate(dev_priv); - } +
[Intel-gfx] [PATCH 21/25] drm/i915/fbc: don't print no_fbc_reason to dmesg
Our dmesg messages started being misleading after we converted to the enable+activate model: we always print "Disabling FBC", even when we're just deactivating it. So, for example, when I boot my machine and do "dmesg | grep -i fbc", I see: [drm:intel_fbc_enable] Enabling FBC on pipe A [drm:set_no_fbc_reason] Disabling FBC: framebuffer not tiled or fenced but then, if I read the debugfs file, I will see: $ sudo cat i915_fbc_status FBC enabled Compressing: yes so we can conclude that dmesg is misleading, since FBC is actually enabled. What happened is that we deactivated FBC due to fbcon not being tiled, but when we silently reactivated it when the display manager started. We don't print activation messages since there may be way too many of these operations per second during normal desktop usage. One possible solution would be to change set_no_fbc_reason to correctly differentiate between disable and deactivation, but we removed support from printing activation/deactivation messages in the past because they were too frequent. So instead of doing this, let's just not print anything on dmesg, and leave the debugfs file if the user needs to investigate something. We already print when we enable and disable FBC anyway on a given pipe, so this should already help triaging bugs. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 43 +++- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 7564f1e..67dfffc 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -459,18 +459,6 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) fbc->deactivate(dev_priv); } -static void set_no_fbc_reason(struct drm_i915_private *dev_priv, - const char *reason) -{ - struct intel_fbc *fbc = &dev_priv->fbc; - - if (fbc->no_fbc_reason == reason) - return; - - fbc->no_fbc_reason = reason; - DRM_DEBUG_KMS("Disabling FBC: %s\n", reason); -} - static bool crtc_can_fbc(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -759,18 +747,18 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) struct intel_fbc_state_cache *cache = &fbc->state_cache; if (!cache->plane.visible) { - set_no_fbc_reason(dev_priv, "primary plane not visible"); + fbc->no_fbc_reason = "primary plane not visible"; return false; } if ((cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) || (cache->crtc.mode_flags & DRM_MODE_FLAG_DBLSCAN)) { - set_no_fbc_reason(dev_priv, "incompatible mode"); + fbc->no_fbc_reason = "incompatible mode"; return false; } if (!intel_fbc_hw_tracking_covers_screen(crtc)) { - set_no_fbc_reason(dev_priv, "mode too large for compression"); + fbc->no_fbc_reason = "mode too large for compression"; return false; } @@ -779,29 +767,29 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) */ if (cache->fb.tiling_mode != I915_TILING_X || cache->fb.fence_reg == I915_FENCE_REG_NONE) { - set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); + fbc->no_fbc_reason = "framebuffer not tiled or fenced"; return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && cache->plane.rotation != BIT(DRM_ROTATE_0)) { - set_no_fbc_reason(dev_priv, "rotation unsupported"); + fbc->no_fbc_reason = "rotation unsupported"; return false; } if (!stride_is_valid(dev_priv, cache->fb.stride)) { - set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); + fbc->no_fbc_reason = "framebuffer stride not supported"; return false; } if (!pixel_format_is_valid(dev_priv, cache->fb.pixel_format)) { - set_no_fbc_reason(dev_priv, "pixel format is invalid"); + fbc->no_fbc_reason = "pixel format is invalid"; return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) && cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) { - set_no_fbc_reason(dev_priv, "pixel rate is too big"); + fbc->no_fbc_reason = "pixel rate is too big"; return false; } @@ -817,7 +805,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) * important case, we can implement it later. */ if (intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) > fbc->compressed_fb.size * fbc->thr
[Intel-gfx] [PATCH 15/25] drm/i915/fbc: rewrite the multiple_pipes_ok() code for locking
Older FBC platforms have this restriction where FBC can't be enabled if multiple pipes are enabled. In the current code, we disable FBC before the second pipe becomes visible. One of the problems with this code is that the current multiple_pipes_ok() implementation just iterates through all CRTCs looking at their states, but it doesn't make sure that the state locks are grabbed. It also can't just grab the locks for every CRTC since this would kill one of the biggest advantages of atomic modesetting. After the recent FBC changes, we now have the appropriate locks for the given CRTC, so we can just try to maintain the state of each CRTC and update it once intel_fbc_pre_update is called. As a last note, I don't have gen 2/3 machines to test this code. My current plan is to enable FBC on just the newer platforms, so this patch is just an attempt to get the gen 2/3 code at least looking sane, so if one day someone decide to fix FBC on these platforms, they may have less work to do. Not-tested-by: Paulo Zanoni (only on HSW+) Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 2 ++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_fbc.c | 55 +++- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 02e6869..65e5771 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -911,6 +911,7 @@ struct intel_fbc { unsigned threshold; unsigned int possible_framebuffer_bits; unsigned int busy_bits; + unsigned int visible_pipes_mask; struct intel_crtc *crtc; struct drm_mm_node compressed_fb; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b7c0707..bfd5336 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15981,6 +15981,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev) modeset_put_power_domains(dev_priv, put_domains); } intel_display_set_init_power(dev_priv, false); + + intel_fbc_init_pipe_state(dev_priv); } void intel_display_resume(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f227bf1..62a25c3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1356,6 +1356,7 @@ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); +void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc); void intel_fbc_global_disable(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 1977176..fe0754c 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -56,6 +56,11 @@ static inline bool fbc_on_plane_a_only(struct drm_i915_private *dev_priv) return INTEL_INFO(dev_priv)->gen < 4; } +static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen <= 3; +} + /* * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's @@ -479,25 +484,25 @@ static bool crtc_can_fbc(struct intel_crtc *crtc) return true; } -static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) +static bool multiple_pipes_ok(struct intel_crtc *crtc) { - enum pipe pipe; - int n_pipes = 0; - struct drm_crtc *crtc; + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_plane *primary = crtc->base.primary; + struct intel_fbc *fbc = &dev_priv->fbc; + enum pipe pipe = crtc->pipe; - if (INTEL_INFO(dev_priv)->gen > 4) + /* Don't even bother tracking anything we don't need. */ + if (!no_fbc_on_multiple_pipes(dev_priv)) return true; - /* FIXME: we don't have the appropriate state locks to do this here. */ - for_each_pipe(dev_priv, pipe) { - crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + WARN_ON(!drm_modeset_is_locked(&primary->mutex)); - if (intel_crtc_active(crtc) && - to_intel_plane_state(crtc->primary->state)->visible) - n_pipes++; - } + if (to_intel_plane_state(primary->state)->visible) + fbc->visible_pipes_mask |= (1 << pipe); + else + fbc->visible_pipes_mask &= ~(1 << pipe); - return (n_pipes < 2); + return (fbc->visible_pipes_mask & ~(1 << pi
[Intel-gfx] [PATCH 06/25] drm/i915/fbc: don't use the frontbuffer tracking subsystem for flips
Before this patch, page flips would call intel_frontbuffer_flip() and intel_frontbuffer_flip_complete(), which would call intel_fbc_flush(), which would call intel_fbc_update(). The problem is that drawing operations also trigger intel_fbc_flush() calls, so it's not guaranteed that we have the CRTC and FB locks grabbed when intel_fbc_flush() happens, since the call trace may come from the rendering path. We're trying to make the FBC code grab the appropriate CRTC/FB locks, so split the drawing and the flipping logic in order to achieve that in later patches. So now the frontbuffer tracking code is just going to be used for frontbuffer drawing, and intel_fbc_update() is going to be used directly for actual page flips. As a note, we don't need to call intel_fbc_flip() during the two places where we call intel_frontbuffer_flip() since in one of them we already have an intel_fbc_update() call, and in the other we have the planes disabled. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_fbc.c | 10 -- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a851cb7..f026ade 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10935,6 +10935,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) mutex_unlock(&dev->struct_mutex); intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit); + intel_fbc_update(crtc); drm_framebuffer_unreference(work->old_fb); BUG_ON(atomic_read(&crtc->unpin_work_count) == 0); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index b4a4191..dad4c6e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -987,7 +987,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, if (!fbc_supported(dev_priv)) return; - if (origin == ORIGIN_GTT) + if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) return; mutex_lock(&fbc->lock); @@ -1013,7 +1013,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (!fbc_supported(dev_priv)) return; - if (origin == ORIGIN_GTT) + if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) return; mutex_lock(&fbc->lock); @@ -1021,12 +1021,10 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, fbc->busy_bits &= ~frontbuffer_bits; if (!fbc->busy_bits && fbc->enabled) { - if (origin != ORIGIN_FLIP && fbc->active) { + if (fbc->active) intel_fbc_recompress(dev_priv); - } else { - __intel_fbc_deactivate(dev_priv); + else __intel_fbc_update(fbc->crtc); - } } mutex_unlock(&fbc->lock); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 19/25] drm/i915/fbc: make FBC work with fastboot
Move intel_fbc_enable to a place where it is called regardless of the "modeset" variable, and make sure intel_fbc_enable can be called multiple times without intel_fbc_disable being called. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 4 +++- drivers/gpu/drm/i915/intel_fbc.c | 10 -- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c74dfd3..5263233 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13607,7 +13607,6 @@ static int intel_atomic_commit(struct drm_device *dev, if (modeset && crtc->state->active) { update_scanline_offset(to_intel_crtc(crtc)); dev_priv->display.crtc_enable(crtc); - intel_fbc_enable(intel_crtc); } if (update_pipe) { @@ -13620,6 +13619,9 @@ static int intel_atomic_commit(struct drm_device *dev, if (!modeset) intel_pre_plane_update(intel_crtc); + if (crtc->state->active && intel_crtc->atomic.update_fbc) + intel_fbc_enable(intel_crtc); + if (crtc->state->active && (crtc->state->planes_changed || update_pipe)) drm_atomic_helper_commit_planes_on_crtc(crtc_state); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 22195cb..a1c1dd5 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1082,7 +1082,9 @@ out: * @crtc: the CRTC * * This function checks if the given CRTC was chosen for FBC, then enables it if - * possible. Notice that it doesn't activate FBC. + * possible. Notice that it doesn't activate FBC. It is valid to call + * intel_fbc_enable multiple times for the same pipe without an + * intel_fbc_disable in the middle, as long as it is deactivated. */ void intel_fbc_enable(struct intel_crtc *crtc) { @@ -1095,7 +1097,11 @@ void intel_fbc_enable(struct intel_crtc *crtc) mutex_lock(&fbc->lock); if (fbc->enabled) { - WARN_ON(fbc->crtc == crtc); + WARN_ON(fbc->crtc == NULL); + if (fbc->crtc == crtc) { + WARN_ON(!crtc->config->enable_fbc); + WARN_ON(fbc->active); + } goto out; } -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/25] drm/i915/fbc: extract intel_fbc_can_enable()
Make our enable/activate checking model more explicit, especially since we now have intel_fbc_can_activate(). Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_fbc.c | 46 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index dff30e1..f3cc6a3 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -826,6 +826,33 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return true; } +static bool intel_fbc_can_enable(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + + if (intel_vgpu_active(dev_priv->dev)) { + set_no_fbc_reason(dev_priv, "VGPU is active"); + return false; + } + + if (i915.enable_fbc < 0) { + set_no_fbc_reason(dev_priv, "disabled per chip default"); + return false; + } + + if (!i915.enable_fbc) { + set_no_fbc_reason(dev_priv, "disabled per module param"); + return false; + } + + if (!crtc_can_fbc(crtc)) { + set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC"); + return false; + } + + return true; +} + /** * __intel_fbc_update - activate/deactivate FBC as needed, unlocked * @crtc: the CRTC that triggered the update @@ -995,25 +1022,8 @@ void intel_fbc_enable(struct intel_crtc *crtc) WARN_ON(dev_priv->fbc.active); WARN_ON(dev_priv->fbc.crtc != NULL); - if (intel_vgpu_active(dev_priv->dev)) { - set_no_fbc_reason(dev_priv, "VGPU is active"); - goto out; - } - - if (i915.enable_fbc < 0) { - set_no_fbc_reason(dev_priv, "disabled per chip default"); - goto out; - } - - if (!i915.enable_fbc) { - set_no_fbc_reason(dev_priv, "disabled per module param"); + if (!intel_fbc_can_enable(crtc)) goto out; - } - - if (!crtc_can_fbc(crtc)) { - set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC"); - goto out; - } if (intel_fbc_alloc_cfb(crtc)) { set_no_fbc_reason(dev_priv, "not enough stolen memory"); -- 2.6.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [IGT PATCH] kms_force_connector_basic: add a test to test the i915 load detection path.
This will force test the load_detect_test parameter in i915, to make sure load detection works as intended. Signed-off-by: Maarten Lankhorst Acked-by: Daniel Vetter --- diff --git a/tests/kms_force_connector_basic.c b/tests/kms_force_connector_basic.c index bd80caeffd82..f827d0008f7b 100644 --- a/tests/kms_force_connector_basic.c +++ b/tests/kms_force_connector_basic.c @@ -52,6 +52,8 @@ static void reset_connectors(void) drmModeFreeConnector(connector); } + + igt_set_module_param_int("load_detect_test", 0); } static int opt_handler(int opt, int opt_index, void *data) @@ -108,6 +110,17 @@ int main(int argc, char **argv) igt_skip_on(vga_connector->connection == DRM_MODE_CONNECTED); } + igt_subtest("force-load-detect") { + igt_set_module_param_int("load_detect_test", 1); + + temp = drmModeGetConnectorCurrent(drm_fd, + vga_connector->connector_id); + + igt_assert(temp->connection != DRM_MODE_UNKNOWNCONNECTION); + + drmModeFreeConnector(temp); + } + igt_subtest("force-connector-state") { igt_display_t display; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear pending reset requests during suspend
On Tue, Jan 19, 2016 at 01:09:28PM +0100, Daniel Vetter wrote: > On Thu, Jan 14, 2016 at 10:49:45AM +, Arun Siluvery wrote: > > Pending reset requests are cleared before suspending, they should be picked > > up > > after resume when new work is submitted. > > > > This is originally added as part of TDR patches for Gen8 from Tomas Elf > > which > > are under review, as suggested by Chris this is extracted as a separate > > patch > > as it can be useful now. > > > > Cc: Mika Kuoppala > > Cc: Chris Wilson > > Signed-off-by: Arun Siluvery > > Pulling in the discussion we had from irc: Imo the right approach is to > simply wait for gpu reset to finish it's job. Since that could in turn > lead to a dead gpu (if we're unlucky and init_hw failed) we'd need to do > that in a loop around gem_idle. And drop dev->struct_mutex in-between. > E.g. > > while (busy) { > mutex_lock(); > gpu_idle(); > mutex_unlock(); > > flush_work(reset_work); > } Where does the requirement for gpu_idle come from? If there is a global reset in progress, it cannot queue a request to flush the work and waiting on the old results will be skipped. So just wait for the global reset to complete, i.e. flush_work(). -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
[Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: Move load time stolen memory init earlier
== Summary == Built on 00a0c7d1ae09b1259c7af8e5a088b0b225d805df drm-intel-nightly: 2016y-01m-18d-16h-50m-37s UTC integration manifest Test gem_ctx_basic: pass -> FAIL (bdw-ultra) Test kms_flip: Subgroup basic-flip-vs-dpms: dmesg-warn -> PASS (skl-i5k-2) Test pm_rpm: Subgroup basic-rte: dmesg-warn -> PASS (byt-nuc) UNSTABLE bdw-nuci7total:140 pass:131 dwarn:0 dfail:0 fail:0 skip:9 bdw-ultratotal:140 pass:132 dwarn:0 dfail:1 fail:1 skip:6 byt-nuc total:143 pass:126 dwarn:2 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:102 dwarn:3 dfail:0 fail:0 skip:38 ivb-t430stotal:137 pass:124 dwarn:3 dfail:4 fail:0 skip:6 skl-i5k-2total:143 pass:134 dwarn:1 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1220/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✗ failure: Fi.CI.BAT
On Thu, Jan 14, 2016 at 04:29:14PM +0200, Ville Syrjälä wrote: > On Thu, Jan 14, 2016 at 02:20:40PM -, Patchwork wrote: > > == Summary == > > > > Built on 8fb2feecca499d11e104264071ac55e273e23af5 drm-intel-nightly: > > 2016y-01m-14d-13h-06m-44s UTC integration manifest > > > > Test gem_basic: > > Subgroup create-close: > > pass -> DMESG-WARN (skl-i7k-2) > > Test gem_cpu_reloc: > > Subgroup basic: > > pass -> DMESG-FAIL (skl-i7k-2) > > Test gem_ctx_param_basic: > > Subgroup basic: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup invalid-param-set: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup non-root-set-no-zeromap: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup root-set-no-zeromap-disabled: > > pass -> DMESG-WARN (skl-i7k-2) > > Test gem_mmap: > > Subgroup basic: > > pass -> DMESG-WARN (skl-i7k-2) > > Test gem_mmap_gtt: > > Subgroup basic-read: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup basic-write: > > pass -> DMESG-WARN (skl-i7k-2) > > Test gem_storedw_loop: > > Subgroup basic-render: > > dmesg-warn -> PASS (skl-i5k-2) UNSTABLE > > dmesg-warn -> PASS (bdw-nuci7) > > dmesg-warn -> PASS (skl-i7k-2) UNSTABLE > > Test kms_addfb_basic: > > Subgroup addfb25-modifier-no-flag: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup addfb25-x-tiled-mismatch: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup addfb25-yf-tiled: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup bad-pitch-1024: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup bad-pitch-63: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup bad-pitch-999: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup clobberred-modifier: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup too-high: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup too-wide: > > pass -> DMESG-WARN (skl-i7k-2) > > Subgroup unused-offsets: > > pass -> DMESG-WARN (skl-i7k-2) > > Test kms_flip: > > Subgroup basic-plain-flip: > > pass -> DMESG-FAIL (skl-i7k-2) > > Test kms_pipe_crc_basic: > > Subgroup nonblocking-crc-pipe-a-frame-sequence: > > pass -> DMESG-FAIL (skl-i7k-2) > > Subgroup read-crc-pipe-b-frame-sequence: > > pass -> DMESG-FAIL (skl-i7k-2) > > Test prime_self_import: > > Subgroup basic-with_two_bos: > > pass -> DMESG-WARN (skl-i7k-2) > > Looks like the GPU died or something on that skl. Can't imagine it being > related > to watermark patches. Mika created a bugzilla for this since this isn't the first time this happened. We have 2 instances of a failure with matching syptoms in normal -nightly CI runs already: https://bugs.freedesktop.org/show_bug.cgi?id=93768 In the future if you have a case where an entire machine dies it's useful to look at the machine history. That shows you the results for the last 50 runs on only that machine for any testcase where results changed. That helps in figuring out whether there's something wrong with that machine, or whether there might indeed be trouble with your patch set. Thanks, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: skl_update_scaler() wants a rotation bitmask instead of bit number
On Tue, Jan 19, 2016 at 03:18:25PM +0200, Ville Syrjälä wrote: > On Tue, Jan 19, 2016 at 09:03:13AM +0100, Daniel Vetter wrote: > > On Mon, Jan 18, 2016 at 04:21:40PM +0200, Ville Syrjälä wrote: > > > On Fri, Jan 15, 2016 at 03:15:00PM -0800, Matt Roper wrote: > > > > On Fri, Jan 15, 2016 at 08:48:26PM +0200, Ville Syrjälä wrote: > > > > > On Thu, Oct 15, 2015 at 05:01:58PM +0300, > > > > > ville.syrj...@linux.intel.com wrote: > > > > > > From: Ville Syrjälä > > > > > > > > > > > > Pass BIT(DRM_ROTATE_0) instead of DRM_ROTATE_0 to > > > > > > skl_update_scaler(). > > > > > > The former is a mask, the latter just the bit number. > > > > > > > > > > > > Fortunately the only thing skl_update_scaler() does with the > > > > > > rotation > > > > > > is check if it's 90/270 degrees or not, and so in this case it would > > > > > > still do the right thing. > > > > > > > > > > > > Cc: Chandra Konduru > > > > > > Signed-off-by: Ville Syrjälä > > > > > > > > > > Ping, anyone care to r-b this one? > > > > > > > > Reviewed-by: Matt Roper > > > > > > > > Looks like this bug has been present since scalers were first added in > > > > 6156a45602f9 ("drm/i915: skylake primary plane scaling using shared > > > > scalers") > > > > > > Pushed to dinq an appropriate Fixes: comment added. Thanks for the review. > > > > Do we have an igt for this? If not need to capture it and make it > > something we must fixe before more scaler stuff lands. > > There's no change in behavior from this fix, so there's nothing to test. Ah, should have read things more carefully, I thought this was the fix for the other recent rotation fail you've patched. _That_ on definitely should come with an igt. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear pending reset requests during suspend
On Tue, Jan 19, 2016 at 01:48:05PM +, Chris Wilson wrote: > On Tue, Jan 19, 2016 at 01:09:28PM +0100, Daniel Vetter wrote: > > On Thu, Jan 14, 2016 at 10:49:45AM +, Arun Siluvery wrote: > > > Pending reset requests are cleared before suspending, they should be > > > picked up > > > after resume when new work is submitted. > > > > > > This is originally added as part of TDR patches for Gen8 from Tomas Elf > > > which > > > are under review, as suggested by Chris this is extracted as a separate > > > patch > > > as it can be useful now. > > > > > > Cc: Mika Kuoppala > > > Cc: Chris Wilson > > > Signed-off-by: Arun Siluvery > > > > Pulling in the discussion we had from irc: Imo the right approach is to > > simply wait for gpu reset to finish it's job. Since that could in turn > > lead to a dead gpu (if we're unlucky and init_hw failed) we'd need to do > > that in a loop around gem_idle. And drop dev->struct_mutex in-between. > > E.g. > > > > while (busy) { > > mutex_lock(); > > gpu_idle(); > > mutex_unlock(); > > > > flush_work(reset_work); > > } > > Where does the requirement for gpu_idle come from? If there is a global > reset in progress, it cannot queue a request to flush the work and > waiting on the old results will be skipped. So just wait for the global > reset to complete, i.e. flush_work(). Yes, but the global reset might in turn leave a wrecked gpu behind, or at least a non-idle one. Hence another gpu_idle on top, to make sure. If we change init_hw() of engines to be synchronous then we should have at least a WARN_ON(not_idle_but_i_expected_so()); in there ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✗ failure: Fi.CI.BAT
On Tue, Jan 19, 2016 at 02:58:14PM +0100, Daniel Vetter wrote: > On Thu, Jan 14, 2016 at 04:29:14PM +0200, Ville Syrjälä wrote: > > On Thu, Jan 14, 2016 at 02:20:40PM -, Patchwork wrote: > > > == Summary == > > > > > > Built on 8fb2feecca499d11e104264071ac55e273e23af5 drm-intel-nightly: > > > 2016y-01m-14d-13h-06m-44s UTC integration manifest > > > > > > Test gem_basic: > > > Subgroup create-close: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Test gem_cpu_reloc: > > > Subgroup basic: > > > pass -> DMESG-FAIL (skl-i7k-2) > > > Test gem_ctx_param_basic: > > > Subgroup basic: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup invalid-param-set: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup non-root-set-no-zeromap: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup root-set-no-zeromap-disabled: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Test gem_mmap: > > > Subgroup basic: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Test gem_mmap_gtt: > > > Subgroup basic-read: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup basic-write: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Test gem_storedw_loop: > > > Subgroup basic-render: > > > dmesg-warn -> PASS (skl-i5k-2) UNSTABLE > > > dmesg-warn -> PASS (bdw-nuci7) > > > dmesg-warn -> PASS (skl-i7k-2) UNSTABLE > > > Test kms_addfb_basic: > > > Subgroup addfb25-modifier-no-flag: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup addfb25-x-tiled-mismatch: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup addfb25-yf-tiled: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup bad-pitch-1024: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup bad-pitch-63: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup bad-pitch-999: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup clobberred-modifier: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup too-high: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup too-wide: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Subgroup unused-offsets: > > > pass -> DMESG-WARN (skl-i7k-2) > > > Test kms_flip: > > > Subgroup basic-plain-flip: > > > pass -> DMESG-FAIL (skl-i7k-2) > > > Test kms_pipe_crc_basic: > > > Subgroup nonblocking-crc-pipe-a-frame-sequence: > > > pass -> DMESG-FAIL (skl-i7k-2) > > > Subgroup read-crc-pipe-b-frame-sequence: > > > pass -> DMESG-FAIL (skl-i7k-2) > > > Test prime_self_import: > > > Subgroup basic-with_two_bos: > > > pass -> DMESG-WARN (skl-i7k-2) > > > > Looks like the GPU died or something on that skl. Can't imagine it being > > related > > to watermark patches. > > Mika created a bugzilla for this since this isn't the first time this > happened. We have 2 instances of a failure with matching syptoms in normal > -nightly CI runs already: > > https://bugs.freedesktop.org/show_bug.cgi?id=93768 > > In the future if you have a case where an entire machine dies it's useful > to look at the machine history. That shows you the results for the last 50 > runs on only that machine for any testcase where results changed. That > helps in figuring out whether there's something wrong with that machine, > or whether there might indeed be trouble with your patch set. Sadly the link to the machine history is busted for patchwork CI results, so doing that is somewhat more tedious than it should be. Might be a good idea to fix all the links once and for all. Cc:ing Tomi... -- 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 08/25] drm/i915/fbc: unconditionally update FBC during atomic commits
Hi Paulo, [auto build test WARNING on drm-intel/for-linux-next] [also build test WARNING on next-20160119] [cannot apply to v4.4] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Paulo-Zanoni/FBC-crtc-fb-locking-smaller-fixes/20160119-214108 base: git://anongit.freedesktop.org/drm-intel for-linux-next config: x86_64-randconfig-x011-01180513 (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): drivers/gpu/drm/i915/intel_display.c: In function 'intel_plane_atomic_calc_changes': >> drivers/gpu/drm/i915/intel_display.c:11811:27: warning: unused variable >> 'dev_priv' [-Wunused-variable] struct drm_i915_private *dev_priv = dev->dev_private; ^ vim +/dev_priv +11811 drivers/gpu/drm/i915/intel_display.c d21fbe87 Matt Roper2015-09-24 11795int src_w = drm_rect_width(&state->src) >> 16; d21fbe87 Matt Roper2015-09-24 11796int src_h = drm_rect_height(&state->src) >> 16; d21fbe87 Matt Roper2015-09-24 11797int dst_w = drm_rect_width(&state->dst); d21fbe87 Matt Roper2015-09-24 11798int dst_h = drm_rect_height(&state->dst); d21fbe87 Matt Roper2015-09-24 11799 d21fbe87 Matt Roper2015-09-24 11800return (src_w != dst_w || src_h != dst_h); d21fbe87 Matt Roper2015-09-24 11801 } d21fbe87 Matt Roper2015-09-24 11802 da20eabd Maarten Lankhorst 2015-06-15 11803 int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, da20eabd Maarten Lankhorst 2015-06-15 11804 struct drm_plane_state *plane_state) da20eabd Maarten Lankhorst 2015-06-15 11805 { ab1d3a0e Maarten Lankhorst 2015-11-19 11806struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state); da20eabd Maarten Lankhorst 2015-06-15 11807struct drm_crtc *crtc = crtc_state->crtc; da20eabd Maarten Lankhorst 2015-06-15 11808struct intel_crtc *intel_crtc = to_intel_crtc(crtc); da20eabd Maarten Lankhorst 2015-06-15 11809struct drm_plane *plane = plane_state->plane; da20eabd Maarten Lankhorst 2015-06-15 11810struct drm_device *dev = crtc->dev; da20eabd Maarten Lankhorst 2015-06-15 @11811struct drm_i915_private *dev_priv = dev->dev_private; da20eabd Maarten Lankhorst 2015-06-15 11812struct intel_plane_state *old_plane_state = da20eabd Maarten Lankhorst 2015-06-15 11813 to_intel_plane_state(plane->state); da20eabd Maarten Lankhorst 2015-06-15 11814int idx = intel_crtc->base.base.id, ret; da20eabd Maarten Lankhorst 2015-06-15 11815int i = drm_plane_index(plane); da20eabd Maarten Lankhorst 2015-06-15 11816bool mode_changed = needs_modeset(crtc_state); da20eabd Maarten Lankhorst 2015-06-15 11817bool was_crtc_enabled = crtc->state->active; da20eabd Maarten Lankhorst 2015-06-15 11818bool is_crtc_enabled = crtc_state->active; da20eabd Maarten Lankhorst 2015-06-15 11819bool turn_off, turn_on, visible, was_visible; :: The code at line 11811 was first introduced by commit :: da20eabd2c69761f9dfd849985eb299e3335531f drm/i915: Split plane updates of crtc->atomic into a helper, v2. :: TO: Maarten Lankhorst :: CC: Daniel Vetter --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear pending reset requests during suspend
On Tue, Jan 19, 2016 at 03:04:40PM +0100, Daniel Vetter wrote: > On Tue, Jan 19, 2016 at 01:48:05PM +, Chris Wilson wrote: > > On Tue, Jan 19, 2016 at 01:09:28PM +0100, Daniel Vetter wrote: > > > On Thu, Jan 14, 2016 at 10:49:45AM +, Arun Siluvery wrote: > > > > Pending reset requests are cleared before suspending, they should be > > > > picked up > > > > after resume when new work is submitted. > > > > > > > > This is originally added as part of TDR patches for Gen8 from Tomas Elf > > > > which > > > > are under review, as suggested by Chris this is extracted as a separate > > > > patch > > > > as it can be useful now. > > > > > > > > Cc: Mika Kuoppala > > > > Cc: Chris Wilson > > > > Signed-off-by: Arun Siluvery > > > > > > Pulling in the discussion we had from irc: Imo the right approach is to > > > simply wait for gpu reset to finish it's job. Since that could in turn > > > lead to a dead gpu (if we're unlucky and init_hw failed) we'd need to do > > > that in a loop around gem_idle. And drop dev->struct_mutex in-between. > > > E.g. > > > > > > while (busy) { > > > mutex_lock(); > > > gpu_idle(); > > > mutex_unlock(); > > > > > > flush_work(reset_work); > > > } > > > > Where does the requirement for gpu_idle come from? If there is a global > > reset in progress, it cannot queue a request to flush the work and > > waiting on the old results will be skipped. So just wait for the global > > reset to complete, i.e. flush_work(). > > Yes, but the global reset might in turn leave a wrecked gpu behind, or at > least a non-idle one. Hence another gpu_idle on top, to make sure. If we > change init_hw() of engines to be synchronous then we should have at least > a WARN_ON(not_idle_but_i_expected_so()); in there ... Does it matter on suspend? We test on resume if the GPU is usable, but if we wanted to test on suspend then we should do flush_work(); if (i915_terminally_wedged()) /* oh noes */; -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
[Intel-gfx] ✗ Fi.CI.BAT: warning for FBC crtc/fb locking + smaller fixes
== Summary == Built on 20c388faff9d8c41ab27e825c685526561b892a2 drm-intel-nightly: 2016y-01m-19d-13h-31m-46s UTC integration manifest Test kms_flip: Subgroup basic-flip-vs-modeset: pass -> DMESG-WARN (skl-i5k-2) bdw-nuci7total:140 pass:131 dwarn:0 dfail:0 fail:0 skip:9 bsw-nuc-2total:143 pass:117 dwarn:2 dfail:0 fail:0 skip:24 byt-nuc total:143 pass:125 dwarn:3 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:102 dwarn:3 dfail:0 fail:0 skip:38 ivb-t430stotal:137 pass:124 dwarn:3 dfail:4 fail:0 skip:6 skl-i5k-2total:143 pass:132 dwarn:3 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1221/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 2/2] lib/igt_kms: Short description between Intel/DRM terminology.
On Fri, Jan 15, 2016 at 02:46:45PM +0200, Ville Syrjälä wrote: > On Fri, Jan 15, 2016 at 11:06:42AM +0200, Marius Vlad wrote: > > lib/igt_kms: Briefly describe Intel-to-DRM mapping between pipes, encoders > > and > > connectors. > > > > Signed-off-by: Marius Vlad > > --- > > lib/igt_kms.c | 82 > > +++ > > 1 file changed, 82 insertions(+) > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c > > index c7a0b77..caa8837 100644 > > --- a/lib/igt_kms.c > > +++ b/lib/igt_kms.c > > @@ -68,6 +68,88 @@ > > * functions have all igt_ prefixes. This part is still very much work in > > * progress and so also lacks a bit documentation for the individual > > functions. > > * > > + * Intel/DRM terminology and display connections: > > + * > > + * Intel documentation describes the road from memory to an output > > connector as > > + * follows: > > + * > > + * |[!<-- language="C" --> > > + * .. .---. .-. .-. > > + * | Memory |>| Pipes |>| Transcoders |>| DDI | > > + * '' '---' '-' '-' > > + * ]| > > + * > > + * Pipes represent the front-end of the display contain the planes, > > blending, > > + * and color correction, while the transcoders contain timing generators, > > + * encoders, A/V mixers and PSR (Panel-Self Refresh) controllers. Finally > > the > > + * DDI represent the connectors attached to the display. > > + * > > + * > > + * In DRM we have the following: > > + * > > + * |[!<-- language="C" --> > > + * .---. .---. .---. .. > > + * | Framebuff |>| Pipes |>| Encoders |>| Connectors | > > + * '---' '---' '---' '' > > "Framebuff"? > > Also should this say crtc instead of pipe? Right, pipe indeed. > > > + * ]| > > + * > > + * > > + * The frame buffer ties a reference to a memory object and provides a > > pointer > > + * to the actual data. > > + * > > + * The pipe is used to set the display mode, timings and gamma tables. On > > some > > + * hardware models this is tied with the transcoder. In DRM-parlance this > > is > > + * referred as a CRTC. > > + * > > + * Each pipe has multiple planes. On older hardware these planes where > > known as > > + * primary plane, overlay/sprite plane, and cursor plane. From GEN9 > > (SKL/BXT) > > + * each pipe has three planes and a cursor plane. > > Not quite true. > > > Each plane can be used as a > > + * primary, as a sprite or as an overlay plane. The planes are the ones > > that > > + * retrieve the pixels from memory and pushes them to the encoder. > > + * > > + * A pipe prior to GEN9: > > Really more like g4x-bdw. Before g4x it was totally different, and gen4 was > sort of mix of both the old and the new. And vlv/chv have two sprites on > each pipe. > > So given all the variations in the hardware, and the fact that it keeps > changing all the time, I'm not convinced there's any point in > documenting this in igt. It'll get stale real quick, and there are > efforts to decouple igt from i915 as much as possible, so next thing you > know someone else will want to docuemnt their favorite hardware here as > well. > > So if we do want to document this stuff, then I think it should be > somewhere in the kernel modeset code (around crtc/plane init I suppose). Yes, it might make more sense to be in the kernel. What I wanted to achieve with this small intro was to bridge the gap between DRM terminology and the one in Intel 01.org PRM for igt. For a first timer is rather tedious to identify software/hadware abstraction when looking at the PRMs and when looking in igt -- I know for a fact that I'm still having trouble identifying those parts. Daniel has already suggested to add some documention between DRM-to-Intel Mappings in the kernel. Do you suggest that we should document all platforms? > > > + * > > + * |[!<-- language="C" --> > > + * .. > > + * | Memory | .. > > + * ||>| Cursor |-->... > > + * || '' > > + * || > > + * || .. > > + * ||>| Sprite |-->... > > + * || '' > > + * || > > + * || .-. > > + * ||->| Primary |>... > > + * || '-' > > + * '' > > + * ]| > > + * > > + * A pipe with universal planes: > > + * > > + * |[!<-- language="C" --> > > + * .. > > + * | Memory | .. > > + * ||>| Cursor |-->... > > + * || '' > > + * || > > + * || .---. > > + * ||>| Plane |-->... > > + * || '---' > > + * || > > + * || .---. > > + * ||->| Plane |>... > > + * || '---' >
Re: [Intel-gfx] [PATCH] drm/i915: Clear pending reset requests during suspend
On 19/01/2016 14:13, Chris Wilson wrote: On Tue, Jan 19, 2016 at 03:04:40PM +0100, Daniel Vetter wrote: On Tue, Jan 19, 2016 at 01:48:05PM +, Chris Wilson wrote: On Tue, Jan 19, 2016 at 01:09:28PM +0100, Daniel Vetter wrote: On Thu, Jan 14, 2016 at 10:49:45AM +, Arun Siluvery wrote: Pending reset requests are cleared before suspending, they should be picked up after resume when new work is submitted. This is originally added as part of TDR patches for Gen8 from Tomas Elf which are under review, as suggested by Chris this is extracted as a separate patch as it can be useful now. Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Arun Siluvery Pulling in the discussion we had from irc: Imo the right approach is to simply wait for gpu reset to finish it's job. Since that could in turn lead to a dead gpu (if we're unlucky and init_hw failed) we'd need to do that in a loop around gem_idle. And drop dev->struct_mutex in-between. E.g. while (busy) { mutex_lock(); gpu_idle(); mutex_unlock(); flush_work(reset_work); } Where does the requirement for gpu_idle come from? If there is a global reset in progress, it cannot queue a request to flush the work and waiting on the old results will be skipped. So just wait for the global reset to complete, i.e. flush_work(). Yes, but the global reset might in turn leave a wrecked gpu behind, or at least a non-idle one. Hence another gpu_idle on top, to make sure. If we change init_hw() of engines to be synchronous then we should have at least a WARN_ON(not_idle_but_i_expected_so()); in there ... gpu_error.work is removed in b8d24a06568368076ebd5a858a011699a97bfa42, we are doing reset in hangcheck work itself so I think there is no need to flush work. while (i915_reset_in_progress(gpu_error) && !i915_terminally_wedged(gpu_error)) { int ret; mutex_lock(&dev->struct_mutex); ret = i915_gpu_idle(dev); if (ret) DRM_ERROR("GPU is in inconsistent state after reset\n"); mutex_unlock(&dev->struct_mutex); } If the reset is successful we are idle before suspend otherwise in a wedged state. is this ok? regards Arun Does it matter on suspend? We test on resume if the GPU is usable, but if we wanted to test on suspend then we should do flush_work(); if (i915_terminally_wedged()) /* oh noes */; -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Retry few time if gpiod_get fails during intel_dsi_init
INTEL_SOC_PMIC is loading later than I915 failing the gpiod_get and pwm_get calls in i915. Add a retry to give time for the INTEL_SOC_PMIC to load. This was fine till now but broke in latest kernel. Maybe load time for the INTEL_SOC_PMIC has increased. Since the lookup tables for GPIO (panel enable) and PWM both are exported by same intel_soc_pmic driver, just retrying for the driver to load in intel_dsi_init is sufficient. By the time we come to setup_backlight, pwm would have been exported as well. Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 91cef35..e309ef6 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1192,10 +1192,14 @@ void intel_dsi_init(struct drm_device *dev) * Panel control. */ if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { + int retry = 4; + do { intel_dsi->gpio_panel = gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH); + msleep(50); + } while (IS_ERR(intel_dsi->gpio_panel) && --retry); - if (IS_ERR(intel_dsi->gpio_panel)) { + if (!retry) { DRM_ERROR("Failed to own gpio for panel control\n"); intel_dsi->gpio_panel = NULL; } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 2/2] lib/igt_kms: Short description between Intel/DRM terminology.
On Tue, Jan 19, 2016 at 05:04:33PM +0200, Marius Vlad wrote: > On Fri, Jan 15, 2016 at 02:46:45PM +0200, Ville Syrjälä wrote: > > On Fri, Jan 15, 2016 at 11:06:42AM +0200, Marius Vlad wrote: > > > lib/igt_kms: Briefly describe Intel-to-DRM mapping between pipes, > > > encoders and > > > connectors. > > > > > > Signed-off-by: Marius Vlad > > > --- > > > lib/igt_kms.c | 82 > > > +++ > > > 1 file changed, 82 insertions(+) > > > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c > > > index c7a0b77..caa8837 100644 > > > --- a/lib/igt_kms.c > > > +++ b/lib/igt_kms.c > > > @@ -68,6 +68,88 @@ > > > * functions have all igt_ prefixes. This part is still very much work in > > > * progress and so also lacks a bit documentation for the individual > > > functions. > > > * > > > + * Intel/DRM terminology and display connections: > > > + * > > > + * Intel documentation describes the road from memory to an output > > > connector as > > > + * follows: > > > + * > > > + * |[!<-- language="C" --> > > > + * .. .---. .-. .-. > > > + * | Memory |>| Pipes |>| Transcoders |>| DDI | > > > + * '' '---' '-' '-' > > > + * ]| > > > + * > > > + * Pipes represent the front-end of the display contain the planes, > > > blending, > > > + * and color correction, while the transcoders contain timing generators, > > > + * encoders, A/V mixers and PSR (Panel-Self Refresh) controllers. > > > Finally the > > > + * DDI represent the connectors attached to the display. > > > + * > > > + * > > > + * In DRM we have the following: > > > + * > > > + * |[!<-- language="C" --> > > > + * .---. .---. .---. .. > > > + * | Framebuff |>| Pipes |>| Encoders |>| Connectors | > > > + * '---' '---' '---' '' > > > > "Framebuff"? > > > > Also should this say crtc instead of pipe? > Right, pipe indeed. > > > > > + * ]| > > > + * > > > + * > > > + * The frame buffer ties a reference to a memory object and provides a > > > pointer > > > + * to the actual data. > > > + * > > > + * The pipe is used to set the display mode, timings and gamma tables. > > > On some > > > + * hardware models this is tied with the transcoder. In DRM-parlance > > > this is > > > + * referred as a CRTC. > > > + * > > > + * Each pipe has multiple planes. On older hardware these planes where > > > known as > > > + * primary plane, overlay/sprite plane, and cursor plane. From GEN9 > > > (SKL/BXT) > > > + * each pipe has three planes and a cursor plane. > > > > Not quite true. > > > > > Each plane can be used as a > > > + * primary, as a sprite or as an overlay plane. The planes are the ones > > > that > > > + * retrieve the pixels from memory and pushes them to the encoder. > > > + * > > > + * A pipe prior to GEN9: > > > > Really more like g4x-bdw. Before g4x it was totally different, and gen4 was > > sort of mix of both the old and the new. And vlv/chv have two sprites on > > each pipe. > > > > So given all the variations in the hardware, and the fact that it keeps > > changing all the time, I'm not convinced there's any point in > > documenting this in igt. It'll get stale real quick, and there are > > efforts to decouple igt from i915 as much as possible, so next thing you > > know someone else will want to docuemnt their favorite hardware here as > > well. > > > > So if we do want to document this stuff, then I think it should be > > somewhere in the kernel modeset code (around crtc/plane init I suppose). > > Yes, it might make more sense to be in the kernel. What I wanted to achieve > with this small intro was to bridge the gap between DRM terminology and > the one in Intel 01.org PRM for igt. For a first timer is rather tedious to > identify software/hadware abstraction when looking at the PRMs and when > looking in igt -- I know for a fact that I'm still having trouble > identifying those parts. > > Daniel has already suggested to add some documention between > DRM-to-Intel Mappings in the kernel. > > Do you suggest that we should document all platforms? I'd either keep it fairly generic, or document all of them. What you had here seemed like something in between. > > > > > > > + * > > > + * |[!<-- language="C" --> > > > + * .. > > > + * | Memory | .. > > > + * ||>| Cursor |-->... > > > + * || '' > > > + * || > > > + * || .. > > > + * ||>| Sprite |-->... > > > + * || '' > > > + * || > > > + * || .-. > > > + * ||->| Primary |>... > > > + * || '-' > > > + * '' > > > + * ]| > > > + * > > > + * A pipe with universal planes: > > > + * > > > + * |[!<-- language="C" --> > >
[Intel-gfx] [PATCH] drm/i915: Do not put big intel_crtc_state on the stack
From: Tvrtko Ursulin Having this on stack triggers the -Wframe-larger-than=1024 and is not nice to put such big things on the kernel stack anyway. This required a little bit of refactoring to handle the new failure path from vlv_force_pll_on. Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Cc: John Harrison Cc: Ville Syrjälä --- Compile tested only! --- drivers/gpu/drm/i915/intel_display.c | 58 +++- drivers/gpu/drm/i915/intel_dp.c | 8 +++-- drivers/gpu/drm/i915/intel_drv.h | 4 +-- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccb3e3f47450..7bf18658c659 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7635,26 +7635,34 @@ static void chv_prepare_pll(struct intel_crtc *crtc, * in cases where we need the PLL enabled even when @pipe is not going to * be enabled. */ -void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, +int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, const struct dpll *dpll) { struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); - struct intel_crtc_state pipe_config = { - .base.crtc = &crtc->base, - .pixel_multiplier = 1, - .dpll = *dpll, - }; + struct intel_crtc_state *pipe_config; + + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) + return -ENOMEM; + + pipe_config->base.crtc = &crtc->base; + pipe_config->pixel_multiplier = 1; + pipe_config->dpll = *dpll; if (IS_CHERRYVIEW(dev)) { - chv_compute_dpll(crtc, &pipe_config); - chv_prepare_pll(crtc, &pipe_config); - chv_enable_pll(crtc, &pipe_config); + chv_compute_dpll(crtc, pipe_config); + chv_prepare_pll(crtc, pipe_config); + chv_enable_pll(crtc, pipe_config); } else { - vlv_compute_dpll(crtc, &pipe_config); - vlv_prepare_pll(crtc, &pipe_config); - vlv_enable_pll(crtc, &pipe_config); + vlv_compute_dpll(crtc, pipe_config); + vlv_prepare_pll(crtc, pipe_config); + vlv_enable_pll(crtc, pipe_config); } + + kfree(pipe_config); + + return 0; } /** @@ -10828,7 +10836,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; struct drm_display_mode *mode; - struct intel_crtc_state pipe_config; + struct intel_crtc_state *pipe_config; int htot = I915_READ(HTOTAL(cpu_transcoder)); int hsync = I915_READ(HSYNC(cpu_transcoder)); int vtot = I915_READ(VTOTAL(cpu_transcoder)); @@ -10839,6 +10847,12 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, if (!mode) return NULL; + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) { + kfree(mode); + return NULL; + } + /* * Construct a pipe_config sufficient for getting the clock info * back out of crtc_clock_get. @@ -10846,14 +10860,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need * to use a real value here instead. */ - pipe_config.cpu_transcoder = (enum transcoder) pipe; - pipe_config.pixel_multiplier = 1; - pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe)); - pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe)); - pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe)); - i9xx_crtc_clock_get(intel_crtc, &pipe_config); - - mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier; + pipe_config->cpu_transcoder = (enum transcoder) pipe; + pipe_config->pixel_multiplier = 1; + pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe)); + pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe)); + pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); + i9xx_crtc_clock_get(intel_crtc, pipe_config); + + mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; mode->hdisplay = (htot & 0x) + 1; mode->htotal = ((htot & 0x) >> 16) + 1; mode->hsync_start = (hsync & 0x) + 1; @@ -10865,6 +10879,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, drm_mode_set_name(mode); + kfree(pipe_config); + return mode; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 17612548c58d..e2bea710614f 100644 --- a/drivers/gpu/drm/i915
Re: [Intel-gfx] [PATCH] drm/i915: Retry few time if gpiod_get fails during intel_dsi_init
On 01/19/2016 08:45 PM, Shobhit Kumar wrote: INTEL_SOC_PMIC is loading later than I915 failing the gpiod_get and pwm_get calls in i915. Add a retry to give time for the INTEL_SOC_PMIC to load. This was fine till now but broke in latest kernel. Maybe load time for the INTEL_SOC_PMIC has increased. Since the lookup tables for GPIO (panel enable) and PWM both are exported by same intel_soc_pmic driver, just retrying for the driver to load in intel_dsi_init is sufficient. By the time we come to setup_backlight, pwm would have been exported as well. Maybe we should play with initcalls here but I was not sure how it will impact if I change it for PMIC driver. IIRC, this discussion came up from Daniel at the time of original patches also but somehow did not close decidedly and has come back as a regression. Regards Shobhit Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 91cef35..e309ef6 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1192,10 +1192,14 @@ void intel_dsi_init(struct drm_device *dev) * Panel control. */ if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { + int retry = 4; + do { intel_dsi->gpio_panel = gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH); + msleep(50); + } while (IS_ERR(intel_dsi->gpio_panel) && --retry); - if (IS_ERR(intel_dsi->gpio_panel)) { + if (!retry) { DRM_ERROR("Failed to own gpio for panel control\n"); intel_dsi->gpio_panel = NULL; } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Retry few time if gpiod_get fails during intel_dsi_init
== Summary == Built on 20c388faff9d8c41ab27e825c685526561b892a2 drm-intel-nightly: 2016y-01m-19d-13h-31m-46s UTC integration manifest Test gem_storedw_loop: Subgroup basic-render: dmesg-warn -> PASS (skl-i5k-2) UNSTABLE bdw-nuci7total:140 pass:131 dwarn:0 dfail:0 fail:0 skip:9 bsw-nuc-2total:143 pass:117 dwarn:2 dfail:0 fail:0 skip:24 byt-nuc total:143 pass:125 dwarn:3 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:102 dwarn:3 dfail:0 fail:0 skip:38 skl-i5k-2total:143 pass:134 dwarn:1 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1222/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC] igt/gem_exec_fence: New test for sync/fence interface
From: John Harrison Note, this is a work in progress. It is being posted now as there is work going on to change the debugging interface used by this test. So it would be useful to get some comments on whether the proposed changes will cause a problem for this test or whether the test itself should be done differently. Signed-off-by: John Harrison Cc: Gustavo Padovan --- lib/intel_batchbuffer.c | 36 ++ lib/intel_batchbuffer.h |1 + tests/Makefile.sources |1 + tests/gem_exec_fence.c | 1470 +++ 4 files changed, 1508 insertions(+) create mode 100644 tests/gem_exec_fence.c diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c index 692521f..55c7f9f 100644 --- a/lib/intel_batchbuffer.c +++ b/lib/intel_batchbuffer.c @@ -186,6 +186,27 @@ intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring) intel_batchbuffer_reset(batch); } +static void +intel_batchbuffer_flush_on_ring_fence(struct intel_batchbuffer *batch, int ring, + int fence_in, int *fence_out) +{ + unsigned int used = flush_on_ring_common(batch, ring); + drm_intel_context *ctx; + + if (used == 0) + return; + + do_or_die(drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer)); + + batch->ptr = NULL; + + ctx = batch->ctx; + do_or_die(drm_intel_gem_bo_context_fence_exec(batch->bo, ctx, used, + ring, fence_in, fence_out)); + + intel_batchbuffer_reset(batch); +} + void intel_batchbuffer_set_context(struct intel_batchbuffer *batch, drm_intel_context *context) @@ -239,6 +260,21 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) intel_batchbuffer_flush_on_ring(batch, ring); } +/** + * intel_batchbuffer_flush_fence: + * @batch: batchbuffer object + * + * Submits the batch for execution on the blitter engine, selecting the right + * ring depending upon the hardware platform. + */ +void +intel_batchbuffer_flush_fence(struct intel_batchbuffer *batch, int fence_in, int *fence_out) +{ + int ring = 0; + if (HAS_BLT_RING(batch->devid)) + ring = I915_EXEC_BLT; + intel_batchbuffer_flush_on_ring_fence(batch, ring, fence_in, fence_out); +} /** * intel_batchbuffer_emit_reloc: diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h index 869747d..5dece2a 100644 --- a/lib/intel_batchbuffer.h +++ b/lib/intel_batchbuffer.h @@ -35,6 +35,7 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch); void intel_batchbuffer_flush(struct intel_batchbuffer *batch); +void intel_batchbuffer_flush_fence(struct intel_batchbuffer *batch, int fence_in, int *fence_out); void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring); void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch, drm_intel_context *context); diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 8fb2de8..1000324 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -26,6 +26,7 @@ TESTS_progs_M = \ gem_exec_alignment \ gem_exec_bad_domains \ gem_exec_faulting_reloc \ + gem_exec_fence \ gem_exec_nop \ gem_exec_params \ gem_exec_parse \ diff --git a/tests/gem_exec_fence.c b/tests/gem_exec_fence.c new file mode 100644 index 000..ab6cc84 --- /dev/null +++ b/tests/gem_exec_fence.c @@ -0,0 +1,1470 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + *Tvrtko Ursulin + *John Harrison + *Geoff Miller + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#in
Re: [Intel-gfx] [PATCH v3] drm/i915: Handle PipeC fused off on IVB/HSW/BDW
On Wed, Jan 13, 2016 at 06:02:52PM +0200, Gabriel Feceoru wrote: > Some Gen7/8 production parts may have the Display Pipe C fused off. > In this case, the display hardware will prevent the Pipe C register bit > from being set to 1. Please elaborate on what pipe c register bit is prevented from being set. Thanks Patrik > > Fixed by adjusting pipe_count to reflect this. > > v2: Rename HSW_PIPE_C_DISABLE to IVB_PIPE_C_DISABLE as it already exists > on ivybridge (Ville) > v3: Remove unnecessary MMIO read, correct the description (Damien) > > Signed-off-by: Gabriel Feceoru > --- > drivers/gpu/drm/i915/i915_dma.c | 3 +++ > drivers/gpu/drm/i915/i915_reg.h | 1 + > 2 files changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c > index 44a896c..dd0d100 100644 > --- a/drivers/gpu/drm/i915/i915_dma.c > +++ b/drivers/gpu/drm/i915/i915_dma.c > @@ -813,6 +813,9 @@ static void intel_device_info_runtime_init(struct > drm_device *dev) >!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { > DRM_INFO("Display fused off, disabling\n"); > info->num_pipes = 0; > + } else if (fuse_strap & IVB_PIPE_C_DISABLE) { > + DRM_INFO("PipeC fused off\n"); > + info->num_pipes -= 1; > } > } > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 0a98889..a182739 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -5945,6 +5945,7 @@ enum skl_disp_power_wells { > #define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31) > #define ILK_INTERNAL_DISPLAY_DISABLE(1 << 30) > #define ILK_DISPLAY_DEBUG_DISABLE (1 << 29) > +#define IVB_PIPE_C_DISABLE (1 << 28) > #define ILK_HDCP_DISABLE(1 << 25) > #define ILK_eDP_A_DISABLE (1 << 24) > #define HSW_CDCLK_LIMIT (1 << 24) > -- > 1.9.1 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- --- Intel Sweden AB Registered Office: Knarrarnasgatan 15, 164 40 Kista, Stockholm, Sweden Registration Number: 556189-6027 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/skl/kbl: Add support for pipe fusing
On Mon, Jan 18, 2016 at 06:01:27PM +0200, Ville Syrjälä wrote: > On Mon, Jan 18, 2016 at 03:11:57PM +0100, Patrik Jakobsson wrote: > > On SKL and KBL we can have pipe A/B/C disabled by fuse settings. The > > pipes must be fused in descending order (e.g. C, B+C, A+B+C). There are > > several registers that can contain fuse settings so to simplify things > > we keep around a mask in device info with bits for each disabled pipe. > > This will also come in handy if the rule about the descending order is > > changed on future platforms. > > > > Signed-off-by: Patrik Jakobsson > > --- > > drivers/gpu/drm/i915/i915_dma.c | 34 ++ > > drivers/gpu/drm/i915/i915_drv.h | 1 + > > drivers/gpu/drm/i915/i915_reg.h | 4 > > 3 files changed, 39 insertions(+) > > > > diff --git a/drivers/gpu/drm/i915/i915_dma.c > > b/drivers/gpu/drm/i915/i915_dma.c > > index 988a380..2e9d47d 100644 > > --- a/drivers/gpu/drm/i915/i915_dma.c > > +++ b/drivers/gpu/drm/i915/i915_dma.c > > @@ -814,6 +814,40 @@ static void intel_device_info_runtime_init(struct > > drm_device *dev) > > DRM_INFO("Display fused off, disabling\n"); > > info->num_pipes = 0; > > } > > + } else if (info->num_pipes > 0 && INTEL_INFO(dev)->gen == 9) { > > + u32 fuse_strap = I915_READ(FUSE_STRAP); > > + u32 dfsm = I915_READ(SKL_DFSM); > > + bool invalid; > > + int num_bits; > > + > > + if (dfsm & SKL_DFSM_PIPE_A_DISABLE) > > + info->pipe_disabled_mask |= BIT(PIPE_A); > > + if (dfsm & SKL_DFSM_PIPE_B_DISABLE) > > + info->pipe_disabled_mask |= BIT(PIPE_B); > > + if (dfsm & SKL_DFSM_PIPE_C_DISABLE) > > + info->pipe_disabled_mask |= BIT(PIPE_C); > > + > > + if (fuse_strap & SKL_DISPLAY_PIPE_C_DISABLE) > > + info->pipe_disabled_mask |= BIT(PIPE_C); > > + > > + num_bits = hweight8(info->pipe_disabled_mask); > > + > > + switch (info->pipe_disabled_mask) { > > + case BIT(PIPE_A): > > + case BIT(PIPE_B): > > + case BIT(PIPE_A) | BIT(PIPE_B): > > + case BIT(PIPE_A) | BIT(PIPE_C): > > + invalid = true; > > + break; > > + default: > > + invalid = false; > > + } > > + > > + if (num_bits > info->num_pipes || invalid) > > + DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", > > + info->pipe_disabled_mask); > > + else > > + info->num_pipes -= num_bits; > > } > > > > /* Initialize slice/subslice/EU info */ > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > b/drivers/gpu/drm/i915/i915_drv.h > > index f0f75d7..2b4783c 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.h > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > @@ -792,6 +792,7 @@ struct intel_device_info { > > u8 num_pipes:3; > > u8 num_sprites[I915_MAX_PIPES]; > > u8 gen; > > + u8 pipe_disabled_mask; > > u8 ring_mask; /* Rings supported by the HW */ > > DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON); > > /* Register offsets for the various display pipes and transcoders */ > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > > b/drivers/gpu/drm/i915/i915_reg.h > > index 7510d508..72f07e6 100644 > > --- a/drivers/gpu/drm/i915/i915_reg.h > > +++ b/drivers/gpu/drm/i915/i915_reg.h > > @@ -5940,6 +5940,7 @@ enum skl_disp_power_wells { > > #define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31) > > #define ILK_INTERNAL_DISPLAY_DISABLE (1 << 30) > > #define ILK_DISPLAY_DEBUG_DISABLE (1 << 29) > > +#define SKL_DISPLAY_PIPE_C_DISABLE(1 << 28) > > Maybe you want to go review the other patch that wants to add this bit? > My bad, we shouldn't look at FUSE_STRAP on SKL+. I'll resend without it. > > #define ILK_HDCP_DISABLE (1 << 25) > > #define ILK_eDP_A_DISABLE (1 << 24) > > #define HSW_CDCLK_LIMIT (1 << 24) > > @@ -5986,6 +5987,9 @@ enum skl_disp_power_wells { > > #define SKL_DFSM_CDCLK_LIMIT_540 (1 << 23) > > #define SKL_DFSM_CDCLK_LIMIT_450 (2 << 23) > > #define SKL_DFSM_CDCLK_LIMIT_337_5 (3 << 23) > > +#define SKL_DFSM_PIPE_A_DISABLE(1 << 30) > > +#define SKL_DFSM_PIPE_B_DISABLE(1 << 21) > > +#define SKL_DFSM_PIPE_C_DISABLE(1 << 28) > > > > #define FF_SLICE_CS_CHICKEN2 _MMIO(0x20e4) > > #define GEN9_TSG_BARRIER_ACK_DISABLE (1<<8) > > -- > > 2.5.0 > > > > ___ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Ville Syrjälä > Intel OTC -- --- Intel Sweden AB Registered Office: Knarrarnasgatan 15, 164 40 Kista, Stockholm,
[Intel-gfx] [PATCH] drm/i915: Fix NULL plane->fb oops on SKL
From: Ville Syrjälä In this atomic age, we can't trust the plane->fb pointer anymore. It might get update too late. Instead we are supposed to use the plane_state->fb pointer instead. Let's do that in intel_plane_obj_offset() and avoid problems from dereferencing the potentially stale plane->fb pointer. Paulo found this with 'kms_frontbuffer_tracking --show-hidden --run-subtest nop-1p-rte' but it can be reproduced with just plain old kms_setplane. I was too lazy to bisect this, so not sure exactly when it broke. The most obvious candidate commit ce7f17285639 ("drm/i915: Fix i915_ggtt_view_equal to handle rotation correctly") was actually still fine, so it must have broken some time after that. Here's the resulting fireworks: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] PGD 8a5f6067 PUD 8a5f5067 PMD 0 Oops: [#1] PREEMPT SMP Modules linked in: i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm intel_gtt agpgart netconsole mousedev hid_generic psmouse usbhid atkbd libps2 coretemp hwmon efi_pstore intel_rapl iosf_mbi x86_pkg_temp_thermal efivars pcspkr e1000e sdhci_pci ptp pps_core sdhci i2c_i801 mmc_core i2c_hid hid i8042 serio evdev sch_fq_codel ip_tables x_tables ipv6 autofs4 CPU: 1 PID: 260 Comm: kms_plane Not tainted 4.4.0-skl+ #171 Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.R00.B104.B00.1511030553 11/03/2015 task: 88008bde2d80 ti: 88008a6ec000 task.ti: 88008a6ec000 RIP: 0010:[] [] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] RSP: 0018:88008a6efa10 EFLAGS: 00010086 RAX: 0001 RBX: 8801674f4240 RCX: 0014 RDX: 88008a7440c0 RSI: RDI: 88008a6efa40 RBP: 88008a6efa30 R08: 88008bde3598 R09: 0001 R10: 88008b782000 R11: R12: R13: 88008a7440c0 R14: R15: 88008a7449c0 FS: 7fa0c07a28c0() GS:88016ec4() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: CR3: 8a6ff000 CR4: 003406e0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Stack: 8801674f4240 88008a7440c0 88008a6efaa0 a02daf25 814ec80e 00070298 8800850d 88008a6efaa0 a02c49c2 0002 Call Trace: [] intel_plane_obj_offset+0x2d/0xa9 [i915] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 [] ? gen9_write32+0x2e8/0x3b8 [i915] [] skl_update_plane+0x203/0x4c5 [i915] [] intel_plane_atomic_update+0x53/0x6a [i915] [] drm_atomic_helper_commit_planes_on_crtc+0x142/0x1d5 [drm_kms_helper] [] intel_atomic_commit+0x1262/0x1350 [i915] [] ? __drm_atomic_helper_crtc_duplicate_state+0x2f/0x41 [drm_kms_helper] [] ? drm_atomic_check_only+0x3e3/0x552 [drm] [] drm_atomic_commit+0x4d/0x52 [drm] [] drm_atomic_helper_update_plane+0xcb/0x118 [drm_kms_helper] [] __setplane_internal+0x1c8/0x224 [drm] [] drm_mode_setplane+0x14e/0x172 [drm] [] drm_ioctl+0x265/0x3ad [drm] [] ? drm_mode_cursor_common+0x158/0x158 [drm] [] ? current_kernel_time64+0x5e/0x98 [] ? trace_hardirqs_on_caller+0x17a/0x196 [] do_vfs_ioctl+0x42b/0x4ea [] ? __fget_light+0x4d/0x71 [] SyS_ioctl+0x43/0x61 [] entry_SYSCALL_64_fastpath+0x12/0x6f Cc: drm-intel-fi...@lists.freedesktop.org Cc: Paulo Zanoni Testcase: igt/kms_plane Reported-by: Paulo Zanoni Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a851cb70479e..5bb960826cd1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2940,7 +2940,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane, struct i915_vma *vma; u64 offset; - intel_fill_fb_ggtt_view(&view, intel_plane->base.fb, + intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb, intel_plane->base.state); vma = i915_gem_obj_to_ggtt_view(obj, &view); -- 2.4.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Do not put big intel_crtc_state on the stack
== Summary == Built on 20c388faff9d8c41ab27e825c685526561b892a2 drm-intel-nightly: 2016y-01m-19d-13h-31m-46s UTC integration manifest Test gem_storedw_loop: Subgroup basic-render: pass -> DMESG-WARN (bdw-nuci7) UNSTABLE Test kms_pipe_crc_basic: Subgroup nonblocking-crc-pipe-b: pass -> SKIP (bdw-nuci7) bdw-nuci7total:140 pass:129 dwarn:1 dfail:0 fail:0 skip:10 bsw-nuc-2total:143 pass:117 dwarn:2 dfail:0 fail:0 skip:24 byt-nuc total:143 pass:125 dwarn:3 dfail:0 fail:0 skip:15 hsw-brixbox total:143 pass:136 dwarn:0 dfail:0 fail:0 skip:7 hsw-gt2 total:143 pass:139 dwarn:0 dfail:0 fail:0 skip:4 ilk-hp8440p total:143 pass:102 dwarn:3 dfail:0 fail:0 skip:38 skl-i5k-2total:143 pass:133 dwarn:2 dfail:0 fail:0 skip:8 snb-dellxps total:143 pass:124 dwarn:5 dfail:0 fail:0 skip:14 snb-x220ttotal:143 pass:124 dwarn:5 dfail:0 fail:1 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_1223/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx