Re: [Intel-gfx] [PATCH] drm/i915: Handle error paths during watermark sanitization properly (v2)

2016-01-11 Thread Maarten Lankhorst
Hey,

Op 11-01-16 om 19:27 schreef Matt Roper:
> sanitize_watermarks() does not properly handle errors returned by
> drm_atomic_helper_duplicate_state().  Make failures drop locks before
> returning.  We also change the lock of connection_mutex to a
> drm_modeset_lock_all_ctx() to make sure any EDEADLK's are handled
> earlier.
>
This patch still doesn't handle failure from intel_atomic_check and
lock_all_ctx correctly. If you fix that you can add:

Reviewed-by: Maarten Lankhorst 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] ✗ failure: Fi.CI.BAT

2016-01-11 Thread Patchwork
== Summary ==

Built on a90796840c30dac6d9907439bf98d1d08046c49d drm-intel-nightly: 
2016y-01m-11d-17h-22m-54s UTC integration manifest

Test gem_storedw_loop:
Subgroup basic-render:
pass   -> DMESG-WARN (skl-i5k-2) UNSTABLE
Test kms_pipe_crc_basic:
Subgroup hang-read-crc-pipe-a:
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ivb-t430s)
pass   -> FAIL   (bdw-ultra)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (ilk-hp8440p)
Subgroup hang-read-crc-pipe-b:
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ivb-t430s)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (ilk-hp8440p)
Subgroup hang-read-crc-pipe-c:
pass   -> DMESG-WARN (bsw-nuc-2)
pass   -> FAIL   (skl-i5k-2)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (skl-i7k-2)
pass   -> FAIL   (ivb-t430s)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
Subgroup nonblocking-crc-pipe-a:
pass   -> FAIL   (skl-i5k-2)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (bdw-ultra)
pass   -> FAIL   (skl-i7k-2)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
pass   -> FAIL   (ilk-hp8440p)
Subgroup nonblocking-crc-pipe-a-frame-sequence:
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (bdw-ultra)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
pass   -> FAIL   (ilk-hp8440p)
Subgroup nonblocking-crc-pipe-b:
dmesg-warn -> DMESG-FAIL (snb-x220t)
dmesg-warn -> DMESG-FAIL (snb-dellxps)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ilk-hp8440p)
Subgroup nonblocking-crc-pipe-b-frame-sequence:
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ilk-hp8440p)
Subgroup nonblocking-crc-pipe-c:
pass   -> FAIL   (hsw-gt2)
Subgroup nonblocking-crc-pipe-c-frame-sequence:
pass   -> FAIL   (bsw-nuc-2)
pass   -> FAIL   (skl-i5k-2)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (skl-i7k-2)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
Subgroup read-crc-pipe-a:
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ivb-t430s)
pass   -> FAIL   (bdw-ultra)
pass   -> FAIL   (skl-i7k-2)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
pass   -> FAIL   (ilk-hp8440p)
Subgroup read-crc-pipe-a-frame-sequence:
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ivb-t430s)
pass   -> FAIL   (bdw-ultra)
pass   -> FAIL   (byt-nuc)
pass   -> FAIL   (snb-x220t)
pass   -> FAIL   (snb-dellxps)
pass   -> FAIL   (hsw-brixbox)
pass   -> FAIL   (bdw-nuci7)
pass   -> FAIL   (ilk-hp8440p)
Subgroup read-crc-pipe-b:
dmesg-warn -> DMESG-FAIL (snb-x220t)
dmesg-warn -> DMESG-FAIL (snb-dellxps)
pass   -> FAIL   (hsw-gt2)
pass   -> FAIL   (ilk-hp8440p)
Subgroup read-crc-pipe-b-frame-sequence:
pass   -> FAIL   (snb-x220t)

[Intel-gfx] ✗ warning: Fi.CI.BAT

2016-01-11 Thread Patchwork
== Summary ==

Built on a90796840c30dac6d9907439bf98d1d08046c49d drm-intel-nightly: 
2016y-01m-11d-17h-22m-54s UTC integration manifest

Test gem_storedw_loop:
Subgroup basic-render:
pass   -> DMESG-WARN (bdw-nuci7)
pass   -> DMESG-WARN (skl-i7k-2) UNSTABLE
pass   -> DMESG-WARN (bdw-ultra)
Test pm_rpm:
Subgroup basic-rte:
dmesg-warn -> PASS   (byt-nuc) UNSTABLE

bdw-nuci7total:138  pass:128  dwarn:1   dfail:0   fail:0   skip:9  
bdw-ultratotal:138  pass:131  dwarn:1   dfail:0   fail:0   skip:6  
bsw-nuc-2total:141  pass:115  dwarn:2   dfail:0   fail:0   skip:24 
byt-nuc  total:141  pass:124  dwarn:2   dfail:0   fail:0   skip:15 
hsw-brixbox  total:141  pass:134  dwarn:0   dfail:0   fail:0   skip:7  
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:132  dwarn:1   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_1136/

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/7] drm/i915/dp: Add methods to update link train params

2016-01-11 Thread R, Durgadoss
>-Original Message-
>From: Ander Conselvan De Oliveira [mailto:conselv...@gmail.com]
>Sent: Monday, January 11, 2016 8:07 PM
>To: R, Durgadoss; intel-gfx@lists.freedesktop.org
>Subject: Re: [PATCH 5/7] drm/i915/dp: Add methods to update link train params
>
>On Fri, 2015-12-11 at 15:09 +0530, Durgadoss R wrote:
>> Retrying with reduced lanes/bw and updating the final
>> available lanes/bw to DPCD is needed for upfront link
>> train logic. Hence, this patch adds these methods
>> and exports them so that these can be called from
>> other files like ddi.c/display.c.
>>
>> Signed-off-by: Durgadoss R 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c  | 34 ++
>>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index f335c92..d8f7830 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -1660,6 +1660,40 @@ void intel_dp_set_link_params(struct intel_dp
>> *intel_dp,
>>  intel_dp->lane_count = pipe_config->lane_count;
>>  }
>>
>> +void intel_dp_update_dpcd_params(struct intel_dp *intel_dp)
>> +{
>> +intel_dp->dpcd[DP_MAX_LANE_COUNT] &= ~DP_MAX_LANE_COUNT_MASK;
>> +intel_dp->dpcd[DP_MAX_LANE_COUNT] |=
>> +intel_dp->lane_count & DP_MAX_LANE_COUNT_MASK;
>> +
>> +intel_dp->dpcd[DP_MAX_LINK_RATE] =
>> +drm_dp_link_rate_to_bw_code(intel_dp->link_rate);
>> +}
>> +
>> +bool intel_dp_get_link_retry_params(uint8_t *lane_count, uint8_t *link_bw)
>> +{
>> +/*
>> + * As per DP1.3 Spec, retry all link rates for a particular
>> + * lane count value, before reducing number of lanes.
>> + */
>> +if (*link_bw == DP_LINK_BW_5_4) {
>> +*link_bw = DP_LINK_BW_2_7;
>> +} else if (*link_bw == DP_LINK_BW_2_7) {
>> +*link_bw = DP_LINK_BW_1_62;
>> +} else if (*lane_count == 4) {
>> +*lane_count = 2;
>> +*link_bw = DP_LINK_BW_5_4;
>> +} else if (*lane_count == 2) {
>> +*lane_count = 1;
>> +*link_bw = DP_LINK_BW_5_4;
>
>If the sink doesn't support 5.4 Gbps, shouldn't we skip that rate?
>
>Also, it would be easier to review these functions if they were in same patch
>were they are used.

Ok, will take care of this next version.

Thanks,
Durga

>
>Ander
>
>> +} else {
>> +/* Tried all combinations, so exit */
>> +return false;
>> +}
>> +
>> +return true;
>> +}
>> +
>>  static void intel_dp_prepare(struct intel_encoder *encoder)
>>  {
>>  struct drm_device *dev = encoder->base.dev;
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h
>> b/drivers/gpu/drm/i915/intel_drv.h
>> index faa91fc..5cefb0e 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -1233,6 +1233,8 @@ bool intel_dp_init_connector(struct intel_digital_port
>> *intel_dig_port,
>>   struct intel_connector *intel_connector);
>>  void intel_dp_set_link_params(struct intel_dp *intel_dp,
>>const struct intel_crtc_state *pipe_config);
>> +void intel_dp_update_dpcd_params(struct intel_dp *intel_dp);
>> +bool intel_dp_get_link_retry_params(uint8_t *lane_count, uint8_t *link_bw);
>>  void intel_dp_start_link_train(struct intel_dp *intel_dp);
>>  void intel_dp_stop_link_train(struct intel_dp *intel_dp);
>>  void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/5] drm: Enable markdown^Wasciidoc for gpu.tmpl

2016-01-11 Thread Jani Nikula
On Tue, 12 Jan 2016, Jonathan Corbet  wrote:
> In my mind, there's clearly no good that can come from (further) delaying
> something that works in favor of an "it would be nice" that may never
> even exist.  So I'm currently thinking that I'll pull this into the docs
> tree once the merge window is done, with the plan to push it for 4.6.
> Then we can see if anybody screams.

Must... resist... urge to bikeshed about the choice of markup...

> The build-time increase is painful in the extreme - about a factor of
> three for a -j1 build, and that's with only one file using the feature.
> It feels wrong, somehow, for the docs build to take longer than building
> the kernel itself.  Can we do something about that?

"Holy big-O, batman. Asciidoc appears to be quadractically slow." [1]

Fortunately the same quote lead me to asciidoctor [2], which was maybe
twice as fast as asciidoc. An improvement, but could be much better.

BR,
Jani.


[1] https://twitter.com/marijnjh/status/473935469676216321
[2] http://asciidoctor.org/docs/asciidoc-asciidoctor-diffs/


-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 13/22] drm/exynos: Remove event cancelling from postclose

2016-01-11 Thread Inki Dae
Hi Daniel,

It seems your patch is exactly same as below my one I posted before,
http://www.spinics.net/lists/dri-devel/msg97922.html

Anyway, it's ok if this patch can go to mainline.

Acked-by: Inki Dae 

2016년 01월 12일 06:41에 Daniel Vetter 이(가) 쓴 글:
> The core takes care of this now. And since kfree(NULL) is ok we can
> simplify the function even further now.
> 
> Cc: Inki Dae 
> Acked-by: Daniel Stone 
> Reviewed-by: Alex Deucher 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 14 --
>  1 file changed, 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
> b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 9756797a15a5..868ab9f54f17 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -335,20 +335,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
>  
>  static void exynos_drm_postclose(struct drm_device *dev, struct drm_file 
> *file)
>  {
> - struct drm_pending_event *e, *et;
> - unsigned long flags;
> -
> - if (!file->driver_priv)
> - return;
> -
> - spin_lock_irqsave(&dev->event_lock, flags);
> - /* Release all events handled by page flip handler but not freed. */
> - list_for_each_entry_safe(e, et, &file->event_list, link) {
> - list_del(&e->link);
> - e->destroy(e);
> - }
> - spin_unlock_irqrestore(&dev->event_lock, flags);
> -
>   kfree(file->driver_priv);
>   file->driver_priv = NULL;
>  }
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] igt/gem_trtt: Exercise the TRTT hardware

2016-01-11 Thread Tian, Kevin
> From: akash.g...@intel.com
> Sent: Saturday, January 09, 2016 7:32 PM
> 

[...]

> 
> There is a provision to keep TR-TT Tables in virtual space, where the pages of
> TRTT tables will be mapped to PPGTT. This is the adopted mode, as in this mode
> UMD will have a full control on TR-TT management, with bare minimum support
> from KMD.
> So the entries of L3 table will contain the PPGTT offset of L2 Table pages,
> similarly entries of L2 table will contain the PPGTT offset of L1 Table pages.
> The entries of L1 table will contain the PPGTT offset of BOs actually backing
> the Sparse resources.
> 

Just a side note. Using virtual address for TRTT table also benefits 
virtualization
side. This way we can let guest own TRTT completely. Otherwise we have to
virtualize TRTT table if physical address is used, which is very complex and
could bring obvious performance impact.

It's appreciated if you can add this virtualization requirement in code comment
so others can catch this limitation if they want to do some change in the 
future. :-)

Thanks
Kevin
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 0/6] drm/i915: start hiding away vbt structure from the driver

2016-01-11 Thread Jani Nikula
On Mon, 11 Jan 2016, Lukas Wunner  wrote:
> Hi,
>
> On Mon, Jan 11, 2016 at 09:54:36PM +0200, Jani Nikula wrote:
>> Hi all, first real patches since the RFC at [1].
>> 
>> The VBT is a monster and it keeps growing. Originally we've extracted
>> bits and pieces out of there, and added them cleanly to our own
>> structures in dev_priv->vbt, with our own macros. Later on we've been
>> slipping and we have copied stuff from VBT verbatim, using the same
>> structs and defines as in VBT.
>
> There's also code spread out across the driver to sanitize VBT data, e.g.:
> http://cgit.freedesktop.org/drm-intel/tree/drivers/gpu/drm/i915/intel_display.c?h=drm-intel-nightly#n15424
>
> (cf. 69f92f67b68a, "drm/i915: Preserve SSC earlier")
>
> Would probably make sense to consolidate that in intel_bios.c as well.

It's worth noting that there's no mmio register access in
intel_bios.c. It's just about parsing the VBT. I'd prefer to keep it
that way.

BR,
Jani.



>
> Best regards,
>
> Lukas
>
>> 
>> Start abstracting the VBT more, hiding away the VBT specific stuff that
>> should not be fiddled with outside of intel_bios.c. Make it more
>> explicit when we're doing so. At this stage, mostly just fork the
>> private parts into intel_bios_private.h. As prep work, move some stuff
>> to intel_bios.c to limit the amount of macros needing to be exposed
>> across the whole driver.
>> 
>> With the MIPI DSI VBT stuff out of the way, this now applies on top of
>> nightly.
>> 
>> 
>> BR,
>> Jani.
>> 
>> [1] http://mid.gmane.org/cover.1450192823.git.jani.nik...@intel.com
>> 
>> 
>> Jani Nikula (6):
>>   drm/i915: move VBT based TV presence check to intel_bios.c
>>   drm/i915: move VBT based LVDS presence check to intel_bios.c
>>   drm/i915: move VBT based eDP port check to intel_bios.c
>>   drm/i915: move VBT based DSI presence check to intel_bios.c
>>   drm/i915/panel: setup pwm backlight based on connector type
>>   drm/i915: hide away VBT private data in a separate header
>> 
>>  Documentation/DocBook/gpu.tmpl|   2 +-
>>  drivers/gpu/drm/i915/i915_drv.h   |   5 +-
>>  drivers/gpu/drm/i915/intel_bios.c | 156 +-
>>  drivers/gpu/drm/i915/intel_bios.h | 860 
>> ++
>>  drivers/gpu/drm/i915/intel_bios_private.h | 823 
>>  drivers/gpu/drm/i915/intel_dp.c   |  21 +-
>>  drivers/gpu/drm/i915/intel_dsi.c  |  23 +-
>>  drivers/gpu/drm/i915/intel_lvds.c |  53 +-
>>  drivers/gpu/drm/i915/intel_panel.c|   2 +-
>>  drivers/gpu/drm/i915/intel_tv.c   |  43 +-
>>  10 files changed, 1034 insertions(+), 954 deletions(-)
>>  create mode 100644 drivers/gpu/drm/i915/intel_bios_private.h
>> 
>> -- 
>> 2.1.4
>> 
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 00/38] GPU scheduler for i915 driver

2016-01-11 Thread Tian, Kevin
> From: john.c.harri...@intel.com
> Sent: Tuesday, January 12, 2016 2:42 AM
> 
> From: John Harrison 
> 
> Implemented a batch buffer submission scheduler for the i915 DRM driver.
> 
> The general theory of operation is that when batch buffers are
> submitted to the driver, the execbuffer() code assigns a unique seqno
> value and then packages up all the information required to execute the
> batch buffer at a later time. This package is given over to the
> scheduler which adds it to an internal node list. The scheduler also
> scans the list of objects associated with the batch buffer and
> compares them against the objects already in use by other buffers in
> the node list. If matches are found then the new batch buffer node is
> marked as being dependent upon the matching node. The same is done for
> the context object. The scheduler also bumps up the priority of such
> matching nodes on the grounds that the more dependencies a given batch
> buffer has the more important it is likely to be.
> 

A curious question. Is this new GPU scheduler still useful when GuC
is enabled? Sorry if this Q. has been answered before.

Thanks
Kevin
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [RFC 2/2] drm/i915: Render decompression support for Gen9

2016-01-11 Thread Konduru, Chandra
> -Original Message-
> From: Daniel Stone [mailto:dan...@fooishbar.org]
> Sent: Wednesday, December 23, 2015 1:37 AM
> To: Kannan, Vandana
> Cc: intel-gfx; Konduru, Chandra; Murthy, Arun R
> Subject: Re: [Intel-gfx] [RFC 2/2] drm/i915: Render decompression support for
> Gen9
> 
> Hi Vandana,
> 
> On 23 December 2015 at 03:20, Kannan, Vandana
>  wrote:
> > How does VT switch work in case of rotation, setting different pixel format,
> > etc?
> 
> Pixel format is a property of the framebuffer, not a per-plane
> property, so is unaffected. Rotation is generic, so there is specific
> code to handle it for fbdev etc.
> 
> But the real problem is that this is an Intel-specific property, and
> in order to get correct results, userspace must know about these
> specific properties in order to unset them. This means that you can't
> run generic userspace, and you can't run old userspace which predates
> these properties either. This seems like a total non-starter to me.
> 
> It would be much cleaner if there was a way to attach the render
> compression property to the framebuffer, e.g. by using the format
> modifiers which were specifically introduced to deal with compression
> and tiling.
> 
> Cheers,
> Daniel

Hi Daniel,
Plan is to handle compression property similar to rotation property. 
Don't see why that will be an issue. 

To address VT-switch concern, there will be a small code change 
resetting compression property in the VT-switch case - which may as well 
apply to other properties.

Please let us know if this is resolving your feedback.

By the way, for rotation in VT switch path (or any other property), 
there isn't code to reset to 0. The only place where reset is at  
"i915_driver_lastclose - clean up after all DRM clients have exited".

Thanks,
Chandra
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 02/38] drm/i915: Explicit power enable during deferred context initialisation

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:31PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> A later patch in this series re-organises the batch buffer submission
> code. Part of that is to reduce the scope of a pm_get/put pair.
> Specifically, they previously wrapped the entire submission path from
> the very start to the very end, now they only wrap the actual hardware
> submission part in the back half.

However, as you haven't fixed the ordering issue that requires rpm_get
before struct_mutex, this is broken. When we have rpm fixed, you don't
need this patch as we can take the wakeref around the GSM access itself.
We still want the prolonged rpm wakeref for the GPU activity, ofc.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/5] drm: Enable markdown^Wasciidoc for gpu.tmpl

2016-01-11 Thread Jonathan Corbet
On Sat, 12 Dec 2015 12:13:45 +0100
Daniel Vetter  wrote:

> I just figured there's no way this could get it, and I'd
> much rather improve the docs themselves than trying to convince core
> kernel folks that this might be useful.

So I'm not quite sure why you figured that; I never said it, certainly.

I've been messing with it a bit, seems to work.  I do still wish we could
consider alternatives, especially those that might simplify the toolchain
rather than complicating it.  But it's clear that I'm not succeeding in
finding time to actually explore that idea; the contents of $EXCUSES are
good, but the end result is the same.  And the patch fairy just isn't
coming through for me on this one.

In my mind, there's clearly no good that can come from (further) delaying
something that works in favor of an "it would be nice" that may never
even exist.  So I'm currently thinking that I'll pull this into the docs
tree once the merge window is done, with the plan to push it for 4.6.
Then we can see if anybody screams.

That gives a couple of weeks for an updated patch set, should you have
one.

The build-time increase is painful in the extreme - about a factor of
three for a -j1 build, and that's with only one file using the feature.
It feels wrong, somehow, for the docs build to take longer than building
the kernel itself.  Can we do something about that?

 - How many of the comments actually use asciidoc features?  Might there
   be some possibility of detecting those in kernel-doc and skipping the
   callout to asciidoc when it's not needed?

 - Pandoc seems to do asciidoc.  I still don't like the idea of depending
   on it for this to work, but having the *option* to use it is fine.  If
   it's really that much faster (yes, Python startup is painful) then
   maybe providing the option is worth it.

 - All over the kernel we've seen that batching improves performance.  It
   would take a bit of work, but I bet kernel-doc could put together all
   the snippets from one file, pass them through a single asciidoc
   invocation, then split the results back apart.  That would probably
   eliminate the performance hit entirely.

None of that is a condition for pulling this stuff in, but can it be
looked into?

Thanks,

jon
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 00/38] GPU scheduler for i915 driver

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:29PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> Implemented a batch buffer submission scheduler for the i915 DRM driver.

I've lost track of the number of patches that are a result of not having
per-context seqno and could be eliminated.
 
> The general theory of operation is that when batch buffers are
> submitted to the driver, the execbuffer() code assigns a unique seqno
> value and then packages up all the information required to execute the
> batch buffer at a later time. This package is given over to the
> scheduler which adds it to an internal node list. The scheduler also
> scans the list of objects associated with the batch buffer and
> compares them against the objects already in use by other buffers in
> the node list. If matches are found then the new batch buffer node is
> marked as being dependent upon the matching node. The same is done for
> the context object. The scheduler also bumps up the priority of such
> matching nodes on the grounds that the more dependencies a given batch
> buffer has the more important it is likely to be.

The implicit synchronisation rules for GEM are best left for GEM.
Through the existing mechansim for synchronising requests, you can also
gather the information required to compute the dependency graph of the
new request. Adding the explicit synchronisation can then be done at the
same juncture.

> The scheduler aims to have a given (tuneable) number of batch buffers
> in flight on the hardware at any given time. If fewer than this are
> currently executing when a new node is queued, then the node is passed
> straight through to the submit function. Otherwise it is simply added
> to the queue and the driver returns back to user land.
> 
> As each batch buffer completes, it raises an interrupt which wakes up
> the scheduler. Note that it is possible for multiple buffers to
> complete before the IRQ handler gets to run. Further, the seqno values
> of the individual buffers are not necessary incrementing as the
> scheduler may have re-ordered their submission. However, the scheduler
> keeps the list of executing buffers in order of hardware submission.
> Thus it can scan through the list until a matching seqno is found and
> then mark all in flight nodes from that point on as completed.
> 
> A deferred work queue is also poked by the interrupt handler. When
> this wakes up it can do more involved processing such as actually
> removing completed nodes from the queue and freeing up the resources
> associated with them (internal memory allocations, DRM object
> references, context reference, etc.). The work handler also checks the
> in flight count and calls the submission code if a new slot has
> appeared.

No. Leave GEM code to GEM. Just handle scheduling of requests, avoid the
struct_mutex and let GEM tidy up after the requests it is tracking. Create
a kthread for the scheduler, long running tasks are not meant to be on the
system_wq. A kthread also allows you to set a rtpriority.
 
> When the scheduler's submit code is called, it scans the queued node
> list for the highest priority node that has no unmet dependencies.
> Note that the dependency calculation is complex as it must take
> inter-ring dependencies and potential preemptions into account. Note
> also that in the future this will be extended to include external
> dependencies such as the Android Native Sync file descriptors and/or
> the linux dma-buff synchronisation scheme.

(You can skip the note since it is just checking if a dependency is a
struct fence and whether that has been signalled, that is not any more
complex than the current request checking.)

> If a suitable node is found then it is sent to execbuff_final() for
> submission to the hardware. The in flight count is then re-checked and
> a new node popped from the list if appropriate.

That was the wrong callback to break up. You just wanted an
engine->submit_request(). But then if you look at execlists, you will
see a way to marry the two such that the scheduler has neglible overhead
above and beyond the already considerable overhead of execlistss. With
legacy, you will have to introduce the cost of interrupt driven
scheduling, but you can borrow an idea or two from execlists to mitigate
that somewhat (i.e. context switch interrupts rather than reusing the
user interrupt after every batch).
 
> The scheduler also allows high priority batch buffers (e.g. from a
> desktop compositor) to jump ahead of whatever is already running if
> the underlying hardware supports pre-emption. In this situation, any
> work that was pre-empted is returned to the queued list ready to be
> resubmitted when no more high priority work is outstanding.

You could actually demonstrate that in execlists without adding a full
blown scheduler.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lis

Re: [Intel-gfx] [PATCH 04/13] drm/i915: Fail engine initialization if LRCA is incorrectly aligned

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 04:02:09PM +, Dave Gordon wrote:
> IIRC the original version of this WARN (in intel_lr_context_descriptor()
> above) was added with the GuC submission code, because the context
> descriptor as used in execlist code is a 64-bit value, but the GuC
> requires that all the unique stuff fits in those 20 unmasked bits of
> a 32-bit value, with the low 12 bits being used for flags. So we
> wanted to check that we never got a context ID that couldn't be
> pruned down to just those 20 bits without losing information. It's
> never been seen to happen since GuC development finished, so we can
> reasonably lose the check now.

I am missing something here as the GuC doesn't use the high 32bits of
the context descriptor, i.e. it never touches the lrca portion?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 18/38] drm/i915: Added scheduler support to __wait_request() calls

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:47PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> The scheduler can cause batch buffers, and hence requests, to be
> submitted to the ring out of order and asynchronously to their
> submission to the driver. Thus at the point of waiting for the
> completion of a given request, it is not even guaranteed that the
> request has actually been sent to the hardware yet. Even it is has
> been sent, it is possible that it could be pre-empted and thus
> 'unsent'.
> 
> This means that it is necessary to be able to submit requests to the
> hardware during the wait call itself. Unfortunately, while some
> callers of __wait_request() release the mutex lock first, others do
> not (and apparently can not). Hence there is the ability to deadlock
> as the wait stalls for submission but the asynchronous submission is
> stalled for the mutex lock.

That is a nonsequitor. Do you mean to say that unless we take action
inside GEM, the request will never be submitted to hardware by the
scheduler?
 
> This change hooks the scheduler in to the __wait_request() code to
> ensure correct behaviour. That is, flush the target batch buffer
> through to the hardware and do not deadlock waiting for something that
> cannot currently be submitted.

The dependencies are known during request construction, how could we
generate a cyclic graph? The scheduler itself does not need the
struct_mutex (other than the buggy code), so GEM holding the
struct_mutex will not prevent the scheduler from eventually submitting
the request we are waiting for. So as far as I can see, you are papering
over your own bugs.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/7] drm/i915: Interrupt driven fences

2016-01-11 Thread Jesse Barnes
On 01/11/2016 11:10 AM, John Harrison wrote:
> On 08/01/2016 22:46, Chris Wilson wrote:
>> On Fri, Jan 08, 2016 at 06:47:26PM +, john.c.harri...@intel.com wrote:
>>> +void i915_gem_request_notify(struct intel_engine_cs *ring, bool 
>>> fence_locked)
>>> +{
>>> +struct drm_i915_gem_request *req, *req_next;
>>> +unsigned long flags;
>>>   u32 seqno;
>>>   -seqno = req->ring->get_seqno(req->ring, false/*lazy_coherency*/);
>>> +if (list_empty(&ring->fence_signal_list))
>>> +return;
>>> +
>>> +if (!fence_locked)
>>> +spin_lock_irqsave(&ring->fence_lock, flags);
>>>   -return i915_seqno_passed(seqno, req->seqno);
>>> +seqno = ring->get_seqno(ring, false);
>> We really don't want to do be doing the forcewake dance from inside the
>> interrupt handler. We made that mistake years ago.
>> -Chris
>>
> What forcewake dance? Nothing in the above code mentions force wake.

get_seqno() w/o lazy_coherency set will do a POSTING_READ of the ring active 
head, which goes through our crazy read function and does forcewake.  So we may 
need something smarter here.

Jesse

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/7] drm/i915: Add per context timelines to fence object

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 02:47:33PM -0800, Jesse Barnes wrote:
> On 01/11/2016 11:03 AM, John Harrison wrote:
> > On 08/01/2016 22:05, Chris Wilson wrote:
> >> On Fri, Jan 08, 2016 at 06:47:24PM +, john.c.harri...@intel.com wrote:
> >>> From: John Harrison 
> >>>
> >>> The fence object used inside the request structure requires a sequence
> >>> number. Although this is not used by the i915 driver itself, it could
> >>> potentially be used by non-i915 code if the fence is passed outside of
> >>> the driver. This is the intention as it allows external kernel drivers
> >>> and user applications to wait on batch buffer completion
> >>> asynchronously via the dma-buff fence API.
> >> That doesn't make any sense as they are not limited by a single
> >> timeline.
> > I don't understand what you mean. Who is not limited by a single timeline?  
> > The point is that the current seqno values cannot be used as there is no 
> > guarantee that they will increment globally once things like a scheduler 
> > and pre-emption arrive. Whereas, the fence internal implementation makes 
> > various assumptions about the linearity of the timeline. External users do 
> > not want to care about timelines or seqnos at all, they just want the fence 
> > API to work as documented.
> > 
> >>
> >>> To ensure that such external users are not confused by strange things
> >>> happening with the seqno, this patch adds in a per context timeline
> >>> that can provide a guaranteed in-order seqno value for the fence. This
> >>> is safe because the scheduler will not re-order batch buffers within a
> >>> context - they are considered to be mutually dependent.
> >> You haven't added per-context breadcrumbs. What we need for being able
> >> to execute requests from parallel timelines, but with requests within a
> >> timeline being ordered, is a per-context page where we can emit the
> >> per-context issued breadcrumb. Then instead of looking up the current
> >> HW seqno in a global page, the request just looks at the current context
> >> HW seqno in the context seq, just
> >> i915_seqno_passed(*req->p_context_seqno, req->seqno).
> > This patch is not attempting to implement per context seqno values. That 
> > can be done as future work. This patch is doing the simplest, least 
> > invasive implementation in order to make external fences work.
> 
> Right.  I think we want to move to per-context seqnos, but we don't have to 
> do it before this work lands.  It should be easier to do it after the rest of 
> these bits land in fact, since seqno handling will be well encapsulated aiui.

This patch is irrelevent then. I think it is actually worse because it
is encapsulating a design detail that is fundamentally wrong.
-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] [PATCH] drm/i915: edp resume/On time optimization.

2016-01-11 Thread abhay . kumar
From: Abhay Kumar 

Make resume/on codepath not to wait for panel_power_cycle_delay(t11_t12)
if this time is already spent in suspend/poweron time.

v2: Use CLOCK_BOOTTIME and remove jiffies for panel power cycle
delay calculation(Ville).

v3: Addressing Ville review comment.

Cc: Ville Syrjälä 
Signed-off-by: Abhay Kumar 
---
 drivers/gpu/drm/i915/intel_dp.c  | 19 ++-
 drivers/gpu/drm/i915/intel_drv.h |  2 +-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796e3d3..d0885bc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1812,12 +1812,21 @@ static void wait_panel_off(struct intel_dp *intel_dp)
 
 static void wait_panel_power_cycle(struct intel_dp *intel_dp)
 {
+   static ktime_t panel_power_on_time;
+   s64 panel_power_off_duration;
+
DRM_DEBUG_KMS("Wait for panel power cycle\n");
 
+   /* take the difference of currrent time and panel power off time
+* and then make panel wait for t11_t12 if needed. */
+   panel_power_on_time = ktime_get_boottime();
+   panel_power_off_duration = ktime_ms_delta(panel_power_on_time, 
intel_dp->panel_power_off_time);
+
/* When we disable the VDD override bit last we have to do the manual
 * wait. */
-   wait_remaining_ms_from_jiffies(intel_dp->last_power_cycle,
-  intel_dp->panel_power_cycle_delay);
+   if (panel_power_off_duration < ((s64) 
intel_dp->panel_power_cycle_delay))
+   wait_remaining_ms_from_jiffies(jiffies,
+  (intel_dp->panel_power_cycle_delay - 
panel_power_off_duration));
 
wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
 }
