[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/execlists: Hesitate before slicing

2019-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915/execlists: Hesitate before slicing
URL   : https://patchwork.freedesktop.org/series/62867/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6375 -> Patchwork_13456


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/

Known issues


  Here are the changes found in Patchwork_13456 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@debugfs_test@read_all_entries:
- fi-ilk-650: [PASS][1] -> [DMESG-WARN][2] ([fdo#106387])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-ilk-650/igt@debugfs_test@read_all_entries.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-ilk-650/igt@debugfs_test@read_all_entries.html

  * igt@gem_mmap_gtt@basic-write-gtt-no-prefault:
- fi-icl-u3:  [PASS][3] -> [DMESG-WARN][4] ([fdo#107724])
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-icl-u3/igt@gem_mmap_...@basic-write-gtt-no-prefault.html
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-icl-u3/igt@gem_mmap_...@basic-write-gtt-no-prefault.html

  * igt@i915_pm_rpm@module-reload:
- fi-kbl-r:   [PASS][5] -> [DMESG-WARN][6] ([fdo#111012])
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-kbl-r/igt@i915_pm_...@module-reload.html
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-kbl-r/igt@i915_pm_...@module-reload.html

  * igt@i915_selftest@live_blt:
- fi-skl-iommu:   [PASS][7] -> [INCOMPLETE][8] ([fdo#108602])
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-skl-iommu/igt@i915_selftest@live_blt.html
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-skl-iommu/igt@i915_selftest@live_blt.html

  * igt@i915_selftest@live_coherency:
- fi-gdg-551: [PASS][9] -> [DMESG-FAIL][10] ([fdo#107164])
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-gdg-551/igt@i915_selftest@live_coherency.html
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-gdg-551/igt@i915_selftest@live_coherency.html

  * igt@i915_selftest@live_hugepages:
- fi-skl-gvtdvm:  [PASS][11] -> [DMESG-WARN][12] ([fdo#110976])
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-skl-gvtdvm/igt@i915_selftest@live_hugepages.html
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-skl-gvtdvm/igt@i915_selftest@live_hugepages.html

  * igt@i915_selftest@live_sanitycheck:
- fi-icl-dsi: [PASS][13] -> [INCOMPLETE][14] ([fdo#107713])
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-icl-dsi/igt@i915_selftest@live_sanitycheck.html
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-icl-dsi/igt@i915_selftest@live_sanitycheck.html

  * igt@kms_busy@basic-flip-a:
- fi-kbl-7567u:   [PASS][15] -> [SKIP][16] ([fdo#109271] / 
[fdo#109278]) +2 similar issues
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-kbl-7567u/igt@kms_b...@basic-flip-a.html
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-kbl-7567u/igt@kms_b...@basic-flip-a.html

  
 Possible fixes 

  * igt@kms_chamelium@common-hpd-after-suspend:
- fi-kbl-7567u:   [WARN][17] ([fdo#109380]) -> [PASS][18]
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-kbl-7567u/igt@kms_chamel...@common-hpd-after-suspend.html
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-kbl-7567u/igt@kms_chamel...@common-hpd-after-suspend.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-c:
- fi-kbl-7567u:   [SKIP][19] ([fdo#109271]) -> [PASS][20] +23 similar 
issues
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-kbl-7567u/igt@kms_pipe_crc_ba...@read-crc-pipe-c.html
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-kbl-7567u/igt@kms_pipe_crc_ba...@read-crc-pipe-c.html

  * igt@prime_self_import@basic-with_two_bos:
- fi-icl-u3:  [DMESG-WARN][21] ([fdo#107724]) -> [PASS][22] +1 
similar issue
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-icl-u3/igt@prime_self_import@basic-with_two_bos.html
   [22]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-icl-u3/igt@prime_self_import@basic-with_two_bos.html

  
 Warnings 

  * igt@i915_pm_rpm@basic-pci-d3-state:
- fi-kbl-guc: [FAIL][23] ([fdo#110829]) -> [SKIP][24] ([fdo#109271])
   [23]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6375/fi-kbl-guc/igt@i915_pm_...@basic-pci-d3-state.html
   [24]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13456/fi-kbl-guc/igt@i915_pm_...@basic-pci-d3-state.html

  
  [fdo#106387]: https://bugs.freedesktop.org/show_bug.cgi?id=106387
  [fdo#107164]: https://bugs.freedesktop.org/show_bug.cgi?id=107164
  [fdo#107713]: https://bugs.freedesktop.org/show_bug

Re: [Intel-gfx] [PATCH i-g-t] gitlab-ci: add tests for MIPS

2019-06-27 Thread Arkadiusz Hiler
On Thu, Jun 27, 2019 at 05:51:32PM +0300, Ser, Simon wrote:
> On Thu, 2019-06-27 at 14:30 +0100, Guillaume Tucker wrote:
> > Use the libatomic1:mips package only in the Debian Stretch Docker
> > image for MIPS and add Gitlab CI step to run tests on MIPS.
> > 
> > Signed-off-by: Guillaume Tucker 
> 
> With this tag added:
> 
> Fixes: 439a9f5d615f ("gitlab-ci: add build for MIPS")
> 
> This patch is:
> 
> Reviewed-by: Simon Ser 

Hey,

https://patchwork.freedesktop.org/series/62859/ and check GitLab.Pipeline

We will be running gitlab pipeline for everything pre-merge and if it
fails we will send out a email (currently we are testing this and no
emails are sent).

You can check the pieline status from patchwork at all times, even for
sucessful ones :-)

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

Re: [Intel-gfx] [PATCH i-g-t] gitlab-ci: add tests for MIPS

2019-06-27 Thread Ser, Simon
On Thu, 2019-06-27 at 14:30 +0100, Guillaume Tucker wrote:
> Use the libatomic1:mips package only in the Debian Stretch Docker
> image for MIPS and add Gitlab CI step to run tests on MIPS.
> 
> Signed-off-by: Guillaume Tucker 

And pushed:

To gitlab.freedesktop.org:drm/igt-gpu-tools.git
   3c4edeba35ac..5f6cf7070b24  master -> master

Thanks!

> ---
>  .gitlab-ci.yml | 14 ++
>  Dockerfile.debian-mips |  2 +-
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
> index 37184b98f5da..665fbb79c523 100644
> --- a/.gitlab-ci.yml
> +++ b/.gitlab-ci.yml
> @@ -173,6 +173,20 @@ test:ninja-test-armhf:
>- build
>  when: on_failure
>  
> +test:ninja-test-mips:
> +  image: $CI_REGISTRY/$CI_PROJECT_PATH/igt-debian-mips:latest
> +  dependencies:
> +- build:tests-debian-meson-mips
> +  stage: test
> +  script:
> +- export PKG_CONFIG_PATH=/usr/lib/mips-linux-gnu/pkgconfig/
> +- env > build/envdump.txt
> +- ninja -C build test
> +  artifacts:
> +paths:
> +  - build
> +when: on_failure
> +
>  test:test-list-diff:
>dependencies:
>  - build:tests-debian-autotools
> diff --git a/Dockerfile.debian-mips b/Dockerfile.debian-mips
> index ebe08db644ea..ee29f5f4ccda 100644
> --- a/Dockerfile.debian-mips
> +++ b/Dockerfile.debian-mips
> @@ -5,7 +5,6 @@ RUN apt-get install -y \
>   flex \
>   bison \
>   pkg-config \
> - libatomic1 \
>   x11proto-dri2-dev \
>   python-docutils \
>   valgrind \
> @@ -15,6 +14,7 @@ RUN dpkg --add-architecture mips
>  RUN apt-get update
>  RUN apt-get install -y \
>   gcc-mips-linux-gnu \
> + libatomic1:mips \
>   libpciaccess-dev:mips \
>   libkmod-dev:mips \
>   libprocps-dev:mips \
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] ✗ Fi.CI.BAT: failure for Extend BT2020 support in iCSC and fixes (rev4)

2019-06-27 Thread Patchwork
== Series Details ==

Series: Extend BT2020 support in iCSC and fixes (rev4)
URL   : https://patchwork.freedesktop.org/series/60480/
State : failure

== Summary ==

CALLscripts/checksyscalls.sh
  CALLscripts/atomic/check-atomics.sh
  DESCEND  objtool
  CHK include/generated/compile.h
  AR  drivers/gpu/drm/i915/built-in.a
  CC [M]  drivers/gpu/drm/i915/header_test_i915_active_types.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_debugfs.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_drv.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_fixed.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_gem_gtt.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_globals.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_irq.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_params.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_priolist_types.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_pvinfo.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_reg.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_scheduler_types.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_utils.o
  CC [M]  drivers/gpu/drm/i915/header_test_i915_vgpu.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_csr.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_drv.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_guc_ct.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_guc_fwif.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_guc_reg.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_gvt.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_pm.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_runtime_pm.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_sideband.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_uc_fw.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_uncore.o
  CC [M]  drivers/gpu/drm/i915/header_test_intel_wakeref.o
  CC [M]  drivers/gpu/drm/i915/display/intel_sprite.o
drivers/gpu/drm/i915/display/intel_sprite.c: In function 
‘icl_program_input_csc’:
drivers/gpu/drm/i915/display/intel_sprite.c:498:4: error: expected ‘}’ before 
‘;’ token
   };
^
scripts/Makefile.build:278: recipe for target 
'drivers/gpu/drm/i915/display/intel_sprite.o' failed
make[4]: *** [drivers/gpu/drm/i915/display/intel_sprite.o] Error 1
scripts/Makefile.build:489: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:489: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:489: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1071: recipe for target 'drivers' failed
make: *** [drivers] Error 2

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

[Intel-gfx] [v4 0/3] Extend BT2020 support in iCSC and fixes

2019-06-27 Thread Uma Shankar
This series adds support for BT2020 YCbCr to RGB conversion
using input CSC. This also fixes issues with BT601 and BT709
coefficients.

v2: Fixed Ville's review comments.

v3: Rebase.

v4: Rebase.

Uma Shankar (3):
  drm/i915/icl: Handle YCbCr to RGB conversion for BT2020 case
  drm/i915/icl: Fix Y pre-offset for Full Range YCbCr
  drm/i915/icl: Fixed Input CSC Co-efficients for BT601/709

 drivers/gpu/drm/i915/display/intel_sprite.c | 55 +++--
 1 file changed, 41 insertions(+), 14 deletions(-)

-- 
2.22.0

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

[Intel-gfx] [v4 2/3] drm/i915/icl: Fix Y pre-offset for Full Range YCbCr

2019-06-27 Thread Uma Shankar
Fixed Y Pre-offset in case of Full Range YCbCr.

v2: Rebase

Reviewed-by: Ville Syrjälä 
Suggested-by: Ville Syrjälä 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_sprite.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c 
b/drivers/gpu/drm/i915/display/intel_sprite.c
index 29861cf644a4..abd89bdf8c5e 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -516,8 +516,11 @@ icl_program_input_csc(struct intel_plane *plane,
 
I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
  PREOFF_YUV_TO_RGB_HI);
-   I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
- PREOFF_YUV_TO_RGB_ME);
+   if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+   I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0);
+   else
+   I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
+ PREOFF_YUV_TO_RGB_ME);
I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
  PREOFF_YUV_TO_RGB_LO);
I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
-- 
2.22.0

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

[Intel-gfx] [v4 3/3] drm/i915/icl: Fixed Input CSC Co-efficients for BT601/709

2019-06-27 Thread Uma Shankar
Input CSC Co-efficients for BT601 and BT709 YCbCR to RGB
conversion were slightly off. Fixed the same.

v2: Fixed the co-eficients as there was issue with reference
matrix, spotted by Ville.

v3: Rebase

Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_sprite.c | 24 ++---
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c 
b/drivers/gpu/drm/i915/display/intel_sprite.c
index abd89bdf8c5e..13e70170745c 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -441,7 +441,7 @@ icl_program_input_csc(struct intel_plane *plane,
 */
[DRM_COLOR_YCBCR_BT709] = {
0x7C98, 0x7800, 0x0,
-   0x9EF8, 0x7800, 0xABF8,
+   0x9EF8, 0x7800, 0xAC00,
0x0, 0x7800,  0x7ED8,
},
/*
@@ -463,26 +463,26 @@ icl_program_input_csc(struct intel_plane *plane,
/*
 * BT.601 Limted range YCbCr -> full range RGB
 * The matrix required is :
-* [1.164384, 0.000, 1.596370,
-*  1.138393, -0.382500, -0.794598,
-*  1.138393, 1.971696, 0.]
+* [1.164384, 0.000, 1.596027,
+*  1.164384, -0.39175, -0.812813,
+*  1.164384, 2.017232, 0.]
 */
[DRM_COLOR_YCBCR_BT601] = {
0x7CC8, 0x7950, 0x0,
-   0x8CB8, 0x7918, 0x9C40,
-   0x0, 0x7918, 0x7FC8,
+   0x8D00, 0x7950, 0x9C88,
+   0x0, 0x7950, 0x6810,
},
/*
 * BT.709 Limited range YCbCr -> full range RGB
 * The matrix required is :
-* [1.164, 0.000, 1.833671,
-*  1.138393, -0.213249, -0.532909,
-*  1.138393, 2.112402, 0.]
+* [1.164384, 0.000, 1.792741,
+*  1.164384, -0.213249, -0.532909,
+*  1.164384, 2.112402, 0.]
 */
[DRM_COLOR_YCBCR_BT709] = {
-   0x7EA8, 0x7950, 0x0,
-   0x, 0x7918, 0xADA8,
-   0x0, 0x7918,  0x6870,
+   0x7E58, 0x7950, 0x0,
+   0x, 0x7950, 0xADA8,
+   0x0, 0x7950,  0x6870,
},
/*
 * BT.2020 Limited range YCbCr -> full range RGB
-- 
2.22.0

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

[Intel-gfx] [v4 1/3] drm/i915/icl: Handle YCbCr to RGB conversion for BT2020 case

2019-06-27 Thread Uma Shankar
Currently input csc for YCbCR to RGB conversion handles only
BT601 and Bt709. Extending it to support BT2020 as well.

v2: Fixed the co-efficients for LR to FR conversion,
as suggested by Ville.

v3: Fixed Y Pre-offset in case of Full Range YCbCr as suggested
by Ville.

v4: Split the v2 and v3 changes.

v5: Rebase

Reviewed-by: Ville Syrjälä 
Signed-off-by: Uma Shankar 
Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/display/intel_sprite.c | 24 +
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c 
b/drivers/gpu/drm/i915/display/intel_sprite.c
index 004b52027ae8..29861cf644a4 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -444,6 +444,18 @@ icl_program_input_csc(struct intel_plane *plane,
0x9EF8, 0x7800, 0xABF8,
0x0, 0x7800,  0x7ED8,
},
+   /*
+* BT.2020 full range YCbCr -> full range RGB
+* The matrix required is :
+* [1.000, 0.000, 1.474,
+*  1.000, -0.1645, -0.5713,
+*  1.000, 1.8814, 0.]
+*/
+   [DRM_COLOR_YCBCR_BT2020] = {
+   0x7BC8, 0x7800, 0x0,
+   0x8928, 0x7800, 0xAA88,
+   0x0, 0x7800, 0x7F10,
+   },
};
 
/* Matrix for Limited Range to Full Range Conversion */
@@ -472,6 +484,18 @@ icl_program_input_csc(struct intel_plane *plane,
0x, 0x7918, 0xADA8,
0x0, 0x7918,  0x6870,
},
+   /*
+* BT.2020 Limited range YCbCr -> full range RGB
+* The matrix required is :
+* [1.164, 0.000, 1.678,
+*  1.164, -0.1873, -0.6504,
+*  1.164, 2.1417, 0.]
+*/
+   [DRM_COLOR_YCBCR_BT2020] = {
+   0x7D70, 0x7950, 0x0,
+   0x8A68, 0x7950, 0xAC00,
+   0x0, 0x7950, 0x6890,
+   };
};
const u16 *csc;
 
-- 
2.22.0

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

Re: [Intel-gfx] [PATCH v2 35/37] drm/i915/query: Expose memory regions through the query uAPI

2019-06-27 Thread Tvrtko Ursulin


On 27/06/2019 21:56, Matthew Auld wrote:

From: Abdiel Janulgue 

Returns the available memory region areas supported by the HW.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
  drivers/gpu/drm/i915/i915_query.c | 57 +++
  include/uapi/drm/i915_drm.h   | 39 +
  2 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 7b7016171057..21c4c2592d6c 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -143,10 +143,67 @@ query_engine_info(struct drm_i915_private *i915,
return len;
  }
  
+static int query_memregion_info(struct drm_i915_private *dev_priv,

+   struct drm_i915_query_item *query_item)
+{
+   struct drm_i915_query_memory_region_info __user *query_ptr =
+   u64_to_user_ptr(query_item->data_ptr);
+   struct drm_i915_memory_region_info __user *info_ptr =
+   &query_ptr->regions[0];
+   struct drm_i915_memory_region_info info = { };
+   struct drm_i915_query_memory_region_info query;
+   u32 total_length;
+   int ret, i;
+
+   if (query_item->flags != 0)
+   return -EINVAL;
+
+   total_length = sizeof(struct drm_i915_query_memory_region_info);
+   for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+   struct intel_memory_region *region = dev_priv->regions[i];
+
+   if (!region)
+   continue;
+
+   total_length += sizeof(struct drm_i915_memory_region_info);
+   }
+
+   ret = copy_query_item(&query, sizeof(query), total_length,
+ query_item);
+   if (ret != 0)
+   return ret;
+
+   if (query.num_regions || query.rsvd[0] || query.rsvd[1] ||
+   query.rsvd[2])
+   return -EINVAL;
+
+   for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+   struct intel_memory_region *region = dev_priv->regions[i];
+
+   if (!region)
+   continue;
+
+   info.id = region->id;
+   info.size = resource_size(®ion->region);
+
+   if (__copy_to_user(info_ptr, &info, sizeof(info)))
+   return -EFAULT;
+
+   query.num_regions++;
+   info_ptr++;
+   }
+
+   if (__copy_to_user(query_ptr, &query, sizeof(query)))
+   return -EFAULT;
+
+   return total_length;
+}
+
  static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
struct drm_i915_query_item *query_item) 
= {
query_topology_info,
query_engine_info,
+   query_memregion_info,
  };
  
  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 5cf976e7608a..9b77d8af9877 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -2041,6 +2041,7 @@ struct drm_i915_query_item {
__u64 query_id;
  #define DRM_I915_QUERY_TOPOLOGY_INFO1
  #define DRM_I915_QUERY_ENGINE_INFO2
+#define DRM_I915_QUERY_MEMREGION_INFO   3
  /* Must be kept compact -- no holes and well documented */
  
  	/*

@@ -2180,6 +2181,44 @@ struct drm_i915_query_engine_info {
struct drm_i915_engine_info engines[];
  };
  
+struct drm_i915_memory_region_info {

+
+   /** Base type of a region
+*/
+#define I915_SYSTEM_MEMORY 0
+#define I915_DEVICE_MEMORY 1
+
+   /** The region id is encoded in a layout which makes it possible to
+*  retrieve the following information:
+*
+*  Base type: log2(ID >> 16)
+*  Instance:  log2(ID & 0x)
+*/
+   __u32 id;


Should we consider, for simplicity and similarity with the engine 
interface, go for something like:


struct i915_memory_type_instance {
__u16 type;
__u16 instance;
};

struct drm_i915_memory_region_info {
struct i915_memory_type_instance region;
...
};

?


+
+   /** Reserved field. MBZ */
+   __u32 rsvd0;
+
+   /** Unused for now. MBZ */
+   __u64 flags;
+
+   __u64 size;
+
+   /** Reserved fields must be cleared to zero. */
+   __u64 rsvd1[4];
+};
+
+struct drm_i915_query_memory_region_info {
+
+   /** Number of struct drm_i915_memory_region_info structs */
+   __u32 num_regions;
+
+   /** MBZ */
+   __u32 rsvd[3];


It's not that important, just a note that given some recent discussion 
on the engine query front, I wished I had more rsvd there. So maybe bump 
this up just to be extra safe.



+
+   struct drm_i915_memory_region_info regions[];
+};
+
  #if defined(__cplusplus)
  }
  #endif



Regards,

Tvrtko
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailma

Re: [Intel-gfx] [PATCH v2 34/37] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION

2019-06-27 Thread Tvrtko Ursulin


On 27/06/2019 21:56, Matthew Auld wrote:

From: Abdiel Janulgue 

This call will specify which memory region an object should be placed.

Note that changing the object's backing storage should be immediately
done after an object is created or if it's not yet in use, otherwise
this will fail on a busy object.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
  drivers/gpu/drm/i915/gem/i915_gem_context.c |  12 ++
  drivers/gpu/drm/i915/gem/i915_gem_context.h |   2 +
  drivers/gpu/drm/i915/gem/i915_gem_ioctls.h  |   2 +
  drivers/gpu/drm/i915/gem/i915_gem_object.c  | 117 
  drivers/gpu/drm/i915/i915_drv.c |   2 +-
  include/uapi/drm/i915_drm.h |  27 +
  6 files changed, 161 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 8a9787cf0cd0..157ca8247752 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -75,6 +75,7 @@
  #include "i915_globals.h"
  #include "i915_trace.h"
  #include "i915_user_extensions.h"
+#include "i915_gem_ioctls.h"
  
  #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
  
@@ -2357,6 +2358,17 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,

return ret;
  }
  
+int i915_gem_setparam_ioctl(struct drm_device *dev, void *data,

+   struct drm_file *file)
+{
+   struct drm_i915_gem_context_param *args = data;
+
+   if (args->param <= I915_CONTEXT_PARAM_MAX)
+   return i915_gem_context_setparam_ioctl(dev, data, file);
+
+   return i915_gem_object_setparam_ioctl(dev, data, file);
+}
+
  int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
   void *data, struct drm_file *file)
  {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h 
b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 9691dd062f72..d5a9a63bb34c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -157,6 +157,8 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, 
void *data,
struct drm_file *file_priv);
  int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_setparam_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file);
  int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
  
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h

index 5abd5b2172f2..af7465bceebd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -32,6 +32,8 @@ int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file);
  int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+int i915_gem_object_setparam_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_priv);
  int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
  int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 691af388e4e7..bc95f449de50 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -551,6 +551,123 @@ int __init i915_global_objects_init(void)
return 0;
  }
  
+static enum intel_region_id

+__region_id(u32 region)
+{
+   enum intel_region_id id;
+
+   for (id = 0; id < ARRAY_SIZE(intel_region_map); ++id) {
+   if (intel_region_map[id] == region)
+   return id;
+   }
+
+   return INTEL_MEMORY_UKNOWN;
+}
+
+static int i915_gem_object_region_select(struct drm_i915_private *dev_priv,
+struct drm_i915_gem_object_param *args,
+struct drm_file *file,
+struct drm_i915_gem_object *obj)
+{
+   struct intel_context *ce = dev_priv->engine[BCS0]->kernel_context;
+   u32 __user *uregions = u64_to_user_ptr(args->data);
+   u32 uregions_copy[INTEL_MEMORY_UKNOWN];
+   int i, ret;
+
+   if (args->size > ARRAY_SIZE(intel_region_map))
+   return -EINVAL;
+
+   memset(uregions_copy, 0, sizeof(uregions_copy));
+   for (i = 0; i < args->size; i++) {
+   u32 region;
+
+   ret = get_user(region, uregions);
+   if (ret)
+   return ret;
+
+   uregions_copy[i] = region;
+   ++u

Re: [Intel-gfx] [PATCH i-g-t v2] tests/i915/gem_ctx_switch: Update with engine discovery

2019-06-27 Thread Tvrtko Ursulin


On 27/06/2019 21:15, Andi Shyti wrote:


Hi Tvrtko,


+const struct intel_execution_engine2 *
+gem_eb_flags_to_engine(unsigned int flags)
+{
+   const struct intel_execution_engine2 *e2;
+
+   __for_each_static_engine(e2) {
+   if (e2->flags == flags)
+   return e2;
+   }
+
+   return NULL;
+}


the amount of "helpers" is getting almost unbearable for a simple
mind like mine.

This means that we can get rid of

  gem_execbuf_flags_to_engine_class
  gem_ring_is_physical_engine
  gem_ring_has_physical_engine

in igt_gt.c, right?


If/when there are no callers left we can like everything. I dont' know 
if that is the case right now.



+bool gem_context_has_engine_map(int fd, uint32_t ctx)
+{
+   struct drm_i915_gem_context_param param = {
+   .param = I915_CONTEXT_PARAM_ENGINES,
+   .ctx_id = ctx
+   };
+   int ret;
+
+   ret = __gem_context_get_param(fd, ¶m);
+   igt_assert_eq(ret, 0);
+
+   return param.size;


a small nitpick: bool to me means '0' or '1'.

So, if you do 'return param.size', I would call the function
gem_context_get_param_size, otherwise I would return
'!!param.size' and keep it bool.


Some people would then complain !! was not needed. ~o~

And actually I think I want to remove the distinction of no map and map 
with no engines for the callers of this helpers. So returning size would 
not work for that.



(We are also somehow abusing on the size definition of bool in
C99/C17 or previous.)

I'm not asking you to change it, but it would make me happier :)


I don't understand the issue with size definition. Size is u32 - will 
not implicit conversion to bool just work?





+}
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index 2415fd1e379b..b175483fac1c 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -53,6 +53,11 @@ int gem_context_lookup_engine(int fd, uint64_t engine, 
uint32_t ctx_id,
  
  void gem_context_set_all_engines(int fd, uint32_t ctx);
  
+bool gem_context_has_engine_map(int fd, uint32_t ctx);

+
+const struct intel_execution_engine2 *
+gem_eb_flags_to_engine(unsigned int flags);
+
  #define __for_each_static_engine(e__) \
for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
  
diff --git a/tests/i915/gem_ctx_switch.c b/tests/i915/gem_ctx_switch.c

index 647911d4c42e..407905de2d34 100644
--- a/tests/i915/gem_ctx_switch.c
+++ b/tests/i915/gem_ctx_switch.c
@@ -55,7 +55,7 @@ static double elapsed(const struct timespec *start, const 
struct timespec *end)
  
  static int measure_qlen(int fd,

struct drm_i915_gem_execbuffer2 *execbuf,
-   unsigned int *engine, unsigned int nengine,
+   const struct intel_engine_data *engines,
int timeout)
  {
const struct drm_i915_gem_exec_object2 * const obj =
@@ -63,15 +63,17 @@ static int measure_qlen(int fd,
uint32_t ctx[64];
int min = INT_MAX, max = 0;
  
-	for (int i = 0; i < ARRAY_SIZE(ctx); i++)

+   for (int i = 0; i < ARRAY_SIZE(ctx); i++) {
ctx[i] = gem_context_create(fd);
+   gem_context_set_all_engines(fd, ctx[i]);
+   }
  
-	for (unsigned int n = 0; n < nengine; n++) {

+   for (unsigned int n = 0; n < engines->nengines; n++) {
uint64_t saved = execbuf->flags;
struct timespec tv = {};
int q;
  
-		execbuf->flags |= engine[n];

+   execbuf->flags |= engines->engines[n].flags;
  
  		for (int i = 0; i < ARRAY_SIZE(ctx); i++) {

execbuf->rsvd1 = ctx[i];
@@ -90,7 +92,8 @@ static int measure_qlen(int fd,
 * Be conservative and aim not to overshoot timeout, so scale
 * down by 8 for hopefully a max of 12.5% error.
 */
-   q = ARRAY_SIZE(ctx) * timeout * 1e9 / igt_nsec_elapsed(&tv) / 8 
+ 1;
+   q = ARRAY_SIZE(ctx) * timeout * 1e9 / igt_nsec_elapsed(&tv) /
+   8 + 1;


I don't know whether it's me who is paranoic, but the change
above doesn't match the commit log.


What do you mean:

"""
Also beware of drive-by formatting changes.
"""

;)

File to many lines falling of 80 char so I tidied it alongside.




if (q < min)
min = q;
if (q > max)
@@ -107,7 +110,7 @@ static int measure_qlen(int fd,
  }
  
  static void single(int fd, uint32_t handle,

-  const struct intel_execution_engine *e,
+  const struct intel_execution_engine2 *e2,
   unsigned flags,
   const int ncpus,
   int timeout)
@@ -125,13 +128,14 @@ static void single(int fd, uint32_t handle,
shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
igt_assert(shared != MAP_FAILED);
  
-	gem_require_ring(fd, e->exec_id | e->flag

Re: [Intel-gfx] [PATCH v6 2/3] drm/i915: whitelist PS_(DEPTH|INVOCATION)_COUNT

2019-06-27 Thread Chris Wilson
Quoting Lionel Landwerlin (2019-06-28 00:53:09)
> On 27/06/2019 14:53, Chris Wilson wrote:
> > Magic! As we can't rely on our selftests to verify that this allows
> > access from user batches, could you poke Anuj for another tested by?
> > -Chris
> >
> I'll let Anuj answer.
> 
> Do I need Cc: sta...@vger.kernel.org ?

Yes, you need this for working userspace on released systems so
backporting is required.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 34/37] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:30)
> +int i915_gem_setparam_ioctl(struct drm_device *dev, void *data,
> +   struct drm_file *file)
> +{
> +   struct drm_i915_gem_context_param *args = data;

The plan was to use the upper_32_bits() or whatever as the class. To
future proof, I would recommend being more explicit with a switch.

> +   if (args->param <= I915_CONTEXT_PARAM_MAX)
> +   return i915_gem_context_setparam_ioctl(dev, data, file);
> +
> +   return i915_gem_object_setparam_ioctl(dev, data, file);
> +}

>  /* Allow drivers to submit batchbuffers directly to hardware, relying
>   * on the security mechanisms provided by hardware.
> @@ -1595,11 +1597,36 @@ struct drm_i915_gem_context_param {
>   *   i915_context_engines_bond (I915_CONTEXT_ENGINES_EXT_BOND)
>   */
>  #define I915_CONTEXT_PARAM_ENGINES 0xa
> +
> +#define I915_CONTEXT_PARAM_MAX 0x
>  /* Must be kept compact -- no holes and well documented */

Hahaha. Good one.

The rest of the patch is clearly very early proof of concept as it needs
the locking reworked.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 29/37] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:25)
> From: Abdiel Janulgue 
> 
> Add a new CPU mmap implementation that allows multiple fault handlers
> that depends on the object's backing pages.
> 
> Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
> and use the zero extending behaviour of drm to differentiate between
> them, when we inspect the flags.
> 
> Signed-off-by: Abdiel Janulgue 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|  2 ++
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 30 ++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
>  drivers/gpu/drm/i915/i915_drv.c   |  3 +-
>  include/uapi/drm/i915_drm.h   | 31 +++
>  5 files changed, 68 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
> b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> index ddc7f2a52b3e..5abd5b2172f2 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> @@ -30,6 +30,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file);
>  int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file);
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +  struct drm_file *file_priv);
>  int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
>  struct drm_file *file);
>  int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index 7b46f44d9c20..cbf89e80a97b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -536,12 +536,42 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void 
> *data,
> struct drm_file *file)
>  {
> struct drm_i915_gem_mmap_offset *args = data;
> +   struct drm_i915_private *i915 = to_i915(dev);
> +
> +   if (args->flags & I915_MMAP_OFFSET_FLAGS)
> +   return i915_gem_mmap_offset_ioctl(dev, data, file);
> +
> +   if (!HAS_MAPPABLE_APERTURE(i915)) {
> +   DRM_ERROR("No aperture, cannot mmap via legacy GTT\n");
> +   return -ENODEV;
> +   }
>  
> return __assign_gem_object_mmap_data(file, args->handle,
>  I915_MMAP_TYPE_GTT,
>  &args->offset);
>  }
>  
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +  struct drm_file *file)

This seems highly redundant and not correctly plugged in.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 28/37] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:24)
> +   vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;

Strictly speaking, it's not actually VM_IO as we do not wrap and expose
mmio registers to userspace.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 28/37] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:24)
> +   if (node->readonly) {

Note that we can now drop the readonly field from the node as we only
added it for out benefit. Now we've extended the vma impl, we can use
our obj readonly flag directly.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 28/37] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:24)
> +int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> +   struct drm_vma_offset_node *node;
> +   struct drm_file *priv = filp->private_data;
> +   struct drm_device *dev = priv->minor->dev;
> +   struct i915_mmap_offset *mmo;
> +   struct drm_gem_object *obj = NULL;
> +
> +   if (drm_dev_is_unplugged(dev))
> +   return -ENODEV;
> +
> +   drm_vma_offset_lock_lookup(dev->vma_offset_manager);
> +   node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
> + vma->vm_pgoff,
> + vma_pages(vma));
> +   if (likely(node)) {
> +   mmo = container_of(node, struct i915_mmap_offset,
> +  vma_node);
> +
> +   /* Take a ref for our mmap_offset and gem objects. The 
> reference is cleaned

/*
 * Take

> +* up when the vma is closed.
> +*
> +* Skip 0-refcnted objects as it is in the process of being 
> destroyed
> +* and will be invalid when the vma manager lock is released.
> +*/
> +   if (kref_get_unless_zero(&mmo->ref)) {
> +   obj = &mmo->obj->base;
> +   if (!kref_get_unless_zero(&obj->refcount))
> +   obj = NULL;
> +   }
> +   }
> +   drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
> +
> +   if (!obj)
> +   return -EINVAL;

Please check the error paths for reference leaks.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 28/37] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:24)
> +static void i915_gem_vm_open(struct vm_area_struct *vma)
> +{
> +   struct i915_mmap_offset *priv = vma->vm_private_data;
> +   struct drm_i915_gem_object *obj = priv->obj;
> +
> +   drm_gem_object_get(&obj->base);

Pleae use the right getters, i915_gem_object_get and
i915_gem_object_put.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH] drm/i915/ehl: Add support for DPLL4 (v9)

2019-06-27 Thread Vivek Kasireddy
This patch adds support for DPLL4 on EHL that include the
following restrictions:

- DPLL4 cannot be used with DDIA (combo port A internal eDP usage).
  DPLL4 can be used with other DDIs, including DDID
  (combo port A external usage).

- DPLL4 cannot be enabled when DC5 or DC6 are enabled.

- The DPLL4 enable, lock, power enabled, and power state are connected
  to the MGPLL1_ENABLE register.

v2: (suggestions from Bob Paauwe)
- Rework ehl_get_dpll() function to call intel_find_shared_dpll() and
  iterate twice: once for Combo plls and once for MG plls.

- Use MG pll funcs for DPLL4 instead of creating new ones and modify
  mg_pll_enable to include the restrictions for EHL.

v3: Fix compilation error

v4: (suggestions from Lucas and Ville)
- Treat DPLL4 as a combo phy PLL and not as MG PLL
- Disable DC states when this DPLL is being enabled
- Reuse icl_get_dpll instead of creating a separate one for EHL

v5: (suggestion from Ville)
- Refcount the DC OFF power domains during the enabling and disabling
  of this DPLL.

v6: rebase

v7: (suggestion from Imre)
- Add a new power domain instead of iterating over the domains
  assoicated with DC OFF power well.

v8: (Ville and Imre)
- Rename POWER_DOMAIN_DPLL4 TO POWER_DOMAIN_DPLL_DC_OFF
- Grab a reference in intel_modeset_setup_hw_state() if this
  DPLL was already enabled perhaps by BIOS.
- Check for the port type instead of the encoder

v9: (Ville)
- Move the block of code that grabs a reference to the power domain
  POWER_DOMAIN_DPLL_DC_OFF to intel_modeset_readout_hw_state() to ensure
  that there is a reference present before this DPLL might get disabled.

Cc: José Roberto de Souza 
Cc: Ville Syrjälä 
Cc: Matt Roper 
Cc: Imre Deak 
Signed-off-by: Vivek Kasireddy 
---
 drivers/gpu/drm/i915/display/intel_display.c  |  7 
 .../drm/i915/display/intel_display_power.c|  3 ++
 .../drm/i915/display/intel_display_power.h|  1 +
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 42 +--
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h |  6 +++
 5 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index e55bd75528c1..3f1ff3bb5e36 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -16569,6 +16569,13 @@ static void intel_modeset_readout_hw_state(struct 
drm_device *dev)
 
pll->on = pll->info->funcs->get_hw_state(dev_priv, pll,
&pll->state.hw_state);
+
+   if (IS_ELKHARTLAKE(dev_priv) && pll->on &&
+   pll->info->id == DPLL_ID_EHL_DPLL4) {
+   pll->wakeref = intel_display_power_get(dev_priv,
+  
POWER_DOMAIN_DPLL_DC_OFF);
+   }
+
pll->state.crtc_mask = 0;
for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state =
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c 
b/drivers/gpu/drm/i915/display/intel_display_power.c
index c93ad512014c..1c101a842331 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -117,6 +117,8 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
return "MODESET";
case POWER_DOMAIN_GT_IRQ:
return "GT_IRQ";
+   case POWER_DOMAIN_DPLL_DC_OFF:
+   return "DPLL_DC_OFF";
default:
MISSING_CASE(domain);
return "?";
@@ -2361,6 +2363,7 @@ void intel_display_power_put(struct drm_i915_private 
*dev_priv,
ICL_PW_2_POWER_DOMAINS |\
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) |   \
+   BIT_ULL(POWER_DOMAIN_DPLL_DC_OFF) | \
BIT_ULL(POWER_DOMAIN_INIT))
 
 #define ICL_DDI_IO_A_POWER_DOMAINS (   \
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h 
b/drivers/gpu/drm/i915/display/intel_display_power.h
index ff57b0a7fe59..8f43f7051a16 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -59,6 +59,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_GMBUS,
POWER_DOMAIN_MODESET,
POWER_DOMAIN_GT_IRQ,
+   POWER_DOMAIN_DPLL_DC_OFF,
POWER_DOMAIN_INIT,
 
POWER_DOMAIN_NUM,
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 2d4e7b9a7b9d..81e1443cb583 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -2806,6 +2806,10 @@ icl_get_dpll(struct intel_crtc_state *crtc_state,
if (intel_port_is_combophy(dev_priv, port)) {
min = DPLL_ID_

Re: [Intel-gfx] [PATCH v2 24/37] drm/i915: set num_fence_regs to 0 if there is no aperture

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:20)
> From: Daniele Ceraolo Spurio 
> 
> We can't fence anything without aperture.

s/aperture/fence registers/
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 23/37] drm/i915: expose missing map_gtt support to users

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:19)
> From: Daniele Ceraolo Spurio 
> 
> Done by returning -ENODEV from the map_gtt version ioctl.
> 
> Cc: Antonio Argenziano 
> Cc: Matthew Auld 
> Signed-off-by: Daniele Ceraolo Spurio 
> ---
>  drivers/gpu/drm/i915/i915_drv.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index ac8fbada0406..34edc0302691 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -425,6 +425,8 @@ static int i915_getparam_ioctl(struct drm_device *dev, 
> void *data,
> return value;
> break;
> case I915_PARAM_MMAP_GTT_VERSION:
> +   if (!HAS_MAPPABLE_APERTURE(dev_priv))
> +   return -ENODEV;

The ioctl version is still going to be there, since we just extend it
report offsets fot the many alternative mappings, with the different
fences and everything. Right?

If we don't support a ggtt mmap via the extended mmap_offset ioctl, we
report the flags as being invalid.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 19/37] drm/i915: treat shmem as a region

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:15)
>  int i915_gem_freeze(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index e4f811fdaedc..958c61e88200 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2941,7 +2941,8 @@ int i915_gem_init_memory_regions(struct 
> drm_i915_private *i915)
>  
> type = MEMORY_TYPE_FROM_REGION(intel_region_map[i]);
> switch (type) {
> -   default:
> +   case INTEL_SMEM:
> +   mem = i915_gem_shmem_setup(i915);
> break;
> }
>  
> @@ -2951,11 +2952,9 @@ int i915_gem_init_memory_regions(struct 
> drm_i915_private *i915)
> goto out_cleanup;
> }
>  
> -   if (mem) {
> -   mem->id = intel_region_map[i];
> -   mem->type = type;
> -   mem->instance = 
> MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);
> -   }
> +   mem->id = intel_region_map[i];
> +   mem->type = type;
> +   mem->instance = 
> MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);