@@ -1969,7 +1978,7 @@ static void edp_panel_vdd_off_sync(struct intel_dp 
*intel_dp)
I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
 
if ((pp & POWER_TARGET_ON) == 0)
-   intel_dp->last_power_cycle = jiffies;
+   intel_dp->panel_power_off_time = ktime_get_boottime();
 
power_domain = intel_display_port_aux_power_domain(intel_encoder);
intel_display_power_put(dev_priv, power_domain);
@@ -2118,7 +2127,7 @@ static void edp_panel_off(struct intel_dp *intel_dp)
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
 
-   intel_dp->last_power_cycle = jiffies;
+   intel_dp->panel_power_off_time = ktime_get_boottime();
wait_panel_off(intel_dp);
 
/* We got a reference when we enabled the VDD. */
@@ -5122,7 +5131,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct 
drm_connector *connect
 
 static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp)
 {
-   intel_dp->last_power_cycle = jiffies;
+   intel_dp->panel_power_off_time = ktime_get_boottime();
intel_dp->last_power_on = jiffies;
intel_dp->last_backlight_off = jiffies;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bdfe403..06b37b8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -793,9 +793,9 @@ struct intel_dp {
int backlight_off_delay;
struct delayed_work panel_vdd_work;
bool want_panel_vdd;
-   unsigned long last_power_cycle;
unsigned long last_power_on;
unsigned long last_backlight_off;
+   ktime_t panel_power_off_time;
 
struct notifier_block edp_notifier;
 
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 073/190] drm/i915: Introduce i915_gem_active for request tracking

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 05:32:27PM +, Tvrtko Ursulin wrote:
> >+struct i915_gem_active {
> >+struct drm_i915_gem_request *request;
> >+};
> >+
> >+static inline void
> >+i915_gem_request_mark_active(struct drm_i915_gem_request *request,
> >+ struct i915_gem_active *active)
> >+{
> >+i915_gem_request_assign(&active->request, request);
> >+}
> 
> This function name bothers me since I think the name is misleading
> and unintuitive. It is not marking a request as active but
> associating it with the second data structure.
> 
> Maybe i915_gem_request_move_to_active to keep the mental association
> with the well established vma_move_to_active ?

That's backwards imo, since it is the i915_gem_active that gets added to
the request. (Or at least will be.)
 
> Maybe struct i915_gem_active could also be better called
> i915_gem_active_list ?

It's not a list but a node. I started with drm_i915_gem_request_node,
but that's too unwieldy and I felt even more confusing.

> It is not ideal because of the future little reversal of who is in
> who's list, so maybe there is something even better. But I think an
> intuitive name is really important for code clarity and
> maintainability.

In userspace, I have the request (which is actually a userspace fence
itself) containing a list of fences (that are identical to i915_gem_active,
they track which request contains the reference and a callback for
signalling) and those fences have a direct correspondence to,
ARB_sync_objects, for example. But we already have plenty of conflict
regarding the term fence, so that's no go.

i915_gem_active, for me, made the association with the active-reference
tracking that is ingrained into the objects and beyond. I quite like the
connection with GPU activity

i915_gem_retire_notifier? Hmm, I still like how
i915_gem_active.request != NULL is quite self-descriptive.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/7] drm/i915: Add per context timelines to fence object

2016-01-11 Thread Jesse Barnes
On 01/11/2016 11:03 AM, John Harrison wrote:
> On 08/01/2016 22:05, Chris Wilson wrote:
>> On Fri, Jan 08, 2016 at 06:47:24PM +, john.c.harri...@intel.com wrote:
>>> From: John Harrison 
>>>
>>> The fence object used inside the request structure requires a sequence
>>> number. Although this is not used by the i915 driver itself, it could
>>> potentially be used by non-i915 code if the fence is passed outside of
>>> the driver. This is the intention as it allows external kernel drivers
>>> and user applications to wait on batch buffer completion
>>> asynchronously via the dma-buff fence API.
>> That doesn't make any sense as they are not limited by a single
>> timeline.
> I don't understand what you mean. Who is not limited by a single timeline?  
> The point is that the current seqno values cannot be used as there is no 
> guarantee that they will increment globally once things like a scheduler and 
> pre-emption arrive. Whereas, the fence internal implementation makes various 
> assumptions about the linearity of the timeline. External users do not want 
> to care about timelines or seqnos at all, they just want the fence API to 
> work as documented.
> 
>>
>>> To ensure that such external users are not confused by strange things
>>> happening with the seqno, this patch adds in a per context timeline
>>> that can provide a guaranteed in-order seqno value for the fence. This
>>> is safe because the scheduler will not re-order batch buffers within a
>>> context - they are considered to be mutually dependent.
>> You haven't added per-context breadcrumbs. What we need for being able
>> to execute requests from parallel timelines, but with requests within a
>> timeline being ordered, is a per-context page where we can emit the
>> per-context issued breadcrumb. Then instead of looking up the current
>> HW seqno in a global page, the request just looks at the current context
>> HW seqno in the context seq, just
>> i915_seqno_passed(*req->p_context_seqno, req->seqno).
> This patch is not attempting to implement per context seqno values. That can 
> be done as future work. This patch is doing the simplest, least invasive 
> implementation in order to make external fences work.

Right.  I think we want to move to per-context seqnos, but we don't have to do 
it before this work lands.  It should be easier to do it after the rest of 
these bits land in fact, since seqno handling will be well encapsulated aiui.

Jesse

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/7] drm/i915: Removed now redudant parameter to i915_gem_request_completed()

2016-01-11 Thread Jesse Barnes
On 01/08/2016 10:47 AM, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> The change to the implementation of i915_gem_request_completed() means
> that the lazy coherency flag is no longer used. This can now be
> removed to simplify the interface.
> 
> For: VIZ-5190
> Signed-off-by: John Harrison 
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c  |  2 +-
>  drivers/gpu/drm/i915/i915_drv.h  |  3 +--
>  drivers/gpu/drm/i915/i915_gem.c  | 18 +-
>  drivers/gpu/drm/i915/intel_display.c |  2 +-
>  drivers/gpu/drm/i915/intel_pm.c  |  4 ++--
>  5 files changed, 14 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index af41e5c..b54d99e 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -601,7 +601,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, 
> void *data)
>  
> i915_gem_request_get_seqno(work->flip_queued_req),
>  dev_priv->next_seqno,
>  ring->get_seqno(ring, true),
> -
> i915_gem_request_completed(work->flip_queued_req, true));
> +
> i915_gem_request_completed(work->flip_queued_req));
>   } else
>   seq_printf(m, "Flip not associated with any 
> ring\n");
>   seq_printf(m, "Flip queued on frame %d, (was ready on 
> frame %d), now %d\n",
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index aa5cba7..caf7897 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2263,8 +2263,7 @@ int i915_gem_request_alloc(struct intel_engine_cs *ring,
>  struct drm_i915_gem_request **req_out);
>  void i915_gem_request_cancel(struct drm_i915_gem_request *req);
>  
> -static inline bool i915_gem_request_completed(struct drm_i915_gem_request 
> *req,
> -   bool lazy_coherency)
> +static inline bool i915_gem_request_completed(struct drm_i915_gem_request 
> *req)
>  {
>   return fence_is_signaled(&req->fence);
>  }
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 1138990..93d2f32 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1165,7 +1165,7 @@ static int __i915_spin_request(struct 
> drm_i915_gem_request *req)
>  
>   timeout = jiffies + 1;
>   while (!need_resched()) {
> - if (i915_gem_request_completed(req, true))
> + if (i915_gem_request_completed(req))
>   return 0;
>  
>   if (time_after_eq(jiffies, timeout))
> @@ -1173,7 +1173,7 @@ static int __i915_spin_request(struct 
> drm_i915_gem_request *req)
>  
>   cpu_relax_lowlatency();
>   }
> - if (i915_gem_request_completed(req, false))
> + if (i915_gem_request_completed(req))
>   return 0;
>  
>   return -EAGAIN;
> @@ -1217,7 +1217,7 @@ int __i915_wait_request(struct drm_i915_gem_request 
> *req,
>   if (list_empty(&req->list))
>   return 0;
>  
> - if (i915_gem_request_completed(req, true))
> + if (i915_gem_request_completed(req))
>   return 0;
>  
>   timeout_expire = timeout ?
> @@ -1257,7 +1257,7 @@ int __i915_wait_request(struct drm_i915_gem_request 
> *req,
>   break;
>   }
>  
> - if (i915_gem_request_completed(req, false)) {
> + if (i915_gem_request_completed(req)) {
>   ret = 0;
>   break;
>   }
> @@ -2759,7 +2759,7 @@ i915_gem_find_active_request(struct intel_engine_cs 
> *ring)
>   struct drm_i915_gem_request *request;
>  
>   list_for_each_entry(request, &ring->request_list, list) {
> - if (i915_gem_request_completed(request, false))
> + if (i915_gem_request_completed(request))
>   continue;
>  
>   return request;
> @@ -2900,7 +2900,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs 
> *ring)
>  struct drm_i915_gem_request,
>  list);
>  
> - if (!i915_gem_request_completed(request, true))
> + if (!i915_gem_request_completed(request))
>   break;
>  
>   i915_gem_request_retire(request);
> @@ -2924,7 +2924,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs 
> *ring)
>   }
>  
>   if (unlikely(ring->trace_irq_req &&
> -  i915_gem_request_completed(ring->trace_irq_req, true))) {
> +  i915_gem_request_completed(ring->trace_irq_req))) {
>   ring->irq_put(ring);
>   i915_gem_request_assign(&ring->

Re: [Intel-gfx] [PATCH 1/7] drm/i915: Convert requests to use struct fence

2016-01-11 Thread Jesse Barnes
On 01/11/2016 11:03 AM, John Harrison wrote:
> On 08/01/2016 21:59, Chris Wilson wrote:
>> On Fri, Jan 08, 2016 at 06:47:22PM +, john.c.harri...@intel.com wrote:
>>> From: John Harrison 
>>>
>>> There is a construct in the linux kernel called 'struct fence' that is
>>> intended to keep track of work that is executed on hardware. I.e. it
>>> solves the basic problem that the drivers 'struct
>>> drm_i915_gem_request' is trying to address. The request structure does
>>> quite a lot more than simply track the execution progress so is very
>>> definitely still required. However, the basic completion status side
>>> could be updated to use the ready made fence implementation and gain
>>> all the advantages that provides.
>>>
>>> This patch makes the first step of integrating a struct fence into the
>>> request. It replaces the explicit reference count with that of the
>>> fence. It also replaces the 'is completed' test with the fence's
>>> equivalent. Currently, that simply chains on to the original request
>>> implementation. A future patch will improve this.
>> But this forces everyone to do the heavyweight polling until the request
>> is completed?
> Not sure what you mean by heavy weight polling. And as described, this is 
> only an intermediate step.

Just the lazy_coherency removal maybe?  Chris?

Jesse
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 21/38] drm/i915: Added a module parameter for allowing scheduler overrides

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:50PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> It can be useful to be able to disable certain features (e.g. the
> entire scheduler) via a module parameter for debugging purposes. A
> parameter has the advantage of not being a compile time switch but
> without implying that it can be changed dynamically at runtime.

> +module_param_named(scheduler_override, i915.scheduler_override, int, 0600);
> +MODULE_PARM_DESC(scheduler_override, "Scheduler override mask (0 = none, 1 = 
> direct submission [default])");

Is this consistent with the other *enable* booleans?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 10/38] drm/i915: Force MMIO flips when scheduler enabled

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:39PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> MMIO flips are the preferred mechanism now but more importantly,

Says who?

> pipe
> based flips cause issues for the scheduler. Specifically, submitting
> work to the rings around the side of the scheduler could cause that
> work to be lost if the scheduler generates a pre-emption event on that
> ring.

That just says that you haven't designed for the ability to schedule a
flip into the scheduler, including handling the priority bump that might
required to hit the deadline.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 20/38] drm/i915: Added scheduler flush calls to ring throttle and idle functions

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:49PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> When requesting that all GPU work is completed, it is now necessary to
> get the scheduler involved in order to flush out work that queued and
> not yet submitted.

But why is this needed over and above waiting on the request? Why do we
actually need to flush the work as the scheduler will get to the request
eventually (one hopes!)?  Why the priority bump? That would not be
intended for either the idle (wait until everybody has finished) or
throttling.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 12/38] drm/i915: Added scheduler hook into i915_gem_request_notify()

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:41PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> The scheduler needs to know when requests have completed so that it
> can keep its own internal state up to date and can submit new requests
> to the hardware from its queue.

Why would you reuse the user interrupt rather than introduce a
context-switch interrupt using the pipe_notify/dword_notify (yes, it can
be done by fixing up the current code). In the case of execlists you
wouldn't even need to add another interrupt vector as you could just
overload the execlists submission routine. For legacy, this would at
least let you reduce the interrupt rate from per batch to per context
switch, and keep the logic separate for user request tracking.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/skl: Use proper plane dimensions for DDB and WM calculations

2016-01-11 Thread Matt Roper
On Mon, Jan 11, 2016 at 09:31:03PM +0200, Ville Syrjälä wrote:
> On Mon, Dec 21, 2015 at 07:31:17AM -0800, Matt Roper wrote:
> > In commit
> > 
> > commit 024c9045221fe45482863c47c4b4c47d37f97cbf
> > Author: Matt Roper 
> > Date:   Thu Sep 24 15:53:11 2015 -0700
> > 
> > drm/i915/skl: Eliminate usage of pipe_wm_parameters from 
> > SKL-style WM (v4)
> > 
> > I fumbled while converting the dimensions stored in the plane_parameters
> > structure to the values stored in plane state and accidentally replaced
> > the plane dimensions with the pipe dimensions in both the DDB allocation
> > function and the WM calculation function.  On the DDB side this is
> > harmless since we effectively treat all of our non-cursor planes as
> > full-screen which may not be optimal, but generally won't cause any
> > problems either (and in 99% of the cases where there's no sprite plane
> > usage or primary plane windowing, there's no effect at all).  On the WM
> > calculation side there's more potential for this fumble to cause actual
> > problems since cursors also get miscalculated.
> > 
> > Cc: Ville Syrjälä 
> > Cc: "Kondapally, Kalyan" 
> > Cc: Radhakrishna Sripada 
> > Signed-off-by: Matt Roper 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 24 +---
> >  1 file changed, 13 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c 
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index 8d0d6f5..f4d4cc7 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2845,25 +2845,22 @@ skl_plane_relative_data_rate(const struct 
> > intel_crtc_state *cstate,
> >  const struct drm_plane_state *pstate,
> >  int y)
> >  {
> > -   struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
> > +   struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
> > struct drm_framebuffer *fb = pstate->fb;
> > +   unsigned w = drm_rect_width(&intel_pstate->dst);
> > +   unsigned h = drm_rect_height(&intel_pstate->dst);
> 
> I think you're supposed to use the src dimensions in most places.

Hmm, just went back to double check the bpsec and if I'm interpreting it
correctly, it looks like we actually need to use the larger of the two:
"Down scaling effectively increases the pixel rate. Up scaling does not
reduce the pixel rate."

Thanks for pointing that out; I'll send an updated patch.



Matt

> 
> >  
> > /* for planar format */
> > if (fb->pixel_format == DRM_FORMAT_NV12) {
> > if (y)  /* y-plane data rate */
> > -   return intel_crtc->config->pipe_src_w *
> > -   intel_crtc->config->pipe_src_h *
> > -   drm_format_plane_cpp(fb->pixel_format, 0);
> > +   return w * h * drm_format_plane_cpp(fb->pixel_format, 
> > 0);
> > else/* uv-plane data rate */
> > -   return (intel_crtc->config->pipe_src_w/2) *
> > -   (intel_crtc->config->pipe_src_h/2) *
> > +   return (w/2) * (h/2) *
> > drm_format_plane_cpp(fb->pixel_format, 1);
> > }
> >  
> > /* for packed formats */
> > -   return intel_crtc->config->pipe_src_w *
> > -   intel_crtc->config->pipe_src_h *
> > -   drm_format_plane_cpp(fb->pixel_format, 0);
> > +   return w * h * drm_format_plane_cpp(fb->pixel_format, 0);
> >  }
> >  
> >  /*
> > @@ -2960,6 +2957,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
> >  * FIXME: we may not allocate every single block here.
> >  */
> > total_data_rate = skl_get_total_relative_data_rate(cstate);
> > +   if (!total_data_rate)
> > +   return;
> >  
> > start = alloc->start;
> > for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> > @@ -3093,12 +3092,15 @@ static bool skl_compute_plane_wm(const struct 
> > drm_i915_private *dev_priv,
> >  {
> > struct drm_plane *plane = &intel_plane->base;
> > struct drm_framebuffer *fb = plane->state->fb;
> > +   struct intel_plane_state *intel_pstate =
> > +   to_intel_plane_state(plane->state);
> > uint32_t latency = dev_priv->wm.skl_latency[level];
> > uint32_t method1, method2;
> > uint32_t plane_bytes_per_line, plane_blocks_per_line;
> > uint32_t res_blocks, res_lines;
> > uint32_t selected_result;
> > uint8_t bytes_per_pixel;
> > +   unsigned w = drm_rect_width(&intel_pstate->dst);
> >  
> > if (latency == 0 || !cstate->base.active || !fb)
> > return false;
> > @@ -3109,12 +3111,12 @@ static bool skl_compute_plane_wm(const struct 
> > drm_i915_private *dev_priv,
> >  latency);
> > method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
> >  cstate->base.adjusted_mode.crtc_htotal,
> > -cstate->pipe_src_w,
> > +   

Re: [Intel-gfx] [PATCH v4 08/38] drm/i915: Prepare retire_requests to handle out-of-order seqnos

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:37PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> A major point of the GPU scheduler is that it re-orders batch buffers
> after they have been submitted to the driver. This leads to requests
> completing out of order. In turn, this means that the retire
> processing can no longer assume that all completed entries are at the
> front of the list. Rather than attempting to re-order the request list
> on a regular basis, it is better to simply scan the entire list.

This is a major misstep. Just think in terms of per-context timelines,
and retirment order within those timelines being consistent..
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 38/38] drm/i915: Allow scheduler to manage inter-ring object synchronisation

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:43:07PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> The scheduler has always tracked batch buffer dependencies based on
> DRM object usage. This means that it will not submit a batch on one
> ring that has outstanding dependencies still executing on other rings.
> This is exactly the same synchronisation performed by
> i915_gem_object_sync() using hardware semaphores where available and
> CPU stalls where not (e.g. in execlist mode and/or on Gen8 hardware).
> 
> Unfortunately, when a batch buffer is submitted to the driver the
> _object_sync() call happens first. Thus in case where hardware
> semaphores are disabled, the driver has already stalled until the
> dependency has been resolved.

But this should just add the dependency to the request in the scheduler
callback for i915_gem_object_sync_to, or better renamed as
i915_gem_request_submit_after. Without a scheduler we can do the
optimisation of doing that work inline, with a scheduler we can just
track the dependency.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 06/38] drm/i915: Re-instate request->uniq because it is extremely useful

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:35PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> The seqno value cannot always be used when debugging issues via trace
> points. This is because it can be reset back to start, especially
> during TDR type tests. Also, when the scheduler arrives the seqno is
> only valid while a given request is executing on the hardware. While
> the request is simply queued waiting for submission, it's seqno value
> will be zero (meaning invalid).

Even with per-context seqno that can be assigned before execution as we
know that requests within a context cannot be reordered?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 04/38] drm/i915: Split i915_dem_do_execbuffer() in half

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 06:42:33PM +, john.c.harri...@intel.com wrote:
> From: John Harrison 
> 
> Split the execbuffer() function in half. The first half collects and
> validates all the information required to process the batch buffer. It
> also does all the object pinning, relocations, active list management,
> etc - basically anything that must be done upfront before the IOCTL
> returns and allows the user land side to start changing/freeing
> things. The second half does the actual ring submission.

I don't get this at all. The point of requests is that GEM constructed a
request, which could be used to pass along all the implicit GEM
synchronisation points and the explict ones, along with the ringbuffer
to execute, to an engine that could then submit it. For legacy, the request
was inline and so added immediately to the ring (but that is an
implementation detail, there is nothing stopping us from using a chained
batch to implement a ring per context), for execlists the request is
queued for future execution. A scheduler was meant to sit in the middle
and determine the order in which requests were executed, but that should
be almost transparent to the high level code tracking the requests.
-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] [PATCH] drm/i915: reboot notifier delay for eDP panels

2016-01-11 Thread clinton . a . taylor
From: Clint Taylor 

Add reboot notifier for all platforms. This guarantees T12 delay
compliance during reboot cycles when pre-os enables the panel within
500ms.

Signed-off-by: Clint Taylor 
---
 drivers/gpu/drm/i915/intel_dp.c |   11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796e3d3..dbbd27a 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -126,6 +126,7 @@ static struct intel_dp *intel_attached_dp(struct 
drm_connector *connector)
 static void intel_dp_link_down(struct intel_dp *intel_dp);
 static bool edp_panel_vdd_on(struct intel_dp *intel_dp);
 static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
+static void edp_panel_off(struct intel_dp *intel_dp);
 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);
@@ -596,6 +597,10 @@ static int edp_notify_handler(struct notifier_block *this, 
unsigned long code,
I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
msleep(intel_dp->panel_power_cycle_delay);
}
+   else
+   {
+   edp_panel_off(intel_dp);
+   }
 
pps_unlock(intel_dp);
 
@@ -5796,10 +5801,10 @@ static bool intel_edp_init_connector(struct intel_dp 
*intel_dp,
}
mutex_unlock(&dev->mode_config.mutex);
 
-   if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
-   intel_dp->edp_notifier.notifier_call = edp_notify_handler;
-   register_reboot_notifier(&intel_dp->edp_notifier);
+   intel_dp->edp_notifier.notifier_call = edp_notify_handler;
+   register_reboot_notifier(&intel_dp->edp_notifier);
 
+   if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
/*
 * Figure out the current pipe for the initial backlight setup.
 * If the current pipe isn't valid, try the PPS pipe, and if 
that
-- 
1.7.9.5

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 5/6] drm/i915/huc: Add debugfs for HuC loading status check

2016-01-11 Thread yu . dai
From: Alex Dai 

Add debugfs entry for HuC loading status check.

Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index ec667f3..7676f56 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2406,6 +2406,37 @@ static int i915_llc(struct seq_file *m, void *data)
return 0;
 }
 
+static int i915_huc_load_status_info(struct seq_file *m, void *data)
+{
+   struct drm_info_node *node = m->private;
+   struct drm_i915_private *dev_priv = node->minor->dev->dev_private;
+   struct intel_uc_fw *huc_fw = &dev_priv->huc.huc_fw;
+
+   if (!HAS_HUC_UCODE(dev_priv->dev))
+   return 0;
+
+   seq_printf(m, "HuC firmware status:\n");
+   seq_printf(m, "\tpath: %s\n", huc_fw->uc_fw_path);
+   seq_printf(m, "\tfetch: %s\n",
+   intel_uc_fw_status_repr(huc_fw->fetch_status));
+   seq_printf(m, "\tload: %s\n",
+   intel_uc_fw_status_repr(huc_fw->load_status));
+   seq_printf(m, "\tversion wanted: %d.%d\n",
+   huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted);
+   seq_printf(m, "\tversion found: %d.%d\n",
+   huc_fw->major_ver_found, huc_fw->minor_ver_found);
+   seq_printf(m, "\theader: offset is %d; size = %d\n",
+   huc_fw->header_offset, huc_fw->header_size);
+   seq_printf(m, "\tuCode: offset is %d; size = %d\n",
+   huc_fw->ucode_offset, huc_fw->ucode_size);
+   seq_printf(m, "\tRSA: offset is %d; size = %d\n",
+   huc_fw->rsa_offset, huc_fw->rsa_size);
+
+   seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2));
+
+   return 0;
+}
+
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
struct drm_info_node *node = m->private;
@@ -5346,6 +5377,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_guc_info", i915_guc_info, 0},
{"i915_guc_load_status", i915_guc_load_status_info, 0},
{"i915_guc_log_dump", i915_guc_log_dump, 0},
+   {"i915_huc_load_status", i915_huc_load_status_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 6/6] drm/i915/huc: Support HuC authentication

2016-01-11 Thread yu . dai
From: Alex Dai 

The HuC authentication is done by host2guc call. The HuC RSA keys
are sent to GuC for authentication.

Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 65 ++
 drivers/gpu/drm/i915/intel_guc_fwif.h  |  1 +
 drivers/gpu/drm/i915/intel_guc_loader.c|  2 +
 3 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 8ce4f32..096b524 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -25,6 +25,7 @@
 #include 
 #include "i915_drv.h"
 #include "intel_guc.h"
+#include "intel_huc.h"
 
 /**
  * DOC: GuC-based command submission
@@ -1059,3 +1060,67 @@ int intel_guc_resume(struct drm_device *dev)
 
return host2guc_action(guc, data, ARRAY_SIZE(data));
 }
+
+/**
+ * intel_huc_ucode_auth() - authenticate ucode
+ * @dev: the drm device
+ *
+ * Triggers a HuC fw authentication request to the GuC via host-2-guc
+ * interface.
+ */
+void intel_huc_ucode_auth(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_guc *guc = &dev_priv->guc;
+   struct intel_huc *huc = &dev_priv->huc;
+   int ret;
+   u32 data[2];
+
+   /* Bypass the case where there is no HuC firmware */
+   if (huc->huc_fw.fetch_status == UC_FIRMWARE_NONE ||
+   huc->huc_fw.load_status == UC_FIRMWARE_NONE)
+   return;
+
+   if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) {
+   DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate");
+   return;
+   }
+
+   if (huc->huc_fw.load_status != UC_FIRMWARE_SUCCESS) {
+   DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate");
+   return;
+   }
+
+   ret = i915_gem_obj_ggtt_pin(huc->huc_fw.uc_fw_obj, 0, 0);
+   if (ret) {
+   DRM_ERROR("HuC: Pin failed");
+   return;
+   }
+
+   /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+   I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+   /* Specify auth action and where public signature is. It's stored
+* at the beginning of the gem object, before the fw bits
+*/
+   data[0] = HOST2GUC_ACTION_AUTHENTICATE_HUC;
+   data[1] = i915_gem_obj_ggtt_offset(huc->huc_fw.uc_fw_obj) +
+   huc->huc_fw.rsa_offset;
+
+   ret = host2guc_action(guc, data, ARRAY_SIZE(data));
+   if (ret) {
+   DRM_ERROR("HuC: GuC did not ack Auth request\n");
+   goto out;
+   }
+
+   /* Check authentication status, it should be done by now */
+   ret = wait_for_atomic(
+   (I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 5000);
+   if (ret) {
+   DRM_ERROR("HuC: Authentication failed\n");
+   goto out;
+   }
+
+out:
+   i915_gem_object_ggtt_unpin(huc->huc_fw.uc_fw_obj);
+}
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/intel_guc_fwif.h
index f8846d6..2974e33 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -429,6 +429,7 @@ enum host2guc_action {
HOST2GUC_ACTION_ENTER_S_STATE = 0x501,
HOST2GUC_ACTION_EXIT_S_STATE = 0x502,
HOST2GUC_ACTION_SLPC_REQUEST = 0x3003,
+   HOST2GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
HOST2GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 5832792..45b9c43 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -424,6 +424,8 @@ int intel_guc_ucode_load(struct drm_device *dev)
intel_uc_fw_status_repr(guc_fw->fetch_status),
intel_uc_fw_status_repr(guc_fw->load_status));
 
+   intel_huc_ucode_auth(dev);
+
if (i915.enable_guc_submission) {
/* The execbuf_client will be recreated. Release it first. */
i915_guc_submission_disable(dev);
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/6] drm/i915/guc: Bypass fw loading gracefully if GuC is not supported

2016-01-11 Thread yu . dai
From: Alex Dai 

This is to rework previous patch:

commit 9f9e539f90bcecfdc7b3679d337b7a62d4313205
Author: Daniel Vetter 
Date:   Fri Oct 23 11:10:59 2015 +0200

drm/i915: Shut up GuC errors when it's disabled

There is the case where GuC loading is needed even GuC submission
is disabled. For example, HuC loading and authentication require
GuC to be loaded regardless. In this patch, driver will try to load
the firmware only when it explicitly asks for that by specifying fw
name and version. All other cases are considered as UC_FIRMWARE_NONE
and the loading is bypassed silently.

Signed-off-by: Alex Dai 
---
 drivers/gpu/drm/i915/intel_guc_loader.c | 32 +++-
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index 70dbeb5..e11e1e8 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -594,39 +594,29 @@ void intel_guc_ucode_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw;
-   const char *fw_path;
+   const char *fw_path = NULL;
+
+   guc_fw->uc_dev = dev;
+   guc_fw->uc_fw_path = NULL;
+   guc_fw->fetch_status = UC_FIRMWARE_NONE;
+   guc_fw->load_status = UC_FIRMWARE_NONE;
 
if (!HAS_GUC_SCHED(dev))
i915.enable_guc_submission = false;
 
-   if (!HAS_GUC_UCODE(dev)) {
-   fw_path = NULL;
-   } else if (IS_SKYLAKE(dev)) {
+   if (!HAS_GUC_UCODE(dev))
+   return;
+
+   if (IS_SKYLAKE(dev)) {
fw_path = I915_SKL_GUC_UCODE;
guc_fw->major_ver_wanted = 4;
guc_fw->minor_ver_wanted = 3;
-   } else {
-   i915.enable_guc_submission = false;
-   fw_path = "";   /* unknown device */
}
 
-   if (!i915.enable_guc_submission)
-   return;
-
-   guc_fw->uc_dev = dev;
-   guc_fw->uc_fw_path = fw_path;
-   guc_fw->fetch_status = UC_FIRMWARE_NONE;
-   guc_fw->load_status = UC_FIRMWARE_NONE;
-
if (fw_path == NULL)
return;
 
-   if (*fw_path == '\0') {
-   DRM_ERROR("No GuC firmware known for this platform\n");
-   guc_fw->fetch_status = UC_FIRMWARE_FAIL;
-   return;
-   }
-
+   guc_fw->uc_fw_path = fw_path;
guc_fw->fetch_status = UC_FIRMWARE_PENDING;
DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
intel_uc_fw_fetch(dev, guc_fw);
-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 3/6] drm/i915/huc: Unified css_header struct for GuC and HuC

2016-01-11 Thread yu . dai
From: Alex Dai 

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/intel_guc.h|  4 
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++---
 drivers/gpu/drm/i915/intel_guc_loader.c | 42 +
 3 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 2324677..45f4fd3 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -59,6 +59,9 @@ enum intel_uc_fw_status {
UC_FIRMWARE_SUCCESS
 };
 
+#define UC_FW_TYPE_GUC 0
+#define UC_FW_TYPE_HUC 1
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -76,6 +79,7 @@ struct intel_uc_fw {
uint16_t major_ver_found;
uint16_t minor_ver_found;
 
+   uint32_t fw_type;
uint32_t header_size;
uint32_t header_offset;
uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/intel_guc_fwif.h
index b4632f0..f8846d6 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -146,7 +146,7 @@
  * The GuC firmware layout looks like this:
  *
  * +---+
- * |guc_css_header |
+ * | uc_css_header |
  * | contains major/minor version  |
  * +---+
  * | uCode |
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  * in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
uint32_t module_type;
/* header_size includes all non-uCode bits, including css_header, rsa
 * key, modulus key and exponent data. */
@@ -205,7 +212,10 @@ struct guc_css_header {
 
char username[8];
char buildnumber[12];
-   uint32_t device_id;
+   union {
+   uint32_t device_id;
+   uint32_t huc_sw_version;
+   };
uint32_t guc_sw_version;
uint32_t prod_preprod_fw;
uint32_t reserved[12];
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index e11e1e8..a704d80 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -464,7 +464,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct 
intel_uc_fw *uc_fw)
 {
struct drm_i915_gem_object *obj;
const struct firmware *fw;
-   struct guc_css_header *css;
+   struct uc_css_header *css;
size_t size;
int err;
 
@@ -481,19 +481,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct 
intel_uc_fw *uc_fw)
uc_fw->uc_fw_path, fw);
 
/* Check the size of the blob before examining buffer contents */
-   if (fw->size < sizeof(struct guc_css_header)) {
+   if (fw->size < sizeof(struct uc_css_header)) {
DRM_ERROR("Firmware header is missing\n");
goto fail;
}
 
-   css = (struct guc_css_header *)fw->data;
+   css = (struct uc_css_header *)fw->data;
 
/* Firmware bits always start from header */
uc_fw->header_offset = 0;
uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-   if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+   if (uc_fw->header_size != sizeof(struct uc_css_header)) {
DRM_ERROR("CSS header definition mismatch\n");
goto fail;
}
@@ -517,23 +517,35 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct 
intel_uc_fw *uc_fw)
goto fail;
}
 
-   /* Header and uCode will be loaded to WOPCM. Size of the two. */
-   size = uc_fw->header_size + uc_fw->ucode_size;
-
-   /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
-   if (size > GUC_WOPCM_SIZE_VALUE - 0x8000) {
-   DRM_ERROR("Firmware is too large to fit in WOPCM\n");
-   goto fail;
-   }
-
/*
 * The uC firmware image has the version number embedded at a w

[Intel-gfx] [PATCH 4/6] drm/i915/huc: Add HuC fw loading support

2016-01-11 Thread yu . dai
From: Alex Dai 

The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
is used for both cases.

HuC loading needs to be before GuC loading. The WOPCM setting must
be done early before loading any of them.

Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/i915_dma.c |   3 +
 drivers/gpu/drm/i915/i915_drv.h |   3 +
 drivers/gpu/drm/i915/i915_gem.c |   7 +
 drivers/gpu/drm/i915/i915_guc_reg.h |   3 +
 drivers/gpu/drm/i915/intel_guc_loader.c |   7 +-
 drivers/gpu/drm/i915/intel_huc.h|  44 ++
 drivers/gpu/drm/i915/intel_huc_loader.c | 262 
 8 files changed, 325 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc.h
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..693cc8f 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -42,6 +42,7 @@ i915-y += i915_cmd_parser.o \
 
 # general-purpose microcontroller (GuC) support
 i915-y += intel_guc_loader.o \
+ intel_huc_loader.o \
  i915_guc_submission.o
 
 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 44a896c..1b99dd3 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -410,6 +410,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
 * working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev);
 
+   intel_huc_ucode_init(dev);
intel_guc_ucode_init(dev);
 
ret = i915_gem_init(dev);
@@ -453,6 +454,7 @@ cleanup_gem:
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
 cleanup_irq:
+   intel_huc_ucode_fini(dev);
intel_guc_ucode_fini(dev);
drm_irq_uninstall(dev);
 cleanup_gem_stolen:
@@ -1194,6 +1196,7 @@ int i915_driver_unload(struct drm_device *dev)
/* Flush any outstanding unpin_work. */
flush_workqueue(dev_priv->wq);
 
+   intel_huc_ucode_fini(dev);
intel_guc_ucode_fini(dev);
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 747d2d8..15e9e59 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -53,6 +53,7 @@
 #include 
 #include 
 #include "intel_guc.h"
+#include "intel_huc.h"
 
 /* General customization:
  */
@@ -1699,6 +1700,7 @@ struct drm_i915_private {
 
struct i915_virtual_gpu vgpu;
 
+   struct intel_huc huc;
struct intel_guc guc;
 
struct intel_csr csr;
@@ -2629,6 +2631,7 @@ struct drm_i915_cmd_table {
 
 #define HAS_GUC_UCODE(dev) (IS_GEN9(dev) && !IS_KABYLAKE(dev))
 #define HAS_GUC_SCHED(dev) (IS_GEN9(dev) && !IS_KABYLAKE(dev))
+#define HAS_HUC_UCODE(dev) (IS_GEN9(dev) && !IS_KABYLAKE(dev))
 
 #define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \
INTEL_INFO(dev)->gen >= 8)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6c60e04..75de2eb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4849,6 +4849,13 @@ i915_gem_init_hw(struct drm_device *dev)
 
/* We can't enable contexts until all firmware is loaded */
if (HAS_GUC_UCODE(dev)) {
+   /* init WOPCM */
+   I915_WRITE(GUC_WOPCM_SIZE, GUC_WOPCM_SIZE_VALUE);
+   I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE |
+   HUC_LOADING_AGENT_GUC);
+
+   intel_huc_ucode_load(dev);
+
ret = intel_guc_ucode_load(dev);
if (ret) {
DRM_ERROR("Failed to initialize GuC, error %d\n", ret);
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h 
b/drivers/gpu/drm/i915/i915_guc_reg.h
index e4ba582..8d27c09 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ b/drivers/gpu/drm/i915/i915_guc_reg.h
@@ -52,9 +52,12 @@
 #define   DMA_ADDRESS_SPACE_GTT  (8 << 16)
 #define DMA_COPY_SIZE  _MMIO(0xc310)
 #define DMA_CTRL   _MMIO(0xc314)
+#define   HUC_UKERNEL(1<<9)
 #define   UOS_MOVE   (1<<4)
 #define   START_DMA  (1<<0)
 #define DMA_GUC_WOPCM_OFFSET   _MMIO(0xc340)
+#define   HUC_LOADING_AGENT_VCR  (0<<1)
+#define   HUC_LOADING_AGENT_GUC  (1<<1)
 #define   GUC_WOPCM_OFFSET_VALUE 0x8   /* 512KB */
 #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4)
 
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
b/drivers/gpu/drm/i915/intel_guc_loader.c
index a704d80..5832792 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_l

[Intel-gfx] [PATCH 0/6] Support HuC loading and authentication

2016-01-11 Thread yu . dai
From: Alex Dai 

This series of patches is to enable HuC firmware loading and authentication.
The GuC loader and css_header are unified for HuC loading.

Alex Dai (6):
  drm/i915/guc: Make the GuC fw loading helper functions general
  drm/i915/guc: Bypass fw loading gracefully if GuC is not supported
  drm/i915/huc: Unified css_header struct for GuC and HuC
  drm/i915/huc: Add HuC fw loading support
  drm/i915/huc: Add debugfs for HuC loading status check
  drm/i915/huc: Support HuC authentication

 drivers/gpu/drm/i915/Makefile  |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c|  44 -
 drivers/gpu/drm/i915/i915_dma.c|   3 +
 drivers/gpu/drm/i915/i915_drv.h|   3 +
 drivers/gpu/drm/i915/i915_gem.c|   7 +
 drivers/gpu/drm/i915/i915_guc_reg.h|   3 +
 drivers/gpu/drm/i915/i915_guc_submission.c |  65 +++
 drivers/gpu/drm/i915/intel_guc.h   |  45 ++---
 drivers/gpu/drm/i915/intel_guc_fwif.h  |  17 +-
 drivers/gpu/drm/i915/intel_guc_loader.c| 246 ++-
 drivers/gpu/drm/i915/intel_huc.h   |  44 +
 drivers/gpu/drm/i915/intel_huc_loader.c| 262 +
 12 files changed, 594 insertions(+), 146 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc.h
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

-- 
2.5.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/6] drm/i915/guc: Make the GuC fw loading helper functions general

2016-01-11 Thread yu . dai
From: Alex Dai 

Rename some of the GuC fw loading code to make them more general. We
will utilize them for HuC loading as well.
s/intel_guc_fw/intel_uc_fw/g
s/GUC_FIRMWARE/UC_FIRMWARE/g

Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
same purpose.

Signed-off-by: Alex Dai 
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/i915/i915_debugfs.c |  12 +--
 drivers/gpu/drm/i915/intel_guc.h|  39 +++
 drivers/gpu/drm/i915/intel_guc_loader.c | 181 +---
 3 files changed, 122 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e3377ab..ec667f3 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2410,7 +2410,7 @@ static int i915_guc_load_status_info(struct seq_file *m, 
void *data)
 {
struct drm_info_node *node = m->private;
struct drm_i915_private *dev_priv = node->minor->dev->dev_private;
-   struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+   struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw;
u32 tmp, i;
 
if (!HAS_GUC_UCODE(dev_priv->dev))
@@ -2418,15 +2418,15 @@ static int i915_guc_load_status_info(struct seq_file 
*m, void *data)
 
seq_printf(m, "GuC firmware status:\n");
seq_printf(m, "\tpath: %s\n",
-   guc_fw->guc_fw_path);
+   guc_fw->uc_fw_path);
seq_printf(m, "\tfetch: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+   intel_uc_fw_status_repr(guc_fw->fetch_status));
seq_printf(m, "\tload: %s\n",
-   intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+   intel_uc_fw_status_repr(guc_fw->load_status));
seq_printf(m, "\tversion wanted: %d.%d\n",
-   guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+   guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
seq_printf(m, "\tversion found: %d.%d\n",
-   guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+   guc_fw->major_ver_found, guc_fw->minor_ver_found);
seq_printf(m, "\theader: offset is %d; size = %d\n",
guc_fw->header_offset, guc_fw->header_size);
seq_printf(m, "\tuCode: offset is %d; size = %d\n",
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 045b149..2324677 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -52,29 +52,29 @@ struct i915_guc_client {
int retcode;
 };
 
-enum intel_guc_fw_status {
-   GUC_FIRMWARE_FAIL = -1,
-   GUC_FIRMWARE_NONE = 0,
-   GUC_FIRMWARE_PENDING,
-   GUC_FIRMWARE_SUCCESS
+enum intel_uc_fw_status {
+   UC_FIRMWARE_FAIL = -1,
+   UC_FIRMWARE_NONE = 0,
+   UC_FIRMWARE_PENDING,
+   UC_FIRMWARE_SUCCESS
 };
 
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
  */
-struct intel_guc_fw {
-   struct drm_device * guc_dev;
-   const char *guc_fw_path;
-   size_t  guc_fw_size;
-   struct drm_i915_gem_object *guc_fw_obj;
-   enum intel_guc_fw_statusguc_fw_fetch_status;
-   enum intel_guc_fw_statusguc_fw_load_status;
-
-   uint16_tguc_fw_major_wanted;
-   uint16_tguc_fw_minor_wanted;
-   uint16_tguc_fw_major_found;
-   uint16_tguc_fw_minor_found;
+struct intel_uc_fw {
+   struct drm_device * uc_dev;
+   const char *uc_fw_path;
+   size_t  uc_fw_size;
+   struct drm_i915_gem_object *uc_fw_obj;
+   enum intel_uc_fw_status fetch_status;
+   enum intel_uc_fw_status load_status;
+
+   uint16_t major_ver_wanted;
+   uint16_t minor_ver_wanted;
+   uint16_t major_ver_found;
+   uint16_t minor_ver_found;
 
uint32_t header_size;
uint32_t header_offset;
@@ -85,7 +85,7 @@ struct intel_guc_fw {
 };
 
 struct intel_guc {
-   struct intel_guc_fw guc_fw;
+   struct intel_uc_fw guc_fw;
uint32_t log_flags;
struct drm_i915_gem_object *log_obj;
 
@@ -114,9 +114,10 @@ struct intel_guc {
 extern void intel_guc_ucode_init(struct drm_device *dev);
 extern int intel_guc_ucode_load(struct drm_device *dev);
 extern void intel_guc_ucode_fini(struct drm_device *dev);
-extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
+extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
 extern int intel_guc_suspend(struct drm_device *dev);
 extern int intel_guc_resume(struct drm_device *dev);
+void intel_uc_fw_fetch(struct drm_device *dev, str

[Intel-gfx] [PATCH 20/22] drm/tilcdc: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

v2: Fixup misplaced hunks.

Cc: Rob Clark 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher  (v1)
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 20 
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  |  8 
 drivers/gpu/drm/tilcdc/tilcdc_drv.h  |  1 -
 3 files changed, 29 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 7d07733bdc86..4802da8e6d6f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -662,26 +662,6 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
return IRQ_HANDLED;
 }
 
-void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
-   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-   struct drm_pending_vblank_event *event;
-   struct drm_device *dev = crtc->dev;
-   unsigned long flags;
-
-   /* Destroy the pending vertical blanking event associated with the
-* pending page flip, if any, and disable vertical blanking interrupts.
-*/
-   spin_lock_irqsave(&dev->event_lock, flags);
-   event = tilcdc_crtc->event;
-   if (event && event->base.file_priv == file) {
-   tilcdc_crtc->event = NULL;
-   event->base.destroy(&event->base);
-   drm_vblank_put(dev, 0);
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
 {
struct tilcdc_crtc *tilcdc_crtc;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 4ddb21e7f52f..b39ba213e303 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -349,13 +349,6 @@ fail_free_priv:
return ret;
 }
 
-static void tilcdc_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct tilcdc_drm_private *priv = dev->dev_private;
-
-   tilcdc_crtc_cancel_page_flip(priv->crtc, file);
-}
-
 static void tilcdc_lastclose(struct drm_device *dev)
 {
struct tilcdc_drm_private *priv = dev->dev_private;
@@ -556,7 +549,6 @@ static struct drm_driver tilcdc_driver = {
.driver_features= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
.load   = tilcdc_load,
.unload = tilcdc_unload,
-   .preclose   = tilcdc_preclose,
.lastclose  = tilcdc_lastclose,
.set_busid  = drm_platform_set_busid,
.irq_handler= tilcdc_irq,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index e863ad0d26fe..66105d8dc620 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -163,7 +163,6 @@ struct tilcdc_panel_info {
 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
 
 struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev);
-void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file 
*file);
 irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc);
 void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
 void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 21/22] drm/vc4: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

v2: Fixup misplaced hunk.

Cc: Eric Anholt 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher  (v1)
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 20 
 drivers/gpu/drm/vc4/vc4_drv.c  | 10 --
 drivers/gpu/drm/vc4/vc4_drv.h  |  1 -
 3 files changed, 31 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 018145e0b87d..937409792b97 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -593,26 +593,6 @@ static const struct drm_crtc_helper_funcs 
vc4_crtc_helper_funcs = {
.atomic_flush = vc4_crtc_atomic_flush,
 };
 
-/* Frees the page flip event when the DRM device is closed with the
- * event still outstanding.
- */
-void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
-   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-   struct drm_device *dev = crtc->dev;
-   unsigned long flags;
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-
-   if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) {
-   vc4_crtc->event->base.destroy(&vc4_crtc->event->base);
-   drm_crtc_vblank_put(crtc);
-   vc4_crtc->event = NULL;
-   }
-
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static const struct vc4_crtc_data pv0_data = {
.hvs_channel = 0,
.encoder0_type = VC4_ENCODER_TYPE_DSI0,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index f1655fff8425..b7d2ff0e6e1f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -43,14 +43,6 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, 
int index)
return map;
 }
 
-static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct drm_crtc *crtc;
-
-   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-   vc4_cancel_page_flip(crtc, file);
-}
-
 static void vc4_lastclose(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -91,8 +83,6 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_HAVE_IRQ |
DRIVER_PRIME),
.lastclose = vc4_lastclose,
-   .preclose = vc4_drm_preclose,
-
.irq_handler = vc4_irq,
.irq_preinstall = vc4_irq_preinstall,
.irq_postinstall = vc4_irq_postinstall,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 080865ec2bae..4c734d087d7f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -376,7 +376,6 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
 extern struct platform_driver vc4_crtc_driver;
 int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id);
 void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id);
-void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
 
 /* vc4_debugfs.c */
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 17/22] drm/rcar: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

Cc: Laurent Pinchart 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 20 
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  2 --
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 10 --
 3 files changed, 32 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 88a4b706be16..4ec80ae1fa99 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -282,26 +282,6 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc 
*rcrtc)
  * Page Flip
  */
 
-void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,
-  struct drm_file *file)
-{
-   struct drm_pending_vblank_event *event;
-   struct drm_device *dev = rcrtc->crtc.dev;
-   unsigned long flags;
-
-   /* Destroy the pending vertical blanking event associated with the
-* pending page flip, if any, and disable vertical blanking interrupts.
-*/
-   spin_lock_irqsave(&dev->event_lock, flags);
-   event = rcrtc->event;
-   if (event && event->base.file_priv == file) {
-   rcrtc->event = NULL;
-   event->base.destroy(&event->base);
-   drm_crtc_vblank_put(&rcrtc->crtc);
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
 {
struct drm_pending_vblank_event *event;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 4b95d9d08c49..2bbe3f5aab65 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -67,8 +67,6 @@ enum rcar_du_output {
 
 int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index);
 void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable);
-void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,
-  struct drm_file *file);
 void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc);
 void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 40422f6b645e..0bb2b31555bf 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -220,15 +220,6 @@ done:
return ret;
 }
 
-static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct rcar_du_device *rcdu = dev->dev_private;
-   unsigned int i;
-
-   for (i = 0; i < rcdu->num_crtcs; ++i)
-   rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file);
-}
-
 static void rcar_du_lastclose(struct drm_device *dev)
 {
struct rcar_du_device *rcdu = dev->dev_private;
@@ -271,7 +262,6 @@ static struct drm_driver rcar_du_driver = {
| DRIVER_ATOMIC,
.load   = rcar_du_load,
.unload = rcar_du_unload,
-   .preclose   = rcar_du_preclose,
.lastclose  = rcar_du_lastclose,
.set_busid  = drm_platform_set_busid,
.get_vblank_counter = drm_vblank_no_hw_counter,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 22/22] drm/vmwgfx: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

v2: I've completely missed eaction->fpriv_head and all the related
code. We need to nuke that too to avoid accidentally deferencing the
freed-up vmwgfx-private fpriv.

v3: Also remove vmw_fpriv->fence_events and unused variables I missed.

Cc: Thomas Hellström 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Reviewed-by: Thomas Hellstrom 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   | 11 
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 52 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h |  2 --
 4 files changed, 66 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index c49812b80dd0..c96a2d2d5107 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -971,15 +971,6 @@ static int vmw_driver_unload(struct drm_device *dev)
return 0;
 }
 
-static void vmw_preclose(struct drm_device *dev,
-struct drm_file *file_priv)
-{
-   struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
-   struct vmw_private *dev_priv = vmw_priv(dev);
-
-   vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events);
-}
-
 static void vmw_postclose(struct drm_device *dev,
 struct drm_file *file_priv)
 {
@@ -1010,7 +1001,6 @@ static int vmw_driver_open(struct drm_device *dev, struct 
drm_file *file_priv)
if (unlikely(vmw_fp == NULL))
return ret;
 
-   INIT_LIST_HEAD(&vmw_fp->fence_events);
vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
if (unlikely(vmw_fp->tfile == NULL))
goto out_no_tfile;
@@ -1500,7 +1490,6 @@ static struct drm_driver driver = {
.master_set = vmw_master_set,
.master_drop = vmw_master_drop,
.open = vmw_driver_open,
-   .preclose = vmw_preclose,
.postclose = vmw_postclose,
.set_busid = drm_pci_set_busid,
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 469cdd520615..5cb1b1687cd4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -80,7 +80,6 @@
 struct vmw_fpriv {
struct drm_master *locked_master;
struct ttm_object_file *tfile;
-   struct list_head fence_events;
bool gb_aware;
 };
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index e0edf149d9d5..ac477863fc07 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -71,7 +71,6 @@ struct vmw_user_fence {
  */
 struct vmw_event_fence_action {
struct vmw_fence_action action;
-   struct list_head fpriv_head;
 
struct drm_pending_event *event;
struct vmw_fence_obj *fence;
@@ -808,44 +807,6 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void 
*data,
 }
 
 /**
- * vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects
- *
- * @fman: Pointer to a struct vmw_fence_manager
- * @event_list: Pointer to linked list of struct vmw_event_fence_action objects
- * with pointers to a struct drm_file object about to be closed.
- *
- * This function removes all pending fence events with references to a
- * specific struct drm_file object about to be closed. The caller is required
- * to pass a list of all struct vmw_event_fence_action objects with such
- * events attached. This function is typically called before the
- * struct drm_file object's event management is taken down.
- */
-void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
-   struct list_head *event_list)
-{
-   struct vmw_event_fence_action *eaction;
-   struct drm_pending_event *event;
-   unsigned long irq_flags;
-
-   while (1) {
-   spin_lock_irqsave(&fman->lock, irq_flags);
-   if (list_empty(event_list))
-   goto out_unlock;
-   eaction = list_first_entry(event_list,
-  struct vmw_event_fence_action,
-  fpriv_head);
-   list_del_init(&eaction->fpriv_head);
-   event = eaction->event;
-   eaction->event = NULL;
-   spin_unlock_irqrestore(&fman->lock, irq_flags);
-   event->destroy(event);
-   }
-out_unlock:
-   spin_unlock_irqrestore(&fman->lock, irq_flags);
-}
-
-
-/**
  * vmw_event_fence_action_seq_passed
  *
  * @action: The struct vmw_fence_action embedded in a struct
@@ -879,7 +840,6 @@ static void vmw_event_fence_action_seq_passed(struct 
vmw_fence_action *action)
*eaction->tv_usec = tv.tv_usec;
}
 
-   list_del_init(&eaction->fpriv_head);
eaction->event = NULL;
drm_send_event_locked(dev, eactio

[Intel-gfx] [PATCH 05/22] drm: Create drm_send_event helpers

2016-01-11 Thread Daniel Vetter
Use them in the core vblank code and exynos/vmwgfx drivers.

Note that the difference between wake_up_all and _interruptible in
vmwgfx doesn't matter since the only waiter is the core code in
drm_fops.c. And that is interruptible.

v2: Adjust existing kerneldoc too.

Reviewed-by: Alex Deucher  (v1)
Acked-by: Daniel Stone 
Cc: Alex Deucher 
Cc: Thomas Hellstrom 
Cc: Inki Dae 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_fops.c  | 42 -
 drivers/gpu/drm/drm_irq.c   |  7 ++
 drivers/gpu/drm/exynos/exynos_drm_g2d.c |  5 +---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c |  5 +---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c   |  3 +--
 include/drm/drmP.h  |  2 ++
 6 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 476408b638e3..d85af1b2a238 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -683,7 +683,9 @@ EXPORT_SYMBOL(drm_poll);
  * This function prepares the passed in event for eventual delivery. If the 
event
  * doesn't get delivered (because the IOCTL fails later on, before queuing up
  * anything) then the even must be cancelled and freed using
- * drm_event_cancel_free().
+ * drm_event_cancel_free(). Successfully initialized events should be sent out
+ * using drm_send_event() or drm_send_event_locked() to signal completion of 
the
+ * asynchronous event to userspace.
  *
  * If callers embedded @p into a larger structure it must be allocated with
  * kmalloc and @p must be the first member element.
@@ -739,3 +741,41 @@ void drm_event_cancel_free(struct drm_device *dev,
p->destroy(p);
 }
 EXPORT_SYMBOL(drm_event_cancel_free);
+
+/**
+ * drm_send_event_locked - send DRM event to file descriptor
+ * @dev: DRM device
+ * @e: DRM event to deliver
+ *
+ * This function sends the event @e, initialized with drm_event_reserve_init(),
+ * to its associated userspace DRM file. Callers must already hold
+ * dev->event_lock, see drm_send_event() for the unlocked version.
+ */
+void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
+{
+   assert_spin_locked(&dev->event_lock);
+
+   list_add_tail(&e->link,
+ &e->file_priv->event_list);
+   wake_up_interruptible(&e->file_priv->event_wait);
+}
+EXPORT_SYMBOL(drm_send_event_locked);
+
+/**
+ * drm_send_event - send DRM event to file descriptor
+ * @dev: DRM device
+ * @e: DRM event to deliver
+ *
+ * This function sends the event @e, initialized with drm_event_reserve_init(),
+ * to its associated userspace DRM file. This function acquires 
dev->event_lock,
+ * see drm_send_event_locked() for callers which already hold this lock.
+ */
+void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
+{
+   unsigned long irqflags;
+
+   spin_lock_irqsave(&dev->event_lock, irqflags);
+   drm_send_event_locked(dev, e);
+   spin_unlock_irqrestore(&dev->event_lock, irqflags);
+}
+EXPORT_SYMBOL(drm_send_event);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index a70b29909974..3fe8dbff6058 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -983,15 +983,12 @@ static void send_vblank_event(struct drm_device *dev,
struct drm_pending_vblank_event *e,
unsigned long seq, struct timeval *now)
 {
-   assert_spin_locked(&dev->event_lock);
-
e->event.sequence = seq;
e->event.tv_sec = now->tv_sec;
e->event.tv_usec = now->tv_usec;
 
-   list_add_tail(&e->base.link,
- &e->base.file_priv->event_list);
-   wake_up_interruptible(&e->base.file_priv->event_wait);
+   drm_send_event_locked(dev, &e->base);
+
trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
 e->event.sequence);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 82e7f95dfed9..db56c8259f18 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -893,10 +893,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 
cmdlist_no)
e->event.tv_usec = now.tv_usec;
e->event.cmdlist_no = cmdlist_no;
 
-   spin_lock_irqsave(&drm_dev->event_lock, flags);
-   list_move_tail(&e->base.link, &e->base.file_priv->event_list);
-   wake_up_interruptible(&e->base.file_priv->event_wait);
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+   drm_send_event(dev, &e->base);
 }
 
 static irqreturn_t g2d_irq_handler(int irq, void *dev_id)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c 
b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index c8819c05e2dd..1f6a6c1881d6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -1520,10 +1520,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv 
*ippdrv,
for_each_ip

[Intel-gfx] [PATCH 09/22] drm: Clean up pending events in the core

2016-01-11 Thread Daniel Vetter
There's really no reason to not do so, instead of replicating this
for every use-case and every driver. Now we can't just nuke the events,
since that would still mean that all drm_event users would need to know
when that has happened, since calling e.g. drm_send_event isn't allowed
any more. Instead just unlink them from the file, and detect this case
and handle it appropriately in all functions.

v2: Adjust existing kerneldoc too.

v3: Improve wording of the kerneldoc and split out vblank cleanup (Laurent).

Cc: Alex Deucher 
Cc: Laurent Pinchart 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher  (v1)
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_fops.c | 30 +-
 include/drm/drmP.h |  2 ++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index d85af1b2a238..109903f5b68a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -264,6 +264,7 @@ static int drm_open_helper(struct file *filp, struct 
drm_minor *minor)
INIT_LIST_HEAD(&priv->fbs);
mutex_init(&priv->fbs_lock);
INIT_LIST_HEAD(&priv->blobs);
+   INIT_LIST_HEAD(&priv->pending_event_list);
INIT_LIST_HEAD(&priv->event_list);
init_waitqueue_head(&priv->event_wait);
priv->event_space = 4096; /* set aside 4k for event buffer */
@@ -366,6 +367,13 @@ static void drm_events_release(struct drm_file *file_priv)
v->base.destroy(&v->base);
}
 