Go back and adjust the stub function you just introduced to avoid
self-inflicted churn.

Meanwhile I'm left with this magic that isn't even defined in this patch
to try and figure out if this is equivalent to the code you just
removed.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v6 2/3] drm/i915: whitelist PS_(DEPTH|INVOCATION)_COUNT

2019-06-27 Thread Lionel Landwerlin

On 27/06/2019 14:53, Chris Wilson wrote:

Quoting Lionel Landwerlin (2019-06-27 10:01:15)

CFL:C0+ changed the status of those registers which are now
blacklisted by default.

This is breaking a number of CTS tests on GL & Vulkan :

   
KHR-GL45.pipeline_statistics_query_tests_ARB.functional_fragment_shader_invocations
 (GL)

   dEQP-VK.query_pool.statistics_query.fragment_shader_invocations.* (Vulkan)

v2: Only use one whitelist entry (Lionel)

Signed-off-by: Lionel Landwerlin 
---
  drivers/gpu/drm/i915/gt/intel_workarounds.c | 17 -
  1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 993804d09517..b117583e38bb 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1092,10 +1092,25 @@ static void glk_whitelist_build(struct intel_engine_cs 
*engine)
  
  static void cfl_whitelist_build(struct intel_engine_cs *engine)

  {
+   struct i915_wa_list *w = &engine->whitelist;
+
 if (engine->class != RENDER_CLASS)
 return;
  
-   gen9_whitelist_build(&engine->whitelist);

+   gen9_whitelist_build(w);
+
+   /*
+* WaAllowPMDepthAndInvocationCountAccessFromUMD:cfl,whl,cml,aml
+*
+* This covers 4 register which are next to one another :
+*   - PS_INVOCATION_COUNT
+*   - PS_INVOCATION_COUNT_UDW
+*   - PS_DEPTH_COUNT
+*   - PS_DEPTH_COUNT_UDW
+*/
+   whitelist_reg_ext(w, PS_INVOCATION_COUNT,
+ RING_FORCE_TO_NONPRIV_RD |
+ RING_FORCE_TO_NONPRIV_RANGE_4);

Magic! As we can't rely on our selftests to verify that this allows
access from user batches, could you poke Anuj for another tested by?
-Chris


I'll let Anuj answer.

Do I need Cc: sta...@vger.kernel.org ?


-Lionel

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

Re: [Intel-gfx] [PATCH v2 16/37] drm/i915/lmem: support pread

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:12)
> We need to add support for pread'ing an LMEM object.
> 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue 
> ---
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  2 +
>  drivers/gpu/drm/i915/i915_gem.c   |  6 ++
>  drivers/gpu/drm/i915/intel_region_lmem.c  | 76 +++
>  3 files changed, 84 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
> b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 80ff5ad9bc07..8cdee185251a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -52,6 +52,8 @@ struct drm_i915_gem_object_ops {
> void (*truncate)(struct drm_i915_gem_object *obj);
> void (*writeback)(struct drm_i915_gem_object *obj);
>  
> +   int (*pread)(struct drm_i915_gem_object *,
> +const struct drm_i915_gem_pread *arg);
> int (*pwrite)(struct drm_i915_gem_object *obj,
>   const struct drm_i915_gem_pwrite *arg);
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 85677ae89849..4ba386ab35e7 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -463,6 +463,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
>  
> trace_i915_gem_object_pread(obj, args->offset, args->size);
>  
> +   ret = -ENODEV;
> +   if (obj->ops->pread)
> +   ret = obj->ops->pread(obj, args);
> +   if (ret != -ENODEV)
> +   goto out;
> +
> ret = i915_gem_object_wait(obj,
>I915_WAIT_INTERRUPTIBLE,
>MAX_SCHEDULE_TIMEOUT);
> diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
> b/drivers/gpu/drm/i915/intel_region_lmem.c
> index 701bcac3479e..54b2c7bf177d 100644
> --- a/drivers/gpu/drm/i915/intel_region_lmem.c
> +++ b/drivers/gpu/drm/i915/intel_region_lmem.c
> @@ -7,10 +7,86 @@
>  #include "intel_memory_region.h"
>  #include "intel_region_lmem.h"
>  
> +static int lmem_pread(struct drm_i915_gem_object *obj,
> + const struct drm_i915_gem_pread *arg)
> +{
> +   struct drm_i915_private *i915 = to_i915(obj->base.dev);
> +   struct intel_runtime_pm *rpm = &i915->runtime_pm;
> +   intel_wakeref_t wakeref;
> +   struct dma_fence *fence;
> +   char __user *user_data;
> +   unsigned int offset;
> +   unsigned long idx;
> +   u64 remain;
> +   int ret;
> +
> +   ret = i915_gem_object_pin_pages(obj);
> +   if (ret)
> +   return ret;
> +
> +   i915_gem_object_lock(obj);
> +   ret = i915_gem_object_set_to_wc_domain(obj, false);

You chose to opt out of the unlocked wait before the locked wait?


> +   if (ret) {
> +   i915_gem_object_unlock(obj);
> +   goto out_unpin;
> +   }
> +
> +   fence = i915_gem_object_lock_fence(obj);
> +   i915_gem_object_unlock(obj);
> +   if (!fence) {
> +   ret = -ENOMEM;
> +   goto out_unpin;
> +   }
> +
> +   wakeref = intel_runtime_pm_get(rpm);

Something not mentioned so far is the story for mm->rpm.

> +   remain = arg->size;
> +   user_data = u64_to_user_ptr(arg->data_ptr);
> +   offset = offset_in_page(arg->offset);
> +   for (idx = arg->offset >> PAGE_SHIFT; remain; idx++) {
> +   unsigned long unwritten;
> +   void __iomem *vaddr;
> +   int length;
> +
> +   length = remain;
> +   if (offset + length > PAGE_SIZE)
> +   length = PAGE_SIZE - offset;
> +
> +   vaddr = i915_gem_object_lmem_io_map_page(obj, idx);
> +   if (!vaddr) {
> +   ret = -ENOMEM;
> +   goto out_put;
> +   }
> +
> +   unwritten = copy_to_user(user_data,

Except this is a secret atomic section!!!

> +(void __force *)vaddr + offset,
> +length);
> +   io_mapping_unmap_atomic(vaddr);
> +   if (unwritten) {
> +   ret = -EFAULT;
> +   goto out_put;
> +   }
> +
> +   remain -= length;
> +   user_data += length;
> +   offset = 0;
> +   }
> +
> +out_put:
> +   intel_runtime_pm_put(rpm, wakeref);
> +   i915_gem_object_unlock_fence(obj, fence);
> +out_unpin:
> +   i915_gem_object_unpin_pages(obj);
> +
> +   return ret;
> +}
> +
>  static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
> .get_pages = i915_memory_region_get_pages_buddy,
> .put_pages = i915_memory_region_put_pages_buddy,
> .release = i915_gem_object_release_memory_region,
> +
> +   .pread = lmem_pread,
>  };
>  
>  static struc

Re: [Intel-gfx] [PATCH v2 15/37] drm/i915/lmem: support CPU relocations

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:11)
> @@ -1020,16 +1022,23 @@ static void reloc_cache_reset(struct reloc_cache 
> *cache)
> i915_gem_object_finish_access((struct drm_i915_gem_object 
> *)cache->node.mm);
> } else {
> wmb();
> -   io_mapping_unmap_atomic((void __iomem *)vaddr);
> -   if (cache->node.allocated) {
> -   struct i915_ggtt *ggtt = cache_to_ggtt(cache);
> -
> -   ggtt->vm.clear_range(&ggtt->vm,
> -cache->node.start,
> -cache->node.size);
> -   drm_mm_remove_node(&cache->node);
> +
> +   if (cache->is_lmem) {
> +   io_mapping_unmap_atomic((void __iomem *)vaddr);
> +   i915_gem_object_unpin_pages((struct 
> drm_i915_gem_object *)cache->node.mm);
> +   cache->is_lmem = false;
> } else {
> -   i915_vma_unpin((struct i915_vma *)cache->node.mm);
> +   io_mapping_unmap_atomic((void __iomem *)vaddr);

The first step of each branch is the same. What am I missing?


> +   if (cache->node.allocated) {
> +   struct i915_ggtt *ggtt = cache_to_ggtt(cache);
> +
> +   ggtt->vm.clear_range(&ggtt->vm,
> +cache->node.start,
> +cache->node.size);
> +   drm_mm_remove_node(&cache->node);
> +   } else {
> +   i915_vma_unpin((struct i915_vma 
> *)cache->node.mm);
> +   }
> }
> }
>  
> @@ -1069,6 +1078,40 @@ static void *reloc_kmap(struct drm_i915_gem_object 
> *obj,
> return vaddr;
>  }
>  
> +static void *reloc_lmem(struct drm_i915_gem_object *obj,
> +   struct reloc_cache *cache,
> +   unsigned long page)
> +{
> +   void *vaddr;
> +   int err;
> +
> +   GEM_BUG_ON(use_cpu_reloc(cache, obj));
> +
> +   if (cache->vaddr) {
> +   io_mapping_unmap_atomic((void __force __iomem *) 
> unmask_page(cache->vaddr));
> +   } else {
> +   i915_gem_object_lock(obj);
> +   err = i915_gem_object_set_to_wc_domain(obj, true);
> +   i915_gem_object_unlock(obj);
> +   if (err)
> +   return ERR_PTR(err);
> +
> +   err = i915_gem_object_pin_pages(obj);
> +   if (err)
> +   return ERR_PTR(err);
> +
> +   cache->node.mm = (void *)obj;
> +   cache->is_lmem = true;
> +   }
> +
> +   vaddr = i915_gem_object_lmem_io_map_page(obj, page);

Secret atomic. Notice the asymmetric release.

> +   cache->vaddr = (unsigned long)vaddr;
> +   cache->page = page;
> +
> +   return vaddr;
> +}
> +
>  static void *reloc_iomap(struct drm_i915_gem_object *obj,
>  struct reloc_cache *cache,
>  unsigned long page)
> @@ -1145,8 +1188,12 @@ static void *reloc_vaddr(struct drm_i915_gem_object 
> *obj,
> vaddr = unmask_page(cache->vaddr);
> } else {
> vaddr = NULL;
> -   if ((cache->vaddr & KMAP) == 0)
> -   vaddr = reloc_iomap(obj, cache, page);
> +   if ((cache->vaddr & KMAP) == 0) {
> +   if (i915_gem_object_is_lmem(obj))
> +   vaddr = reloc_lmem(obj, cache, page);
> +   else
> +   vaddr = reloc_iomap(obj, cache, page);
> +   }
> if (!vaddr)
> vaddr = reloc_kmap(obj, cache, page);
> }
> -- 
> 2.20.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 14/37] drm/i915/selftest: extend coverage to include LMEM huge-pages

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:10)
> Signed-off-by: Matthew Auld 
> ---
>  .../gpu/drm/i915/gem/selftests/huge_pages.c   | 122 +-
>  1 file changed, 121 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
> b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> index 1862bf06a20f..c81ea9ce289b 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> @@ -981,7 +981,7 @@ static int gpu_write(struct i915_vma *vma,
>vma->size >> PAGE_SHIFT, val);
>  }
>  
> -static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
> +static int __cpu_check_shmem(struct drm_i915_gem_object *obj, u32 dword, u32 
> val)
>  {
> unsigned int needs_flush;
> unsigned long n;
> @@ -1013,6 +1013,53 @@ static int cpu_check(struct drm_i915_gem_object *obj, 
> u32 dword, u32 val)
> return err;
>  }
>  
> +static int __cpu_check_lmem(struct drm_i915_gem_object *obj, u32 dword, u32 
> val)
> +{
> +   unsigned long n;
> +   int err;
> +
> +   i915_gem_object_lock(obj);
> +   err = i915_gem_object_set_to_wc_domain(obj, false);
> +   i915_gem_object_unlock(obj);
> +   if (err)
> +   return err;
> +
> +   err = i915_gem_object_pin_pages(obj);
> +   if (err)
> +   return err;
> +
> +   for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) {
> +   u32 __iomem *base;
> +   u32 read_val;
> +
> +   base = i915_gem_object_lmem_io_map_page(obj, n);
> +
> +   read_val = ioread32(base + dword);
> +   io_mapping_unmap_atomic(base);
> +   if (read_val != val) {
> +   pr_err("n=%lu base[%u]=%u, val=%u\n",
> +  n, dword, read_val, val);
> +   err = -EINVAL;
> +   break;
> +   }
> +   }
> +
> +   i915_gem_object_unpin_pages(obj);
> +   return err;
> +}
> +
> +static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)

We have different meanings of cpu :-p
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 13/37] drm/i915/selftests: don't just test CACHE_NONE for huge-pages

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:09)
> We also want to test LLC.

Then add a test for llc/snoop. It should be fine if it is physically
tagged...
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Enable Transcoder Port Sync feature for Tiled displays (rev4)

2019-06-27 Thread Patchwork
== Series Details ==

Series: Enable Transcoder Port Sync feature for Tiled displays (rev4)
URL   : https://patchwork.freedesktop.org/series/59837/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
1ed185770840 drm/i915/display: Rename update_crtcs() to commit_modeset_enables()
1df0691a4636 drm/i915/display: Move the commit_tail() disable sequence to 
commit_modeset_disables() hook
321c24b27347 drm/i915/display/icl: Save Master transcoder in slave's crtc_state 
for Transcoder Port Sync
0e45d45ced7e drm/i915/display/icl: Enable TRANSCODER PORT SYNC for tiled 
displays across separate ports
6acc068f0bef drm/i915/display/icl: HW state readout for transcoder port sync 
config
-:39: CHECK:BRACES: braces {} should be used on all arms of this statement
#39: FILE: drivers/gpu/drm/i915/display/intel_display.c:10283:
+   if (trans_port_sync & PORT_SYNC_MODE_ENABLE) {
[...]
+   } else
[...]

-:56: CHECK:BRACES: Unbalanced braces around else statement
#56: FILE: drivers/gpu/drm/i915/display/intel_display.c:10300:
+   } else

total: 0 errors, 0 warnings, 2 checks, 56 lines checked
e1d605f6dfff drm/i915/display/icl: Enable master-slaves in trans port sync mode 
in correct order
-:146: WARNING:LONG_LINE: line over 100 characters
#146: FILE: drivers/gpu/drm/i915/display/intel_display.c:14047:
+
&to_intel_crtc_state(old_crtc_state)->wm.skl.ddb) &&

total: 0 errors, 1 warnings, 0 checks, 263 lines checked
352a9304b1ba drm/i915/display/icl: Disable transcoder port sync as part of 
crtc_disable() sequence
802f2b59efd1 drm/i915/display/icl: In port sync mode disable slaves first then 
masters

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

Re: [Intel-gfx] [PATCH v2 10/37] drm/i915/blt: support copying objects

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:06)
> We can already clear an object with the blt, so try to do the same to
> support copying from one object backing store to another. Really this is
> just object -> object, which is not that useful yet, what we really want
> is two backing stores, but that will require some vma rework first,
> otherwise we are stuck with "tmp" objects.
> 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue  ---
>  .../gpu/drm/i915/gem/i915_gem_object_blt.c| 135 ++
>  .../gpu/drm/i915/gem/i915_gem_object_blt.h|   8 ++
>  .../i915/gem/selftests/i915_gem_object_blt.c  | 105 ++
>  drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |   3 +-
>  4 files changed, 250 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> index cb42e3a312e2..c2b28e06c379 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> @@ -102,6 +102,141 @@ int i915_gem_object_fill_blt(struct drm_i915_gem_object 
> *obj,
> return err;
>  }
>  
> +int intel_emit_vma_copy_blt(struct i915_request *rq,
> +   struct i915_vma *src,
> +   struct i915_vma *dst)
> +{
> +   const int gen = INTEL_GEN(rq->i915);
> +   u32 *cs;
> +
> +   GEM_BUG_ON(src->size != dst->size);

For a low level interface, I would suggest a little over engineering and
take src_offset, dst_offset, length. For bonus points, 2D -- but I
accept that may be too much over-engineering without a user.

> +   cs = intel_ring_begin(rq, 10);
> +   if (IS_ERR(cs))
> +   return PTR_ERR(cs);
> +
> +   if (gen >= 9) {
> +   *cs++ = GEN9_XY_FAST_COPY_BLT_CMD | (10-2);
> +   *cs++ = BLT_DEPTH_32 | PAGE_SIZE;
> +   *cs++ = 0;
> +   *cs++ = src->size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
> +   *cs++ = lower_32_bits(dst->node.start);
> +   *cs++ = upper_32_bits(dst->node.start);
> +   *cs++ = 0;
> +   *cs++ = PAGE_SIZE;
> +   *cs++ = lower_32_bits(src->node.start);
> +   *cs++ = upper_32_bits(src->node.start);

Reminds me that we didn't fix the earlier routines to handle more than
32k pages either. Please add a test case :)
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 09/37] drm/i915/lmem: support kernel mapping

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:05)
> From: Abdiel Janulgue 
> 
> We can create LMEM objects, but we also need to support mapping them
> into kernel space for internal use.
> 
> Signed-off-by: Abdiel Janulgue 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_pages.c | 18 -
>  drivers/gpu/drm/i915/intel_region_lmem.c  | 24 ++
>  drivers/gpu/drm/i915/intel_region_lmem.h  |  6 ++
>  .../drm/i915/selftests/intel_memory_region.c  | 77 +++
>  4 files changed, 121 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index b36ad269f4ea..15eaaedffc46 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -176,7 +176,9 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
> *obj)
> void *ptr;
>  
> ptr = page_mask_bits(obj->mm.mapping);
> -   if (is_vmalloc_addr(ptr))
> +   if (i915_gem_object_is_lmem(obj))
> +   io_mapping_unmap(ptr);
> +   else if (is_vmalloc_addr(ptr))
> vunmap(ptr);
> else
> kunmap(kmap_to_page(ptr));
> @@ -235,7 +237,7 @@ int __i915_gem_object_put_pages(struct 
> drm_i915_gem_object *obj,
>  }
>  
>  /* The 'mapping' part of i915_gem_object_pin_map() below */
> -static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
> +static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>  enum i915_map_type type)
>  {
> unsigned long n_pages = obj->base.size >> PAGE_SHIFT;
> @@ -248,6 +250,11 @@ static void *i915_gem_object_map(const struct 
> drm_i915_gem_object *obj,
> pgprot_t pgprot;
> void *addr;
>  
> +   if (i915_gem_object_is_lmem(obj)) {
> +   /* XXX: we are ignoring the type here -- this is simply wc */

Yeah, don't. The callers certainly do not expect that.

> +   return i915_gem_object_lmem_io_map(obj, 0, obj->base.size);
> +   }
> +
> /* A single page can always be kmapped */
> if (n_pages == 1 && type == I915_MAP_WB)
> return kmap(sg_page(sgt->sgl));
> @@ -293,7 +300,8 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
> *obj,
> void *ptr;
> int err;
>  
> -   if (unlikely(!i915_gem_object_has_struct_page(obj)))
> +   if (unlikely(!i915_gem_object_has_struct_page(obj) &&
> +!i915_gem_object_is_lmem(obj)))

Redefine the feature bit in the obj->ops->flags.

> return ERR_PTR(-ENXIO);
>  
> err = mutex_lock_interruptible(&obj->mm.lock);
> @@ -325,7 +333,9 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
> *obj,
> goto err_unpin;
> }
>  
> -   if (is_vmalloc_addr(ptr))
> +   if (i915_gem_object_is_lmem(obj))
> +   io_mapping_unmap(ptr);
> +   else if (is_vmalloc_addr(ptr))
> vunmap(ptr);
> else
> kunmap(kmap_to_page(ptr));
> diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
> b/drivers/gpu/drm/i915/intel_region_lmem.c
> index 15655cc5013f..701bcac3479e 100644
> --- a/drivers/gpu/drm/i915/intel_region_lmem.c
> +++ b/drivers/gpu/drm/i915/intel_region_lmem.c
> @@ -73,6 +73,30 @@ static const struct intel_memory_region_ops 
> region_lmem_ops = {
> .create_object = lmem_create_object,
>  };
>  
> +/* XXX: Time to vfunc your life up? */
> +void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object 
> *obj,
> +  unsigned long n)
> +{
> +   resource_size_t offset;
> +
> +   offset = i915_gem_object_get_dma_address(obj, n);

That seems dubious. So dubious that I again say do not mix terms.

> +   return io_mapping_map_atomic_wc(&obj->memory_region->iomap, offset);

Ahem. The caller may not be ready to abide by the terms of the atomic
contract.

> +}
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 07/37] drm/i915: support creating LMEM objects

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:03)
> We currently define LMEM, or local memory, as just another memory
> region, like system memory or stolen, which we can expose to userspace
> and can be mapped to the CPU via some BAR.
> 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue 
> ---
>  drivers/gpu/drm/i915/Makefile |  1 +
>  drivers/gpu/drm/i915/i915_drv.h   |  5 ++
>  drivers/gpu/drm/i915/intel_region_lmem.c  | 66 +++
>  drivers/gpu/drm/i915/intel_region_lmem.h  | 16 +
>  .../drm/i915/selftests/i915_live_selftests.h  |  1 +
>  .../drm/i915/selftests/intel_memory_region.c  | 43 
>  6 files changed, 132 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c
>  create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 28fac19f7b04..e782f7d10524 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -132,6 +132,7 @@ i915-y += \
>   i915_scheduler.o \
>   i915_trace_points.o \
>   i915_vma.o \
> + intel_region_lmem.o \
>   intel_wopcm.o
>  
>  # general-purpose microcontroller (GuC) support
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 838a796d9c55..7cbdffe3f129 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -93,6 +93,8 @@
>  #include "gt/intel_timeline.h"
>  #include "i915_vma.h"
>  
> +#include "intel_region_lmem.h"
> +
>  #include "intel_gvt.h"
>  
>  /* General customization:
> @@ -1341,6 +1343,8 @@ struct drm_i915_private {
>  */
> resource_size_t stolen_usable_size; /* Total size minus reserved 
> ranges */
>  
> +   struct intel_memory_region *regions[ARRAY_SIZE(intel_region_map)];
> +
> struct intel_uncore uncore;
>  
> struct i915_virtual_gpu vgpu;
> @@ -2289,6 +2293,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  #define HAS_IPC(dev_priv)   
> (INTEL_INFO(dev_priv)->display.has_ipc)
>  
>  #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
> +#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
>  
>  /*
>   * For now, anything with a GuC requires uCode loading, and then supports
> diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
> b/drivers/gpu/drm/i915/intel_region_lmem.c
> new file mode 100644
> index ..c4b5a88627a3
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_region_lmem.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#include "i915_drv.h"
> +#include "intel_memory_region.h"
> +#include "intel_region_lmem.h"
> +
> +static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
> +   .get_pages = i915_memory_region_get_pages_buddy,
> +   .put_pages = i915_memory_region_put_pages_buddy,
> +   .release = i915_gem_object_release_memory_region,
> +};
> +
> +static struct drm_i915_gem_object *
> +lmem_create_object(struct intel_memory_region *mem,
> +  resource_size_t size,
> +  unsigned int flags)
> +{
> +   struct drm_i915_private *i915 = mem->i915;
> +   struct drm_i915_gem_object *obj;
> +   unsigned int cache_level;
> +
> +   if (flags & I915_BO_ALLOC_CONTIGUOUS)
> +   size = roundup_pow_of_two(size);

That should not be required. Seems like a missed opportunity to
pass the flag down to the allocator.

> +   if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
> +   return ERR_PTR(-E2BIG);
> +
> +   obj = i915_gem_object_alloc();
> +   if (!obj)
> +   return ERR_PTR(-ENOMEM);
> +
> +   drm_gem_private_object_init(&i915->drm, &obj->base, size);
> +   i915_gem_object_init(obj, ®ion_lmem_obj_ops);


> +   obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
> +   cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
> +   i915_gem_object_set_cache_coherency(obj, cache_level);

That seems a little optimistic. I would strongly suggest pulling that
information from the intel_memory_region.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 07/37] drm/i915: support creating LMEM objects

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:03)
> We currently define LMEM, or local memory, as just another memory
> region, like system memory or stolen, which we can expose to userspace
> and can be mapped to the CPU via some BAR.
> 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue 
> ---
>  drivers/gpu/drm/i915/Makefile |  1 +
>  drivers/gpu/drm/i915/i915_drv.h   |  5 ++
>  drivers/gpu/drm/i915/intel_region_lmem.c  | 66 +++
>  drivers/gpu/drm/i915/intel_region_lmem.h  | 16 +

You missed the mm/ vibes I was trying to send? ;)
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 06/37] drm/i915: Add memory region information to device_info

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:02)
> From: Abdiel Janulgue 
> 
> Exposes available regions for the platform. Shared memory will
> always be available.
> 
> Signed-off-by: Abdiel Janulgue 
> Signed-off-by: Matthew Auld 
> ---
>  drivers/gpu/drm/i915/i915_drv.h   |  2 ++
>  drivers/gpu/drm/i915/i915_pci.c   | 29 ++-
>  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
>  .../gpu/drm/i915/selftests/mock_gem_device.c  |  2 ++
>  4 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 97d02b32a208..838a796d9c55 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2288,6 +2288,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  
>  #define HAS_IPC(dev_priv)   
> (INTEL_INFO(dev_priv)->display.has_ipc)
>  
> +#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
> +
>  /*
>   * For now, anything with a GuC requires uCode loading, and then supports
>   * command submission once loaded. But these are logically independent
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 94b588e0a1dd..c513532b8da7 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -144,6 +144,9 @@
>  #define GEN_DEFAULT_PAGE_SIZES \
> .page_sizes = I915_GTT_PAGE_SIZE_4K
>  
> +#define GEN_DEFAULT_REGIONS \
> +   .memory_regions = REGION_SMEM | REGION_STOLEN

But you didn't add a stolen memory_region and use the new interface for
allocating the current stolen objects?
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 06/37] drm/i915: Add memory region information to device_info

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:02)
> From: Abdiel Janulgue 
> 
> Exposes available regions for the platform. Shared memory will
> always be available.
> 
> Signed-off-by: Abdiel Janulgue 
> Signed-off-by: Matthew Auld 
> ---
>  drivers/gpu/drm/i915/i915_drv.h   |  2 ++
>  drivers/gpu/drm/i915/i915_pci.c   | 29 ++-
>  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
>  .../gpu/drm/i915/selftests/mock_gem_device.c  |  2 ++
>  4 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 97d02b32a208..838a796d9c55 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2288,6 +2288,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>  
>  #define HAS_IPC(dev_priv)   
> (INTEL_INFO(dev_priv)->display.has_ipc)
>  
> +#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
> +
>  /*
>   * For now, anything with a GuC requires uCode loading, and then supports
>   * command submission once loaded. But these are logically independent
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 94b588e0a1dd..c513532b8da7 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -144,6 +144,9 @@
>  #define GEN_DEFAULT_PAGE_SIZES \
> .page_sizes = I915_GTT_PAGE_SIZE_4K
>  
> +#define GEN_DEFAULT_REGIONS \
> +   .memory_regions = REGION_SMEM | REGION_STOLEN
> +
>  #define I830_FEATURES \
> GEN(2), \
> .is_mobile = 1, \
> @@ -161,7 +164,8 @@
> I9XX_PIPE_OFFSETS, \
> I9XX_CURSOR_OFFSETS, \
> I9XX_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  #define I845_FEATURES \
> GEN(2), \
> @@ -178,7 +182,8 @@
> I845_PIPE_OFFSETS, \
> I845_CURSOR_OFFSETS, \
> I9XX_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  static const struct intel_device_info intel_i830_info = {
> I830_FEATURES,
> @@ -212,7 +217,8 @@ static const struct intel_device_info intel_i865g_info = {
> I9XX_PIPE_OFFSETS, \
> I9XX_CURSOR_OFFSETS, \
> I9XX_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  static const struct intel_device_info intel_i915g_info = {
> GEN3_FEATURES,
> @@ -297,7 +303,8 @@ static const struct intel_device_info 
> intel_pineview_m_info = {
> I9XX_PIPE_OFFSETS, \
> I9XX_CURSOR_OFFSETS, \
> I965_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  static const struct intel_device_info intel_i965g_info = {
> GEN4_FEATURES,
> @@ -347,7 +354,8 @@ static const struct intel_device_info intel_gm45_info = {
> I9XX_PIPE_OFFSETS, \
> I9XX_CURSOR_OFFSETS, \
> ILK_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  static const struct intel_device_info intel_ironlake_d_info = {
> GEN5_FEATURES,
> @@ -377,7 +385,8 @@ static const struct intel_device_info 
> intel_ironlake_m_info = {
> I9XX_PIPE_OFFSETS, \
> I9XX_CURSOR_OFFSETS, \
> ILK_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  #define SNB_D_PLATFORM \
> GEN6_FEATURES, \
> @@ -425,7 +434,8 @@ static const struct intel_device_info 
> intel_sandybridge_m_gt2_info = {
> IVB_PIPE_OFFSETS, \
> IVB_CURSOR_OFFSETS, \
> IVB_COLORS, \
> -   GEN_DEFAULT_PAGE_SIZES
> +   GEN_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  #define IVB_D_PLATFORM \
> GEN7_FEATURES, \
> @@ -486,6 +496,7 @@ static const struct intel_device_info 
> intel_valleyview_info = {
> I9XX_CURSOR_OFFSETS,
> I965_COLORS,
> GEN_DEFAULT_PAGE_SIZES,
> +   GEN_DEFAULT_REGIONS,
>  };
>  
>  #define G75_FEATURES  \
> @@ -582,6 +593,7 @@ static const struct intel_device_info 
> intel_cherryview_info = {
> CHV_CURSOR_OFFSETS,
> CHV_COLORS,
> GEN_DEFAULT_PAGE_SIZES,
> +   GEN_DEFAULT_REGIONS,
>  };
>  
>  #define GEN9_DEFAULT_PAGE_SIZES \
> @@ -657,7 +669,8 @@ static const struct intel_device_info 
> intel_skylake_gt4_info = {
> HSW_PIPE_OFFSETS, \
> IVB_CURSOR_OFFSETS, \
> IVB_COLORS, \
> -   GEN9_DEFAULT_PAGE_SIZES
> +   GEN9_DEFAULT_PAGE_SIZES, \
> +   GEN_DEFAULT_REGIONS
>  
>  static const struct intel_device_info intel_broxton_info = {
> GEN9_LP_FEATURES,
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
> b/drivers/gpu/drm/i915/intel_device_info.h
> index ddafc819bf30..63369b65110e 100644
> --- a/drivers/gpu/drm/i915/intel_devi

Re: [Intel-gfx] [PATCH v2 05/37] drm/i915/region: support volatile objects

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:01)
> Volatile objects are marked as DONTNEED while pinned, therefore once
> unpinned the backing store can be discarded.

Apply to existing code...
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 04/37] drm/i915/region: support continuous allocations

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:56:00)
> Some objects may need to be allocated as a continuous block, thinking
> ahead the various kernel io_mapping interfaces seem to expect it.
> 
> Signed-off-by: Matthew Auld 
> Cc: Joonas Lahtinen 
> Cc: Abdiel Janulgue 
> ---
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |   4 +
>  drivers/gpu/drm/i915/intel_memory_region.c|   7 +-
>  .../drm/i915/selftests/intel_memory_region.c  | 152 +-
>  drivers/gpu/drm/i915/selftests/mock_region.c  |   3 +
>  4 files changed, 160 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
> b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 87000fc24ab3..1c4b99e507c3 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -133,6 +133,10 @@ struct drm_i915_gem_object {
> struct list_head batch_pool_link;
> I915_SELFTEST_DECLARE(struct list_head st_link);
>  
> +   unsigned long flags;
> +#define I915_BO_ALLOC_CONTIGUOUS (1<<0)
BIT(0)
> +#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
> +
> /*
>  * Is the object to be mapped as read-only to the GPU
>  * Only honoured if hardware has relevant pte bit
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
> b/drivers/gpu/drm/i915/intel_memory_region.c
> index 721b47e46492..9b6a32bfa20d 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -90,6 +90,7 @@ i915_memory_region_get_pages_buddy(struct 
> drm_i915_gem_object *obj)
>  {
> struct intel_memory_region *mem = obj->memory_region;
> resource_size_t size = obj->base.size;
> +   unsigned int flags = obj->flags;

Was unsigned long.

> struct sg_table *st;
> struct scatterlist *sg;
> unsigned int sg_page_sizes;
> @@ -130,7 +131,7 @@ i915_memory_region_get_pages_buddy(struct 
> drm_i915_gem_object *obj)
> if (!IS_ERR(block))
> break;
>  
> -   if (!order--) {
> +   if (flags & I915_BO_ALLOC_CONTIGUOUS || !order--) {
> resource_size_t target;
> int err;
>  
> @@ -219,6 +220,9 @@ i915_gem_object_create_region(struct intel_memory_region 
> *mem,
> if (!mem)
> return ERR_PTR(-ENODEV);
>  
> +   if (flags & ~I915_BO_ALLOC_FLAGS)
> +   return ERR_PTR(-EINVAL);
> +
> size = round_up(size, mem->min_page_size);
>  
> GEM_BUG_ON(!size);
> @@ -236,6 +240,7 @@ i915_gem_object_create_region(struct intel_memory_region 
> *mem,
>  
> INIT_LIST_HEAD(&obj->blocks);
> obj->memory_region = mem;
> +   obj->flags = flags;
>  
> mutex_lock(&mem->obj_lock);
> list_add(&obj->region_link, &mem->objects);
> diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c 
> b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> index ece499869747..c9de8b5039e4 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
> @@ -78,17 +78,17 @@ static int igt_mock_fill(void *arg)
>  
>  static void igt_mark_evictable(struct drm_i915_gem_object *obj)
>  {
> -   i915_gem_object_unpin_pages(obj);
> +   if (i915_gem_object_has_pinned_pages(obj))
> +   i915_gem_object_unpin_pages(obj);
> obj->mm.madv = I915_MADV_DONTNEED;
> list_move(&obj->region_link, &obj->memory_region->purgeable);
>  }
>  
> -static int igt_mock_evict(void *arg)
> +static int igt_frag_region(struct intel_memory_region *mem,
> +  struct list_head *objects)
>  {
> -   struct intel_memory_region *mem = arg;
> struct drm_i915_gem_object *obj;
> unsigned long n_objects;
> -   LIST_HEAD(objects);
> resource_size_t target;
> resource_size_t total;
> int err = 0;
> @@ -104,7 +104,7 @@ static int igt_mock_evict(void *arg)
> goto err_close_objects;
> }
>  
> -   list_add(&obj->st_link, &objects);
> +   list_add(&obj->st_link, objects);
>  
> err = i915_gem_object_pin_pages(obj);
> if (err)
> @@ -118,6 +118,39 @@ static int igt_mock_evict(void *arg)
> igt_mark_evictable(obj);
> }
>  
> +   return 0;
> +
> +err_close_objects:
> +   close_objects(objects);
> +   return err;
> +}
> +
> +static void igt_defrag_region(struct list_head *objects)
> +{
> +   struct drm_i915_gem_object *obj;
> +
> +   list_for_each_entry(obj, objects, st_link) {
> +   if (obj->mm.madv == I915_MADV_WILLNEED)
> +   igt_mark_evictable(obj);
> +   }
> +}
> +
> +static int igt_mock_evict(void *arg)
> +{
> +   struct intel_memory_region *

Re: [Intel-gfx] [PATCH v2 03/37] drm/i915/region: support basic eviction

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:55:59)
> +int i915_memory_region_evict(struct intel_memory_region *mem,

What type is this again?

> +resource_size_t target)
> +{
> +   struct drm_i915_gem_object *obj, *on;
> +   resource_size_t found;
> +   LIST_HEAD(purgeable);
> +   int err;
> +
> +   err = 0;
> +   found = 0;
> +
> +   mutex_lock(&mem->obj_lock);
> +
> +   list_for_each_entry(obj, &mem->purgeable, region_link) {
> +   if (!i915_gem_object_has_pages(obj))
> +   continue;
> +
> +   if (READ_ONCE(obj->pin_global))
> +   continue;
> +
> +   if (atomic_read(&obj->bind_count))
> +   continue;
> +
> +   list_add(&obj->eviction_link, &purgeable);
> +
> +   found += obj->base.size;
> +   if (found >= target)
> +   goto found;
> +   }
> +
> +   err = -ENOSPC;
> +found:
> +   list_for_each_entry_safe(obj, on, &purgeable, eviction_link) {
> +   if (!err) {
> +   __i915_gem_object_put_pages(obj, I915_MM_SHRINKER);

How come put_pages is not taking mm->obj_lock to remove the
obj->region_link?

I'm getting fishy vibes.

> +
> +   mutex_lock_nested(&obj->mm.lock, I915_MM_SHRINKER);

> +   if (!i915_gem_object_has_pages(obj))
> +   obj->mm.madv = __I915_MADV_PURGED;

That should be pushed to put_pages() as reason. The unlock/lock is just
asking for trouble.

> +   mutex_unlock(&obj->mm.lock);
> +   }
> +
> +   list_del(&obj->eviction_link);
> +   }

You will have noticed that a separate eviction_link is superfluous? If
both region_link and evction_link are only valid underneath obj_lock,
you can list_move(&obj->region_link, &purgeable) in the first pass, and
unwind on error.

However, I'm going hmm.

So you keep all objects on the shrink lists even when not allocated. Ho
hum. With a bit more creative locking, read careful acquisition of
resources then dropping the lock before actually evicting, it should
work out.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH v4 8/8] drm/i915/display/icl: In port sync mode disable slaves first then masters

2019-06-27 Thread Manasi Navare
In the transcoder port sync mode, the slave transcoders mask their vblanks
until master transcoder's vblank so while disabling them, make
sure slaves are disabled first and then the masters.

v2:
* Use the intel_old_crtc_state_disables() helper

Cc: Ville Syrjälä 
Cc: Maarten Lankhorst 
Cc: Matt Roper 
Cc: Jani Nikula 
Signed-off-by: Manasi Navare 
---
 drivers/gpu/drm/i915/display/intel_display.c | 68 ++--
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 3ccba539cce0..e244d9cb4e33 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -13912,6 +13912,57 @@ static void intel_commit_modeset_disables(struct 
drm_atomic_state *state)
}
 }
 
+static void icl_commit_modeset_disables(struct drm_atomic_state *state)
+{
+   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+   struct intel_crtc_state *new_intel_crtc_state, *old_intel_crtc_state;
+   struct drm_crtc *crtc;
+   struct intel_crtc *intel_crtc;
+   int i;
+
+   /*
+* Disable all the Port Sync Slaves first
+*/
+   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
+   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
+   new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
+   intel_crtc = to_intel_crtc(crtc);
+
+   if (!needs_modeset(new_crtc_state) ||
+   !is_trans_port_sync_slave(old_intel_crtc_state))
+   continue;
+
+   intel_pre_plane_update(old_intel_crtc_state, 
new_intel_crtc_state);
+
+   if (old_crtc_state->active)
+   intel_old_crtc_state_disables(state,
+ old_intel_crtc_state,
+ new_intel_crtc_state,
+ intel_crtc);
+   }
+
+   /*
+* Disable rest of the CRTCs other than slaves
+*/
+   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
+   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
+   new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
+   intel_crtc = to_intel_crtc(crtc);
+
+   if (!needs_modeset(new_crtc_state) ||
+   is_trans_port_sync_slave(old_intel_crtc_state))
+   continue;
+
+   intel_pre_plane_update(old_intel_crtc_state, 
new_intel_crtc_state);
+
+   if (old_crtc_state->active)
+   intel_old_crtc_state_disables(state,
+ old_intel_crtc_state,
+ new_intel_crtc_state,
+ intel_crtc);
+   }
+}
+
 static void intel_commit_modeset_enables(struct drm_atomic_state *state)
 {
struct drm_crtc *crtc;
@@ -14268,6 +14319,11 @@ static void intel_atomic_commit_tail(struct 
drm_atomic_state *state)
 
intel_atomic_commit_fence_wait(intel_state);
 
+   drm_atomic_helper_wait_for_dependencies(state);
+
+   if (intel_state->modeset)
+   wakeref = intel_display_power_get(dev_priv, 
POWER_DOMAIN_MODESET);
+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
intel_crtc = to_intel_crtc(crtc);
@@ -14280,11 +14336,6 @@ static void intel_atomic_commit_tail(struct 
drm_atomic_state *state)
}
}
 
-   drm_atomic_helper_wait_for_dependencies(state);
-
-   if (intel_state->modeset)
-   wakeref = intel_display_power_get(dev_priv, 
POWER_DOMAIN_MODESET);
-
dev_priv->display.commit_modeset_disables(state);
 
/* FIXME: Eventually get rid of our intel_crtc->config pointer */
@@ -16181,7 +16232,12 @@ void intel_init_display_hooks(struct drm_i915_private 
*dev_priv)
else
dev_priv->display.commit_modeset_enables = 
intel_commit_modeset_enables;
 
-   dev_priv->display.commit_modeset_disables = 
intel_commit_modeset_disables;
+   if (INTEL_GEN(dev_priv) >= 11)
+   dev_priv->display.commit_modeset_disables =
+   icl_commit_modeset_disables;
+   else
+   dev_priv->display.commit_modeset_disables =
+   intel_commit_modeset_disables;
 
 }
 
-- 
2.19.1

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

[Intel-gfx] [PATCH v4 2/8] drm/i915/display: Move the commit_tail() disable sequence to commit_modeset_disables() hook

2019-06-27 Thread Manasi Navare
Create a new hook commit_modeset_disables() consistent with the naming
in drm atomic helpers and similar to the commit_modeset_enables() hook.
This helps better organize the disable sequence in atomic_commit_tail()
and move that to this disable hook.

No functional change

v2:
* Create a helper for old_crtc_state disables (Lucas)

Suggested-by: Daniel Vetter 
Cc: Ville Syrjälä 
Cc: Maarten Lankhorst 
Cc: Matt Roper 
Cc: Jani Nikula 
Signed-off-by: Manasi Navare 
---
 drivers/gpu/drm/i915/display/intel_display.c | 116 ---
 drivers/gpu/drm/i915/i915_drv.h  |   1 +
 2 files changed, 75 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 71e86e2f0f90..4b088fa24aad 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -13613,6 +13613,69 @@ static void intel_update_crtc(struct drm_crtc *crtc,
intel_finish_crtc_commit(to_intel_atomic_state(state), intel_crtc);
 }
 
+static void intel_old_crtc_state_disables(struct drm_atomic_state *state,
+ struct intel_crtc_state 
*old_intel_crtc_state,
+ struct intel_crtc_state 
*new_intel_crtc_state,
+ struct intel_crtc *intel_crtc)
+{
+   struct drm_i915_private *dev_priv = to_i915(state->dev);
+   struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+   struct drm_crtc_state *new_crtc_state = &new_intel_crtc_state->base;
+
+   intel_crtc_disable_planes(intel_state, intel_crtc);
+
+   /*
+* We need to disable pipe CRC before disabling the pipe,
+* or we race against vblank off.
+*/
+   intel_crtc_disable_pipe_crc(intel_crtc);
+
+   dev_priv->display.crtc_disable(old_intel_crtc_state, state);
+   intel_crtc->active = false;
+   intel_fbc_disable(intel_crtc);
+   intel_disable_shared_dpll(old_intel_crtc_state);
+
+   /*
+* Underruns don't always raise interrupts,
+* so check manually.
+*/
+   intel_check_cpu_fifo_underruns(dev_priv);
+   intel_check_pch_fifo_underruns(dev_priv);
+
+   /* FIXME unify this for all platforms */
+   if (!new_crtc_state->active &&
+   !HAS_GMCH(dev_priv) &&
+   dev_priv->display.initial_watermarks)
+   dev_priv->display.initial_watermarks(intel_state,
+new_intel_crtc_state);
+}
+
+static void intel_commit_modeset_disables(struct drm_atomic_state *state)
+{
+   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+   struct intel_crtc_state *new_intel_crtc_state, *old_intel_crtc_state;
+   struct drm_crtc *crtc;
+   struct intel_crtc *intel_crtc;
+   int i;
+
+   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
+   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
+   new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
+   intel_crtc = to_intel_crtc(crtc);
+
+   if (!needs_modeset(new_crtc_state))
+   continue;
+
+   intel_pre_plane_update(old_intel_crtc_state, 
new_intel_crtc_state);
+
+   if (old_crtc_state->active)
+   intel_old_crtc_state_disables(state,
+ old_intel_crtc_state,
+ new_intel_crtc_state,
+ intel_crtc);
+   }
+}
+
 static void intel_commit_modeset_enables(struct drm_atomic_state *state)
 {
struct drm_crtc *crtc;
@@ -13769,7 +13832,7 @@ static void intel_atomic_commit_tail(struct 
drm_atomic_state *state)
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
-   struct intel_crtc_state *new_intel_crtc_state, *old_intel_crtc_state;
+   struct intel_crtc_state *new_intel_crtc_state;
struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
u64 put_domains[I915_MAX_PIPES] = {};
@@ -13778,58 +13841,24 @@ static void intel_atomic_commit_tail(struct 
drm_atomic_state *state)
 
intel_atomic_commit_fence_wait(intel_state);
 
-   drm_atomic_helper_wait_for_dependencies(state);
-
-   if (intel_state->modeset)
-   wakeref = intel_display_power_get(dev_priv, 
POWER_DOMAIN_MODESET);
-
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
-   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
intel_crtc = to_intel_crtc(crtc);
 
if (need

Re: [Intel-gfx] [PATCH v2 02/37] drm/i915: introduce intel_memory_region

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:55:58)
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
> b/drivers/gpu/drm/i915/intel_memory_region.c
> new file mode 100644
> index ..4c89853a7769
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -0,0 +1,215 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#include "intel_memory_region.h"
> +#include "i915_drv.h"
> +
> +static void
> +memory_region_free_pages(struct drm_i915_gem_object *obj,
> +struct sg_table *pages)
> +{
> +
> +   struct i915_buddy_block *block, *on;
> +
> +   lockdep_assert_held(&obj->memory_region->mm_lock);
> +
> +   list_for_each_entry_safe(block, on, &obj->blocks, link) {
> +   list_del_init(&block->link);

Block is freed, link is dead already.

> +   i915_buddy_free(&obj->memory_region->mm, block);
> +   }

So instead of deleting every link, you can just reinitialise the list.

> +   sg_free_table(pages);
> +   kfree(pages);
> +}
> +
> +void
> +i915_memory_region_put_pages_buddy(struct drm_i915_gem_object *obj,
> +  struct sg_table *pages)
> +{
> +   mutex_lock(&obj->memory_region->mm_lock);
> +   memory_region_free_pages(obj, pages);
> +   mutex_unlock(&obj->memory_region->mm_lock);
> +
> +   obj->mm.dirty = false;
> +}
> +
> +int
> +i915_memory_region_get_pages_buddy(struct drm_i915_gem_object *obj)

This is not operating on a intel_memory_region now, is it?

> +{
> +   struct intel_memory_region *mem = obj->memory_region;
> +   resource_size_t size = obj->base.size;
> +   struct sg_table *st;
> +   struct scatterlist *sg;
> +   unsigned int sg_page_sizes;
> +   unsigned long n_pages;
> +
> +   GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.min_size));
> +   GEM_BUG_ON(!list_empty(&obj->blocks));
> +
> +   st = kmalloc(sizeof(*st), GFP_KERNEL);
> +   if (!st)
> +   return -ENOMEM;
> +
> +   n_pages = size >> ilog2(mem->mm.min_size);
> +
> +   if (sg_alloc_table(st, n_pages, GFP_KERNEL)) {
> +   kfree(st);
> +   return -ENOMEM;
> +   }
> +
> +   sg = st->sgl;
> +   st->nents = 0;
> +   sg_page_sizes = 0;
> +
> +   mutex_lock(&mem->mm_lock);
> +
> +   do {
> +   struct i915_buddy_block *block;
> +   unsigned int order;
> +   u64 block_size;
> +   u64 offset;
> +
> +   order = fls(n_pages) - 1;
> +   GEM_BUG_ON(order > mem->mm.max_order);
> +
> +   do {
> +   block = i915_buddy_alloc(&mem->mm, order);
> +   if (!IS_ERR(block))
> +   break;
> +
> +   /* XXX: some kind of eviction pass, local to the 
> device */
> +   if (!order--)
> +   goto err_free_blocks;
> +   } while (1);
> +
> +   n_pages -= BIT(order);
> +
> +   INIT_LIST_HEAD(&block->link);

No need, list_add works on the unitialised.

> +   list_add(&block->link, &obj->blocks);
> +
> +   /*
> +* TODO: it might be worth checking consecutive blocks here 
> and
> +* coalesce if we can.
> +   */
Hah.
> +   block_size = i915_buddy_block_size(&mem->mm, block);
> +   offset = i915_buddy_block_offset(block);
> +
> +   sg_dma_address(sg) = mem->region.start + offset;
> +   sg_dma_len(sg) = block_size;
> +
> +   sg->length = block_size;
> +   sg_page_sizes |= block_size;
> +   st->nents++;
> +
> +   if (!n_pages) {
> +   sg_mark_end(sg);
> +   break;
> +   }
> +
> +   sg = __sg_next(sg);
> +   } while (1);
> +

Ok, nothing else strayed under the lock.

> +   mutex_unlock(&mem->mm_lock);
> +
> +   i915_sg_trim(st);
> +
> +   __i915_gem_object_set_pages(obj, st, sg_page_sizes);
> +
> +   return 0;
> +
> +err_free_blocks:
> +   memory_region_free_pages(obj, st);
> +   mutex_unlock(&mem->mm_lock);
> +   return -ENXIO;
> +}
> +
> +int i915_memory_region_init_buddy(struct intel_memory_region *mem)
> +{
> +   return i915_buddy_init(&mem->mm, resource_size(&mem->region),
> +  mem->min_page_size);
> +}
> +
> +void i915_memory_region_release_buddy(struct intel_memory_region *mem)

Exporting these, with the wrong prefix even?

> +{
> +   i915_buddy_fini(&mem->mm);
> +}
> +
> +struct drm_i915_gem_object *
> +i915_gem_object_create_region(struct intel_memory_region *mem,
> + resource_size_t size,
> + unsigned int flags)
> +{
> +   struct drm_i915_gem_object *obj;
> +
> +   if (!mem)
> + 

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v2,1/2] drm/i915: Use port clock to set correct N value

2019-06-27 Thread Patchwork
== Series Details ==

Series: series starting with [v2,1/2] drm/i915: Use port clock to set correct N 
value
URL   : https://patchwork.freedesktop.org/series/62895/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Use port clock to set correct N value
Okay!

Commit: drm/i915: Add N & CTS values for 10/12 bit deep color
+drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
+drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)

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

Re: [Intel-gfx] [PATCH v2 01/37] drm/i915: buddy allocator

2019-06-27 Thread Chris Wilson
Quoting Matthew Auld (2019-06-27 21:55:57)
> Simple buddy allocator. We want to allocate properly aligned
> power-of-two blocks to promote usage of huge-pages for the GTT, so 64K,
> 2M and possibly even 1G. While we do support allocating stuff at a
> specific offset, it is more intended for preallocating portions of the
> address space, say for an initial framebuffer, for other uses drm_mm is
> probably a much better fit. Anyway, hopefully this can all be thrown
> away if we eventually move to having the core MM manage device memory.

Yeah, I still have no idea why drm_mm doesn't suffice.

The advantage of drm_mm_node being embedded and non-allocating is still
present, but drm_mm_node has the disadvantage of having grown to
accommodate multiple primary keys.

A bit more of a detailed discussion on the shortcomings, and
measurements for why we should use an intrinsically aligned allocator
over an allocator that allows arbitrary alignments. The obvious one
being allocation speed for >chunk_size allocations, but numbers :)
And just how frequently does it matter?

The major downside is the fragmentation penalty. That also needs
discussion. (Think of the joys of kcompactd and kmigrated.)

That discussion should also be mirrored in a theory of operation
documentation.
 
> Signed-off-by: Matthew Auld 
> ---
>  drivers/gpu/drm/i915/Makefile |   1 +
>  drivers/gpu/drm/i915/i915_buddy.c | 413 +++
>  drivers/gpu/drm/i915/i915_buddy.h | 115 
>  drivers/gpu/drm/i915/selftests/i915_buddy.c   | 491 ++
>  .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
>  5 files changed, 1021 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/i915_buddy.c
>  create mode 100644 drivers/gpu/drm/i915/i915_buddy.h
>  create mode 100644 drivers/gpu/drm/i915/selftests/i915_buddy.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 3bd8f0349a8a..cb66cf1a5a10 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -117,6 +117,7 @@ gem-y += \
>  i915-y += \
>   $(gem-y) \
>   i915_active.o \
> + i915_buddy.o \
>   i915_cmd_parser.o \
>   i915_gem_batch_pool.o \
>   i915_gem_evict.o \
> diff --git a/drivers/gpu/drm/i915/i915_buddy.c 
> b/drivers/gpu/drm/i915/i915_buddy.c
> new file mode 100644
> index ..c0ac68d71d94
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_buddy.c
> @@ -0,0 +1,413 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#include 
> +#include 
> +
> +#include "i915_buddy.h"
> +
> +#include "i915_gem.h"
> +#include "i915_utils.h"
> +
> +static void mark_allocated(struct i915_buddy_block *block)
> +{
> +   block->header &= ~I915_BUDDY_HEADER_STATE;
> +   block->header |= I915_BUDDY_ALLOCATED;
> +
> +   list_del_init(&block->link);
> +}
> +
> +static void mark_free(struct i915_buddy_mm *mm,
> + struct i915_buddy_block *block)
> +{
> +   block->header &= ~I915_BUDDY_HEADER_STATE;
> +   block->header |= I915_BUDDY_FREE;
> +
> +   list_add(&block->link,
> +&mm->free_list[i915_buddy_block_order(block)]);
> +}
> +
> +static void mark_split(struct i915_buddy_block *block)
> +{
> +   block->header &= ~I915_BUDDY_HEADER_STATE;
> +   block->header |= I915_BUDDY_SPLIT;
> +
> +   list_del_init(&block->link);
> +}
> +
> +int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 min_size)
> +{
> +   unsigned int i;
> +   u64 offset;
> +
> +   if (size < min_size)
> +   return -EINVAL;
> +
> +   if (min_size < PAGE_SIZE)
> +   return -EINVAL;
> +
> +   if (!is_power_of_2(min_size))
> +   return -EINVAL;
> +
> +   size = round_down(size, min_size);
> +
> +   mm->size = size;
> +   mm->min_size = min_size;
> +   mm->max_order = ilog2(rounddown_pow_of_two(size)) - ilog2(min_size);

ilog2(rounddown_pow_of_two(size)) is ilog2(size)

rounddown_pow_of_two(size): 1 << ilog2(size)
so you are saying ilog2(1 << ilog2(size))

fwiw, I still think of min_size as min_chunk_size (or just chunk_size).

> +
> +   GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER);
> +
> +   mm->free_list = kmalloc_array(mm->max_order + 1,
> + sizeof(struct list_head),
> + GFP_KERNEL);
> +   if (!mm->free_list)
> +   return -ENOMEM;
> +
> +   for (i = 0; i <= mm->max_order; ++i)
> +   INIT_LIST_HEAD(&mm->free_list[i]);
> +
> +   mm->blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN);
> +   if (!mm->blocks)
> +   goto out_free_list;

Would not one global slab cache will suffice? We would have better
reuse, if the kernel hasn't decided to merge slab caches.