+   /* Unlink pending events */
+   list_for_each_entry_safe(e, et, &file_priv->pending_event_list,
+pending_link) {
+   list_del(&e->pending_link);
+   e->file_priv = NULL;
+   }
+
/* Remove unconsumed events */
list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
list_del(&e->link);
@@ -712,6 +720,7 @@ int drm_event_reserve_init(struct drm_device *dev,
file_priv->event_space -= e->length;
 
p->event = e;
+   list_add(&p->pending_link, &file_priv->pending_event_list);
p->file_priv = file_priv;
 
/* we *could* pass this in as arg, but everyone uses kfree: */
@@ -736,7 +745,10 @@ void drm_event_cancel_free(struct drm_device *dev,
 {
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
-   p->file_priv->event_space += p->event->length;
+   if (p->file_priv) {
+   p->file_priv->event_space += p->event->length;
+   list_del(&p->pending_link);
+   }
spin_unlock_irqrestore(&dev->event_lock, flags);
p->destroy(p);
 }
@@ -750,11 +762,22 @@ EXPORT_SYMBOL(drm_event_cancel_free);
  * This function sends the event @e, initialized with drm_event_reserve_init(),
  * to its associated userspace DRM file. Callers must already hold
  * dev->event_lock, see drm_send_event() for the unlocked version.
+ *
+ * Note that the core will take care of unlinking and disarming events when the
+ * corresponding DRM file is closed. Drivers need not worry about whether the
+ * DRM file for this event still exists and can call this function upon
+ * completion of the asynchronous work unconditionally.
  */
 void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
assert_spin_locked(&dev->event_lock);
 
+   if (!e->file_priv) {
+   e->destroy(e);
+   return;
+   }
+
+   list_del(&e->pending_link);
list_add_tail(&e->link,
  &e->file_priv->event_list);
wake_up_interruptible(&e->file_priv->event_wait);
@@ -769,6 +792,11 @@ EXPORT_SYMBOL(drm_send_event_locked);
  * This function sends the event @e, initialized with drm_event_reserve_init(),
  * to its associated userspace DRM file. This function acquires 
dev->event_lock,
  * see drm_send_event_locked() for callers which already hold this lock.
+ *
+ * Note that the core will take care of unlinking and disarming events when the
+ * corresponding DRM file is closed. Drivers need not worry about whether the
+ * DRM file for this event still exists and can call this function upon
+ * completion of the asynchronous work unconditionally.
  */
 void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
 {
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index ae73abf5c2cf..3d78a7406d54 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {
 struct drm_pending_event {
struct drm_event *event;
struct list_head link;
+   struct list_head pending_link;
struct drm_file *file_priv;
pid_t pid; /* pid of requester, no guarantee it's valid by the time
  we deliver the event, for tracing only */
@@ -346,6 +347,7 @@ struct drm_file {
struct list_head blobs;
 
wait_queue_head_t event_wait;
+   struct list_head pending_event_list;
s

[Intel-gfx] [PATCH 06/22] drm/fsl: Remove preclose hook

2016-01-11 Thread Daniel Vetter
Doesn't do anything, but annoys when auditing them all.

Cc: Jianwei Wang 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index fca97d3fc846..9648b7f9a31c 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -112,10 +112,6 @@ static int fsl_dcu_unload(struct drm_device *dev)
return 0;
 }
 
-static void fsl_dcu_drm_preclose(struct drm_device *dev, struct drm_file *file)
-{
-}
-
 static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
 {
struct drm_device *dev = arg;
@@ -191,7 +187,6 @@ static struct drm_driver fsl_dcu_drm_driver = {
| DRIVER_PRIME | DRIVER_ATOMIC,
.load   = fsl_dcu_load,
.unload = fsl_dcu_unload,
-   .preclose   = fsl_dcu_drm_preclose,
.irq_handler= fsl_dcu_drm_irq,
.get_vblank_counter = drm_vblank_no_hw_counter,
.enable_vblank  = fsl_dcu_drm_enable_vblank,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 10/22] drm: Nuke vblank event file cleanup code

2016-01-11 Thread Daniel Vetter
The core code now takes care of unlinking drm_events from the file in
a generic way, so this code isn't needed any more.

For those wondering where the drm_vblank_put went to: With the new
logic events only get unlinked, but still exist. Hence any resources
(like vblank counters) don't need to be released since the event user
will still process the event normally. In this case this is the
callsites of send_vblank_event, which of course already have a
drm_vblank_put.

Cc: Laurent Pinchart 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_fops.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 109903f5b68a..faae642390a6 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -354,19 +354,10 @@ static void drm_events_release(struct drm_file *file_priv)
 {
struct drm_device *dev = file_priv->minor->dev;
struct drm_pending_event *e, *et;
-   struct drm_pending_vblank_event *v, *vt;
unsigned long flags;
 
spin_lock_irqsave(&dev->event_lock, flags);
 
-   /* Remove pending flips */
-   list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link)
-   if (v->base.file_priv == file_priv) {
-   list_del(&v->base.link);
-   drm_vblank_put(dev, v->pipe);
-   v->base.destroy(&v->base);
-   }
-
/* Unlink pending events */
list_for_each_entry_safe(e, et, &file_priv->pending_event_list,
 pending_link) {
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/vmwgfx: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

v2: I've completely missed eaction->fpriv_head and all the related
code. We need to nuke that too to avoid accidentally deferencing the
freed-up vmwgfx-private fpriv.

v3: Also remove vmw_fpriv->fence_events and unused variables I missed.

Cc: Thomas Hellström 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Reviewed-by: Thomas Hellstrom 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   | 11 
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |  1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 52 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h |  2 --
 4 files changed, 66 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index c49812b80dd0..c96a2d2d5107 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -971,15 +971,6 @@ static int vmw_driver_unload(struct drm_device *dev)
return 0;
 }
 
-static void vmw_preclose(struct drm_device *dev,
-struct drm_file *file_priv)
-{
-   struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
-   struct vmw_private *dev_priv = vmw_priv(dev);
-
-   vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events);
-}
-
 static void vmw_postclose(struct drm_device *dev,
 struct drm_file *file_priv)
 {
@@ -1010,7 +1001,6 @@ static int vmw_driver_open(struct drm_device *dev, struct 
drm_file *file_priv)
if (unlikely(vmw_fp == NULL))
return ret;
 
-   INIT_LIST_HEAD(&vmw_fp->fence_events);
vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
if (unlikely(vmw_fp->tfile == NULL))
goto out_no_tfile;
@@ -1500,7 +1490,6 @@ static struct drm_driver driver = {
.master_set = vmw_master_set,
.master_drop = vmw_master_drop,
.open = vmw_driver_open,
-   .preclose = vmw_preclose,
.postclose = vmw_postclose,
.set_busid = drm_pci_set_busid,
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 469cdd520615..5cb1b1687cd4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -80,7 +80,6 @@
 struct vmw_fpriv {
struct drm_master *locked_master;
struct ttm_object_file *tfile;
-   struct list_head fence_events;
bool gb_aware;
 };
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index e0edf149d9d5..ac477863fc07 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -71,7 +71,6 @@ struct vmw_user_fence {
  */
 struct vmw_event_fence_action {
struct vmw_fence_action action;
-   struct list_head fpriv_head;
 
struct drm_pending_event *event;
struct vmw_fence_obj *fence;
@@ -808,44 +807,6 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void 
*data,
 }
 
 /**
- * vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects
- *
- * @fman: Pointer to a struct vmw_fence_manager
- * @event_list: Pointer to linked list of struct vmw_event_fence_action objects
- * with pointers to a struct drm_file object about to be closed.
- *
- * This function removes all pending fence events with references to a
- * specific struct drm_file object about to be closed. The caller is required
- * to pass a list of all struct vmw_event_fence_action objects with such
- * events attached. This function is typically called before the
- * struct drm_file object's event management is taken down.
- */
-void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
-   struct list_head *event_list)
-{
-   struct vmw_event_fence_action *eaction;
-   struct drm_pending_event *event;
-   unsigned long irq_flags;
-
-   while (1) {
-   spin_lock_irqsave(&fman->lock, irq_flags);
-   if (list_empty(event_list))
-   goto out_unlock;
-   eaction = list_first_entry(event_list,
-  struct vmw_event_fence_action,
-  fpriv_head);
-   list_del_init(&eaction->fpriv_head);
-   event = eaction->event;
-   eaction->event = NULL;
-   spin_unlock_irqrestore(&fman->lock, irq_flags);
-   event->destroy(event);
-   }
-out_unlock:
-   spin_unlock_irqrestore(&fman->lock, irq_flags);
-}
-
-
-/**
  * vmw_event_fence_action_seq_passed
  *
  * @action: The struct vmw_fence_action embedded in a struct
@@ -879,7 +840,6 @@ static void vmw_event_fence_action_seq_passed(struct 
vmw_fence_action *action)
*eaction->tv_usec = tv.tv_usec;
}
 
-   list_del_init(&eaction->fpriv_head);
eaction->event = NULL;
drm_send_event_locked(dev, eactio

[Intel-gfx] [PATCH 14/22] drm/imx: Unconfuse preclose logic

2016-01-11 Thread Daniel Vetter
So this one is special, since it tries to prevent races when userspace
crashes simply by disabling the vblank machinery. Well except that imx
always has vblanks enabled, and the disable_vblank hook actually just
tries to cancel a pending pageflip. Without any locking whatsoever. Of
course this is wrong, since it'll result in the hw not actually
displaying what drm thinks is the current frontbuffer.

Well since the core takes care of the disappearing DRM fd now. So we
can nuke all this confused code without ill side-effects.

Someone else needs to audit the locking for ->newfb and
->page_flip_event and fix it up. Common approach is to reuse
dev->event_lock for this.

Cc: Sascha Hauer 
Cc: Philipp Zabel 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/imx/imx-drm-core.c | 13 -
 drivers/gpu/drm/imx/ipuv3-crtc.c   |  4 
 2 files changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c 
b/drivers/gpu/drm/imx/imx-drm-core.c
index 7be7ac808304..ff94ca4a2c1e 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -171,18 +171,6 @@ static void imx_drm_disable_vblank(struct drm_device *drm, 
unsigned int pipe)
imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
 }
 
-static void imx_drm_driver_preclose(struct drm_device *drm,
-   struct drm_file *file)
-{
-   int i;
-
-   if (!file->is_master)
-   return;
-
-   for (i = 0; i < MAX_CRTC; i++)
-   imx_drm_disable_vblank(drm, i);
-}
-
 static const struct file_operations imx_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -462,7 +450,6 @@ static struct drm_driver imx_drm_driver = {
.load   = imx_drm_driver_load,
.unload = imx_drm_driver_unload,
.lastclose  = imx_drm_driver_lastclose,
-   .preclose   = imx_drm_driver_preclose,
.set_busid  = drm_platform_set_busid,
.gem_free_object= drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 30a57185bdb4..846b5f558897 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -285,10 +285,6 @@ static int ipu_enable_vblank(struct drm_crtc *crtc)
 
 static void ipu_disable_vblank(struct drm_crtc *crtc)
 {
-   struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-   ipu_crtc->page_flip_event = NULL;
-   ipu_crtc->newfb = NULL;
 }
 
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 08/22] drm/gma500: Remove empty preclose hook

2016-01-11 Thread Daniel Vetter
I'm auditing them all, empty ones just confuse ...

Cc: Patrik Jakobsson 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/gma500/psb_drv.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 92e7e5795398..4e1c6850520e 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -442,14 +442,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned 
int cmd,
/* FIXME: do we need to wrap the other side of this */
 }
 
-/*
- * When a client dies:
- *- Check for and clean up flipped page state
- */
-static void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
-{
-}
-
 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
return drm_get_pci_dev(pdev, ent, &driver);
@@ -495,7 +487,6 @@ static struct drm_driver driver = {
.load = psb_driver_load,
.unload = psb_driver_unload,
.lastclose = psb_driver_lastclose,
-   .preclose = psb_driver_preclose,
.set_busid = drm_pci_set_busid,
 
.num_ioctls = ARRAY_SIZE(psb_ioctls),
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 12/22] drm/atmel: Nuke preclose

2016-01-11 Thread Daniel Vetter
The only thing this did was cancle pending flip events, and the core
takes care of that now.

Cc: Boris Brezillon 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 18 --
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c   | 10 --
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h   |  3 ---
 3 files changed, 31 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 468a14f266a7..9863291a9a54 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -280,24 +280,6 @@ static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c)
kfree(crtc);
 }
 
-void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *c,
-  struct drm_file *file)
-{
-   struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
-   struct drm_pending_vblank_event *event;
-   struct drm_device *dev = c->dev;
-   unsigned long flags;
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-   event = crtc->event;
-   if (event && event->base.file_priv == file) {
-   event->base.destroy(&event->base);
-   drm_vblank_put(dev, crtc->id);
-   crtc->event = NULL;
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc)
 {
struct drm_device *dev = crtc->base.dev;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index a45b32ba029e..3d8d16402d07 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -619,15 +619,6 @@ static void atmel_hlcdc_dc_connector_unplug_all(struct 
drm_device *dev)
mutex_unlock(&dev->mode_config.mutex);
 }
 
-static void atmel_hlcdc_dc_preclose(struct drm_device *dev,
-   struct drm_file *file)
-{
-   struct drm_crtc *crtc;
-
-   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-   atmel_hlcdc_crtc_cancel_page_flip(crtc, file);
-}
-
 static void atmel_hlcdc_dc_lastclose(struct drm_device *dev)
 {
struct atmel_hlcdc_dc *dc = dev->dev_private;
@@ -698,7 +689,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
   DRIVER_MODESET | DRIVER_PRIME |
   DRIVER_ATOMIC,
-   .preclose = atmel_hlcdc_dc_preclose,
.lastclose = atmel_hlcdc_dc_lastclose,
.irq_handler = atmel_hlcdc_dc_irq_handler,
.irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index cf6b375bc38d..fed517f297da 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -152,9 +152,6 @@ int atmel_hlcdc_plane_prepare_disc_area(struct 
drm_crtc_state *c_state);
 
 void atmel_hlcdc_crtc_irq(struct drm_crtc *c);
 
-void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *crtc,
-  struct drm_file *file);
-
 void atmel_hlcdc_crtc_suspend(struct drm_crtc *crtc);
 void atmel_hlcdc_crtc_resume(struct drm_crtc *crtc);
 
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 19/22] drm/tegra: Stop cancelling page flip events

2016-01-11 Thread Daniel Vetter
The core takes care of that now.

v2: Fixup misplaced hunk.

Cc: Thierry Reding 
Cc: Terje Bergström 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/tegra/dc.c  | 17 -
 drivers/gpu/drm/tegra/drm.c |  3 ---
 drivers/gpu/drm/tegra/drm.h |  1 -
 3 files changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index dde6f208c347..fb2b4b0271a2 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -988,23 +988,6 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
spin_unlock_irqrestore(&drm->event_lock, flags);
 }
 
-void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
-{
-   struct tegra_dc *dc = to_tegra_dc(crtc);
-   struct drm_device *drm = crtc->dev;
-   unsigned long flags;
-
-   spin_lock_irqsave(&drm->event_lock, flags);
-
-   if (dc->event && dc->event->base.file_priv == file) {
-   dc->event->base.destroy(&dc->event->base);
-   drm_crtc_vblank_put(crtc);
-   dc->event = NULL;
-   }
-
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void tegra_dc_destroy(struct drm_crtc *crtc)
 {
drm_crtc_cleanup(crtc);
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index c5c856a0879d..021d0e1398fb 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -860,9 +860,6 @@ static void tegra_drm_preclose(struct drm_device *drm, 
struct drm_file *file)
struct tegra_drm_context *context, *tmp;
struct drm_crtc *crtc;
 
-   list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-   tegra_dc_cancel_page_flip(crtc, file);
-
list_for_each_entry_safe(context, tmp, &fpriv->contexts, list)
tegra_drm_context_free(context);
 
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index c088f2f67eda..8a10f5b7d9dc 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -195,7 +195,6 @@ struct tegra_dc_window {
 u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc);
 void tegra_dc_enable_vblank(struct tegra_dc *dc);
 void tegra_dc_disable_vblank(struct tegra_dc *dc);
-void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
 void tegra_dc_commit(struct tegra_dc *dc);
 int tegra_dc_state_setup_clock(struct tegra_dc *dc,
   struct drm_crtc_state *crtc_state,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 15/22] drm/msm: Nuke preclose hooks

2016-01-11 Thread Daniel Vetter
They only complete the page flip events to avoid oops when the drm
file closes. The core takes care of that now and we can remove this
code.

Cc: Rob Clark 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c |  7 ---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c  | 11 ---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h  |  1 -
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c |  6 --
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c  | 11 ---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h  |  1 -
 6 files changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
index 28df397c3b04..909d74250de7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
@@ -575,13 +575,6 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc)
return mdp4_crtc->vblank.irqmask;
 }
 
-void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file 
*file)
-{
-   struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
-   DBG("%s: cancel: %p", mdp4_crtc->name, file);
-   complete_flip(crtc, file);
-}
-
 /* set dma config, ie. the format the encoder wants. */
 void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config)
 {
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 5a8e3d6bcbff..1c8e330f8d98 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -179,16 +179,6 @@ static long mdp4_round_pixclk(struct msm_kms *kms, 
unsigned long rate,
}
 }
 
-static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
-{
-   struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-   struct msm_drm_private *priv = mdp4_kms->dev->dev_private;
-   unsigned i;
-
-   for (i = 0; i < priv->num_crtcs; i++)
-   mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file);
-}
-
 static void mdp4_destroy(struct msm_kms *kms)
 {
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
@@ -213,7 +203,6 @@ static const struct mdp_kms_funcs kms_funcs = {
.wait_for_crtc_commit_done = mdp4_wait_for_crtc_commit_done,
.get_format  = mdp_get_format,
.round_pixclk= mdp4_round_pixclk,
-   .preclose= mdp4_preclose,
.destroy = mdp4_destroy,
},
.set_irqmask = mdp4_set_irqmask,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
index d2c96ef431f4..9ec53b464662 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
@@ -199,7 +199,6 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
enum mdp4_pipe pipe_id, bool private_plane);
 
 uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
-void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file 
*file);
 void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
 void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
 void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 20cee5ce4071..46682aa8870c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -721,12 +721,6 @@ uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc)
return mdp5_crtc->vblank.irqmask;
 }
 
-void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file 
*file)
-{
-   DBG("cancel: %p", file);
-   complete_flip(crtc, file);
-}
-
 void mdp5_crtc_set_pipeline(struct drm_crtc *crtc,
struct mdp5_interface *intf, struct mdp5_ctl *ctl)
 {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index e115318402bd..5e4d16b399c7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -117,16 +117,6 @@ static int mdp5_set_split_display(struct msm_kms *kms,
return mdp5_encoder_set_split_display(encoder, slave_encoder);
 }
 
-static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file)
-{
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-   struct msm_drm_private *priv = mdp5_kms->dev->dev_private;
-   unsigned i;
-
-   for (i = 0; i < priv->num_crtcs; i++)
-   mdp5_crtc_cancel_pending_flip(priv->crtcs[i], file);
-}
-
 static void mdp5_destroy(struct msm_kms *kms)
 {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -164,7 +154,6 @@ static const struct mdp_kms_funcs kms_funcs = {
.get_format  = mdp_get_format,
.round_pixclk= mdp5_round_pixclk,
.set_split_display = mdp5_set_split_display,
-   .preclose= mdp5_pr

[Intel-gfx] [PATCH 02/22] drm: Add functions to setup/tear down drm_events.

2016-01-11 Thread Daniel Vetter
An attempt at not spreading out the file_priv->event_space stuff out
quite so far and wide.  And I think fixes something in ipp_get_event()
that is broken (or if they are doing something more weird/subtle, then
breaks it in a fun way).

Based upon a patch from Rob Clark, rebased and polished.

v2: Spelling fixes (Alex).

Cc: Alex Deucher 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Cc: Rob Clark 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c | 44 -
 drivers/gpu/drm/drm_crtc.c   | 36 +++-
 drivers/gpu/drm/drm_fops.c   | 67 
 include/drm/drmP.h   |  7 -
 4 files changed, 94 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3f74193885f1..8fb469c4e4b8 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1347,44 +1347,23 @@ static struct drm_pending_vblank_event 
*create_vblank_event(
struct drm_device *dev, struct drm_file *file_priv, uint64_t 
user_data)
 {
struct drm_pending_vblank_event *e = NULL;
-   unsigned long flags;
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-   if (file_priv->event_space < sizeof e->event) {
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-   goto out;
-   }
-   file_priv->event_space -= sizeof e->event;
-   spin_unlock_irqrestore(&dev->event_lock, flags);
+   int ret;
 
e = kzalloc(sizeof *e, GFP_KERNEL);
-   if (e == NULL) {
-   spin_lock_irqsave(&dev->event_lock, flags);
-   file_priv->event_space += sizeof e->event;
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-   goto out;
-   }
+   if (!e)
+   return NULL;
 
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
-   e->event.base.length = sizeof e->event;
+   e->event.base.length = sizeof(e->event);
e->event.user_data = user_data;
-   e->base.event = &e->event.base;
-   e->base.file_priv = file_priv;
-   e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
-
-out:
-   return e;
-}
 
-static void destroy_vblank_event(struct drm_device *dev,
-   struct drm_file *file_priv, struct drm_pending_vblank_event *e)
-{
-   unsigned long flags;
+   ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
+   if (ret) {
+   kfree(e);
+   return NULL;
+   }
 
-   spin_lock_irqsave(&dev->event_lock, flags);
-   file_priv->event_space += sizeof e->event;
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-   kfree(e);
+   return e;
 }
 
 static int atomic_set_prop(struct drm_atomic_state *state,
@@ -1646,8 +1625,7 @@ out:
if (!crtc_state->event)
continue;
 
-   destroy_vblank_event(dev, file_priv,
-crtc_state->event);
+   drm_event_cancel_free(dev, &crtc_state->event->base);
}
}
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1e75a145834a..60a4184d41b7 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5264,7 +5264,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_framebuffer *fb = NULL;
struct drm_pending_vblank_event *e = NULL;
-   unsigned long flags;
int ret = -EINVAL;
 
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
@@ -5315,41 +5314,26 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
 
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
-   ret = -ENOMEM;
-   spin_lock_irqsave(&dev->event_lock, flags);
-   if (file_priv->event_space < sizeof(e->event)) {
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-   goto out;
-   }
-   file_priv->event_space -= sizeof(e->event);
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-
-   e = kzalloc(sizeof(*e), GFP_KERNEL);
-   if (e == NULL) {
-   spin_lock_irqsave(&dev->event_lock, flags);
-   file_priv->event_space += sizeof(e->event);
-   spin_unlock_irqrestore(&dev->event_lock, flags);
+   e = kzalloc(sizeof *e, GFP_KERNEL);
+   if (!e) {
+   ret = -ENOMEM;
goto out;
}
-
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
e->event.base.length = sizeof(e->event);
e->event.user_data = page_flip->user_data;
-   e->base.event = &e->event.base;
-   e->base.file_priv = file_priv;
-   e->base.destroy 

[Intel-gfx] [PATCH 04/22] drm/vmwgfx: Use the new event init/free functions

2016-01-11 Thread Daniel Vetter
Cc: Rob Clark 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 32 
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 8e689b439890..eda93bf52a6e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -1025,38 +1025,26 @@ static int vmw_event_fence_action_create(struct 
drm_file *file_priv,
struct vmw_event_fence_pending *event;
struct vmw_fence_manager *fman = fman_from_fence(fence);
struct drm_device *dev = fman->dev_priv->dev;
-   unsigned long irq_flags;
int ret;
 
-   spin_lock_irqsave(&dev->event_lock, irq_flags);
-
-   ret = (file_priv->event_space < sizeof(event->event)) ? -EBUSY : 0;
-   if (likely(ret == 0))
-   file_priv->event_space -= sizeof(event->event);
-
-   spin_unlock_irqrestore(&dev->event_lock, irq_flags);
-
-   if (unlikely(ret != 0)) {
-   DRM_ERROR("Failed to allocate event space for this file.\n");
-   goto out_no_space;
-   }
-
-
event = kzalloc(sizeof(*event), GFP_KERNEL);
if (unlikely(event == NULL)) {
DRM_ERROR("Failed to allocate an event.\n");
ret = -ENOMEM;
-   goto out_no_event;
+   goto out_no_space;
}
 
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
event->event.base.length = sizeof(*event);
event->event.user_data = user_data;
 
-   event->base.event = &event->event.base;
-   event->base.file_priv = file_priv;
-   event->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+   ret = drm_event_reserve_init(dev, file_priv, &event->base, 
&event->event.base);
 
+   if (unlikely(ret != 0)) {
+   DRM_ERROR("Failed to allocate event space for this file.\n");
+   kfree(event);
+   goto out_no_space;
+   }
 
if (flags & DRM_VMW_FE_FLAG_REQ_TIME)
ret = vmw_event_fence_action_queue(file_priv, fence,
@@ -1076,11 +1064,7 @@ static int vmw_event_fence_action_create(struct drm_file 
*file_priv,
return 0;
 
 out_no_queue:
-   event->base.destroy(&event->base);
-out_no_event:
-   spin_lock_irqsave(&dev->event_lock, irq_flags);
-   file_priv->event_space += sizeof(*event);
-   spin_unlock_irqrestore(&dev->event_lock, irq_flags);
+   drm_event_cancel_free(dev, &event->base);
 out_no_space:
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 07/22] drm/armada: Remove NULL open/pre/postclose hooks

2016-01-11 Thread Daniel Vetter
The compiler will do this, but the void hits when grepping all the
hooks for a subsystem wide audit are slightly annoying. So remove them
for next time around.

Cc: Russell King 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/armada/armada_drv.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_drv.c 
b/drivers/gpu/drm/armada/armada_drv.c
index 3bd7e1cde99e..82043c204b76 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -188,9 +188,6 @@ static const struct file_operations armada_drm_fops = {
 
 static struct drm_driver armada_drm_driver = {
.load   = armada_drm_load,
-   .open   = NULL,
-   .preclose   = NULL,
-   .postclose  = NULL,
.lastclose  = armada_drm_lastclose,
.unload = armada_drm_unload,
.set_busid  = drm_platform_set_busid,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 18/22] drm/shmob: Nuke preclose hook

2016-01-11 Thread Daniel Vetter
Again since the drm core takes care of event unlinking/disarming this
is now just needless code.

v2: Fixup misplaced hunk.

Cc: Laurent Pinchart 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher  (v1)
Reviewed-by: Laurent Pinchart 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 20 
 drivers/gpu/drm/shmobile/shmob_drm_crtc.h |  2 --
 drivers/gpu/drm/shmobile/shmob_drm_drv.c  |  8 
 3 files changed, 30 deletions(-)

diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c 
b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index b80802f55143..de7959a60774 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -438,26 +438,6 @@ static const struct drm_crtc_helper_funcs 
crtc_helper_funcs = {
.mode_set_base = shmob_drm_crtc_mode_set_base,
 };
 
-void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc,
-struct drm_file *file)
-{
-   struct drm_pending_vblank_event *event;
-   struct drm_device *dev = scrtc->crtc.dev;
-   unsigned long flags;
-
-   /* Destroy the pending vertical blanking event associated with the
-* pending page flip, if any, and disable vertical blanking interrupts.
-*/
-   spin_lock_irqsave(&dev->event_lock, flags);
-   event = scrtc->event;
-   if (event && event->base.file_priv == file) {
-   scrtc->event = NULL;
-   event->base.destroy(&event->base);
-   drm_vblank_put(dev, 0);
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
 {
struct drm_pending_vblank_event *event;
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h 
b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h
index eddad6dcc88a..38ed4ff8aaf2 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h
@@ -47,8 +47,6 @@ struct shmob_drm_connector {
 
 int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
 void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev, bool enable);
-void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc,
-struct drm_file *file);
 void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc);
 void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc);
 void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c 
b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index 04e66e3751b4..7700ff172079 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -200,13 +200,6 @@ done:
return ret;
 }
 
-static void shmob_drm_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct shmob_drm_device *sdev = dev->dev_private;
-
-   shmob_drm_crtc_cancel_page_flip(&sdev->crtc, file);
-}
-
 static irqreturn_t shmob_drm_irq(int irq, void *arg)
 {
struct drm_device *dev = arg;
@@ -266,7 +259,6 @@ static struct drm_driver shmob_drm_driver = {
| DRIVER_PRIME,
.load   = shmob_drm_load,
.unload = shmob_drm_unload,
-   .preclose   = shmob_drm_preclose,
.set_busid  = drm_platform_set_busid,
.irq_handler= shmob_drm_irq,
.get_vblank_counter = drm_vblank_no_hw_counter,
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 11/22] drm/i915: Nuke intel_modeset_preclose

2016-01-11 Thread Daniel Vetter
Now that the drm core unlinks/disarms events there's no need to do so
ourselves anymore. Nuke the code.

Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_dma.c  |  2 --
 drivers/gpu/drm/i915/intel_display.c | 21 -
 drivers/gpu/drm/i915/intel_drv.h |  1 -
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a0f5659032fc..4bfa72e5a217 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1262,8 +1262,6 @@ void i915_driver_preclose(struct drm_device *dev, struct 
drm_file *file)
i915_gem_context_close(dev, file);
i915_gem_release(dev, file);
mutex_unlock(&dev->struct_mutex);
-
-   intel_modeset_preclose(dev, file);
 }
 
 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 86fce41281fb..ec75e260f1eb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -16357,24 +16357,3 @@ intel_display_print_error_state(struct 
drm_i915_error_state_buf *m,
err_printf(m, "  VSYNC: %08x\n", error->transcoder[i].vsync);
}
 }
-
-void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct intel_crtc *crtc;
-
-   for_each_intel_crtc(dev, crtc) {
-   struct intel_unpin_work *work;
-
-   spin_lock_irq(&dev->event_lock);
-
-   work = crtc->unpin_work;
-
-   if (work && work->event &&
-   work->event->base.file_priv == file) {
-   kfree(work->event);
-   work->event = NULL;
-   }
-
-   spin_unlock_irq(&dev->event_lock);
-   }
-}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e88050aee0c1..5e7422085162 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1235,7 +1235,6 @@ enum intel_display_power_domain
 intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 struct intel_crtc_state *pipe_config);
-void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
 
 int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
 int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state 
*crtc_state);
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 13/22] drm/exynos: Remove event cancelling from postclose

2016-01-11 Thread Daniel Vetter
The core takes care of this now. And since kfree(NULL) is ok we can
simplify the function even further now.

Cc: Inki Dae 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 9756797a15a5..868ab9f54f17 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -335,20 +335,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
 
 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
 {
-   struct drm_pending_event *e, *et;
-   unsigned long flags;
-
-   if (!file->driver_priv)
-   return;
-
-   spin_lock_irqsave(&dev->event_lock, flags);
-   /* Release all events handled by page flip handler but not freed. */
-   list_for_each_entry_safe(e, et, &file->event_list, link) {
-   list_del(&e->link);
-   e->destroy(e);
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-
kfree(file->driver_priv);
file->driver_priv = NULL;
 }
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 16/22] drm/omap: Nuke close hooks

2016-01-11 Thread Daniel Vetter
Again since the core takes care of this we can remove them. While at
it also remove the postclose hook, it's empty.

v2: Laurent pointed me at even more code to delete.

Cc: Laurent Pinchart 
Cc: Tomi Valkeinen 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 13 +---
 drivers/gpu/drm/omapdrm/omap_drv.c  | 41 -
 drivers/gpu/drm/omapdrm/omap_drv.h  |  1 -
 3 files changed, 1 insertion(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 2ed0754ed19e..d38fcbcc43a8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -269,18 +269,7 @@ static void omap_crtc_complete_page_flip(struct drm_crtc 
*crtc)
return;
 
spin_lock_irqsave(&dev->event_lock, flags);
-
-   list_del(&event->base.link);
-
-   /*
-* Queue the event for delivery if it's still linked to a file
-* handle, otherwise just destroy it.
-*/
-   if (event->base.file_priv)
-   drm_crtc_send_vblank_event(crtc, event);
-   else
-   event->base.destroy(&event->base);
-
+   drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index dfafdb602ad2..603a65498b40 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -175,17 +175,6 @@ static int omap_atomic_commit(struct drm_device *dev,
priv->commit.pending |= commit->crtcs;
spin_unlock(&priv->commit.lock);
 
-   /* Keep track of all CRTC events to unlink them in preclose(). */
-   spin_lock_irqsave(&dev->event_lock, flags);
-   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-   struct drm_crtc_state *cstate = state->crtc_states[i];
-
-   if (cstate && cstate->event)
-   list_add_tail(&cstate->event->base.link,
- &priv->commit.events);
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-
/* Swap the state, this is the point of no return. */
drm_atomic_helper_swap_state(dev, state);
 
@@ -673,7 +662,6 @@ static int dev_load(struct drm_device *dev, unsigned long 
flags)
priv->wq = alloc_ordered_workqueue("omapdrm", 0);
init_waitqueue_head(&priv->commit.wait);
spin_lock_init(&priv->commit.lock);
-   INIT_LIST_HEAD(&priv->commit.events);
 
spin_lock_init(&priv->list_lock);
INIT_LIST_HEAD(&priv->obj_list);
@@ -787,33 +775,6 @@ static void dev_lastclose(struct drm_device *dev)
}
 }
 