> +   mm->n_roots = hweight64(size);
> +
> +   mm->roots = kmalloc_array(mm->n_roots

[Intel-gfx] [PATCH v2 2/2] drm/i915: Add N & CTS values for 10/12 bit deep color

2019-06-27 Thread Aditya Swarup
Adding N & CTS values for 10/12 bit deep color from Appendix C
table in HDMI 2.0 spec. The correct values for N is not chosen
automatically by hardware for deep color modes.

v2: Remove unnecessary initialization of size

Signed-off-by: Aditya Swarup 
Cc: Clint Taylor 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_audio.c | 79 +++---
 1 file changed, 68 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index 156d524c29d9..c8fd35a7ca42 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -72,6 +72,13 @@ struct dp_aud_n_m {
u16 n;
 };
 
+struct hdmi_aud_ncts {
+   int sample_rate;
+   int clock;
+   int n;
+   int cts;
+};
+
 /* Values according to DP 1.4 Table 2-104 */
 static const struct dp_aud_n_m dp_aud_n_m[] = {
{ 32000, LC_162M, 1024, 10125 },
@@ -148,12 +155,7 @@ static const struct {
 #define TMDS_594M 594000
 #define TMDS_593M 593407
 
-static const struct {
-   int sample_rate;
-   int clock;
-   int n;
-   int cts;
-} hdmi_aud_ncts[] = {
+static const struct hdmi_aud_ncts hdmi_aud_ncts_24bpp[] = {
{ 32000, TMDS_296M, 5824, 421875 },
{ 32000, TMDS_297M, 3072, 222750 },
{ 32000, TMDS_593M, 5824, 843750 },
@@ -184,6 +186,49 @@ static const struct {
{ 192000, TMDS_594M, 24576, 594000 },
 };
 
+/* Appendix C - N & CTS values for deep color from HDMI 2.0 spec*/
+/* HDMI N/CTS table for 10 bit deep color(30 bpp)*/
+#define TMDS_371M 371250
+#define TMDS_370M 370878
+
+static const struct hdmi_aud_ncts hdmi_aud_ncts_30bpp[] = {
+   { 32000, TMDS_370M, 5824, 527344 },
+   { 32000, TMDS_371M, 6144, 556875 },
+   { 44100, TMDS_370M, 8918, 585938 },
+   { 44100, TMDS_371M, 4704, 309375 },
+   { 88200, TMDS_370M, 17836, 585938 },
+   { 88200, TMDS_371M, 9408, 309375 },
+   { 176400, TMDS_370M, 35672, 585938 },
+   { 176400, TMDS_371M, 18816, 309375 },
+   { 48000, TMDS_370M, 11648, 703125 },
+   { 48000, TMDS_371M, 5120, 309375 },
+   { 96000, TMDS_370M, 23296, 703125 },
+   { 96000, TMDS_371M, 10240, 309375 },
+   { 192000, TMDS_370M, 46592, 703125 },
+   { 192000, TMDS_371M, 20480, 309375 },
+};
+
+/* HDMI N/CTS table for 12 bit deep color(36 bpp)*/
+#define TMDS_445_5M 445500
+#define TMDS_445M 445054
+
+static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
+   { 32000, TMDS_445M, 5824, 632813 },
+   { 32000, TMDS_445_5M, 4096, 445500 },
+   { 44100, TMDS_445M, 8918, 703125 },
+   { 44100, TMDS_445_5M, 4704, 371250 },
+   { 88200, TMDS_445M, 17836, 703125 },
+   { 88200, TMDS_445_5M, 9408, 371250 },
+   { 176400, TMDS_445M, 35672, 703125 },
+   { 176400, TMDS_445_5M, 18816, 371250 },
+   { 48000, TMDS_445M, 5824, 421875 },
+   { 48000, TMDS_445_5M, 5120, 371250 },
+   { 96000, TMDS_445M, 11648, 421875 },
+   { 96000, TMDS_445_5M, 10240, 371250 },
+   { 192000, TMDS_445M, 23296, 421875 },
+   { 192000, TMDS_445_5M, 20480, 371250 },
+};
+
 /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
 static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state 
*crtc_state)
 {
@@ -212,12 +257,24 @@ static u32 audio_config_hdmi_pixel_clock(const struct 
intel_crtc_state *crtc_sta
 static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
   int rate)
 {
-   int i;
+   const struct hdmi_aud_ncts *hdmi_ncts_table;
+   int i, size;
+
+   if (crtc_state->pipe_bpp == 36) {
+   hdmi_ncts_table = hdmi_aud_ncts_36bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_36bpp);
+   } else if (crtc_state->pipe_bpp == 30) {
+   hdmi_ncts_table = hdmi_aud_ncts_30bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_30bpp);
+   } else {
+   hdmi_ncts_table = hdmi_aud_ncts_24bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_24bpp);
+   }
 
-   for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) {
-   if (rate == hdmi_aud_ncts[i].sample_rate &&
-   crtc_state->port_clock == hdmi_aud_ncts[i].clock) {
-   return hdmi_aud_ncts[i].n;
+   for (i = 0; i < size; i++) {
+   if (rate == hdmi_ncts_table[i].sample_rate &&
+   crtc_state->port_clock == hdmi_ncts_table[i].clock) {
+   return hdmi_ncts_table[i].n;
}
}
return 0;
-- 
2.17.1

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

[Intel-gfx] [PATCH v2 1/2] drm/i915: Use port clock to set correct N value

2019-06-27 Thread Aditya Swarup
Use port_clock to check the clock values in n/cts lookup table instead
of crtc_clock. As port_clock is already adjusted based on color mode set
(8 bit or deep color), this will help in checking clock values for deep
color modes from n/cts lookup table.

Signed-off-by: Aditya Swarup 
Cc: Clint Taylor 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_audio.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index 840daff12246..156d524c29d9 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -212,13 +212,11 @@ static u32 audio_config_hdmi_pixel_clock(const struct 
intel_crtc_state *crtc_sta
 static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
   int rate)
 {
-   const struct drm_display_mode *adjusted_mode =
-   &crtc_state->base.adjusted_mode;
int i;
 
for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) {
if (rate == hdmi_aud_ncts[i].sample_rate &&
-   adjusted_mode->crtc_clock == hdmi_aud_ncts[i].clock) {
+   crtc_state->port_clock == hdmi_aud_ncts[i].clock) {
return hdmi_aud_ncts[i].n;
}
}
-- 
2.17.1

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

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for Set correct values for N in deep color mode

2019-06-27 Thread Patchwork
== Series Details ==

Series: Set correct values for N in deep color mode
URL   : https://patchwork.freedesktop.org/series/62894/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Use port clock to set correct N value
Okay!

Commit: drm/i915: Add N & CTS values for 10/12 bit deep color
+drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
+drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:1026:34: warning: expression using 
sizeof(void)

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

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for Introduce memory region concept (including device local memory) (rev2)

2019-06-27 Thread Patchwork
== Series Details ==

Series: Introduce memory region concept (including device local memory) (rev2)
URL   : https://patchwork.freedesktop.org/series/56683/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: buddy allocator
+drivers/gpu/drm/i915/selftests/i915_buddy.c:292:13: warning: expression using 
sizeof(void)
+drivers/gpu/drm/i915/selftests/i915_buddy.c:292:13: warning: expression using 
sizeof(void)
+drivers/gpu/drm/i915/selftests/i915_buddy.c:422:24: warning: expression using 
sizeof(void)
+drivers/gpu/drm/i915/selftests/i915_buddy.c:422:24: warning: expression using 
sizeof(void)
+./include/linux/slab.h:666:13: error: not a function 
+./include/linux/slab.h:666:13: error: undefined identifier 
'__builtin_mul_overflow'
+./include/linux/slab.h:666:13: warning: call with no type!

Commit: drm/i915: introduce intel_memory_region
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from 
constant value (8000 becomes 0)

Commit: drm/i915/region: support basic eviction
Okay!

Commit: drm/i915/region: support continuous allocations
Okay!

Commit: drm/i915/region: support volatile objects
Okay!

Commit: drm/i915: Add memory region information to device_info
Okay!

Commit: drm/i915: support creating LMEM objects
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from 
constant value (8000 becomes 0)

Commit: drm/i915: setup io-mapping for LMEM
Okay!

Commit: drm/i915/lmem: support kernel mapping
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:180:42:expected void [noderef] 
*vaddr
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:180:42:got void *[assigned] ptr
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:180:42: warning: incorrect type in 
argument 1 (different address spaces)
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:255:51:expected void *
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:255:51:got void [noderef] 
*
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:255:51: warning: incorrect type in 
return expression (different address spaces)
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:337:42:expected void [noderef] 
*vaddr
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:337:42:got void *[assigned] ptr
+drivers/gpu/drm/i915/gem/i915_gem_pages.c:337:42: warning: incorrect type in 
argument 1 (different address spaces)

Commit: drm/i915/blt: support copying objects
Okay!

Commit: drm/i915/selftests: move gpu-write-dw into utils
Okay!

Commit: drm/i915/selftests: add write-dword test for LMEM
Okay!

Commit: drm/i915/selftests: don't just test CACHE_NONE for huge-pages
Okay!

Commit: drm/i915/selftest: extend coverage to include LMEM huge-pages
Okay!

Commit: drm/i915/lmem: support CPU relocations
+drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:1107:15:expected void *vaddr
+drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:1107:15:got void [noderef] 
*
+drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:1107:15: warning: incorrect 
type in assignment (different address spaces)

Commit: drm/i915/lmem: support pread
Okay!

Commit: drm/i915/lmem: support pwrite
Okay!

Commit: drm/i915: enumerate and init each supported region
Okay!

Commit: drm/i915: treat shmem as a region
Okay!

Commit: drm/i915: treat stolen as a region
Okay!

Commit: drm/i915: define HAS_MAPPABLE_APERTURE
Okay!

Commit: drm/i915: do not map aperture if it is not available.
Okay!

Commit: drm/i915: expose missing map_gtt support to users
Okay!

Commit: drm/i915: set num_fence_regs to 0 if there is no aperture
Okay!

Commit: drm/i915/selftests: check for missing aperture
Okay!

Commit: drm/i915: error capture with no ggtt slot
+drivers/gpu/drm/i915/i915_gpu_error.c:1048:27:expected void *s
+drivers/gpu/drm/i915/i915_gpu_error.c:1048:27:got void [noderef] *
+drivers/gpu/drm/i915/i915_gpu_error.c:1048:27: warning: incorrect type in 
assignment (different address spaces)
+drivers/gpu/drm/i915/i915_gpu_error.c:1050:49:expected void [noderef] 
*vaddr
+drivers/gpu/drm/i915/i915_gpu_error.c:1050:49:got void *s
+drivers/gpu/drm/i915/i915_gpu_error.c:1050:49: warning: incorrect type in 
argument 1 (different address spaces)

Commit: drm/i915: Don't try to place HWS in non-existing mappable region
Okay!

Commit: drm/i915: Allow i915 to manage the vma offset nodes instead of drm core
+ ^
+ ^~
+ }
-drivers/gpu/drm/i915/display/icl_dsi.c:135:33: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/icl_dsi.c:1425:25: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/icl_dsi.c:1425:25: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/icl_dsi.c:1426:26: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/icl_dsi.c:1426:26: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:306:15: warning: expression using 
sizeof(void)
-drivers/gpu/drm/i915/display/intel_audio.c:306:15: warning: ex

[Intel-gfx] [PATCH 2/2] drm/i915: Add N & CTS values for 10/12 bit deep color

2019-06-27 Thread Aditya Swarup
Adding N & CTS values for 10/12 bit deep color from Appendix C
table in HDMI 2.0 spec. The correct values for N is not chosen
automatically by hardware for deep color modes.

Signed-off-by: Aditya Swarup 
Cc: Clint Taylor 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_audio.c | 79 +++---
 1 file changed, 68 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index 156d524c29d9..9305e7c354fb 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -72,6 +72,13 @@ struct dp_aud_n_m {
u16 n;
 };
 
+struct hdmi_aud_ncts {
+   int sample_rate;
+   int clock;
+   int n;
+   int cts;
+};
+
 /* Values according to DP 1.4 Table 2-104 */
 static const struct dp_aud_n_m dp_aud_n_m[] = {
{ 32000, LC_162M, 1024, 10125 },
@@ -148,12 +155,7 @@ static const struct {
 #define TMDS_594M 594000
 #define TMDS_593M 593407
 
-static const struct {
-   int sample_rate;
-   int clock;
-   int n;
-   int cts;
-} hdmi_aud_ncts[] = {
+static const struct hdmi_aud_ncts hdmi_aud_ncts_24bpp[] = {
{ 32000, TMDS_296M, 5824, 421875 },
{ 32000, TMDS_297M, 3072, 222750 },
{ 32000, TMDS_593M, 5824, 843750 },
@@ -184,6 +186,49 @@ static const struct {
{ 192000, TMDS_594M, 24576, 594000 },
 };
 
+/* Appendix C - N & CTS values for deep color from HDMI 2.0 spec*/
+/* HDMI N/CTS table for 10 bit deep color(30 bpp)*/
+#define TMDS_371M 371250
+#define TMDS_370M 370878
+
+static const struct hdmi_aud_ncts hdmi_aud_ncts_30bpp[] = {
+   { 32000, TMDS_370M, 5824, 527344 },
+   { 32000, TMDS_371M, 6144, 556875 },
+   { 44100, TMDS_370M, 8918, 585938 },
+   { 44100, TMDS_371M, 4704, 309375 },
+   { 88200, TMDS_370M, 17836, 585938 },
+   { 88200, TMDS_371M, 9408, 309375 },
+   { 176400, TMDS_370M, 35672, 585938 },
+   { 176400, TMDS_371M, 18816, 309375 },
+   { 48000, TMDS_370M, 11648, 703125 },
+   { 48000, TMDS_371M, 5120, 309375 },
+   { 96000, TMDS_370M, 23296, 703125 },
+   { 96000, TMDS_371M, 10240, 309375 },
+   { 192000, TMDS_370M, 46592, 703125 },
+   { 192000, TMDS_371M, 20480, 309375 },
+};
+
+/* HDMI N/CTS table for 12 bit deep color(36 bpp)*/
+#define TMDS_445_5M 445500
+#define TMDS_445M 445054
+
+static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
+   { 32000, TMDS_445M, 5824, 632813 },
+   { 32000, TMDS_445_5M, 4096, 445500 },
+   { 44100, TMDS_445M, 8918, 703125 },
+   { 44100, TMDS_445_5M, 4704, 371250 },
+   { 88200, TMDS_445M, 17836, 703125 },
+   { 88200, TMDS_445_5M, 9408, 371250 },
+   { 176400, TMDS_445M, 35672, 703125 },
+   { 176400, TMDS_445_5M, 18816, 371250 },
+   { 48000, TMDS_445M, 5824, 421875 },
+   { 48000, TMDS_445_5M, 5120, 371250 },
+   { 96000, TMDS_445M, 11648, 421875 },
+   { 96000, TMDS_445_5M, 10240, 371250 },
+   { 192000, TMDS_445M, 23296, 421875 },
+   { 192000, TMDS_445_5M, 20480, 371250 },
+};
+
 /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
 static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state 
*crtc_state)
 {
@@ -212,12 +257,24 @@ static u32 audio_config_hdmi_pixel_clock(const struct 
intel_crtc_state *crtc_sta
 static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
   int rate)
 {
-   int i;
+   const struct hdmi_aud_ncts *hdmi_ncts_table;
+   int i, size = 0;
+
+   if (crtc_state->pipe_bpp == 36) {
+   hdmi_ncts_table = hdmi_aud_ncts_36bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_36bpp);
+   } else if (crtc_state->pipe_bpp == 30) {
+   hdmi_ncts_table = hdmi_aud_ncts_30bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_30bpp);
+   } else {
+   hdmi_ncts_table = hdmi_aud_ncts_24bpp;
+   size = ARRAY_SIZE(hdmi_aud_ncts_24bpp);
+   }
 
-   for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) {
-   if (rate == hdmi_aud_ncts[i].sample_rate &&
-   crtc_state->port_clock == hdmi_aud_ncts[i].clock) {
-   return hdmi_aud_ncts[i].n;
+   for (i = 0; i < size; i++) {
+   if (rate == hdmi_ncts_table[i].sample_rate &&
+   crtc_state->port_clock == hdmi_ncts_table[i].clock) {
+   return hdmi_ncts_table[i].n;
}
}
return 0;
-- 
2.17.1

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

[Intel-gfx] [PATCH 1/2] drm/i915: Use port clock to set correct N value

2019-06-27 Thread Aditya Swarup
Use port_clock to check the clock values in n/cts lookup table instead
of crtc_clock. As port_clock is already adjusted based on color mode set
(8 bit or deep color), this will help in checking clock values for deep
color modes from n/cts lookup table.

Signed-off-by: Aditya Swarup 
Cc: Clint Taylor 
Cc: Jani Nikula 
Cc: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_audio.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index 840daff12246..156d524c29d9 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -212,13 +212,11 @@ static u32 audio_config_hdmi_pixel_clock(const struct 
intel_crtc_state *crtc_sta
 static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
   int rate)
 {
-   const struct drm_display_mode *adjusted_mode =
-   &crtc_state->base.adjusted_mode;
int i;
 
for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) {
if (rate == hdmi_aud_ncts[i].sample_rate &&
-   adjusted_mode->crtc_clock == hdmi_aud_ncts[i].clock) {
+   crtc_state->port_clock == hdmi_aud_ncts[i].clock) {
return hdmi_aud_ncts[i].n;
}
}
-- 
2.17.1

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

[Intel-gfx] [PATCH 0/2] Set correct values for N in deep color mode

2019-06-27 Thread Aditya Swarup
Patch series to set correct values for N based on port clock in deep
color mode. Currently, the hardware doesn't set the correct N in deep
color mode. 

Aditya Swarup (2):
  drm/i915: Use port clock to set correct N value
  drm/i915: Add N & CTS values for 10/12 bit deep color

 drivers/gpu/drm/i915/display/intel_audio.c | 81 ++
 1 file changed, 68 insertions(+), 13 deletions(-)

-- 
2.17.1

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

[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce memory region concept (including device local memory) (rev2)

2019-06-27 Thread Patchwork
== Series Details ==

Series: Introduce memory region concept (including device local memory) (rev2)
URL   : https://patchwork.freedesktop.org/series/56683/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
6f6eb8a214a1 drm/i915: buddy allocator
-:29: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does 
MAINTAINERS need updating?
#29: 
new file mode 100644

-:278: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#278: FILE: drivers/gpu/drm/i915/i915_buddy.c:245:
+void i915_buddy_free_list(struct i915_buddy_mm *mm,
+ struct list_head *objects)

-:436: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#436: FILE: drivers/gpu/drm/i915/i915_buddy.c:403:
+   if (buddy && (i915_buddy_block_free(block) &&
+   i915_buddy_block_free(buddy)))

-:468: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#468: FILE: drivers/gpu/drm/i915/i915_buddy.h:16:
+#define   I915_BUDDY_ALLOCATED (1<<10)
  ^

-:469: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#469: FILE: drivers/gpu/drm/i915/i915_buddy.h:17:
+#define   I915_BUDDY_FREE (2<<10)
 ^

-:470: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#470: FILE: drivers/gpu/drm/i915/i915_buddy.h:18:
+#define   I915_BUDDY_SPLIT(3<<10)
 ^

total: 0 errors, 1 warnings, 5 checks, 1030 lines checked
9dd43433710a drm/i915: introduce intel_memory_region
-:65: CHECK:LINE_SPACING: Please don't use multiple blank lines
#65: FILE: drivers/gpu/drm/i915/gem/selftests/huge_pages.c:451:
 
+

-:95: ERROR:CODE_INDENT: code indent should use tabs where possible
#95: FILE: drivers/gpu/drm/i915/gem/selftests/huge_pages.c:481:
+^I^I&obj->memory_region->region.start);$

-:179: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does 
MAINTAINERS need updating?
#179: 
new file mode 100644

-:196: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#196: FILE: drivers/gpu/drm/i915/intel_memory_region.c:13:
+{
+

-:278: WARNING:BLOCK_COMMENT_STYLE: Block comments should align the * on each 
line
#278: FILE: drivers/gpu/drm/i915/intel_memory_region.c:95:
+* coalesce if we can.
+   */

-:437: WARNING:TYPO_SPELLING: 'UKNOWN' may be misspelled - perhaps 'UNKNOWN'?
#437: FILE: drivers/gpu/drm/i915/intel_memory_region.h:33:
+   INTEL_MEMORY_UKNOWN, /* Should be last */

-:446: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'r' may be better as '(r)' to 
avoid precedence issues
#446: FILE: drivers/gpu/drm/i915/intel_memory_region.h:42:
+#define MEMORY_TYPE_FROM_REGION(r) (ilog2(r >> INTEL_MEMORY_TYPE_SHIFT))

-:447: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'r' may be better as '(r)' to 
avoid precedence issues
#447: FILE: drivers/gpu/drm/i915/intel_memory_region.h:43:
+#define MEMORY_INSTANCE_FROM_REGION(r) (ilog2(r & 0x))

-:461: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct 
intel_memory_region *' should also have an identifier name
#461: FILE: drivers/gpu/drm/i915/intel_memory_region.h:57:
+   int (*init)(struct intel_memory_region *);

-:462: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct 
intel_memory_region *' should also have an identifier name
#462: FILE: drivers/gpu/drm/i915/intel_memory_region.h:58:
+   void (*release)(struct intel_memory_region *);

-:464: WARNING:FUNCTION_ARGUMENTS: function definition argument 'struct 
intel_memory_region *' should also have an identifier name
#464: FILE: drivers/gpu/drm/i915/intel_memory_region.h:60:
+   struct drm_i915_gem_object *

-:464: WARNING:FUNCTION_ARGUMENTS: function definition argument 
'resource_size_t' should also have an identifier name
#464: FILE: drivers/gpu/drm/i915/intel_memory_region.h:60:
+   struct drm_i915_gem_object *

-:464: WARNING:FUNCTION_ARGUMENTS: function definition argument 'unsigned int' 
should also have an identifier name
#464: FILE: drivers/gpu/drm/i915/intel_memory_region.h:60:
+   struct drm_i915_gem_object *

-:479: CHECK:UNCOMMENTED_DEFINITION: struct mutex definition without comment
#479: FILE: drivers/gpu/drm/i915/intel_memory_region.h:75:
+   struct mutex mm_lock;

-:593: WARNING:EMBEDDED_FUNCTION_NAME: Prefer using '"%s...", __func__' to 
using 'igt_mock_fill', this function's name, in a string
#593: FILE: drivers/gpu/drm/i915/selftests/intel_memory_region.c:67:
+   pr_err("igt_mock_fill failed, space still left in 
region\n");

total: 1 errors, 9 warnings, 5 checks, 649 lines checked
b199239505e9 drm/i915/region: support basic eviction
97c56199279a drm/i915/region: support continuous allocations
-:22: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#22: FILE: drivers/gpu/drm/i915/gem/i915_gem_object_types.h:137:
+#define I915_BO_ALLOC_CONTIGUOUS (1<<0)
^

total: 0 errors, 0 warn

Re: [Intel-gfx] [RFC] drm/i915/tgl: Gen12 csb support

2019-06-27 Thread Chris Wilson
Quoting Daniele Ceraolo Spurio (2019-06-27 21:32:25)
> The CSB format has been reworked for Gen12 to include information on
> both the context we're switching away from and the context we're
> switching to. After the change, some of the events don't have their
> own bit anymore and need to be inferred from other values in the csb.
> One of the context IDs (0x7FF) has also been reserved to indicate
> the invalid ctx, i.e. engine idle.
> To keep the logic simple, we can convert the new gen12 format to the
> gen11 format and re-use the legacy csb handling logic. This result
> in a sliglthly slower handling for gen12 but allows us to get running
> with a relatively small change and avoids code duplication.
> 
> RFC: base TGL support [1] is not yet in the tree, but I wanted to get
> some early comments on this because I'm not totally convinced that the
> conversion is the best way of doing this. This way if another approach
> is proposed I can do the work while the base support gets reviewed. If
> we stick with the conversion we can probably optimize a bit.
> Toughts?

We only require a few states and so I wonder if we should try to map to
the current internal states

switch (csb_parse_fn[gen](buf + i)) {
case PREEMPT:
...
/* fallthrough */
case PROMOTE:
break;

case COMPLETE:
break;

default: /* boring non-event */
break;
}

I hope function pointers like that are not severely penalized nowadays.

Basically instead of compiling the mask, we have a sequence of check
and return. If we keep on logging the full CSB[] that is at least the
information we need to verify the events against our state tracking,
except that we push the effort out to the debugger to parse the event
details.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v2 12/23] drm/i915: Sanitize the TypeC connect/detect sequences

2019-06-27 Thread Souza, Jose
On Thu, 2019-06-27 at 12:48 +0300, Imre Deak wrote:
> On Thu, Jun 27, 2019 at 02:55:21AM +0300, Souza, Jose wrote:
> > On Thu, 2019-06-20 at 17:05 +0300, Imre Deak wrote:
> > > Make the order during detection more consistent: first reset the
> > > TypeC
> > > port mode if needed (adding new helpers for this), then detect
> > > any
> > > connected sink.
> > > 
> > > To check if a port mode reset is needed determine first the
> > > target
> > > port
> > > mode based on the live status if a sink is already connected or
> > > the
> > > PHY status complete flag otherwise.
> > > 
> > > Add a WARN in legacy mode if unexpectedly we can't set the unsafe
> > > mode
> > > or if the FIA doesn't provide the 4 lanes required.
> > > 
> > > Cc: José Roberto de Souza 
> > > Cc: Rodrigo Vivi 
> > > Cc: Paulo Zanoni 
> > > Cc: Ville Syrjälä 
> > > Signed-off-by: Imre Deak 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_tc.c | 96 ---
> > > 
> > > --
> > >  1 file changed, 47 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_tc.c
> > > b/drivers/gpu/drm/i915/display/intel_tc.c
> > > index fffe4c4a6602..ed2253b21b09 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_tc.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> > > @@ -172,41 +172,43 @@ static bool icl_tc_phy_set_safe_mode(struct
> > > intel_digital_port *dig_port,
> > >   * will require a lot of coordination with user space and
> > > thorough
> > > testing for
> > >   * the extra possible cases.
> > >   */
> > > -static bool icl_tc_phy_connect(struct intel_digital_port
> > > *dig_port)
> > > +static void icl_tc_phy_connect(struct intel_digital_port
> > > *dig_port)
> > >  {
> > > - u32 live_status_mask;
> > > -
> > > - if (dig_port->tc_mode != TC_PORT_LEGACY &&
> > > - dig_port->tc_mode != TC_PORT_DP_ALT)
> > > - return true;
> > > -
> > >   if (!icl_tc_phy_status_complete(dig_port)) {
> > >   DRM_DEBUG_KMS("Port %s: PHY not ready\n",
> > > dig_port->tc_port_name);
> > > - WARN_ON(dig_port->tc_legacy_port);
> > > - return false;
> > > + goto out_set_tbt_alt_mode;
> > >   }
> > >  
> > > - if (!icl_tc_phy_set_safe_mode(dig_port, false))
> > > - return false;
> > > + if (!icl_tc_phy_set_safe_mode(dig_port, false) &&
> > > + !WARN_ON(dig_port->tc_legacy_port))
> > > + goto out_set_tbt_alt_mode;
> > 
> > Marking as not safe even for TBT?
> 
> You mean if the above will set not-safe mode even for TBT? No, we
> will try to set not-safe mode only for DP-alt and legacy as the PHY
> status complete flag was set.

Oh okay, as you explained the complete flag will not be set for TBT.

Reviewed-by: José Roberto de Souza 


> 
> > >  
> > > - if (dig_port->tc_mode == TC_PORT_LEGACY)
> > > - return true;
> > > + if (dig_port->tc_legacy_port) {
> > > + WARN_ON(intel_tc_port_fia_max_lane_count(dig_port) !=
> > > 4);
> > > + dig_port->tc_mode = TC_PORT_LEGACY;
> > >  
> > > - live_status_mask = tc_port_live_status_mask(dig_port);
> > > + return;
> > > + }
> > >  
> > >   /*
> > >* Now we have to re-check the live state, in case the port
> > > recently
> > >* became disconnected. Not necessary for legacy mode.
> > >*/
> > > - if (!(live_status_mask & BIT(TC_PORT_DP_ALT))) {
> > > + if (!(tc_port_live_status_mask(dig_port) &
> > > BIT(TC_PORT_DP_ALT))) {
> > >   DRM_DEBUG_KMS("Port %s: PHY sudden disconnect\n",
> > > dig_port->tc_port_name);
> > > - icl_tc_phy_disconnect(dig_port);
> > > - return false;
> > > + goto out_set_safe_mode;
> > >   }
> > >  
> > > - return true;
> > > + dig_port->tc_mode = TC_PORT_DP_ALT;
> > > +
> > > + return;
> > > +
> > > +out_set_safe_mode:
> > > + icl_tc_phy_set_safe_mode(dig_port, true);
> > > +out_set_tbt_alt_mode:
> > > + dig_port->tc_mode = TC_PORT_TBT_ALT;
> > >  }
> > >  
> > >  /*
> > > @@ -227,27 +229,37 @@ void icl_tc_phy_disconnect(struct
> > > intel_digital_port *dig_port)
> > >   default:
> > >   MISSING_CASE(dig_port->tc_mode);
> > >   }
> > > +}
> > >  
> > > - DRM_DEBUG_KMS("Port %s: mode %s disconnected\n",
> > > -   dig_port->tc_port_name,
> > > -   tc_port_mode_name(dig_port->tc_mode));
> > > +static enum tc_port_mode
> > > +intel_tc_port_get_target_mode(struct intel_digital_port
> > > *dig_port)
> > > +{
> > > + u32 live_status_mask = tc_port_live_status_mask(dig_port);
> > > +
> > > + if (live_status_mask)
> > > + return fls(live_status_mask) - 1;
> > > +
> > > + return icl_tc_phy_status_complete(dig_port) &&
> > > +dig_port->tc_legacy_port ? TC_PORT_LEGACY :
> > > +   TC_PORT_TBT_ALT;
> > 
> > You are right about the order that C will execute this but could
> > you
> > add a pair of parenthesis around
> > icl_tc_phy_status_complete(dig_port)
> > && dig_port->tc_legacy_port to make easier to read?
>

[Intel-gfx] [PATCH v2 29/37] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Add a new CPU mmap implementation that allows multiple fault handlers
that depends on the object's backing pages.

Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
and use the zero extending behaviour of drm to differentiate between
them, when we inspect the flags.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|  2 ++
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 30 ++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
 drivers/gpu/drm/i915/i915_drv.c   |  3 +-
 include/uapi/drm/i915_drm.h   | 31 +++
 5 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
index ddc7f2a52b3e..5abd5b2172f2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -30,6 +30,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
 int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_priv);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 7b46f44d9c20..cbf89e80a97b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -536,12 +536,42 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file)
 {
struct drm_i915_gem_mmap_offset *args = data;
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   if (args->flags & I915_MMAP_OFFSET_FLAGS)
+   return i915_gem_mmap_offset_ioctl(dev, data, file);
+
+   if (!HAS_MAPPABLE_APERTURE(i915)) {
+   DRM_ERROR("No aperture, cannot mmap via legacy GTT\n");
+   return -ENODEV;
+   }
 
return __assign_gem_object_mmap_data(file, args->handle,
 I915_MMAP_TYPE_GTT,
 &args->offset);
 }
 
+int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file)
+{
+   struct drm_i915_gem_mmap_offset *args = data;
+   enum i915_mmap_type type;
+
+   if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
+   !boot_cpu_has(X86_FEATURE_PAT))
+   return -ENODEV;
+
+   if (args->flags & I915_MMAP_OFFSET_WC)
+   type = I915_MMAP_TYPE_OFFSET_WC;
+   else if (args->flags & I915_MMAP_OFFSET_WB)
+   type = I915_MMAP_TYPE_OFFSET_WB;
+   else if (args->flags & I915_MMAP_OFFSET_UC)
+   type = I915_MMAP_TYPE_OFFSET_UC;
+
+   return __assign_gem_object_mmap_data(file, args->handle, type,
+&args->offset);
+}
+
 void i915_mmap_offset_object_release(struct kref *ref)
 {
struct i915_mmap_offset *mmo = container_of(ref,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 86f358da8085..f95e54a25426 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -63,6 +63,9 @@ struct drm_i915_gem_object_ops {
 
 enum i915_mmap_type {
I915_MMAP_TYPE_GTT = 0,
+   I915_MMAP_TYPE_OFFSET_WC,
+   I915_MMAP_TYPE_OFFSET_WB,
+   I915_MMAP_TYPE_OFFSET_UC,
 };
 
 struct i915_mmap_offset {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0f1f3b7f3029..8dadd6b9a0a9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -459,6 +459,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void 
*data,
case I915_PARAM_HAS_EXEC_BATCH_FIRST:
case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
+   case I915_PARAM_MMAP_OFFSET_VERSION:
/* For the time being all of these are always true;
 * if some supported hardware does not have one of these
 * features this value needs to be provided from
@@ -3176,7 +3177,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
-   DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 
DRM_RE

[Intel-gfx] [PATCH v2 36/37] HAX drm/i915: add the fake lmem region

2019-06-27 Thread Matthew Auld
Intended for upstream testing so that we can still exercise the LMEM
plumbing and !HAS_MAPPABLE_APERTURE paths. Smoke tested on Skull Canyon
device. This works by allocating an intel_memory_region for a reserved
portion of system memory, which we treat like LMEM. For the LMEMBAR we
steal the aperture and 1:1 it map to the stolen region.

To enable simply set i915_fake_lmem_start= on the kernel cmdline with the
start of reserved region(see memmap=). The size of the region we can
use is determined by the size of the mappable aperture, so the size of
reserved region should be >= mappable_end.

eg. memmap=2G$16G i915.fake_lmem_start=0x4

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/i915_drv.c| 15 +
 drivers/gpu/drm/i915/i915_drv.h|  2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c|  3 +
 drivers/gpu/drm/i915/i915_params.c |  3 +
 drivers/gpu/drm/i915/i915_params.h |  3 +-
 drivers/gpu/drm/i915/intel_memory_region.h |  4 ++
 drivers/gpu/drm/i915/intel_region_lmem.c   | 76 ++
 drivers/gpu/drm/i915/intel_region_lmem.h   |  3 +
 8 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3d6fe993f26e..891937de6a2b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1869,6 +1869,9 @@ static void i915_driver_destroy(struct drm_i915_private 
*i915)
pci_set_drvdata(pdev, NULL);
 }
 
+struct resource intel_graphics_fake_lmem_res __ro_after_init = 
DEFINE_RES_MEM(0, 0);
+EXPORT_SYMBOL(intel_graphics_fake_lmem_res);
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @pdev: PCI device
@@ -1895,6 +1898,18 @@ int i915_driver_load(struct pci_dev *pdev, const struct 
pci_device_id *ent)
if (!i915_modparams.nuclear_pageflip && match_info->gen < 5)
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
 
+   /* Check if we need fake LMEM */
+   if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.fake_lmem_start > 0) {
+   intel_graphics_fake_lmem_res.start = 
i915_modparams.fake_lmem_start;
+   intel_graphics_fake_lmem_res.end = SZ_2G; /* Placeholder; 
depends on aperture size */
+
+   mkwrite_device_info(dev_priv)->memory_regions =
+   REGION_SMEM | REGION_LMEM;
+   GEM_BUG_ON(!HAS_LMEM(dev_priv));
+
+   pr_info("Intel graphics fake LMEM starts at %pa\n", 
&intel_graphics_fake_lmem_res.start);
+   }
+
ret = pci_enable_device(pdev);
if (ret)
goto out_fini;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 715e630a872d..9a2c79fa8088 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2815,4 +2815,6 @@ static inline void add_taint_for_CI(unsigned int taint)
add_taint(taint, LOCKDEP_STILL_OK);
 }
 
+extern struct resource intel_graphics_fake_lmem_res;
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3a8965048a06..df4928c8b10a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2938,6 +2938,9 @@ int i915_gem_init_memory_regions(struct drm_i915_private 
*i915)
case INTEL_STOLEN:
mem = i915_gem_stolen_setup(i915);
break;
+   case INTEL_LMEM:
+   mem = i915_gem_setup_fake_lmem(i915);
+   break;
}
 
if (IS_ERR(mem)) {
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 296452f9efe4..59a6ad6261b9 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -164,6 +164,9 @@ i915_param_named_unsafe(dmc_firmware_path, charp, 0400,
 i915_param_named_unsafe(enable_dp_mst, bool, 0600,
"Enable multi-stream transport (MST) for new DisplayPort sinks. 
(default: true)");
 
+i915_param_named_unsafe(fake_lmem_start, ulong, 0600,
+   "Fake LMEM start offset (default: 0)");
+
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
 i915_param_named_unsafe(inject_load_failure, uint, 0400,
"Force an error after a number of failure check points (0:disabled 
(default), N:force failure at the Nth failure check point)");
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index d29ade3b7de6..b9698722c957 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -77,7 +77,8 @@ struct drm_printer;
param(bool, verbose_state_checks, true) \
param(bool, nuclear_pageflip, false) \
param(bool, enable_dp_mst, true) \
-   param(bool, enable_gvt, false)
+   param(bool, enable_gvt, false) \
+   param(unsigned long, fake_lmem_start, 0)
 
 #define MEMBER(T, member, ...) T member;
 

[Intel-gfx] [PATCH v2 32/37] drm/i915: cpu-map based dumb buffers

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

If there is no aperture we can't use map_gtt to map dumb buffers, so we
need a cpu-map based path to do it. We prefer map_gtt on platforms that
do have aperture.

Signed-off-by: Abdiel Janulgue 
Cc: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 15 +++
 drivers/gpu/drm/i915/gem/i915_gem_object_types.h |  1 +
 drivers/gpu/drm/i915/i915_drv.c  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h  |  2 +-
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 5941648ee0ce..ce95d3f2b819 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -599,6 +599,19 @@ __assign_gem_object_mmap_data(struct drm_file *file,
return ret;
 }
 
+int
+i915_gem_mmap_dumb(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle,
+ u64 *offset)
+{
+   struct drm_i915_private *i915 = dev->dev_private;
+   enum i915_mmap_type mmap_type = HAS_MAPPABLE_APERTURE(i915) ?
+   I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_DUMB_WC;
+
+   return __assign_gem_object_mmap_data(file, handle, mmap_type, offset);
+}
+
 /**
  * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
  * @dev: DRM device
@@ -710,6 +723,7 @@ static void set_vmdata_mmap_offset(struct i915_mmap_offset 
*mmo, struct vm_area_
 {
switch (mmo->mmap_type) {
case I915_MMAP_TYPE_OFFSET_WC:
+   case I915_MMAP_TYPE_DUMB_WC:
vma->vm_page_prot =
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
break;
@@ -794,6 +808,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct 
*vma)
case I915_MMAP_TYPE_OFFSET_WC:
case I915_MMAP_TYPE_OFFSET_WB:
case I915_MMAP_TYPE_OFFSET_UC:
+   case I915_MMAP_TYPE_DUMB_WC:
set_vmdata_mmap_offset(mmo, vma);
break;
case I915_MMAP_TYPE_GTT:
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index f95e54a25426..a888ca64cc3f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -66,6 +66,7 @@ enum i915_mmap_type {
I915_MMAP_TYPE_OFFSET_WC,
I915_MMAP_TYPE_OFFSET_WB,
I915_MMAP_TYPE_OFFSET_UC,
+   I915_MMAP_TYPE_DUMB_WC,
 };
 
 struct i915_mmap_offset {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8dadd6b9a0a9..1c3d5cb2893c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -3229,7 +3229,7 @@ static struct drm_driver driver = {
.get_scanout_position = i915_get_crtc_scanoutpos,
 
.dumb_create = i915_gem_dumb_create,
-   .dumb_map_offset = i915_gem_mmap_gtt,
+   .dumb_map_offset = i915_gem_mmap_dumb,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = &i915_driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dc2bf48165f0..715e630a872d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2513,7 +2513,7 @@ i915_mutex_lock_interruptible(struct drm_device *dev)
 int i915_gem_dumb_create(struct drm_file *file_priv,
 struct drm_device *dev,
 struct drm_mode_create_dumb *args);
-int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
+int i915_gem_mmap_dumb(struct drm_file *file_priv, struct drm_device *dev,
  u32 handle, u64 *offset);
 int i915_gem_mmap_gtt_version(void);
 
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 35/37] drm/i915/query: Expose memory regions through the query uAPI

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Returns the available memory region areas supported by the HW.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_query.c | 57 +++
 include/uapi/drm/i915_drm.h   | 39 +
 2 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 7b7016171057..21c4c2592d6c 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -143,10 +143,67 @@ query_engine_info(struct drm_i915_private *i915,
return len;
 }
 
+static int query_memregion_info(struct drm_i915_private *dev_priv,
+   struct drm_i915_query_item *query_item)
+{
+   struct drm_i915_query_memory_region_info __user *query_ptr =
+   u64_to_user_ptr(query_item->data_ptr);
+   struct drm_i915_memory_region_info __user *info_ptr =
+   &query_ptr->regions[0];
+   struct drm_i915_memory_region_info info = { };
+   struct drm_i915_query_memory_region_info query;
+   u32 total_length;
+   int ret, i;
+
+   if (query_item->flags != 0)
+   return -EINVAL;
+
+   total_length = sizeof(struct drm_i915_query_memory_region_info);
+   for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+   struct intel_memory_region *region = dev_priv->regions[i];
+
+   if (!region)
+   continue;
+
+   total_length += sizeof(struct drm_i915_memory_region_info);
+   }
+
+   ret = copy_query_item(&query, sizeof(query), total_length,
+ query_item);
+   if (ret != 0)
+   return ret;
+
+   if (query.num_regions || query.rsvd[0] || query.rsvd[1] ||
+   query.rsvd[2])
+   return -EINVAL;
+
+   for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) {
+   struct intel_memory_region *region = dev_priv->regions[i];
+
+   if (!region)
+   continue;
+
+   info.id = region->id;
+   info.size = resource_size(®ion->region);
+
+   if (__copy_to_user(info_ptr, &info, sizeof(info)))
+   return -EFAULT;
+
+   query.num_regions++;
+   info_ptr++;
+   }
+
+   if (__copy_to_user(query_ptr, &query, sizeof(query)))
+   return -EFAULT;
+
+   return total_length;
+}
+
 static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
struct drm_i915_query_item *query_item) 
= {
query_topology_info,
query_engine_info,
+   query_memregion_info,
 };
 
 int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 5cf976e7608a..9b77d8af9877 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -2041,6 +2041,7 @@ struct drm_i915_query_item {
__u64 query_id;
 #define DRM_I915_QUERY_TOPOLOGY_INFO1
 #define DRM_I915_QUERY_ENGINE_INFO 2
+#define DRM_I915_QUERY_MEMREGION_INFO   3
 /* Must be kept compact -- no holes and well documented */
 
/*
@@ -2180,6 +2181,44 @@ struct drm_i915_query_engine_info {
struct drm_i915_engine_info engines[];
 };
 
+struct drm_i915_memory_region_info {
+
+   /** Base type of a region
+*/
+#define I915_SYSTEM_MEMORY 0
+#define I915_DEVICE_MEMORY 1
+
+   /** The region id is encoded in a layout which makes it possible to
+*  retrieve the following information:
+*
+*  Base type: log2(ID >> 16)
+*  Instance:  log2(ID & 0x)
+*/
+   __u32 id;
+
+   /** Reserved field. MBZ */
+   __u32 rsvd0;
+
+   /** Unused for now. MBZ */
+   __u64 flags;
+
+   __u64 size;
+
+   /** Reserved fields must be cleared to zero. */
+   __u64 rsvd1[4];
+};
+
+struct drm_i915_query_memory_region_info {
+
+   /** Number of struct drm_i915_memory_region_info structs */
+   __u32 num_regions;
+
+   /** MBZ */
+   __u32 rsvd[3];
+
+   struct drm_i915_memory_region_info regions[];
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 33/37] drm/i915: support basic object migration

2019-06-27 Thread Matthew Auld
We are going want to able to move objects between different regions
like system memory and local memory. In the future everything should
be just another region.

Signed-off-by: Matthew Auld 
Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c| 129 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   8 ++
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |   2 +-
 .../drm/i915/selftests/intel_memory_region.c  | 129 ++
 4 files changed, 267 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 343162bc8181..691af388e4e7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -28,6 +28,7 @@
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
 #include "i915_gem_object.h"
+#include "i915_gem_object_blt.h"
 #include "i915_globals.h"
 
 static struct i915_global_object {
@@ -171,6 +172,134 @@ void i915_gem_close_object(struct drm_gem_object *gem, 
struct drm_file *file)
}
 }
 
+int i915_gem_object_prepare_move(struct drm_i915_gem_object *obj)
+{
+   int err;
+
+   lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+   if (obj->mm.madv != I915_MADV_WILLNEED)
+   return -EINVAL;
+
+   if (i915_gem_object_needs_bit17_swizzle(obj))
+   return -EINVAL;
+
+   if (atomic_read(&obj->mm.pages_pin_count) >
+   atomic_read(&obj->bind_count))
+   return -EBUSY;
+
+   if (obj->pin_global)
+   return -EBUSY;
+
+   i915_gem_object_release_mmap(obj);
+
+   GEM_BUG_ON(obj->mm.mapping);
+   GEM_BUG_ON(obj->base.filp && mapping_mapped(obj->base.filp->f_mapping));
+
+   err = i915_gem_object_wait(obj,
+  I915_WAIT_INTERRUPTIBLE |
+  I915_WAIT_LOCKED |
+  I915_WAIT_ALL,
+  MAX_SCHEDULE_TIMEOUT);
+   if (err)
+   return err;
+
+   return i915_gem_object_unbind(obj);
+}
+
+int i915_gem_object_migrate(struct drm_i915_gem_object *obj,
+   struct intel_context *ce,
+   enum intel_region_id id)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct drm_i915_gem_object *donor;
+   struct intel_memory_region *mem;
+   int err = 0;
+
+   lockdep_assert_held(&i915->drm.struct_mutex);
+
+   GEM_BUG_ON(id >= INTEL_MEMORY_UKNOWN);
+   GEM_BUG_ON(obj->memory_region->id == id);
+   GEM_BUG_ON(obj->mm.madv != I915_MADV_WILLNEED);
+
+   mem = i915->regions[id];
+
+   donor = i915_gem_object_create_region(mem, obj->base.size, 0);
+   if (IS_ERR(donor))
+   return PTR_ERR(donor);
+
+   /* Copy backing-pages if we have to */
+   if (i915_gem_object_has_pages(obj)) {
+   struct sg_table *pages;
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   goto err_put_donor;
+
+   err = i915_gem_object_copy_blt(obj, donor, ce);
+   if (err)
+   goto err_put_donor;
+
+   i915_gem_object_lock(donor);
+   err = i915_gem_object_set_to_cpu_domain(donor, false);
+   i915_gem_object_unlock(donor);
+   if (err)
+   goto err_put_donor;
+
+   i915_retire_requests(i915);
+
+   i915_gem_object_unbind(donor);
+   err = i915_gem_object_unbind(obj);
+   if (err)
+   goto err_put_donor;
+
+   mutex_lock(&obj->mm.lock);
+
+   pages = fetch_and_zero(&obj->mm.pages);
+   obj->ops->put_pages(obj, pages);
+
+   memcpy(&obj->mm.page_sizes, &donor->mm.page_sizes,
+  sizeof(struct i915_page_sizes));
+   obj->mm.pages = __i915_gem_object_unset_pages(donor);
+
+   obj->mm.get_page.sg_pos = obj->mm.pages->sgl;
+   obj->mm.get_page.sg_idx = 0;
+   __i915_gem_object_reset_page_iter(obj);
+
+   mutex_unlock(&obj->mm.lock);
+   }
+
+   if (obj->ops->release)
+   obj->ops->release(obj);
+
+   /* We need still need a little special casing for shmem */
+   if (obj->base.filp)
+   fput(fetch_and_zero(&obj->base.filp));
+   else
+   obj->base.filp = fetch_and_zero(&donor->base.filp);
+
+   obj->base.size = donor->base.size;
+   obj->memory_region = mem;
+   obj->flags = donor->flags;
+   obj->ops = donor->ops;
+
+   list_replace_init(&donor->blocks, &obj->blocks);
+
+   mutex_lock(&mem->obj_lock);
+   list_add(&obj->region_link, &mem->objects);
+   mutex_unlock(&mem->obj_lock);
+
+   GEM_BUG_ON(i915_gem_object_has_pages

[Intel-gfx] [PATCH v2 37/37] HAX drm/i915/lmem: default userspace allocations to LMEM

2019-06-27 Thread Matthew Auld
Hack patch to default all userspace allocations to LMEM. Useful for
testing purposes.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/i915_gem.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ecdaca437797..a6f29acfb300 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -44,6 +44,7 @@
 #include "gem/i915_gem_clflush.h"
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_ioctls.h"
+#include "gem/i915_gem_object_blt.h"
 #include "gem/i915_gem_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
@@ -164,9 +165,45 @@ i915_gem_create(struct drm_file *file,
 
/* Allocate the new object */
obj = i915_gem_object_create_shmem(dev_priv, size);
+   if (HAS_LMEM(dev_priv))
+   obj = i915_gem_object_create_lmem(dev_priv, size, 0);
+   else
+   obj = i915_gem_object_create_shmem(dev_priv, size);
if (IS_ERR(obj))
return PTR_ERR(obj);
 
+   if (i915_gem_object_is_lmem(obj)) {
+   struct intel_context *ce =
+   dev_priv->engine[BCS0]->kernel_context;
+
+   /*
+* XXX: We really want to move this to get_pages(), but we
+* require grabbing the BKL for the blitting operation which is
+* annoying. In the pipeline is support for async get_pages()
+* which should fit nicely for this. Also note that the actual
+* clear should be done async(we currently do an object_wait
+* which is pure garbage), we just need to take care if
+* userspace opts of implicit sync for the execbuf, to avoid any
+* potential info leak.
+*/
+
+   mutex_lock(&dev_priv->drm.struct_mutex);
+   ret = i915_gem_object_fill_blt(obj, ce, 0);
+   mutex_unlock(&dev_priv->drm.struct_mutex);
+   if (ret) {
+   i915_gem_object_put(obj);
+   return ret;
+   }
+
+   i915_gem_object_lock(obj);
+   ret = i915_gem_object_set_to_cpu_domain(obj, false);
+   i915_gem_object_unlock(obj);
+   if (ret) {
+   i915_gem_object_put(obj);
+   return ret;
+   }
+   }
+
ret = drm_gem_handle_create(file, &obj->base, &handle);
/* drop reference from allocate - handle holds it now */
i915_gem_object_put(obj);
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 17/37] drm/i915/lmem: support pwrite

2019-06-27 Thread Matthew Auld
We need to add support for pwrite'ing an LMEM object.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 75 
 1 file changed, 75 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
index 54b2c7bf177d..d0a5311cf235 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -81,12 +81,87 @@ static int lmem_pread(struct drm_i915_gem_object *obj,
return ret;
 }
 
+static int lmem_pwrite(struct drm_i915_gem_object *obj,
+  const struct drm_i915_gem_pwrite *arg)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct intel_runtime_pm *rpm = &i915->runtime_pm;
+   intel_wakeref_t wakeref;
+   struct dma_fence *fence;
+   char __user *user_data;
+   unsigned int offset;
+   unsigned long idx;
+   u64 remain;
+   int ret;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return ret;
+
+   i915_gem_object_lock(obj);
+   ret = i915_gem_object_set_to_wc_domain(obj, true);
+   if (ret) {
+   i915_gem_object_unlock(obj);
+   goto out_unpin;
+   }
+
+   fence = i915_gem_object_lock_fence(obj);
+   i915_gem_object_unlock(obj);
+   if (!fence) {
+   ret = -ENOMEM;
+   goto out_unpin;
+   }
+
+   wakeref = intel_runtime_pm_get(rpm);
+
+   remain = arg->size;
+   user_data = u64_to_user_ptr(arg->data_ptr);
+   offset = offset_in_page(arg->offset);
+   for (idx = arg->offset >> PAGE_SHIFT; remain; idx++) {
+   unsigned long unwritten;
+   void __iomem *vaddr;
+   int length;
+
+   length = remain;
+   if (offset + length > PAGE_SIZE)
+   length = PAGE_SIZE - offset;
+
+   vaddr = i915_gem_object_lmem_io_map_page(obj, idx);
+   if (!vaddr) {
+   ret = -ENOMEM;
+   goto out_put;
+   }
+
+   unwritten = copy_from_user((void __force*)vaddr + offset,
+  user_data,
+  length);
+   io_mapping_unmap_atomic(vaddr);
+   if (unwritten) {
+   ret = -EFAULT;
+   goto out_put;
+   }
+
+   remain -= length;
+   user_data += length;
+   offset = 0;
+   }
+
+out_put:
+   intel_runtime_pm_put(rpm, wakeref);
+   i915_gem_object_unlock_fence(obj, fence);
+out_unpin:
+   i915_gem_object_unpin_pages(obj);
+
+   return ret;
+}
+
 static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
.get_pages = i915_memory_region_get_pages_buddy,
.put_pages = i915_memory_region_put_pages_buddy,
.release = i915_gem_object_release_memory_region,
 
.pread = lmem_pread,
+   .pwrite = lmem_pwrite,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 30/37] drm/i915/lmem: add helper to get CPU accessible offset

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

LMEM can be accessed by the CPU through a BAR. The mapping itself should
be 1:1.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 16 
 drivers/gpu/drm/i915/intel_region_lmem.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
index d0a5311cf235..ceec2bff465f 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -248,6 +248,22 @@ void __iomem *i915_gem_object_lmem_io_map(struct 
drm_i915_gem_object *obj,
return io_mapping_map_wc(&obj->memory_region->iomap, offset, size);
 }
 
+resource_size_t i915_gem_object_lmem_io_offset(struct drm_i915_gem_object *obj,
+  unsigned long n)
+{
+   struct intel_memory_region *mem = obj->memory_region;
+   dma_addr_t daddr;
+
+   /*
+* XXX: It's not a dma address, more a device address or physical
+* offset, so we are clearly abusing the semantics of the sg_table
+* here, and elsewhere like in the gtt paths.
+*/
+   daddr = i915_gem_object_get_dma_address(obj, n);
+
+   return mem->io_start + daddr;
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
struct intel_memory_region *region = obj->memory_region;
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h 
b/drivers/gpu/drm/i915/intel_region_lmem.h
index 20084f7b4bff..609de692489d 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.h
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -12,6 +12,9 @@ void __iomem *i915_gem_object_lmem_io_map(struct 
drm_i915_gem_object *obj,
 void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
   unsigned long n);
 
+resource_size_t i915_gem_object_lmem_io_offset(struct drm_i915_gem_object *obj,
+  unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 24/37] drm/i915: set num_fence_regs to 0 if there is no aperture

2019-06-27 Thread Matthew Auld
From: Daniele Ceraolo Spurio 

We can't fence anything without aperture.

Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Stuart Summers 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_fence_reg.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c 
b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
index bcac359ec661..bb7d9321cadf 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
@@ -808,8 +808,10 @@ void i915_ggtt_init_fences(struct i915_ggtt *ggtt)
 
detect_bit_6_swizzle(i915);
 
-   if (INTEL_GEN(i915) >= 7 &&
-   !(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   num_fences = 0;
+   else if (INTEL_GEN(i915) >= 7 &&
+!(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
num_fences = 32;
else if (INTEL_GEN(i915) >= 4 ||
 IS_I945G(i915) || IS_I945GM(i915) ||
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 34/37] drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

This call will specify which memory region an object should be placed.

Note that changing the object's backing storage should be immediately
done after an object is created or if it's not yet in use, otherwise
this will fail on a busy object.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c |  12 ++
 drivers/gpu/drm/i915/gem/i915_gem_context.h |   2 +
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h  |   2 +
 drivers/gpu/drm/i915/gem/i915_gem_object.c  | 117 
 drivers/gpu/drm/i915/i915_drv.c |   2 +-
 include/uapi/drm/i915_drm.h |  27 +
 6 files changed, 161 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 8a9787cf0cd0..157ca8247752 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -75,6 +75,7 @@
 #include "i915_globals.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
+#include "i915_gem_ioctls.h"
 
 #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
 
@@ -2357,6 +2358,17 @@ int i915_gem_context_setparam_ioctl(struct drm_device 
*dev, void *data,
return ret;
 }
 
+int i915_gem_setparam_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file)
+{
+   struct drm_i915_gem_context_param *args = data;
+
+   if (args->param <= I915_CONTEXT_PARAM_MAX)
+   return i915_gem_context_setparam_ioctl(dev, data, file);
+
+   return i915_gem_object_setparam_ioctl(dev, data, file);
+}
+
 int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
   void *data, struct drm_file *file)
 {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h 
b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 9691dd062f72..d5a9a63bb34c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -157,6 +157,8 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, 
void *data,
struct drm_file *file_priv);
 int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_setparam_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file);
 int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
index 5abd5b2172f2..af7465bceebd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -32,6 +32,8 @@ int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file);
 int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+int i915_gem_object_setparam_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_priv);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 691af388e4e7..bc95f449de50 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -551,6 +551,123 @@ int __init i915_global_objects_init(void)
return 0;
 }
 
+static enum intel_region_id
+__region_id(u32 region)
+{
+   enum intel_region_id id;
+
+   for (id = 0; id < ARRAY_SIZE(intel_region_map); ++id) {
+   if (intel_region_map[id] == region)
+   return id;
+   }
+
+   return INTEL_MEMORY_UKNOWN;
+}
+
+static int i915_gem_object_region_select(struct drm_i915_private *dev_priv,
+struct drm_i915_gem_object_param *args,
+struct drm_file *file,
+struct drm_i915_gem_object *obj)
+{
+   struct intel_context *ce = dev_priv->engine[BCS0]->kernel_context;
+   u32 __user *uregions = u64_to_user_ptr(args->data);
+   u32 uregions_copy[INTEL_MEMORY_UKNOWN];
+   int i, ret;
+
+   if (args->size > ARRAY_SIZE(intel_region_map))
+   return -EINVAL;
+
+   memset(uregions_copy, 0, sizeof(uregions_copy));
+   for (i = 0; i < args->size; i++) {
+   u32 region;
+
+   ret = get_user(region, uregions);
+   if (ret)
+   return ret;
+
+   uregions_copy[i] = region;
+   ++uregions;
+   }
+
+   mutex_lock(&dev_priv->drm.struct_mutex);
+

[Intel-gfx] [PATCH v2 31/37] drm/i915: Add cpu and lmem fault handlers

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Fault handler to handle missing pages to be filled depending on an
object's backing storage. Handle also changes needed to refault pages
depending on fault handler usage.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   | 154 +++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h |   2 +-
 drivers/gpu/drm/i915/i915_gem.c|   2 +-
 drivers/gpu/drm/i915/intel_region_lmem.c   |  47 +++
 drivers/gpu/drm/i915/intel_region_lmem.h   |   2 +
 5 files changed, 192 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index cbf89e80a97b..5941648ee0ce 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -369,7 +370,61 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
}
 }
 
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf)
+{
+   struct vm_area_struct *area = vmf->vma;
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
+   struct drm_device *dev = obj->base.dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   vm_fault_t vmf_ret;
+   unsigned long size = area->vm_end - area->vm_start;
+   bool write = area->vm_flags & VM_WRITE;
+   int i, ret;
+
+   /* Sanity check that we allow writing into this object */
+   if (i915_gem_object_is_readonly(obj) && write)
+   return VM_FAULT_SIGBUS;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   goto err;
+
+   for (i = 0; i < size >> PAGE_SHIFT; i++) {
+   struct page *page = i915_gem_object_get_page(obj, i);
+   vmf_ret = vmf_insert_pfn(area,
+(unsigned long)area->vm_start + i * 
PAGE_SIZE,
+page_to_pfn(page));
+   if (vmf_ret & VM_FAULT_ERROR) {
+   ret = vm_fault_to_errno(vmf_ret, 0);
+   break;
+   }
+   }
+
+   i915_gem_object_unpin_pages(obj);
+err:
+   switch (ret) {
+   case -EIO:
+   if (!i915_terminally_wedged(dev_priv))
+   return VM_FAULT_SIGBUS;
+   case -EAGAIN:
+   case 0:
+   case -ERESTARTSYS:
+   case -EINTR:
+   case -EBUSY:
+   return VM_FAULT_NOPAGE;
+   case -ENOMEM:
+   return VM_FAULT_OOM;
+   case -ENOSPC:
+   case -EFAULT:
+   return VM_FAULT_SIGBUS;
+   default:
+   WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret);
+   return VM_FAULT_SIGBUS;
+   }
+}
+
+void __i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
struct i915_mmap_offset *mmo;
@@ -378,21 +433,20 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
 
obj->userfault_count = 0;
list_del(&obj->userfault_link);
-   list_for_each_entry(mmo, &obj->mmap_offsets, offset)
-   drm_vma_node_unmap(&mmo->vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+
+   mutex_lock(&obj->mmo_lock);
+   list_for_each_entry(mmo, &obj->mmap_offsets, offset) {
+   if (mmo->mmap_type == I915_MMAP_TYPE_GTT)
+   drm_vma_node_unmap(&mmo->vma_node,
+  
obj->base.dev->anon_inode->i_mapping);
+   }
+   mutex_unlock(&obj->mmo_lock);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
 }
 
 /**
- * i915_gem_object_release_mmap - remove physical page mappings
- * @obj: obj in question
- *
- * Preserve the reservation of the mmapping with the DRM core code, but
- * relinquish ownership of the pages back to the system.
- *
  * It is vital that we remove the page mapping if we have mapped a tiled
  * object through the GTT and then lose the fence register due to
  * resource pressure. Similarly if the object has been moved out of the
@@ -400,7 +454,7 @@ void __i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
  * mapping will then trigger a page fault on the next user access, allowing
  * fixup by i915_gem_fault().
  */
-void i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
+static void i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj)
 {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
intel_wakeref_t wakeref;
@@ -419,7 +473,7 @@ void i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
if (!obj->userfault_count)
goto out;
 
-   __i915_gem_object_release_mmap(obj);
+   _

[Intel-gfx] [PATCH v2 16/37] drm/i915/lmem: support pread

2019-06-27 Thread Matthew Auld
We need to add support for pread'ing an LMEM object.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  2 +
 drivers/gpu/drm/i915/i915_gem.c   |  6 ++
 drivers/gpu/drm/i915/intel_region_lmem.c  | 76 +++
 3 files changed, 84 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 80ff5ad9bc07..8cdee185251a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -52,6 +52,8 @@ struct drm_i915_gem_object_ops {
void (*truncate)(struct drm_i915_gem_object *obj);
void (*writeback)(struct drm_i915_gem_object *obj);
 
+   int (*pread)(struct drm_i915_gem_object *,
+const struct drm_i915_gem_pread *arg);
int (*pwrite)(struct drm_i915_gem_object *obj,
  const struct drm_i915_gem_pwrite *arg);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 85677ae89849..4ba386ab35e7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -463,6 +463,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 
trace_i915_gem_object_pread(obj, args->offset, args->size);
 
+   ret = -ENODEV;
+   if (obj->ops->pread)
+   ret = obj->ops->pread(obj, args);
+   if (ret != -ENODEV)
+   goto out;
+
ret = i915_gem_object_wait(obj,
   I915_WAIT_INTERRUPTIBLE,
   MAX_SCHEDULE_TIMEOUT);
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
index 701bcac3479e..54b2c7bf177d 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -7,10 +7,86 @@
 #include "intel_memory_region.h"
 #include "intel_region_lmem.h"
 
+static int lmem_pread(struct drm_i915_gem_object *obj,
+ const struct drm_i915_gem_pread *arg)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct intel_runtime_pm *rpm = &i915->runtime_pm;
+   intel_wakeref_t wakeref;
+   struct dma_fence *fence;
+   char __user *user_data;
+   unsigned int offset;
+   unsigned long idx;
+   u64 remain;
+   int ret;
+
+   ret = i915_gem_object_pin_pages(obj);
+   if (ret)
+   return ret;
+
+   i915_gem_object_lock(obj);
+   ret = i915_gem_object_set_to_wc_domain(obj, false);
+   if (ret) {
+   i915_gem_object_unlock(obj);
+   goto out_unpin;
+   }
+
+   fence = i915_gem_object_lock_fence(obj);
+   i915_gem_object_unlock(obj);
+   if (!fence) {
+   ret = -ENOMEM;
+   goto out_unpin;
+   }
+
+   wakeref = intel_runtime_pm_get(rpm);
+
+   remain = arg->size;
+   user_data = u64_to_user_ptr(arg->data_ptr);
+   offset = offset_in_page(arg->offset);
+   for (idx = arg->offset >> PAGE_SHIFT; remain; idx++) {
+   unsigned long unwritten;
+   void __iomem *vaddr;
+   int length;
+
+   length = remain;
+   if (offset + length > PAGE_SIZE)
+   length = PAGE_SIZE - offset;
+
+   vaddr = i915_gem_object_lmem_io_map_page(obj, idx);
+   if (!vaddr) {
+   ret = -ENOMEM;
+   goto out_put;
+   }
+
+   unwritten = copy_to_user(user_data,
+(void __force *)vaddr + offset,
+length);
+   io_mapping_unmap_atomic(vaddr);
+   if (unwritten) {
+   ret = -EFAULT;
+   goto out_put;
+   }
+
+   remain -= length;
+   user_data += length;
+   offset = 0;
+   }
+
+out_put:
+   intel_runtime_pm_put(rpm, wakeref);
+   i915_gem_object_unlock_fence(obj, fence);
+out_unpin:
+   i915_gem_object_unpin_pages(obj);
+
+   return ret;
+}
+
 static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
.get_pages = i915_memory_region_get_pages_buddy,
.put_pages = i915_memory_region_put_pages_buddy,
.release = i915_gem_object_release_memory_region,
+
+   .pread = lmem_pread,
 };
 
 static struct drm_i915_gem_object *
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 22/37] drm/i915: do not map aperture if it is not available.