-static void dev_preclose(struct drm_device *dev, struct drm_file *file)
-{
-   struct omap_drm_private *priv = dev->dev_private;
-   struct drm_pending_event *event;
-   unsigned long flags;
-
-   DBG("preclose: dev=%p", dev);
-
-   /*
-* Unlink all pending CRTC events to make sure they won't be queued up
-* by a pending asynchronous commit.
-*/
-   spin_lock_irqsave(&dev->event_lock, flags);
-   list_for_each_entry(event, &priv->commit.events, link) {
-   if (event->file_priv == file) {
-   file->event_space += event->event->length;
-   event->file_priv = NULL;
-   }
-   }
-   spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-static void dev_postclose(struct drm_device *dev, struct drm_file *file)
-{
-   DBG("postclose: dev=%p, file=%p", dev, file);
-}
-
 static const struct vm_operations_struct omap_gem_vm_ops = {
.fault = omap_gem_fault,
.open = drm_gem_vm_open,
@@ -838,8 +799,6 @@ static struct drm_driver omap_drm_driver = {
.unload = dev_unload,
.open = dev_open,
.lastclose = dev_lastclose,
-   .preclose = dev_preclose,
-   .postclose = dev_postclose,
.set_busid = drm_platform_set_busid,
.get_vblank_counter = drm_vblank_no_hw_counter,
.enable_vblank = omap_irq_enable_vblank,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 9e0030731c37..c23cbe6fe9e4 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -106,7 +106,6 @@ struct omap_drm_private {
 
/* atomic commit */
struct {
-   struct list_head events;
wait_queue_head_t wait;
u32 pending;
spinlock_t lock;/* Protects commit.pending */
-- 
2.6.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 03/22] drm/exynos: Use the new event init/free functions

2016-01-11 Thread Daniel Vetter
Also fixes a bug in IPP with not correctly checking/allocating for
space in the event space. Not a too serious bug since it's not a
real ringbuffer, just a limit to avoid too much kernel allocations.

Cc: Rob Clark 
Cc: Inki Dae 
Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 31 ---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 23 +--
 2 files changed, 17 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index c17efdb238a6..82e7f95dfed9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1072,7 +1072,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
struct drm_exynos_pending_g2d_event *e;
struct g2d_cmdlist_node *node;
struct g2d_cmdlist *cmdlist;
-   unsigned long flags;
int size;
int ret;
 
@@ -1094,21 +1093,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
node->event = NULL;
 
if (req->event_type != G2D_EVENT_NOT) {
-   spin_lock_irqsave(&drm_dev->event_lock, flags);
-   if (file->event_space < sizeof(e->event)) {
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
-   ret = -ENOMEM;
-   goto err;
-   }
-   file->event_space -= sizeof(e->event);
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
-
e = kzalloc(sizeof(*node->event), GFP_KERNEL);
if (!e) {
-   spin_lock_irqsave(&drm_dev->event_lock, flags);
-   file->event_space += sizeof(e->event);
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
-
ret = -ENOMEM;
goto err;
}
@@ -1116,9 +1102,12 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
e->event.base.type = DRM_EXYNOS_G2D_EVENT;
e->event.base.length = sizeof(e->event);
e->event.user_data = req->user_data;
-   e->base.event = &e->event.base;
-   e->base.file_priv = file;
-   e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+   ret = drm_event_reserve_init(drm_dev, file, &e->base, 
&e->event.base);
+   if (ret) {
+   kfree(e);
+   goto err;
+   }
 
node->event = e;
}
@@ -1219,12 +1208,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
 err_unmap:
g2d_unmap_cmdlist_gem(g2d, node, file);
 err_free_event:
-   if (node->event) {
-   spin_lock_irqsave(&drm_dev->event_lock, flags);
-   file->event_space += sizeof(e->event);
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
-   kfree(node->event);
-   }
+   if (node->event)
+   drm_event_cancel_free(drm_dev, &node->event->base);
 err:
g2d_put_cmdlist(g2d, node);
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c 
b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 67d24236e745..c8819c05e2dd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -618,27 +618,18 @@ static void ipp_clean_mem_nodes(struct drm_device 
*drm_dev,
mutex_unlock(&c_node->mem_lock);
 }
 
-static void ipp_free_event(struct drm_pending_event *event)
-{
-   kfree(event);
-}
-
 static int ipp_get_event(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_queue_buf *qbuf)
 {
struct drm_exynos_ipp_send_event *e;
-   unsigned long flags;
+   int ret;
 
DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id);
 
e = kzalloc(sizeof(*e), GFP_KERNEL);
-   if (!e) {
-   spin_lock_irqsave(&drm_dev->event_lock, flags);
-   c_node->filp->event_space += sizeof(e->event);
-   spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+   if (!e)
return -ENOMEM;
-   }
 
/* make event */
e->event.base.type = DRM_EXYNOS_IPP_EVENT;
@@ -646,9 +637,13 @@ static int ipp_get_event(struct drm_device *drm_dev,
e->event.user_data = qbuf->user_data;
e->event.prop_id = qbuf->prop_id;
e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id;
-   e->base.event = &e->event.base;
-   e->base.file_priv = c_node->filp;
-   e->base.destroy = ipp_free_event;
+
+   ret = drm_event_reserve_init(drm_dev, c_node->filp, &e->base, 
&e->event.base);
+   if (ret) {
+   kfree(e);
+   return ret;
+   }
+
   

[Intel-gfx] [PATCH 01/22] drm: kerneldoc for drm_fops.c

2016-01-11 Thread Daniel Vetter
Just prep work before I throw more drm_event refactorings on top.

Acked-by: Daniel Stone 
Reviewed-by: Alex Deucher 
Signed-off-by: Daniel Vetter 
---
 Documentation/DocBook/gpu.tmpl |  48 +--
 drivers/gpu/drm/drm_fops.c | 129 ++---
 include/drm/drmP.h |  17 +++---
 3 files changed, 117 insertions(+), 77 deletions(-)

diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index ea0112387f85..01467efff3f5 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -2886,52 +2886,8 @@ void (*postclose) (struct drm_device *, struct drm_file 
*);
 
 
   File Operations
-  const struct file_operations *fops
-  File operations for the DRM device node.
-  
-Drivers must define the file operations structure that forms the DRM
-   userspace API entry point, even though most of those operations are
-   implemented in the DRM core. The open,
-   release and ioctl
-   operations are handled by
-   
-   .owner = THIS_MODULE,
-   .open = drm_open,
-   .release = drm_release,
-   .unlocked_ioctl = drm_ioctl,
-  #ifdef CONFIG_COMPAT
-   .compat_ioctl = drm_compat_ioctl,
-  #endif
-
-  
-  
-Drivers that implement private ioctls that requires 32/64bit
-   compatibility support must provide their own
-   compat_ioctl handler that processes private
-   ioctls and calls drm_compat_ioctl for core ioctls.
-  
-  
-The read and poll
-   operations provide support for reading DRM events and polling them. They
-   are implemented by
-   
-   .poll = drm_poll,
-   .read = drm_read,
-   .llseek = no_llseek,
-   
-  
-  
-The memory mapping implementation varies depending on how the driver
-   manages memory. Pre-GEM drivers will use drm_mmap,
-   while GEM-aware drivers will use drm_gem_mmap. See
-   .
-   
-   .mmap = drm_gem_mmap,
-   
-  
-  
-No other file operation is supported by the DRM API.
-  
+!Pdrivers/gpu/drm/drm_fops.c file operations
+!Edrivers/gpu/drm/drm_fops.c
 
 
   IOCTLs
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 359ec13cdf9d..73075a1fa380 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -1,4 +1,4 @@
-/**
+/*
  * \file drm_fops.c
  * File operations for DRM
  *
@@ -44,6 +44,46 @@
 /* from BKL pushdown */
 DEFINE_MUTEX(drm_global_mutex);
 
+/**
+ * DOC: file operations
+ *
+ * Drivers must define the file operations structure that forms the DRM
+ * userspace API entry point, even though most of those operations are
+ * implemented in the DRM core. The mandatory functions are drm_open(),
+ * drm_read(), drm_ioctl() and drm_compat_ioctl if CONFIG_COMPAT is enabled.
+ * Drivers which implement private ioctls that require 32/64 bit compatibility
+ * support must provided their onw .compat_ioctl() handler that processes
+ * private ioctls and calls drm_compat_ioctl() for core ioctls.
+ *
+ * In addition drm_read() and drm_poll() provide support for DRM events. DRM
+ * events are a generic and extensible means to send asynchronous events to
+ * userspace through the file descriptor. They are used to send vblank event 
and
+ * page flip completions by the KMS API. But drivers can also use it for their
+ * own needs, e.g. to signal completion of rendering.
+ *
+ * The memory mapping implementation will vary depending on how the driver
+ * manages memory. Legacy drivers will use the deprecated drm_legacy_mmap()
+ * function, modern drivers should use one of the provided memory-manager
+ * specific implementations. For GEM-based drivers this is drm_gem_mmap().
+ *
+ * No other file operations are supported by the DRM userspace API. Overall the
+ * following is an example #file_operations structure:
+ *
+ * static const example_drm_fops = {
+ * .owner = THIS_MODULE,
+ * .open = drm_open,
+ * .release = drm_release,
+ * .unlocked_ioctl = drm_ioctl,
+ * #ifdef CONFIG_COMPAT
+ * .compat_ioctl = drm_compat_ioctl,
+ * #endif
+ * .poll = drm_poll,
+ * .read = drm_read,
+ * .llseek = no_llseek,
+ * .mmap = drm_gem_mmap,
+ * };
+ */
+
 static int drm_open_helper(struct file *filp, struct drm_minor *minor);
 
 static int drm_setup(struct drm_device * dev)
@@ -67,15 +107,17 @@ static int drm_setup(struct drm_device * dev)
 }
 
 /**
- * Open file.
+ * drm_open - open method for DRM file
+ * @inode: device inode
+ * @filp: file pointer.
  *
- * \param inode device inode
- * \param filp file pointer.
- * \return zero on success or a negative number on failure.
+ * This function must be used by drivers as their .open() #file_operations
+ * method. It looks up the correct DRM device and instantiates all the per-file
+ * resources f

[Intel-gfx] [PATCH 00/22] drm_event cleanup, round 2

2016-01-11 Thread Daniel Vetter
Hi all,

Mostly just small changes from review feedback (plus a few misplaced hunks,
silly me). Plus an attempt at better kerneldoc to explain how this works. Since
that caused questions both from Thomas and Laurent let me explain things also
here:

Currently anyone using drm_events (vblank code, atomic/legacy flips, drivers
like exynos) need to handle event setup, sending to the drm file and handling
when the drm file disappears themselves. This patch series provides functions to
encapsulate all these steps. Furthermore the file closing is handled
differently: Events are no longer completely destroyed in preclose hooks like
all current users do, but instead they're just unlinked from the file. The new
drm_send_event can still be called, but instead of transmitting the event to the
file it'll destroy it right away.

This means that when the drm file disappears it's entirely transparent to
drivers, and we can remove all the special tracking and cleanup code around
preclose functions.

The other consequence is that it's opt-in - drivers are still free to remove
events explicitly when the file disappears, it's just needless code. Which means
the patch series can be split up really nicely into core parts + driver patches.
The only patch I didn't split up in this fashion is the one that creates
drm_send_event - it's imo easier to review this way, and the driver changes are
really simple.

Cheers, Daniel

Daniel Vetter (22):
  drm: kerneldoc for drm_fops.c
  drm: Add functions to setup/tear down drm_events.
  drm/exynos: Use the new event init/free functions
  drm/vmwgfx: Use the new event init/free functions
  drm: Create drm_send_event helpers
  drm/fsl: Remove preclose hook
  drm/armada: Remove NULL open/pre/postclose hooks
  drm/gma500: Remove empty preclose hook
  drm: Clean up pending events in the core
  drm: Nuke vblank event file cleanup code
  drm/i915: Nuke intel_modeset_preclose
  drm/atmel: Nuke preclose
  drm/exynos: Remove event cancelling from postclose
  drm/imx: Unconfuse preclose logic
  drm/msm: Nuke preclose hooks
  drm/omap: Nuke close hooks
  drm/rcar: Nuke preclose hook
  drm/shmob: Nuke preclose hook
  drm/tegra: Stop cancelling page flip events
  drm/tilcdc: Nuke preclose hook
  drm/vc4: Nuke preclose hook
  drm/vmwgfx: Nuke preclose hook

 Documentation/DocBook/gpu.tmpl |  48 +
 drivers/gpu/drm/armada/armada_drv.c|   3 -
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c |  18 --
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c   |  10 -
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h   |   3 -
 drivers/gpu/drm/drm_atomic.c   |  44 +---
 drivers/gpu/drm/drm_crtc.c |  36 +---
 drivers/gpu/drm/drm_fops.c | 271 ++---
 drivers/gpu/drm/drm_irq.c  |   7 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c|  14 --
 drivers/gpu/drm/exynos/exynos_drm_g2d.c|  36 +---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c|  28 +--
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  |   5 -
 drivers/gpu/drm/gma500/psb_drv.c   |   9 -
 drivers/gpu/drm/i915/i915_dma.c|   2 -
 drivers/gpu/drm/i915/intel_display.c   |  21 --
 drivers/gpu/drm/i915/intel_drv.h   |   1 -
 drivers/gpu/drm/imx/imx-drm-core.c |  13 --
 drivers/gpu/drm/imx/ipuv3-crtc.c   |   4 -
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c   |   7 -
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c|  11 -
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h|   1 -
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c   |   6 -
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c|  11 -
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h|   1 -
 drivers/gpu/drm/omapdrm/omap_crtc.c|  13 +-
 drivers/gpu/drm/omapdrm/omap_drv.c |  41 
 drivers/gpu/drm/omapdrm/omap_drv.h |   1 -
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  20 --
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |   2 -
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  |  10 -
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c  |  20 --
 drivers/gpu/drm/shmobile/shmob_drm_crtc.h  |   2 -
 drivers/gpu/drm/shmobile/shmob_drm_drv.c   |   8 -
 drivers/gpu/drm/tegra/dc.c |  17 --
 drivers/gpu/drm/tegra/drm.c|   3 -
 drivers/gpu/drm/tegra/drm.h|   1 -
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c   |  20 --
 drivers/gpu/drm/tilcdc/tilcdc_drv.c|   8 -
 drivers/gpu/drm/tilcdc/tilcdc_drv.h|   1 -
 drivers/gpu/drm/vc4/vc4_crtc.c |  20 --
 drivers/gpu/drm/vc4/vc4_drv.c  |  10 -
 drivers/gpu/drm/vc4/vc4_drv.h  |   1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c|  11 -
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|   1 -
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c  |  87 +---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h  |   2 -
 includ

Re: [Intel-gfx] [PATCH 07/10] drm/i915: Support for pread/pwrite from/to non shmem backed objects

2016-01-11 Thread Chris Wilson
On Mon, Jan 11, 2016 at 05:15:54PM +, Tvrtko Ursulin wrote:
> > Is that not what was written? I take it my telepathy isn't working
> > again.
> 
> Sorry not a new loop, new case in a old loop. This is the hunk I think
> is not helping readability:
> 
> @@ -869,11 +967,29 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915,
>   /* If we get a fault while copying data, then (presumably) our
>* source page isn't available.  Return the error and we'll
>* retry in the slow path.
> +  * If the object is non-shmem backed, we retry again with the
> +  * path that handles page fault.
>*/
> - if (fast_user_write(i915->gtt.mappable, page_base,
> - page_offset, user_data, page_length)) {
> - ret = -EFAULT;
> - goto out_flush;
> + if (faulted || fast_user_write(i915->gtt.mappable,
> + page_base, page_offset,
> + user_data, page_length)) {
> + if (!obj->base.filp) {

This is just wrong, we neither need the faulted nor the difference in
behaviour based on storage.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/6] drm: Create Color Management DRM properties

2016-01-11 Thread Daniel Stone
Hi,

On 5 January 2016 at 10:23, Daniel Vetter  wrote:
> On Wed, Dec 23, 2015 at 09:47:00AM +, Daniel Stone wrote:
>> It's not even a legacy vs. atomic thing, this can happen in
>> pure-atomic as well. Same as the render-compression plane property
>> that I just replied to here as well.
>>
>> - Weston starts and sets up palette/CTM properties
>> - VT switch to Mutter, which isn't aware of new properties
>> - Mutter atomically sets new plane state, containing framebuffer which
>> is already colour-corrected for the target
>> - result is now double-corrected as Mutter didn't know to unset the
>> old properties
>>
>> IOW, in the current model, any user of CM has to explicitly unset it
>> before handover (not always actually possible), or any generic
>> userspace must unset every property it sees and doesn't know about,
>> hoping that setting to 0 will do the right thing.
>>
>> Or we could add another client cap, which would prevent the CM
>> properties from ever being exposed to userspace which doesn't know how
>> to work with it. Passing the client caps through to
>> plane_duplicate_state also means that we can unset the CM properties
>> at this early point for unaware clients. This would mean that we
>> wouldn't have to have code to explicitly unset it in, e.g., every
>> legacy hook.
>
> We don't have any support for unsetting anything really. Same argument you
> make for CM here applies to rotation too. The only generic solution (if
> you really care about this) would be for logind to once sample all atomic
> state on boot-up, and force-restore that state when switching. Restoring
> atomic state doesn't require userspace to understanding the semantics
> really.

Sure, but on the other hand, rotation has been around ~forever, and is
implemented in multiple places. Colour management is a lot less
obvious.

> This kind of force-restoring is probably something we should implement in
> the fbdev emulation, which would cover about 99% of all cases where
> developers/users want to run different compositors. Or fbdev should simply
> reset CM state, like it does for rotation already (that part is easy to
> add, but indeed seems to be missing).
>
> Trying to create an ad-hoc solution (using opt-in flags) to this problem
> for every single feature seems pointless imo.

Fair enough, I guess it could be more difficult, so how about a new
flag to the atomic ioctl which requests state be _reset_ to scratch
rather than duplicated? That way, clients could be really sure they
weren't going to get screwed by rotation / colour management / render
compression / whatever.

>> Yeah, there is a single 'length' property per table, but given the
>> dizzying array of options available, I'm not really sure if that's
>> sufficient.
>
> The idea is to just give a hint to generic userspace. Fancy userspace that
> wants to exploit all the other options needs to have some baked-in
> knowledge of the hardware it runs on. This is kinda similar to how you can
> do dumb buffers, but for fancy ones userspace (at least currently) needs
> to just know how to allocate stuff. Imo there's just plain limits to how
> generic KMS can be. And it's not worth pushing beyond those.

I get the point, but am really struggling to make sense of the options
presented, and how a halfway-sensible generic userspace would work.
Exposing length/depth tuples might not be the worst idea; it also
sounds like there's more to dig out in terms of index interpolation as
well. But these are much smaller objections than having unwitting
clients inherit the CM state ...

Cheers,
Daniel
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 0/6] drm/i915: start hiding away vbt structure from the driver

2016-01-11 Thread Lukas Wunner
Hi,

On Mon, Jan 11, 2016 at 09:54:36PM +0200, Jani Nikula wrote:
> Hi all, first real patches since the RFC at [1].
> 
> The VBT is a monster and it keeps growing. Originally we've extracted
> bits and pieces out of there, and added them cleanly to our own
> structures in dev_priv->vbt, with our own macros. Later on we've been
> slipping and we have copied stuff from VBT verbatim, using the same
> structs and defines as in VBT.

There's also code spread out across the driver to sanitize VBT data, e.g.:
http://cgit.freedesktop.org/drm-intel/tree/drivers/gpu/drm/i915/intel_display.c?h=drm-intel-nightly#n15424

(cf. 69f92f67b68a, "drm/i915: Preserve SSC earlier")

Would probably make sense to consolidate that in intel_bios.c as well.

Best regards,

Lukas

> 
> Start abstracting the VBT more, hiding away the VBT specific stuff that
> should not be fiddled with outside of intel_bios.c. Make it more
> explicit when we're doing so. At this stage, mostly just fork the
> private parts into intel_bios_private.h. As prep work, move some stuff
> to intel_bios.c to limit the amount of macros needing to be exposed
> across the whole driver.
> 
> With the MIPI DSI VBT stuff out of the way, this now applies on top of
> nightly.
> 
> 
> BR,
> Jani.
> 
> [1] http://mid.gmane.org/cover.1450192823.git.jani.nik...@intel.com
> 
> 
> Jani Nikula (6):
>   drm/i915: move VBT based TV presence check to intel_bios.c
>   drm/i915: move VBT based LVDS presence check to intel_bios.c
>   drm/i915: move VBT based eDP port check to intel_bios.c
>   drm/i915: move VBT based DSI presence check to intel_bios.c
>   drm/i915/panel: setup pwm backlight based on connector type
>   drm/i915: hide away VBT private data in a separate header
> 
>  Documentation/DocBook/gpu.tmpl|   2 +-
>  drivers/gpu/drm/i915/i915_drv.h   |   5 +-
>  drivers/gpu/drm/i915/intel_bios.c | 156 +-
>  drivers/gpu/drm/i915/intel_bios.h | 860 
> ++
>  drivers/gpu/drm/i915/intel_bios_private.h | 823 
>  drivers/gpu/drm/i915/intel_dp.c   |  21 +-
>  drivers/gpu/drm/i915/intel_dsi.c  |  23 +-
>  drivers/gpu/drm/i915/intel_lvds.c |  53 +-
>  drivers/gpu/drm/i915/intel_panel.c|   2 +-
>  drivers/gpu/drm/i915/intel_tv.c   |  43 +-
>  10 files changed, 1034 insertions(+), 954 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_bios_private.h
> 
> -- 
> 2.1.4
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 021/190] drm/i915: Use HWS for seqno tracking everywhere

2016-01-11 Thread Dave Gordon

On 11/01/16 09:16, Chris Wilson wrote:

By using the same address for storing the HWS on every platform, we can
remove the platform specific vfuncs and reduce the get-seqno routine to
a single read of a cached memory location.

Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_debugfs.c  | 10 ++--
  drivers/gpu/drm/i915/i915_drv.h  |  4 +-
  drivers/gpu/drm/i915/i915_gpu_error.c|  2 +-
  drivers/gpu/drm/i915/i915_irq.c  |  4 +-
  drivers/gpu/drm/i915/i915_trace.h|  2 +-
  drivers/gpu/drm/i915/intel_breadcrumbs.c |  4 +-
  drivers/gpu/drm/i915/intel_lrc.c | 46 ++---
  drivers/gpu/drm/i915/intel_ringbuffer.c  | 86 
  drivers/gpu/drm/i915/intel_ringbuffer.h  |  7 +--
  9 files changed, 43 insertions(+), 122 deletions(-)


Generally I like this, except the changes to pc_render_add_request() (as 
previously noted) ...



diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 57ec21c5b1ab..c86d0e17d785 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1216,19 +1216,17 @@ static int gen8_rcs_signal(struct drm_i915_gem_request 
*signaller_req,
return ret;

for_each_ring(waiter, dev_priv, i) {
-   u32 seqno;
u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
continue;

-   seqno = i915_gem_request_get_seqno(signaller_req);
intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
   PIPE_CONTROL_QW_WRITE |
   PIPE_CONTROL_FLUSH_ENABLE);
intel_ring_emit(signaller, lower_32_bits(gtt_offset));
intel_ring_emit(signaller, upper_32_bits(gtt_offset));
-   intel_ring_emit(signaller, seqno);
+   intel_ring_emit(signaller, signaller_req->seqno);
intel_ring_emit(signaller, 0);
intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
   MI_SEMAPHORE_TARGET(waiter->id));
@@ -1257,18 +1255,16 @@ static int gen8_xcs_signal(struct drm_i915_gem_request 
*signaller_req,
return ret;

for_each_ring(waiter, dev_priv, i) {
-   u32 seqno;
u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
continue;

-   seqno = i915_gem_request_get_seqno(signaller_req);
intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
   MI_FLUSH_DW_OP_STOREDW);
intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
   MI_FLUSH_DW_USE_GTT);
intel_ring_emit(signaller, upper_32_bits(gtt_offset));
-   intel_ring_emit(signaller, seqno);
+   intel_ring_emit(signaller, signaller_req->seqno);
intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
   MI_SEMAPHORE_TARGET(waiter->id));
intel_ring_emit(signaller, 0);
@@ -1299,11 +1295,9 @@ static int gen6_signal(struct drm_i915_gem_request 
*signaller_req,
i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[i];

if (i915_mmio_reg_valid(mbox_reg)) {
-   u32 seqno = i915_gem_request_get_seqno(signaller_req);
-
intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit_reg(signaller, mbox_reg);
-   intel_ring_emit(signaller, seqno);
+   intel_ring_emit(signaller, signaller_req->seqno);
}
}

@@ -1338,7 +1332,7 @@ gen6_add_request(struct drm_i915_gem_request *req)

intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-   intel_ring_emit(ring, i915_gem_request_get_seqno(req));
+   intel_ring_emit(ring, req->seqno);
intel_ring_emit(ring, MI_USER_INTERRUPT);
__intel_ring_advance(ring);

@@ -1440,7 +1434,9 @@ static int
  pc_render_add_request(struct drm_i915_gem_request *req)
  {
struct intel_engine_cs *ring = req->ring;
-   u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES;
+   u32 addr = req->ring->status_page.gfx_addr +
+   (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+   u32 scratch_addr = addr;
int ret;


What I don't like is that this will now splat dummy writes across the 
HWSP. I'd rather the HWSP was kept for communicating /useful/ messages 
from the GPU to CPU, and the scratch page be used for dummy writes (as 

[Intel-gfx] [PATCH v2 4/6] drm/i915: move VBT based DSI presence check to intel_bios.c

2016-01-11 Thread Jani Nikula
Hide knowledge about VBT child devices in intel_bios.c.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 +-
 drivers/gpu/drm/i915/intel_bios.c | 33 -
 drivers/gpu/drm/i915/intel_dsi.c  | 23 ++-
 3 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6ae828f984de..f8516f564d0a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1474,7 +1474,6 @@ struct intel_vbt_data {
 
/* MIPI DSI */
struct {
-   u16 port;
u16 panel_id;
struct mipi_config *config;
struct mipi_pps_data *pps;
@@ -3350,6 +3349,7 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t 
size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
 bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 
*i2c_pin);
 bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
+bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port 
*port);
 
 /* intel_opregion.c */
 #ifdef CONFIG_ACPI
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index a7491a450cc8..94c2baa50db7 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1221,7 +1221,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
&&p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT) {
DRM_DEBUG_KMS("Found MIPI as LFP\n");
dev_priv->vbt.has_mipi = 1;
-   dev_priv->vbt.dsi.port = p_child->common.dvo_port;
}
 
child_dev_ptr = dev_priv->vbt.child_dev + count;
@@ -1536,3 +1535,35 @@ bool intel_bios_is_port_edp(struct drm_i915_private 
*dev_priv, enum port port)
 
return false;
 }
+
+/**
+ * intel_bios_is_dsi_present - is DSI present in VBT
+ * @dev_priv:  i915 device instance
+ * @port:  port for DSI if present
+ *
+ * Return true if DSI is present, and return the port in %port.
+ */
+bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv,
+  enum port *port)
+{
+   union child_device_config *p_child;
+   int i;
+
+   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+   p_child = dev_priv->vbt.child_dev + i;
+
+   if (!(p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT))
+   continue;
+
+   switch (p_child->common.dvo_port) {
+   case DVO_PORT_MIPIA:
+   case DVO_PORT_MIPIB:
+   case DVO_PORT_MIPIC:
+   case DVO_PORT_MIPID:
+   *port = p_child->common.dvo_port - DVO_PORT_MIPIA;
+   return true;
+   }
+   }
+
+   return false;
+}
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 91cef3525c93..33f219cfba43 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1112,9 +1112,15 @@ void intel_dsi_init(struct drm_device *dev)
DRM_DEBUG_KMS("\n");
 
/* There is no detection method for MIPI so rely on VBT */
-   if (!dev_priv->vbt.has_mipi)
+   if (!intel_bios_is_dsi_present(dev_priv, &port))
return;
 
+   if (port != PORT_A && port != PORT_C) {
+   DRM_DEBUG_KMS("VBT has unsupported DSI port %c\n",
+ port_name(port));
+   return;
+   }
+
if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
} else {
@@ -1153,16 +1159,15 @@ void intel_dsi_init(struct drm_device *dev)
intel_connector->unregister = intel_connector_unregister;
 
/* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */
-   if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
-   intel_encoder->crtc_mask = (1 << PIPE_A);
-   intel_dsi->ports = (1 << PORT_A);
-   } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) {
-   intel_encoder->crtc_mask = (1 << PIPE_B);
-   intel_dsi->ports = (1 << PORT_C);
-   }
+   if (port == PORT_A)
+   intel_encoder->crtc_mask = 1 << PIPE_A;
+   else
+   intel_encoder->crtc_mask = 1 << PIPE_B;
 
if (dev_priv->vbt.dsi.config->dual_link)
-   intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
+   intel_dsi->ports = (1 << PORT_A) | (1 << PORT_C);
+   else
+   intel_dsi->ports = 1 << port;
 
/* Create a DSI host (and a device) for each port. */
for_each_dsi_port(port, intel_dsi->ports) {
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel

[Intel-gfx] [PATCH v2 3/6] drm/i915: move VBT based eDP port check to intel_bios.c

2016-01-11 Thread Jani Nikula
Hide knowledge about VBT child devices in intel_bios.c.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 drivers/gpu/drm/i915/intel_bios.c | 33 +
 drivers/gpu/drm/i915/intel_dp.c   | 21 +
 3 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5f0d44b380aa..6ae828f984de 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3349,6 +3349,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
 bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 
*i2c_pin);
+bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
 
 /* intel_opregion.c */
 #ifdef CONFIG_ACPI
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 099f3f0002a2..a7491a450cc8 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1503,3 +1503,36 @@ bool intel_bios_is_lvds_present(struct drm_i915_private 
*dev_priv, u8 *i2c_pin)
 
return false;
 }