2019-06-27 Thread Matthew Auld
From: Daniele Ceraolo Spurio 

Skip both setup and cleanup of the aperture mapping if the HW doesn't
have an aperture bar.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 36 ++---
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5b7e46e487bf..43b99136a3ae 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2984,8 +2984,10 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
 
mutex_unlock(&i915->drm.struct_mutex);
 
-   arch_phys_wc_del(ggtt->mtrr);
-   io_mapping_fini(&ggtt->iomap);
+   if (HAS_MAPPABLE_APERTURE(i915)) {
+   arch_phys_wc_del(ggtt->mtrr);
+   io_mapping_fini(&ggtt->iomap);
+   }
 }
 
 /**
@@ -3386,10 +3388,13 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
int err;
 
/* TODO: We're not aware of mappable constraints on gen8 yet */
-   ggtt->gmadr =
-   (struct resource) DEFINE_RES_MEM(pci_resource_start(pdev, 2),
-pci_resource_len(pdev, 2));
-   ggtt->mappable_end = resource_size(&ggtt->gmadr);
+   /* FIXME: We probably need to add do device_info or runtime_info */
+   if (!HAS_LMEM(dev_priv)) {
+   ggtt->gmadr =
+   (struct resource) 
DEFINE_RES_MEM(pci_resource_start(pdev, 2),
+pci_resource_len(pdev, 
2));
+   ggtt->mappable_end = resource_size(&ggtt->gmadr);
+   }
 
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(39));
if (!err)
@@ -3619,15 +3624,18 @@ static int ggtt_init_hw(struct i915_ggtt *ggtt)
if (!HAS_LLC(i915) && !HAS_PPGTT(i915))
ggtt->vm.mm.color_adjust = i915_gtt_color_adjust;
 
-   if (!io_mapping_init_wc(&ggtt->iomap,
-   ggtt->gmadr.start,
-   ggtt->mappable_end)) {
-   ggtt->vm.cleanup(&ggtt->vm);
-   ret = -EIO;
-   goto out;
-   }
+   if (HAS_MAPPABLE_APERTURE(i915)) {
+   if (!io_mapping_init_wc(&ggtt->iomap,
+   ggtt->gmadr.start,
+   ggtt->mappable_end)) {
+   ggtt->vm.cleanup(&ggtt->vm);
+   ret = -EIO;
+   goto out;
+   }
 
-   ggtt->mtrr = arch_phys_wc_add(ggtt->gmadr.start, ggtt->mappable_end);
+   ggtt->mtrr = arch_phys_wc_add(ggtt->gmadr.start,
+ ggtt->mappable_end);
+   }
 
i915_ggtt_init_fences(ggtt);
 
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 15/37] drm/i915/lmem: support CPU relocations

2019-06-27 Thread Matthew Auld
Add LMEM support for the CPU reloc path. When doing relocations we have
both a GPU and CPU reloc path, as well as some debugging options to force a
particular path. The GPU reloc path is preferred when the object
is not currently idle, otherwise we use the CPU reloc path. Since we
can't kmap the object, and the mappable aperture might not be available,
add support for mapping it through LMEMBAR.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
Cc: Rodrigo Vivi 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 69 ---
 1 file changed, 58 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 1c5dfbfad71b..b724143e88d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -251,6 +251,7 @@ struct i915_execbuffer {
bool has_llc : 1;
bool has_fence : 1;
bool needs_unfenced : 1;
+   bool is_lmem : 1;
 
struct i915_request *rq;
u32 *rq_cmd;
@@ -963,6 +964,7 @@ static void reloc_cache_init(struct reloc_cache *cache,
cache->use_64bit_reloc = HAS_64BIT_RELOC(i915);
cache->has_fence = cache->gen < 4;
cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment;
+   cache->is_lmem = false;
cache->node.allocated = false;
cache->rq = NULL;
cache->rq_size = 0;
@@ -1020,16 +1022,23 @@ static void reloc_cache_reset(struct reloc_cache *cache)
i915_gem_object_finish_access((struct drm_i915_gem_object 
*)cache->node.mm);
} else {
wmb();
-   io_mapping_unmap_atomic((void __iomem *)vaddr);
-   if (cache->node.allocated) {
-   struct i915_ggtt *ggtt = cache_to_ggtt(cache);
-
-   ggtt->vm.clear_range(&ggtt->vm,
-cache->node.start,
-cache->node.size);
-   drm_mm_remove_node(&cache->node);
+
+   if (cache->is_lmem) {
+   io_mapping_unmap_atomic((void __iomem *)vaddr);
+   i915_gem_object_unpin_pages((struct drm_i915_gem_object 
*)cache->node.mm);
+   cache->is_lmem = false;
} else {
-   i915_vma_unpin((struct i915_vma *)cache->node.mm);
+   io_mapping_unmap_atomic((void __iomem *)vaddr);
+   if (cache->node.allocated) {
+   struct i915_ggtt *ggtt = cache_to_ggtt(cache);
+
+   ggtt->vm.clear_range(&ggtt->vm,
+cache->node.start,
+cache->node.size);
+   drm_mm_remove_node(&cache->node);
+   } else {
+   i915_vma_unpin((struct i915_vma 
*)cache->node.mm);
+   }
}
}
 
@@ -1069,6 +1078,40 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
return vaddr;
 }
 
+static void *reloc_lmem(struct drm_i915_gem_object *obj,
+   struct reloc_cache *cache,
+   unsigned long page)
+{
+   void *vaddr;
+   int err;
+
+   GEM_BUG_ON(use_cpu_reloc(cache, obj));
+
+   if (cache->vaddr) {
+   io_mapping_unmap_atomic((void __force __iomem *) 
unmask_page(cache->vaddr));
+   } else {
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_wc_domain(obj, true);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return ERR_PTR(err);
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   return ERR_PTR(err);
+
+   cache->node.mm = (void *)obj;
+   cache->is_lmem = true;
+   }
+
+   vaddr = i915_gem_object_lmem_io_map_page(obj, page);
+
+   cache->vaddr = (unsigned long)vaddr;
+   cache->page = page;
+
+   return vaddr;
+}
+
 static void *reloc_iomap(struct drm_i915_gem_object *obj,
 struct reloc_cache *cache,
 unsigned long page)
@@ -1145,8 +1188,12 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
vaddr = unmask_page(cache->vaddr);
} else {
vaddr = NULL;
-   if ((cache->vaddr & KMAP) == 0)
-   vaddr = reloc_iomap(obj, cache, page);
+   if ((cache->vaddr & KMAP) == 0) {
+   if (i915_gem_object_is_lmem(obj))
+   vaddr = reloc_lmem(obj, cache, page);
+   else
+   vaddr = reloc_iomap(obj, cache, page);
+ 

[Intel-gfx] [PATCH v2 26/37] drm/i915: error capture with no ggtt slot

2019-06-27 Thread Matthew Auld
From: Daniele Ceraolo Spurio 

If the aperture is not available in HW we can't use a ggtt slot and wc
copy, so fall back to regular kmap.

Signed-off-by: Daniele Ceraolo Spurio 
Signed-off-by: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 16 ---
 drivers/gpu/drm/i915/i915_gpu_error.c | 63 ---
 2 files changed, 57 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 43b99136a3ae..3a8965048a06 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2850,13 +2850,15 @@ static int init_ggtt(struct i915_ggtt *ggtt)
if (ret)
return ret;
 
-   /* Reserve a mappable slot for our lockless error capture */
-   ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, &ggtt->error_capture,
- PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
- 0, ggtt->mappable_end,
- DRM_MM_INSERT_LOW);
-   if (ret)
-   return ret;
+   if (HAS_MAPPABLE_APERTURE(ggtt->vm.i915)) {
+   /* Reserve a mappable slot for our lockless error capture */
+   ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, 
&ggtt->error_capture,
+ PAGE_SIZE, 0, 
I915_COLOR_UNEVICTABLE,
+ 0, ggtt->mappable_end,
+ DRM_MM_INSERT_LOW);
+   if (ret)
+   return ret;
+   }
 
/*
 * The upper portion of the GuC address space has a sizeable hole
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 5489cd879315..be920deb7ed7 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -218,7 +218,7 @@ struct compress {
void *tmp;
 };
 
-static bool compress_init(struct compress *c)
+static bool compress_init(struct compress *c, bool wc)
 {
struct z_stream_s *zstream = memset(&c->zstream, 0, sizeof(c->zstream));
 
@@ -234,7 +234,7 @@ static bool compress_init(struct compress *c)
}
 
c->tmp = NULL;
-   if (i915_has_memcpy_from_wc())
+   if (wc && i915_has_memcpy_from_wc())
c->tmp = (void *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN);
 
return true;
@@ -335,10 +335,12 @@ static void err_compression_marker(struct 
drm_i915_error_state_buf *m)
 #else
 
 struct compress {
+   bool wc;
 };
 
-static bool compress_init(struct compress *c)
+static bool compress_init(struct compress *c, bool wc)
 {
+   c->wc = wc;
return true;
 }
 
@@ -354,7 +356,7 @@ static int compress_page(struct compress *c,
return -ENOMEM;
 
ptr = (void *)page;
-   if (!i915_memcpy_from_wc(ptr, src, PAGE_SIZE))
+   if (!(c->wc && i915_memcpy_from_wc(ptr, src, PAGE_SIZE)))
memcpy(ptr, src, PAGE_SIZE);
dst->pages[dst->page_count++] = ptr;
 
@@ -998,7 +1000,6 @@ i915_error_object_create(struct drm_i915_private *i915,
struct compress compress;
unsigned long num_pages;
struct sgt_iter iter;
-   dma_addr_t dma;
int ret;
 
if (!vma || !vma->pages)
@@ -1017,22 +1018,52 @@ i915_error_object_create(struct drm_i915_private *i915,
dst->page_count = 0;
dst->unused = 0;
 
-   if (!compress_init(&compress)) {
+   if (!compress_init(&compress, 
drm_mm_node_allocated(&ggtt->error_capture))) {
kfree(dst);
return NULL;
}
 
ret = -EINVAL;
-   for_each_sgt_dma(dma, iter, vma->pages) {
+   if (drm_mm_node_allocated(&ggtt->error_capture)) {
void __iomem *s;
+   dma_addr_t dma;
 
-   ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
+   for_each_sgt_dma(dma, iter, vma->pages) {
+   ggtt->vm.insert_page(&ggtt->vm, dma, slot,
+I915_CACHE_NONE, 0);
 
-   s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
-   ret = compress_page(&compress, (void  __force *)s, dst);
-   io_mapping_unmap_atomic(s);
-   if (ret)
-   break;
+   s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
+   ret = compress_page(&compress, (void  __force *)s, dst);
+   io_mapping_unmap_atomic(s);
+
+   if (ret)
+   break;
+   }
+   } else if (i915_gem_object_is_lmem(vma->obj)) {
+   void *s;
+   dma_addr_t dma;
+   struct intel_memory_region *mem = vma->obj->memory_region;
+
+   for_each_sgt_dma(dma, iter, vma->pages) {
+   s = io_mapping_m

[Intel-gfx] [PATCH v2 28/37] drm/i915: Allow i915 to manage the vma offset nodes instead of drm core

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

This enables us to store extra data within vma->vm_private_data and assign
the pagefault ops for each mmap instance.

We replace the core drm_gem_mmap implementation to overcome the limitation
in having only a single offset node per gem object, allowing us to have
multiple offsets per object. This enables a mapping instance to use unique
fault-hadlers, per object.

Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 179 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  32 
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  17 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  17 ++
 .../drm/i915/gem/selftests/i915_gem_mman.c|  12 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |  19 +-
 drivers/gpu/drm/i915/i915_drv.c   |   9 +-
 drivers/gpu/drm/i915/i915_drv.h   |   1 +
 drivers/gpu/drm/i915/i915_vma.c   |  21 +-
 9 files changed, 268 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 391621ee3cbb..7b46f44d9c20 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -219,7 +219,8 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
struct vm_area_struct *area = vmf->vma;
-   struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
+   struct i915_mmap_offset *priv = area->vm_private_data;
+   struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_runtime_pm *rpm = &i915->runtime_pm;
@@ -371,13 +372,15 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj)
 {
struct i915_vma *vma;
+   struct i915_mmap_offset *mmo;
 
GEM_BUG_ON(!obj->userfault_count);
 
obj->userfault_count = 0;
list_del(&obj->userfault_link);
-   drm_vma_node_unmap(&obj->base.vma_node,
-  obj->base.dev->anon_inode->i_mapping);
+   list_for_each_entry(mmo, &obj->mmap_offsets, offset)
+   drm_vma_node_unmap(&mmo->vma_node,
+  obj->base.dev->anon_inode->i_mapping);
 
for_each_ggtt_vma(vma, obj)
i915_vma_unset_userfault(vma);
@@ -431,14 +434,31 @@ void i915_gem_object_release_mmap(struct 
drm_i915_gem_object *obj)
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 }
 
-static int create_mmap_offset(struct drm_i915_gem_object *obj)
+static void init_mmap_offset(struct drm_i915_gem_object *obj,
+struct i915_mmap_offset *mmo)
+{
+   mutex_lock(&obj->mmo_lock);
+   kref_init(&mmo->ref);
+   list_add(&mmo->offset, &obj->mmap_offsets);
+   mutex_unlock(&obj->mmo_lock);
+}
+
+static int create_mmap_offset(struct drm_i915_gem_object *obj,
+ struct i915_mmap_offset *mmo)
 {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct drm_device *dev = obj->base.dev;
int err;
 
-   err = drm_gem_create_mmap_offset(&obj->base);
-   if (likely(!err))
+   drm_vma_node_reset(&mmo->vma_node);
+   if (mmo->file)
+   drm_vma_node_allow(&mmo->vma_node, mmo->file);
+   err = drm_vma_offset_add(dev->vma_offset_manager, &mmo->vma_node,
+obj->base.size / PAGE_SIZE);
+   if (likely(!err)) {
+   init_mmap_offset(obj, mmo);
return 0;
+   }
 
/* Attempt to reap some mmap space from dead objects */
do {
@@ -449,32 +469,49 @@ static int create_mmap_offset(struct drm_i915_gem_object 
*obj)
break;
 
i915_gem_drain_freed_objects(i915);
-   err = drm_gem_create_mmap_offset(&obj->base);
-   if (!err)
+   err = drm_vma_offset_add(dev->vma_offset_manager, 
&mmo->vma_node,
+obj->base.size / PAGE_SIZE);
+   if (!err) {
+   init_mmap_offset(obj, mmo);
break;
+   }
 
} while (flush_delayed_work(&i915->gem.retire_work));
 
return err;
 }
 
-int
-i915_gem_mmap_gtt(struct drm_file *file,
- struct drm_device *dev,
- u32 handle,
- u64 *offset)
+static int
+__assign_gem_object_mmap_data(struct drm_file *file,
+ u32 handle,
+ enum i915_mmap_type mmap_type,
+ u64 *offset)
 {
struct drm_i915_gem_object *obj;
+   struct i915_mmap_offset *mmo;
int ret;
 
obj = i915_gem_object_lookup(file, handle);
if (!obj)
return -ENOENT;
 
-   ret =

[Intel-gfx] [PATCH v2 12/37] drm/i915/selftests: add write-dword test for LMEM

2019-06-27 Thread Matthew Auld
Simple test writing to dwords across an object, using various engines in
a randomized order, checking that our writes land from the cpu.

Signed-off-by: Matthew Auld 
---
 .../drm/i915/selftests/intel_memory_region.c  | 161 ++
 1 file changed, 161 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c 
b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 85d118c10d15..23c466a1b800 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -10,6 +10,7 @@
 #include "mock_gem_device.h"
 #include "gem/selftests/mock_context.h"
 #include "selftests/igt_flush_test.h"
+#include "selftests/i915_random.h"
 #include "mock_drm.h"
 
 #include "gem/i915_gem_object_blt.h"
@@ -347,6 +348,128 @@ static int igt_mock_volatile(void *arg)
return err;
 }
 
+static int igt_gpu_write_dw(struct i915_vma *vma,
+   struct i915_gem_context *ctx,
+   struct intel_engine_cs *engine,
+   u32 dword,
+   u32 value)
+{
+   int err;
+
+   i915_gem_object_lock(vma->obj);
+   err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
+   i915_gem_object_unlock(vma->obj);
+   if (err)
+   return err;
+
+   return igt_gpu_fill_dw(vma, ctx, engine, dword * sizeof(u32),
+  vma->size >> PAGE_SHIFT, value);
+}
+
+static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+   unsigned long n;
+   int err;
+
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_wc_domain(obj, false);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return err;
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   return err;
+
+   for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) {
+   u32 __iomem *base;
+   u32 read_val;
+
+   base = i915_gem_object_lmem_io_map_page(obj, n);
+
+   read_val = ioread32(base + dword);
+   io_mapping_unmap_atomic(base);
+   if (read_val != val) {
+   pr_err("n=%lu base[%u]=%u, val=%u\n",
+  n, dword, read_val, val);
+   err = -EINVAL;
+   break;
+   }
+   }
+
+   i915_gem_object_unpin_pages(obj);
+   return err;
+}
+
+static int igt_gpu_write(struct i915_gem_context *ctx,
+struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *i915 = ctx->i915;
+   struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
+   static struct intel_engine_cs *engines[I915_NUM_ENGINES];
+   struct intel_engine_cs *engine;
+   IGT_TIMEOUT(end_time);
+   I915_RND_STATE(prng);
+   struct i915_vma *vma;
+   unsigned int id;
+   int *order;
+   int i, n;
+   int err;
+
+   n = 0;
+   for_each_engine(engine, i915, id) {
+   if (!intel_engine_can_store_dword(engine)) {
+   pr_info("store-dword-imm not supported on engine=%u\n",
+   id);
+   continue;
+   }
+   engines[n++] = engine;
+   }
+
+   if (!n)
+   return 0;
+
+   order = i915_random_order(n * I915_NUM_ENGINES, &prng);
+   if (!order)
+   return -ENOMEM;
+
+   vma = i915_vma_instance(obj, vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out_free;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER);
+   if (err)
+   goto out_free;
+
+   i = 0;
+   do {
+   u32 rng = prandom_u32_state(&prng);
+   u32 dword = offset_in_page(rng) / 4;
+
+   engine = engines[order[i] % n];
+   i = (i + 1) % (n * I915_NUM_ENGINES);
+
+   err = igt_gpu_write_dw(vma, ctx, engine, dword, rng);
+   if (err)
+   break;
+
+   err = igt_cpu_check(obj, dword, rng);
+   if (err)
+   break;
+   } while (!__igt_timeout(end_time, NULL));
+
+   i915_vma_unpin(vma);
+out_free:
+   kfree(order);
+
+   if (err == -ENOMEM)
+   err = 0;
+
+   return err;
+}
+
 static int igt_lmem_create(void *arg)
 {
struct drm_i915_private *i915 = arg;
@@ -368,6 +491,43 @@ static int igt_lmem_create(void *arg)
return err;
 }
 
+static int igt_lmem_write_gpu(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   I915_RND_STATE(prng);
+   u32 sz;
+   int err;
+
+   /*
+* XXX: Nothing too big for now; we don't want to upset CI. What we
+* really want is the huge dma stuff for device memory, then we can go
+* to town...
+*/

[Intel-gfx] [PATCH v2 20/37] drm/i915: treat stolen as a region

2019-06-27 Thread Matthew Auld
Convert stolen memory over to a region object. Still leaves open the
question with what to do with pre-allocated objects...

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 66 +++---
 drivers/gpu/drm/i915/i915_drv.h|  3 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c| 14 +
 drivers/gpu/drm/i915/intel_memory_region.c |  2 +-
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index de1fab2058ec..d0b894854921 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -149,7 +149,7 @@ static int i915_adjust_stolen(struct drm_i915_private 
*dev_priv,
return 0;
 }
 
-void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
+static void i915_gem_cleanup_stolen(struct drm_i915_private *dev_priv)
 {
if (!drm_mm_initialized(&dev_priv->mm.stolen))
return;
@@ -354,7 +354,7 @@ static void icl_get_stolen_reserved(struct drm_i915_private 
*i915,
}
 }
 
-int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
+static int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
 {
resource_size_t reserved_base, stolen_top;
resource_size_t reserved_total, reserved_size;
@@ -533,6 +533,9 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object 
*obj)
 
i915_gem_stolen_remove_node(dev_priv, stolen);
kfree(stolen);
+
+   if (obj->memory_region)
+   i915_gem_object_release_memory_region(obj);
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
@@ -542,8 +545,8 @@ static const struct drm_i915_gem_object_ops 
i915_gem_object_stolen_ops = {
 };
 
 static struct drm_i915_gem_object *
-_i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
-  struct drm_mm_node *stolen)
+__i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+   struct drm_mm_node *stolen)
 {
struct drm_i915_gem_object *obj;
unsigned int cache_level;
@@ -570,10 +573,12 @@ _i915_gem_object_create_stolen(struct drm_i915_private 
*dev_priv,
return NULL;
 }
 
-struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
- resource_size_t size)
+static struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct intel_memory_region *mem,
+  resource_size_t size,
+  unsigned int flags)
 {
+   struct drm_i915_private *dev_priv = mem->i915;
struct drm_i915_gem_object *obj;
struct drm_mm_node *stolen;
int ret;
@@ -594,7 +599,7 @@ i915_gem_object_create_stolen(struct drm_i915_private 
*dev_priv,
return NULL;
}
 
-   obj = _i915_gem_object_create_stolen(dev_priv, stolen);
+   obj = __i915_gem_object_create_stolen(dev_priv, stolen);
if (obj)
return obj;
 
@@ -603,6 +608,49 @@ i915_gem_object_create_stolen(struct drm_i915_private 
*dev_priv,
return NULL;
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
+ resource_size_t size)
+{
+   struct drm_i915_gem_object *obj;
+
+   obj = 
i915_gem_object_create_region(dev_priv->regions[INTEL_MEMORY_STOLEN],
+   size, I915_BO_ALLOC_CONTIGUOUS);
+   if (IS_ERR(obj))
+   return NULL;
+
+   return obj;
+}
+
+static int init_stolen(struct intel_memory_region *mem)
+{
+   /*
+* Initialise stolen early so that we may reserve preallocated
+* objects for the BIOS to KMS transition.
+*/
+   return i915_gem_init_stolen(mem->i915);
+}
+
+static void release_stolen(struct intel_memory_region *mem)
+{
+   i915_gem_cleanup_stolen(mem->i915);
+}
+
+static const struct intel_memory_region_ops i915_region_stolen_ops = {
+   .init = init_stolen,
+   .release = release_stolen,
+   .create_object = _i915_gem_object_create_stolen,
+};
+
+struct intel_memory_region *i915_gem_stolen_setup(struct drm_i915_private 
*i915)
+{
+   return intel_memory_region_create(i915,
+ intel_graphics_stolen_res.start,
+ 
resource_size(&intel_graphics_stolen_res),
+ I915_GTT_PAGE_SIZE_4K, 0,
+ &i915_region_stolen_ops);
+}
+
 struct drm_i915_gem_object *
 i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private 
*dev_priv,
   resource_size_t stolen_offset,
@@ -644,7 +692,7 @@ i915_gem_object_create_stolen_for_preallocated(struct 
drm_i915_private *dev_priv
retur

[Intel-gfx] [PATCH v2 23/37] drm/i915: expose missing map_gtt support to users

2019-06-27 Thread Matthew Auld
From: Daniele Ceraolo Spurio 

Done by returning -ENODEV from the map_gtt version ioctl.

Cc: Antonio Argenziano 
Cc: Matthew Auld 
Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/i915_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ac8fbada0406..34edc0302691 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -425,6 +425,8 @@ static int i915_getparam_ioctl(struct drm_device *dev, void 
*data,
return value;
break;
case I915_PARAM_MMAP_GTT_VERSION:
+   if (!HAS_MAPPABLE_APERTURE(dev_priv))
+   return -ENODEV;
/* Though we've started our numbering from 1, and so class all
 * earlier versions as 0, in effect their value is undefined as
 * the ioctl will report EINVAL for the unknown param!
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 25/37] drm/i915/selftests: check for missing aperture

2019-06-27 Thread Matthew Auld
We may be missing support for the mappable aperture on some platforms.

Signed-off-by: Matthew Auld 
Cc: Daniele Ceraolo Spurio 
---
 .../drm/i915/gem/selftests/i915_gem_coherency.c|  5 -
 drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c |  3 +++
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c   | 14 ++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c  |  3 +++
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
index 8f22d3f18422..7f80fdc94e40 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
@@ -242,7 +242,10 @@ static bool always_valid(struct drm_i915_private *i915)
 
 static bool needs_fence_registers(struct drm_i915_private *i915)
 {
-   return !i915_terminally_wedged(i915);
+   if (i915_terminally_wedged(i915))
+   return false;
+
+   return i915->ggtt.num_fences;
 }
 
 static bool needs_mi_store_dword(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index a1f0b235f56b..6949df0f963f 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -184,6 +184,9 @@ static int igt_partial_tiling(void *arg)
int tiling;
int err;
 
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   return 0;
+
/* We want to check the page mapping and fencing of a large object
 * mmapped through the GTT. The object we create is larger than can
 * possibly be mmaped as a whole, and so we must use partial GGTT vma.
diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c 
b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index cf592a049a71..d9712149aa1a 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -1182,8 +1182,12 @@ static int __igt_reset_evict_vma(struct drm_i915_private 
*i915,
struct i915_request *rq;
struct evict_vma arg;
struct hang h;
+   unsigned int pin_flags;
int err;
 
+   if (!i915->ggtt.num_fences && flags & EXEC_OBJECT_NEEDS_FENCE)
+   return 0;
+
if (!intel_engine_can_store_dword(i915->engine[RCS0]))
return 0;
 
@@ -1220,10 +1224,12 @@ static int __igt_reset_evict_vma(struct 
drm_i915_private *i915,
goto out_obj;
}
 
-   err = i915_vma_pin(arg.vma, 0, 0,
-  i915_vma_is_ggtt(arg.vma) ?
-  PIN_GLOBAL | PIN_MAPPABLE :
-  PIN_USER);
+   pin_flags = i915_vma_is_ggtt(arg.vma) ? PIN_GLOBAL : PIN_USER;
+
+   if (flags & EXEC_OBJECT_NEEDS_FENCE)
+   pin_flags |= PIN_MAPPABLE;
+
+   err = i915_vma_pin(arg.vma, 0, 0, pin_flags);
if (err) {
i915_request_add(rq);
goto out_obj;
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 31a51ca1ddcb..d049b7f32233 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1148,6 +1148,9 @@ static int igt_ggtt_page(void *arg)
unsigned int *order, n;
int err;
 
+   if (!HAS_MAPPABLE_APERTURE(i915))
+   return 0;
+
mutex_lock(&i915->drm.struct_mutex);
 
obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 19/37] drm/i915: treat shmem as a region

2019-06-27 Thread Matthew Auld
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 67 ++-
 drivers/gpu/drm/i915/i915_drv.c   |  5 +-
 drivers/gpu/drm/i915/i915_drv.h   |  4 +-
 drivers/gpu/drm/i915/i915_gem.c   | 13 +---
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 11 ++-
 drivers/gpu/drm/i915/intel_memory_region.c|  9 +++
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  4 --
 7 files changed, 68 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 19d9ecdb2894..11c7ebda9e0e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -8,6 +8,7 @@
 #include 
 
 #include "i915_drv.h"
+#include "i915_gemfs.h"
 #include "i915_gem_object.h"
 #include "i915_scatterlist.h"
 
@@ -25,6 +26,7 @@ static void check_release_pagevec(struct pagevec *pvec)
 static int shmem_get_pages(struct drm_i915_gem_object *obj)
 {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct intel_memory_region *mem = obj->memory_region;
const unsigned long page_count = obj->base.size / PAGE_SIZE;
unsigned long i;
struct address_space *mapping;
@@ -51,7 +53,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 * If there's no chance of allocating enough pages for the whole
 * object, bail early.
 */
-   if (page_count > totalram_pages())
+   if (obj->base.size > resource_size(&mem->region))
return -ENOMEM;
 
st = kmalloc(sizeof(*st), GFP_KERNEL);
@@ -424,9 +426,11 @@ const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {
.writeback = shmem_writeback,
 
.pwrite = shmem_pwrite,
+
+   .release = i915_gem_object_release_memory_region,
 };
 
-static int create_shmem(struct drm_i915_private *i915,
+static int __create_shmem(struct drm_i915_private *i915,
struct drm_gem_object *obj,
size_t size)
 {
@@ -447,31 +451,23 @@ static int create_shmem(struct drm_i915_private *i915,
return 0;
 }
 
-struct drm_i915_gem_object *
-i915_gem_object_create_shmem(struct drm_i915_private *i915, u64 size)
+static struct drm_i915_gem_object *
+create_shmem(struct intel_memory_region *mem,
+resource_size_t size,
+unsigned flags)
 {
+   struct drm_i915_private *i915 = mem->i915;
struct drm_i915_gem_object *obj;
struct address_space *mapping;
unsigned int cache_level;
gfp_t mask;
int ret;
 
-   /* There is a prevalence of the assumption that we fit the object's
-* page count inside a 32bit _signed_ variable. Let's document this and
-* catch if we ever need to fix it. In the meantime, if you do spot
-* such a local variable, please consider fixing!
-*/
-   if (size >> PAGE_SHIFT > INT_MAX)
-   return ERR_PTR(-E2BIG);
-
-   if (overflows_type(size, obj->base.size))
-   return ERR_PTR(-E2BIG);
-
obj = i915_gem_object_alloc();
if (!obj)
return ERR_PTR(-ENOMEM);
 
-   ret = create_shmem(i915, &obj->base, size);
+   ret = __create_shmem(i915, &obj->base, size);
if (ret)
goto fail;
 
@@ -510,8 +506,6 @@ i915_gem_object_create_shmem(struct drm_i915_private *i915, 
u64 size)
 
i915_gem_object_set_cache_coherency(obj, cache_level);
 
-   trace_i915_gem_object_create(obj);
-
return obj;
 
 fail:
@@ -519,6 +513,13 @@ i915_gem_object_create_shmem(struct drm_i915_private 
*i915, u64 size)
return ERR_PTR(ret);
 }
 
+struct drm_i915_gem_object *
+i915_gem_object_create_shmem(struct drm_i915_private *i915, u64 size)
+{
+   return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_SMEM],
+size, 0);
+}
+
 /* Allocate a new GEM object and fill it with the supplied data */
 struct drm_i915_gem_object *
 i915_gem_object_create_shmem_from_data(struct drm_i915_private *dev_priv,
@@ -569,3 +570,33 @@ i915_gem_object_create_shmem_from_data(struct 
drm_i915_private *dev_priv,
i915_gem_object_put(obj);
return ERR_PTR(err);
 }
+
+static int init_shmem(struct intel_memory_region *mem)
+{
+   int err;
+
+   err = i915_gemfs_init(mem->i915);
+   if (err)
+DRM_NOTE("Unable to create a private tmpfs mount, hugepage 
support will be disabled(%d).\n", err);
+
+   return 0; /* Don't error, we can simply fallback to the kernel mnt */
+}
+
+static void release_shmem(struct intel_memory_region *mem)
+{
+   i915_gemfs_fini(mem->i915);
+}
+
+static const struct intel_memory_region_ops shmem_region_ops = {
+   .init = init_shmem,
+   .release = release_shmem,
+   .create_object = create_shmem,
+};
+
+struct intel_memory_region *i915_gem_shmem_setup(s

[Intel-gfx] [PATCH v2 27/37] drm/i915: Don't try to place HWS in non-existing mappable region

2019-06-27 Thread Matthew Auld
From: Michal Wajdeczko 

HWS placement restrictions can't just rely on HAS_LLC flag.

Signed-off-by: Michal Wajdeczko 
Cc: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index d1508f0b4c84..a4aedf1d7f2a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -543,7 +543,7 @@ static int pin_ggtt_status_page(struct intel_engine_cs 
*engine,
unsigned int flags;
 
flags = PIN_GLOBAL;
-   if (!HAS_LLC(engine->i915))
+   if (!HAS_LLC(engine->i915) && HAS_MAPPABLE_APERTURE(engine->i915))
/*
 * On g33, we cannot place HWS above 256MiB, so
 * restrict its pinning to the low mappable arena.
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 21/37] drm/i915: define HAS_MAPPABLE_APERTURE

2019-06-27 Thread Matthew Auld
From: Daniele Ceraolo Spurio 

The following patches in the series will use it to avoid certain
operations when aperture is not available in HW.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a124d1b17773..4d24f9dc1193 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2244,6 +2244,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
(INTEL_INFO(dev_priv)->display.overlay_needs_physical)
 
+#define HAS_MAPPABLE_APERTURE(dev_priv) (dev_priv->ggtt.mappable_end > 0)
+
 /* Early gen2 have a totally busted CS tlb and require pinned batches. */
 #define HAS_BROKEN_CS_TLB(dev_priv)(IS_I830(dev_priv) || 
IS_I845G(dev_priv))
 
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 18/37] drm/i915: enumerate and init each supported region

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Nothing to enumerate yet...

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/i915_drv.h   |  3 +
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 73 +--
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  6 ++
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7cbdffe3f129..42674a41e469 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2607,6 +2607,9 @@ int __must_check i915_gem_evict_for_node(struct 
i915_address_space *vm,
 unsigned int flags);
 int i915_gem_evict_vm(struct i915_address_space *vm);
 
+void i915_gem_cleanup_memory_regions(struct drm_i915_private *i915);
+int i915_gem_init_memory_regions(struct drm_i915_private *i915);
+
 /* i915_gem_stolen.c */
 int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv,
struct drm_mm_node *node, u64 size,
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ff1d5008a256..e4f811fdaedc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2902,6 +2902,71 @@ int i915_init_ggtt(struct drm_i915_private *i915)
return 0;
 }
 
+void i915_gem_cleanup_memory_regions(struct drm_i915_private *i915)
+{
+   int i;
+
+   i915_gem_cleanup_stolen(i915);
+
+   for (i = 0; i < ARRAY_SIZE(i915->regions); ++i) {
+   struct intel_memory_region *region = i915->regions[i];
+
+   if (region)
+   intel_memory_region_destroy(region);
+   }
+}
+
+int i915_gem_init_memory_regions(struct drm_i915_private *i915)
+{
+   int err, i;
+
+   /* All platforms currently have system memory */
+   GEM_BUG_ON(!HAS_REGION(i915, REGION_SMEM));
+
+   /*
+* Initialise stolen early so that we may reserve preallocated
+* objects for the BIOS to KMS transition.
+*/
+   /* XXX: stolen will become a region at some point */
+   err = i915_gem_init_stolen(i915);
+   if (err)
+   return err;
+
+   for (i = 0; i < ARRAY_SIZE(intel_region_map); i++) {
+   struct intel_memory_region *mem = NULL;
+   u32 type;
+
+   if (!HAS_REGION(i915, BIT(i)))
+   continue;
+
+   type = MEMORY_TYPE_FROM_REGION(intel_region_map[i]);
+   switch (type) {
+   default:
+   break;
+   }
+
+   if (IS_ERR(mem)) {
+   err = PTR_ERR(mem);
+   DRM_ERROR("Failed to setup region(%d) type=%d\n", err, 
type);
+   goto out_cleanup;
+   }
+
+   if (mem) {
+   mem->id = intel_region_map[i];
+   mem->type = type;
+   mem->instance = 
MEMORY_INSTANCE_FROM_REGION(intel_region_map[i]);
+   }
+
+   i915->regions[i] = mem;
+   }
+
+   return 0;
+
+out_cleanup:
+   i915_gem_cleanup_memory_regions(i915);
+   return err;
+}
+
 static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
 {
struct drm_i915_private *i915 = ggtt->vm.i915;
@@ -2950,7 +3015,7 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *i915)
__pagevec_release(pvec);
}
 
-   i915_gem_cleanup_stolen(i915);
+   i915_gem_cleanup_memory_regions(i915);
 }
 
 static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
@@ -3600,11 +3665,7 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
if (ret)
return ret;
 
-   /*
-* Initialise stolen early so that we may reserve preallocated
-* objects for the BIOS to KMS transition.
-*/
-   ret = i915_gem_init_stolen(dev_priv);
+   ret = i915_gem_init_memory_regions(dev_priv);
if (ret)
goto out_gtt_cleanup;
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f8b48304fcec..df07a0bd089d 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -82,6 +82,8 @@ static void mock_device_release(struct drm_device *dev)
 
i915_gemfs_fini(i915);
 
+   i915_gem_cleanup_memory_regions(i915);
+
drm_mode_config_cleanup(&i915->drm);
 
drm_dev_fini(&i915->drm);
@@ -225,6 +227,10 @@ struct drm_i915_private *mock_gem_device(void)
 
WARN_ON(i915_gemfs_init(i915));
 
+   err = i915_gem_init_memory_regions(i915);
+   if (err)
+   goto err_context;
+
return i915;
 
 err_context:
-- 
2.20.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.or

[Intel-gfx] [PATCH v2 04/37] drm/i915/region: support continuous allocations

2019-06-27 Thread Matthew Auld
Some objects may need to be allocated as a continuous block, thinking
ahead the various kernel io_mapping interfaces seem to expect it.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   4 +
 drivers/gpu/drm/i915/intel_memory_region.c|   7 +-
 .../drm/i915/selftests/intel_memory_region.c  | 152 +-
 drivers/gpu/drm/i915/selftests/mock_region.c  |   3 +
 4 files changed, 160 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 87000fc24ab3..1c4b99e507c3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -133,6 +133,10 @@ struct drm_i915_gem_object {
struct list_head batch_pool_link;
I915_SELFTEST_DECLARE(struct list_head st_link);
 
+   unsigned long flags;
+#define I915_BO_ALLOC_CONTIGUOUS (1<<0)
+#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
+
/*
 * Is the object to be mapped as read-only to the GPU
 * Only honoured if hardware has relevant pte bit
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
b/drivers/gpu/drm/i915/intel_memory_region.c
index 721b47e46492..9b6a32bfa20d 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -90,6 +90,7 @@ i915_memory_region_get_pages_buddy(struct drm_i915_gem_object 
*obj)
 {
struct intel_memory_region *mem = obj->memory_region;
resource_size_t size = obj->base.size;
+   unsigned int flags = obj->flags;
struct sg_table *st;
struct scatterlist *sg;
unsigned int sg_page_sizes;
@@ -130,7 +131,7 @@ i915_memory_region_get_pages_buddy(struct 
drm_i915_gem_object *obj)
if (!IS_ERR(block))
break;
 
-   if (!order--) {
+   if (flags & I915_BO_ALLOC_CONTIGUOUS || !order--) {
resource_size_t target;
int err;
 
@@ -219,6 +220,9 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
if (!mem)
return ERR_PTR(-ENODEV);
 
+   if (flags & ~I915_BO_ALLOC_FLAGS)
+   return ERR_PTR(-EINVAL);
+
size = round_up(size, mem->min_page_size);
 
GEM_BUG_ON(!size);
@@ -236,6 +240,7 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
 
INIT_LIST_HEAD(&obj->blocks);
obj->memory_region = mem;
+   obj->flags = flags;
 
mutex_lock(&mem->obj_lock);
list_add(&obj->region_link, &mem->objects);
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c 
b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index ece499869747..c9de8b5039e4 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -78,17 +78,17 @@ static int igt_mock_fill(void *arg)
 
 static void igt_mark_evictable(struct drm_i915_gem_object *obj)
 {
-   i915_gem_object_unpin_pages(obj);
+   if (i915_gem_object_has_pinned_pages(obj))
+   i915_gem_object_unpin_pages(obj);
obj->mm.madv = I915_MADV_DONTNEED;
list_move(&obj->region_link, &obj->memory_region->purgeable);
 }
 
-static int igt_mock_evict(void *arg)
+static int igt_frag_region(struct intel_memory_region *mem,
+  struct list_head *objects)
 {
-   struct intel_memory_region *mem = arg;
struct drm_i915_gem_object *obj;
unsigned long n_objects;
-   LIST_HEAD(objects);
resource_size_t target;
resource_size_t total;
int err = 0;
@@ -104,7 +104,7 @@ static int igt_mock_evict(void *arg)
goto err_close_objects;
}
 
-   list_add(&obj->st_link, &objects);
+   list_add(&obj->st_link, objects);
 
err = i915_gem_object_pin_pages(obj);
if (err)
@@ -118,6 +118,39 @@ static int igt_mock_evict(void *arg)
igt_mark_evictable(obj);
}
 
+   return 0;
+
+err_close_objects:
+   close_objects(objects);
+   return err;
+}
+
+static void igt_defrag_region(struct list_head *objects)
+{
+   struct drm_i915_gem_object *obj;
+
+   list_for_each_entry(obj, objects, st_link) {
+   if (obj->mm.madv == I915_MADV_WILLNEED)
+   igt_mark_evictable(obj);
+   }
+}
+
+static int igt_mock_evict(void *arg)
+{
+   struct intel_memory_region *mem = arg;
+   struct drm_i915_gem_object *obj;
+   LIST_HEAD(objects);
+   resource_size_t target;
+   resource_size_t total;
+   int err;
+
+   err = igt_frag_region(mem, &objects);
+   if (err)
+   return err;
+
+   total = resource_size(&mem->region);
+   target = mem->mm.min_size;
+

[Intel-gfx] [PATCH v2 03/37] drm/i915/region: support basic eviction

2019-06-27 Thread Matthew Auld
Support basic eviction for regions.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  7 ++
 drivers/gpu/drm/i915/i915_gem.c   | 16 
 drivers/gpu/drm/i915/intel_memory_region.c| 89 ++-
 drivers/gpu/drm/i915/intel_memory_region.h| 10 +++
 .../drm/i915/selftests/intel_memory_region.c  | 73 +++
 drivers/gpu/drm/i915/selftests/mock_region.c  |  1 +
 6 files changed, 192 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 8d760e852c4b..87000fc24ab3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -72,6 +72,13 @@ struct drm_i915_gem_object {
 * List of memory region blocks allocated for this object.
 */
struct list_head blocks;
+   /**
+* Element within memory_region->objects or memory_region->purgeable if
+* the object is marked as DONTNEED. Access is protected by
+* memory_region->obj_lock.
+*/
+   struct list_head region_link;
+   struct list_head eviction_link;
 
struct {
/**
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index db3744b0bc80..85677ae89849 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1122,6 +1122,22 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void 
*data,
!i915_gem_object_has_pages(obj))
i915_gem_object_truncate(obj);
 
+   if (obj->memory_region) {
+   mutex_lock(&obj->memory_region->obj_lock);
+
+   switch (obj->mm.madv) {
+   case I915_MADV_WILLNEED:
+   list_move(&obj->region_link, 
&obj->memory_region->objects);
+   break;
+   default:
+   list_move(&obj->region_link,
+ &obj->memory_region->purgeable);
+   break;
+   }
+
+   mutex_unlock(&obj->memory_region->obj_lock);
+   }
+
args->retained = obj->mm.madv != __I915_MADV_PURGED;
mutex_unlock(&obj->mm.lock);
 
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
b/drivers/gpu/drm/i915/intel_memory_region.c
index 4c89853a7769..721b47e46492 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -6,6 +6,56 @@
 #include "intel_memory_region.h"
 #include "i915_drv.h"
 
+int i915_memory_region_evict(struct intel_memory_region *mem,
+resource_size_t target)
+{
+   struct drm_i915_gem_object *obj, *on;
+   resource_size_t found;
+   LIST_HEAD(purgeable);
+   int err;
+
+   err = 0;
+   found = 0;
+
+   mutex_lock(&mem->obj_lock);
+
+   list_for_each_entry(obj, &mem->purgeable, region_link) {
+   if (!i915_gem_object_has_pages(obj))
+   continue;
+
+   if (READ_ONCE(obj->pin_global))
+   continue;
+
+   if (atomic_read(&obj->bind_count))
+   continue;
+
+   list_add(&obj->eviction_link, &purgeable);
+
+   found += obj->base.size;
+   if (found >= target)
+   goto found;
+   }
+
+   err = -ENOSPC;
+found:
+   list_for_each_entry_safe(obj, on, &purgeable, eviction_link) {
+   if (!err) {
+   __i915_gem_object_put_pages(obj, I915_MM_SHRINKER);
+
+   mutex_lock_nested(&obj->mm.lock, I915_MM_SHRINKER);
+   if (!i915_gem_object_has_pages(obj))
+   obj->mm.madv = __I915_MADV_PURGED;
+   mutex_unlock(&obj->mm.lock);
+   }
+
+   list_del(&obj->eviction_link);
+   }
+
+   mutex_unlock(&mem->obj_lock);
+
+   return err;
+}
+
 static void
 memory_region_free_pages(struct drm_i915_gem_object *obj,
 struct sg_table *pages)
@@ -70,7 +120,8 @@ i915_memory_region_get_pages_buddy(struct 
drm_i915_gem_object *obj)
unsigned int order;
u64 block_size;
u64 offset;
-
+   bool retry = true;
+retry:
order = fls(n_pages) - 1;
GEM_BUG_ON(order > mem->mm.max_order);
 
@@ -79,9 +130,24 @@ i915_memory_region_get_pages_buddy(struct 
drm_i915_gem_object *obj)
if (!IS_ERR(block))
break;
 
-   /* XXX: some kind of eviction pass, local to the device 
*/
-   if (!order--)
-   goto err_free_blocks;
+   if (!order--) {
+   resource_size_t target;
+   int e

[Intel-gfx] [PATCH v2 13/37] drm/i915/selftests: don't just test CACHE_NONE for huge-pages

2019-06-27 Thread Matthew Auld
We also want to test LLC.

Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 1cdf98b7535e..1862bf06a20f 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -152,6 +152,7 @@ huge_pages_object(struct drm_i915_private *i915,
  unsigned int page_mask)
 {
struct drm_i915_gem_object *obj;
+   unsigned int cache_level;
 
GEM_BUG_ON(!size);
GEM_BUG_ON(!IS_ALIGNED(size, BIT(__ffs(page_mask;
@@ -171,7 +172,9 @@ huge_pages_object(struct drm_i915_private *i915,
 
obj->write_domain = I915_GEM_DOMAIN_CPU;
obj->read_domains = I915_GEM_DOMAIN_CPU;
-   obj->cache_level = I915_CACHE_NONE;
+
+   cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+   i915_gem_object_set_cache_coherency(obj, cache_level);
 
obj->mm.page_mask = page_mask;
 
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 08/37] drm/i915: setup io-mapping for LMEM

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Signed-off-by: Abdiel Janulgue 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/intel_region_lmem.c | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
index c4b5a88627a3..15655cc5013f 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -43,9 +43,33 @@ lmem_create_object(struct intel_memory_region *mem,
return obj;
 }
 
+static void
+region_lmem_release(struct intel_memory_region *mem)
+{
+   io_mapping_fini(&mem->iomap);
+   i915_memory_region_release_buddy(mem);
+}
+
+static int
+region_lmem_init(struct intel_memory_region *mem)
+{
+   int ret;
+
+   if (!io_mapping_init_wc(&mem->iomap,
+   mem->io_start,
+   resource_size(&mem->region)))
+   return -EIO;
+
+   ret = i915_memory_region_init_buddy(mem);
+   if (ret)
+   io_mapping_fini(&mem->iomap);
+
+   return ret;
+}
+
 static const struct intel_memory_region_ops region_lmem_ops = {
-   .init = i915_memory_region_init_buddy,
-   .release = i915_memory_region_release_buddy,
+   .init = region_lmem_init,
+   .release = region_lmem_release,
.create_object = lmem_create_object,
 };
 
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 01/37] drm/i915: buddy allocator

2019-06-27 Thread Matthew Auld
Simple buddy allocator. We want to allocate properly aligned
power-of-two blocks to promote usage of huge-pages for the GTT, so 64K,
2M and possibly even 1G. While we do support allocating stuff at a
specific offset, it is more intended for preallocating portions of the
address space, say for an initial framebuffer, for other uses drm_mm is
probably a much better fit. Anyway, hopefully this can all be thrown
away if we eventually move to having the core MM manage device memory.

Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/i915_buddy.c | 413 +++
 drivers/gpu/drm/i915/i915_buddy.h | 115 
 drivers/gpu/drm/i915/selftests/i915_buddy.c   | 491 ++
 .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
 5 files changed, 1021 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_buddy.c
 create mode 100644 drivers/gpu/drm/i915/i915_buddy.h
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_buddy.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 3bd8f0349a8a..cb66cf1a5a10 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -117,6 +117,7 @@ gem-y += \
 i915-y += \
  $(gem-y) \
  i915_active.o \
+ i915_buddy.o \
  i915_cmd_parser.o \
  i915_gem_batch_pool.o \
  i915_gem_evict.o \
diff --git a/drivers/gpu/drm/i915/i915_buddy.c 
b/drivers/gpu/drm/i915/i915_buddy.c
new file mode 100644
index ..c0ac68d71d94
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_buddy.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include 
+#include 
+
+#include "i915_buddy.h"
+
+#include "i915_gem.h"
+#include "i915_utils.h"
+
+static void mark_allocated(struct i915_buddy_block *block)
+{
+   block->header &= ~I915_BUDDY_HEADER_STATE;
+   block->header |= I915_BUDDY_ALLOCATED;
+
+   list_del_init(&block->link);
+}
+
+static void mark_free(struct i915_buddy_mm *mm,
+ struct i915_buddy_block *block)
+{
+   block->header &= ~I915_BUDDY_HEADER_STATE;
+   block->header |= I915_BUDDY_FREE;
+
+   list_add(&block->link,
+&mm->free_list[i915_buddy_block_order(block)]);
+}
+
+static void mark_split(struct i915_buddy_block *block)
+{
+   block->header &= ~I915_BUDDY_HEADER_STATE;
+   block->header |= I915_BUDDY_SPLIT;
+
+   list_del_init(&block->link);
+}
+
+int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 min_size)
+{
+   unsigned int i;
+   u64 offset;
+
+   if (size < min_size)
+   return -EINVAL;
+
+   if (min_size < PAGE_SIZE)
+   return -EINVAL;
+
+   if (!is_power_of_2(min_size))
+   return -EINVAL;
+
+   size = round_down(size, min_size);
+
+   mm->size = size;
+   mm->min_size = min_size;
+   mm->max_order = ilog2(rounddown_pow_of_two(size)) - ilog2(min_size);
+
+   GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER);
+
+   mm->free_list = kmalloc_array(mm->max_order + 1,
+ sizeof(struct list_head),
+ GFP_KERNEL);
+   if (!mm->free_list)
+   return -ENOMEM;
+
+   for (i = 0; i <= mm->max_order; ++i)
+   INIT_LIST_HEAD(&mm->free_list[i]);
+
+   mm->blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN);
+   if (!mm->blocks)
+   goto out_free_list;
+
+   mm->n_roots = hweight64(size);
+
+   mm->roots = kmalloc_array(mm->n_roots,
+ sizeof(struct i915_buddy_block *),
+ GFP_KERNEL);
+   if (!mm->roots)
+   goto out_free_blocks;
+
+   offset = 0;
+   i = 0;
+
+   /*
+* Split into power-of-two blocks, in case we are given a size that is
+* not itself a power-of-two.
+*/
+   do {
+   struct i915_buddy_block *root;
+   unsigned int order;
+   u64 root_size;
+
+   root = kmem_cache_zalloc(mm->blocks, GFP_KERNEL);
+   if (!root)
+   goto out_free_roots;
+
+   root_size = rounddown_pow_of_two(size);
+   order = ilog2(root_size) - ilog2(min_size);
+
+   root->header = offset;
+   root->header |= order;
+
+   mark_free(mm, root);
+
+   GEM_BUG_ON(i > mm->max_order);
+   GEM_BUG_ON(i915_buddy_block_size(mm, root) < min_size);
+
+   mm->roots[i] = root;
+
+   offset += root_size;
+   size -= root_size;
+   i++;
+   } while (size);
+
+   return 0;
+
+out_free_roots:
+   while (i--)
+   kmem_cache_free(mm->blocks, mm->roots[i]);
+   kfree(mm->roots);
+out_free_blocks:
+   kmem_cache_destroy(mm->blocks);
+out_fre

[Intel-gfx] [PATCH v2 14/37] drm/i915/selftest: extend coverage to include LMEM huge-pages

2019-06-27 Thread Matthew Auld
Signed-off-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 122 +-
 1 file changed, 121 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 1862bf06a20f..c81ea9ce289b 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -981,7 +981,7 @@ static int gpu_write(struct i915_vma *vma,
   vma->size >> PAGE_SHIFT, val);
 }
 
-static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+static int __cpu_check_shmem(struct drm_i915_gem_object *obj, u32 dword, u32 
val)
 {
unsigned int needs_flush;
unsigned long n;
@@ -1013,6 +1013,53 @@ static int cpu_check(struct drm_i915_gem_object *obj, 
u32 dword, u32 val)
return err;
 }
 
+static int __cpu_check_lmem(struct drm_i915_gem_object *obj, u32 dword, u32 
val)
+{
+   unsigned long n;
+   int err;
+
+   i915_gem_object_lock(obj);
+   err = i915_gem_object_set_to_wc_domain(obj, false);
+   i915_gem_object_unlock(obj);
+   if (err)
+   return err;
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   return err;
+
+   for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) {
+   u32 __iomem *base;
+   u32 read_val;
+
+   base = i915_gem_object_lmem_io_map_page(obj, n);
+
+   read_val = ioread32(base + dword);
+   io_mapping_unmap_atomic(base);
+   if (read_val != val) {
+   pr_err("n=%lu base[%u]=%u, val=%u\n",
+  n, dword, read_val, val);
+   err = -EINVAL;
+   break;
+   }
+   }
+
+   i915_gem_object_unpin_pages(obj);
+   return err;
+}
+
+static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+   if (i915_gem_object_has_struct_page(obj))
+   return __cpu_check_shmem(obj, dword, val);
+   else if (HAS_LMEM(i915) && obj->memory_region)
+   return __cpu_check_lmem(obj, dword, val);
+
+   return -ENODEV;
+}
+
 static int __igt_write_huge(struct i915_gem_context *ctx,
struct intel_engine_cs *engine,
struct drm_i915_gem_object *obj,
@@ -1393,6 +1440,78 @@ static int igt_ppgtt_gemfs_huge(void *arg)
return err;
 }
 
+static int igt_ppgtt_lmem_huge(void *arg)
+{
+   struct i915_gem_context *ctx = arg;
+   struct drm_i915_private *i915 = ctx->i915;
+   struct drm_i915_gem_object *obj;
+   static const unsigned int sizes[] = {
+   SZ_64K,
+   SZ_512K,
+   SZ_1M,
+   SZ_2M,
+   };
+   int i;
+   int err;
+
+   if (!HAS_LMEM(i915)) {
+   pr_info("device lacks LMEM support, skipping\n");
+   return 0;
+   }
+
+   /*
+* Sanity check that the HW uses huge pages correctly through LMEM
+* -- ensure that our writes land in the right place.
+*/
+
+   for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
+   unsigned int size = sizes[i];
+
+   obj = i915_gem_object_create_lmem(i915, size, 
I915_BO_ALLOC_CONTIGUOUS);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   if (err == -E2BIG) {
+   pr_info("object too big for region!\n");
+   return 0;
+   }
+
+   return err;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   goto out_put;
+
+   if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_64K) {
+   pr_info("LMEM unable to allocate huge-page(s) with 
size=%u\n",
+   size);
+   goto out_unpin;
+   }
+
+   err = igt_write_huge(ctx, obj);
+   if (err) {
+   pr_err("LMEM write-huge failed with size=%u\n", size);
+   goto out_unpin;
+   }
+
+   i915_gem_object_unpin_pages(obj);
+   __i915_gem_object_put_pages(obj, I915_MM_NORMAL);
+   i915_gem_object_put(obj);
+   }
+
+   return 0;
+
+out_unpin:
+   i915_gem_object_unpin_pages(obj);
+out_put:
+   i915_gem_object_put(obj);
+
+   if (err == -ENOMEM)
+   err = 0;
+
+   return err;
+}
+
 static int igt_ppgtt_pin_update(void *arg)
 {
struct i915_gem_context *ctx = arg;
@@ -1717,6 +1836,7 @@ int i915_gem_huge_page_live_selftests(struct 
drm_i915_private *dev_priv)
SUBTEST(igt_ppgtt_exhaust_huge),
SUBTEST(igt_ppgtt_gemfs_huge),

[Intel-gfx] [PATCH v2 07/37] drm/i915: support creating LMEM objects

2019-06-27 Thread Matthew Auld
We currently define LMEM, or local memory, as just another memory
region, like system memory or stolen, which we can expose to userspace
and can be mapped to the CPU via some BAR.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/i915/Makefile |  1 +
 drivers/gpu/drm/i915/i915_drv.h   |  5 ++
 drivers/gpu/drm/i915/intel_region_lmem.c  | 66 +++
 drivers/gpu/drm/i915/intel_region_lmem.h  | 16 +
 .../drm/i915/selftests/i915_live_selftests.h  |  1 +
 .../drm/i915/selftests/intel_memory_region.c  | 43 
 6 files changed, 132 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c
 create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 28fac19f7b04..e782f7d10524 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -132,6 +132,7 @@ i915-y += \
  i915_scheduler.o \
  i915_trace_points.o \
  i915_vma.o \
+ intel_region_lmem.o \
  intel_wopcm.o
 
 # general-purpose microcontroller (GuC) support
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 838a796d9c55..7cbdffe3f129 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -93,6 +93,8 @@
 #include "gt/intel_timeline.h"
 #include "i915_vma.h"
 
+#include "intel_region_lmem.h"
+
 #include "intel_gvt.h"
 
 /* General customization:
@@ -1341,6 +1343,8 @@ struct drm_i915_private {
 */
resource_size_t stolen_usable_size; /* Total size minus reserved 
ranges */
 
+   struct intel_memory_region *regions[ARRAY_SIZE(intel_region_map)];
+
struct intel_uncore uncore;
 
struct i915_virtual_gpu vgpu;
@@ -2289,6 +2293,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_IPC(dev_priv)   (INTEL_INFO(dev_priv)->display.has_ipc)
 
 #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
+#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
 
 /*
  * For now, anything with a GuC requires uCode loading, and then supports
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
new file mode 100644
index ..c4b5a88627a3
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_memory_region.h"
+#include "intel_region_lmem.h"
+
+static const struct drm_i915_gem_object_ops region_lmem_obj_ops = {
+   .get_pages = i915_memory_region_get_pages_buddy,
+   .put_pages = i915_memory_region_put_pages_buddy,
+   .release = i915_gem_object_release_memory_region,
+};
+
+static struct drm_i915_gem_object *
+lmem_create_object(struct intel_memory_region *mem,
+  resource_size_t size,
+  unsigned int flags)
+{
+   struct drm_i915_private *i915 = mem->i915;
+   struct drm_i915_gem_object *obj;
+   unsigned int cache_level;
+
+   if (flags & I915_BO_ALLOC_CONTIGUOUS)
+   size = roundup_pow_of_two(size);
+
+   if (size > BIT(mem->mm.max_order) * mem->mm.min_size)
+   return ERR_PTR(-E2BIG);
+
+   obj = i915_gem_object_alloc();
+   if (!obj)
+   return ERR_PTR(-ENOMEM);
+
+   drm_gem_private_object_init(&i915->drm, &obj->base, size);
+   i915_gem_object_init(obj, ®ion_lmem_obj_ops);
+
+   obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
+
+   cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+   i915_gem_object_set_cache_coherency(obj, cache_level);
+
+   return obj;
+}
+
+static const struct intel_memory_region_ops region_lmem_ops = {
+   .init = i915_memory_region_init_buddy,
+   .release = i915_memory_region_release_buddy,
+   .create_object = lmem_create_object,
+};
+
+bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
+{
+   struct intel_memory_region *region = obj->memory_region;
+
+   return region && region->type == INTEL_LMEM;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_lmem(struct drm_i915_private *i915,
+   resource_size_t size,
+   unsigned int flags)
+{
+   return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_LMEM],
+size, flags);
+}
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h 
b/drivers/gpu/drm/i915/intel_region_lmem.h
new file mode 100644
index ..0f0a6249d5b9
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef __INTEL_REGION_LMEM_H
+#define __INTEL_REGION_LMEM_H
+
+bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);

[Intel-gfx] [PATCH v2 06/37] drm/i915: Add memory region information to device_info

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

Exposes available regions for the platform. Shared memory will
always be available.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
---
 drivers/gpu/drm/i915/i915_drv.h   |  2 ++
 drivers/gpu/drm/i915/i915_pci.c   | 29 ++-
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  2 ++
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 97d02b32a208..838a796d9c55 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2288,6 +2288,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_IPC(dev_priv)   (INTEL_INFO(dev_priv)->display.has_ipc)
 
+#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
+
 /*
  * For now, anything with a GuC requires uCode loading, and then supports
  * command submission once loaded. But these are logically independent
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 94b588e0a1dd..c513532b8da7 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -144,6 +144,9 @@
 #define GEN_DEFAULT_PAGE_SIZES \
.page_sizes = I915_GTT_PAGE_SIZE_4K
 
+#define GEN_DEFAULT_REGIONS \
+   .memory_regions = REGION_SMEM | REGION_STOLEN
+
 #define I830_FEATURES \
GEN(2), \
.is_mobile = 1, \
@@ -161,7 +164,8 @@
I9XX_PIPE_OFFSETS, \
I9XX_CURSOR_OFFSETS, \
I9XX_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 #define I845_FEATURES \
GEN(2), \
@@ -178,7 +182,8 @@
I845_PIPE_OFFSETS, \
I845_CURSOR_OFFSETS, \
I9XX_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 static const struct intel_device_info intel_i830_info = {
I830_FEATURES,
@@ -212,7 +217,8 @@ static const struct intel_device_info intel_i865g_info = {
I9XX_PIPE_OFFSETS, \
I9XX_CURSOR_OFFSETS, \
I9XX_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 static const struct intel_device_info intel_i915g_info = {
GEN3_FEATURES,
@@ -297,7 +303,8 @@ static const struct intel_device_info intel_pineview_m_info 
= {
I9XX_PIPE_OFFSETS, \
I9XX_CURSOR_OFFSETS, \
I965_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 static const struct intel_device_info intel_i965g_info = {
GEN4_FEATURES,
@@ -347,7 +354,8 @@ static const struct intel_device_info intel_gm45_info = {
I9XX_PIPE_OFFSETS, \
I9XX_CURSOR_OFFSETS, \
ILK_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 static const struct intel_device_info intel_ironlake_d_info = {
GEN5_FEATURES,
@@ -377,7 +385,8 @@ static const struct intel_device_info intel_ironlake_m_info 
= {
I9XX_PIPE_OFFSETS, \
I9XX_CURSOR_OFFSETS, \
ILK_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 #define SNB_D_PLATFORM \
GEN6_FEATURES, \
@@ -425,7 +434,8 @@ static const struct intel_device_info 
intel_sandybridge_m_gt2_info = {
IVB_PIPE_OFFSETS, \
IVB_CURSOR_OFFSETS, \
IVB_COLORS, \
-   GEN_DEFAULT_PAGE_SIZES
+   GEN_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 #define IVB_D_PLATFORM \
GEN7_FEATURES, \
@@ -486,6 +496,7 @@ static const struct intel_device_info intel_valleyview_info 
= {
I9XX_CURSOR_OFFSETS,
I965_COLORS,
GEN_DEFAULT_PAGE_SIZES,
+   GEN_DEFAULT_REGIONS,
 };
 
 #define G75_FEATURES  \
@@ -582,6 +593,7 @@ static const struct intel_device_info intel_cherryview_info 
= {
CHV_CURSOR_OFFSETS,
CHV_COLORS,
GEN_DEFAULT_PAGE_SIZES,
+   GEN_DEFAULT_REGIONS,
 };
 
 #define GEN9_DEFAULT_PAGE_SIZES \
@@ -657,7 +669,8 @@ static const struct intel_device_info 
intel_skylake_gt4_info = {
HSW_PIPE_OFFSETS, \
IVB_CURSOR_OFFSETS, \
IVB_COLORS, \
-   GEN9_DEFAULT_PAGE_SIZES
+   GEN9_DEFAULT_PAGE_SIZES, \
+   GEN_DEFAULT_REGIONS
 
 static const struct intel_device_info intel_broxton_info = {
GEN9_LP_FEATURES,
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index ddafc819bf30..63369b65110e 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -170,6 +170,7 @@ struct intel_device_info {
} display;
 
u16 ddb_size; /* in blocks */
+   u32 memory_regions;
 
/* Register offsets for the various display pipes and transcoders */
int pipe_offsets[I915_MAX_TRANSCODERS];
diff --git a/drivers/g

[Intel-gfx] [PATCH v2 00/37] Introduce memory region concept (including device local memory)

2019-06-27 Thread Matthew Auld
In preparation for upcoming devices with device local memory, introduce the
concept of different memory regions, and a simple buddy allocator to manage
them.

One of the concerns raised from v1 was around not using enough of TTM, which is
a fair criticism, so trying to get better alignment here is something we are
investigating, though currently that is still WIP so in the meantime v2 still
continues to push more of the low-level details forward, but not yet the TTM
interactions.

Abdiel Janulgue (11):
  drm/i915: Add memory region information to device_info
  drm/i915: setup io-mapping for LMEM
  drm/i915/lmem: support kernel mapping
  drm/i915: enumerate and init each supported region
  drm/i915: Allow i915 to manage the vma offset nodes instead of drm
core
  drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET
  drm/i915/lmem: add helper to get CPU accessible offset
  drm/i915: Add cpu and lmem fault handlers
  drm/i915: cpu-map based dumb buffers
  drm/i915: Introduce GEM_OBJECT_SETPARAM with I915_PARAM_MEMORY_REGION
  drm/i915/query: Expose memory regions through the query uAPI

Daniele Ceraolo Spurio (5):
  drm/i915: define HAS_MAPPABLE_APERTURE
  drm/i915: do not map aperture if it is not available.
  drm/i915: expose missing map_gtt support to users
  drm/i915: set num_fence_regs to 0 if there is no aperture
  drm/i915: error capture with no ggtt slot

Matthew Auld (20):
  drm/i915: buddy allocator
  drm/i915: introduce intel_memory_region
  drm/i915/region: support basic eviction
  drm/i915/region: support continuous allocations
  drm/i915/region: support volatile objects
  drm/i915: support creating LMEM objects
  drm/i915/blt: support copying objects
  drm/i915/selftests: move gpu-write-dw into utils
  drm/i915/selftests: add write-dword test for LMEM
  drm/i915/selftests: don't just test CACHE_NONE for huge-pages
  drm/i915/selftest: extend coverage to include LMEM huge-pages
  drm/i915/lmem: support CPU relocations
  drm/i915/lmem: support pread
  drm/i915/lmem: support pwrite
  drm/i915: treat shmem as a region
  drm/i915: treat stolen as a region
  drm/i915/selftests: check for missing aperture
  drm/i915: support basic object migration
  HAX drm/i915: add the fake lmem region
  HAX drm/i915/lmem: default userspace allocations to LMEM

Michal Wajdeczko (1):
  drm/i915: Don't try to place HWS in non-existing mappable region

 drivers/gpu/drm/i915/Makefile |   3 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  12 +
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |   2 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  69 +-
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|   4 +
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  | 370 +++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c| 278 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  27 +-
 .../gpu/drm/i915/gem/i915_gem_object_blt.c| 135 +++
 .../gpu/drm/i915/gem/i915_gem_object_blt.h|   8 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  44 +
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |  20 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c |  67 +-
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c|  66 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 329 +---
 .../i915/gem/selftests/i915_gem_coherency.c   |   5 +-
 .../drm/i915/gem/selftests/i915_gem_context.c | 134 +--
 .../drm/i915/gem/selftests/i915_gem_mman.c|  15 +-
 .../i915/gem/selftests/i915_gem_object_blt.c  | 105 +++
 .../drm/i915/gem/selftests/igt_gem_utils.c| 135 +++
 .../drm/i915/gem/selftests/igt_gem_utils.h|  16 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   2 +-
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |   3 +-
 drivers/gpu/drm/i915/gt/intel_reset.c |  19 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |  14 +-
 drivers/gpu/drm/i915/i915_buddy.c | 413 +
 drivers/gpu/drm/i915/i915_buddy.h | 115 +++
 drivers/gpu/drm/i915/i915_drv.c   |  38 +-
 drivers/gpu/drm/i915/i915_drv.h   |  25 +-
 drivers/gpu/drm/i915/i915_gem.c   |  75 +-
 drivers/gpu/drm/i915/i915_gem_fence_reg.c |   6 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 119 ++-
 drivers/gpu/drm/i915/i915_gpu_error.c |  63 +-
 drivers/gpu/drm/i915/i915_params.c|   3 +
 drivers/gpu/drm/i915/i915_params.h|   3 +-
 drivers/gpu/drm/i915/i915_pci.c   |  29 +-
 drivers/gpu/drm/i915/i915_query.c |  57 ++
 drivers/gpu/drm/i915/i915_vma.c   |  21 +-
 drivers/gpu/drm/i915/intel_device_info.h  |   1 +
 drivers/gpu/drm/i915/intel_memory_region.c| 321 +++
 drivers/gpu/drm/i915/intel_memory_region.h| 121 +++
 drivers/gpu/drm/i915/intel_region_lmem.c  | 404 +
 drivers/gpu/drm/i915/intel_region_lmem.h  |  30 +
 drivers/gpu/drm/i915/selftests/i915_buddy.c   | 491 +++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |   3 +
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 .../dr

[Intel-gfx] [PATCH v2 05/37] drm/i915/region: support volatile objects

2019-06-27 Thread Matthew Auld
Volatile objects are marked as DONTNEED while pinned, therefore once
unpinned the backing store can be discarded.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue 
Signed-off-by: CQ Tang 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 +-
 drivers/gpu/drm/i915/intel_memory_region.c| 13 -
 .../drm/i915/selftests/intel_memory_region.c  | 56 +++
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 1c4b99e507c3..80ff5ad9bc07 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -135,7 +135,8 @@ struct drm_i915_gem_object {
 
unsigned long flags;
 #define I915_BO_ALLOC_CONTIGUOUS (1<<0)
-#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS)
+#define I915_BO_ALLOC_VOLATILE   (1<<1)
+#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | I915_BO_ALLOC_VOLATILE)
 
/*
 * Is the object to be mapped as read-only to the GPU
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c 
b/drivers/gpu/drm/i915/intel_memory_region.c
index 9b6a32bfa20d..cd41c212bc35 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -82,6 +82,9 @@ i915_memory_region_put_pages_buddy(struct drm_i915_gem_object 
*obj,
memory_region_free_pages(obj, pages);
mutex_unlock(&obj->memory_region->mm_lock);
 
+   if (obj->flags & I915_BO_ALLOC_VOLATILE)
+   obj->mm.madv = I915_MADV_WILLNEED;
+
obj->mm.dirty = false;
 }
 
@@ -182,6 +185,9 @@ i915_memory_region_get_pages_buddy(struct 
drm_i915_gem_object *obj)
 
i915_sg_trim(st);
 
+   if (flags & I915_BO_ALLOC_VOLATILE)
+   obj->mm.madv = I915_MADV_DONTNEED;
+
__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
return 0;
@@ -243,7 +249,12 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
obj->flags = flags;
 
mutex_lock(&mem->obj_lock);
-   list_add(&obj->region_link, &mem->objects);
+
+   if (flags & I915_BO_ALLOC_VOLATILE)
+   list_add(&obj->region_link, &mem->purgeable);
+   else
+   list_add(&obj->region_link, &mem->objects);
+
mutex_unlock(&mem->obj_lock);
 
return obj;
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c 
b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index c9de8b5039e4..bdf044e4781d 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -289,12 +289,68 @@ static int igt_mock_continuous(void *arg)
return err;
 }
 
+static int igt_mock_volatile(void *arg)
+{
+   struct intel_memory_region *mem = arg;
+   struct drm_i915_gem_object *obj;
+   int err;
+
+   obj = i915_gem_object_create_region(mem, PAGE_SIZE, 0);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   goto err_put;
+
+   i915_gem_object_unpin_pages(obj);
+
+   err = i915_memory_region_evict(mem, PAGE_SIZE);
+   if (err != -ENOSPC) {
+   pr_err("shrink memory region\n");
+   goto err_put;
+   }
+
+   i915_gem_object_put(obj);
+
+   obj = i915_gem_object_create_region(mem, PAGE_SIZE, 
I915_BO_ALLOC_VOLATILE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   if (!(obj->flags & I915_BO_ALLOC_VOLATILE)) {
+   pr_err("missing flags\n");
+   goto err_put;
+   }
+
+   err = i915_gem_object_pin_pages(obj);
+   if (err)
+   goto err_put;
+
+   i915_gem_object_unpin_pages(obj);
+
+   err = i915_memory_region_evict(mem, PAGE_SIZE);
+   if (err) {
+   pr_err("failed to shrink memory\n");
+   goto err_put;
+   }
+
+   if (i915_gem_object_has_pages(obj)) {
+   pr_err("object pages not discarded\n");
+   err = -EINVAL;
+   }
+
+err_put:
+   i915_gem_object_put(obj);
+   return err;
+}
+
 int intel_memory_region_mock_selftests(void)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_mock_fill),
SUBTEST(igt_mock_evict),
SUBTEST(igt_mock_continuous),
+   SUBTEST(igt_mock_volatile),
};
struct intel_memory_region *mem;
struct drm_i915_private *i915;
-- 
2.20.1

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

[Intel-gfx] [PATCH v2 09/37] drm/i915/lmem: support kernel mapping

2019-06-27 Thread Matthew Auld
From: Abdiel Janulgue 

We can create LMEM objects, but we also need to support mapping them
into kernel space for internal use.

Signed-off-by: Abdiel Janulgue 
Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 18 -
 drivers/gpu/drm/i915/intel_region_lmem.c  | 24 ++
 drivers/gpu/drm/i915/intel_region_lmem.h  |  6 ++
 .../drm/i915/selftests/intel_memory_region.c  | 77 +++
 4 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index b36ad269f4ea..15eaaedffc46 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -176,7 +176,9 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
*obj)
void *ptr;
 
ptr = page_mask_bits(obj->mm.mapping);
-   if (is_vmalloc_addr(ptr))
+   if (i915_gem_object_is_lmem(obj))
+   io_mapping_unmap(ptr);
+   else if (is_vmalloc_addr(ptr))
vunmap(ptr);
else
kunmap(kmap_to_page(ptr));
@@ -235,7 +237,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object 
*obj,
 }
 
 /* The 'mapping' part of i915_gem_object_pin_map() below */
-static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
+static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
 enum i915_map_type type)
 {
unsigned long n_pages = obj->base.size >> PAGE_SHIFT;
@@ -248,6 +250,11 @@ static void *i915_gem_object_map(const struct 
drm_i915_gem_object *obj,
pgprot_t pgprot;
void *addr;
 
+   if (i915_gem_object_is_lmem(obj)) {
+   /* XXX: we are ignoring the type here -- this is simply wc */
+   return i915_gem_object_lmem_io_map(obj, 0, obj->base.size);
+   }
+
/* A single page can always be kmapped */
if (n_pages == 1 && type == I915_MAP_WB)
return kmap(sg_page(sgt->sgl));
@@ -293,7 +300,8 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
*obj,
void *ptr;
int err;
 
-   if (unlikely(!i915_gem_object_has_struct_page(obj)))
+   if (unlikely(!i915_gem_object_has_struct_page(obj) &&
+!i915_gem_object_is_lmem(obj)))
return ERR_PTR(-ENXIO);
 
err = mutex_lock_interruptible(&obj->mm.lock);
@@ -325,7 +333,9 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
*obj,
goto err_unpin;
}
 
-   if (is_vmalloc_addr(ptr))
+   if (i915_gem_object_is_lmem(obj))
+   io_mapping_unmap(ptr);
+   else if (is_vmalloc_addr(ptr))
vunmap(ptr);
else
kunmap(kmap_to_page(ptr));
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c 
b/drivers/gpu/drm/i915/intel_region_lmem.c
index 15655cc5013f..701bcac3479e 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.c
+++ b/drivers/gpu/drm/i915/intel_region_lmem.c
@@ -73,6 +73,30 @@ static const struct intel_memory_region_ops region_lmem_ops 
= {
.create_object = lmem_create_object,
 };
 
+/* XXX: Time to vfunc your life up? */
+void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
+  unsigned long n)
+{
+   resource_size_t offset;
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+
+   return io_mapping_map_atomic_wc(&obj->memory_region->iomap, offset);
+}
+
+void __iomem *i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
+ unsigned long n,
+ unsigned long size)
+{
+   resource_size_t offset;
+
+   GEM_BUG_ON(!(obj->flags & I915_BO_ALLOC_CONTIGUOUS));
+
+   offset = i915_gem_object_get_dma_address(obj, n);
+
+   return io_mapping_map_wc(&obj->memory_region->iomap, offset, size);
+}
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
 {
struct intel_memory_region *region = obj->memory_region;
diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h 
b/drivers/gpu/drm/i915/intel_region_lmem.h
index 0f0a6249d5b9..20084f7b4bff 100644
--- a/drivers/gpu/drm/i915/intel_region_lmem.h
+++ b/drivers/gpu/drm/i915/intel_region_lmem.h
@@ -6,6 +6,12 @@
 #ifndef __INTEL_REGION_LMEM_H
 #define __INTEL_REGION_LMEM_H
 
+
+void __iomem *i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
+ unsigned long n, unsigned long size);
+void __iomem *i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
+  unsigned long n);
+
 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj);
 
 struct drm_i915_gem_object *