+
+/**
+ * intel_bios_is_port_edp - is the device in given port eDP
+ * @dev_priv:  i915 device instance
+ * @port:  port to check
+ *
+ * Return true if the device in %port is eDP.
+ */
+bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port)
+{
+   union child_device_config *p_child;
+   static const short port_mapping[] = {
+   [PORT_B] = DVO_PORT_DPB,
+   [PORT_C] = DVO_PORT_DPC,
+   [PORT_D] = DVO_PORT_DPD,
+   [PORT_E] = DVO_PORT_DPE,
+   };
+   int i;
+
+   if (!dev_priv->vbt.child_dev_num)
+   return false;
+
+   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+   p_child = dev_priv->vbt.child_dev + i;
+
+   if (p_child->common.dvo_port == port_mapping[port] &&
+   (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
+   (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
+   return true;
+   }
+
+   return false;
+}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796e3d313cb9..02cb4e9bf5ea 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5068,14 +5068,6 @@ put_power:
 bool intel_dp_is_edp(struct drm_device *dev, enum port port)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
-   union child_device_config *p_child;
-   int i;
-   static const short port_mapping[] = {
-   [PORT_B] = DVO_PORT_DPB,
-   [PORT_C] = DVO_PORT_DPC,
-   [PORT_D] = DVO_PORT_DPD,
-   [PORT_E] = DVO_PORT_DPE,
-   };
 
/*
 * eDP not supported on g4x. so bail out early just
@@ -5087,18 +5079,7 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port 
port)
if (port == PORT_A)
return true;
 
-   if (!dev_priv->vbt.child_dev_num)
-   return false;
-
-   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
-   p_child = dev_priv->vbt.child_dev + i;
-
-   if (p_child->common.dvo_port == port_mapping[port] &&
-   (p_child->common.device_type & DEVICE_TYPE_eDP_BITS) ==
-   (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
-   return true;
-   }
-   return false;
+   return intel_bios_is_port_edp(dev_priv, port);
 }
 
 void
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 6/6] drm/i915: hide away VBT private data in a separate header

2016-01-11 Thread Jani Nikula
We've been accumulating code across the driver that depends on the VBT
specific structures and defines. The VBT is an uncontrollable
beast. Encourage encapsulation of the VBT data by hiding the structures
and defines in a private header only to be included from intel_bios.c.

Signed-off-by: Jani Nikula 
---
 Documentation/DocBook/gpu.tmpl|   2 +-
 drivers/gpu/drm/i915/intel_bios.c |   2 +-
 drivers/gpu/drm/i915/intel_bios.h | 860 ++
 drivers/gpu/drm/i915/intel_bios_private.h | 823 
 4 files changed, 859 insertions(+), 828 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_bios_private.h

diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index 351e801cead9..4ba7c6f8e8b1 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -3323,7 +3323,7 @@ int num_ioctls;
Video BIOS Table (VBT)
 !Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT)
 !Idrivers/gpu/drm/i915/intel_bios.c
-!Idrivers/gpu/drm/i915/intel_bios.h
+!Idrivers/gpu/drm/i915/intel_bios_private.h
   
 
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 94c2baa50db7..83b78e0df306 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -29,7 +29,7 @@
 #include 
 #include 
 #include "i915_drv.h"
-#include "intel_bios.h"
+#include "intel_bios_private.h"
 
 /**
  * DOC: Video BIOS Table (VBT)
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 350d4e0f75a4..536d90f0c3eb 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006 Intel Corporation
+ * Copyright © 2016 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,543 +19,15 @@
  * 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:
- *Eric Anholt 
- *
- */
-
-#ifndef _INTEL_BIOS_H_
-#define _INTEL_BIOS_H_
-
-/**
- * struct vbt_header - VBT Header structure
- * @signature: VBT signature, always starts with "$VBT"
- * @version:   Version of this structure
- * @header_size:   Size of this structure
- * @vbt_size:  Size of VBT (VBT Header, BDB Header and data blocks)
- * @vbt_checksum:  Checksum
- * @reserved0: Reserved
- * @bdb_offset:Offset of &struct bdb_header from beginning of 
VBT
- * @aim_offset:Offsets of add-in data blocks from beginning of 
VBT
- */
-struct vbt_header {
-   u8 signature[20];
-   u16 version;
-   u16 header_size;
-   u16 vbt_size;
-   u8 vbt_checksum;
-   u8 reserved0;
-   u32 bdb_offset;
-   u32 aim_offset[4];
-} __packed;
-
-/**
- * struct bdb_header - BDB Header structure
- * @signature: BDB signature "BIOS_DATA_BLOCK"
- * @version:   Version of the data block definitions
- * @header_size:   Size of this structure
- * @bdb_size:  Size of BDB (BDB Header and data blocks)
- */
-struct bdb_header {
-   u8 signature[16];
-   u16 version;
-   u16 header_size;
-   u16 bdb_size;
-} __packed;
-
-/* strictly speaking, this is a "skip" block, but it has interesting info */
-struct vbios_data {
-   u8 type; /* 0 == desktop, 1 == mobile */
-   u8 relstage;
-   u8 chipset;
-   u8 lvds_present:1;
-   u8 tv_present:1;
-   u8 rsvd2:6; /* finish byte */
-   u8 rsvd3[4];
-   u8 signon[155];
-   u8 copyright[61];
-   u16 code_segment;
-   u8 dos_boot_mode;
-   u8 bandwidth_percent;
-   u8 rsvd4; /* popup memory size */
-   u8 resize_pci_bios;
-   u8 rsvd5; /* is crt already on ddc2 */
-} __packed;
-
-/*
- * There are several types of BIOS data blocks (BDBs), each block has
- * an ID and size in the first 3 bytes (ID in first, size in next 2).
- * Known types are listed below.
  */
-#define BDB_GENERAL_FEATURES 1
-#define BDB_GENERAL_DEFINITIONS  2
-#define BDB_OLD_TOGGLE_LIST  3
-#define BDB_MODE_SUPPORT_LIST4
-#define BDB_GENERIC_MODE_TABLE   5
-#define BDB_EXT_MMIO_REGS6
-#define BDB_SWF_IO   7
-#define BDB_SWF_MMIO 8
-#define BDB_PSR  9
-#define BDB_MODE_REMOVAL_TABLE  10
-#define BDB_CHILD_DEVICE_TABLE  11
-#define BDB_DRIVER_FEATURES 12
-#define BDB_DRIVER_PERSISTENCE  13
-#define BDB_EXT_TABLE_PTRS  14
-#define BDB_DOT_CLOCK_OVERRIDE  15
-#define BDB_DISPLAY_SELECT  16
-/* 17 rsvd */
-#define BDB_DRIVER_ROTATION 18
-#define BDB_DISPLAY_REMOVE  19
-#define BDB_OEM_CUSTOM  20
-#define BDB_EFP_LIST21 /* workarounds for VGA hsync/vsync */
-#define BDB_SDVO_LVDS

[Intel-gfx] [PATCH v2 5/6] drm/i915/panel: setup pwm backlight based on connector type

2016-01-11 Thread Jani Nikula
Use the connector type instead of VBT directly to decide which backlight
mechanism to use on VLV/CHV. (Indirectly, this is the same thing, but
hides the VBT use.)

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_panel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 21ee6477bf98..f7fbb7c223b1 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1745,7 +1745,7 @@ intel_panel_init_backlight_funcs(struct intel_panel 
*panel)
panel->backlight.get = pch_get_backlight;
panel->backlight.hz_to_pwm = pch_hz_to_pwm;
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-   if (dev_priv->vbt.has_mipi) {
+   if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
panel->backlight.setup = pwm_setup_backlight;
panel->backlight.enable = pwm_enable_backlight;
panel->backlight.disable = pwm_disable_backlight;
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 0/6] drm/i915: start hiding away vbt structure from the driver

2016-01-11 Thread Jani Nikula
Hi all, first real patches since the RFC at [1].

The VBT is a monster and it keeps growing. Originally we've extracted
bits and pieces out of there, and added them cleanly to our own
structures in dev_priv->vbt, with our own macros. Later on we've been
slipping and we have copied stuff from VBT verbatim, using the same
structs and defines as in VBT.

Start abstracting the VBT more, hiding away the VBT specific stuff that
should not be fiddled with outside of intel_bios.c. Make it more
explicit when we're doing so. At this stage, mostly just fork the
private parts into intel_bios_private.h. As prep work, move some stuff
to intel_bios.c to limit the amount of macros needing to be exposed
across the whole driver.

With the MIPI DSI VBT stuff out of the way, this now applies on top of
nightly.


BR,
Jani.

[1] http://mid.gmane.org/cover.1450192823.git.jani.nik...@intel.com


Jani Nikula (6):
  drm/i915: move VBT based TV presence check to intel_bios.c
  drm/i915: move VBT based LVDS presence check to intel_bios.c
  drm/i915: move VBT based eDP port check to intel_bios.c
  drm/i915: move VBT based DSI presence check to intel_bios.c
  drm/i915/panel: setup pwm backlight based on connector type
  drm/i915: hide away VBT private data in a separate header

 Documentation/DocBook/gpu.tmpl|   2 +-
 drivers/gpu/drm/i915/i915_drv.h   |   5 +-
 drivers/gpu/drm/i915/intel_bios.c | 156 +-
 drivers/gpu/drm/i915/intel_bios.h | 860 ++
 drivers/gpu/drm/i915/intel_bios_private.h | 823 
 drivers/gpu/drm/i915/intel_dp.c   |  21 +-
 drivers/gpu/drm/i915/intel_dsi.c  |  23 +-
 drivers/gpu/drm/i915/intel_lvds.c |  53 +-
 drivers/gpu/drm/i915/intel_panel.c|   2 +-
 drivers/gpu/drm/i915/intel_tv.c   |  43 +-
 10 files changed, 1034 insertions(+), 954 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_bios_private.h

-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 2/6] drm/i915: move VBT based LVDS presence check to intel_bios.c

2016-01-11 Thread Jani Nikula
Hide knowledge about VBT child devices in intel_bios.c.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 drivers/gpu/drm/i915/intel_bios.c | 50 
 drivers/gpu/drm/i915/intel_lvds.c | 53 +--
 3 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3822c465d3dc..5f0d44b380aa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3348,6 +3348,7 @@ extern void intel_i2c_reset(struct drm_device *dev);
 int intel_bios_init(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
+bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 
*i2c_pin);
 
 /* intel_opregion.c */
 #ifdef CONFIG_ACPI
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index bb9e8b086b63..099f3f0002a2 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1453,3 +1453,53 @@ bool intel_bios_is_tv_present(struct drm_i915_private 
*dev_priv)
 
return false;
 }
+
+/**
+ * intel_bios_is_lvds_present - is LVDS present in VBT
+ * @dev_priv:  i915 device instance
+ * @i2c_pin:   i2c pin for LVDS if present
+ *
+ * Return true if LVDS is present. If no child devices were parsed from VBT,
+ * assume LVDS is present.
+ */
+bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
+{
+   int i;
+
+   if (!dev_priv->vbt.child_dev_num)
+   return true;
+
+   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+   union child_device_config *uchild = dev_priv->vbt.child_dev + i;
+   struct old_child_dev_config *child = &uchild->old;
+
+   /* If the device type is not LFP, continue.
+* We have to check both the new identifiers as well as the
+* old for compatibility with some BIOSes.
+*/
+   if (child->device_type != DEVICE_TYPE_INT_LFP &&
+   child->device_type != DEVICE_TYPE_LFP)
+   continue;
+
+   if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
+   *i2c_pin = child->i2c_pin;
+
+   /* However, we cannot trust the BIOS writers to populate
+* the VBT correctly.  Since LVDS requires additional
+* information from AIM blocks, a non-zero addin offset is
+* a good indicator that the LVDS is actually present.
+*/
+   if (child->addin_offset)
+   return true;
+
+   /* But even then some BIOS writers perform some black magic
+* and instantiate the device without reference to any
+* additional data.  Trust that if the VBT was written into
+* the OpRegion then they have validated the LVDS's existence.
+*/
+   if (dev_priv->opregion.vbt)
+   return true;
+   }
+
+   return false;
+}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 0da0240caf81..80f8684e5137 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -772,57 +772,6 @@ static const struct dmi_system_id intel_no_lvds[] = {
{ } /* terminating entry */
 };
 
-/*
- * Enumerate the child dev array parsed from VBT to check whether
- * the LVDS is present.
- * If it is present, return 1.
- * If it is not present, return false.
- * If no child dev is parsed from VBT, it assumes that the LVDS is present.
- */
-static bool lvds_is_present_in_vbt(struct drm_device *dev,
-  u8 *i2c_pin)
-{
-   struct drm_i915_private *dev_priv = dev->dev_private;
-   int i;
-
-   if (!dev_priv->vbt.child_dev_num)
-   return true;
-
-   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
-   union child_device_config *uchild = dev_priv->vbt.child_dev + i;
-   struct old_child_dev_config *child = &uchild->old;
-
-   /* If the device type is not LFP, continue.
-* We have to check both the new identifiers as well as the
-* old for compatibility with some BIOSes.
-*/
-   if (child->device_type != DEVICE_TYPE_INT_LFP &&
-   child->device_type != DEVICE_TYPE_LFP)
-   continue;
-
-   if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
-   *i2c_pin = child->i2c_pin;
-
-   /* However, we cannot trust the BIOS writers to populate
-* the VBT correctly.  Since LVDS requires additional
-* information from AIM blocks, a non-zero addin offset is
-   

[Intel-gfx] [PATCH v2 1/6] drm/i915: move VBT based TV presence check to intel_bios.c

2016-01-11 Thread Jani Nikula
Hide knowledge about VBT child devices in intel_bios.c.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h   |  1 +
 drivers/gpu/drm/i915/intel_bios.c | 38 ++
 drivers/gpu/drm/i915/intel_tv.c   | 43 +--
 3 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 104bd1809936..3822c465d3dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3347,6 +3347,7 @@ extern void intel_i2c_reset(struct drm_device *dev);
 /* intel_bios.c */
 int intel_bios_init(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
+bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
 
 /* intel_opregion.c */
 #ifdef CONFIG_ACPI
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 15ba52bd2538..bb9e8b086b63 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1415,3 +1415,41 @@ intel_bios_init(struct drm_i915_private *dev_priv)
 
return 0;
 }
+
+/**
+ * intel_bios_is_tv_present - is integrated TV present in VBT
+ * @dev_priv:  i915 device instance
+ *
+ * Return true if TV is present. If no child devices were parsed from VBT,
+ * assume TV is present.
+ */
+bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv)
+{
+   union child_device_config *p_child;
+   int i;
+
+   if (!dev_priv->vbt.child_dev_num)
+   return true;
+
+   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+   p_child = dev_priv->vbt.child_dev + i;
+   /*
+* If the device type is not TV, continue.
+*/
+   switch (p_child->old.device_type) {
+   case DEVICE_TYPE_INT_TV:
+   case DEVICE_TYPE_TV:
+   case DEVICE_TYPE_TV_SVIDEO_COMPOSITE:
+   break;
+   default:
+   continue;
+   }
+   /* Only when the addin_offset is non-zero, it is regarded
+* as present.
+*/
+   if (p_child->old.addin_offset)
+   return true;
+   }
+
+   return false;
+}
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 948cbff6c62e..29e68859b9b7 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1529,47 +1529,6 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs 
= {
.destroy = intel_encoder_destroy,
 };
 
-/*
- * Enumerate the child dev array parsed from VBT to check whether
- * the integrated TV is present.
- * If it is present, return 1.
- * If it is not present, return false.
- * If no child dev is parsed from VBT, it assumes that the TV is present.
- */
-static int tv_is_present_in_vbt(struct drm_device *dev)
-{
-   struct drm_i915_private *dev_priv = dev->dev_private;
-   union child_device_config *p_child;
-   int i, ret;
-
-   if (!dev_priv->vbt.child_dev_num)
-   return 1;
-
-   ret = 0;
-   for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
-   p_child = dev_priv->vbt.child_dev + i;
-   /*
-* If the device type is not TV, continue.
-*/
-   switch (p_child->old.device_type) {
-   case DEVICE_TYPE_INT_TV:
-   case DEVICE_TYPE_TV:
-   case DEVICE_TYPE_TV_SVIDEO_COMPOSITE:
-   break;
-   default:
-   continue;
-   }
-   /* Only when the addin_offset is non-zero, it is regarded
-* as present.
-*/
-   if (p_child->old.addin_offset) {
-   ret = 1;
-   break;
-   }
-   }
-   return ret;
-}
-
 void
 intel_tv_init(struct drm_device *dev)
 {
@@ -1585,7 +1544,7 @@ intel_tv_init(struct drm_device *dev)
if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
return;
 
-   if (!tv_is_present_in_vbt(dev)) {
+   if (!intel_bios_is_tv_present(dev_priv)) {
DRM_DEBUG_KMS("Integrated TV is not present.\n");
return;
}
-- 
2.1.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 05/13] drm/i915: Cache LRCA in the context

2016-01-11 Thread Dave Gordon

On 11/01/16 08:38, Daniel Vetter wrote:

On Fri, Jan 08, 2016 at 11:29:44AM +, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

We are not allowed to call i915_gem_obj_ggtt_offset from irq
context without the big kernel lock held.

LRCA lifetime is well defined so cache it so it can be looked up
cheaply from the interrupt context and at command submission
time.

v2: Added irq context reasoning to the commit message. (Daniel Vetter)

Signed-off-by: Tvrtko Ursulin 


A i915_obj_for_each_vma macro with a
WARN_ON(!mutex_is_locked(dev->struct_mutex)) would be awesome to validate
this. Especially since this is by far not the only time I've seen this
bug. Needs to be a follow-up though to avoid stalling this fix.


---
  drivers/gpu/drm/i915/i915_debugfs.c | 15 ++
  drivers/gpu/drm/i915/i915_drv.h |  1 +
  drivers/gpu/drm/i915/intel_lrc.c| 40 -
  drivers/gpu/drm/i915/intel_lrc.h|  3 ++-
  4 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 3b05bd189eab..714a45cf8a51 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1976,12 +1976,13 @@ static int i915_context_status(struct seq_file *m, void 
*unused)
  }

  static void i915_dump_lrc_obj(struct seq_file *m,
- struct intel_engine_cs *ring,
- struct drm_i915_gem_object *ctx_obj)
+ struct intel_context *ctx,
+ struct intel_engine_cs *ring)
  {
struct page *page;
uint32_t *reg_state;
int j;
+   struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state;
unsigned long ggtt_offset = 0;

if (ctx_obj == NULL) {
@@ -1991,7 +1992,7 @@ static void i915_dump_lrc_obj(struct seq_file *m,
}

seq_printf(m, "CONTEXT: %s %u\n", ring->name,
-  intel_execlists_ctx_id(ctx_obj));
+  intel_execlists_ctx_id(ctx, ring));

if (!i915_gem_obj_ggtt_bound(ctx_obj))
seq_puts(m, "\tNot bound in GGTT\n");
@@ -2040,8 +2041,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)
-   i915_dump_lrc_obj(m, ring,
- ctx->engine[i].state);
+   i915_dump_lrc_obj(m, ctx, ring);
}
}

@@ -2115,11 +2115,8 @@ static int i915_execlists(struct seq_file *m, void *data)

seq_printf(m, "\t%d requests in queue\n", count);
if (head_req) {
-   struct drm_i915_gem_object *ctx_obj;
-
-   ctx_obj = head_req->ctx->engine[ring_id].state;
seq_printf(m, "\tHead request id: %u\n",
-  intel_execlists_ctx_id(ctx_obj));
+  intel_execlists_ctx_id(head_req->ctx, ring));
seq_printf(m, "\tHead request tail: %u\n",
   head_req->tail);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8cf655c6fc03..b77a5d84eac2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -881,6 +881,7 @@ struct intel_context {
struct drm_i915_gem_object *state;
struct intel_ringbuffer *ringbuf;
int pin_count;
+   u32 lrca;


lrc_offset imo. Consistent with our other usage in the driver, and
actually readable. Please apply liberally everywhere else (I know that
bsepc calls it lrca, but we don't need to follow bad naming styles
blindly).

With that Reviewed-by: Daniel Vetter 


} engine[I915_NUM_RINGS];

struct list_head link;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ff146a15d395..ffe004de22b0 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -265,7 +265,8 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, 
int enable_execlists

  /**
   * intel_execlists_ctx_id() - get the Execlists Context ID
- * @ctx_obj: Logical Ring Context backing object.
+ * @ctx: Context to get the ID for
+ * @ring: Engine to get the ID for
   *
   * Do not confuse with ctx->id! Unfortunately we have a name overload
   * here: the old context ID we pass to userspace as a handler so that
@@ -275,14 +276,12 @@ int intel_sanitize_enable_execlists(struct drm_device 
*dev, int enable_execlists
   *
   * Return: 20-bits globally unique context ID.
   */
-u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj)
+u32 intel_execlists_ctx_id(struct intel_context *ctx,
+

Re: [Intel-gfx] [PATCH] drm/i915/skl: Use proper plane dimensions for DDB and WM calculations

2016-01-11 Thread Ville Syrjälä
On Mon, Dec 21, 2015 at 07:31:17AM -0800, Matt Roper wrote:
> In commit
> 
> commit 024c9045221fe45482863c47c4b4c47d37f97cbf
> Author: Matt Roper 
> Date:   Thu Sep 24 15:53:11 2015 -0700
> 
> drm/i915/skl: Eliminate usage of pipe_wm_parameters from 
> SKL-style WM (v4)
> 
> I fumbled while converting the dimensions stored in the plane_parameters
> structure to the values stored in plane state and accidentally replaced
> the plane dimensions with the pipe dimensions in both the DDB allocation
> function and the WM calculation function.  On the DDB side this is
> harmless since we effectively treat all of our non-cursor planes as
> full-screen which may not be optimal, but generally won't cause any
> problems either (and in 99% of the cases where there's no sprite plane
> usage or primary plane windowing, there's no effect at all).  On the WM
> calculation side there's more potential for this fumble to cause actual
> problems since cursors also get miscalculated.
> 
> Cc: Ville Syrjälä 
> Cc: "Kondapally, Kalyan" 
> Cc: Radhakrishna Sripada 
> Signed-off-by: Matt Roper 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 24 +---
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 8d0d6f5..f4d4cc7 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2845,25 +2845,22 @@ skl_plane_relative_data_rate(const struct 
> intel_crtc_state *cstate,
>const struct drm_plane_state *pstate,
>int y)
>  {
> - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
> + struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
>   struct drm_framebuffer *fb = pstate->fb;
> + unsigned w = drm_rect_width(&intel_pstate->dst);
> + unsigned h = drm_rect_height(&intel_pstate->dst);

I think you're supposed to use the src dimensions in most places.

>  
>   /* for planar format */
>   if (fb->pixel_format == DRM_FORMAT_NV12) {
>   if (y)  /* y-plane data rate */
> - return intel_crtc->config->pipe_src_w *
> - intel_crtc->config->pipe_src_h *
> - drm_format_plane_cpp(fb->pixel_format, 0);
> + return w * h * drm_format_plane_cpp(fb->pixel_format, 
> 0);
>   else/* uv-plane data rate */
> - return (intel_crtc->config->pipe_src_w/2) *
> - (intel_crtc->config->pipe_src_h/2) *
> + return (w/2) * (h/2) *
>   drm_format_plane_cpp(fb->pixel_format, 1);
>   }
>  
>   /* for packed formats */
> - return intel_crtc->config->pipe_src_w *
> - intel_crtc->config->pipe_src_h *
> - drm_format_plane_cpp(fb->pixel_format, 0);
> + return w * h * drm_format_plane_cpp(fb->pixel_format, 0);
>  }
>  
>  /*
> @@ -2960,6 +2957,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>* FIXME: we may not allocate every single block here.
>*/
>   total_data_rate = skl_get_total_relative_data_rate(cstate);
> + if (!total_data_rate)
> + return;
>  
>   start = alloc->start;
>   for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> @@ -3093,12 +3092,15 @@ static bool skl_compute_plane_wm(const struct 
> drm_i915_private *dev_priv,
>  {
>   struct drm_plane *plane = &intel_plane->base;
>   struct drm_framebuffer *fb = plane->state->fb;
> + struct intel_plane_state *intel_pstate =
> + to_intel_plane_state(plane->state);
>   uint32_t latency = dev_priv->wm.skl_latency[level];
>   uint32_t method1, method2;
>   uint32_t plane_bytes_per_line, plane_blocks_per_line;
>   uint32_t res_blocks, res_lines;
>   uint32_t selected_result;
>   uint8_t bytes_per_pixel;
> + unsigned w = drm_rect_width(&intel_pstate->dst);
>  
>   if (latency == 0 || !cstate->base.active || !fb)
>   return false;
> @@ -3109,12 +3111,12 @@ static bool skl_compute_plane_wm(const struct 
> drm_i915_private *dev_priv,
>latency);
>   method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
>cstate->base.adjusted_mode.crtc_htotal,
> -  cstate->pipe_src_w,
> +  w,
>bytes_per_pixel,
>fb->modifier[0],
>latency);
>  
> - plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel;
> + plane_bytes_per_line = w * bytes_per_pixel;
>   plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
>  
>   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> -- 
> 2.1.4
> 
> ___
> 

Re: [Intel-gfx] [PATCH 0/7] Convert requests to use struct fence

2016-01-11 Thread John Harrison

On 08/01/2016 22:47, Chris Wilson wrote:

On Fri, Jan 08, 2016 at 06:47:21PM +, john.c.harri...@intel.com wrote:

[Patches against drm-intel-nightly tree fetched 17/11/2015]

Branch url?


Not sure what you mean. The branch is 'drm-intel-nightly' from the DRM 
intel git repository (git://anongit.freedesktop.org/drm-intel/). How 
many versions of 'drm-intel-nightly' are there?




-Chris



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v5 10/12] drm/i915: Defer probe if gmux is present but its driver isn't

2016-01-11 Thread Lukas Wunner
gmux is a microcontroller built into dual GPU MacBook Pros.
On pre-retina MBPs, if we're the inactive GPU, we need apple-gmux
to temporarily switch DDC so that we can probe the panel's EDID.

The checks for CONFIG_VGA_ARB and CONFIG_VGA_SWITCHEROO are necessary
because if either of them is disabled but gmux is present, the driver
would never load, even if we're the active GPU. (vga_default_device()
would evaluate to NULL and vga_switcheroo_handler_flags() would
evaluate to 0.)

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Tested-by: Lukas Wunner 
[MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina  15"]
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/drm/i915/i915_drv.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3ac616d..4a5fc5d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -35,9 +35,12 @@
 #include "i915_trace.h"
 #include "intel_drv.h"
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 static struct drm_driver driver;
@@ -967,6 +970,15 @@ static int i915_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
if (PCI_FUNC(pdev->devfn))
return -ENODEV;
 
+   /*
+* apple-gmux is needed on dual GPU MacBook Pro
+* to probe the panel if we're the inactive GPU.
+*/
+   if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) &&
+   apple_gmux_present() && pdev != vga_default_device() &&
+   !vga_switcheroo_handler_flags())
+   return -EPROBE_DEFER;
+
return drm_get_pci_dev(pdev, ent, &driver);
 }
 
-- 
1.8.5.2 (Apple Git-48)

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v5 06/12] drm/i915: Switch DDC when reading the EDID

2016-01-11 Thread Lukas Wunner
The pre-retina MacBook Pro uses an LVDS panel and a gmux controller
to switch the panel between its two GPUs. The panel mode in VBIOS
is notoriously bogus on these machines and some models have no
VBIOS at all.

Use drm_get_edid_switcheroo() in lieu of drm_get_edid() on LVDS
if the vga_switcheroo handler is capable of temporarily switching
the panel's DDC lines to the integrated GPU. This allows us to
retrieve the EDID if the panel is currently muxed to the discrete GPU.

This only enables EDID probing on the pre-retina MBP (2008 - 2013).
The retina MBP (2012 - present) uses eDP and gmux is not capable of
switching AUX separately from the main link on these models.
This will be addressed in later patches.

List of pre-retina MBPs with dual GPUs, one of them Intel:
[MBP  6,2 2010  intel ILK + nvidia GT216  pre-retina  15"]
[MBP  6,1 2010  intel ILK + nvidia GT216  pre-retina  17"]
[MBP  8,2 2011  intel SNB + amd turks pre-retina  15"]
[MBP  8,3 2011  intel SNB + amd turks pre-retina  17"]
[MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina  15"]

v3: Commit newly added due to introduction of drm_get_edid_switcheroo()
wrapper which drivers need to opt-in to.

v5: Rebase on "vga_switcheroo: Add handler flags infrastructure",
i.e. call drm_get_edid_switcheroo() only if the handler
indicates that DDC is switchable.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Tested-by: Lukas Wunner 
[MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina  15"]
Signed-off-by: Lukas Wunner 
---
 drivers/gpu/drm/i915/intel_lvds.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 0da0240..811ddf7 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1080,7 +1081,12 @@ void intel_lvds_init(struct drm_device *dev)
 * preferred mode is the right one.
 */
mutex_lock(&dev->mode_config.mutex);
-   edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
+   if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
+   edid = drm_get_edid_switcheroo(connector,
+   intel_gmbus_get_adapter(dev_priv, pin));
+   else
+   edid = drm_get_edid(connector,
+   intel_gmbus_get_adapter(dev_priv, pin));
if (edid) {
if (drm_add_edid_modes(connector, edid)) {
drm_mode_connector_update_edid_property(connector,
-- 
1.8.5.2 (Apple Git-48)

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/7] drm/i915: Interrupt driven fences

2016-01-11 Thread John Harrison

On 08/01/2016 22:46, Chris Wilson wrote:

On Fri, Jan 08, 2016 at 06:47:26PM +, john.c.harri...@intel.com wrote:

+void i915_gem_request_notify(struct intel_engine_cs *ring, bool fence_locked)
+{
+   struct drm_i915_gem_request *req, *req_next;
+   unsigned long flags;
u32 seqno;
  
-	seqno = req->ring->get_seqno(req->ring, false/*lazy_coherency*/);

+   if (list_empty(&ring->fence_signal_list))
+   return;
+
+   if (!fence_locked)
+   spin_lock_irqsave(&ring->fence_lock, flags);
  
-	return i915_seqno_passed(seqno, req->seqno);

+   seqno = ring->get_seqno(ring, false);

We really don't want to do be doing the forcewake dance from inside the
interrupt handler. We made that mistake years ago.
-Chris


What forcewake dance? Nothing in the above code mentions force wake.
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v5 00/12] Enable GPU switching on pre-retina MacBook Pro

2016-01-11 Thread Lukas Wunner
Enable GPU switching on the pre-retina MacBook Pro (2008 - 2013), v5.

The main obstacle on these machines is that the panel mode in VBIOS
is bogus. Fortunately gmux can switch DDC independently from the
display, thereby allowing the inactive GPU to probe the panel's EDID.

In short, vga_switcheroo and apple-gmux are amended with hooks to
switch DDC, DRM core is amended with a drm_get_edid_switcheroo() helper,
and relevant drivers are amended to call that for LVDS outputs.

The retina MacBook Pro (2012 - present) uses eDP and cannot switch
AUX independently from the main link. The main obstacle there is link
training, I'm currently working on this, it will be addressed in a
future patch set.

This series is also reviewable on GitHub:
https://github.com/l1k/linux/commits/mbp_switcheroo_v5

Changes:

* New patch [01/12]: vga_switcheroo handler flags
  Alex Deucher asked if this series might regress on non-Apple laptops.
  To address this concern, I let handlers declare their capabilities in
  a bitmask. DRM drivers call drm_get_edid_switcheroo() only if the
  handler has set the VGA_SWITCHEROO_CAN_SWITCH_DDC flag.
  Currently just one other flag is defined which is used on retinas.

* Changed patch [02/12]: vga_switcheroo DDC locking
  Rename ddc_lock to mux_hw_lock, suggested by Daniel Vetter.

* New patch [03/12]: track switch state of apple-gmux
  Fixes a bug in previous versions of this series which occurred if
  the system was suspended while DDC was temporarily switched:
  On resume DDC was switched to the wrong GPU.

* New patches [09/12 - 12/12]: deferred probing
  Previously I used connector reprobing if the inactive GPU's driver
  loaded before gmux. I've ditched that in favor of deferred driver
  probing, which is much simpler. Thanks to Daniel Vetter for the
  suggestion.

Caution: Patch [09/12] depends on a new acpi_dev_present() API which
will land in 4.5 via Rafael J. Wysocki's tree.

I would particularly be interested in feedback on the handler flags
patch [01/12]. I'm not 100% happy with the number of characters
required to query the flags (e.g.: if (vga_switcheroo_handler_flags() &
VGA_SWITCHEROO_CAN_SWITCH_DDC)), but failed to come up with something
shorter. Thierry Reding used a struct of bools instead of a bitmask
for his recent drm_dp_link_caps patches. Maybe use that instead?
http://lists.freedesktop.org/archives/dri-devel/2015-December/097025.html

Thanks,

Lukas


Lukas Wunner (12):
  vga_switcheroo: Add handler flags infrastructure
  vga_switcheroo: Add support for switching only the DDC
  apple-gmux: Track switch state
  apple-gmux: Add switch_ddc support
  drm/edid: Switch DDC when reading the EDID
  drm/i915: Switch DDC when reading the EDID
  drm/nouveau: Switch DDC when reading the EDID
  drm/radeon: Switch DDC when reading the EDID
  apple-gmux: Add helper for presence detect
  drm/i915: Defer probe if gmux is present but its driver isn't
  drm/nouveau: Defer probe if gmux is present but its driver isn't
  drm/radeon: Defer probe if gmux is present but its driver isn't

 Documentation/DocBook/gpu.tmpl   |   5 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c |   3 +-
 drivers/gpu/drm/drm_edid.c   |  26 +
 drivers/gpu/drm/i915/i915_drv.c  |  12 +++
 drivers/gpu/drm/i915/intel_lvds.c|   8 +-
 drivers/gpu/drm/nouveau/nouveau_acpi.c   |   2 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c  |  21 +++-
 drivers/gpu/drm/nouveau/nouveau_drm.c|  11 +++
 drivers/gpu/drm/radeon/radeon_atpx_handler.c |   3 +-
 drivers/gpu/drm/radeon/radeon_connectors.c   |   6 ++
 drivers/gpu/drm/radeon/radeon_drv.c  |  11 +++
 drivers/gpu/vga/vga_switcheroo.c | 119 ++-
 drivers/platform/x86/apple-gmux.c| 111 -
 include/drm/drm_crtc.h   |   2 +
 include/linux/apple-gmux.h   |  39 
 include/linux/vga_switcheroo.h   |  36 ++-
 16 files changed, 382 insertions(+), 33 deletions(-)
 create mode 100644 include/linux/apple-gmux.h

-- 
1.8.5.2 (Apple Git-48)

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/7] drm/i915: Delay the freeing of requests until retire time

2016-01-11 Thread John Harrison

On 08/01/2016 22:08, Chris Wilson wrote:

On Fri, Jan 08, 2016 at 06:47:25PM +, john.c.harri...@intel.com wrote:

From: John Harrison 

The request structure is reference counted. When the count reached
zero, the request was immediately freed and all associated objects
were unrefereced/unallocated. This meant that the driver mutex lock
must be held at the point where the count reaches zero. This was fine
while all references were held internally to the driver. However, the
plan is to allow the underlying fence object (and hence the request
itself) to be returned to other drivers and to userland. External
users cannot be expected to acquire a driver private mutex lock.

It's a trivial issue to fix to enable freeing requests without holding the
struct_mutex. You don't need to even add any new lists, delayed freeing
mechanisms and whotnot.
-Chris



As the driver stands, it is not trivial to free a request without 
holding the mutex. It does things like unpinning buffers, freeing up 
contexts (which is a whole other bundle of complication), releasing 
IRQs. It may be possible to re-organise things to make those operations 
safe to do without the mutex but it certainly does not look trivial!


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/7] drm/i915: Add per context timelines to fence object

2016-01-11 Thread John Harrison

On 08/01/2016 22:05, Chris Wilson wrote:

On Fri, Jan 08, 2016 at 06:47:24PM +, john.c.harri...@intel.com wrote:

From: John Harrison 

The fence object used inside the request structure requires a sequence
number. Although this is not used by the i915 driver itself, it could
potentially be used by non-i915 code if the fence is passed outside of
the driver. This is the intention as it allows external kernel drivers
and user applications to wait on batch buffer completion
asynchronously via the dma-buff fence API.

That doesn't make any sense as they are not limited by a single
timeline.
I don't understand what you mean. Who is not limited by a single 
timeline?  The point is that the current seqno values cannot be used as 
there is no guarantee that they will increment globally once things like 
a scheduler and pre-emption arrive. Whereas, the fence internal 
implementation makes various assumptions about the linearity of the 
timeline. External users do not want to care about timelines or seqnos 
at all, they just want the fence API to work as documented.





To ensure that such external users are not confused by strange things
happening with the seqno, this patch adds in a per context timeline
that can provide a guaranteed in-order seqno value for the fence. This
is safe because the scheduler will not re-order batch buffers within a
context - they are considered to be mutually dependent.

You haven't added per-context breadcrumbs. What we need for being able
to execute requests from parallel timelines, but with requests within a
timeline being ordered, is a per-context page where we can emit the
per-context issued breadcrumb. Then instead of looking up the current
HW seqno in a global page, the request just looks at the current context
HW seqno in the context seq, just
i915_seqno_passed(*req->p_context_seqno, req->seqno).
This patch is not attempting to implement per context seqno values. That 
can be done as future work. This patch is doing the simplest, least 
invasive implementation in order to make external fences work.



The retirment ordered requests lists are moved from the engine to the
context and retirement cleanup are restricted to the context.
-Chris



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/7] drm/i915: Convert requests to use struct fence

2016-01-11 Thread John Harrison

On 08/01/2016 21:59, Chris Wilson wrote:

On Fri, Jan 08, 2016 at 06:47:22PM +, john.c.harri...@intel.com wrote:

From: John Harrison 

There is a construct in the linux kernel called 'struct fence' that is
intended to keep track of work that is executed on hardware. I.e. it
solves the basic problem that the drivers 'struct
drm_i915_gem_request' is trying to address. The request structure does
quite a lot more than simply track the execution progress so is very
definitely still required. However, the basic completion status side
could be updated to use the ready made fence implementation and gain
all the advantages that provides.

This patch makes the first step of integrating a struct fence into the
request. It replaces the explicit reference count with that of the
fence. It also replaces the 'is completed' test with the fence's
equivalent. Currently, that simply chains on to the original request
implementation. A future patch will improve this.

But this forces everyone to do the heavyweight polling until the request
is completed?
Not sure what you mean by heavy weight polling. And as described, this 
is only an intermediate step.



The seqno is already CPU cacheable and with the exception
of interrupt polling, the question of whether a fence is complete can be
determined by just inspecting that value. Only one place (the
interrupt/signalling path) should ever be concerned about the
complication of how we emit the breadcrumb and interrupt from the ring.
There is still only one piece of code that needs to worry about the 
internal details. This is change is simply moving that around to make it 
easier to be interrupt driven later on (which is required for the 
scheduler).




-Chris



___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2 02/10] drm/i915: Cleanup phys status page too

2016-01-11 Thread ville . syrjala
From: Ville Syrjälä 

Restore the lost phys status page cleanup.

Fixes the following splat with DMA_API_DEBUG=y:

WARNING: CPU: 0 PID: 21615 at ../lib/dma-debug.c:974 
dma_debug_device_change+0x190/0x1f0()
pci :00:02.0: DMA-API: device driver has pending DMA allocations while 
released from device [count=1]
   One of leaked entries details: [device 
address=0x23163000] [size=4096 bytes] [mapped with DMA_BIDIRECTIONAL] 
[mapped as coherent]
Modules linked in: i915(-) i2c_algo_bit drm_kms_helper syscopyarea sysfillrect 
sysimgblt fb_sys_fops drm sha256_generic hmac drbg ctr ccm sch_fq_codel 
binfmt_misc joydev mousedev arc4 ath5k iTCO_wdt mac80211 smsc_ircc2 ath 
snd_intel8x0m snd_intel8x0 snd_ac97_codec ac97_bus psmouse snd_pcm input_leds 
i2c_i801 pcspkr snd_timer cfg80211 snd soundcore i2c_core ehci_pci 
firewire_ohci ehci_hcd firewire_core lpc_ich 8139too rfkill crc_itu_t mfd_core 
mii usbcore rng_core intel_agp intel_gtt usb_common agpgart irda crc_ccitt 
fujitsu_laptop led_class parport_pc video parport evdev backlight
CPU: 0 PID: 21615 Comm: rmmod Tainted: G U  4.4.0-rc4-mgm-ovl+ #4
Hardware name: FUJITSU SIEMENS LIFEBOOK S6120/FJNB16C, BIOS Version 1.26  
05/10/2004
 e31a3de0 e31a3de0 e31a3d9c c128d4bd e31a3dd0 c1045a0c c15e00c4 e31a3dfc
 546f c15dfad2 03ce c12b3740 03ce c12b3740  0001
 f61fb8a0 e31a3de8 c1045a83 0009 e31a3de0 c15e00c4 e31a3dfc e31a3e4c
Call Trace:
 [] dump_stack+0x16/0x19
 [] warn_slowpath_common+0x8c/0xd0
 [] ? dma_debug_device_change+0x190/0x1f0
 [] ? dma_debug_device_change+0x190/0x1f0
 [] warn_slowpath_fmt+0x33/0x40
 [] dma_debug_device_change+0x190/0x1f0
 [] notifier_call_chain+0x59/0x70
 [] __blocking_notifier_call_chain+0x3f/0x80
 [] blocking_notifier_call_chain+0x1f/0x30
 [] __device_release_driver+0xc3/0xf0
 [] driver_detach+0x97/0xa0
 [] bus_remove_driver+0x40/0x90
 [] driver_unregister+0x28/0x60
 [] ? trace_hardirqs_on_caller+0x12c/0x1d0
 [] pci_unregister_driver+0x18/0x80
 [] drm_pci_exit+0x87/0xb0 [drm]
 [] i915_exit+0x1b/0x1ee [i915]
 [] SyS_delete_module+0x14c/0x210
 [] ? trace_hardirqs_on_caller+0x12c/0x1d0
 [] ? fput+0xd/0x10
 [] do_fast_syscall_32+0xa4/0x450
 [] sysenter_past_esp+0x3b/0x5d
---[ end trace c2ecbc77760f10a0 ]---
Mapped at:
 [] debug_dma_alloc_coherent+0x33/0x90
 [] drm_pci_alloc+0x18c/0x1e0 [drm]
 [] intel_init_ring_buffer+0x2af/0x490 [i915]
 [] intel_init_render_ring_buffer+0x130/0x750 [i915]
 [] i915_gem_init_rings+0x1e/0x110 [i915]

v2: s/BUG_ON/WARN_ON/ since dim doens't like the former anymore

Cc: Chris Wilson 
Fixes: 5c6c600 ("drm/i915: Remove DRI1 ring accessors and API")
Signed-off-by: Ville Syrjälä 
Reviewed-by: Chris Wilson  (v1)
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 339701d7a9a5..d9e0b400294d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1899,6 +1899,17 @@ i915_dispatch_execbuffer(struct drm_i915_gem_request 
*req,
return 0;
 }
 
+static void cleanup_phys_status_page(struct intel_engine_cs *ring)
+{
+   struct drm_i915_private *dev_priv = to_i915(ring->dev);
+
+   if (!dev_priv->status_page_dmah)
+   return;
+
+   drm_pci_free(ring->dev, dev_priv->status_page_dmah);
+   ring->status_page.page_addr = NULL;
+}
+
 static void cleanup_status_page(struct intel_engine_cs *ring)
 {
struct drm_i915_gem_object *obj;
@@ -1915,9 +1926,9 @@ static void cleanup_status_page(struct intel_engine_cs 
*ring)
 
 static int init_status_page(struct intel_engine_cs *ring)
 {
-   struct drm_i915_gem_object *obj;
+   struct drm_i915_gem_object *obj = ring->status_page.obj;
 
-   if ((obj = ring->status_page.obj) == NULL) {
+   if (obj == NULL) {
unsigned flags;
int ret;
 
@@ -2162,7 +2173,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
if (ret)
goto error;
} else {
-   BUG_ON(ring->id != RCS);
+   WARN_ON(ring->id != RCS);
ret = init_phys_status_page(ring);
if (ret)
goto error;
@@ -2208,7 +2219,12 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs 
*ring)
if (ring->cleanup)
ring->cleanup(ring);
 
-   cleanup_status_page(ring);
+   if (I915_NEED_GFX_HWS(ring->dev)) {
+   cleanup_status_page(ring);
+   } else {
+   WARN_ON(ring->id != RCS);
+   cleanup_phys_status_page(ring);
+   }
 
i915_cmd_parser_fini_ring(ring);
i915_gem_batch_pool_fini(&ring->batch_pool);
-- 
2.4.10

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v4 27/38] drm/i915: Added debugfs interface to scheduler tuning parameters

2016-01-11 Thread John . C . Harrison
From: John Harrison 

There are various parameters within the scheduler which can be tuned
to improve performance, reduce memory footprint, etc. This change adds
support for altering these via debugfs.

v2: Updated for priorities now being signed values.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 141 
 1 file changed, 141 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e55294c..611e691 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -39,6 +39,7 @@
 #include "intel_ringbuffer.h"
 #include 
 #include "i915_drv.h"
+#include "i915_scheduler.h"
 
 enum {
ACTIVE_LIST,
@@ -1122,6 +1123,141 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
i915_next_seqno_get, i915_next_seqno_set,
"0x%llx\n");
 
+static int
+i915_scheduler_priority_min_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = (u64) scheduler->priority_level_min;
+   return 0;
+}
+
+static int
+i915_scheduler_priority_min_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->priority_level_min = (int32_t) val;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_priority_min_fops,
+   i915_scheduler_priority_min_get,
+   i915_scheduler_priority_min_set,
+   "%lld\n");
+
+static int
+i915_scheduler_priority_max_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = (u64) scheduler->priority_level_max;
+   return 0;
+}
+
+static int
+i915_scheduler_priority_max_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->priority_level_max = (int32_t) val;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_priority_max_fops,
+   i915_scheduler_priority_max_get,
+   i915_scheduler_priority_max_set,
+   "%lld\n");
+
+static int
+i915_scheduler_priority_preempt_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = (u64) scheduler->priority_level_preempt;
+   return 0;
+}
+
+static int
+i915_scheduler_priority_preempt_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->priority_level_preempt = (u32) val;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_priority_preempt_fops,
+   i915_scheduler_priority_preempt_get,
+   i915_scheduler_priority_preempt_set,
+   "%lld\n");
+
+static int
+i915_scheduler_min_flying_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = (u64) scheduler->min_flying;
+   return 0;
+}
+
+static int
+i915_scheduler_min_flying_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->min_flying = (u32) val;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_min_flying_fops,
+   i915_scheduler_min_flying_get,
+   i915_scheduler_min_flying_set,
+   "%llu\n");
+
+static int
+i915_scheduler_file_queue_max_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = (u64) scheduler->file_queue_max;
+   return 0;
+}
+
+static int
+i915_scheduler_file_queue_max_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->file

[Intel-gfx] [PATCH v4 21/38] drm/i915: Added a module parameter for allowing scheduler overrides

2016-01-11 Thread John . C . Harrison
From: John Harrison 