diff --git a/drivers/gpu

[Intel-gfx] [PATCH v2 02/37] drm/i915: introduce intel_memory_region

2019-06-27 Thread Matthew Auld
Support memory regions, as defined by a given (start, end), and allow
creating GEM objects which are backed by said region. The immediate goal
here is to have something to represent our device memory, but later on
we also want to represent every memory domain with a region, so stolen,
shmem, and of course device. At some point we are probably going to want
use a common struct here, such that we are better aligned with say TTM.

Signed-off-by: Matthew Auld 
Signed-off-by: Abdiel Janulgue 
Cc: Joonas Lahtinen 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   9 +
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |  82 +++
 drivers/gpu/drm/i915/i915_drv.h   |   1 +
 drivers/gpu/drm/i915/i915_gem.c   |   1 +
 drivers/gpu/drm/i915/intel_memory_region.c| 215 ++
 drivers/gpu/drm/i915/intel_memory_region.h| 107 +
 .../drm/i915/selftests/i915_mock_selftests.h  |   1 +
 .../drm/i915/selftests/intel_memory_region.c  | 111 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |   1 +
 drivers/gpu/drm/i915/selftests/mock_region.c  |  55 +
 drivers/gpu/drm/i915/selftests/mock_region.h  |  16 ++
 12 files changed, 600 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/intel_memory_region.h
 create mode 100644 drivers/gpu/drm/i915/selftests/intel_memory_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.c
 create mode 100644 drivers/gpu/drm/i915/selftests/mock_region.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cb66cf1a5a10..28fac19f7b04 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -59,6 +59,7 @@ i915-y += i915_drv.o \
 i915-y += \
i915_memcpy.o \
i915_mm.o \
+   intel_memory_region.o \
i915_sw_fence.o \
i915_syncmap.o \
i915_user_extensions.o
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 34b51fad02de..8d760e852c4b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -64,6 +64,15 @@ struct drm_i915_gem_object {
 
const struct drm_i915_gem_object_ops *ops;
 
+   /**
+* Memory region for this object.
+*/
+   struct intel_memory_region *memory_region;
+   /**
+* List of memory region blocks allocated for this object.
+*/
+   struct list_head blocks;
+
struct {
/**
 * @vma.lock: protect the list/tree of vmas
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 2154cdee4ab3..fd547b98ec69 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -17,6 +17,7 @@
 
 #include "selftests/mock_drm.h"
 #include "selftests/mock_gem_device.h"
+#include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
 static const unsigned int page_sizes[] = {
@@ -447,6 +448,86 @@ static int igt_mock_exhaust_device_supported_pages(void 
*arg)
return err;
 }
 
+
+static int igt_mock_memory_region_huge_pages(void *arg)
+{
+   struct i915_ppgtt *ppgtt = arg;
+   struct drm_i915_private *i915 = ppgtt->vm.i915;
+   unsigned long supported = INTEL_INFO(i915)->page_sizes;
+   struct intel_memory_region *mem;
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   int bit;
+   int err = 0;
+
+   mem = mock_region_create(i915, 0, SZ_2G,
+I915_GTT_PAGE_SIZE_4K, 0);
+   if (IS_ERR(mem)) {
+   pr_err("failed to create memory region\n");
+   return PTR_ERR(mem);
+   }
+
+   for_each_set_bit(bit, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) {
+   unsigned int page_size = BIT(bit);
+   resource_size_t phys;
+
+   obj = i915_gem_object_create_region(mem, page_size, 0);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto out_destroy_device;
+   }
+
+   pr_info("memory region start(%pa)\n",
+   &obj->memory_region->region.start);
+   pr_info("creating object, size=%x\n", page_size);
+
+   vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
+   if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
+   goto out_put;
+   }
+
+   err = i915_vma_pin(vma, 0, 0, PIN_USER);
+   if (err)
+   goto out_close;
+
+   phys = i915_gem_object_get_dma_address(obj, 0);
+   if (!IS_ALIGNED(phys, page_size)) {
+   pr_err("memory region misaligned(%pa)\n", &phys);
+ 

[Intel-gfx] [PATCH v2 10/37] drm/i915/blt: support copying objects

2019-06-27 Thread Matthew Auld
We can already clear an object with the blt, so try to do the same to
support copying from one object backing store to another. Really this is
just object -> object, which is not that useful yet, what we really want
is two backing stores, but that will require some vma rework first,
otherwise we are stuck with "tmp" objects.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Abdiel Janulgue i915);
+   u32 *cs;
+
+   GEM_BUG_ON(src->size != dst->size);
+
+   cs = intel_ring_begin(rq, 10);
+   if (IS_ERR(cs))
+   return PTR_ERR(cs);
+
+   if (gen >= 9) {
+   *cs++ = GEN9_XY_FAST_COPY_BLT_CMD | (10-2);
+   *cs++ = BLT_DEPTH_32 | PAGE_SIZE;
+   *cs++ = 0;
+   *cs++ = src->size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+   *cs++ = lower_32_bits(dst->node.start);
+   *cs++ = upper_32_bits(dst->node.start);
+   *cs++ = 0;
+   *cs++ = PAGE_SIZE;
+   *cs++ = lower_32_bits(src->node.start);
+   *cs++ = upper_32_bits(src->node.start);
+   } else if (gen >= 8) {
+   *cs++ = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (10-2);
+   *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
+   *cs++ = 0;
+   *cs++ = src->size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+   *cs++ = lower_32_bits(dst->node.start);
+   *cs++ = upper_32_bits(dst->node.start);
+   *cs++ = 0;
+   *cs++ = PAGE_SIZE;
+   *cs++ = lower_32_bits(src->node.start);
+   *cs++ = upper_32_bits(src->node.start);
+   } else {
+   *cs++ = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (8-2);
+   *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
+   *cs++ = 0;
+   *cs++ = src->size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+   *cs++ = dst->node.start;
+   *cs++ = 0;
+   *cs++ = PAGE_SIZE;
+   *cs++ = src->node.start;
+   *cs++ = MI_NOOP;
+   *cs++ = MI_NOOP;
+   }
+
+   intel_ring_advance(rq, cs);
+
+   return 0;
+}
+
+int i915_gem_object_copy_blt(struct drm_i915_gem_object *src,
+struct drm_i915_gem_object *dst,
+struct intel_context *ce)
+{
+   struct drm_i915_private *i915 = to_i915(src->base.dev);
+   struct i915_gem_context *ctx = ce->gem_context;
+   struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
+   struct drm_gem_object *objs[] = { &src->base, &dst->base };
+   struct ww_acquire_ctx acquire;
+   struct i915_vma *vma_src, *vma_dst;
+   struct i915_request *rq;
+   int err;
+
+   vma_src = i915_vma_instance(src, vm, NULL);
+   if (IS_ERR(vma_src))
+   return PTR_ERR(vma_src);
+
+   err = i915_vma_pin(vma_src, 0, 0, PIN_USER);
+   if (unlikely(err))
+   return err;
+
+   vma_dst = i915_vma_instance(dst, vm, NULL);
+   if (IS_ERR(vma_dst))
+   goto out_unpin_src;
+
+   err = i915_vma_pin(vma_dst, 0, 0, PIN_USER);
+   if (unlikely(err))
+   goto out_unpin_src;
+
+   rq = i915_request_create(ce);
+   if (IS_ERR(rq)) {
+   err = PTR_ERR(rq);
+   goto out_unpin_dst;
+   }
+
+   err = drm_gem_lock_reservations(objs, ARRAY_SIZE(objs), &acquire);
+   if (unlikely(err))
+   goto out_request;
+
+   if (src->cache_dirty & ~src->cache_coherent)
+   i915_gem_clflush_object(src, 0);
+
+   if (dst->cache_dirty & ~dst->cache_coherent)
+   i915_gem_clflush_object(dst, 0);
+
+   err = i915_request_await_object(rq, src, false);
+   if (unlikely(err))
+   goto out_unlock;
+
+   err = i915_vma_move_to_active(vma_src, rq, 0);
+   if (unlikely(err))
+   goto out_unlock;
+
+   err = i915_request_await_object(rq, dst, true);
+   if (unlikely(err))
+   goto out_unlock;
+
+   err = i915_vma_move_to_active(vma_dst, rq, EXEC_OBJECT_WRITE);
+   if (unlikely(err))
+   goto out_unlock;
+
+   if (ce->engine->emit_init_breadcrumb) {
+   err = ce->engine->emit_init_breadcrumb(rq);
+   if (unlikely(err))
+   goto out_unlock;
+   }
+
+   err = intel_emit_vma_copy_blt(rq, vma_src, vma_dst);
+out_unlock:
+   drm_gem_unlock_reservations(objs, ARRAY_SIZE(objs), &acquire);
+out_request:
+   if (unlikely(err))
+   i915_request_skip(rq, err);
+
+   i915_request_add(rq);
+out_unpin_dst:
+   i915_vma_unpin(vma_dst);
+out_unpin_src:
+   i915_vma_unpin(vma_src);
+   return err;
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/i915_gem_object_blt.c"
 #endif
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.h
index 7ec

[Intel-gfx] [PATCH v2 11/37] drm/i915/selftests: move gpu-write-dw into utils

2019-06-27 Thread Matthew Auld
Using the gpu to write to some dword over a number of pages is rather
useful, and we already have two copies of such a thing, and we don't
want a third so move it to utils. There is probably some other stuff
also...

Signed-off-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 120 ++--
 .../drm/i915/gem/selftests/i915_gem_context.c | 134 ++---
 .../drm/i915/gem/selftests/igt_gem_utils.c| 135 ++
 .../drm/i915/gem/selftests/igt_gem_utils.h|  16 +++
 4 files changed, 169 insertions(+), 236 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index fd547b98ec69..1cdf98b7535e 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -960,126 +960,22 @@ static int igt_mock_ppgtt_64K(void *arg)
return err;
 }
 
-static struct i915_vma *
-gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val)
-{
-   struct drm_i915_private *i915 = vma->vm->i915;
-   const int gen = INTEL_GEN(i915);
-   unsigned int count = vma->size >> PAGE_SHIFT;
-   struct drm_i915_gem_object *obj;
-   struct i915_vma *batch;
-   unsigned int size;
-   u32 *cmd;
-   int n;
-   int err;
-
-   size = (1 + 4 * count) * sizeof(u32);
-   size = round_up(size, PAGE_SIZE);
-   obj = i915_gem_object_create_internal(i915, size);
-   if (IS_ERR(obj))
-   return ERR_CAST(obj);
-
-   cmd = i915_gem_object_pin_map(obj, I915_MAP_WC);
-   if (IS_ERR(cmd)) {
-   err = PTR_ERR(cmd);
-   goto err;
-   }
-
-   offset += vma->node.start;
-
-   for (n = 0; n < count; n++) {
-   if (gen >= 8) {
-   *cmd++ = MI_STORE_DWORD_IMM_GEN4;
-   *cmd++ = lower_32_bits(offset);
-   *cmd++ = upper_32_bits(offset);
-   *cmd++ = val;
-   } else if (gen >= 4) {
-   *cmd++ = MI_STORE_DWORD_IMM_GEN4 |
-   (gen < 6 ? MI_USE_GGTT : 0);
-   *cmd++ = 0;
-   *cmd++ = offset;
-   *cmd++ = val;
-   } else {
-   *cmd++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
-   *cmd++ = offset;
-   *cmd++ = val;
-   }
-
-   offset += PAGE_SIZE;
-   }
-
-   *cmd = MI_BATCH_BUFFER_END;
-   intel_gt_chipset_flush(vma->vm->gt);
-
-   i915_gem_object_unpin_map(obj);
-
-   batch = i915_vma_instance(obj, vma->vm, NULL);
-   if (IS_ERR(batch)) {
-   err = PTR_ERR(batch);
-   goto err;
-   }
-
-   err = i915_vma_pin(batch, 0, 0, PIN_USER);
-   if (err)
-   goto err;
-
-   return batch;
-
-err:
-   i915_gem_object_put(obj);
-
-   return ERR_PTR(err);
-}
-
 static int gpu_write(struct i915_vma *vma,
 struct i915_gem_context *ctx,
 struct intel_engine_cs *engine,
-u32 dword,
-u32 value)
+u32 dw,
+u32 val)
 {
-   struct i915_request *rq;
-   struct i915_vma *batch;
int err;
 
-   GEM_BUG_ON(!intel_engine_can_store_dword(engine));
-
-   batch = gpu_write_dw(vma, dword * sizeof(u32), value);
-   if (IS_ERR(batch))
-   return PTR_ERR(batch);
-
-   rq = igt_request_alloc(ctx, engine);
-   if (IS_ERR(rq)) {
-   err = PTR_ERR(rq);
-   goto err_batch;
-   }
-
-   i915_vma_lock(batch);
-   err = i915_vma_move_to_active(batch, rq, 0);
-   i915_vma_unlock(batch);
-   if (err)
-   goto err_request;
-
-   i915_vma_lock(vma);
-   err = i915_gem_object_set_to_gtt_domain(vma->obj, false);
-   if (err == 0)
-   err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
-   i915_vma_unlock(vma);
+   i915_gem_object_lock(vma->obj);
+   err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
+   i915_gem_object_unlock(vma->obj);
if (err)
-   goto err_request;
-
-   err = engine->emit_bb_start(rq,
-   batch->node.start, batch->node.size,
-   0);
-err_request:
-   if (err)
-   i915_request_skip(rq, err);
-   i915_request_add(rq);
-err_batch:
-   i915_vma_unpin(batch);
-   i915_vma_close(batch);
-   i915_vma_put(batch);
+   return err;
 
-   return err;
+   return igt_gpu_fill_dw(vma, ctx, engine, dw * sizeof(u32),
+  vma->size >> PAGE_SHIFT, val);
 }
 
 static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/

[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/tgl: Gen12 csb support

2019-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915/tgl: Gen12 csb support
URL   : https://patchwork.freedesktop.org/series/62890/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
72f2fb88c700 drm/i915/tgl: Gen12 csb support
-:41: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'csb_dw' may be better as 
'(csb_dw)' to avoid precedence issues
#41: FILE: drivers/gpu/drm/i915/gt/intel_lrc.c:168:
+#define GEN12_CTX_SWITCH_DETAIL(csb_dw)(csb_dw & 0xF) /* upper csb 
dword */

-:112: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'ctx_away 
== ctx_to'
#112: FILE: drivers/gpu/drm/i915/gt/intel_lrc.c:1347:
+   if ((ctx_away == ctx_to) && ctx_to_valid)

-:115: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'ctx_away 
!= ctx_to'
#115: FILE: drivers/gpu/drm/i915/gt/intel_lrc.c:1350:
+   if ((ctx_away != ctx_to) && ctx_away_valid && ctx_to_valid && 
!new_queue)

-:118: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 
'switch_detail == GEN12_CTX_PREEMPTED'
#118: FILE: drivers/gpu/drm/i915/gt/intel_lrc.c:1353:
+   if ((switch_detail == GEN12_CTX_PREEMPTED) || (new_queue && 
ctx_away_valid))

-:121: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 
'switch_detail == GEN12_CTX_COMPLETE'
#121: FILE: drivers/gpu/drm/i915/gt/intel_lrc.c:1356:
+   if ((switch_detail == GEN12_CTX_COMPLETE) && ctx_away_valid)

total: 0 errors, 0 warnings, 5 checks, 117 lines checked

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

Re: [Intel-gfx] [CI v3 13/23] drm/i915: Fix the TypeC port mode sanitization during loading/resume

2019-06-27 Thread Souza, Jose
On Wed, 2019-06-26 at 23:50 +0300, Imre Deak wrote:
> For using the correct AUX power domains we have to sanitize the TypeC
> port mode early, so move that before encoder sanitization. To do this
> properly read out the actual port mode instead of just relying on the
> VBT legacy port flag (which can be incorrect).
> 
> We also verify that the PHY is connected as expected if the port is
> active. In case the port is inactive we connect the PHY in case of a
> legacy port - as we did so far. The PHY will be connected during
> detection for DP-alt mode - as it was done so far. For TBT-alt mode
> nothing needs to be done to connect the PHY.
> 
> v2:
> - Use DRM_DEBUG_KMS instead of DRM_DEBUG_DRIVER. (José)
> v3:
> - Detect TCCOLD any time PORT_TX_DFLEXDPCSSS is read. (Ville)
> 
> Cc: José Roberto de Souza 
> Cc: Rodrigo Vivi 
> Cc: Paulo Zanoni 
> Cc: Ville Syrjälä 
> Signed-off-by: Imre Deak 
> Reviewed-by: José Roberto de Souza  (v2)

Reviewed-by: José Roberto de Souza  

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 16 +---
>  drivers/gpu/drm/i915/display/intel_display.c | 10 +++
>  drivers/gpu/drm/i915/display/intel_dp_mst.h  |  8 +-
>  drivers/gpu/drm/i915/display/intel_tc.c  | 84
> 
>  drivers/gpu/drm/i915/display/intel_tc.h  |  2 +
>  5 files changed, 104 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 2be7cdc319ba..0c5bfbd66b19 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3931,17 +3931,6 @@ static void intel_ddi_encoder_suspend(struct
> intel_encoder *encoder)
>   icl_tc_phy_disconnect(dig_port);
>  }
>  
> -static void intel_ddi_encoder_reset(struct drm_encoder *drm_encoder)
> -{
> - struct intel_digital_port *dig_port =
> enc_to_dig_port(drm_encoder);
> - struct drm_i915_private *i915 = to_i915(drm_encoder->dev);
> -
> - if (intel_port_is_tc(i915, dig_port->base.port))
> - intel_digital_port_connected(&dig_port->base);
> -
> - intel_dp_encoder_reset(drm_encoder);
> -}
> -
>  static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
>  {
>   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
> @@ -3957,7 +3946,7 @@ static void intel_ddi_encoder_destroy(struct
> drm_encoder *encoder)
>  }
>  
>  static const struct drm_encoder_funcs intel_ddi_funcs = {
> - .reset = intel_ddi_encoder_reset,
> + .reset = intel_dp_encoder_reset,
>   .destroy = intel_ddi_encoder_destroy,
>  };
>  
> @@ -4328,9 +4317,6 @@ void intel_ddi_init(struct drm_i915_private
> *dev_priv, enum port port)
>  
>   intel_infoframe_init(intel_dig_port);
>  
> - if (intel_port_is_tc(dev_priv, port))
> - intel_digital_port_connected(intel_encoder);
> -
>   return;
>  
>  err:
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index e47df8a8401e..dee9b89eb3ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -78,6 +78,7 @@
>  #include "intel_quirks.h"
>  #include "intel_sideband.h"
>  #include "intel_sprite.h"
> +#include "intel_tc.h"
>  
>  /* Primary plane formats for gen <= 3 */
>  static const u32 i8xx_primary_formats[] = {
> @@ -16844,6 +16845,15 @@ intel_modeset_setup_hw_state(struct
> drm_device *dev,
>   intel_modeset_readout_hw_state(dev);
>  
>   /* HW state is read out, now we need to sanitize this mess. */
> +
> + /* Sanitize the TypeC port mode upfront, encoders depend on
> this */
> + for_each_intel_encoder(dev, encoder) {
> + /* We need to sanitize only the MST primary port. */
> + if (encoder->type != INTEL_OUTPUT_DP_MST &&
> + intel_port_is_tc(dev_priv, encoder->port))
> + intel_tc_port_sanitize(enc_to_dig_port(&encoder
> ->base));
> + }
> +
>   get_encoder_power_domains(dev_priv);
>  
>   if (HAS_PCH_IBX(dev_priv))
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> index 1470c6e0514b..6754c211205a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> @@ -6,9 +6,15 @@
>  #ifndef __INTEL_DP_MST_H__
>  #define __INTEL_DP_MST_H__
>  
> -struct intel_digital_port;
> +#include "intel_drv.h"
>  
>  int intel_dp_mst_encoder_init(struct intel_digital_port
> *intel_dig_port, int conn_id);
>  void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> *intel_dig_port);
> +static inline int
> +intel_dp_mst_encoder_active_links(struct intel_digital_port
> *intel_dig_port)
> +{
> + return intel_dig_port->dp.active_mst_links;
> +}
> +
>  
>  #endif /* __INTEL_DP_MST_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.c
> b/drivers/gpu/drm/i915/display/intel_tc.c
> index f63ddf39b369..78340115b994 100644

[Intel-gfx] [RFC] drm/i915/tgl: Gen12 csb support

2019-06-27 Thread Daniele Ceraolo Spurio
The CSB format has been reworked for Gen12 to include information on
both the context we're switching away from and the context we're
switching to. After the change, some of the events don't have their
own bit anymore and need to be inferred from other values in the csb.
One of the context IDs (0x7FF) has also been reserved to indicate
the invalid ctx, i.e. engine idle.
To keep the logic simple, we can convert the new gen12 format to the
gen11 format and re-use the legacy csb handling logic. This result
in a sliglthly slower handling for gen12 but allows us to get running
with a relatively small change and avoids code duplication.

RFC: base TGL support [1] is not yet in the tree, but I wanted to get
some early comments on this because I'm not totally convinced that the
conversion is the best way of doing this. This way if another approach
is proposed I can do the work while the base support gets reviewed. If
we stick with the conversion we can probably optimize a bit.
Toughts?

[1]: https://patchwork.freedesktop.org/series/62726/

Bspec: 4, 46144
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Mika Kuoppala 
---
 drivers/gpu/drm/i915/gt/intel_lrc.c | 93 -
 1 file changed, 91 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 471e134de186..61cf016b8e15 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -164,6 +164,15 @@
 
 #define CTX_DESC_FORCE_RESTORE BIT_ULL(2)
 
+#define GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE (0x1) /* lower csb dword */
+#define GEN12_CTX_SWITCH_DETAIL(csb_dw)(csb_dw & 0xF) /* upper csb 
dword */
+#define  GEN12_CTX_COMPLETE(0x0)
+#define  GEN12_CTX_PREEMPTED   (0x5)
+#define GEN12_CSB_CTX(csb_dw)  (((csb_dw) & GENMASK_ULL(31, 15)) >> 15)
+#define GEN12_CTX_SW_ID(ctx)   ((ctx) & GENMASK(10, 0))
+#define GEN12_CTX_SW_COUNTER(ctx)  (((ctx) & GENMASK(16, 11)) >> 11)
+#define GEN12_CTX_INVALID_ID   0x7FF
+
 /* Typical size of the average request (2 pipecontrols and a MI_BB) */
 #define EXECLISTS_REQUEST_SIZE 64 /* bytes */
 #define WA_TAIL_DWORDS 2
@@ -1279,6 +1288,80 @@ reset_in_progress(const struct intel_engine_execlists 
*execlists)
return unlikely(!__tasklet_is_enabled(&execlists->tasklet));
 }
 
+/*
+ * Starting with Gen12, the csb has a new format:
+ *
+ * lower_dw:
+ *   bit  0: switched to new queue
+ *   bit  1: reserved
+ *   bits 3-5:   engine class
+ *   bits 6-11:  engine instance
+ *   bits 12-14: reserved
+ *   bits 15-25: sw context id of the lrc we're switching to
+ *   bits 26-31: sw counter of the lrc we're switching to
+ *
+ * upper_dw:
+ *   bits 0-3:   context switch detail
+ * 0: ctx complete
+ * 1: wait on sync flip
+ * 2: wait on vblank
+ * 3: wait on scanline
+ * 4: wait on semaphore
+ * 5: ctx preempted (not on SEMAPHORE_WAIT or WAIT_FOR_EVENT)
+ *   bit  4: reserved
+ *   bits 5-11:  wait detail (for switch detail 1 to 4)
+ *   bits 12-14: reserved
+ *   bits 15-25: sw context id of the lrc we're switching away from
+ *   bits 26-31: sw counter of the lrc we're switching away from
+ *
+ * To keep the logic simple, we convert the new gen12 format to the gen11
+ * format and re-use the legacy csb handling logic. The upper 32 bits of the
+ * legacy status should be set to the upper 32 bits of the descriptor of the
+ * ctx we're switching away from, but since we don't use that value in our
+ * logic at the moment we skip that setting.
+ */
+static u32
+gen12_convert_csb(struct intel_engine_cs *engine, u32 lower_dw, u32 upper_dw)
+{
+   u32 legacy_status = 0;
+   u32 ctx_to = GEN12_CSB_CTX(lower_dw);
+   u32 ctx_away = GEN12_CSB_CTX(upper_dw);
+   u8 switch_detail = GEN12_CTX_SWITCH_DETAIL(upper_dw);
+   bool new_queue = lower_dw & GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE;
+   bool ctx_to_valid = GEN12_CTX_SW_ID(ctx_to) != GEN12_CTX_INVALID_ID;
+   bool ctx_away_valid = GEN12_CTX_SW_ID(ctx_away) != GEN12_CTX_INVALID_ID;
+
+   if (!ctx_away_valid && ctx_to_valid)
+   legacy_status |= GEN8_CTX_STATUS_IDLE_ACTIVE;
+
+   /*
+* ctx_away_valid && !ctx_to_valid can indicate either a ctx completion
+* or a preempt-to-idle of a running ctx. The 2 cases can be
+* differentiated by the value of new_queue, but since the
+* GEN8_CTX_STATUS_ACTIVE_IDLE is set in both situations we don't
+* differentiate between them here.
+*/
+   if (ctx_away_valid && !ctx_to_valid)
+   legacy_status |= GEN8_CTX_STATUS_ACTIVE_IDLE;
+
+   if ((ctx_away == ctx_to) && ctx_to_valid)
+   legacy_status |= GEN8_CTX_STATUS_LITE_RESTORE;
+
+   if ((ctx_away != ctx_to) && ctx_away_valid && ctx_to_valid && 
!new_queue)
+

Re: [Intel-gfx] [PATCH i-g-t v2] tests/i915/gem_ctx_switch: Update with engine discovery

2019-06-27 Thread Chris Wilson
Quoting Andi Shyti (2019-06-27 21:15:30)
> > +bool gem_context_has_engine_map(int fd, uint32_t ctx)
> > +{
> > + struct drm_i915_gem_context_param param = {
> > + .param = I915_CONTEXT_PARAM_ENGINES,
> > + .ctx_id = ctx
> > + };
> > + int ret;
> > +
> > + ret = __gem_context_get_param(fd, ¶m);
> > + igt_assert_eq(ret, 0);
> > +
> > + return param.size;
> 
> a small nitpick: bool to me means '0' or '1'.
> 
> So, if you do 'return param.size', I would call the function
> gem_context_get_param_size, otherwise I would return
> '!!param.size' and keep it bool.

An integer in boolean context is 0 or 1, the !! is implicit. We use that
quite frequently, e.g. bool has_ptr(void **x) { return *x; }
 
> (We are also somehow abusing on the size definition of bool in
> C99/C17 or previous.)

I hope we never assume the size or alignment of bool. I always hope the
compiler will just reduce it to the control flags for inline predicates.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 10/28] drm/i915/tgl: Add power well support

2019-06-27 Thread Lucas De Marchi

On Thu, Jun 27, 2019 at 12:15:26PM -0700, Manasi Navare wrote:

On Tue, Jun 25, 2019 at 10:54:19AM -0700, Lucas De Marchi wrote:

From: Imre Deak 

The patch adds the new power wells introduced by TGL (GEN 12) and
maps these to existing/new power domains. The changes for GEN 12 wrt
to GEN 11 are the following:

- Transcoder#EDP removed from power well#1 (Transcoder#A used in
  low-power mode instead)
- Transcoder#A is now backed by power well#1 instead of power well#3
- The DDI#B/C combo PHY ports are now backed by power well#1 instead of
  power well#3
- New power well#5 added for pipe#D functionality (TODO)
- 2 additional TC ports (TC#5-6) backed by power well#3, 2 port
  specific IO power wells (only for the non-TBT modes) and 4 port
  specific AUX power wells (2-2 for TBT vs. non-TBT modes)
- Power well#2 backs now VDSC/joining for pipe#A instead of VDSC for
  eDP and MIPI DSI (TODO)

On TGL Port DDI#C changed to be a combo PHY (native DP/HDMI) and
BSpec has renamed ports DDI#D-F to TC#4-6 respectively. Thus on ICL we
have the following naming for ports:

- Combo PHYs (native DP/HDMI):
  DDI#A-B
- TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
  DDI#C-F

Starting from GEN 12 we have the following naming for ports:
- Combo PHYs (native DP/HDMI):
  DDI#A-C
- TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
  DDI TC#1-6

To save some space in the power domain enum the power domain naming in
the driver reflects the above change, that is power domains TC#1-3 are
added as aliases for DDI#D-F and new power domains are reserved for
TC#4-6.

Cc: Anusha Srivatsa 
Cc: Rodrigo Vivi 
Cc: José Roberto de Souza 
Signed-off-by: Imre Deak 
Signed-off-by: Lucas De Marchi 
---
 .../drm/i915/display/intel_display_power.c| 474 +-
 .../drm/i915/display/intel_display_power.h|  26 +-
 drivers/gpu/drm/i915/i915_debugfs.c   |   3 +-
 drivers/gpu/drm/i915/i915_reg.h   |  18 +
 4 files changed, 502 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c 
b/drivers/gpu/drm/i915/display/intel_display_power.c
index c93ad512014c..20b2009cecc6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -22,8 +22,11 @@ bool intel_display_power_well_is_enabled(struct 
drm_i915_private *dev_priv,
 enum i915_power_well_id power_well_id);

 const char *
-intel_display_power_domain_str(enum intel_display_power_domain domain)
+intel_display_power_domain_str(struct drm_i915_private *i915,
+  enum intel_display_power_domain domain)
 {
+   bool ddi_tc_ports = IS_GEN(i915, 12);
+
switch (domain) {
case POWER_DOMAIN_DISPLAY_CORE:
return "DISPLAY_CORE";
@@ -60,11 +63,23 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
case POWER_DOMAIN_PORT_DDI_C_LANES:
return "PORT_DDI_C_LANES";
case POWER_DOMAIN_PORT_DDI_D_LANES:
-   return "PORT_DDI_D_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_LANES !=
+POWER_DOMAIN_PORT_DDI_TC1_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC1_LANES" : "PORT_DDI_D_LANES";
case POWER_DOMAIN_PORT_DDI_E_LANES:
-   return "PORT_DDI_E_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_LANES !=
+POWER_DOMAIN_PORT_DDI_TC2_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC2_LANES" : "PORT_DDI_E_LANES";
case POWER_DOMAIN_PORT_DDI_F_LANES:
-   return "PORT_DDI_F_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_F_LANES !=
+POWER_DOMAIN_PORT_DDI_TC3_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC3_LANES" : "PORT_DDI_F_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC4_LANES:
+   return "PORT_DDI_TC4_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC5_LANES:
+   return "PORT_DDI_TC5_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC6_LANES:
+   return "PORT_DDI_TC6_LANES";
case POWER_DOMAIN_PORT_DDI_A_IO:
return "PORT_DDI_A_IO";
case POWER_DOMAIN_PORT_DDI_B_IO:
@@ -72,11 +87,23 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
case POWER_DOMAIN_PORT_DDI_C_IO:
return "PORT_DDI_C_IO";
case POWER_DOMAIN_PORT_DDI_D_IO:
-   return "PORT_DDI_D_IO";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_IO !=
+POWER_DOMAIN_PORT_DDI_TC1_IO);
+   return ddi_tc_ports ? "PORT_DDI_TC1_IO" : "PORT_DDI_D_IO";
case POWER_DOMAIN_PORT_DDI_E_IO:
-   return "PORT_DDI_E_IO";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_IO !=
+POWER_DOMAIN_PORT_DDI_TC2_IO);
+   return ddi_tc_ports ? "PORT_DDI_TC2_IO" : "PORT_DDI_E_IO";
case P

Re: [Intel-gfx] [PATCH 10/28] drm/i915/tgl: Add power well support

2019-06-27 Thread Lucas De Marchi

On Thu, Jun 27, 2019 at 12:31:30PM -0700, Jose Souza wrote:

On Tue, 2019-06-25 at 10:54 -0700, Lucas De Marchi wrote:

From: Imre Deak 

The patch adds the new power wells introduced by TGL (GEN 12) and
maps these to existing/new power domains. The changes for GEN 12 wrt
to GEN 11 are the following:

- Transcoder#EDP removed from power well#1 (Transcoder#A used in
  low-power mode instead)
- Transcoder#A is now backed by power well#1 instead of power well#3
- The DDI#B/C combo PHY ports are now backed by power well#1 instead
of
  power well#3
- New power well#5 added for pipe#D functionality (TODO)
- 2 additional TC ports (TC#5-6) backed by power well#3, 2 port
  specific IO power wells (only for the non-TBT modes) and 4 port
  specific AUX power wells (2-2 for TBT vs. non-TBT modes)
- Power well#2 backs now VDSC/joining for pipe#A instead of VDSC for
  eDP and MIPI DSI (TODO)

On TGL Port DDI#C changed to be a combo PHY (native DP/HDMI) and
BSpec has renamed ports DDI#D-F to TC#4-6 respectively. Thus on ICL
we
have the following naming for ports:

- Combo PHYs (native DP/HDMI):
  DDI#A-B
- TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
  DDI#C-F

Starting from GEN 12 we have the following naming for ports:
- Combo PHYs (native DP/HDMI):
  DDI#A-C
- TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
  DDI TC#1-6

To save some space in the power domain enum the power domain naming
in
the driver reflects the above change, that is power domains TC#1-3
are
added as aliases for DDI#D-F and new power domains are reserved for
TC#4-6.

Cc: Anusha Srivatsa 
Cc: Rodrigo Vivi 
Cc: José Roberto de Souza 
Signed-off-by: Imre Deak 
Signed-off-by: Lucas De Marchi 
---
 .../drm/i915/display/intel_display_power.c| 474
+-
 .../drm/i915/display/intel_display_power.h|  26 +-
 drivers/gpu/drm/i915/i915_debugfs.c   |   3 +-
 drivers/gpu/drm/i915/i915_reg.h   |  18 +
 4 files changed, 502 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
b/drivers/gpu/drm/i915/display/intel_display_power.c
index c93ad512014c..20b2009cecc6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -22,8 +22,11 @@ bool intel_display_power_well_is_enabled(struct
drm_i915_private *dev_priv,
 enum i915_power_well_id
power_well_id);

 const char *
-intel_display_power_domain_str(enum intel_display_power_domain
domain)
+intel_display_power_domain_str(struct drm_i915_private *i915,
+  enum intel_display_power_domain domain)
 {
+   bool ddi_tc_ports = IS_GEN(i915, 12);
+
switch (domain) {
case POWER_DOMAIN_DISPLAY_CORE:
return "DISPLAY_CORE";
@@ -60,11 +63,23 @@ intel_display_power_domain_str(enum
intel_display_power_domain domain)
case POWER_DOMAIN_PORT_DDI_C_LANES:
return "PORT_DDI_C_LANES";
case POWER_DOMAIN_PORT_DDI_D_LANES:
-   return "PORT_DDI_D_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_LANES !=
+POWER_DOMAIN_PORT_DDI_TC1_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC1_LANES" :
"PORT_DDI_D_LANES";
case POWER_DOMAIN_PORT_DDI_E_LANES:
-   return "PORT_DDI_E_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_LANES !=
+POWER_DOMAIN_PORT_DDI_TC2_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC2_LANES" :
"PORT_DDI_E_LANES";
case POWER_DOMAIN_PORT_DDI_F_LANES:
-   return "PORT_DDI_F_LANES";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_F_LANES !=
+POWER_DOMAIN_PORT_DDI_TC3_LANES);
+   return ddi_tc_ports ? "PORT_DDI_TC3_LANES" :
"PORT_DDI_F_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC4_LANES:
+   return "PORT_DDI_TC4_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC5_LANES:
+   return "PORT_DDI_TC5_LANES";
+   case POWER_DOMAIN_PORT_DDI_TC6_LANES:
+   return "PORT_DDI_TC6_LANES";
case POWER_DOMAIN_PORT_DDI_A_IO:
return "PORT_DDI_A_IO";
case POWER_DOMAIN_PORT_DDI_B_IO:
@@ -72,11 +87,23 @@ intel_display_power_domain_str(enum
intel_display_power_domain domain)
case POWER_DOMAIN_PORT_DDI_C_IO:
return "PORT_DDI_C_IO";
case POWER_DOMAIN_PORT_DDI_D_IO:
-   return "PORT_DDI_D_IO";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_IO !=
+POWER_DOMAIN_PORT_DDI_TC1_IO);
+   return ddi_tc_ports ? "PORT_DDI_TC1_IO" :
"PORT_DDI_D_IO";
case POWER_DOMAIN_PORT_DDI_E_IO:
-   return "PORT_DDI_E_IO";
+   BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_IO !=
+POWER_DOMAIN_PORT_DDI_TC2_IO);
+   return ddi_tc_ports ? "PORT_DDI_TC2_IO" :
"PORT_DDI_E_IO";
case POWER_DOMAIN_PO

Re: [Intel-gfx] [PATCH i-g-t v2] tests/i915/gem_ctx_switch: Update with engine discovery

2019-06-27 Thread Andi Shyti

Hi Tvrtko,

> +const struct intel_execution_engine2 *
> +gem_eb_flags_to_engine(unsigned int flags)
> +{
> + const struct intel_execution_engine2 *e2;
> +
> + __for_each_static_engine(e2) {
> + if (e2->flags == flags)
> + return e2;
> + }
> +
> + return NULL;
> +}

the amount of "helpers" is getting almost unbearable for a simple
mind like mine.

This means that we can get rid of

 gem_execbuf_flags_to_engine_class
 gem_ring_is_physical_engine
 gem_ring_has_physical_engine

in igt_gt.c, right?

> +bool gem_context_has_engine_map(int fd, uint32_t ctx)
> +{
> + struct drm_i915_gem_context_param param = {
> + .param = I915_CONTEXT_PARAM_ENGINES,
> + .ctx_id = ctx
> + };
> + int ret;
> +
> + ret = __gem_context_get_param(fd, ¶m);
> + igt_assert_eq(ret, 0);
> +
> + return param.size;

a small nitpick: bool to me means '0' or '1'.

So, if you do 'return param.size', I would call the function
gem_context_get_param_size, otherwise I would return
'!!param.size' and keep it bool.

(We are also somehow abusing on the size definition of bool in
C99/C17 or previous.)

I'm not asking you to change it, but it would make me happier :)

> +}
> diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
> index 2415fd1e379b..b175483fac1c 100644
> --- a/lib/i915/gem_engine_topology.h
> +++ b/lib/i915/gem_engine_topology.h
> @@ -53,6 +53,11 @@ int gem_context_lookup_engine(int fd, uint64_t engine, 
> uint32_t ctx_id,
>  
>  void gem_context_set_all_engines(int fd, uint32_t ctx);
>  
> +bool gem_context_has_engine_map(int fd, uint32_t ctx);
> +
> +const struct intel_execution_engine2 *
> +gem_eb_flags_to_engine(unsigned int flags);
> +
>  #define __for_each_static_engine(e__) \
>   for ((e__) = intel_execution_engines2; (e__)->name; (e__)++)
>  
> diff --git a/tests/i915/gem_ctx_switch.c b/tests/i915/gem_ctx_switch.c
> index 647911d4c42e..407905de2d34 100644
> --- a/tests/i915/gem_ctx_switch.c
> +++ b/tests/i915/gem_ctx_switch.c
> @@ -55,7 +55,7 @@ static double elapsed(const struct timespec *start, const 
> struct timespec *end)
>  
>  static int measure_qlen(int fd,
>   struct drm_i915_gem_execbuffer2 *execbuf,
> - unsigned int *engine, unsigned int nengine,
> + const struct intel_engine_data *engines,
>   int timeout)
>  {
>   const struct drm_i915_gem_exec_object2 * const obj =
> @@ -63,15 +63,17 @@ static int measure_qlen(int fd,
>   uint32_t ctx[64];
>   int min = INT_MAX, max = 0;
>  
> - for (int i = 0; i < ARRAY_SIZE(ctx); i++)
> + for (int i = 0; i < ARRAY_SIZE(ctx); i++) {
>   ctx[i] = gem_context_create(fd);
> + gem_context_set_all_engines(fd, ctx[i]);
> + }
>  
> - for (unsigned int n = 0; n < nengine; n++) {
> + for (unsigned int n = 0; n < engines->nengines; n++) {
>   uint64_t saved = execbuf->flags;
>   struct timespec tv = {};
>   int q;
>  
> - execbuf->flags |= engine[n];
> + execbuf->flags |= engines->engines[n].flags;
>  
>   for (int i = 0; i < ARRAY_SIZE(ctx); i++) {
>   execbuf->rsvd1 = ctx[i];
> @@ -90,7 +92,8 @@ static int measure_qlen(int fd,
>* Be conservative and aim not to overshoot timeout, so scale
>* down by 8 for hopefully a max of 12.5% error.
>*/
> - q = ARRAY_SIZE(ctx) * timeout * 1e9 / igt_nsec_elapsed(&tv) / 8 
> + 1;
> + q = ARRAY_SIZE(ctx) * timeout * 1e9 / igt_nsec_elapsed(&tv) /
> + 8 + 1;

I don't know whether it's me who is paranoic, but the change
above doesn't match the commit log.

>   if (q < min)
>   min = q;
>   if (q > max)
> @@ -107,7 +110,7 @@ static int measure_qlen(int fd,
>  }
>  
>  static void single(int fd, uint32_t handle,
> -const struct intel_execution_engine *e,
> +const struct intel_execution_engine2 *e2,
>  unsigned flags,
>  const int ncpus,
>  int timeout)
> @@ -125,13 +128,14 @@ static void single(int fd, uint32_t handle,
>   shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
>   igt_assert(shared != MAP_FAILED);
>  
> - gem_require_ring(fd, e->exec_id | e->flags);
> -
>   for (n = 0; n < 64; n++) {
>   if (flags & QUEUE)
>   contexts[n] = gem_queue_create(fd);
>   else
>   contexts[n] = gem_context_create(fd);
> +
> + if (gem_context_has_engine_map(fd, 0))
> + gem_context_set_all_engines(fd, contexts[n]);
>   }
>  
>   memset(&obj, 0, sizeof(obj));
> @@ -152,12 +156,12 @@ static void single(int fd, uint32_t handle,
>   execbuf.buffers_ptr = to_user_pointer(&obj);
>  

Re: [Intel-gfx] [PATCH v3 8/8] drm/i915/display/icl: In port sync mode disable slaves first then masters

2019-06-27 Thread Manasi Navare
On Mon, Jun 24, 2019 at 11:34:42PM -0700, Lucas De Marchi wrote:
> On Mon, Jun 24, 2019 at 2:07 PM Manasi Navare  
> wrote:
> >
> > In the transcoder port sync mode, the slave transcoders mask their vblanks
> > until master transcoder's vblank so while disabling them, make
> > sure slaves are disabled first and then the masters.
> >
> > Cc: Ville Syrjälä 
> > Cc: Maarten Lankhorst 
> > Cc: Matt Roper 
> > Cc: Jani Nikula 
> > Signed-off-by: Manasi Navare 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 117 ++-
> >  1 file changed, 111 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 0a0d97ef03d6..85746a26d0e0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -13901,6 +13901,106 @@ static void intel_commit_modeset_disables(struct 
> > drm_atomic_state *state)
> > }
> >  }
> >
> > +static void icl_commit_modeset_disables(struct drm_atomic_state *state)
> > +{
> > +   struct drm_device *dev = state->dev;
> > +   struct intel_atomic_state *intel_state = 
> > to_intel_atomic_state(state);
> > +   struct drm_i915_private *dev_priv = to_i915(dev);
> > +   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> > +   struct intel_crtc_state *new_intel_crtc_state, 
> > *old_intel_crtc_state;
> > +   struct drm_crtc *crtc;
> > +   struct intel_crtc *intel_crtc;
> > +   int i;
> > +
> > +   /*
> > +* Disable all the Port Sync Slaves first
> > +*/
> > +   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
> > new_crtc_state, i) {
> > +   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
> > +   new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
> > +   intel_crtc = to_intel_crtc(crtc);
> > +
> > +   if (!needs_modeset(new_crtc_state) ||
> > +   !is_trans_port_sync_slave(old_intel_crtc_state))
> > +   continue;
> > +
> > +   intel_pre_plane_update(old_intel_crtc_state, 
> > new_intel_crtc_state);
> > +
> > +   if (old_crtc_state->active) {
> > +   intel_crtc_disable_planes(intel_state, intel_crtc);
> > +
> > +   /*
> > +* We need to disable pipe CRC before disabling the 
> > pipe,
> > +* or we race against vblank off.
> > +*/
> > +   intel_crtc_disable_pipe_crc(intel_crtc);
> > +
> > +   
> > dev_priv->display.crtc_disable(old_intel_crtc_state, state);
> > +   intel_crtc->active = false;
> > +   intel_fbc_disable(intel_crtc);
> > +   intel_disable_shared_dpll(old_intel_crtc_state);
> > +
> > +   /*
> > +* Underruns don't always raise interrupts,
> > +* so check manually.
> > +*/
> > +   intel_check_cpu_fifo_underruns(dev_priv);
> > +   intel_check_pch_fifo_underruns(dev_priv);
> > +
> > +   /* FIXME unify this for all platforms */
> > +   if (!new_crtc_state->active &&
> > +   !HAS_GMCH(dev_priv) &&
> > +   dev_priv->display.initial_watermarks)
> > +   
> > dev_priv->display.initial_watermarks(intel_state,
> > +
> > new_intel_crtc_state);
> > +   }

I will move this part inside if (old_crtc_state->active) to a helper function.
Any suggestions on the name of this helper?

Manasi

> > +   }
> > +
> > +   /*
> > +* Disable rest of the CRTCs other than slaves
> > +*/
> > +   for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
> > new_crtc_state, i) {
> > +   old_intel_crtc_state = to_intel_crtc_state(old_crtc_state);
> > +   new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
> > +   intel_crtc = to_intel_crtc(crtc);
> > +
> > +   if (!needs_modeset(new_crtc_state) ||
> > +   is_trans_port_sync_slave(old_intel_crtc_state))
> > +   continue;
> > +
> > +   intel_pre_plane_update(old_intel_crtc_state, 
> > new_intel_crtc_state);
> > +
> > +   if (old_crtc_state->active) {
> > +   intel_crtc_disable_planes(intel_state, intel_crtc);
> > +
> > +   /*
> > +* We need to disable pipe CRC before disabling the 
> > pipe,
> > +* or we race against vblank off.
> > +*/
> > +   intel_crtc_disable_pipe_crc(intel_crtc);
> > +

Re: [Intel-gfx] [PATCH 10/28] drm/i915/tgl: Add power well support

2019-06-27 Thread Souza, Jose
On Tue, 2019-06-25 at 10:54 -0700, Lucas De Marchi wrote:
> From: Imre Deak 
> 
> The patch adds the new power wells introduced by TGL (GEN 12) and
> maps these to existing/new power domains. The changes for GEN 12 wrt
> to GEN 11 are the following:
> 
> - Transcoder#EDP removed from power well#1 (Transcoder#A used in
>   low-power mode instead)
> - Transcoder#A is now backed by power well#1 instead of power well#3
> - The DDI#B/C combo PHY ports are now backed by power well#1 instead
> of
>   power well#3
> - New power well#5 added for pipe#D functionality (TODO)
> - 2 additional TC ports (TC#5-6) backed by power well#3, 2 port
>   specific IO power wells (only for the non-TBT modes) and 4 port
>   specific AUX power wells (2-2 for TBT vs. non-TBT modes)
> - Power well#2 backs now VDSC/joining for pipe#A instead of VDSC for
>   eDP and MIPI DSI (TODO)
> 
> On TGL Port DDI#C changed to be a combo PHY (native DP/HDMI) and
> BSpec has renamed ports DDI#D-F to TC#4-6 respectively. Thus on ICL
> we
> have the following naming for ports:
> 
> - Combo PHYs (native DP/HDMI):
>   DDI#A-B
> - TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
>   DDI#C-F
> 
> Starting from GEN 12 we have the following naming for ports:
> - Combo PHYs (native DP/HDMI):
>   DDI#A-C
> - TBT/non-TBT (TC altmode, native DP/HDMI) PHYs:
>   DDI TC#1-6
> 
> To save some space in the power domain enum the power domain naming
> in
> the driver reflects the above change, that is power domains TC#1-3
> are
> added as aliases for DDI#D-F and new power domains are reserved for
> TC#4-6.
> 
> Cc: Anusha Srivatsa 
> Cc: Rodrigo Vivi 
> Cc: José Roberto de Souza 
> Signed-off-by: Imre Deak 
> Signed-off-by: Lucas De Marchi 
> ---
>  .../drm/i915/display/intel_display_power.c| 474
> +-
>  .../drm/i915/display/intel_display_power.h|  26 +-
>  drivers/gpu/drm/i915/i915_debugfs.c   |   3 +-
>  drivers/gpu/drm/i915/i915_reg.h   |  18 +
>  4 files changed, 502 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> b/drivers/gpu/drm/i915/display/intel_display_power.c
> index c93ad512014c..20b2009cecc6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -22,8 +22,11 @@ bool intel_display_power_well_is_enabled(struct
> drm_i915_private *dev_priv,
>enum i915_power_well_id
> power_well_id);
>  
>  const char *
> -intel_display_power_domain_str(enum intel_display_power_domain
> domain)
> +intel_display_power_domain_str(struct drm_i915_private *i915,
> +enum intel_display_power_domain domain)
>  {
> + bool ddi_tc_ports = IS_GEN(i915, 12);
> +
>   switch (domain) {
>   case POWER_DOMAIN_DISPLAY_CORE:
>   return "DISPLAY_CORE";
> @@ -60,11 +63,23 @@ intel_display_power_domain_str(enum
> intel_display_power_domain domain)
>   case POWER_DOMAIN_PORT_DDI_C_LANES:
>   return "PORT_DDI_C_LANES";
>   case POWER_DOMAIN_PORT_DDI_D_LANES:
> - return "PORT_DDI_D_LANES";
> + BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_LANES !=
> +  POWER_DOMAIN_PORT_DDI_TC1_LANES);
> + return ddi_tc_ports ? "PORT_DDI_TC1_LANES" :
> "PORT_DDI_D_LANES";
>   case POWER_DOMAIN_PORT_DDI_E_LANES:
> - return "PORT_DDI_E_LANES";
> + BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_LANES !=
> +  POWER_DOMAIN_PORT_DDI_TC2_LANES);
> + return ddi_tc_ports ? "PORT_DDI_TC2_LANES" :
> "PORT_DDI_E_LANES";
>   case POWER_DOMAIN_PORT_DDI_F_LANES:
> - return "PORT_DDI_F_LANES";
> + BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_F_LANES !=
> +  POWER_DOMAIN_PORT_DDI_TC3_LANES);
> + return ddi_tc_ports ? "PORT_DDI_TC3_LANES" :
> "PORT_DDI_F_LANES";
> + case POWER_DOMAIN_PORT_DDI_TC4_LANES:
> + return "PORT_DDI_TC4_LANES";
> + case POWER_DOMAIN_PORT_DDI_TC5_LANES:
> + return "PORT_DDI_TC5_LANES";
> + case POWER_DOMAIN_PORT_DDI_TC6_LANES:
> + return "PORT_DDI_TC6_LANES";
>   case POWER_DOMAIN_PORT_DDI_A_IO:
>   return "PORT_DDI_A_IO";
>   case POWER_DOMAIN_PORT_DDI_B_IO:
> @@ -72,11 +87,23 @@ intel_display_power_domain_str(enum
> intel_display_power_domain domain)
>   case POWER_DOMAIN_PORT_DDI_C_IO:
>   return "PORT_DDI_C_IO";
>   case POWER_DOMAIN_PORT_DDI_D_IO:
> - return "PORT_DDI_D_IO";
> + BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_IO !=
> +  POWER_DOMAIN_PORT_DDI_TC1_IO);
> + return ddi_tc_ports ? "PORT_DDI_TC1_IO" :
> "PORT_DDI_D_IO";
>   case POWER_DOMAIN_PORT_DDI_E_IO:
> - return "PORT_DDI_E_IO";
> + BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_IO !=
> +  POWER_DOMAIN_PORT_DDI_TC2_IO);
> +  

Re: [Intel-gfx] [PATCH 12/28] drm/i915/tgl: Add TRANSCODER_A_VDSC power domain

2019-06-27 Thread Manasi Navare
On Thu, Jun 27, 2019 at 07:28:15PM +, Souza, Jose wrote:
> On Tue, 2019-06-25 at 10:54 -0700, Lucas De Marchi wrote:
> > From: José Roberto de Souza 
> > 
> > On TGL the special EDP transcoder is gone and it should be handled by
> > transcoder A. Add POWER_DOMAIN_TRANSCODER_A_VDSC to make this
> > distinction clear and update vdsc code path.
> > 
> > Cc: Imre Deak 
> > Signed-off-by: José Roberto de Souza 
> > Signed-off-by: Lucas De Marchi 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display_power.c |  2 ++
> >  drivers/gpu/drm/i915/display/intel_display_power.h |  1 +
> >  drivers/gpu/drm/i915/display/intel_vdsc.c  | 11 ---
> >  3 files changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> > b/drivers/gpu/drm/i915/display/intel_display_power.c
> > index 0c7d4a363deb..15582841fefc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> > @@ -58,6 +58,8 @@ intel_display_power_domain_str(struct
> > drm_i915_private *i915,
> > return "TRANSCODER_EDP";
> > case POWER_DOMAIN_TRANSCODER_EDP_VDSC:
> > return "TRANSCODER_EDP_VDSC";
> > +   case POWER_DOMAIN_TRANSCODER_A_VDSC:
> > +   return "TRANSCODER_A_VDSC";
> > case POWER_DOMAIN_TRANSCODER_DSI_A:
> > return "TRANSCODER_DSI_A";
> > case POWER_DOMAIN_TRANSCODER_DSI_C:
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h
> > b/drivers/gpu/drm/i915/display/intel_display_power.h
> > index 79262a5bceb4..7761b493608a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> > @@ -29,6 +29,7 @@ enum intel_display_power_domain {
> > POWER_DOMAIN_TRANSCODER_D,
> > POWER_DOMAIN_TRANSCODER_EDP,
> > POWER_DOMAIN_TRANSCODER_EDP_VDSC,
> > +   POWER_DOMAIN_TRANSCODER_A_VDSC,
> > POWER_DOMAIN_TRANSCODER_DSI_A,
> > POWER_DOMAIN_TRANSCODER_DSI_C,
> > POWER_DOMAIN_PORT_DDI_A_LANES,
> > diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c
> > b/drivers/gpu/drm/i915/display/intel_vdsc.c
> > index ffec807b8960..0c75b408d6ba 100644
> > --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> > @@ -459,16 +459,21 @@ int intel_dp_compute_dsc_params(struct intel_dp
> > *intel_dp,
> >  enum intel_display_power_domain
> >  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
> >  {
> > +   struct drm_i915_private *dev_priv = to_i915(crtc_state-
> > >base.state->dev);
> > enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> >  
> > /*
> > -* On ICL VDSC/joining for eDP transcoder uses a separate power
> > well PW2
> > -* This requires POWER_DOMAIN_TRANSCODER_EDP_VDSC power domain.
> > +* On ICL+ VDSC/joining for eDP/A transcoder uses a separate
> > power well
> > +* PW2. This requires
> > +*
> > POWER_DOMAIN_TRANSCODER_EDP_VDSC/POWER_DOMAIN_TRANSCODER_A_VDSC power
> > +* domain.
> >  * For any other transcoder, VDSC/joining uses the power well
> > associated
> >  * with the pipe/transcoder in use. Hence another reference on
> > the
> >  * transcoder power domain will suffice.
> >  */
> > -   if (cpu_transcoder == TRANSCODER_EDP)
> > +   if (INTEL_GEN(dev_priv) >= 12 && cpu_transcoder ==
> > TRANSCODER_A)
> > +   return POWER_DOMAIN_TRANSCODER_A_VDSC;
> > +   else if (cpu_transcoder == TRANSCODER_EDP)
> > return POWER_DOMAIN_TRANSCODER_EDP_VDSC;
> > else
> > return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
> 
> 
> This is missing the change adding POWER_DOMAIN_TRANSCODER_EDP_VDSC to
> TGL_PW_2_POWER_DOMAINS.

You mean POWER_DOMAIN_TRANSCODER_A_VDSC?

Manasi

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

  1   2   3   >