It can be useful to be able to disable certain features (e.g. the
entire scheduler) via a module parameter for debugging purposes. A
parameter has the advantage of not being a compile time switch but
without implying that it can be changed dynamically at runtime.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_drv.h   | 1 +
 drivers/gpu/drm/i915/i915_params.c| 4 
 drivers/gpu/drm/i915/i915_scheduler.c | 5 -
 drivers/gpu/drm/i915/i915_scheduler.h | 5 +
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2906bb0..8d6d07a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2709,6 +2709,7 @@ struct i915_params {
bool verbose_state_checks;
bool nuclear_pageflip;
int edp_vswing;
+   int scheduler_override;
 };
 extern struct i915_params i915 __read_mostly;
 
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index ba7274a..be2e16c 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -54,6 +54,7 @@ struct i915_params i915 __read_mostly = {
.edp_vswing = 0,
.enable_guc_submission = true,
.guc_log_level = -1,
+   .scheduler_override = 1,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -191,3 +192,6 @@ MODULE_PARM_DESC(enable_guc_submission, "Enable GuC 
submission (default:false)")
 module_param_named(guc_log_level, i915.guc_log_level, int, 0400);
 MODULE_PARM_DESC(guc_log_level,
"GuC firmware logging level (-1:disabled (default), 0-3:enabled)");
+
+module_param_named(scheduler_override, i915.scheduler_override, int, 0600);
+MODULE_PARM_DESC(scheduler_override, "Scheduler override mask (0 = none, 1 = 
direct submission [default])");
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index bd52752..bfde3a2 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -44,6 +44,9 @@ bool i915_scheduler_is_enabled(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
+   if (i915.scheduler_override & i915_so_direct_submit)
+   return false;
+
return dev_priv->scheduler != NULL;
 }
 
@@ -144,7 +147,7 @@ int i915_scheduler_queue_execbuffer(struct 
i915_scheduler_queue_entry *qe)
 
WARN_ON(!scheduler);
 
-   if (1/*i915.scheduler_override & i915_so_direct_submit*/) {
+   if (i915.scheduler_override & i915_so_direct_submit) {
int ret;
 
intel_ring_reserved_space_cancel(qe->params.request->ringbuf);
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index 7654013..cc9205b 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -84,6 +84,11 @@ enum {
i915_sf_submitting  = (1 << 1),
 };
 
+/* Options for 'scheduler_override' module parameter: */
+enum {
+   i915_so_direct_submit   = (1 << 0),
+};
+
 booli915_scheduler_is_enabled(struct drm_device *dev);
 int i915_scheduler_init(struct drm_device *dev);
 int i915_scheduler_closefile(struct drm_device *dev,
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 30/38] drm/i915: Added scheduler statistic reporting to debugfs

2016-01-11 Thread John . C . Harrison
From: John Harrison 

It is useful for know what the scheduler is doing for both debugging
and performance analysis purposes. This change adds a bunch of
counters and such that keep track of various scheduler operations
(batches submitted, completed, flush requests, etc.). The data can
then be read in userland via the debugfs mechanism.

v2: Updated to match changes to scheduler implementation.

v3: Updated for changes to kill code and flush code.

v4: Removed the fence/sync code as that will be part of a separate
patch series. Wrapped a long line to keep the style checker happy.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_debugfs.c| 73 ++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 +
 drivers/gpu/drm/i915/i915_scheduler.c  | 70 ++--
 drivers/gpu/drm/i915/i915_scheduler.h  | 31 +
 4 files changed, 171 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 611e691..73d0f97 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3602,6 +3602,78 @@ static int i915_drrs_status(struct seq_file *m, void 
*unused)
return 0;
 }
 
+static int i915_scheduler_info(struct seq_file *m, void *unused)
+{
+   struct drm_info_node *node = (struct drm_info_node *) m->private;
+   struct drm_device *dev = node->minor->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+   struct i915_scheduler_stats *stats = scheduler->stats;
+   struct i915_scheduler_stats_nodes node_stats[I915_NUM_RINGS];
+   struct intel_engine_cs *ring;
+   char   str[50 * (I915_NUM_RINGS + 1)], name[50], *ptr;
+   int ret, i, r;
+
+   ret = mutex_lock_interruptible(&dev->mode_config.mutex);
+   if (ret)
+   return ret;
+
+#define PRINT_VAR(name, fmt, var)  \
+   do {\
+   sprintf(str, "%-22s", name);\
+   ptr = str + strlen(str);\
+   for_each_ring(ring, dev_priv, r) {  \
+   sprintf(ptr, " %10" fmt, var);  \
+   ptr += strlen(ptr); \
+   }   \
+   seq_printf(m, "%s\n", str); \
+   } while (0)
+
+   PRINT_VAR("Ring name:", "s", dev_priv->ring[r].name);
+   PRINT_VAR("  Ring seqno",   "d", ring->get_seqno(ring, false));
+   seq_putc(m, '\n');
+
+   seq_puts(m, "Batch submissions:\n");
+   PRINT_VAR("  Queued",   "u", stats[r].queued);
+   PRINT_VAR("  Submitted","u", stats[r].submitted);
+   PRINT_VAR("  Completed","u", stats[r].completed);
+   PRINT_VAR("  Expired",  "u", stats[r].expired);
+   seq_putc(m, '\n');
+
+   seq_puts(m, "Flush counts:\n");
+   PRINT_VAR("  By object","u", stats[r].flush_obj);
+   PRINT_VAR("  By request",   "u", stats[r].flush_req);
+   PRINT_VAR("  By stamp", "u", stats[r].flush_stamp);
+   PRINT_VAR("  Blanket",  "u", stats[r].flush_all);
+   PRINT_VAR("  Entries bumped",   "u", stats[r].flush_bump);
+   PRINT_VAR("  Entries submitted","u", stats[r].flush_submit);
+   seq_putc(m, '\n');
+
+   seq_puts(m, "Miscellaneous:\n");
+   PRINT_VAR("  ExecEarly retry",  "u", stats[r].exec_early);
+   PRINT_VAR("  ExecFinal requeue","u", stats[r].exec_again);
+   PRINT_VAR("  ExecFinal killed", "u", stats[r].exec_dead);
+   PRINT_VAR("  Hung flying",  "u", stats[r].kill_flying);
+   PRINT_VAR("  Hung queued",  "u", stats[r].kill_queued);
+   seq_putc(m, '\n');
+
+   seq_puts(m, "Queue contents:\n");
+   for_each_ring(ring, dev_priv, i)
+   i915_scheduler_query_stats(ring, node_stats + ring->id);
+
+   for (i = 0; i < (i915_sqs_MAX + 1); i++) {
+   sprintf(name, "  %s", i915_scheduler_queue_status_str(i));
+   PRINT_VAR(name, "d", node_stats[r].counts[i]);
+   }
+   seq_putc(m, '\n');
+
+#undef PRINT_VAR
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+
 struct pipe_crc_info {
const char *name;
struct drm_device *dev;
@@ -5570,6 +5642,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_semaphore_status", i915_semaphore_status, 0},
{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
{"i915_dp_mst_info", i915_dp_mst_info, 0},
+   {"i915_scheduler_info", i915_scheduler_info, 0},
{"i915_wa_reg

[Intel-gfx] [PATCH v4 22/38] drm/i915: Support for 'unflushed' ring idle

2016-01-11 Thread John . C . Harrison
From: John Harrison 

When the seqno wraps around zero, the entire GPU is forced to be idle
for some reason (possibly only to work around issues with hardware
semaphores but no-one seems too sure!). This causes a problem if the
force idle occurs at an inopportune moment such as in the middle of
submitting a batch buffer. Specifically, it would lead to recursive
submits - submitting work requires a new seqno, the new seqno requires
idling the ring, idling the ring requires submitting work, submitting
work requires a new seqno...

This change adds a 'flush' parameter to the idle function call which
specifies whether the scheduler queues should be flushed out. I.e. is
the call intended to just idle the ring as it is right now (no flush)
or is it intended to force all outstanding work out of the system
(with flush).

In the seqno wrap case, pending work is not an issue because the next
operation will be to submit it. However, in other cases, the intention
is to make sure everything that could be done has been done.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_gem.c |  4 ++--
 drivers/gpu/drm/i915/intel_lrc.c|  2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c | 17 +++--
 drivers/gpu/drm/i915/intel_ringbuffer.h |  2 +-
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6ea0896..073b334 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2510,7 +2510,7 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno)
 
/* Carefully retire all requests without writing to the rings */
for_each_ring(ring, dev_priv, i) {
-   ret = intel_ring_idle(ring);
+   ret = intel_ring_idle(ring, false);
if (ret)
return ret;
}
@@ -3753,7 +3753,7 @@ int i915_gpu_idle(struct drm_device *dev)
i915_add_request_no_flush(req);
}
 
-   ret = intel_ring_idle(ring);
+   ret = intel_ring_idle(ring, true);
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7ea4d96..d8ddf18 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1014,7 +1014,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring)
if (!intel_ring_initialized(ring))
return;
 
-   ret = intel_ring_idle(ring);
+   ret = intel_ring_idle(ring, true);
if (ret && !i915_reset_in_progress(&to_i915(ring->dev)->gpu_error))
DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
  ring->name, ret);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 0ae70a6..3f3d928 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2278,9 +2278,22 @@ static void __wrap_ring_buffer(struct intel_ringbuffer 
*ringbuf)
intel_ring_update_space(ringbuf);
 }
 
-int intel_ring_idle(struct intel_engine_cs *ring)
+int intel_ring_idle(struct intel_engine_cs *ring, bool flush)
 {
struct drm_i915_gem_request *req;
+   int ret;
+
+   /*
+* NB: Must not flush the scheduler if this idle request is from
+* within an execbuff submission (i.e. due to 'get_seqno' calling
+* 'wrap_seqno' calling 'idle'). As that would lead to recursive
+* flushes!
+*/
+   if (flush) {
+   ret = i915_scheduler_flush(ring, true);
+   if (ret)
+   return ret;
+   }
 
/* Wait upon the last request to be completed */
if (list_empty(&ring->request_list))
@@ -3085,7 +3098,7 @@ intel_stop_ring_buffer(struct intel_engine_cs *ring)
if (!intel_ring_initialized(ring))
return;
 
-   ret = intel_ring_idle(ring);
+   ret = intel_ring_idle(ring, true);
if (ret && !i915_reset_in_progress(&to_i915(ring->dev)->gpu_error))
DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
  ring->name, ret);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index a103019..136a039 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -465,7 +465,7 @@ void intel_ring_update_space(struct intel_ringbuffer 
*ringbuf);
 int intel_ring_space(struct intel_ringbuffer *ringbuf);
 bool intel_ring_stopped(struct intel_engine_cs *ring);
 
-int __must_check intel_ring_idle(struct intel_engine_cs *ring);
+int __must_check intel_ring_idle(struct intel_engine_cs *ring, bool flush);
 void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno);
 int intel_ring_flush_all_caches(struct drm_i915_gem_request *req);
 int intel_ring_invalidat

[Intel-gfx] [PATCH v4 31/38] drm/i915: Added seqno values to scheduler status dump

2016-01-11 Thread John . C . Harrison
From: John Harrison 

It is useful to be able to see what seqnos have actually popped out of
the hardware when viewing the scheduler status.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_scheduler.c | 10 ++
 drivers/gpu/drm/i915/i915_scheduler.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 666e142..c93f69e 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -153,6 +153,7 @@ const char *i915_scheduler_flag_str(uint32_t flags)
TEST_FLAG(i915_sf_dump_force, "DumpForce|");
TEST_FLAG(i915_sf_dump_details,   "DumpDetails|");
TEST_FLAG(i915_sf_dump_dependencies,  "DumpDeps|");
+   TEST_FLAG(i915_sf_dump_seqno, "DumpSeqno|");
 
 #undef TEST_FLAG
 
@@ -787,6 +788,7 @@ static int i915_scheduler_dump_all_locked(struct drm_device 
*dev,
for_each_ring(ring, dev_priv, i) {
scheduler->flags[ring->id] |= i915_sf_dump_force   |
  i915_sf_dump_details |
+ i915_sf_dump_seqno   |
  i915_sf_dump_dependencies;
r = i915_scheduler_dump_locked(ring, msg);
if (ret == 0)
@@ -869,6 +871,14 @@ static int i915_scheduler_dump_locked(struct 
intel_engine_cs *ring,
return 0;
}
 
+   if (scheduler->flags[ring->id] & i915_sf_dump_seqno) {
+   uint32_tseqno;
+
+   seqno= ring->get_seqno(ring, true);
+
+   DRM_DEBUG_DRIVER("<%s> Seqno = %d\n", ring->name, seqno);
+   }
+
if (scheduler->flags[ring->id] & i915_sf_dump_details) {
int i, deps;
uint32_tcount, counts[i915_sqs_MAX];
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index eff5d8f..1cf40fc 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -122,6 +122,7 @@ enum {
i915_sf_dump_force  = (1 << 8),
i915_sf_dump_details= (1 << 9),
i915_sf_dump_dependencies   = (1 << 10),
+   i915_sf_dump_seqno  = (1 << 11),
 };
 const char *i915_scheduler_flag_str(uint32_t flags);
 
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 12/38] drm/i915: Added scheduler hook into i915_gem_request_notify()

2016-01-11 Thread John . C . Harrison
From: John Harrison 

The scheduler needs to know when requests have completed so that it
can keep its own internal state up to date and can submit new requests
to the hardware from its queue.

v2: Updated due to changes in request handling. The operation is now
reversed from before. Rather than the scheduler being in control of
completion events, it is now the request code itself. The scheduler
merely receives a notification event. It can then optionally request
it's worker thread be woken up after all completion processing is
complete.

v4: Downgraded a BUG_ON to a WARN_ON as the latter is preferred.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 ++
 drivers/gpu/drm/i915/i915_gem.c   | 16 
 drivers/gpu/drm/i915/i915_scheduler.c | 28 ++--
 drivers/gpu/drm/i915/i915_scheduler.h |  1 +
 4 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 38f423b..ac4d44b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2262,6 +2262,8 @@ struct drm_i915_gem_request {
/** process identifier submitting this request */
struct pid *pid;
 
+   struct i915_scheduler_queue_entry   *scheduler_qe;
+
/**
 * The ELSP only accepts two elements at a time, so we queue
 * context/tail pairs on a given queue (ring->execlist_queue) until the
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d4f1d63..3d109b4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2817,6 +2817,7 @@ void i915_gem_request_notify(struct intel_engine_cs 
*ring, bool fence_locked)
 {
struct drm_i915_gem_request *req, *req_next;
unsigned long flags;
+   bool wake_sched = false;
u32 seqno;
 
if (list_empty(&ring->fence_signal_list)) {
@@ -2852,6 +2853,14 @@ void i915_gem_request_notify(struct intel_engine_cs 
*ring, bool fence_locked)
 */
list_del_init(&req->signal_link);
 
+   /*
+* NB: Must notify the scheduler before signalling
+* the node. Otherwise the node can get retired first
+* and call scheduler_clean() while the scheduler
+* thinks it is still active.
+*/
+   wake_sched |= i915_scheduler_notify_request(req);
+
if (!req->cancelled) {
fence_signal_locked(&req->fence);
trace_i915_gem_request_complete(req);
@@ -2868,6 +2877,13 @@ void i915_gem_request_notify(struct intel_engine_cs 
*ring, bool fence_locked)
 
if (!fence_locked)
spin_unlock_irqrestore(&ring->fence_lock, flags);
+
+   /* Necessary? Or does the fence_signal() call do an implicit wakeup? */
+   wake_up_all(&ring->irq_queue);
+
+   /* Final scheduler processing after all individual updates are done. */
+   if (wake_sched)
+   i915_scheduler_wakeup(ring->dev);
 }
 
 static const char *i915_gem_request_get_driver_name(struct fence *req_fence)
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 26cd088..ac0a6172 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -174,6 +174,9 @@ int i915_scheduler_queue_execbuffer(struct 
i915_scheduler_queue_entry *qe)
node->stamp  = jiffies;
i915_gem_request_reference(node->params.request);
 
+   WARN_ON(node->params.request->scheduler_qe);
+   node->params.request->scheduler_qe = node;
+
/* Need to determine the number of incomplete entries in the list as
 * that will be the maximum size of the dependency list.
 *
@@ -350,14 +353,16 @@ static void i915_scheduler_node_kill(struct 
i915_scheduler_queue_entry *node)
  * code has mapped it back to a request and will mark that request complete.
  * It also calls this function to notify the scheduler about the completion
  * so the scheduler's node can be updated appropriately.
- * Returns true if the request is scheduler managed, false if not.
+ * Returns true if the request is scheduler managed, false if not. The return
+ * value is combined for all freshly completed requests and if any were true
+ * then i915_scheduler_wakeup() is called so the scheduler can do further
+ * processing (submit more work) at the end.
  */
 bool i915_scheduler_notify_request(struct drm_i915_gem_request *req)
 {
struct drm_i915_private *dev_priv  = to_i915(req->ring->dev);
struct i915_scheduler   *scheduler = dev_priv->scheduler;
-   /* XXX: Need to map back from request to node */
-   struct i915_scheduler_queue_entry *node = NULL;
+   struct i915_scheduler_queue_entry *node = req->scheduler_qe;
unsigned long   flags;
 
if (!node)
@@ -375,16 +380,18 

[Intel-gfx] [PATCH v4 36/38] drm/i915: Add scheduling priority to per-context parameters

2016-01-11 Thread John . C . Harrison
From: Dave Gordon 

Added an interface for user land applications/libraries/services to
set their GPU scheduler priority. This extends the existing context
parameter IOCTL interface to add a scheduler priority parameter. The
range is +/-1023 with +ve numbers meaning higher priority. Only
system processes may set a higher priority than the default (zero),
normal applications may only lower theirs.

v2: New patch in series.

For: VIZ-1587
Signed-off-by: Dave Gordon 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_drv.h| 14 ++
 drivers/gpu/drm/i915/i915_gem_context.c| 24 
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  3 +++
 include/uapi/drm/i915_drm.h|  1 +
 4 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1df2a2f..f7cd9dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -843,6 +843,19 @@ struct i915_ctx_hang_stats {
bool banned;
 };
 
+/*
+ * User-settable GFX scheduler priorities are on a scale of -1023 (I don't
+ * care about running) to +1023 (I'm the most important thing in existence)
+ * with zero being the default. Any process may decrease its scheduling
+ * priority, but only a sufficiently privileged process may increase it
+ * beyond zero.
+ */
+
+struct i915_ctx_sched_info {
+   /* Scheduling priority */
+   int32_t priority;
+};
+
 struct i915_fence_timeline {
charname[32];
unsignedfence_context;
@@ -883,6 +896,7 @@ struct intel_context {
int flags;
struct drm_i915_file_private *file_priv;
struct i915_ctx_hang_stats hang_stats;
+   struct i915_ctx_sched_info sched_info;
struct i915_hw_ppgtt *ppgtt;
 
/* Legacy ring buffer submission */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 4570edd..84aa942 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -947,6 +947,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, 
void *data,
else
args->value = to_i915(dev)->gtt.base.total;
break;
+   case I915_CONTEXT_PARAM_PRIORITY:
+   args->value = (__u64) ctx->sched_info.priority;
+   break;
default:
ret = -EINVAL;
break;
@@ -984,6 +987,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, 
void *data,
else
ctx->hang_stats.ban_period_seconds = args->value;
break;
+
case I915_CONTEXT_PARAM_NO_ZEROMAP:
if (args->size) {
ret = -EINVAL;
@@ -992,6 +996,26 @@ int i915_gem_context_setparam_ioctl(struct drm_device 
*dev, void *data,
ctx->flags |= args->value ? CONTEXT_NO_ZEROMAP : 0;
}
break;
+
+   case I915_CONTEXT_PARAM_PRIORITY:
+   {
+   int32_t priority = (int32_t) args->value;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   if (args->size)
+   ret = -EINVAL;
+   else if ((priority > scheduler->priority_level_max) ||
+(priority < scheduler->priority_level_min))
+   ret = -EINVAL;
+   else if ((priority > 0) &&
+!capable(CAP_SYS_ADMIN))
+   ret = -EPERM;
+   else
+   ctx->sched_info.priority = priority;
+   break;
+   }
+
default:
ret = -EINVAL;
break;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index a752b7f..069a0a4 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1662,6 +1662,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
params->args_DR4= args->DR4;
params->batch_obj   = batch_obj;
 
+   /* Start with the context's priority level */
+   qe.priority = ctx->sched_info.priority;
+
/*
 * Save away the list of objects used by this batch buffer for the
 * purpose of tracking inter-buffer dependencies.
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 67cebe6..86a255c 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1128,6 +1128,7 @@ struct drm_i915_gem_context_param {
 #define I915_CONTEXT_PARAM_BAN_PERIOD  0x1
 #define I915_CONTEXT_PARAM_NO_ZEROMAP  0x2
 #define I915_CONTEXT_PARAM_GTT_SIZE0x3
+#define I915_CONTEXT_PARAM_PRIORITY0x4
__u64 value;
 };
 
-- 
1.9.1

___
In

[Intel-gfx] [PATCH v4 09/38] drm/i915: Disable hardware semaphores when GPU scheduler is enabled

2016-01-11 Thread John . C . Harrison
From: John Harrison 

Hardware sempahores require seqno values to be continuously
incrementing. However, the scheduler's reordering of batch buffers
means that the seqno values going through the hardware could be out of
order. Thus semaphores can not be used.

On the other hand, the scheduler superceeds the need for hardware
semaphores anyway. Having one ring stall waiting for something to
complete on another ring is inefficient if that ring could be working
on some other, independent task. This is what the scheduler is meant
to do - keep the hardware as busy as possible by reordering batch
buffers to avoid dependency stalls.

v4: Downgraded a BUG_ON to WARN_ON as the latter is preferred.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_drv.c | 9 +
 drivers/gpu/drm/i915/i915_scheduler.c   | 7 +++
 drivers/gpu/drm/i915/i915_scheduler.h   | 1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c | 4 
 4 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 858d58c..e6be8f5 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -34,6 +34,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include "i915_scheduler.h"
 
 #include 
 #include 
@@ -581,6 +582,14 @@ void intel_detect_pch(struct drm_device *dev)
 
 bool i915_semaphore_is_enabled(struct drm_device *dev)
 {
+   /* Hardware semaphores are not compatible with the scheduler due to the
+* seqno values being potentially out of order. However, semaphores are
+* also not required as the scheduler will handle interring dependencies
+* and try do so in a way that does not cause dead time on the hardware.
+*/
+   if (i915_scheduler_is_enabled(dev))
+   return false;
+
if (INTEL_INFO(dev)->gen < 6)
return false;
 
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 8cb9063..fc48955 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -38,6 +38,13 @@ static int i915_scheduler_priority_bump(struct 
i915_scheduler *scheduler
struct 
i915_scheduler_queue_entry *target,
uint32_t bump);
 
+bool i915_scheduler_is_enabled(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
+   return dev_priv->scheduler != NULL;
+}
+
 int i915_scheduler_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index 00dc7f3..2d50d83 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -84,6 +84,7 @@ enum {
i915_sf_submitting  = (1 << 1),
 };
 
+booli915_scheduler_is_enabled(struct drm_device *dev);
 int i915_scheduler_init(struct drm_device *dev);
 int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry 
*qe);
 booli915_scheduler_notify_request(struct drm_i915_gem_request *req);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1dec252..a93bbce 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -32,6 +32,7 @@
 #include 
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include "i915_scheduler.h"
 
 bool
 intel_ring_initialized(struct intel_engine_cs *ring)
@@ -1411,6 +1412,9 @@ gen6_ring_sync(struct drm_i915_gem_request *waiter_req,
u32 wait_mbox = signaller->semaphore.mbox.wait[waiter->id];
int ret;
 
+   /* Arithmetic on sequence numbers is unreliable with a scheduler. */
+   WARN_ON(i915_scheduler_is_enabled(signaller->dev));
+
/* Throughout all of the GEM code, seqno passed implies our current
 * seqno is >= the last seqno executed. However for hardware the
 * comparison is strictly greater than.
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 37/38] drm/i915: Add support for retro-actively banning batch buffers

2016-01-11 Thread John . C . Harrison
From: John Harrison 

If a given context submits too many hanging batch buffers then it will
be banned and no further batch buffers will be accepted for it.
However, it is possible that a large number of buffers may already
have been accepted and are sat in the scheduler waiting to be
executed. This patch adds a late ban check to ensure that these will
also be discarded.

v4: New patch in series.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 ++
 drivers/gpu/drm/i915/intel_lrc.c   | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 069a0a4..cb076e1 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1244,6 +1244,12 @@ int i915_gem_ringbuffer_submission_final(struct 
i915_execbuffer_params *params)
/* The mutex must be acquired before calling this function */
WARN_ON(!mutex_is_locked(¶ms->dev->struct_mutex));
 
+   /* Check the context wasn't banned between submission and execution: */
+   if (params->ctx->hang_stats.banned) {
+   DRM_DEBUG("Trying to execute for banned context!\n");
+   return -ENOENT;
+   }
+
/* Make sure the request's seqno is the latest and greatest: */
if (req->reserved_seqno != dev_priv->last_seqno) {
ret = i915_gem_get_seqno(ring->dev, &req->reserved_seqno);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ae5dd0a..b2861aa 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -958,6 +958,12 @@ int intel_execlists_submission_final(struct 
i915_execbuffer_params *params)
/* The mutex must be acquired before calling this function */
WARN_ON(!mutex_is_locked(¶ms->dev->struct_mutex));
 
+   /* Check the context wasn't banned between submission and execution: */
+   if (params->ctx->hang_stats.banned) {
+   DRM_DEBUG("Trying to execute for banned context!\n");
+   return -ENOENT;
+   }
+
/* Make sure the request's seqno is the latest and greatest: */
if (req->reserved_seqno != dev_priv->last_seqno) {
ret = i915_gem_get_seqno(ring->dev, &req->reserved_seqno);
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 28/38] drm/i915: Added debug state dump facilities to scheduler

2016-01-11 Thread John . C . Harrison
From: John Harrison 

When debugging batch buffer submission issues, it is useful to be able
to see what the current state of the scheduler is. This change adds
functions for decoding the internal scheduler state and reporting it.

v3: Updated a debug message with the new state_str() function.

v4: Wrapped some long lines to keep the style checker happy. Removed
the fence/sync code as that will now be part of a separate patch series.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_scheduler.c | 281 +-
 drivers/gpu/drm/i915/i915_scheduler.h |  14 ++
 2 files changed, 293 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index be5df22..2b4b74f 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -35,6 +35,10 @@ static int i915_scheduler_submit_max_priority(struct 
intel_engine_cs *ri
  bool is_locked);
 static uint32_ti915_scheduler_count_flying(struct i915_scheduler 
*scheduler,
   struct intel_engine_cs *ring);
+static int i915_scheduler_dump_locked(struct intel_engine_cs *ring,
+ const char *msg);
+static int i915_scheduler_dump_all_locked(struct drm_device *dev,
+ const char *msg);
 static voidi915_scheduler_priority_bump_clear(struct i915_scheduler 
*scheduler);
 static int i915_scheduler_priority_bump(struct i915_scheduler 
*scheduler,
struct 
i915_scheduler_queue_entry *target,
@@ -52,6 +56,116 @@ bool i915_scheduler_is_enabled(struct drm_device *dev)
return dev_priv->scheduler != NULL;
 }
 
+const char *i915_qe_state_str(struct i915_scheduler_queue_entry *node)
+{
+   static char str[50];
+   char*ptr = str;
+
+   *(ptr++) = node->bumped ? 'B' : '-',
+   *(ptr++) = i915_gem_request_completed(node->params.request) ? 'C' : '-';
+
+   *ptr = 0;
+
+   return str;
+}
+
+char i915_scheduler_queue_status_chr(enum i915_scheduler_queue_status status)
+{
+   switch (status) {
+   case i915_sqs_none:
+   return 'N';
+
+   case i915_sqs_queued:
+   return 'Q';
+
+   case i915_sqs_popped:
+   return 'X';
+
+   case i915_sqs_flying:
+   return 'F';
+
+   case i915_sqs_complete:
+   return 'C';
+
+   case i915_sqs_dead:
+   return 'D';
+
+   default:
+   break;
+   }
+
+   return '?';
+}
+
+const char *i915_scheduler_queue_status_str(
+   enum i915_scheduler_queue_status status)
+{
+   static char str[50];
+
+   switch (status) {
+   case i915_sqs_none:
+   return "None";
+
+   case i915_sqs_queued:
+   return "Queued";
+
+   case i915_sqs_popped:
+   return "Popped";
+
+   case i915_sqs_flying:
+   return "Flying";
+
+   case i915_sqs_complete:
+   return "Complete";
+
+   case i915_sqs_dead:
+   return "Dead";
+
+   default:
+   break;
+   }
+
+   sprintf(str, "[Unknown_%d!]", status);
+   return str;
+}
+
+const char *i915_scheduler_flag_str(uint32_t flags)
+{
+   static char str[100];
+   char   *ptr = str;
+
+   *ptr = 0;
+
+#define TEST_FLAG(flag, msg)   \
+   do {\
+   if (flags & (flag)) {   \
+   strcpy(ptr, msg);   \
+   ptr += strlen(ptr); \
+   flags &= ~(flag);   \
+   }   \
+   } while (0)
+
+   TEST_FLAG(i915_sf_interrupts_enabled, "IntOn|");
+   TEST_FLAG(i915_sf_submitting, "Submitting|");
+   TEST_FLAG(i915_sf_dump_force, "DumpForce|");
+   TEST_FLAG(i915_sf_dump_details,   "DumpDetails|");
+   TEST_FLAG(i915_sf_dump_dependencies,  "DumpDeps|");
+
+#undef TEST_FLAG
+
+   if (flags) {
+   sprintf(ptr, "Unknown_0x%X!", flags);
+   ptr += strlen(ptr);
+   }
+
+   if (ptr == str)
+   strcpy(str, "-");
+   else
+   ptr[-1] = 0;
+
+   return str;
+};
+
 int i915_scheduler_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -630,6 +744,169 @@ void i915_gem_scheduler_work_handler(struct work_struct 
*work)
}
 }
 
+int i915_scheduler_dump_all(struct drm_device *dev, const char *msg)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->sc

[Intel-gfx] [PATCH v4 26/38] drm/i915: Added scheduler queue throttling by DRM file handle

2016-01-11 Thread John . C . Harrison
From: John Harrison 

The scheduler decouples the submission of batch buffers to the driver
from their subsequent submission to the hardware. This means that an
application which is continuously submitting buffers as fast as it can
could potentialy flood the driver. To prevent this, the driver now
tracks how many buffers are in progress (queued in software or
executing in hardware) and limits this to a given (tunable) number. If
this number is exceeded then the queue to the driver will return
EAGAIN and thus prevent the scheduler's queue becoming arbitrarily
large.

v3: Added a missing decrement of the file queue counter.

v4: Updated a comment.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_drv.h|  2 ++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  8 +++
 drivers/gpu/drm/i915/i915_scheduler.c  | 35 ++
 drivers/gpu/drm/i915/i915_scheduler.h  |  2 ++
 4 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a304918..1df2a2f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -342,6 +342,8 @@ struct drm_i915_file_private {
} rps;
 
struct intel_engine_cs *bsd_ring;
+
+   u32 scheduler_queue_length;
 };
 
 enum intel_dpll_id {
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 87a8059..de8607e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1756,6 +1756,10 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
 
+   /* Throttle batch requests per device file */
+   if (i915_scheduler_file_queue_is_full(file))
+   return -EAGAIN;
+
/* Copy in the exec list from userland */
exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
@@ -1844,6 +1848,10 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EINVAL;
}
 
+   /* Throttle batch requests per device file */
+   if (i915_scheduler_file_queue_is_full(file))
+   return -EAGAIN;
+
exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
 GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
if (exec2_list == NULL)
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 02b458f..be5df22 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -39,6 +39,8 @@ static voidi915_scheduler_priority_bump_clear(struct 
i915_scheduler *sch
 static int i915_scheduler_priority_bump(struct i915_scheduler 
*scheduler,
struct 
i915_scheduler_queue_entry *target,
uint32_t bump);
+static voidi915_scheduler_file_queue_inc(struct drm_file *file);
+static voidi915_scheduler_file_queue_dec(struct drm_file *file);
 
 bool i915_scheduler_is_enabled(struct drm_device *dev)
 {
@@ -73,6 +75,7 @@ int i915_scheduler_init(struct drm_device *dev)
scheduler->priority_level_max = 1023;
scheduler->priority_level_preempt = 900;
scheduler->min_flying = 2;
+   scheduler->file_queue_max = 64;
 
dev_priv->scheduler = scheduler;
 
@@ -261,6 +264,8 @@ int i915_scheduler_queue_execbuffer(struct 
i915_scheduler_queue_entry *qe)
 
list_add_tail(&node->link, &scheduler->node_queue[ring->id]);
 
+   i915_scheduler_file_queue_inc(node->params.file);
+
if (i915.scheduler_override & i915_so_submit_on_queue)
not_flying = true;
else
@@ -554,6 +559,12 @@ static int i915_scheduler_remove(struct intel_engine_cs 
*ring)
/* Strip the dependency info while the mutex is still locked */
i915_scheduler_remove_dependent(scheduler, node);
 
+   /* Likewise clean up the file pointer. */
+   if (node->params.file) {
+   i915_scheduler_file_queue_dec(node->params.file);
+   node->params.file = NULL;
+   }
+
continue;
}
 
@@ -1093,6 +1104,7 @@ int i915_scheduler_closefile(struct drm_device *dev, 
struct drm_file *file)
 node->status,
 ring->name);
 
+   i915_scheduler_file_queue_dec(node->params.file);
node->params.file = NULL;
}
}
@@ -1101,3 +1113,26 @@ int i915_scheduler_closefile(struct drm_device *dev, 
struct drm_file *file)
 
return 0;
 }
+
+bool i915_scheduler_file_queue_is_full(struct drm_file *file)
+{
+   struct drm_i915_file_pri

[Intel-gfx] [PATCH v4 34/38] drm/i915: Scheduler state dump via debugfs

2016-01-11 Thread John . C . Harrison
From: John Harrison 

Added a facility for triggering the scheduler state dump via a debugfs
entry.

v2: New patch in series.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_debugfs.c   | 33 +
 drivers/gpu/drm/i915/i915_scheduler.c |  9 +
 drivers/gpu/drm/i915/i915_scheduler.h |  6 ++
 3 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 1c4c6fe..a99f9c5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1285,6 +1285,38 @@ 
DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_file_queue_max_fops,
i915_scheduler_file_queue_max_set,
"%llu\n");
 
+static int
+i915_scheduler_dump_flags_get(void *data, u64 *val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   *val = scheduler->dump_flags;
+
+   return 0;
+}
+
+static int
+i915_scheduler_dump_flags_set(void *data, u64 val)
+{
+   struct drm_device   *dev   = data;
+   struct drm_i915_private *dev_priv  = dev->dev_private;
+   struct i915_scheduler   *scheduler = dev_priv->scheduler;
+
+   scheduler->dump_flags = lower_32_bits(val) & i915_sf_dump_mask;
+
+   if (val & 1)
+   i915_scheduler_dump_all(dev, "DebugFS");
+
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(i915_scheduler_dump_flags_fops,
+   i915_scheduler_dump_flags_get,
+   i915_scheduler_dump_flags_set,
+   "0x%llx\n");
+
 static int i915_frequency_info(struct seq_file *m, void *unused)
 {
struct drm_info_node *node = m->private;
@@ -5698,6 +5730,7 @@ static const struct i915_debugfs_files {
{"i915_scheduler_priority_preempt", 
&i915_scheduler_priority_preempt_fops},
{"i915_scheduler_min_flying", &i915_scheduler_min_flying_fops},
{"i915_scheduler_file_queue_max", &i915_scheduler_file_queue_max_fops},
+   {"i915_scheduler_dump_flags", &i915_scheduler_dump_flags_fops},
{"i915_display_crc_ctl", &i915_display_crc_ctl_fops},
{"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
{"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 3edf856..8426927 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -195,6 +195,10 @@ int i915_scheduler_init(struct drm_device *dev)
scheduler->priority_level_preempt = 900;
scheduler->min_flying = 2;
scheduler->file_queue_max = 64;
+   scheduler->dump_flags = i915_sf_dump_force   |
+   i915_sf_dump_details |
+   i915_sf_dump_seqno   |
+   i915_sf_dump_dependencies;
 
dev_priv->scheduler = scheduler;
 
@@ -787,10 +791,7 @@ static int i915_scheduler_dump_all_locked(struct 
drm_device *dev,
int i, r, ret = 0;
 
for_each_ring(ring, dev_priv, i) {
-   scheduler->flags[ring->id] |= i915_sf_dump_force   |
- i915_sf_dump_details |
- i915_sf_dump_seqno   |
- i915_sf_dump_dependencies;
+   scheduler->flags[ring->id] |= scheduler->dump_flags & 
i915_sf_dump_mask;
r = i915_scheduler_dump_locked(ring, msg);
if (ret == 0)
ret = r;
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index d7aa542..3d1484d 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -108,6 +108,7 @@ struct i915_scheduler {
int32_t priority_level_preempt;
uint32_tmin_flying;
uint32_tfile_queue_max;
+   uint32_tdump_flags;
 
/* Statistics: */
struct i915_scheduler_stats stats[I915_NUM_RINGS];
@@ -124,6 +125,11 @@ enum {
i915_sf_dump_details= (1 << 9),
i915_sf_dump_dependencies   = (1 << 10),
i915_sf_dump_seqno  = (1 << 11),
+
+   i915_sf_dump_mask   = i915_sf_dump_force|
+ i915_sf_dump_details  |
+ i915_sf_dump_dependencies |
+ i915_sf_dump_seqno,
 };
 const char *i915_scheduler_flag_str(uint32_t flags);
 
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel

[Intel-gfx] [PATCH v4 11/38] drm/i915: Added scheduler hook when closing DRM file handles

2016-01-11 Thread John . C . Harrison
From: John Harrison 

The scheduler decouples the submission of batch buffers to the driver
with submission of batch buffers to the hardware. Thus it is possible
for an application to close its DRM file handle while there is still
work outstanding. That means the scheduler needs to know about file
close events so it can remove the file pointer from such orphaned
batch buffers and not attempt to dereference it later.

v3: Updated to not wait for outstanding work to complete but merely
remove the file handle reference. The wait was getting excessively
complicated with inter-ring dependencies, pre-emption, and other such
issues.

v4: Changed some white space to keep the style checker happy.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_dma.c   |  3 +++
 drivers/gpu/drm/i915/i915_scheduler.c | 35 +++
 drivers/gpu/drm/i915/i915_scheduler.h |  2 ++
 3 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 731cf31..c2f9c03 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include "i915_scheduler.h"
 #include 
 #include 
 #include 
@@ -1250,6 +1251,8 @@ void i915_driver_lastclose(struct drm_device *dev)
 
 void i915_driver_preclose(struct drm_device *dev, struct drm_file *file)
 {
+   i915_scheduler_closefile(dev, file);
+
mutex_lock(&dev->struct_mutex);
i915_gem_context_close(dev, file);
i915_gem_release(dev, file);
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index fc48955..26cd088 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -802,3 +802,38 @@ static int i915_scheduler_remove_dependent(struct 
i915_scheduler *scheduler,
 
return 0;
 }
+
+int i915_scheduler_closefile(struct drm_device *dev, struct drm_file *file)
+{
+   struct i915_scheduler_queue_entry  *node;
+   struct drm_i915_private*dev_priv = dev->dev_private;
+   struct i915_scheduler  *scheduler = dev_priv->scheduler;
+   struct intel_engine_cs  *ring;
+   int i;
+   unsigned long   flags;
+
+   if (!scheduler)
+   return 0;
+
+   spin_lock_irqsave(&scheduler->lock, flags);
+
+   for_each_ring(ring, dev_priv, i) {
+   list_for_each_entry(node, &scheduler->node_queue[ring->id], 
link) {
+   if (node->params.file != file)
+   continue;
+
+   if (!I915_SQS_IS_COMPLETE(node))
+   DRM_DEBUG_DRIVER("Closing file handle with 
outstanding work: %d:%d/%d on %s\n",
+node->params.request->uniq,
+node->params.request->seqno,
+node->status,
+ring->name);
+
+   node->params.file = NULL;
+   }
+   }
+
+   spin_unlock_irqrestore(&scheduler->lock, flags);
+
+   return 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h 
b/drivers/gpu/drm/i915/i915_scheduler.h
index 2d50d83..02ac6f2 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -86,6 +86,8 @@ enum {
 
 booli915_scheduler_is_enabled(struct drm_device *dev);
 int i915_scheduler_init(struct drm_device *dev);
+int i915_scheduler_closefile(struct drm_device *dev,
+struct drm_file *file);
 int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry 
*qe);
 booli915_scheduler_notify_request(struct drm_i915_gem_request *req);
 
-- 
1.9.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v4 29/38] drm/i915: Add early exit to execbuff_final() if insufficient ring space

2016-01-11 Thread John . C . Harrison
From: John Harrison 

One of the major purposes of the GPU scheduler is to avoid stalling
the CPU when the GPU is busy and unable to accept more work. This
change adds support to the ring submission code to allow a ring space
check to be performed before attempting to submit a batch buffer to
the hardware. If insufficient space is available then the scheduler
can go away and come back later, letting the CPU get on with other
work, rather than stalling and waiting for the hardware to catch up.

v3: Updated to use locally cached request pointer.

v4: Line wrapped some comments differently to keep the style checker
happy. Downgraded a BUG_ON to a WARN_ON as the latter is preferred.

Removed some obsolete, commented out code.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 42 +--
 drivers/gpu/drm/i915/intel_lrc.c   | 54 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.c| 26 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h|  1 +
 4 files changed, 108 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index de8607e..6336479 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1099,25 +1099,19 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev,
 {
struct intel_engine_cs *ring = req->ring;
struct drm_i915_private *dev_priv = dev->dev_private;
-   int ret, i;
+   int i;
 
if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS]) {
DRM_DEBUG("sol reset is gen7/rcs only\n");
return -EINVAL;
}
 
-   ret = intel_ring_begin(req, 4 * 3);
-   if (ret)
-   return ret;
-
for (i = 0; i < 4; i++) {
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i));
intel_ring_emit(ring, 0);
}
 
-   intel_ring_advance(ring);
-
return 0;
 }
 
@@ -1245,6 +1239,7 @@ int i915_gem_ringbuffer_submission_final(struct 
i915_execbuffer_params *params)
struct intel_engine_cs  *ring = params->ring;
u64 exec_start, exec_len;
int ret;
+   uint32_t min_space;
 
/* The mutex must be acquired before calling this function */
WARN_ON(!mutex_is_locked(¶ms->dev->struct_mutex));
@@ -1267,8 +1262,36 @@ int i915_gem_ringbuffer_submission_final(struct 
i915_execbuffer_params *params)
if (ret)
return ret;
 
+   /*
+* It would be a bad idea to run out of space while writing commands
+* to the ring. One of the major aims of the scheduler is to not
+* stall at any point for any reason. However, doing an early exit
+* half way through submission could result in a partial sequence
+* being written which would leave the engine in an unknown state.
+* Therefore, check in advance that there will be enough space for
+* the entire submission whether emitted by the code below OR by any
+* other functions that may be executed before the end of final().
+*
+* NB: This test deliberately overestimates, because that's easier
+* than tracing every potential path that could be taken!
+*
+* Current measurements suggest that we may need to emit up to 186
+* dwords, so this is rounded up to 256 here. Then double that to get
+* the free space requirement, because the block is not allowed to
+* span the transition from the end to the beginning of the ring.
+*/
+#define I915_BATCH_EXEC_MAX_LEN 256/* max dwords emitted here */
+   min_space = I915_BATCH_EXEC_MAX_LEN * 2 * sizeof(uint32_t);
+   ret = intel_ring_test_space(req->ringbuf, min_space);
+   if (ret)
+   goto early_error;
+
intel_runtime_pm_get(dev_priv);
 
+   ret = intel_ring_begin(req, I915_BATCH_EXEC_MAX_LEN);
+   if (ret)
+   goto error;
+
/*
 * Unconditionally invalidate gpu caches and ensure that we do flush
 * any residual writes from the previous batch.
@@ -1287,10 +1310,6 @@ int i915_gem_ringbuffer_submission_final(struct 
i915_execbuffer_params *params)
 
if (ring == &dev_priv->ring[RCS] &&
params->instp_mode != dev_priv->relative_constants_mode) {
-   ret = intel_ring_begin(req, 4);
-   if (ret)
-   goto error;
-
intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(ring, INSTPM);
@@ -1327,6 +1346,7 @@ error:
 */
intel_runtime_pm_put(dev_priv);
 
+early_error:
if (ret)
intel_ring_reserved_space_cancel(req->ringbuf);
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel

[Intel-gfx] [PATCH v4 20/38] drm/i915: Added scheduler flush calls to ring throttle and idle functions

2016-01-11 Thread John . C . Harrison
From: John Harrison 

When requesting that all GPU work is completed, it is now necessary to
get the scheduler involved in order to flush out work that queued and
not yet submitted.

v2: Updated to add support for flushing the scheduler queue by time
stamp rather than just doing a blanket flush.

v3: Moved submit_max_priority() to this patch from an earlier patch
is it is no longer required in the other.

v4: Corrected the format of a comment to keep the style checker happy.
Downgraded a BUG_ON to a WARN_ON as the latter is preferred.

For: VIZ-1587
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_gem.c   |  24 +-
 drivers/gpu/drm/i915/i915_scheduler.c | 134 ++
 drivers/gpu/drm/i915/i915_scheduler.h |   3 +
 3 files changed, 160 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7716462..6ea0896 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3733,6 +3733,10 @@ int i915_gpu_idle(struct drm_device *dev)
 
/* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) {
+   ret = i915_scheduler_flush(ring, true);
+   if (ret < 0)
+   return ret;
+
if (!i915.enable_execlists) {
struct drm_i915_gem_request *req;
 
@@ -4446,7 +4450,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct 
drm_file *file)
unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES;
struct drm_i915_gem_request *request, *target = NULL;
unsigned reset_counter;
-   int ret;
+   int i, ret;
+   struct intel_engine_cs *ring;
 
ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
if (ret)
@@ -4456,6 +4461,23 @@ i915_gem_ring_throttle(struct drm_device *dev, struct 
drm_file *file)
if (ret)
return ret;
 
+   for_each_ring(ring, dev_priv, i) {
+   /*
+* Flush out scheduler entries that are getting 'stale'. Note
+* that the following recent_enough test will only check
+* against the time at which the request was submitted to the
+* hardware (i.e. when it left the scheduler) not the time it
+* was submitted to the driver.
+*
+* Also, there is not much point worring about busy return
+* codes from the scheduler flush call. Even if more work
+* cannot be submitted right now for whatever reason, we
+* still want to throttle against stale work that has already
+* been submitted.
+*/
+   i915_scheduler_flush_stamp(ring, recent_enough, false);
+   }
+
spin_lock(&file_priv->mm.lock);
list_for_each_entry(request, &file_priv->mm.request_list, client_list) {
if (time_after_eq(request->emitted_jiffies, recent_enough))
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c 
b/drivers/gpu/drm/i915/i915_scheduler.c
index 8c05dd0..bd52752 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -31,6 +31,8 @@ static int i915_scheduler_remove_dependent(struct 
i915_scheduler *schedu
   struct 
i915_scheduler_queue_entry *remove);
 static int i915_scheduler_submit(struct intel_engine_cs *ring,
 bool is_locked);
+static int i915_scheduler_submit_max_priority(struct intel_engine_cs 
*ring,
+ bool is_locked);
 static uint32_ti915_scheduler_count_flying(struct i915_scheduler 
*scheduler,
   struct intel_engine_cs *ring);
 static voidi915_scheduler_priority_bump_clear(struct i915_scheduler 
*scheduler);
@@ -589,6 +591,100 @@ void i915_gem_scheduler_work_handler(struct work_struct 
*work)
}
 }
 
+int i915_scheduler_flush_stamp(struct intel_engine_cs *ring,
+  unsigned long target,
+  bool is_locked)
+{
+   struct i915_scheduler_queue_entry *node;
+   struct drm_i915_private   *dev_priv;
+   struct i915_scheduler *scheduler;
+   unsigned long   flags;
+   int flush_count = 0;
+
+   if (!ring)
+   return -EINVAL;
+
+   dev_priv  = ring->dev->dev_private;
+   scheduler = dev_priv->scheduler;
+
+   if (!scheduler)
+   return 0;
+
+   if (is_locked && (scheduler->flags[ring->id] & i915_sf_submitting)) {
+   /*
+* Scheduler is busy already submitting another batch,
+* come back later rather than going recursive...
+*/
+   return -EAGAIN;
+   }
+
+   spin_lock_irqsave(&sch

  1   2   3   4   5   >