Re: [PATCH 3/4] drm/hisilicon/hibmc: Implement hibmc_dumb_create() with generic helpers

2019-11-25 Thread Thomas Zimmermann
Hi

thanks for the review.

Am 23.11.19 um 09:56 schrieb Sam Ravnborg:
> Hi Thomas.
> 
> Change looks good. If you spin this could you move the
> changes to generic drm code to a separate patch?
> As it is now it is hidden for most.
> But then there are also no users of drm_gem_vram_fill_create_dumb()

I just posted a patchset for mgag200 that uses this function. Maybe
it'll have to stay.

Best regards
Thomas

> 
> One small nit below that you can safely ignore :-)
> 
> 
>   Sam
> 
> 
> On Fri, Nov 22, 2019 at 09:30:43AM +0100, Thomas Zimmermann wrote:
>> The hibmc driver aligns scanlines to 16 bytes. Adding the pitch alignment
>> as an argument to drm_gem_vram_fill_create_dumb() allows to use the generic
>> implementation with hibmc. A value of 0 disables scanline pitches.
>>
>> Signed-off-by: Thomas Zimmermann 
>> ---
>>  drivers/gpu/drm/drm_gem_vram_helper.c | 10 ++--
>>  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  4 --
>>  drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 48 +--
>>  include/drm/drm_gem_vram_helper.h |  1 +
>>  4 files changed, 10 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
>> b/drivers/gpu/drm/drm_gem_vram_helper.c
>> index 666cb4c22bb9..f098784e7dfd 100644
>> --- a/drivers/gpu/drm/drm_gem_vram_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_vram_helper.c
>> @@ -485,6 +485,7 @@ EXPORT_SYMBOL(drm_gem_vram_vunmap);
>>   * @dev:the DRM device
>>   * @bdev:   the TTM BO device managing the buffer object
>>   * @pg_align:   the buffer's alignment in multiples of the page 
>> size
>> + * @pitch_align:the scanline's alignment in powers of 2
>>   * @interruptible:  sleep interruptible if waiting for memory
>>   * @args:   the arguments as provided to \
>>   drm_driver.dumb_create
>> @@ -502,6 +503,7 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file,
>>struct drm_device *dev,
>>struct ttm_bo_device *bdev,
>>unsigned long pg_align,
>> +  unsigned long pitch_align,
>>bool interruptible,
>>struct drm_mode_create_dumb *args)
>>  {
>> @@ -510,7 +512,9 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file,
>>  int ret;
>>  u32 handle;
>>  
>> -pitch = args->width * ((args->bpp + 7) / 8);
>> +pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
> Semi related change...
> 
>> +if (pitch_align)
>> +pitch = ALIGN(pitch, pitch_align);
>>  size = pitch * args->height;
>>  
>>  size = roundup(size, PAGE_SIZE);
>> @@ -612,8 +616,8 @@ int drm_gem_vram_driver_dumb_create(struct drm_file 
>> *file,
>>  if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
>>  return -EINVAL;
>>  
>> -return drm_gem_vram_fill_create_dumb(file, dev, >vram_mm->bdev, 0,
>> - false, args);
>> +return drm_gem_vram_fill_create_dumb(file, dev, >vram_mm->bdev,
>> + 0, 0, false, args);
>>  }
>>  EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
>>  
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h 
>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> index 8eb7258b236a..50a0c1f9d211 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> @@ -18,7 +18,6 @@
>>  #include 
>>  
>>  struct drm_device;
>> -struct drm_gem_object;
>>  
>>  struct hibmc_drm_private {
>>  /* hw */
>> @@ -41,9 +40,6 @@ void hibmc_set_current_gate(struct hibmc_drm_private *priv,
>>  int hibmc_de_init(struct hibmc_drm_private *priv);
>>  int hibmc_vdac_init(struct hibmc_drm_private *priv);
>>  
>> -int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
>> - struct drm_gem_object **obj);
>> -
>>  int hibmc_mm_init(struct hibmc_drm_private *hibmc);
>>  void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
>>  int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c 
>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> index f6d25b85c209..0af5d966a480 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> @@ -47,55 +47,11 @@ void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
>>  drm_vram_helper_release_mm(hibmc->dev);
>>  }
>>  
>> -int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
>> - struct drm_gem_object **obj)
>> -{
>> -struct drm_gem_vram_object *gbo;
>> -int ret;
>> -
>> -*obj = NULL;
>> -
>> -size = roundup(size, PAGE_SIZE);
>> -if (size == 0)
>> -return -EINVAL;
>> -
>> -gbo = drm_gem_vram_create(dev, >vram_mm->bdev, size, 0, false);
>> -if 

Re: [PATCH 3/4] drm/hisilicon/hibmc: Implement hibmc_dumb_create() with generic helpers

2019-11-25 Thread Thomas Zimmermann
Hi

Am 25.11.19 um 10:14 schrieb Daniel Vetter:
> On Fri, Nov 22, 2019 at 09:30:43AM +0100, Thomas Zimmermann wrote:
>> The hibmc driver aligns scanlines to 16 bytes. Adding the pitch alignment
>> as an argument to drm_gem_vram_fill_create_dumb() allows to use the generic
>> implementation with hibmc. A value of 0 disables scanline pitches.
>>
>> Signed-off-by: Thomas Zimmermann 
> 
> I concur with Sam, the vram change should be split out.
> 
>> ---
>>  drivers/gpu/drm/drm_gem_vram_helper.c | 10 ++--
>>  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  4 --
>>  drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 48 +--
>>  include/drm/drm_gem_vram_helper.h |  1 +
>>  4 files changed, 10 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
>> b/drivers/gpu/drm/drm_gem_vram_helper.c
>> index 666cb4c22bb9..f098784e7dfd 100644
>> --- a/drivers/gpu/drm/drm_gem_vram_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_vram_helper.c
>> @@ -485,6 +485,7 @@ EXPORT_SYMBOL(drm_gem_vram_vunmap);
>>   * @dev:the DRM device
>>   * @bdev:   the TTM BO device managing the buffer object
>>   * @pg_align:   the buffer's alignment in multiples of the page 
>> size
>> + * @pitch_align:the scanline's alignment in powers of 2
>>   * @interruptible:  sleep interruptible if waiting for memory
> 
> I also noticed that no one sets this to true, neither here nor in
> drm_gem_vram_create(). Maybe remove that too? Otherwise the argument list
> becomes very unwielding. And you're already touching the (few) callers.

OK, I'll add this as a separate patch.

BTW What's the DRM interface's behavior wrt interruption? For example,
can a ioctl call like CREATE_DUMB return EINTR to userspace?

Best regards
Thomas

> 
>>   * @args:   the arguments as provided to \
>>   drm_driver.dumb_create
>> @@ -502,6 +503,7 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file,
>>struct drm_device *dev,
>>struct ttm_bo_device *bdev,
>>unsigned long pg_align,
>> +  unsigned long pitch_align,
>>bool interruptible,
>>struct drm_mode_create_dumb *args)
>>  {
>> @@ -510,7 +512,9 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file,
>>  int ret;
>>  u32 handle;
>>  
>> -pitch = args->width * ((args->bpp + 7) / 8);
>> +pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
>> +if (pitch_align)
>> +pitch = ALIGN(pitch, pitch_align);
> 
> Maybe throw a WARN_IS(is_pot(align)) in here?
> 
> Cheers, Daniel
> 
>>  size = pitch * args->height;
>>  
>>  size = roundup(size, PAGE_SIZE);
>> @@ -612,8 +616,8 @@ int drm_gem_vram_driver_dumb_create(struct drm_file 
>> *file,
>>  if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
>>  return -EINVAL;
>>  
>> -return drm_gem_vram_fill_create_dumb(file, dev, >vram_mm->bdev, 0,
>> - false, args);
>> +return drm_gem_vram_fill_create_dumb(file, dev, >vram_mm->bdev,
>> + 0, 0, false, args);
>>  }
>>  EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
>>  
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h 
>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> index 8eb7258b236a..50a0c1f9d211 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> @@ -18,7 +18,6 @@
>>  #include 
>>  
>>  struct drm_device;
>> -struct drm_gem_object;
>>  
>>  struct hibmc_drm_private {
>>  /* hw */
>> @@ -41,9 +40,6 @@ void hibmc_set_current_gate(struct hibmc_drm_private *priv,
>>  int hibmc_de_init(struct hibmc_drm_private *priv);
>>  int hibmc_vdac_init(struct hibmc_drm_private *priv);
>>  
>> -int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
>> - struct drm_gem_object **obj);
>> -
>>  int hibmc_mm_init(struct hibmc_drm_private *hibmc);
>>  void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
>>  int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c 
>> b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> index f6d25b85c209..0af5d966a480 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
>> @@ -47,55 +47,11 @@ void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
>>  drm_vram_helper_release_mm(hibmc->dev);
>>  }
>>  
>> -int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
>> - struct drm_gem_object **obj)
>> -{
>> -struct drm_gem_vram_object *gbo;
>> -int ret;
>> -
>> -*obj = NULL;
>> -
>> -size = roundup(size, PAGE_SIZE);
>> -if (size == 0)
>> -return -EINVAL;
>> -
>> - 

[PATCH 2/4] drm/mgag200: Store flags from PCI driver data in device structure

2019-11-25 Thread Thomas Zimmermann
The flags field in struct mga_device has been unused so far. We now
use it to store flag bits from the PCI driver.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.h  | 8 
 drivers/gpu/drm/mgag200/mgag200_main.c | 1 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 976404634092..4b4f9ce74a84 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -151,6 +151,7 @@ enum mga_type {
 };
 
 #define MGAG200_TYPE_MASK  (0x00ff)
+#define MGAG200_FLAG_MASK  (0x0000)
 
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
@@ -188,6 +189,13 @@ mgag200_type_from_driver_data(kernel_ulong_t driver_data)
 {
return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
 }
+
+static inline unsigned long
+mgag200_flags_from_driver_data(kernel_ulong_t driver_data)
+{
+   return driver_data & MGAG200_FLAG_MASK;
+}
+
/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c 
b/drivers/gpu/drm/mgag200/mgag200_main.c
index 517c5693ad69..e1bc5b0aa774 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -94,6 +94,7 @@ static int mgag200_device_init(struct drm_device *dev,
struct mga_device *mdev = dev->dev_private;
int ret, option;
 
+   mdev->flags = mgag200_flags_from_driver_data(flags);
mdev->type = mgag200_type_from_driver_data(flags);
 
/* Hardcode the number of CRTCs to 1 */
-- 
2.23.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/4] drm/mgag200: Add module parameter to pin all buffers at offset 0

2019-11-25 Thread Thomas Zimmermann
For hardware that does not interpret the startadd field correctly,
add the module parameter 'hw_bug_no_startadd', which enables the
workaround.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index d43951caeea0..79836b09a54a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -27,6 +27,10 @@ int mgag200_modeset = -1;
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, mgag200_modeset, int, 0400);
 
+int mgag200_hw_bug_no_startadd = -1;
+MODULE_PARM_DESC(modeset, "HW does not interpret scanout-buffer start address 
correctly");
+module_param_named(hw_bug_no_startadd, mgag200_hw_bug_no_startadd, int, 0400);
+
 static struct drm_driver driver;
 
 static const struct pci_device_id pciidlist[] = {
@@ -64,6 +68,10 @@ DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
 
 static bool mgag200_pin_bo_at_0(const struct mga_device *mdev)
 {
+   if (!mgag200_hw_bug_no_startadd)
+   return false;
+   else if (mgag200_hw_bug_no_startadd > 0)
+   return true;
return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD;
 }
 
-- 
2.23.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 0/4] drm/mgag200: Workaround HW bug with non-0 offset

2019-11-25 Thread Thomas Zimmermann
We found an MGA chip that does not interpret the scanout offset
correctly. This patch works around the problem by placing all buffer
objects at offset 0 on this system.

There's a new module parameter 'hw_bug_no_startadd' that enables and
disables the offset-0 placement. Default is auto-detection.

Thomas Zimmermann (4):
  drm/mgag200: Extract device type from flags
  drm/mgag200: Store flags from PCI driver data in device structure
  drm/mgag200: Add workaround for HW that does not support 'startadd'
  drm/mgag200: Add module parameter to pin all buffers at offset 0

 drivers/gpu/drm/mgag200/mgag200_drv.c  | 44 +-
 drivers/gpu/drm/mgag200/mgag200_drv.h  | 18 +++
 drivers/gpu/drm/mgag200/mgag200_main.c |  3 +-
 3 files changed, 63 insertions(+), 2 deletions(-)

--
2.23.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 3/4] drm/mgag200: Add workaround for HW that does not support 'startadd'

2019-11-25 Thread Thomas Zimmermann
There's at least one system that does not interpret the value of
the device's 'startadd' field correctly, which leads to incorrectly
displayed scanout buffers. Always placing the active scanout buffer
at offset 0 works around the problem.

Signed-off-by: Thomas Zimmermann 
Reported-by: John Donnelly 
Link: https://gitlab.freedesktop.org/drm/misc/issues/7
---
 drivers/gpu/drm/mgag200/mgag200_drv.c | 36 ++-
 drivers/gpu/drm/mgag200/mgag200_drv.h |  3 +++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 397f8b0a9af8..d43951caeea0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -30,6 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400);
 static struct drm_driver driver;
 
 static const struct pci_device_id pciidlist[] = {
+   { PCI_VENDOR_ID_MATROX, 0x522, PCI_VENDOR_ID_SUN, 0x4852, 0, 0,
+   G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A 
},
{ PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B 
},
{ PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
@@ -60,6 +62,35 @@ static void mga_pci_remove(struct pci_dev *pdev)
 
 DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
 
+static bool mgag200_pin_bo_at_0(const struct mga_device *mdev)
+{
+   return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD;
+}
+
+int mgag200_driver_dumb_create(struct drm_file *file,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args)
+{
+   struct mga_device *mdev = dev->dev_private;
+   unsigned long pg_align;
+
+   if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
+   return -EINVAL;
+
+   pg_align = 0ul;
+
+   /*
+* Aligning scanout buffers to the size of the video ram forces
+* placement at offset 0. Works around a bug where HW does not
+* respect 'startadd' field.
+*/
+   if (mgag200_pin_bo_at_0(mdev))
+   pg_align = PFN_UP(mdev->mc.vram_size);
+
+   return drm_gem_vram_fill_create_dumb(file, dev, >vram_mm->bdev,
+pg_align, false, args);
+}
+
 static struct drm_driver driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET,
.load = mgag200_driver_load,
@@ -71,7 +102,10 @@ static struct drm_driver driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
-   DRM_GEM_VRAM_DRIVER
+   .debugfs_init = drm_vram_mm_debugfs_init,
+   .dumb_create = mgag200_driver_dumb_create,
+   .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset,
+   .gem_prime_mmap = drm_gem_prime_mmap,
 };
 
 static struct pci_driver mgag200_pci_driver = {
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 4b4f9ce74a84..aa32aad222c2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -150,6 +150,9 @@ enum mga_type {
G200_EW3,
 };
 
+/* HW does not handle 'startadd' field correct. */
+#define MGAG200_FLAG_HW_BUG_NO_STARTADD(1ul << 8)
+
 #define MGAG200_TYPE_MASK  (0x00ff)
 #define MGAG200_FLAG_MASK  (0x0000)
 
-- 
2.23.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/4] drm/mgag200: Extract device type from flags

2019-11-25 Thread Thomas Zimmermann
Adds a conversion function that extracts the device type from the
PCI id-table flags. Allows for storing additional information in the
other flag bits.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.h  | 7 +++
 drivers/gpu/drm/mgag200/mgag200_main.c | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 0ea9a525e57d..976404634092 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -150,6 +150,8 @@ enum mga_type {
G200_EW3,
 };
 
+#define MGAG200_TYPE_MASK  (0x00ff)
+
 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
 
 struct mga_device {
@@ -181,6 +183,11 @@ struct mga_device {
u32 unique_rev_id;
 };
 
+static inline enum mga_type
+mgag200_type_from_driver_data(kernel_ulong_t driver_data)
+{
+   return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
+}
/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c 
b/drivers/gpu/drm/mgag200/mgag200_main.c
index 5f74aabcd3df..517c5693ad69 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -94,7 +94,7 @@ static int mgag200_device_init(struct drm_device *dev,
struct mga_device *mdev = dev->dev_private;
int ret, option;
 
-   mdev->type = flags;
+   mdev->type = mgag200_type_from_driver_data(flags);
 
/* Hardcode the number of CRTCs to 1 */
mdev->num_crtc = 1;
-- 
2.23.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 6/7] drm/mediatek: support CMDQ interface in ddp component

2019-11-25 Thread Bibby Hsieh
The CMDQ (Command Queue) in MT8183 is used to help
update all relevant display controller registers
with critical time limation.
This patch add cmdq interface in ddp_comp interface,
let all ddp_comp interface can support cpu/cmdq function
at the same time.

Signed-off-by: YT Shen 
Signed-off-by: CK Hu 
Signed-off-by: Philipp Zabel 
Signed-off-by: Bibby Hsieh 
Signed-off-by: Yongqiang Niu 
---
 drivers/gpu/drm/mediatek/mtk_disp_color.c   |   7 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  65 ++-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  43 ---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  11 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 120 ++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  55 ++---
 6 files changed, 190 insertions(+), 111 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c 
b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 59de2a46aa49..6fb0d6983a4a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mtk_drm_crtc.h"
 #include "mtk_drm_ddp_comp.h"
@@ -45,12 +46,12 @@ static inline struct mtk_disp_color *comp_to_color(struct 
mtk_ddp_comp *comp)
 
 static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
 unsigned int h, unsigned int vrefresh,
-unsigned int bpc)
+unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_color *color = comp_to_color(comp);
 
-   writel(w, comp->regs + DISP_COLOR_WIDTH(color));
-   writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
+   mtk_ddp_write(cmdq_pkt, w, comp, DISP_COLOR_WIDTH(color));
+   mtk_ddp_write(cmdq_pkt, h, comp, DISP_COLOR_HEIGHT(color));
 }
 
 static void mtk_color_start(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 722a5adb79dc..0732cd3ee4c8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mtk_drm_crtc.h"
 #include "mtk_drm_ddp_comp.h"
@@ -125,14 +126,15 @@ static void mtk_ovl_stop(struct mtk_ddp_comp *comp)
 
 static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
   unsigned int h, unsigned int vrefresh,
-  unsigned int bpc)
+  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
if (w != 0 && h != 0)
-   writel_relaxed(h << 16 | w, comp->regs + DISP_REG_OVL_ROI_SIZE);
-   writel_relaxed(0x0, comp->regs + DISP_REG_OVL_ROI_BGCLR);
+   mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, comp,
+ DISP_REG_OVL_ROI_SIZE);
+   mtk_ddp_write_relaxed(cmdq_pkt, 0x0, comp, DISP_REG_OVL_ROI_BGCLR);
 
-   writel(0x1, comp->regs + DISP_REG_OVL_RST);
-   writel(0x0, comp->regs + DISP_REG_OVL_RST);
+   mtk_ddp_write(cmdq_pkt, 0x1, comp, DISP_REG_OVL_RST);
+   mtk_ddp_write(cmdq_pkt, 0x0, comp, DISP_REG_OVL_RST);
 }
 
 static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
@@ -176,16 +178,16 @@ static int mtk_ovl_layer_check(struct mtk_ddp_comp *comp, 
unsigned int idx,
return 0;
 }
 
-static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
+static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx,
+struct cmdq_pkt *cmdq_pkt)
 {
-   unsigned int reg;
unsigned int gmc_thrshd_l;
unsigned int gmc_thrshd_h;
unsigned int gmc_value;
struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
 
-   writel(0x1, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
-
+   mtk_ddp_write(cmdq_pkt, 0x1, comp,
+ DISP_REG_OVL_RDMA_CTRL(idx));
gmc_thrshd_l = GMC_THRESHOLD_LOW >>
  (GMC_THRESHOLD_BITS - ovl->data->gmc_bits);
gmc_thrshd_h = GMC_THRESHOLD_HIGH >>
@@ -195,22 +197,19 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, 
unsigned int idx)
else
gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 |
gmc_thrshd_h << 16 | gmc_thrshd_h << 24;
-   writel(gmc_value, comp->regs + DISP_REG_OVL_RDMA_GMC(idx));
-
-   reg = readl(comp->regs + DISP_REG_OVL_SRC_CON);
-   reg = reg | BIT(idx);
-   writel(reg, comp->regs + DISP_REG_OVL_SRC_CON);
+   mtk_ddp_write(cmdq_pkt, gmc_value,
+ comp, DISP_REG_OVL_RDMA_GMC(idx));
+   mtk_ddp_write_mask(cmdq_pkt, BIT(idx), comp,
+  DISP_REG_OVL_SRC_CON, BIT(idx));
 }
 
-static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
+static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx,
+ struct cmdq_pkt *cmdq_pkt)
 {
-   

[PATCH 7/7] drm/mediatek: apply CMDQ control flow

2019-11-25 Thread Bibby Hsieh
Unlike other SoCs, MT8183 does not have "shadow"
registers for performaing an atomic video mode
set or page flip at vblank/vsync.

The CMDQ (Commend Queue) in MT8183 is used to help
update all relevant display controller registers
with critical time limation.

Signed-off-by: YT Shen 
Signed-off-by: CK Hu 
Signed-off-by: Philipp Zabel 
Signed-off-by: Bibby Hsieh 
Signed-off-by: Yongqiang Niu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 165 ++--
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  31 
 drivers/gpu/drm/mediatek/mtk_drm_plane.c|   4 +
 4 files changed, 187 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 3935fac624f6..4fb346cdda79 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -12,6 +12,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "mtk_drm_drv.h"
 #include "mtk_drm_crtc.h"
@@ -20,6 +22,7 @@
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
 
+typedef void (*drm_cmdq_cb)(struct cmdq_cb_data data);
 /**
  * struct mtk_drm_crtc - MediaTek specific crtc structure.
  * @base: crtc object.
@@ -42,6 +45,10 @@ struct mtk_drm_crtc {
unsigned intlayer_nr;
boolpending_planes;
boolcursor_update;
+
+   struct cmdq_client  *cmdq_client;
+   u32 cmdq_event;
+
void __iomem*config_regs;
const struct mtk_mmsys_reg_data *mmsys_reg_data;
struct mtk_disp_mutex   *mutex;
@@ -57,6 +64,12 @@ struct mtk_crtc_state {
unsigned intpending_width;
unsigned intpending_height;
unsigned intpending_vrefresh;
+   struct cmdq_pkt *cmdq_handle;
+};
+
+struct mtk_cmdq_cb_data {
+   struct drm_crtc_state   *state;
+   struct cmdq_pkt *cmdq_handle;
 };
 
 static inline struct mtk_drm_crtc *to_mtk_crtc(struct drm_crtc *c)
@@ -228,8 +241,71 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct 
drm_crtc *crtc,
 
WARN(1, "Failed to find component for plane %d\n", plane->index);
return NULL;
+};
+
+#ifdef CONFIG_MTK_CMDQ
+static void ddp_cmdq_cursor_cb(struct cmdq_cb_data data)
+{
+   struct mtk_cmdq_cb_data *cb_data = data.data;
+
+   cmdq_pkt_destroy(cb_data->cmdq_handle);
+   kfree(cb_data);
 }
 
+static void ddp_cmdq_cb(struct cmdq_cb_data data)
+{
+   struct mtk_cmdq_cb_data *cb_data = data.data;
+   struct drm_crtc_state *crtc_state = cb_data->state;
+   struct drm_atomic_state *atomic_state = crtc_state->state;
+   struct drm_crtc *crtc = crtc_state->crtc;
+   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+
+   if (mtk_crtc->pending_needs_vblank) {
+   /* cmdq_vblank_event must be read after cmdq_needs_event */
+   smp_rmb();
+
+   mtk_drm_crtc_finish_page_flip(mtk_crtc);
+   mtk_crtc->pending_needs_vblank = false;
+   }
+   mtk_atomic_state_put_queue(atomic_state);
+   cmdq_pkt_destroy(cb_data->cmdq_handle);
+   kfree(cb_data);
+}
+
+static void mtk_cmdq_acquire(struct drm_crtc *crtc)
+{
+   struct mtk_crtc_state *mtk_crtc_state =
+   to_mtk_crtc_state(crtc->state);
+   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+
+   mtk_crtc_state->cmdq_handle =
+   cmdq_pkt_create(mtk_crtc->cmdq_client,
+   PAGE_SIZE);
+   cmdq_pkt_clear_event(mtk_crtc_state->cmdq_handle,
+mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(mtk_crtc_state->cmdq_handle, mtk_crtc->cmdq_event);
+}
+
+static void mtk_cmdq_release(struct drm_crtc *crtc,
+struct drm_crtc_state *old_crtc_state,
+drm_cmdq_cb cb)
+{
+   struct mtk_crtc_state *mtk_crtc_state =
+   to_mtk_crtc_state(crtc->state);
+   struct mtk_cmdq_cb_data *cb_data;
+
+   cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
+   if (!cb_data) {
+   DRM_DEV_ERROR(crtc->dev->dev, "Failed to alloc cb_data\n");
+   return;
+   }
+
+   cb_data->cmdq_handle = mtk_crtc_state->cmdq_handle;
+   cb_data->state = old_crtc_state;
+   cmdq_pkt_flush_async(mtk_crtc_state->cmdq_handle,
+cb, cb_data);
+}
+#endif
 static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 {
struct drm_crtc *crtc = _crtc->base;
@@ -371,7 +447,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-   struct 

[PATCH 0/7] drm/mediatek: fix cursor issue and apply CMDQ in

2019-11-25 Thread Bibby Hsieh
The CMDQ (Command Queue) in MT8183 is used to help update all
relevant display controller registers with critical time limation.
This patch add cmdq interface in ddp_comp interface, let all
ddp_comp interface can support cpu/cmdq function at the same time.

These patches also can fixup cursor moving is not smooth
when heavy load in webgl.

This patch depends on ptach:
add drm support for MT8183
(https://patchwork.kernel.org/cover/11121519/)
support gce on mt8183 platform
(https://patchwork.kernel.org/cover/11255147)
drm/mediatek: Refactor plane init/check and support rotation
(https://pw-emeril.freedesktop.org/series/69015/)
drm/mediatek: Check return value of mtk_drm_ddp_comp_for_plane
(https://lore.kernel.org/patchwork/patch/1154517/)

Bibby Hsieh (7):
  drm/mediatek: fix atomic_state reference counting
  drm/mediatek: put "event" in critical section
  drm/mediatek: use DRM core's atomic commit helper
  drm/mediatek: handle events when enabling/disabling crtc
  drm/mediatek: update cursors by using async atomic update
  drm/mediatek: support CMDQ interface in ddp component
  drm/mediatek: apply CMDQ control flow

 drivers/gpu/drm/mediatek/mtk_disp_color.c   |   7 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  65 +++---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  43 ++--
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 223 ++--
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 151 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  55 +++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 143 +++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  17 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c|  54 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|   2 +
 11 files changed, 575 insertions(+), 189 deletions(-)

-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/7] drm/mediatek: fix atomic_state reference counting

2019-11-25 Thread Bibby Hsieh
The DRM core takes care of all atomic state refcounting.
However, mediatek drm defers some work that accesses planes
and plane_states in drm_atomic_state, and must therefore
keep its own atomic state references until this work complete.

We take the atomic_state reference in atomic_fulsh() and ensure all the
information in atomic_state already was updated in hardware for
showing on screen and then schedules unreference_work to drop references
on atomic_state.

Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 11 +++-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 79 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  9 +++
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 29d0582e90e9..68b92adc96bb 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -7,7 +7,7 @@
 #include 
 
 #include 
-
+#include 
 #include 
 #include 
 #include 
@@ -47,6 +47,7 @@ struct mtk_drm_crtc {
struct mtk_disp_mutex   *mutex;
unsigned intddp_comp_nr;
struct mtk_ddp_comp **ddp_comp;
+   struct drm_crtc_state   *old_crtc_state;
 };
 
 struct mtk_crtc_state {
@@ -362,6 +363,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+   struct drm_atomic_state *atomic_state = mtk_crtc->old_crtc_state->state;
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
unsigned int i;
@@ -399,6 +401,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
plane_state->pending.config = false;
}
mtk_crtc->pending_planes = false;
+   mtk_atomic_state_put_queue(atomic_state);
}
 }
 
@@ -494,6 +497,7 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
  struct drm_crtc_state *old_crtc_state)
 {
+   struct drm_atomic_state *old_atomic_state = old_crtc_state->state;
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0;
@@ -512,8 +516,11 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
*crtc,
pending_planes |= BIT(i);
}
}
-   if (pending_planes)
+   if (pending_planes) {
mtk_crtc->pending_planes = true;
+   drm_atomic_state_get(old_atomic_state);
+   mtk_crtc->old_crtc_state = old_crtc_state;
+   }
if (crtc->state->color_mgmt_changed)
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6588dc6dd5e3..6c68283b6124 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -115,10 +115,85 @@ static int mtk_atomic_commit(struct drm_device *drm,
return 0;
 }
 
+struct mtk_atomic_state {
+   struct drm_atomic_state base;
+   struct list_head list;
+};
+
+static inline struct mtk_atomic_state *to_mtk_state(struct drm_atomic_state *s)
+{
+   return container_of(s, struct mtk_atomic_state, base);
+}
+
+void mtk_atomic_state_put_queue(struct drm_atomic_state *state)
+{
+   struct drm_device *drm = state->dev;
+   struct mtk_drm_private *mtk_drm = drm->dev_private;
+   struct mtk_atomic_state *mtk_state = to_mtk_state(state);
+   unsigned long flags;
+
+   spin_lock_irqsave(_drm->unreference.lock, flags);
+   list_add_tail(_state->list, _drm->unreference.list);
+   spin_unlock_irqrestore(_drm->unreference.lock, flags);
+
+   schedule_work(_drm->unreference.work);
+}
+
+static void mtk_unreference_work(struct work_struct *work)
+{
+   struct mtk_drm_private *mtk_drm = container_of(work,
+   struct mtk_drm_private, unreference.work);
+   unsigned long flags;
+   struct mtk_atomic_state *state, *tmp;
+
+   /*
+* framebuffers cannot be unreferenced in atomic context.
+* Therefore, only hold the spinlock when iterating unreference_list,
+* and drop it when doing the unreference.
+*/
+   spin_lock_irqsave(_drm->unreference.lock, flags);
+   list_for_each_entry_safe(state, tmp, _drm->unreference.list, list) {
+   list_del(>list);
+   spin_unlock_irqrestore(_drm->unreference.lock, flags);
+   

[PATCH 4/7] drm/mediatek: handle events when enabling/disabling crtc

2019-11-25 Thread Bibby Hsieh
The driver currently handles vblank events only when updating planes on
an already enabled CRTC. The atomic update API however allows requesting
an event when enabling or disabling a CRTC. This currently leads to
event objects being leaked in the kernel and to events not being sent
out. Fix it.

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index e38506d7a4e8..408a6d6a15ba 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -335,6 +335,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
*mtk_crtc)
 static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 {
struct drm_device *drm = mtk_crtc->base.dev;
+   struct drm_crtc *crtc = _crtc->base;
int i;
 
DRM_DEBUG_DRIVER("%s\n", __func__);
@@ -358,6 +359,13 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
mtk_disp_mutex_unprepare(mtk_crtc->mutex);
 
pm_runtime_put(drm->dev);
+
+   if (crtc->state->event && !crtc->state->active) {
+   spin_lock_irq(>dev->event_lock);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   crtc->state->event = NULL;
+   spin_unlock_irq(>dev->event_lock);
+   }
 }
 
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 3/7] drm/mediatek: use DRM core's atomic commit helper

2019-11-25 Thread Bibby Hsieh
The DRM core atomic helper now supports asynchronous commits natively.
The custom drm implementation isn't needed anymore, remove it.

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 92 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |  7 --
 2 files changed, 16 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6c68283b6124..97949dee2af0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -36,84 +36,25 @@
 #define DRIVER_MAJOR 1
 #define DRIVER_MINOR 0
 
-static void mtk_atomic_schedule(struct mtk_drm_private *private,
-   struct drm_atomic_state *state)
+static void mtk_drm_atomic_helper_commit_tail_rpm
+   (struct drm_atomic_state *old_state)
 {
-   private->commit.state = state;
-   schedule_work(>commit.work);
-}
-
-static void mtk_atomic_complete(struct mtk_drm_private *private,
-   struct drm_atomic_state *state)
-{
-   struct drm_device *drm = private->drm;
+   struct drm_device *dev = old_state->dev;
 
-   drm_atomic_helper_wait_for_fences(drm, state, false);
-
-   /*
-* Mediatek drm supports runtime PM, so plane registers cannot be
-* written when their crtc is disabled.
-*
-* The comment for drm_atomic_helper_commit states:
-* For drivers supporting runtime PM the recommended sequence is
-*
-* drm_atomic_helper_commit_modeset_disables(dev, state);
-* drm_atomic_helper_commit_modeset_enables(dev, state);
-* drm_atomic_helper_commit_planes(dev, state,
-* DRM_PLANE_COMMIT_ACTIVE_ONLY);
-*
-* See the kerneldoc entries for these three functions for more details.
-*/
-   drm_atomic_helper_commit_modeset_disables(drm, state);
-   drm_atomic_helper_commit_modeset_enables(drm, state);
-   drm_atomic_helper_commit_planes(drm, state,
+   drm_atomic_helper_wait_for_fences(dev, old_state, false);
+   drm_atomic_helper_commit_modeset_disables(dev, old_state);
+   drm_atomic_helper_commit_modeset_enables(dev, old_state);
+   drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
-   drm_atomic_helper_wait_for_vblanks(drm, state);
-
-   drm_atomic_helper_cleanup_planes(drm, state);
-   drm_atomic_state_put(state);
+   drm_atomic_helper_fake_vblank(old_state);
+   drm_atomic_helper_commit_hw_done(old_state);
+   drm_atomic_helper_wait_for_vblanks(dev, old_state);
+   drm_atomic_helper_cleanup_planes(dev, old_state);
 }
 
-static void mtk_atomic_work(struct work_struct *work)
-{
-   struct mtk_drm_private *private = container_of(work,
-   struct mtk_drm_private, commit.work);
-
-   mtk_atomic_complete(private, private->commit.state);
-}
-
-static int mtk_atomic_commit(struct drm_device *drm,
-struct drm_atomic_state *state,
-bool async)
-{
-   struct mtk_drm_private *private = drm->dev_private;
-   int ret;
-
-   ret = drm_atomic_helper_prepare_planes(drm, state);
-   if (ret)
-   return ret;
-
-   mutex_lock(>commit.lock);
-   flush_work(>commit.work);
-
-   ret = drm_atomic_helper_swap_state(state, true);
-   if (ret) {
-   mutex_unlock(>commit.lock);
-   drm_atomic_helper_cleanup_planes(drm, state);
-   return ret;
-   }
-
-   drm_atomic_state_get(state);
-   if (async)
-   mtk_atomic_schedule(private, state);
-   else
-   mtk_atomic_complete(private, state);
-
-   mutex_unlock(>commit.lock);
-
-   return 0;
-}
+static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = 
{
+   .atomic_commit_tail = mtk_drm_atomic_helper_commit_tail_rpm,
+};
 
 struct mtk_atomic_state {
struct drm_atomic_state base;
@@ -191,7 +132,7 @@ static void mtk_drm_atomic_state_free(struct 
drm_atomic_state *state)
 static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
.fb_create = mtk_drm_mode_fb_create,
.atomic_check = drm_atomic_helper_check,
-   .atomic_commit = mtk_atomic_commit,
+   .atomic_commit = drm_atomic_helper_commit,
.atomic_state_alloc = mtk_drm_atomic_state_alloc,
.atomic_state_free = mtk_drm_atomic_state_free
 };
@@ -340,6 +281,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
drm->mode_config.max_width = 4096;
drm->mode_config.max_height = 4096;
drm->mode_config.funcs = _drm_mode_config_funcs;
+   drm->mode_config.helper_private = _drm_mode_config_helpers;
 
ret = component_bind_all(drm->dev, drm);
if (ret)
@@ -619,8 +561,6 @@ static int 

[PATCH 2/7] drm/mediatek: put "event" in critical section

2019-11-25 Thread Bibby Hsieh
The state->base.event variable would be access by thread context
in mtk_drm_crtc_atomic_begin() or by interrupt context in
mtk_drm_crtc_finish_page_flip(), so each part should be a critical
section. Fix it.

Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 68b92adc96bb..e38506d7a4e8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -486,12 +486,15 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc 
*crtc,
if (mtk_crtc->event && state->base.event)
DRM_ERROR("new event while there is still a pending event\n");
 
+   spin_lock_irq(>dev->event_lock);
if (state->base.event) {
state->base.event->pipe = drm_crtc_index(crtc);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+   WARN_ON(mtk_crtc->event);
mtk_crtc->event = state->base.event;
state->base.event = NULL;
}
+   spin_unlock_irq(>dev->event_lock);
 }
 
 static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
-- 
2.18.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 5/7] drm/mediatek: update cursors by using async atomic update

2019-11-25 Thread Bibby Hsieh
Support to async updates of cursors by using the new atomic
interface for that.

Signed-off-by: Bibby Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 41 ++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h  |  3 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h   |  3 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 50 
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +
 6 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 408a6d6a15ba..c457591a176e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -41,7 +41,7 @@ struct mtk_drm_crtc {
struct drm_plane*planes;
unsigned intlayer_nr;
boolpending_planes;
-
+   boolcursor_update;
void __iomem*config_regs;
const struct mtk_mmsys_reg_data *mmsys_reg_data;
struct mtk_disp_mutex   *mutex;
@@ -409,7 +409,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
plane_state->pending.config = false;
}
mtk_crtc->pending_planes = false;
-   mtk_atomic_state_put_queue(atomic_state);
+   if (!mtk_crtc->cursor_update)
+   mtk_atomic_state_put_queue(atomic_state);
+   mtk_crtc->cursor_update = false;
}
 }
 
@@ -425,6 +427,41 @@ int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct 
drm_plane *plane,
return 0;
 }
 
+void mtk_drm_crtc_cursor_update(struct drm_crtc *crtc, struct drm_plane *plane,
+   struct drm_plane_state *new_state)
+{
+   struct mtk_drm_private *priv = crtc->dev->dev_private;
+   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+   const struct drm_plane_helper_funcs *plane_helper_funcs =
+   plane->helper_private;
+   int i;
+
+   if (!mtk_crtc->enabled)
+   return;
+
+   mutex_lock(>hw_lock);
+   plane_helper_funcs->atomic_update(plane, new_state);
+
+   for (i = 0; i < mtk_crtc->layer_nr; i++) {
+   struct drm_plane *plane = _crtc->planes[i];
+   struct mtk_plane_state *plane_state;
+
+   plane_state = to_mtk_plane_state(plane->state);
+   if (plane_state->pending.cursor_dirty) {
+   plane_state->pending.config = true;
+   plane_state->pending.cursor_update = false;
+   plane_state->pending.cursor_dirty = false;
+   }
+   }
+   mtk_crtc->pending_planes = true;
+   if (priv->data->shadow_register) {
+   mtk_disp_mutex_acquire(mtk_crtc->mutex);
+   mtk_crtc_ddp_config(crtc);
+   mtk_disp_mutex_release(mtk_crtc->mutex);
+   }
+   mutex_unlock(>hw_lock);
+}
+
 static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
   struct drm_crtc_state *old_state)
 {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 6afe1c19557a..42a3f650f564 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -22,4 +22,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 struct mtk_plane_state *state);
 
+void mtk_drm_crtc_cursor_update(struct drm_crtc *crtc, struct drm_plane *plane,
+   struct drm_plane_state *plane_state);
+
 #endif /* MTK_DRM_CRTC_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 97949dee2af0..3884a89a07e6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -40,12 +40,15 @@ static void mtk_drm_atomic_helper_commit_tail_rpm
(struct drm_atomic_state *old_state)
 {
struct drm_device *dev = old_state->dev;
+   struct mtk_drm_private *private = dev->dev_private;
 
drm_atomic_helper_wait_for_fences(dev, old_state, false);
+   mutex_lock(>hw_lock);
drm_atomic_helper_commit_modeset_disables(dev, old_state);
drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
+   mutex_unlock(>hw_lock);
drm_atomic_helper_fake_vblank(old_state);
drm_atomic_helper_commit_hw_done(old_state);
drm_atomic_helper_wait_for_vblanks(dev, old_state);
@@ -357,6 +360,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
INIT_WORK(>unreference.work, mtk_unreference_work);

[PATCH 3/5] udmabuf: add a pointer to the miscdevice in dma-buf private data

2019-11-25 Thread Gurchetan Singh
Will be used later.

v2: rename 'udmabuf_misc' to 'device' (kraxel)

Signed-off-by: Gurchetan Singh 
---
 drivers/dma-buf/udmabuf.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index ce9c9e4b..9e6fdd2bc979 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -19,6 +19,7 @@ struct udmabuf {
u32 flags;
pgoff_t pagecount;
struct page **pages;
+   struct miscdevice *device;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -127,8 +128,9 @@ static const struct dma_buf_ops udmabuf_ops = {
 #define SEALS_WANTED (F_SEAL_SHRINK)
 #define SEALS_DENIED (F_SEAL_WRITE)
 
-static long udmabuf_create(const struct udmabuf_create_list *head,
-  const struct udmabuf_create_item *list)
+static long udmabuf_create(struct miscdevice *device,
+  struct udmabuf_create_list *head,
+  struct udmabuf_create_item *list)
 {
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct file *memfd = NULL;
@@ -200,6 +202,8 @@ static long udmabuf_create(const struct udmabuf_create_list 
*head,
exp_info.flags = O_RDWR;
 
ubuf->flags = head->flags;
+   ubuf->device = device;
+
buf = dma_buf_export(_info);
if (IS_ERR(buf)) {
ret = PTR_ERR(buf);
@@ -237,7 +241,7 @@ static long udmabuf_ioctl_create(struct file *filp, 
unsigned long arg)
list.offset = create.offset;
list.size   = create.size;
 
-   return udmabuf_create(, );
+   return udmabuf_create(filp->private_data, , );
 }
 
 static long udmabuf_ioctl_create_list(struct file *filp, unsigned long arg)
@@ -256,7 +260,7 @@ static long udmabuf_ioctl_create_list(struct file *filp, 
unsigned long arg)
if (IS_ERR(list))
return PTR_ERR(list);
 
-   ret = udmabuf_create(, list);
+   ret = udmabuf_create(filp->private_data, , list);
kfree(list);
return ret;
 }
-- 
2.24.0.432.g9d3f5f5b63-goog

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/5] udmabuf: allow userspace to set map attributes

2019-11-25 Thread Gurchetan Singh
The main use for udmabuf is sending guest memory pages
to the host.

It's generally a bad idea to have to separate mappings with
different attributes. For example, a WC mapping the guest
kernel and cached mapping on the host is problematic.

v2: Cache attribute flags instead of read/write flags (kraxel@)
---
 drivers/dma-buf/udmabuf.c| 12 
 include/uapi/linux/udmabuf.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index b345e91d831a..ce9c9e4b 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -16,6 +16,7 @@ static const u32list_limit = 1024;  /* 
udmabuf_create_list->count limit */
 static const size_t size_limit_mb = 64; /* total dmabuf size, in megabytes  */
 
 struct udmabuf {
+   u32 flags;
pgoff_t pagecount;
struct page **pages;
 };
@@ -37,6 +38,12 @@ static const struct vm_operations_struct udmabuf_vm_ops = {
 static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
 {
struct udmabuf *ubuf = buf->priv;
+   pgprot_t pgprot = vm_get_page_prot(vma->vm_flags);
+
+   if (ubuf->flags & UDMABUF_FLAGS_WC)
+   vma->vm_page_prot = pgprot_writecombine(pgprot);
+   else if (ubuf->flags & UDMABUF_FLAGS_NONCACHED)
+   vma->vm_page_prot = pgprot_noncached(pgprot);
 
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
@@ -132,6 +139,10 @@ static long udmabuf_create(const struct 
udmabuf_create_list *head,
int seals, ret = -EINVAL;
u32 i, flags;
 
+   if ((head->flags & UDMABUF_FLAGS_NONCACHED) &&
+   (head->flags & UDMABUF_FLAGS_WC))
+   return -EINVAL;
+
ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
if (!ubuf)
return -ENOMEM;
@@ -188,6 +199,7 @@ static long udmabuf_create(const struct udmabuf_create_list 
*head,
exp_info.priv = ubuf;
exp_info.flags = O_RDWR;
 
+   ubuf->flags = head->flags;
buf = dma_buf_export(_info);
if (IS_ERR(buf)) {
ret = PTR_ERR(buf);
diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h
index 46b6532ed855..f90831f2bb0d 100644
--- a/include/uapi/linux/udmabuf.h
+++ b/include/uapi/linux/udmabuf.h
@@ -6,6 +6,8 @@
 #include 
 
 #define UDMABUF_FLAGS_CLOEXEC  0x01
+#define UDMABUF_FLAGS_WC   0x02
+#define UDMABUF_FLAGS_NONCACHED 0x04
 
 struct udmabuf_create {
__u32 memfd;
-- 
2.24.0.432.g9d3f5f5b63-goog

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/5] udmabuf: use cache_sgt_mapping option

2019-11-25 Thread Gurchetan Singh
The GEM prime helpers do it, so should we. It's also possible to make
it optional later.

Signed-off-by: Gurchetan Singh 
---
 drivers/dma-buf/udmabuf.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 9635897458a0..b345e91d831a 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -108,12 +108,13 @@ static void kunmap_udmabuf(struct dma_buf *buf, unsigned 
long page_num,
 }
 
 static const struct dma_buf_ops udmabuf_ops = {
-   .map_dma_buf  = map_udmabuf,
-   .unmap_dma_buf= unmap_udmabuf,
-   .release  = release_udmabuf,
-   .map  = kmap_udmabuf,
-   .unmap= kunmap_udmabuf,
-   .mmap = mmap_udmabuf,
+   .cache_sgt_mapping = true,
+   .map_dma_buf   = map_udmabuf,
+   .unmap_dma_buf = unmap_udmabuf,
+   .release   = release_udmabuf,
+   .map   = kmap_udmabuf,
+   .unmap = kunmap_udmabuf,
+   .mmap  = mmap_udmabuf,
 };
 
 #define SEALS_WANTED (F_SEAL_SHRINK)
-- 
2.24.0.432.g9d3f5f5b63-goog

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/5] udmabuf: separate out creating/destroying scatter-table

2019-11-25 Thread Gurchetan Singh
These are nice functions and can be re-used.

Signed-off-by: Gurchetan Singh 
---
 drivers/dma-buf/udmabuf.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 9e6fdd2bc979..67e89bb034c5 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -54,10 +54,10 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
return 0;
 }
 
-static struct sg_table *map_udmabuf(struct dma_buf_attachment *at,
-   enum dma_data_direction direction)
+static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
+enum dma_data_direction direction)
 {
-   struct udmabuf *ubuf = at->dmabuf->priv;
+   struct udmabuf *ubuf = buf->priv;
struct sg_table *sg;
int ret;
 
@@ -69,7 +69,7 @@ static struct sg_table *map_udmabuf(struct dma_buf_attachment 
*at,
GFP_KERNEL);
if (ret < 0)
goto err;
-   if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) {
+   if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
ret = -EINVAL;
goto err;
}
@@ -81,13 +81,25 @@ static struct sg_table *map_udmabuf(struct 
dma_buf_attachment *at,
return ERR_PTR(ret);
 }
 
+static void put_sg_table(struct device *dev, struct sg_table *sg,
+enum dma_data_direction direction)
+{
+   dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+   sg_free_table(sg);
+   kfree(sg);
+}
+
+static struct sg_table *map_udmabuf(struct dma_buf_attachment *at,
+   enum dma_data_direction direction)
+{
+   return get_sg_table(at->dev, at->dmabuf, direction);
+}
+
 static void unmap_udmabuf(struct dma_buf_attachment *at,
  struct sg_table *sg,
  enum dma_data_direction direction)
 {
-   dma_unmap_sg(at->dev, sg->sgl, sg->nents, direction);
-   sg_free_table(sg);
-   kfree(sg);
+   return put_sg_table(at->dev, sg, direction);
 }
 
 static void release_udmabuf(struct dma_buf *buf)
-- 
2.24.0.432.g9d3f5f5b63-goog

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 5/5] udmabuf: implement begin_cpu_access/end_cpu_access hooks

2019-11-25 Thread Gurchetan Singh
With the misc device, we should end up using the result of
get_arch_dma_ops(..) or dma-direct ops.

This can allow us to have WC mappings in the guest after
synchronization.

Signed-off-by: Gurchetan Singh 
---
 drivers/dma-buf/udmabuf.c | 40 +++
 1 file changed, 40 insertions(+)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 67e89bb034c5..142444922acd 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -19,6 +19,7 @@ struct udmabuf {
u32 flags;
pgoff_t pagecount;
struct page **pages;
+   struct sg_table *sg;
struct miscdevice *device;
 };
 
@@ -105,8 +106,12 @@ static void unmap_udmabuf(struct dma_buf_attachment *at,
 static void release_udmabuf(struct dma_buf *buf)
 {
struct udmabuf *ubuf = buf->priv;
+   struct device *dev = ubuf->device->this_device;
pgoff_t pg;
 
+   if (ubuf->sg)
+   put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
+
for (pg = 0; pg < ubuf->pagecount; pg++)
put_page(ubuf->pages[pg]);
kfree(ubuf->pages);
@@ -127,6 +132,39 @@ static void kunmap_udmabuf(struct dma_buf *buf, unsigned 
long page_num,
kunmap(vaddr);
 }
 
+static int begin_cpu_udmabuf(struct dma_buf *buf,
+enum dma_data_direction direction)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct device *dev = ubuf->device->this_device;
+
+   if (!ubuf->sg) {
+   ubuf->sg = get_sg_table(dev, buf, direction);
+   if (IS_ERR(ubuf->sg))
+   return PTR_ERR(ubuf->sg);
+   } else {
+   dma_sync_sg_for_device(dev, ubuf->sg->sgl,
+  ubuf->sg->nents,
+  direction);
+   }
+
+   return 0;
+}
+
+static int end_cpu_udmabuf(struct dma_buf *buf,
+  enum dma_data_direction direction)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct device *dev = ubuf->device->this_device;
+
+   if (!ubuf->sg)
+   return -EINVAL;
+
+   dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction);
+   return 0;
+}
+
+
 static const struct dma_buf_ops udmabuf_ops = {
.cache_sgt_mapping = true,
.map_dma_buf   = map_udmabuf,
@@ -135,6 +173,8 @@ static const struct dma_buf_ops udmabuf_ops = {
.map   = kmap_udmabuf,
.unmap = kunmap_udmabuf,
.mmap  = mmap_udmabuf,
+   .begin_cpu_access  = begin_cpu_udmabuf,
+   .end_cpu_access= end_cpu_udmabuf,
 };
 
 #define SEALS_WANTED (F_SEAL_SHRINK)
-- 
2.24.0.432.g9d3f5f5b63-goog

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 05/15] drm/armada: Delete dma_buf->k(un)map implemenation

2019-11-25 Thread Russell King - ARM Linux admin
On Mon, Nov 25, 2019 at 10:44:43PM +0100, Daniel Vetter wrote:
> On Mon, Nov 18, 2019 at 11:35:26AM +0100, Daniel Vetter wrote:
> > It's a dummy anyway.
> > 
> > Signed-off-by: Daniel Vetter 
> > Cc: Russell King 
> 
> I merged the entire series except this one and the final patch, sill
> waiting a bit more for an ack on this perhaps.

Acked-by: Russell King 

I thought drm trees closed around -rc6?

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/armada/armada_gem.c | 12 
> >  1 file changed, 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/armada/armada_gem.c 
> > b/drivers/gpu/drm/armada/armada_gem.c
> > index 93cf8b8bfcff..976685f2939e 100644
> > --- a/drivers/gpu/drm/armada/armada_gem.c
> > +++ b/drivers/gpu/drm/armada/armada_gem.c
> > @@ -461,16 +461,6 @@ static void armada_gem_prime_unmap_dma_buf(struct 
> > dma_buf_attachment *attach,
> > kfree(sgt);
> >  }
> >  
> > -static void *armada_gem_dmabuf_no_kmap(struct dma_buf *buf, unsigned long 
> > n)
> > -{
> > -   return NULL;
> > -}
> > -
> > -static void
> > -armada_gem_dmabuf_no_kunmap(struct dma_buf *buf, unsigned long n, void 
> > *addr)
> > -{
> > -}
> > -
> >  static int
> >  armada_gem_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
> >  {
> > @@ -481,8 +471,6 @@ static const struct dma_buf_ops 
> > armada_gem_prime_dmabuf_ops = {
> > .map_dma_buf= armada_gem_prime_map_dma_buf,
> > .unmap_dma_buf  = armada_gem_prime_unmap_dma_buf,
> > .release= drm_gem_dmabuf_release,
> > -   .map= armada_gem_dmabuf_no_kmap,
> > -   .unmap  = armada_gem_dmabuf_no_kunmap,
> > .mmap   = armada_gem_dmabuf_mmap,
> >  };
> >  
> > -- 
> > 2.24.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v4] drm/scheduler: Avoid accessing freed bad job.

2019-11-25 Thread Grodzovsky, Andrey
Christian asked to submit it to drm-misc instead of our drm-next to avoid later 
conflicts with Steven's patch which he mentioned in this thread which is not in 
drm-next yet.
Christian, Alex, once this merged to drm-misc I guess we need to pull all 
latest changes from there to drm-next so the issue Emily reported can be 
avoided.

Andrey


From: Deng, Emily 
Sent: 25 November 2019 16:44:36
To: Grodzovsky, Andrey
Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; Koenig, 
Christian; steven.pr...@arm.com; Grodzovsky, Andrey
Subject: RE: [PATCH v4] drm/scheduler: Avoid accessing freed bad job.

[AMD Official Use Only - Internal Distribution Only]

Hi Andrey,
Seems you didn't submit this patch?

Best wishes
Emily Deng



>-Original Message-
>From: Andrey Grodzovsky 
>Sent: Monday, November 25, 2019 12:51 PM
>Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; Koenig,
>Christian ; Deng, Emily
>; steven.pr...@arm.com; Grodzovsky, Andrey
>
>Subject: [PATCH v4] drm/scheduler: Avoid accessing freed bad job.
>
>Problem:
>Due to a race between drm_sched_cleanup_jobs in sched thread and
>drm_sched_job_timedout in timeout work there is a possiblity that bad job
>was already freed while still being accessed from the timeout thread.
>
>Fix:
>Instead of just peeking at the bad job in the mirror list remove it from the 
>list
>under lock and then put it back later when we are garanteed no race with
>main sched thread is possible which is after the thread is parked.
>
>v2: Lock around processing ring_mirror_list in drm_sched_cleanup_jobs.
>
>v3: Rebase on top of drm-misc-next. v2 is not needed anymore as
>drm_sched_get_cleanup_job already has a lock there.
>
>v4: Fix comments to relfect latest code in drm-misc.
>
>Signed-off-by: Andrey Grodzovsky 
>Reviewed-by: Christian König 
>Tested-by: Emily Deng 
>---
> drivers/gpu/drm/scheduler/sched_main.c | 27
>+++
> 1 file changed, 27 insertions(+)
>
>diff --git a/drivers/gpu/drm/scheduler/sched_main.c
>b/drivers/gpu/drm/scheduler/sched_main.c
>index 6774955..1bf9c40 100644
>--- a/drivers/gpu/drm/scheduler/sched_main.c
>+++ b/drivers/gpu/drm/scheduler/sched_main.c
>@@ -284,10 +284,21 @@ static void drm_sched_job_timedout(struct
>work_struct *work)
>   unsigned long flags;
>
>   sched = container_of(work, struct drm_gpu_scheduler,
>work_tdr.work);
>+
>+  /* Protects against concurrent deletion in
>drm_sched_get_cleanup_job */
>+  spin_lock_irqsave(>job_list_lock, flags);
>   job = list_first_entry_or_null(>ring_mirror_list,
>  struct drm_sched_job, node);
>
>   if (job) {
>+  /*
>+   * Remove the bad job so it cannot be freed by concurrent
>+   * drm_sched_cleanup_jobs. It will be reinserted back after
>sched->thread
>+   * is parked at which point it's safe.
>+   */
>+  list_del_init(>node);
>+  spin_unlock_irqrestore(>job_list_lock, flags);
>+
>   job->sched->ops->timedout_job(job);
>
>   /*
>@@ -298,6 +309,8 @@ static void drm_sched_job_timedout(struct
>work_struct *work)
>   job->sched->ops->free_job(job);
>   sched->free_guilty = false;
>   }
>+  } else {
>+  spin_unlock_irqrestore(>job_list_lock, flags);
>   }
>
>   spin_lock_irqsave(>job_list_lock, flags); @@ -370,6 +383,20
>@@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct
>drm_sched_job *bad)
>   kthread_park(sched->thread);
>
>   /*
>+   * Reinsert back the bad job here - now it's safe as
>+   * drm_sched_get_cleanup_job cannot race against us and release the
>+   * bad job at this point - we parked (waited for) any in progress
>+   * (earlier) cleanups and drm_sched_get_cleanup_job will not be
>called
>+   * now until the scheduler thread is unparked.
>+   */
>+  if (bad && bad->sched == sched)
>+  /*
>+   * Add at the head of the queue to reflect it was the earliest
>+   * job extracted.
>+   */
>+  list_add(>node, >ring_mirror_list);
>+
>+  /*
>* Iterate the job list from later to  earlier one and either deactive
>* their HW callbacks or remove them from mirror list if they already
>* signaled.
>--
>2.7.4
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 17/19] powerpc: book3s64: convert to pin_user_pages() and put_user_page()

2019-11-25 Thread John Hubbard
1. Convert from get_user_pages() to pin_user_pages().

2. As required by pin_user_pages(), release these pages via
put_user_page(). In this case, do so via put_user_pages_dirty_lock().

That has the side effect of calling set_page_dirty_lock(), instead
of set_page_dirty(). This is probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Cc: Jan Kara 
Signed-off-by: John Hubbard 
---
 arch/powerpc/mm/book3s64/iommu_api.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/iommu_api.c 
b/arch/powerpc/mm/book3s64/iommu_api.c
index 56cc84520577..fc1670a6fc3c 100644
--- a/arch/powerpc/mm/book3s64/iommu_api.c
+++ b/arch/powerpc/mm/book3s64/iommu_api.c
@@ -103,7 +103,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
for (entry = 0; entry < entries; entry += chunk) {
unsigned long n = min(entries - entry, chunk);
 
-   ret = get_user_pages(ua + (entry << PAGE_SHIFT), n,
+   ret = pin_user_pages(ua + (entry << PAGE_SHIFT), n,
FOLL_WRITE | FOLL_LONGTERM,
mem->hpages + entry, NULL);
if (ret == n) {
@@ -167,9 +167,8 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
return 0;
 
 free_exit:
-   /* free the reference taken */
-   for (i = 0; i < pinned; i++)
-   put_page(mem->hpages[i]);
+   /* free the references taken */
+   put_user_pages(mem->hpages, pinned);
 
vfree(mem->hpas);
kfree(mem);
@@ -212,10 +211,9 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (!page)
continue;
 
-   if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
-   SetPageDirty(page);
+   put_user_pages_dirty_lock(, 1,
+   mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
 
-   put_page(page);
mem->hpas[i] = 0;
}
 }
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 18/19] mm/gup_benchmark: use proper FOLL_WRITE flags instead of hard-coding "1"

2019-11-25 Thread John Hubbard
Fix the gup benchmark flags to use the symbolic FOLL_WRITE,
instead of a hard-coded "1" value.

Also, clean up the filtering of gup flags a little, by just doing
it once before issuing any of the get_user_pages*() calls. This
makes it harder to overlook, instead of having little "gup_flags & 1"
phrases in the function calls.

Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/gup_benchmark.c | 9 ++---
 tools/testing/selftests/vm/gup_benchmark.c | 6 +-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/mm/gup_benchmark.c b/mm/gup_benchmark.c
index 7dd602d7f8db..7fc44d25eca7 100644
--- a/mm/gup_benchmark.c
+++ b/mm/gup_benchmark.c
@@ -48,18 +48,21 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
nr = (next - addr) / PAGE_SIZE;
}
 
+   /* Filter out most gup flags: only allow a tiny subset here: */
+   gup->flags &= FOLL_WRITE;
+
switch (cmd) {
case GUP_FAST_BENCHMARK:
-   nr = get_user_pages_fast(addr, nr, gup->flags & 1,
+   nr = get_user_pages_fast(addr, nr, gup->flags,
 pages + i);
break;
case GUP_LONGTERM_BENCHMARK:
nr = get_user_pages(addr, nr,
-   (gup->flags & 1) | FOLL_LONGTERM,
+   gup->flags | FOLL_LONGTERM,
pages + i, NULL);
break;
case GUP_BENCHMARK:
-   nr = get_user_pages(addr, nr, gup->flags & 1, pages + i,
+   nr = get_user_pages(addr, nr, gup->flags, pages + i,
NULL);
break;
default:
diff --git a/tools/testing/selftests/vm/gup_benchmark.c 
b/tools/testing/selftests/vm/gup_benchmark.c
index 485cf06ef013..389327e9b30a 100644
--- a/tools/testing/selftests/vm/gup_benchmark.c
+++ b/tools/testing/selftests/vm/gup_benchmark.c
@@ -18,6 +18,9 @@
 #define GUP_LONGTERM_BENCHMARK _IOWR('g', 2, struct gup_benchmark)
 #define GUP_BENCHMARK  _IOWR('g', 3, struct gup_benchmark)
 
+/* Just the flags we need, copied from mm.h: */
+#define FOLL_WRITE 0x01/* check pte is writable */
+
 struct gup_benchmark {
__u64 get_delta_usec;
__u64 put_delta_usec;
@@ -85,7 +88,8 @@ int main(int argc, char **argv)
}
 
gup.nr_pages_per_call = nr_pages;
-   gup.flags = write;
+   if (write)
+   gup.flags |= FOLL_WRITE;
 
fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR);
if (fd == -1)
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 15/19] media/v4l2-core: pin_user_pages (FOLL_PIN) and put_user_page() conversion

2019-11-25 Thread John Hubbard
1. Change v4l2 from get_user_pages() to pin_user_pages().

2. Because all FOLL_PIN-acquired pages must be released via
put_user_page(), also convert the put_page() call over to
put_user_pages_dirty_lock().

Acked-by: Hans Verkuil 
Cc: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/media/v4l2-core/videobuf-dma-sg.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c 
b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 28262190c3ab..162a2633b1e3 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -183,12 +183,12 @@ static int videobuf_dma_init_user_locked(struct 
videobuf_dmabuf *dma,
dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
data, size, dma->nr_pages);
 
-   err = get_user_pages(data & PAGE_MASK, dma->nr_pages,
+   err = pin_user_pages(data & PAGE_MASK, dma->nr_pages,
 flags | FOLL_LONGTERM, dma->pages, NULL);
 
if (err != dma->nr_pages) {
dma->nr_pages = (err >= 0) ? err : 0;
-   dprintk(1, "get_user_pages: err=%d [%d]\n", err,
+   dprintk(1, "pin_user_pages: err=%d [%d]\n", err,
dma->nr_pages);
return err < 0 ? err : -EINVAL;
}
@@ -349,11 +349,8 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
BUG_ON(dma->sglen);
 
if (dma->pages) {
-   for (i = 0; i < dma->nr_pages; i++) {
-   if (dma->direction == DMA_FROM_DEVICE)
-   set_page_dirty_lock(dma->pages[i]);
-   put_page(dma->pages[i]);
-   }
+   put_user_pages_dirty_lock(dma->pages, dma->nr_pages,
+ dma->direction == DMA_FROM_DEVICE);
kfree(dma->pages);
dma->pages = NULL;
}
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 16/19] vfio, mm: pin_user_pages (FOLL_PIN) and put_user_page() conversion

2019-11-25 Thread John Hubbard
1. Change vfio from get_user_pages_remote(), to
pin_user_pages_remote().

2. Because all FOLL_PIN-acquired pages must be released via
put_user_page(), also convert the put_page() call over to
put_user_pages_dirty_lock().

Note that this effectively changes the code's behavior in
vfio_iommu_type1.c: put_pfn(): it now ultimately calls
set_page_dirty_lock(), instead of set_page_dirty(). This is
probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Signed-off-by: John Hubbard 
---
 drivers/vfio/vfio_iommu_type1.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index b800fc9a0251..18bfc2fc8e6d 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -309,9 +309,8 @@ static int put_pfn(unsigned long pfn, int prot)
 {
if (!is_invalid_reserved_pfn(pfn)) {
struct page *page = pfn_to_page(pfn);
-   if (prot & IOMMU_WRITE)
-   SetPageDirty(page);
-   put_page(page);
+
+   put_user_pages_dirty_lock(, 1, prot & IOMMU_WRITE);
return 1;
}
return 0;
@@ -329,7 +328,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
flags |= FOLL_WRITE;
 
down_read(>mmap_sem);
-   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
+   ret = pin_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
page, NULL, NULL);
if (ret == 1) {
*pfn = page_to_pfn(page[0]);
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 19/19] mm, tree-wide: rename put_user_page*() to unpin_user_page*()

2019-11-25 Thread John Hubbard
In order to provide a clearer, more symmetric API for pinning
and unpinning DMA pages. This way, pin_user_pages*() calls
match up with unpin_user_pages*() calls, and the API is a lot
closer to being self-explanatory.

Reviewed-by: Jan Kara 
Signed-off-by: John Hubbard 
---
 Documentation/core-api/pin_user_pages.rst   |  2 +-
 arch/powerpc/mm/book3s64/iommu_api.c|  4 +--
 drivers/gpu/drm/via/via_dmablit.c   |  4 +--
 drivers/infiniband/core/umem.c  |  2 +-
 drivers/infiniband/hw/hfi1/user_pages.c |  2 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c |  6 ++--
 drivers/infiniband/hw/qib/qib_user_pages.c  |  2 +-
 drivers/infiniband/hw/qib/qib_user_sdma.c   |  6 ++--
 drivers/infiniband/hw/usnic/usnic_uiom.c|  2 +-
 drivers/infiniband/sw/siw/siw_mem.c |  2 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c   |  4 +--
 drivers/platform/goldfish/goldfish_pipe.c   |  4 +--
 drivers/vfio/vfio_iommu_type1.c |  2 +-
 fs/io_uring.c   |  4 +--
 include/linux/mm.h  | 26 -
 mm/gup.c| 32 ++---
 mm/process_vm_access.c  |  4 +--
 net/xdp/xdp_umem.c  |  2 +-
 18 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
index 4f26637a5005..bba96428ade7 100644
--- a/Documentation/core-api/pin_user_pages.rst
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -220,7 +220,7 @@ since the system was booted, via two new /proc/vmstat 
entries: ::
 /proc/vmstat/nr_foll_pin_requested
 
 Those are both going to show zero, unless CONFIG_DEBUG_VM is set. This is
-because there is a noticeable performance drop in put_user_page(), when they
+because there is a noticeable performance drop in unpin_user_page(), when they
 are activated.
 
 References
diff --git a/arch/powerpc/mm/book3s64/iommu_api.c 
b/arch/powerpc/mm/book3s64/iommu_api.c
index fc1670a6fc3c..b965a0dfd4a2 100644
--- a/arch/powerpc/mm/book3s64/iommu_api.c
+++ b/arch/powerpc/mm/book3s64/iommu_api.c
@@ -168,7 +168,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, 
unsigned long ua,
 
 free_exit:
/* free the references taken */
-   put_user_pages(mem->hpages, pinned);
+   unpin_user_pages(mem->hpages, pinned);
 
vfree(mem->hpas);
kfree(mem);
@@ -211,7 +211,7 @@ static void mm_iommu_unpin(struct 
mm_iommu_table_group_mem_t *mem)
if (!page)
continue;
 
-   put_user_pages_dirty_lock(, 1,
+   unpin_user_pages_dirty_lock(, 1,
mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
 
mem->hpas[i] = 0;
diff --git a/drivers/gpu/drm/via/via_dmablit.c 
b/drivers/gpu/drm/via/via_dmablit.c
index 37c5e572993a..719d036c9384 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -188,8 +188,8 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t 
*vsg)
kfree(vsg->desc_pages);
/* fall through */
case dr_via_pages_locked:
-   put_user_pages_dirty_lock(vsg->pages, vsg->num_pages,
- (vsg->direction == DMA_FROM_DEVICE));
+   unpin_user_pages_dirty_lock(vsg->pages, vsg->num_pages,
+  (vsg->direction == DMA_FROM_DEVICE));
/* fall through */
case dr_via_pages_alloc:
vfree(vsg->pages);
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 39a1542e6707..663b5c785716 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -54,7 +54,7 @@ static void __ib_umem_release(struct ib_device *dev, struct 
ib_umem *umem, int d
 
for_each_sg_page(umem->sg_head.sgl, _iter, umem->sg_nents, 0) {
page = sg_page_iter_page(_iter);
-   put_user_pages_dirty_lock(, 1, umem->writable && dirty);
+   unpin_user_pages_dirty_lock(, 1, umem->writable && dirty);
}
 
sg_free_table(>sg_head);
diff --git a/drivers/infiniband/hw/hfi1/user_pages.c 
b/drivers/infiniband/hw/hfi1/user_pages.c
index 9a94761765c0..3b505006c0a6 100644
--- a/drivers/infiniband/hw/hfi1/user_pages.c
+++ b/drivers/infiniband/hw/hfi1/user_pages.c
@@ -118,7 +118,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned 
long vaddr, size_t np
 void hfi1_release_user_pages(struct mm_struct *mm, struct page **p,
 size_t npages, bool dirty)
 {
-   put_user_pages_dirty_lock(p, npages, dirty);
+   unpin_user_pages_dirty_lock(p, npages, dirty);
 
if (mm) { /* during close after signal, mm can be NULL */
atomic64_sub(npages, >pinned_vm);
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c 

[PATCH v2 01/19] mm/gup: factor out duplicate code from four routines

2019-11-25 Thread John Hubbard
There are four locations in gup.c that have a fair amount of code
duplication. This means that changing one requires making the same
changes in four places, not to mention reading the same code four
times, and wondering if there are subtle differences.

Factor out the common code into static functions, thus reducing the
overall line count and the code's complexity.

Also, take the opportunity to slightly improve the efficiency of the
error cases, by doing a mass subtraction of the refcount, surrounded
by get_page()/put_page().

Also, further simplify (slightly), by waiting until the the successful
end of each routine, to increment *nr.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Jan Kara 
Cc: Ira Weiny 
Cc: Christoph Hellwig 
Cc: Aneesh Kumar K.V 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 91 ++--
 1 file changed, 36 insertions(+), 55 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 7646bf993b25..f764432914c4 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1978,6 +1978,25 @@ static int __gup_device_huge_pud(pud_t pud, pud_t *pudp, 
unsigned long addr,
 }
 #endif
 
+static int record_subpages(struct page *page, unsigned long addr,
+  unsigned long end, struct page **pages)
+{
+   int nr;
+
+   for (nr = 0; addr != end; addr += PAGE_SIZE)
+   pages[nr++] = page++;
+
+   return nr;
+}
+
+static void put_compound_head(struct page *page, int refs)
+{
+   /* Do a get_page() first, in case refs == page->_refcount */
+   get_page(page);
+   page_ref_sub(page, refs);
+   put_page(page);
+}
+
 #ifdef CONFIG_ARCH_HAS_HUGEPD
 static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
  unsigned long sz)
@@ -2007,32 +2026,20 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, 
unsigned long addr,
/* hugepages are never "special" */
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-   refs = 0;
head = pte_page(pte);
-
page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
-   do {
-   VM_BUG_ON(compound_head(page) != head);
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(head, refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pte_val(pte) != pte_val(*ptep))) {
-   /* Could be optimized better */
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2079,28 +2086,19 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, 
unsigned long addr,
return __gup_device_huge_pmd(orig, pmdp, addr, end, pages, nr);
}
 
-   refs = 0;
page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
-   do {
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(pmd_page(orig), refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2120,28 +2118,19 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, 
unsigned long addr,
return __gup_device_huge_pud(orig, pudp, addr, end, pages, nr);
}
 
-   refs = 0;
page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
-   do {
-   pages[*nr] = page;
-   (*nr)++;
-   page++;
-   refs++;
-   } while (addr += PAGE_SIZE, addr != end);
+   refs = record_subpages(page, addr, end, pages + *nr);
 
head = try_get_compound_head(pud_page(orig), refs);
-   if (!head) {
-   *nr -= refs;
+   if (!head)
return 0;
-   }
 
if (unlikely(pud_val(orig) != pud_val(*pudp))) {
-   *nr -= refs;
-   while (refs--)
-   put_page(head);
+   put_compound_head(head, refs);
return 0;
}
 
+   *nr += refs;
SetPageReferenced(head);
return 1;
 }
@@ -2157,28 +2146,20 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, 
unsigned long 

[PATCH v2 03/19] mm: Cleanup __put_devmap_managed_page() vs ->page_free()

2019-11-25 Thread John Hubbard
From: Dan Williams 

After the removal of the device-public infrastructure there are only 2
->page_free() call backs in the kernel. One of those is a device-private
callback in the nouveau driver, the other is a generic wakeup needed in
the DAX case. In the hopes that all ->page_free() callbacks can be
migrated to common core kernel functionality, move the device-private
specific actions in __put_devmap_managed_page() under the
is_device_private_page() conditional, including the ->page_free()
callback. For the other page types just open-code the generic wakeup.

Yes, the wakeup is only needed in the MEMORY_DEVICE_FSDAX case, but it
does no harm in the MEMORY_DEVICE_DEVDAX and MEMORY_DEVICE_PCI_P2PDMA
case.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jérôme Glisse 
Cc: Jan Kara 
Cc: Ira Weiny 
Signed-off-by: Dan Williams 
Signed-off-by: John Hubbard 
---
 drivers/nvdimm/pmem.c |  6 
 mm/memremap.c | 80 ---
 2 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index ad8e4df1282b..4eae441f86c9 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -337,13 +337,7 @@ static void pmem_release_disk(void *__pmem)
put_disk(pmem->disk);
 }
 
-static void pmem_pagemap_page_free(struct page *page)
-{
-   wake_up_var(>_refcount);
-}
-
 static const struct dev_pagemap_ops fsdax_pagemap_ops = {
-   .page_free  = pmem_pagemap_page_free,
.kill   = pmem_pagemap_kill,
.cleanup= pmem_pagemap_cleanup,
 };
diff --git a/mm/memremap.c b/mm/memremap.c
index 022e78e68ea0..e1678e575d9f 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -27,7 +27,8 @@ static void devmap_managed_enable_put(void)
 
 static int devmap_managed_enable_get(struct dev_pagemap *pgmap)
 {
-   if (!pgmap->ops || !pgmap->ops->page_free) {
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE &&
+   (!pgmap->ops || !pgmap->ops->page_free)) {
WARN(1, "Missing page_free method\n");
return -EINVAL;
}
@@ -444,44 +445,51 @@ void __put_devmap_managed_page(struct page *page)
 {
int count = page_ref_dec_return(page);
 
-   /*
-* If refcount is 1 then page is freed and refcount is stable as nobody
-* holds a reference on the page.
-*/
-   if (count == 1) {
-   /* Clear Active bit in case of parallel mark_page_accessed */
-   __ClearPageActive(page);
-   __ClearPageWaiters(page);
+   /* still busy */
+   if (count > 1)
+   return;
 
-   mem_cgroup_uncharge(page);
+   /* only triggered by the dev_pagemap shutdown path */
+   if (count == 0) {
+   __put_page(page);
+   return;
+   }
 
-   /*
-* When a device_private page is freed, the page->mapping field
-* may still contain a (stale) mapping value. For example, the
-* lower bits of page->mapping may still identify the page as
-* an anonymous page. Ultimately, this entire field is just
-* stale and wrong, and it will cause errors if not cleared.
-* One example is:
-*
-*  migrate_vma_pages()
-*migrate_vma_insert_page()
-*  page_add_new_anon_rmap()
-*__page_set_anon_rmap()
-*  ...checks page->mapping, via PageAnon(page) call,
-*and incorrectly concludes that the page is an
-*anonymous page. Therefore, it incorrectly,
-*silently fails to set up the new anon rmap.
-*
-* For other types of ZONE_DEVICE pages, migration is either
-* handled differently or not done at all, so there is no need
-* to clear page->mapping.
-*/
-   if (is_device_private_page(page))
-   page->mapping = NULL;
+   /* notify page idle for dax */
+   if (!is_device_private_page(page)) {
+   wake_up_var(>_refcount);
+   return;
+   }
 
-   page->pgmap->ops->page_free(page);
-   } else if (!count)
-   __put_page(page);
+   /* Clear Active bit in case of parallel mark_page_accessed */
+   __ClearPageActive(page);
+   __ClearPageWaiters(page);
+
+   mem_cgroup_uncharge(page);
+
+   /*
+* When a device_private page is freed, the page->mapping field
+* may still contain a (stale) mapping value. For example, the
+* lower bits of page->mapping may still identify the page as an
+* anonymous page. Ultimately, this entire field is just stale
+* and wrong, and it will cause errors if not cleared.  One
+* example is:
+*
+*  

[PATCH v2 05/19] mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM

2019-11-25 Thread John Hubbard
As it says in the updated comment in gup.c: current FOLL_LONGTERM
behavior is incompatible with FAULT_FLAG_ALLOW_RETRY because of the
FS DAX check requirement on vmas.

However, the corresponding restriction in get_user_pages_remote() was
slightly stricter than is actually required: it forbade all
FOLL_LONGTERM callers, but we can actually allow FOLL_LONGTERM callers
that do not set the "locked" arg.

Update the code and comments to loosen the restriction, allowing
FOLL_LONGTERM in some cases.

Also, copy the DAX check ("if a VMA is DAX, don't allow long term
pinning") from the VFIO call site, all the way into the internals
of get_user_pages_remote() and __gup_longterm_locked(). That is:
get_user_pages_remote() calls __gup_longterm_locked(), which in turn
calls check_dax_vmas(). This check will then be removed from the VFIO
call site in a subsequent patch.

Thanks to Jason Gunthorpe for pointing out a clean way to fix this,
and to Dan Williams for helping clarify the DAX refactoring.

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Ira Weiny 
Suggested-by: Jason Gunthorpe 
Cc: Dan Williams 
Cc: Jerome Glisse 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 3ecce297a47f..c0c56888e7cc 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -29,6 +29,13 @@ struct follow_page_context {
unsigned int page_mask;
 };
 
+static __always_inline long __gup_longterm_locked(struct task_struct *tsk,
+ struct mm_struct *mm,
+ unsigned long start,
+ unsigned long nr_pages,
+ struct page **pages,
+ struct vm_area_struct **vmas,
+ unsigned int flags);
 /*
  * Return the compound head page with ref appropriately incremented,
  * or NULL if that failed.
@@ -1179,13 +1186,23 @@ long get_user_pages_remote(struct task_struct *tsk, 
struct mm_struct *mm,
struct vm_area_struct **vmas, int *locked)
 {
/*
-* FIXME: Current FOLL_LONGTERM behavior is incompatible with
+* Parts of FOLL_LONGTERM behavior are incompatible with
 * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on
-* vmas.  As there are no users of this flag in this call we simply
-* disallow this option for now.
+* vmas. However, this only comes up if locked is set, and there are
+* callers that do request FOLL_LONGTERM, but do not set locked. So,
+* allow what we can.
 */
-   if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM))
-   return -EINVAL;
+   if (gup_flags & FOLL_LONGTERM) {
+   if (WARN_ON_ONCE(locked))
+   return -EINVAL;
+   /*
+* This will check the vmas (even if our vmas arg is NULL)
+* and return -ENOTSUPP if DAX isn't allowed in this case:
+*/
+   return __gup_longterm_locked(tsk, mm, start, nr_pages, pages,
+vmas, gup_flags | FOLL_TOUCH |
+FOLL_REMOTE);
+   }
 
return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas,
   locked,
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 13/19] net/xdp: set FOLL_PIN via pin_user_pages()

2019-11-25 Thread John Hubbard
Convert net/xdp to use the new pin_longterm_pages() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages.

In partial anticipation of this work, the net/xdp code was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
here is to change get_user_pages() to pin_user_pages().

Acked-by: Björn Töpel 
Signed-off-by: John Hubbard 
---
 net/xdp/xdp_umem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
index 3049af269fbf..d071003b5e76 100644
--- a/net/xdp/xdp_umem.c
+++ b/net/xdp/xdp_umem.c
@@ -291,7 +291,7 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
return -ENOMEM;
 
down_read(>mm->mmap_sem);
-   npgs = get_user_pages(umem->address, umem->npgs,
+   npgs = pin_user_pages(umem->address, umem->npgs,
  gup_flags | FOLL_LONGTERM, >pgs[0], NULL);
up_read(>mm->mmap_sem);
 
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN

2019-11-25 Thread John Hubbard
Introduce pin_user_pages*() variations of get_user_pages*() calls,
and also pin_longterm_pages*() variations.

For now, these are placeholder calls, until the various call sites
are converted to use the correct get_user_pages*() or
pin_user_pages*() API.

These variants will eventually all set FOLL_PIN, which is also
introduced, and thoroughly documented.

pin_user_pages()
pin_user_pages_remote()
pin_user_pages_fast()

All pages that are pinned via the above calls, must be unpinned via
put_user_page().

The underlying rules are:

* FOLL_PIN is a gup-internal flag, so the call sites should not directly
set it. That behavior is enforced with assertions.

* Call sites that want to indicate that they are going to do DirectIO
  ("DIO") or something with similar characteristics, should call a
  get_user_pages()-like wrapper call that sets FOLL_PIN. These wrappers
  will:
* Start with "pin_user_pages" instead of "get_user_pages". That
  makes it easy to find and audit the call sites.
* Set FOLL_PIN

* For pages that are received via FOLL_PIN, those pages must be returned
  via put_user_page().

Thanks to Jan Kara and Vlastimil Babka for explaining the 4 cases
in this documentation. (I've reworded it and expanded upon it.)

Reviewed-by: Jan Kara 
Reviewed-by: Mike Rapoport   # Documentation
Reviewed-by: Jérôme Glisse 
Cc: Jonathan Corbet 
Cc: Ira Weiny 
Signed-off-by: John Hubbard 
---
 Documentation/core-api/index.rst  |   1 +
 Documentation/core-api/pin_user_pages.rst | 233 ++
 include/linux/mm.h|  63 --
 mm/gup.c  | 161 +--
 4 files changed, 424 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/core-api/pin_user_pages.rst

diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index ab0eae1c153a..413f7d7c8642 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -31,6 +31,7 @@ Core utilities
generic-radix-tree
memory-allocation
mm-api
+   pin_user_pages
gfp_mask-from-fs-io
timekeeping
boot-time-mm
diff --git a/Documentation/core-api/pin_user_pages.rst 
b/Documentation/core-api/pin_user_pages.rst
new file mode 100644
index ..4f26637a5005
--- /dev/null
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -0,0 +1,233 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+
+pin_user_pages() and related calls
+
+
+.. contents:: :local:
+
+Overview
+
+
+This document describes the following functions: ::
+
+ pin_user_pages
+ pin_user_pages_fast
+ pin_user_pages_remote
+
+Basic description of FOLL_PIN
+=
+
+FOLL_PIN and FOLL_LONGTERM are flags that can be passed to the 
get_user_pages*()
+("gup") family of functions. FOLL_PIN has significant interactions and
+interdependencies with FOLL_LONGTERM, so both are covered here.
+
+FOLL_PIN is internal to gup, meaning that it should not appear at the gup call
+sites. This allows the associated wrapper functions  (pin_user_pages*() and
+others) to set the correct combination of these flags, and to check for 
problems
+as well.
+
+FOLL_LONGTERM, on the other hand, *is* allowed to be set at the gup call sites.
+This is in order to avoid creating a large number of wrapper functions to cover
+all combinations of get*(), pin*(), FOLL_LONGTERM, and more. Also, the
+pin_user_pages*() APIs are clearly distinct from the get_user_pages*() APIs, so
+that's a natural dividing line, and a good point to make separate wrapper 
calls.
+In other words, use pin_user_pages*() for DMA-pinned pages, and
+get_user_pages*() for other cases. There are four cases described later on in
+this document, to further clarify that concept.
+
+FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However,
+multiple threads and call sites are free to pin the same struct pages, via both
+FOLL_PIN and FOLL_GET. It's just the call site that needs to choose one or the
+other, not the struct page(s).
+
+The FOLL_PIN implementation is nearly the same as FOLL_GET, except that 
FOLL_PIN
+uses a different reference counting technique.
+
+FOLL_PIN is a prerequisite to FOLL_LONGTGERM. Another way of saying that is,
+FOLL_LONGTERM is a specific case, more restrictive case of FOLL_PIN.
+
+Which flags are set by each wrapper
+===
+
+For these pin_user_pages*() functions, FOLL_PIN is OR'd in with whatever gup
+flags the caller provides. The caller is required to pass in a non-null struct
+pages* array, and the function then pin pages by incrementing each by a special
+value. For now, that value is +1, just like get_user_pages*().::
+
+ Function
+ 
+ pin_user_pages  FOLL_PIN is always set internally by this function.
+ pin_user_pages_fast FOLL_PIN is always set internally by this function.
+ 

[PATCH v2 11/19] drm/via: set FOLL_PIN via pin_user_pages_fast()

2019-11-25 Thread John Hubbard
Convert drm/via to use the new pin_user_pages_fast() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages, and therefore for any code that calls
put_user_page().

In partial anticipation of this work, the drm/via driver was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
is to change get_user_pages() to pin_user_pages().

Acked-by: Daniel Vetter 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/gpu/drm/via/via_dmablit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/via/via_dmablit.c 
b/drivers/gpu/drm/via/via_dmablit.c
index 3db000aacd26..37c5e572993a 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -239,7 +239,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  
drm_via_dmablit_t *xfer)
vsg->pages = vzalloc(array_size(sizeof(struct page *), vsg->num_pages));
if (NULL == vsg->pages)
return -ENOMEM;
-   ret = get_user_pages_fast((unsigned long)xfer->mem_addr,
+   ret = pin_user_pages_fast((unsigned long)xfer->mem_addr,
vsg->num_pages,
vsg->direction == DMA_FROM_DEVICE ? FOLL_WRITE : 0,
vsg->pages);
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 14/19] media/v4l2-core: set pages dirty upon releasing DMA buffers

2019-11-25 Thread John Hubbard
After DMA is complete, and the device and CPU caches are synchronized,
it's still required to mark the CPU pages as dirty, if the data was
coming from the device. However, this driver was just issuing a
bare put_page() call, without any set_page_dirty*() call.

Fix the problem, by calling set_page_dirty_lock() if the CPU pages
were potentially receiving data from the device.

Reviewed-by: Christoph Hellwig 
Acked-by: Hans Verkuil 
Cc: Mauro Carvalho Chehab 
Cc: 
Signed-off-by: John Hubbard 
---
 drivers/media/v4l2-core/videobuf-dma-sg.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c 
b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 66a6c6c236a7..28262190c3ab 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -349,8 +349,11 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
BUG_ON(dma->sglen);
 
if (dma->pages) {
-   for (i = 0; i < dma->nr_pages; i++)
+   for (i = 0; i < dma->nr_pages; i++) {
+   if (dma->direction == DMA_FROM_DEVICE)
+   set_page_dirty_lock(dma->pages[i]);
put_page(dma->pages[i]);
+   }
kfree(dma->pages);
dma->pages = NULL;
}
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 09/19] IB/{core, hw, umem}: set FOLL_PIN via pin_user_pages*(), fix up ODP

2019-11-25 Thread John Hubbard
Convert infiniband to use the new pin_user_pages*() calls.

Also, revert earlier changes to Infiniband ODP that had it using
put_user_page(). ODP is "Case 3" in
Documentation/core-api/pin_user_pages.rst, which is to say, normal
get_user_pages() and put_page() is the API to use there.

The new pin_user_pages*() calls replace corresponding get_user_pages*()
calls, and set the FOLL_PIN flag. The FOLL_PIN flag requires that the
caller must return the pages via put_user_page*() calls, but infiniband
was already doing that as part of an earlier commit.

Reviewed-by: Jason Gunthorpe 
Signed-off-by: John Hubbard 
---
 drivers/infiniband/core/umem.c  |  2 +-
 drivers/infiniband/core/umem_odp.c  | 13 ++---
 drivers/infiniband/hw/hfi1/user_pages.c |  2 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c |  2 +-
 drivers/infiniband/hw/qib/qib_user_pages.c  |  2 +-
 drivers/infiniband/hw/qib/qib_user_sdma.c   |  2 +-
 drivers/infiniband/hw/usnic/usnic_uiom.c|  2 +-
 drivers/infiniband/sw/siw/siw_mem.c |  2 +-
 8 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 7a3b99597ead..39a1542e6707 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -267,7 +267,7 @@ struct ib_umem *ib_umem_get(struct ib_udata *udata, 
unsigned long addr,
 
while (npages) {
down_read(>mmap_sem);
-   ret = get_user_pages(cur_base,
+   ret = pin_user_pages(cur_base,
 min_t(unsigned long, npages,
   PAGE_SIZE / sizeof (struct page *)),
 gup_flags | FOLL_LONGTERM,
diff --git a/drivers/infiniband/core/umem_odp.c 
b/drivers/infiniband/core/umem_odp.c
index e42d44e501fd..abc3bb6578cc 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -308,9 +308,8 @@ EXPORT_SYMBOL(ib_umem_odp_release);
  * The function returns -EFAULT if the DMA mapping operation fails. It returns
  * -EAGAIN if a concurrent invalidation prevents us from updating the page.
  *
- * The page is released via put_user_page even if the operation failed. For
- * on-demand pinning, the page is released whenever it isn't stored in the
- * umem.
+ * The page is released via put_page even if the operation failed. For 
on-demand
+ * pinning, the page is released whenever it isn't stored in the umem.
  */
 static int ib_umem_odp_map_dma_single_page(
struct ib_umem_odp *umem_odp,
@@ -363,7 +362,7 @@ static int ib_umem_odp_map_dma_single_page(
}
 
 out:
-   put_user_page(page);
+   put_page(page);
return ret;
 }
 
@@ -473,7 +472,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, 
u64 user_virt,
ret = -EFAULT;
break;
}
-   put_user_page(local_page_list[j]);
+   put_page(local_page_list[j]);
continue;
}
 
@@ -500,8 +499,8 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, 
u64 user_virt,
 * ib_umem_odp_map_dma_single_page().
 */
if (npages - (j + 1) > 0)
-   put_user_pages(_page_list[j+1],
-  npages - (j + 1));
+   release_pages(_page_list[j+1],
+ npages - (j + 1));
break;
}
}
diff --git a/drivers/infiniband/hw/hfi1/user_pages.c 
b/drivers/infiniband/hw/hfi1/user_pages.c
index 469acb961fbd..9a94761765c0 100644
--- a/drivers/infiniband/hw/hfi1/user_pages.c
+++ b/drivers/infiniband/hw/hfi1/user_pages.c
@@ -106,7 +106,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned 
long vaddr, size_t np
int ret;
unsigned int gup_flags = FOLL_LONGTERM | (writable ? FOLL_WRITE : 0);
 
-   ret = get_user_pages_fast(vaddr, npages, gup_flags, pages);
+   ret = pin_user_pages_fast(vaddr, npages, gup_flags, pages);
if (ret < 0)
return ret;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c 
b/drivers/infiniband/hw/mthca/mthca_memfree.c
index edccfd6e178f..8269ab040c21 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -472,7 +472,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct 
mthca_uar *uar,
goto out;
}
 
-   ret = get_user_pages_fast(uaddr & PAGE_MASK, 1,
+   ret = pin_user_pages_fast(uaddr & PAGE_MASK, 1,
  FOLL_WRITE | FOLL_LONGTERM, pages);
if (ret < 0)
goto out;
diff --git 

[PATCH v2 02/19] mm/gup: move try_get_compound_head() to top, fix minor issues

2019-11-25 Thread John Hubbard
An upcoming patch uses try_get_compound_head() more widely,
so move it to the top of gup.c.

Also fix a tiny spelling error and a checkpatch.pl warning.

Reviewed-by: Christoph Hellwig 
Reviewed-by: Jan Kara 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/gup.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index f764432914c4..3ecce297a47f 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -29,6 +29,21 @@ struct follow_page_context {
unsigned int page_mask;
 };
 
+/*
+ * Return the compound head page with ref appropriately incremented,
+ * or NULL if that failed.
+ */
+static inline struct page *try_get_compound_head(struct page *page, int refs)
+{
+   struct page *head = compound_head(page);
+
+   if (WARN_ON_ONCE(page_ref_count(head) < 0))
+   return NULL;
+   if (unlikely(!page_cache_add_speculative(head, refs)))
+   return NULL;
+   return head;
+}
+
 /**
  * put_user_pages_dirty_lock() - release and optionally dirty gup-pinned pages
  * @pages:  array of pages to be maybe marked dirty, and definitely released.
@@ -1807,20 +1822,6 @@ static void __maybe_unused undo_dev_pagemap(int *nr, int 
nr_start,
}
 }
 
-/*
- * Return the compund head page with ref appropriately incremented,
- * or NULL if that failed.
- */
-static inline struct page *try_get_compound_head(struct page *page, int refs)
-{
-   struct page *head = compound_head(page);
-   if (WARN_ON_ONCE(page_ref_count(head) < 0))
-   return NULL;
-   if (unlikely(!page_cache_add_speculative(head, refs)))
-   return NULL;
-   return head;
-}
-
 #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
 static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
 unsigned int flags, struct page **pages, int *nr)
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 10/19] mm/process_vm_access: set FOLL_PIN via pin_user_pages_remote()

2019-11-25 Thread John Hubbard
Convert process_vm_access to use the new pin_user_pages_remote()
call, which sets FOLL_PIN. Setting FOLL_PIN is now required for
code that requires tracking of pinned pages.

Also, release the pages via put_user_page*().

Also, rename "pages" to "pinned_pages", as this makes for
easier reading of process_vm_rw_single_vec().

Reviewed-by: Jan Kara 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 mm/process_vm_access.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 357aa7bef6c0..fd20ab675b85 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -42,12 +42,11 @@ static int process_vm_rw_pages(struct page **pages,
if (copy > len)
copy = len;
 
-   if (vm_write) {
+   if (vm_write)
copied = copy_page_from_iter(page, offset, copy, iter);
-   set_page_dirty_lock(page);
-   } else {
+   else
copied = copy_page_to_iter(page, offset, copy, iter);
-   }
+
len -= copied;
if (copied < copy && iov_iter_count(iter))
return -EFAULT;
@@ -96,7 +95,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
flags |= FOLL_WRITE;
 
while (!rc && nr_pages && iov_iter_count(iter)) {
-   int pages = min(nr_pages, max_pages_per_loop);
+   int pinned_pages = min(nr_pages, max_pages_per_loop);
int locked = 1;
size_t bytes;
 
@@ -106,14 +105,15 @@ static int process_vm_rw_single_vec(unsigned long addr,
 * current/current->mm
 */
down_read(>mmap_sem);
-   pages = get_user_pages_remote(task, mm, pa, pages, flags,
- process_pages, NULL, );
+   pinned_pages = pin_user_pages_remote(task, mm, pa, pinned_pages,
+flags, process_pages,
+NULL, );
if (locked)
up_read(>mmap_sem);
-   if (pages <= 0)
+   if (pinned_pages <= 0)
return -EFAULT;
 
-   bytes = pages * PAGE_SIZE - start_offset;
+   bytes = pinned_pages * PAGE_SIZE - start_offset;
if (bytes > len)
bytes = len;
 
@@ -122,10 +122,12 @@ static int process_vm_rw_single_vec(unsigned long addr,
 vm_write);
len -= bytes;
start_offset = 0;
-   nr_pages -= pages;
-   pa += pages * PAGE_SIZE;
-   while (pages)
-   put_page(process_pages[--pages]);
+   nr_pages -= pinned_pages;
+   pa += pinned_pages * PAGE_SIZE;
+
+   /* If vm_write is set, the pages need to be made dirty: */
+   put_user_pages_dirty_lock(process_pages, pinned_pages,
+ vm_write);
}
 
return rc;
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 08/19] goldish_pipe: convert to pin_user_pages() and put_user_page()

2019-11-25 Thread John Hubbard
1. Call the new global pin_user_pages_fast(), from pin_goldfish_pages().

2. As required by pin_user_pages(), release these pages via
put_user_page(). In this case, do so via put_user_pages_dirty_lock().

That has the side effect of calling set_page_dirty_lock(), instead
of set_page_dirty(). This is probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [1]

Another side effect is that the release code is simplified because
the page[] loop is now in gup.c instead of here, so just delete the
local release_user_pages() entirely, and call
put_user_pages_dirty_lock() directly, instead.

[1] https://lore.kernel.org/r/20190723153640.gb...@lst.de

Reviewed-by: Jan Kara 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/platform/goldfish/goldfish_pipe.c | 17 +++--
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index ef50c264db71..2a5901efecde 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -274,7 +274,7 @@ static int goldfish_pin_pages(unsigned long first_page,
*iter_last_page_size = last_page_size;
}
 
-   ret = get_user_pages_fast(first_page, requested_pages,
+   ret = pin_user_pages_fast(first_page, requested_pages,
  !is_write ? FOLL_WRITE : 0,
  pages);
if (ret <= 0)
@@ -285,18 +285,6 @@ static int goldfish_pin_pages(unsigned long first_page,
return ret;
 }
 
-static void release_user_pages(struct page **pages, int pages_count,
-  int is_write, s32 consumed_size)
-{
-   int i;
-
-   for (i = 0; i < pages_count; i++) {
-   if (!is_write && consumed_size > 0)
-   set_page_dirty(pages[i]);
-   put_page(pages[i]);
-   }
-}
-
 /* Populate the call parameters, merging adjacent pages together */
 static void populate_rw_params(struct page **pages,
   int pages_count,
@@ -372,7 +360,8 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe,
 
*consumed_size = pipe->command_buffer->rw_params.consumed_size;
 
-   release_user_pages(pipe->pages, pages_count, is_write, *consumed_size);
+   put_user_pages_dirty_lock(pipe->pages, pages_count,
+ !is_write && *consumed_size > 0);
 
mutex_unlock(>lock);
return 0;
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 12/19] fs/io_uring: set FOLL_PIN via pin_user_pages()

2019-11-25 Thread John Hubbard
Convert fs/io_uring to use the new pin_user_pages() call, which sets
FOLL_PIN. Setting FOLL_PIN is now required for code that requires
tracking of pinned pages, and therefore for any code that calls
put_user_page().

In partial anticipation of this work, the io_uring code was already
calling put_user_page() instead of put_page(). Therefore, in order to
convert from the get_user_pages()/put_page() model, to the
pin_user_pages()/put_user_page() model, the only change required
here is to change get_user_pages() to pin_user_pages().

Reviewed-by: Jens Axboe 
Reviewed-by: Jan Kara 
Signed-off-by: John Hubbard 
---
 fs/io_uring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index e5bff60f61d6..869191d8f8d4 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4239,7 +4239,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx 
*ctx, void __user *arg,
 
ret = 0;
down_read(>mm->mmap_sem);
-   pret = get_user_pages(ubuf, nr_pages,
+   pret = pin_user_pages(ubuf, nr_pages,
  FOLL_WRITE | FOLL_LONGTERM,
  pages, vmas);
if (pret == nr_pages) {
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 00/19] pin_user_pages(): reduced-risk series for Linux 5.5

2019-11-25 Thread John Hubbard
Hi,

Changes since v1:

* Fixed up ppc in response to Jan Kara's review comments (thanks for
  those!).

* Fixed a kbuilt robot-detected build failure: added a stub function for
  the !CONFIG_MMU case.

* Cover letter: now refers to "unpin_user_page()", reflecting the name
  change in the last patch (instead of put_user_page() ).

* Rebased onto today's linux-next: c165016bac27 ("Add linux-next
  specific files for 20191125")


Here is a set of well-reviewed (expect for one patch), lower-risk  items
that can go into Linux 5.5. (Update: the powerpc conversion patch has
had some initial review now, since v1 was posted.)

This is essentially a cut-down v8 of "mm/gup: track dma-pinned pages:
FOLL_PIN" [1], and with one of the VFIO patches split into two patches.
The idea here is to get this long list of "noise" checked into 5.5, so
that the actual, higher-risk "track FOLL_PIN pages" (which is deferred:
not part of this series) will be a much shorter patchset to review.

For the v4l2-core changes, I've left those here (instead of sending
them separately to the -media tree), in order to get the name change
done now (put_user_page --> unpin_user_page). However, I've added a Cc
stable, as recommended during the last round of reviews.

Here are the relevant notes from the original cover letter, edited to
match the current situation:

This is a prerequisite to tracking dma-pinned pages. That in turn is a
prerequisite to solving the larger problem of proper interactions
between file-backed pages, and [R]DMA activities, as discussed in [1],
[2], [3], and in a remarkable number of email threads since about
2017. :)

A new internal gup flag, FOLL_PIN is introduced, and thoroughly
documented in the last patch's Documentation/vm/pin_user_pages.rst.

I believe that this will provide a good starting point for doing the
layout lease work that Ira Weiny has been working on. That's because
these new wrapper functions provide a clean, constrained, systematically
named set of functionality that, again, is required in order to even
know if a page is "dma-pinned".

In contrast to earlier approaches, the page tracking can be
incrementally applied to the kernel call sites that, until now, have
been simply calling get_user_pages() ("gup"). In other words, opt-in by
changing from this:

get_user_pages() (sets FOLL_GET)
put_page()

to this:
pin_user_pages() (sets FOLL_PIN)
unpin_user_page()

Because there are interdependencies with FOLL_LONGTERM, a similar
conversion as for FOLL_PIN, was applied. The change was from this:

get_user_pages(FOLL_LONGTERM) (also sets FOLL_GET)
put_page()

to this:
pin_longterm_pages() (sets FOLL_PIN | FOLL_LONGTERM)
unpin_user_page()

[1] https://lore.kernel.org/r/20191121071354.456618-1-jhubb...@nvidia.com

thanks,
John Hubbard
NVIDIA


Dan Williams (1):
  mm: Cleanup __put_devmap_managed_page() vs ->page_free()

John Hubbard (18):
  mm/gup: factor out duplicate code from four routines
  mm/gup: move try_get_compound_head() to top, fix minor issues
  goldish_pipe: rename local pin_user_pages() routine
  mm: fix get_user_pages_remote()'s handling of FOLL_LONGTERM
  vfio: fix FOLL_LONGTERM use, simplify get_user_pages_remote() call
  mm/gup: introduce pin_user_pages*() and FOLL_PIN
  goldish_pipe: convert to pin_user_pages() and put_user_page()
  IB/{core,hw,umem}: set FOLL_PIN via pin_user_pages*(), fix up ODP
  mm/process_vm_access: set FOLL_PIN via pin_user_pages_remote()
  drm/via: set FOLL_PIN via pin_user_pages_fast()
  fs/io_uring: set FOLL_PIN via pin_user_pages()
  net/xdp: set FOLL_PIN via pin_user_pages()
  media/v4l2-core: set pages dirty upon releasing DMA buffers
  media/v4l2-core: pin_user_pages (FOLL_PIN) and put_user_page()
conversion
  vfio, mm: pin_user_pages (FOLL_PIN) and put_user_page() conversion
  powerpc: book3s64: convert to pin_user_pages() and put_user_page()
  mm/gup_benchmark: use proper FOLL_WRITE flags instead of hard-coding
"1"
  mm, tree-wide: rename put_user_page*() to unpin_user_page*()

 Documentation/core-api/index.rst|   1 +
 Documentation/core-api/pin_user_pages.rst   | 233 ++
 arch/powerpc/mm/book3s64/iommu_api.c|  12 +-
 drivers/gpu/drm/via/via_dmablit.c   |   6 +-
 drivers/infiniband/core/umem.c  |   4 +-
 drivers/infiniband/core/umem_odp.c  |  13 +-
 drivers/infiniband/hw/hfi1/user_pages.c |   4 +-
 drivers/infiniband/hw/mthca/mthca_memfree.c |   8 +-
 drivers/infiniband/hw/qib/qib_user_pages.c  |   4 +-
 drivers/infiniband/hw/qib/qib_user_sdma.c   |   8 +-
 drivers/infiniband/hw/usnic/usnic_uiom.c|   4 +-
 drivers/infiniband/sw/siw/siw_mem.c |   4 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c   |   8 +-
 drivers/nvdimm/pmem.c   |   6 -
 drivers/platform/goldfish/goldfish_

[PATCH v2 04/19] goldish_pipe: rename local pin_user_pages() routine

2019-11-25 Thread John Hubbard
1. Avoid naming conflicts: rename local static function from
"pin_user_pages()" to "goldfish_pin_pages()".

An upcoming patch will introduce a global pin_user_pages()
function.

Reviewed-by: Jan Kara 
Reviewed-by: Jérôme Glisse 
Reviewed-by: Ira Weiny 
Signed-off-by: John Hubbard 
---
 drivers/platform/goldfish/goldfish_pipe.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index cef0133aa47a..ef50c264db71 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -257,12 +257,12 @@ static int goldfish_pipe_error_convert(int status)
}
 }
 
-static int pin_user_pages(unsigned long first_page,
- unsigned long last_page,
- unsigned int last_page_size,
- int is_write,
- struct page *pages[MAX_BUFFERS_PER_COMMAND],
- unsigned int *iter_last_page_size)
+static int goldfish_pin_pages(unsigned long first_page,
+ unsigned long last_page,
+ unsigned int last_page_size,
+ int is_write,
+ struct page *pages[MAX_BUFFERS_PER_COMMAND],
+ unsigned int *iter_last_page_size)
 {
int ret;
int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1;
@@ -354,9 +354,9 @@ static int transfer_max_buffers(struct goldfish_pipe *pipe,
if (mutex_lock_interruptible(>lock))
return -ERESTARTSYS;
 
-   pages_count = pin_user_pages(first_page, last_page,
-last_page_size, is_write,
-pipe->pages, _last_page_size);
+   pages_count = goldfish_pin_pages(first_page, last_page,
+last_page_size, is_write,
+pipe->pages, _last_page_size);
if (pages_count < 0) {
mutex_unlock(>lock);
return pages_count;
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 06/19] vfio: fix FOLL_LONGTERM use, simplify get_user_pages_remote() call

2019-11-25 Thread John Hubbard
Update VFIO to take advantage of the recently loosened restriction on
FOLL_LONGTERM with get_user_pages_remote(). Also, now it is possible to
fix a bug: the VFIO caller is logically a FOLL_LONGTERM user, but it
wasn't setting FOLL_LONGTERM.

Also, remove an unnessary pair of calls that were releasing and
reacquiring the mmap_sem. There is no need to avoid holding mmap_sem
just in order to call page_to_pfn().

Also, now that the the DAX check ("if a VMA is DAX, don't allow long
term pinning") is in the internals of get_user_pages_remote() and
__gup_longterm_locked(), there's no need for it at the VFIO call site.
So remove it.

Tested-by: Alex Williamson 
Acked-by: Alex Williamson 
Reviewed-by: Jason Gunthorpe 
Reviewed-by: Ira Weiny 
Suggested-by: Jason Gunthorpe 
Cc: Dan Williams 
Cc: Jerome Glisse 
Signed-off-by: John Hubbard 
---
 drivers/vfio/vfio_iommu_type1.c | 30 +-
 1 file changed, 5 insertions(+), 25 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 2ada8e6cdb88..b800fc9a0251 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -322,7 +322,6 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
 {
struct page *page[1];
struct vm_area_struct *vma;
-   struct vm_area_struct *vmas[1];
unsigned int flags = 0;
int ret;
 
@@ -330,33 +329,14 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
flags |= FOLL_WRITE;
 
down_read(>mmap_sem);
-   if (mm == current->mm) {
-   ret = get_user_pages(vaddr, 1, flags | FOLL_LONGTERM, page,
-vmas);
-   } else {
-   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page,
-   vmas, NULL);
-   /*
-* The lifetime of a vaddr_get_pfn() page pin is
-* userspace-controlled. In the fs-dax case this could
-* lead to indefinite stalls in filesystem operations.
-* Disallow attempts to pin fs-dax pages via this
-* interface.
-*/
-   if (ret > 0 && vma_is_fsdax(vmas[0])) {
-   ret = -EOPNOTSUPP;
-   put_page(page[0]);
-   }
-   }
-   up_read(>mmap_sem);
-
+   ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
+   page, NULL, NULL);
if (ret == 1) {
*pfn = page_to_pfn(page[0]);
-   return 0;
+   ret = 0;
+   goto done;
}
 
-   down_read(>mmap_sem);
-
vaddr = untagged_addr(vaddr);
 
vma = find_vma_intersection(mm, vaddr, vaddr + 1);
@@ -366,7 +346,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
if (is_invalid_reserved_pfn(*pfn))
ret = 0;
}
-
+done:
up_read(>mmap_sem);
return ret;
 }
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 05/15] drm/armada: Delete dma_buf->k(un)map implemenation

2019-11-25 Thread Daniel Vetter
On Mon, Nov 18, 2019 at 11:35:26AM +0100, Daniel Vetter wrote:
> It's a dummy anyway.
> 
> Signed-off-by: Daniel Vetter 
> Cc: Russell King 

I merged the entire series except this one and the final patch, sill
waiting a bit more for an ack on this perhaps.
-Daniel

> ---
>  drivers/gpu/drm/armada/armada_gem.c | 12 
>  1 file changed, 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/armada/armada_gem.c 
> b/drivers/gpu/drm/armada/armada_gem.c
> index 93cf8b8bfcff..976685f2939e 100644
> --- a/drivers/gpu/drm/armada/armada_gem.c
> +++ b/drivers/gpu/drm/armada/armada_gem.c
> @@ -461,16 +461,6 @@ static void armada_gem_prime_unmap_dma_buf(struct 
> dma_buf_attachment *attach,
>   kfree(sgt);
>  }
>  
> -static void *armada_gem_dmabuf_no_kmap(struct dma_buf *buf, unsigned long n)
> -{
> - return NULL;
> -}
> -
> -static void
> -armada_gem_dmabuf_no_kunmap(struct dma_buf *buf, unsigned long n, void *addr)
> -{
> -}
> -
>  static int
>  armada_gem_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
>  {
> @@ -481,8 +471,6 @@ static const struct dma_buf_ops 
> armada_gem_prime_dmabuf_ops = {
>   .map_dma_buf= armada_gem_prime_map_dma_buf,
>   .unmap_dma_buf  = armada_gem_prime_unmap_dma_buf,
>   .release= drm_gem_dmabuf_release,
> - .map= armada_gem_dmabuf_no_kmap,
> - .unmap  = armada_gem_dmabuf_no_kunmap,
>   .mmap   = armada_gem_dmabuf_mmap,
>  };
>  
> -- 
> 2.24.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

RE: [PATCH v4] drm/scheduler: Avoid accessing freed bad job.

2019-11-25 Thread Deng, Emily
[AMD Official Use Only - Internal Distribution Only]

Hi Andrey,
Seems you didn't submit this patch?

Best wishes
Emily Deng



>-Original Message-
>From: Andrey Grodzovsky 
>Sent: Monday, November 25, 2019 12:51 PM
>Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; Koenig,
>Christian ; Deng, Emily
>; steven.pr...@arm.com; Grodzovsky, Andrey
>
>Subject: [PATCH v4] drm/scheduler: Avoid accessing freed bad job.
>
>Problem:
>Due to a race between drm_sched_cleanup_jobs in sched thread and
>drm_sched_job_timedout in timeout work there is a possiblity that bad job
>was already freed while still being accessed from the timeout thread.
>
>Fix:
>Instead of just peeking at the bad job in the mirror list remove it from the 
>list
>under lock and then put it back later when we are garanteed no race with
>main sched thread is possible which is after the thread is parked.
>
>v2: Lock around processing ring_mirror_list in drm_sched_cleanup_jobs.
>
>v3: Rebase on top of drm-misc-next. v2 is not needed anymore as
>drm_sched_get_cleanup_job already has a lock there.
>
>v4: Fix comments to relfect latest code in drm-misc.
>
>Signed-off-by: Andrey Grodzovsky 
>Reviewed-by: Christian König 
>Tested-by: Emily Deng 
>---
> drivers/gpu/drm/scheduler/sched_main.c | 27
>+++
> 1 file changed, 27 insertions(+)
>
>diff --git a/drivers/gpu/drm/scheduler/sched_main.c
>b/drivers/gpu/drm/scheduler/sched_main.c
>index 6774955..1bf9c40 100644
>--- a/drivers/gpu/drm/scheduler/sched_main.c
>+++ b/drivers/gpu/drm/scheduler/sched_main.c
>@@ -284,10 +284,21 @@ static void drm_sched_job_timedout(struct
>work_struct *work)
>   unsigned long flags;
>
>   sched = container_of(work, struct drm_gpu_scheduler,
>work_tdr.work);
>+
>+  /* Protects against concurrent deletion in
>drm_sched_get_cleanup_job */
>+  spin_lock_irqsave(>job_list_lock, flags);
>   job = list_first_entry_or_null(>ring_mirror_list,
>  struct drm_sched_job, node);
>
>   if (job) {
>+  /*
>+   * Remove the bad job so it cannot be freed by concurrent
>+   * drm_sched_cleanup_jobs. It will be reinserted back after
>sched->thread
>+   * is parked at which point it's safe.
>+   */
>+  list_del_init(>node);
>+  spin_unlock_irqrestore(>job_list_lock, flags);
>+
>   job->sched->ops->timedout_job(job);
>
>   /*
>@@ -298,6 +309,8 @@ static void drm_sched_job_timedout(struct
>work_struct *work)
>   job->sched->ops->free_job(job);
>   sched->free_guilty = false;
>   }
>+  } else {
>+  spin_unlock_irqrestore(>job_list_lock, flags);
>   }
>
>   spin_lock_irqsave(>job_list_lock, flags); @@ -370,6 +383,20
>@@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct
>drm_sched_job *bad)
>   kthread_park(sched->thread);
>
>   /*
>+   * Reinsert back the bad job here - now it's safe as
>+   * drm_sched_get_cleanup_job cannot race against us and release the
>+   * bad job at this point - we parked (waited for) any in progress
>+   * (earlier) cleanups and drm_sched_get_cleanup_job will not be
>called
>+   * now until the scheduler thread is unparked.
>+   */
>+  if (bad && bad->sched == sched)
>+  /*
>+   * Add at the head of the queue to reflect it was the earliest
>+   * job extracted.
>+   */
>+  list_add(>node, >ring_mirror_list);
>+
>+  /*
>* Iterate the job list from later to  earlier one and either deactive
>* their HW callbacks or remove them from mirror list if they already
>* signaled.
>--
>2.7.4
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC 06/13] drm/i915/svm: Page table mirroring support

2019-11-25 Thread Niranjan Vishwanathapura

On Mon, Nov 25, 2019 at 11:33:27AM -0500, Jerome Glisse wrote:

On Fri, Nov 22, 2019 at 11:33:12PM +, Jason Gunthorpe wrote:

On Fri, Nov 22, 2019 at 12:57:27PM -0800, Niranjana Vishwanathapura wrote:


[...]


> +static int
> +i915_range_fault(struct i915_svm *svm, struct hmm_range *range)
> +{
> +  long ret;
> +
> +  range->default_flags = 0;
> +  range->pfn_flags_mask = -1UL;
> +
> +  ret = hmm_range_register(range, >mirror);
> +  if (ret) {
> +  up_read(>mm->mmap_sem);
> +  return (int)ret;
> +  }


Using a temporary range is the pattern from nouveau, is it really
necessary in this driver?


Just to comment on this, for GPU the usage model is not application
register range of virtual address it wants to use. It is GPU can
access _any_ CPU valid address just like the CPU would (modulo mmap
of device file).

This is because the API you want in userspace is application passing
random pointer to the GPU and GPU being able to chase down any kind
of random pointer chain (assuming all valid ie pointing to valid
virtual address for the process).

This is unlike the RDMA case.


That being said, for best performance we still expect well behaving
application to provide hint to kernel so that we know if a range of
virtual address is likely to be use by the GPU or not. But this is
not, and should not be a requirement.


I posted patchset and given talks about this, but long term i believe
we want a common API to manage hint provided by userspace (see my
talk at LPC this year about new syscall to bind memory to device).
With such thing in place we could hang mmu notifier range to it. But
the driver will still need to be able to handle the case where there
is no hint provided by userspace and thus no before knowledge of what
VA might be accessed.



Thanks Jerome for the explanation. Will checkout your LPC talk.
Yes I agree. When GPU faulting support is available, driver will handle the 
fault,
migrate page if needed and bind the page using HMM.
This patch series adds support for prefetch and bind hints (via explicit 
ioctls).
Also, patch 12 of the series provides the ability to enable/disable SVM on a per
VM basis for user, and by default SVM is disabled.

Niranjana


Cheers,
Jérôme


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

RE: [PATCH v4] drm: Add support for DP 1.4 Compliance edid corruption test 4.2.2.6

2019-11-25 Thread Zuo, Jerry
Please kindly give a review on my latest revision. Thanks a lot.

Regards,
Jerry

-Original Message-
From: Jerry (Fangzhi) Zuo  
Sent: November 5, 2019 11:38 AM
To: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org
Cc: ly...@redhat.com; manasi.d.nav...@intel.com; Wentland, Harry 
; Zuo, Jerry 
Subject: [PATCH v4] drm: Add support for DP 1.4 Compliance edid corruption test 
4.2.2.6

DP 1.4 edid corruption test requires source DUT to write calculated CRC, not 
the corrupted CRC from reference sink.

Return the calculated CRC back, and initiate the required sequence.

-v2: Have separate routine for returning real CRC

-v3: Rewrite checksum computation routine to avoid duplicated code.
 Rename to avoid confusion

-v4: Fix a minor typo.

Signed-off-by: Jerry (Fangzhi) Zuo 
---
 drivers/gpu/drm/drm_dp_helper.c | 36 
 drivers/gpu/drm/drm_edid.c  | 18 +++---
 include/drm/drm_connector.h |  7 +++
 include/drm/drm_dp_helper.h |  3 +++
 4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c 
index ffc68d305afe..22a0e966ea9f 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -336,6 +336,42 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,  
}  EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+/**
+  * drm_dp_send_real_edid_checksum() - send back real edid checksum 
+value
+  * @aux: DisplayPort AUX channel
+  * @real_edid_checksum: real edid checksum for the last block
+  *
+  * Returns true on success
+  */
+bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux,
+u8 real_edid_checksum) {
+u8 link_edid_read = 0, auto_test_req = 0;
+u8 test_resp = 0;
+
+drm_dp_dpcd_read(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, _test_req, 1);
+auto_test_req &= DP_AUTOMATED_TEST_REQUEST;
+
+drm_dp_dpcd_read(aux, DP_TEST_REQUEST, _edid_read, 1);
+link_edid_read &= DP_TEST_LINK_EDID_READ;
+
+if (!auto_test_req || !link_edid_read) {
+DRM_DEBUG_KMS("Source DUT does not support TEST_EDID_READ\n");
+return false;
+}
+
+drm_dp_dpcd_write(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, 
+ _test_req, 1);
+
+/* send back checksum for the last edid extension block data */
+drm_dp_dpcd_write(aux, DP_TEST_EDID_CHECKSUM, 
+ _edid_checksum, 1);
+
+test_resp |= DP_TEST_EDID_CHECKSUM_WRITE;
+drm_dp_dpcd_write(aux, DP_TEST_RESPONSE, _resp, 1);
+
+return true;
+}
+EXPORT_SYMBOL(drm_dp_send_real_edid_checksum);
+
 /**
  * drm_dp_link_probe() - probe a DisplayPort link for capabilities
  * @aux: DisplayPort AUX channel
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 
82a4ceed3fcf..ff64e5f1feb6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1348,10 +1348,19 @@ static int drm_edid_block_checksum(const u8 *raw_edid)  
{
int i;
u8 csum = 0;
-   for (i = 0; i < EDID_LENGTH; i++)
+
+   for (i = 0; i < EDID_LENGTH - 1; i++)
csum += raw_edid[i];
 
-   return csum;
+   return (0x100 - csum);
+}
+
+static bool drm_edid_block_checksum_diff(const u8 *raw_edid, u8 
+real_checksum) {
+   if (raw_edid[EDID_LENGTH - 1] != real_checksum)
+   return true;
+   else
+   return false;
 }
 
 static bool drm_edid_is_zero(const u8 *in_edid, int length) @@ -1409,7 +1418,7 
@@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
}
 
csum = drm_edid_block_checksum(raw_edid);
-   if (csum) {
+   if (drm_edid_block_checksum_diff(raw_edid, csum)) {
if (edid_corrupt)
*edid_corrupt = true;
 
@@ -1572,6 +1581,9 @@ static void connector_bad_edid(struct drm_connector 
*connector,
   prefix, DUMP_PREFIX_NONE, 16, 1,
   block, EDID_LENGTH, false);
}
+
+   /* Calculate real checksum for the last edid extension block data */
+   connector->real_edid_checksum = drm_edid_block_checksum(edid + 
+edid[0x7e] * EDID_LENGTH);
 }
 
 /* Get override or firmware EDID */
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 
681cb590f952..eb0d8c7b35fd 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1345,6 +1345,13 @@ struct drm_connector {
 * rev1.1 4.2.2.6
 */
bool edid_corrupt;
+   /**
+ * @real_edid_checksum: real edid checksum value for corrupted edid 
block.
+ * Required in Displayport 1.4 compliance testing
+ * rev1.1 4.2.2.6
+ */
+uint8_t real_edid_checksum;
+
 
/** @debugfs_entry: debugfs directory for this connector */
struct dentry *debugfs_entry;
diff --git a/include/drm/drm_dp_helper.h 

Re: [PATCH] Revert "drm/fbdev: Fallback to non tiled mode if all tiles not present"

2019-11-25 Thread Daniel Vetter
On Mon, Nov 25, 2019 at 05:07:26PM +0200, Jani Nikula wrote:
> On Sat, 23 Nov 2019, Uma Shankar  wrote:
> > This reverts commit f25c7a006cd1c07254780e3406e45cee4842b933.
> >
> > 2p2c display configuration blows up dmesg when one connector is
> > disconnected, causing issues in CI.
> >
> > Below are the sample errors thrown in logs:
> >
> > [IGT] core_getversion: executing
> > [IGT] core_getversion: exiting, ret=0
> > Setting dangerous option reset - tainting kernel
> > drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> > flip_done timed out
> > drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> > flip_done timed out
> > drm:drm_atomic_helper_wait_for_dependencies] ERROR [PLANE:92:plane 1B] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_flip_done] ERROR [CRTC:152:pipe B] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_dependencies] ERROR [PLANE:92:plane 1B] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_flip_done] ERROR [CRTC:152:pipe B] 
> > flip_done timed out
> > Console: switching to colour frame buffer device 480x135
> > [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> > flip_done timed out
> > [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> > flip_done timed out
> >
> > Reverting the change for now to unblock CI execution.
> >
> > Cc: Ville Syrjälä 
> > Cc: Dave Airlie 
> > Cc: Jani Nikula 
> > Cc: Manasi Navare 
> > Signed-off-by: Uma Shankar 
> 
> Pushed to drm-misc-next with Daniel's irc ack. Thanks for the
> revert. Back to the drawing board.
> 
> I was about to add the Bugzilla: reference, but this being a gitlab
> issue instead, I opted for the gitlab Closes: tag:
> 
>   Closes: https://gitlab.freedesktop.org/drm/intel/issues/6
> 
> We should probably align on what we want to use going forward. And do we
> want to keep using Bugzilla for bugzilla bugs?

I guess we could/should have that discussion once we have the git repos on
gitlab too. Right now I don't think the above does anything ...

Aside from that I think this makes sense.
-Daniel

> 
> BR,
> Jani.
> 
> 
> > ---
> >  drivers/gpu/drm/drm_client_modeset.c | 70 
> >  1 file changed, 70 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_client_modeset.c 
> > b/drivers/gpu/drm/drm_client_modeset.c
> > index f2150a0bac4c..895b73f23079 100644
> > --- a/drivers/gpu/drm/drm_client_modeset.c
> > +++ b/drivers/gpu/drm/drm_client_modeset.c
> > @@ -114,33 +114,6 @@ drm_client_find_modeset(struct drm_client_dev *client, 
> > struct drm_crtc *crtc)
> > return NULL;
> >  }
> >  
> > -static struct drm_display_mode *
> > -drm_connector_get_tiled_mode(struct drm_connector *connector)
> > -{
> > -   struct drm_display_mode *mode;
> > -
> > -   list_for_each_entry(mode, >modes, head) {
> > -   if (mode->hdisplay == connector->tile_h_size &&
> > -   mode->vdisplay == connector->tile_v_size)
> > -   return mode;
> > -   }
> > -   return NULL;
> > -}
> > -
> > -static struct drm_display_mode *
> > -drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
> > -{
> > -   struct drm_display_mode *mode;
> > -
> > -   list_for_each_entry(mode, >modes, head) {
> > -   if (mode->hdisplay == connector->tile_h_size &&
> > -   mode->vdisplay == connector->tile_v_size)
> > -   continue;
> > -   return mode;
> > -   }
> > -   return NULL;
> > -}
> > -
> >  static struct drm_display_mode *
> >  drm_connector_has_preferred_mode(struct drm_connector *connector, int 
> > width, int height)
> >  {
> > @@ -375,14 +348,8 @@ static bool drm_client_target_preferred(struct 
> > drm_connector **connectors,
> > struct drm_connector *connector;
> > u64 conn_configured = 0;
> > int tile_pass = 0;
> > -   int num_tiled_conns = 0;
> > int i;
> >  
> > -   for (i = 0; i < connector_count; i++) {
> > -   if (connectors[i]->has_tile)
> > -   num_tiled_conns++;
> > -   }
> > -
> >  retry:
> > for (i = 0; i < connector_count; i++) {
> > connector = connectors[i];
> > @@ -432,28 +399,6 @@ static bool drm_client_target_preferred(struct 
> > drm_connector **connectors,
> > list_for_each_entry(modes[i], >modes, head)
> > break;
> > }
> > -   /*
> > -* In case of tiled mode if all tiles not present fallback to
> > -* first available non tiled mode.
> > -* After all tiles are present, try to find the tiled mode
> > -* for all and if tiled mode not present due to fbcon size
> > -* limitations, use first non tiled mode only for
> > -* tile 0,0 

[PATCH v4] drm/scheduler: Avoid accessing freed bad job.

2019-11-25 Thread Andrey Grodzovsky
Problem:
Due to a race between drm_sched_cleanup_jobs in sched thread and
drm_sched_job_timedout in timeout work there is a possiblity that
bad job was already freed while still being accessed from the
timeout thread.

Fix:
Instead of just peeking at the bad job in the mirror list
remove it from the list under lock and then put it back later when
we are garanteed no race with main sched thread is possible which
is after the thread is parked.

v2: Lock around processing ring_mirror_list in drm_sched_cleanup_jobs.

v3: Rebase on top of drm-misc-next. v2 is not needed anymore as
drm_sched_get_cleanup_job already has a lock there.

v4: Fix comments to relfect latest code in drm-misc.

Signed-off-by: Andrey Grodzovsky 
Reviewed-by: Christian König 
Tested-by: Emily Deng 
---
 drivers/gpu/drm/scheduler/sched_main.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 6774955..1bf9c40 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -284,10 +284,21 @@ static void drm_sched_job_timedout(struct work_struct 
*work)
unsigned long flags;
 
sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
+
+   /* Protects against concurrent deletion in drm_sched_get_cleanup_job */
+   spin_lock_irqsave(>job_list_lock, flags);
job = list_first_entry_or_null(>ring_mirror_list,
   struct drm_sched_job, node);
 
if (job) {
+   /*
+* Remove the bad job so it cannot be freed by concurrent
+* drm_sched_cleanup_jobs. It will be reinserted back after 
sched->thread
+* is parked at which point it's safe.
+*/
+   list_del_init(>node);
+   spin_unlock_irqrestore(>job_list_lock, flags);
+
job->sched->ops->timedout_job(job);
 
/*
@@ -298,6 +309,8 @@ static void drm_sched_job_timedout(struct work_struct *work)
job->sched->ops->free_job(job);
sched->free_guilty = false;
}
+   } else {
+   spin_unlock_irqrestore(>job_list_lock, flags);
}
 
spin_lock_irqsave(>job_list_lock, flags);
@@ -370,6 +383,20 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
struct drm_sched_job *bad)
kthread_park(sched->thread);
 
/*
+* Reinsert back the bad job here - now it's safe as
+* drm_sched_get_cleanup_job cannot race against us and release the
+* bad job at this point - we parked (waited for) any in progress
+* (earlier) cleanups and drm_sched_get_cleanup_job will not be called
+* now until the scheduler thread is unparked.
+*/
+   if (bad && bad->sched == sched)
+   /*
+* Add at the head of the queue to reflect it was the earliest
+* job extracted.
+*/
+   list_add(>node, >ring_mirror_list);
+
+   /*
 * Iterate the job list from later to  earlier one and either deactive
 * their HW callbacks or remove them from mirror list if they already
 * signaled.
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 17/19] powerpc: book3s64: convert to pin_user_pages() and put_user_page()

2019-11-25 Thread John Hubbard
On 11/25/19 12:59 AM, Jan Kara wrote:
> On Sun 24-11-19 20:20:09, John Hubbard wrote:
>> 1. Convert from get_user_pages() to pin_user_pages().
>>
>> 2. As required by pin_user_pages(), release these pages via
>> put_user_page(). In this case, do so via put_user_pages_dirty_lock().
>>
>> That has the side effect of calling set_page_dirty_lock(), instead
>> of set_page_dirty(). This is probably more accurate.
>>
>> As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
>> dealing with a file backed page where we have reference on the inode it
>> hangs off." [1]
>>
>> 3. Release each page in mem->hpages[] (instead of mem->hpas[]), because
>> that is the array that pin_longterm_pages() filled in. This is more
>> accurate and should be a little safer from a maintenance point of
>> view.
> 
> Except that this breaks the code. hpages is unioned with hpas...
> 

OK. 

>> @@ -212,10 +211,9 @@ static void mm_iommu_unpin(struct 
>> mm_iommu_table_group_mem_t *mem)
>>  if (!page)
>>  continue;
>>  
>> -if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
>> -SetPageDirty(page);
>> +put_user_pages_dirty_lock(>hpages[i], 1,
>> +  MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);
> 
> And the dirtying condition is wrong here as well. Currently it is always
> true.
> 
>   Honza
> 

Yes. Fixed up locally. The function now looks like this (for this patch, not for
the entire series, which renames "put" to "unpin"):


static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem)
{
long i;
struct page *page = NULL;

if (!mem->hpas)
return;

for (i = 0; i < mem->entries; ++i) {
if (!mem->hpas[i])
continue;

page = pfn_to_page(mem->hpas[i] >> PAGE_SHIFT);
if (!page)
continue;

put_user_pages_dirty_lock(, 1,
mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY);

mem->hpas[i] = 0;
}
}

thanks,
-- 
John Hubbard
NVIDIA

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 07/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN

2019-11-25 Thread John Hubbard
On 11/25/19 12:44 AM, kbuild test robot wrote:
> Hi John,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on rdma/for-next]
> [cannot apply to v5.4 next-20191122]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system. BTW, we also suggest to use '--base' option to specify the
> base tree in git format-patch, please see 
> https://stackoverflow.com/a/37406982]
> 
> url:
> https://github.com/0day-ci/linux/commits/John-Hubbard/pin_user_pages-reduced-risk-series-for-Linux-5-5/20191125-125637
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git for-next
> config: arm-randconfig-a001-20191125 (attached as .config)
> compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=7.4.0 make.cross ARCH=arm 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 
> 
> All errors (new ones prefixed by >>):
> 
>mm/gup.o: In function `pin_user_pages_remote':
>>> mm/gup.c:2528: undefined reference to `get_user_pages_remote'
> 
> vim +2528 mm/gup.c


This, and the other (sh) report, is due to !CONFIG_MMU lacking a 
get_user_pages_remote(), 
but pin_user_pages_remote() needs it for a (temporary) implementation. I'll 
post the fix, 
in v2.


thanks,
-- 
John Hubbard
NVIDIA
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Ville Syrjälä
On Fri, Nov 22, 2019 at 09:50:53PM -0800, Thomas Anderson wrote:
> The new modes are needed for exotic displays such as 8K. Verified that
> modes like 8K60 and 4K120 are properly obtained from a Samsung Q900R.

978f6b0693c7 ("drm/edid: Add CTA-861-G modes with VIC < 128")

and

https://patchwork.freedesktop.org/series/63555/
(been trying to get someone to review that for >1 year...)

> 
> Signed-off-by: Thomas Anderson 
> ---
>  drivers/gpu/drm/drm_edid.c  | 388 +++-
>  include/drm/drm_connector.h |  16 +-
>  2 files changed, 391 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 6b0177112e18..ff5c928516fb 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1278,6 +1278,374 @@ static const struct drm_display_mode edid_cea_modes[] 
> = {
>  4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
>  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 108 - 1280x720@48Hz 16:9 */
> + { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
> +2280, 2500, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 109 - 1280x720@48Hz 64:27 */
> + { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
> +2280, 2500, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 110 - 1680x720@48Hz 64:27 */
> + { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
> +2530, 2750, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 111 - 1920x1080@48Hz 16:9 */
> + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
> +2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 112 - 1920x1080@48Hz 64:27 */
> + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
> +2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 113 - 2560x1080@48Hz 64:27 */
> + { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
> +3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 114 - 3840x2160@48Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 115 - 4096x2160@48Hz 256:135 */
> + { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48,
> +   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
> + /* 116 - 3840x2160@48Hz 64:27 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 117 - 3840x2160@100Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
> +4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 118 - 3840x2160@120Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
> +4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 119 - 3840x2160@100Hz 64:27 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
> +4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 120 - 3840x2160@120Hz 64:27 */
> + { DRM_MODE("3840x2160", 

Re: [PATCH] drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Bhawanpreet Lakha

Reviewed-by: Bhawanpreet Lakha 

On 2019-11-25 1:14 p.m., Harry Wentland wrote:

+Bhawan who has been looking at this from our side.

Harry

On 2019-11-23 12:50 a.m., Thomas Anderson wrote:

The new modes are needed for exotic displays such as 8K. Verified that
modes like 8K60 and 4K120 are properly obtained from a Samsung Q900R.

Signed-off-by: Thomas Anderson 
---
  drivers/gpu/drm/drm_edid.c  | 388 +++-
  include/drm/drm_connector.h |  16 +-
  2 files changed, 391 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6b0177112e18..ff5c928516fb 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1278,6 +1278,374 @@ static const struct drm_display_mode edid_cea_modes[] = 
{
   4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 108 - 1280x720@48Hz 16:9 */
+   { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
+  2280, 2500, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 109 - 1280x720@48Hz 64:27 */
+   { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
+  2280, 2500, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 110 - 1680x720@48Hz 64:27 */
+   { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
+  2530, 2750, 0, 720, 725, 730, 750, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 111 - 1920x1080@48Hz 16:9 */
+   { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
+  2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 112 - 1920x1080@48Hz 64:27 */
+   { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
+  2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 113 - 2560x1080@48Hz 64:27 */
+   { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
+  3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 114 - 3840x2160@48Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 115 - 4096x2160@48Hz 256:135 */
+   { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48,
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+   /* 116 - 3840x2160@48Hz 64:27 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
+  5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 117 - 3840x2160@100Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
+  4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 118 - 3840x2160@120Hz 16:9 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
+  4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+   /* 119 - 3840x2160@100Hz 64:27 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
+  4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+   /* 120 - 3840x2160@120Hz 64:27 */
+   { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
+  4104, 4400, 0, 

Re: [PATCH 0/5] drm/udl: Convert to GEM framebuffer helpers

2019-11-25 Thread Sam Ravnborg
Hi Thomas.

On Thu, Nov 14, 2019 at 03:10:20PM +0100, Thomas Zimmermann wrote:
> Udl uses struct udl_framebuffer for representing its framebuffer. The
> type can be replaced by the standard DRM framebuffer structure.
> 
> Patches 1 to 4 prepare the driver for the conversion. Patch 5 replaces
> the structure.
> 
> The patchset has been tested by running the fb console, X11 and Weston
> on a DisplayLink adapter.

Series looks good, with some nice cleanup to prepare for the
removal of udl_framebuffer.

Whole series is:
Acked-by: Sam Ravnborg 

> 
> Thomas Zimmermann (5):
>   drm/udl: Unmap buffer object after damage update
>   drm/udl: Remove udl implementation of GEM's free_object()
>   drm/udl: Store active framebuffer in device structure
>   drm/udl: Call udl_handle_damage() with DRM framebuffer
>   drm/udl: Replace struct udl_framebuffer with generic implementation
> 
>  drivers/gpu/drm/udl/udl_drv.h |  14 ++--
>  drivers/gpu/drm/udl/udl_fb.c  | 131 +++---
>  drivers/gpu/drm/udl/udl_gem.c |  18 +---
>  drivers/gpu/drm/udl/udl_main.c|   3 +
>  drivers/gpu/drm/udl/udl_modeset.c |  31 +++
>  5 files changed, 70 insertions(+), 127 deletions(-)
> 
> --
> 2.23.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Harry Wentland
+Bhawan who has been looking at this from our side.

Harry

On 2019-11-23 12:50 a.m., Thomas Anderson wrote:
> The new modes are needed for exotic displays such as 8K. Verified that
> modes like 8K60 and 4K120 are properly obtained from a Samsung Q900R.
> 
> Signed-off-by: Thomas Anderson 
> ---
>  drivers/gpu/drm/drm_edid.c  | 388 +++-
>  include/drm/drm_connector.h |  16 +-
>  2 files changed, 391 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 6b0177112e18..ff5c928516fb 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1278,6 +1278,374 @@ static const struct drm_display_mode edid_cea_modes[] 
> = {
>  4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
>  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 108 - 1280x720@48Hz 16:9 */
> + { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
> +2280, 2500, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 109 - 1280x720@48Hz 64:27 */
> + { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 9, 1280, 2240,
> +2280, 2500, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 110 - 1680x720@48Hz 64:27 */
> + { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 2490,
> +2530, 2750, 0, 720, 725, 730, 750, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 111 - 1920x1080@48Hz 16:9 */
> + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
> +2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 112 - 1920x1080@48Hz 64:27 */
> + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2558,
> +2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 113 - 2560x1080@48Hz 64:27 */
> + { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 3558,
> +3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 114 - 3840x2160@48Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 115 - 4096x2160@48Hz 256:135 */
> + { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48,
> +   .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
> + /* 116 - 3840x2160@48Hz 64:27 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 5116,
> +5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 48, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 117 - 3840x2160@100Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
> +4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 118 - 3840x2160@120Hz 16:9 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
> +4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
> + /* 119 - 3840x2160@100Hz 64:27 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4896,
> +4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
> +DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
> +   .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
> + /* 120 - 3840x2160@120Hz 64:27 */
> + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1188000, 3840, 4016,
> +4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
> +

Re: [Intel-gfx] [PATCH 3/7] drm: Extract page_flip_{internal, atomic}()

2019-11-25 Thread Daniel Vetter
On Mon, Nov 25, 2019 at 4:05 PM Ville Syrjälä
 wrote:
>
> On Mon, Nov 25, 2019 at 10:02:38AM +0100, Daniel Vetter wrote:
> > On Fri, Nov 22, 2019 at 08:35:13PM +0200, Ville Syrjälä wrote:
> > > On Tue, Nov 19, 2019 at 11:14:43AM +0100, Daniel Vetter wrote:
> > > > On Fri, Nov 15, 2019 at 09:42:00PM +0200, Ville Syrjala wrote:
> > > > > From: Ville Syrjälä 
> > > > >
> > > > > Yank out the code for the plane->fb/old_fb/crtc handling from
> > > > > the page flip path into page_flip_internal(), and provide a
> > > > > simpler variant for atomic drivers.
> > > > >
> > > > > We'll also move the fb vs. src viewport checks into the new
> > > > > functions as they are slightly different between the two paths.
> > > > > If the atomic .page_flip() implementations are guaranteed
> > > > > to call drm_atomic_plane_check() we could even drop the check
> > > > > entirely from page_flip_atomic(). For now toss in a FIXME.
> > > > >
> > > > > v2: Bit more polish in page_flip_internal()
> > > > >
> > > > > Signed-off-by: Ville Syrjälä 
> > > > > ---
> > > > >  drivers/gpu/drm/drm_plane.c | 159 
> > > > > +++-
> > > > >  1 file changed, 102 insertions(+), 57 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> > > > > index 38878da5b704..6052475a20a5 100644
> > > > > --- a/drivers/gpu/drm/drm_plane.c
> > > > > +++ b/drivers/gpu/drm/drm_plane.c
> > > > > @@ -1031,13 +1031,109 @@ int drm_mode_cursor2_ioctl(struct drm_device 
> > > > > *dev,
> > > > > return drm_mode_cursor_common(dev, req, file_priv);
> > > > >  }
> > > > >
> > > > > +static int page_flip_check_fbs(const struct drm_framebuffer *fb,
> > > > > +  const struct drm_framebuffer *old_fb)
> > > > > +{
> > > > > +   /* The framebuffer is currently unbound, presumably
> > > > > +* due to a hotplug event, that userspace has not
> > > > > +* yet discovered.
> > > > > +*/
> > > > > +   if (!old_fb)
> > > > > +   return -EBUSY;
> > > > > +
> > > > > +   if (old_fb->format != fb->format) {
> > > > > +   DRM_DEBUG_KMS("Page flip is not allowed to change 
> > > > > frame buffer format.\n");
> > > > > +   return -EINVAL;
> > > > > +   }
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +
> > > > > +static int page_flip_internal(struct drm_crtc *crtc,
> > > > > + struct drm_framebuffer *fb,
> > > > > + struct drm_pending_vblank_event *e,
> > > > > + u32 flags,
> > > > > + u32 target_vblank,
> > > > > + struct drm_modeset_acquire_ctx *ctx)
> > > > > +{
> > > > > +   struct drm_plane *plane = crtc->primary;
> > > > > +   int ret;
> > > > > +
> > > > > +   WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
> > > > > +
> > > > > +   ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
> > > > > + >mode, fb);
> > > > > +   if (ret)
> > > > > +   return ret;
> > > > > +
> > > > > +   ret = page_flip_check_fbs(fb, plane->fb);
> > > > > +   if (ret)
> > > > > +   return ret;
> > > > > +
> > > > > +   plane->old_fb = plane->fb;
> > > > > +   if (crtc->funcs->page_flip_target)
> > > > > +   ret = crtc->funcs->page_flip_target(crtc, fb, e, 
> > > > > flags,
> > > > > +   target_vblank, 
> > > > > ctx);
> > > > > +   else
> > > > > +   ret = crtc->funcs->page_flip(crtc, fb, e, flags, ctx);
> > > > > +   if (ret) {
> > > > > +   plane->old_fb = NULL;
> > > > > +   return ret;
> > > > > +   }
> > > > > +
> > > > > +   plane->fb = fb;
> > > > > +   drm_framebuffer_get(plane->fb);
> > > > > +
> > > > > +   drm_framebuffer_put(plane->old_fb);
> > > > > +   plane->old_fb = NULL;
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +
> > > > > +static int page_flip_atomic(struct drm_crtc *crtc,
> > > > > +   struct drm_framebuffer *fb,
> > > > > +   struct drm_pending_vblank_event *e,
> > > > > +   u32 flags,
> > > > > +   u32 target_vblank,
> > > > > +   struct drm_modeset_acquire_ctx *ctx)
> > > > > +{
> > > > > +   struct drm_plane *plane = crtc->primary;
> > > > > +   struct drm_plane_state *plane_state = plane->state;
> > > > > +   int ret;
> > > > > +
> > > > > +   WARN_ON(!drm_drv_uses_atomic_modeset(crtc->dev));
> > > > > +
> > > > > +   /*
> > > > > +* FIXME: Can we assume all drivers end up calling
> > > > > +* drm_atomic_plane_check() in their page flip paths?
> > > > > +* If so we could remove this.
> > > > > +*/
> > > >
> > > > This is definitely 

[Bug 205649] New: Daisy Chain (MST) Session Crash after Screen Lock Resume

2019-11-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205649

Bug ID: 205649
   Summary: Daisy Chain (MST) Session Crash after Screen Lock
Resume
   Product: Drivers
   Version: 2.5
Kernel Version: 5.4
  Hardware: Intel
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: mich...@rauch.be
Regression: No

Error message:
Nov 25 17:18:59 hoi kernel: [  664.616065] [drm] DM_MST: stopping TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:19:03 hoi kernel: [  668.779501] [drm] DM_MST: Disabling connector:
20957698 [id: 72] [master: d2ec50d2]
Nov 25 17:19:03 hoi kernel: [  668.780518] [drm] DM_MST: Disabling connector:
a3e45904 [id: 67] [master: d2ec50d2]
Nov 25 17:19:03 hoi kernel: [  668.795264] [drm] DM_MST: starting TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:19:03 hoi kernel: [  668.868743] [drm] DM_MST: added connector:
a5e1fa4b [id: 84] [master: d2ec50d2]
Nov 25 17:19:03 hoi kernel: [  669.018055] [drm] DM_MST: added connector:
a62ddae1 [id: 102] [master: d2ec50d2]
Nov 25 17:19:49 hoi kernel: [  715.510276] [drm] DM_MST: stopping TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:19:54 hoi kernel: [  719.723556] [drm] DM_MST: Disabling connector:
a62ddae1 [id: 102] [master: d2ec50d2]
Nov 25 17:19:54 hoi kernel: [  719.724562] [drm] DM_MST: Disabling connector:
a5e1fa4b [id: 84] [master: d2ec50d2]
Nov 25 17:19:54 hoi kernel: [  719.738593] [drm] DM_MST: starting TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:19:54 hoi kernel: [  719.799040] [drm] DM_MST: added connector:
84594915 [id: 82] [master: d2ec50d2]
Nov 25 17:19:54 hoi kernel: [  719.944380] [drm] DM_MST: added connector:
7a6df593 [id: 111] [master: d2ec50d2]
Nov 25 17:27:56 hoi kernel: [ 1202.137752] [drm] DM_MST: stopping TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:28:00 hoi kernel: [ 1206.380336] [drm] DM_MST: Disabling connector:
7a6df593 [id: 111] [master: d2ec50d2]
Nov 25 17:28:00 hoi kernel: [ 1206.381399] [drm] DM_MST: Disabling connector:
84594915 [id: 82] [master: d2ec50d2]
Nov 25 17:28:00 hoi kernel: [ 1206.395858] [drm] DM_MST: starting TM on
aconnector: d2ec50d2 [id: 64]
Nov 25 17:28:00 hoi kernel: [ 1206.478238] [drm] DM_MST: added connector:
e1e4c871 [id: 84] [master: d2ec50d2]
Nov 25 17:28:01 hoi kernel: [ 1206.628767] [drm] DM_MST: added connector:
a3c8d4bc [id: 109] [master: d2ec50d2]


Setup:
2 monitors in Daisy Chain (MST) setup as separate displays


How to reproduce the issue:
1. Enable Screen Lock for a Gnome Session
2. Wake up the session after the monitors go to sleep


During the issue, the following occured:
1. Session crash for a running user session after wake up
2. User has to login to a new session


System specification:
Radeon PRO WX 2100
Ubuntu 18.04


I have tried the following combination:
Kernel 5.3, 5.4
Mesa 19.0.8


Let me know if more logfiles are needed

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 2/2] drm/scheduler: Avoid accessing freed bad job.

2019-11-25 Thread Steven Price
On 25/11/2019 14:10, Andrey Grodzovsky wrote:
> Problem:
> Due to a race between drm_sched_cleanup_jobs in sched thread and
> drm_sched_job_timedout in timeout work there is a possiblity that
> bad job was already freed while still being accessed from the
> timeout thread.
> 
> Fix:
> Instead of just peeking at the bad job in the mirror list
> remove it from the list under lock and then put it back later when
> we are garanteed no race with main sched thread is possible which
> is after the thread is parked.
> 
> v2: Lock around processing ring_mirror_list in drm_sched_cleanup_jobs.
> 
> v3: Rebase on top of drm-misc-next. v2 is not needed anymore as
> drm_sched_cleanup_jobs already has a lock there.
> 
> Signed-off-by: Andrey Grodzovsky 
> Reviewed-by: Christian König 
> Tested-by: Emily Deng 
> ---
>  drivers/gpu/drm/scheduler/sched_main.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> b/drivers/gpu/drm/scheduler/sched_main.c
> index 6774955..a604dfa 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -284,10 +284,24 @@ static void drm_sched_job_timedout(struct work_struct 
> *work)
>   unsigned long flags;
>  
>   sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
> +
> + /*
> +  * Protects against concurrent deletion in drm_sched_cleanup_jobs that
   ^

drm_sched_cleanup_jobs() is gone - replaced with
drm_sched_get_cleanup_job() and code in drm_sched_main(). See:

588b9828f074 ("drm: Don't free jobs in wait_event_interruptible()")

> +  * is already in progress.
> +  */
> + spin_lock_irqsave(>job_list_lock, flags);
>   job = list_first_entry_or_null(>ring_mirror_list,
>  struct drm_sched_job, node);
>  
>   if (job) {
> + /*
> +  * Remove the bad job so it cannot be freed by already in 
> progress
> +  * drm_sched_cleanup_jobs. It will be reinsrted back after 
> sched->thread
  ^
Typo: s/reinsrted/reinserted/

> +  * is parked at which point it's safe.
> +  */
> + list_del_init(>node);
> + spin_unlock_irqrestore(>job_list_lock, flags);
> +
>   job->sched->ops->timedout_job(job);
>  
>   /*
> @@ -298,6 +312,8 @@ static void drm_sched_job_timedout(struct work_struct 
> *work)
>   job->sched->ops->free_job(job);
>   sched->free_guilty = false;
>   }
> + } else {
> + spin_unlock_irqrestore(>job_list_lock, flags);
>   }
>  
>   spin_lock_irqsave(>job_list_lock, flags);
> @@ -370,6 +386,19 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> struct drm_sched_job *bad)
>   kthread_park(sched->thread);
>  
>   /*
> +  * Reinsert back the bad job here - now it's safe as 
> drm_sched_cleanup_jobs

Another reference to drm_sched_cleanup_jobs.

> +  * cannot race against us and release the bad job at this point - we 
> parked
> +  * (waited for) any in progress (earlier) cleanups and any later ones 
> will
> +  * bail out due to sched->thread being parked.

As explained in the other patch - after the kthread_park() has returned
there will be no more calls to drm_sched_get_cleanup_job() until the
thread is unparked.

Steve

> +  */
> + if (bad && bad->sched == sched)
> + /*
> +  * Add at the head of the queue to reflect it was the earliest
> +  * job extracted.
> +  */
> + list_add(>node, >ring_mirror_list);
> +
> + /*
>* Iterate the job list from later to  earlier one and either deactive
>* their HW callbacks or remove them from mirror list if they already
>* signaled.
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [Intel-gfx] [RFC 03/13] drm/i915/svm: Runtime (RT) allocator support

2019-11-25 Thread Niranjan Vishwanathapura

On Mon, Nov 25, 2019 at 09:59:37AM +, Chris Wilson wrote:

Quoting Niranjana Vishwanathapura (2019-11-22 20:57:24)

Shared Virtual Memory (SVM) runtime allocator support allows
binding a shared virtual address to a buffer object (BO) in the
device page table through an ioctl call.


The ioctl though is not svm specific, it is to do with "bulk residency"
and can be used to reduce execbuf traffic to provide virtual address
layout controls to e.g. Vulkan clients.

I915_VM_BIND {
uint32_t vm_id;
int32_t fd; /* or -1 for anon, or buf depending on flags */
uint64_t flags;
uint64_t offset; /* offset info fd [page aligned] */
uint64_t length; /* page aligned */
uint64_t iova; /* page aligned */
uint64_t extensions;
}; /* where page aligned is actually more I915_GTT_PAGE_ALIGNMENT */

as I recall. I also recall it being part of a future command stream
interface to reduce ioctls, but that is another story.


Thanks Chris.
I will change I915_BIND to I915_VM_BIND.
Currently, it is only addressing binding SVM system (buffer) and runtime (BOs)
allocations. But it can be expanded for other bindings. I have 'type' field
instead of 'fd' and 'extensions' & 'iov' can be added later if required.
Is that OK?


-Chris

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 1/2] drm/sched: Avoid job cleanup if sched thread is parked.

2019-11-25 Thread Steven Price
On 25/11/2019 14:10, Andrey Grodzovsky wrote:
> When the sched thread is parked we assume ring_mirror_list is
> not accessed from here.

FWIW I don't think this is necessary. kthread_park() will wait until the
thread is parked, at which point the thread is stuck in kthread_parkme()
until unparked.

So all this does is avoid waiting for any cleanup jobs before parking -
which might be a reasonable goal in itself, but if so lets at least
document that.

Steve

> 
> Signed-off-by: Andrey Grodzovsky 
> Reviewed-by: Christian König 
> ---
>  drivers/gpu/drm/scheduler/sched_main.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> b/drivers/gpu/drm/scheduler/sched_main.c
> index d4cc728..6774955 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -635,9 +635,13 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler 
> *sched)
>   struct drm_sched_job *job;
>   unsigned long flags;
>  
> - /* Don't destroy jobs while the timeout worker is running */
> - if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
> - !cancel_delayed_work(>work_tdr))
> + /*
> + * Don't destroy jobs while the timeout worker is running  OR thread
> + * is being parked and hence assumed to not touch ring_mirror_list
> + */
> + if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
> +  !cancel_delayed_work(>work_tdr)) ||
> +  __kthread_should_park(sched->thread))
>   return NULL;
>  
>   spin_lock_irqsave(>job_list_lock, flags);
> 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC 06/13] drm/i915/svm: Page table mirroring support

2019-11-25 Thread Niranjan Vishwanathapura

On Mon, Nov 25, 2019 at 01:24:18PM +, Jason Gunthorpe wrote:

On Sun, Nov 24, 2019 at 01:12:47PM -0800, Niranjan Vishwanathapura wrote:


> > > Using a temporary range is the pattern from nouveau, is it really
> > > necessary in this driver?
> >
> > Yah, not required. In my local build I tried with proper default_flags
> > and set pfn_flags_mask to 0 and it is working fine.
>
> Sorry, I ment calling hmm_range_register during fault processing.
>
> If your driver works around user space objects that cover a VA then
> the range should be created when the object is created.
>

Oh ok. No, there is no user space object here.
Binding the user space object to device page table is handled in
patch 03 of this series (no HMM there).
This is for binding a system allocated (malloc) memory. User calls
the bind ioctl with the VA range.

> > > > +   /*
> > > > +* No needd to dma map the host pages and later unmap it, as
> > > > +* GPU is not allowed to access it with SVM. Hence, no need
> > > > +* of any intermediate data strucutre to hold the mappings.
> > > > +*/
> > > > +   for (i = 0; i < npages; i++) {
> > > > +   u64 addr = range->pfns[i] & ~((1UL << range->pfn_shift) - 
1);
> > > > +
> > > > +   if (sg && (addr == (sg_dma_address(sg) + sg->length))) {
> > > > +   sg->length += PAGE_SIZE;
> > > > +   sg_dma_len(sg) += PAGE_SIZE;
> > > > +   continue;
> > > > +   }
> > > > +
> > > > +   if (sg)
> > > > +   sg_page_sizes |= sg->length;
> > > > +
> > > > +   sg =  sg ? __sg_next(sg) : st->sgl;
> > > > +   sg_dma_address(sg) = addr;
> > > > +   sg_dma_len(sg) = PAGE_SIZE;
> > > > +   sg->length = PAGE_SIZE;
> > > > +   st->nents++;
> > >
> > > It is odd to build the range into a sgl.
> > >
> > > IMHO it is not a good idea to use the sg_dma_address like this, that
> > > should only be filled in by a dma map. Where does it end up being
> > > used?
> >
> > The sgl is used to plug into the page table update function in i915.
> >
> > For the device memory in discrete card, we don't need dma map which
> > is the case here.
>
> How did we get to device memory on a card? Isn't range->pfns a CPU PFN
> at this point?
>
> I'm confused.

Device memory plugin is done through devm_memremap_pages() in patch 07 of
this series. In that patch, we convert the CPU PFN to device PFN before
building the sgl (this is similar to the nouveau driver).


But earlier just called hmm_range_fault(), it can return all kinds of
pages. If these are only allowed to be device pages here then that
must be checked (under lock)



Yah, let me add the check.
(I kept is unchecked for debug purpose, forgot to add the check before sending
the patches.)


And putting the cpu PFN of a ZONE_DEVICE device page into
sg_dma_address still looks very wrong to me



The below call in patch 7 does convert any cpu PFN to device address.
So, it won't be CPU PFN.
i915_dmem_convert_pfn(vm->i915, );

Also, only reason to use sgl list is because i915 driver page table update
functions takes an sgl, otherwise we can directly deal with range.pfns array.

Niranjana


Jason

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC 06/13] drm/i915/svm: Page table mirroring support

2019-11-25 Thread Jerome Glisse
On Mon, Nov 25, 2019 at 01:24:18PM +, Jason Gunthorpe wrote:
> On Sun, Nov 24, 2019 at 01:12:47PM -0800, Niranjan Vishwanathapura wrote:
> 
> > > > > Using a temporary range is the pattern from nouveau, is it really
> > > > > necessary in this driver?
> > > > 
> > > > Yah, not required. In my local build I tried with proper default_flags
> > > > and set pfn_flags_mask to 0 and it is working fine.
> > > 
> > > Sorry, I ment calling hmm_range_register during fault processing.
> > > 
> > > If your driver works around user space objects that cover a VA then
> > > the range should be created when the object is created.
> > > 
> > 
> > Oh ok. No, there is no user space object here.
> > Binding the user space object to device page table is handled in
> > patch 03 of this series (no HMM there).
> > This is for binding a system allocated (malloc) memory. User calls
> > the bind ioctl with the VA range.
> > 
> > > > > > +   /*
> > > > > > +* No needd to dma map the host pages and later unmap it, as
> > > > > > +* GPU is not allowed to access it with SVM. Hence, no need
> > > > > > +* of any intermediate data strucutre to hold the mappings.
> > > > > > +*/
> > > > > > +   for (i = 0; i < npages; i++) {
> > > > > > +   u64 addr = range->pfns[i] & ~((1UL << range->pfn_shift) 
> > > > > > - 1);
> > > > > > +
> > > > > > +   if (sg && (addr == (sg_dma_address(sg) + sg->length))) {
> > > > > > +   sg->length += PAGE_SIZE;
> > > > > > +   sg_dma_len(sg) += PAGE_SIZE;
> > > > > > +   continue;
> > > > > > +   }
> > > > > > +
> > > > > > +   if (sg)
> > > > > > +   sg_page_sizes |= sg->length;
> > > > > > +
> > > > > > +   sg =  sg ? __sg_next(sg) : st->sgl;
> > > > > > +   sg_dma_address(sg) = addr;
> > > > > > +   sg_dma_len(sg) = PAGE_SIZE;
> > > > > > +   sg->length = PAGE_SIZE;
> > > > > > +   st->nents++;
> > > > >
> > > > > It is odd to build the range into a sgl.
> > > > >
> > > > > IMHO it is not a good idea to use the sg_dma_address like this, that
> > > > > should only be filled in by a dma map. Where does it end up being
> > > > > used?
> > > > 
> > > > The sgl is used to plug into the page table update function in i915.
> > > > 
> > > > For the device memory in discrete card, we don't need dma map which
> > > > is the case here.
> > > 
> > > How did we get to device memory on a card? Isn't range->pfns a CPU PFN
> > > at this point?
> > > 
> > > I'm confused.
> > 
> > Device memory plugin is done through devm_memremap_pages() in patch 07 of
> > this series. In that patch, we convert the CPU PFN to device PFN before
> > building the sgl (this is similar to the nouveau driver).
> 
> But earlier just called hmm_range_fault(), it can return all kinds of
> pages. If these are only allowed to be device pages here then that
> must be checked (under lock)
> 
> And putting the cpu PFN of a ZONE_DEVICE device page into
> sg_dma_address still looks very wrong to me

Yeah, nouveau has different code path but this is because nouveau
driver architecture allows it, i do not see any easy way to hammer
this inside i915 current architecture. I will ponder on this a bit
more.

Cheers,
Jérôme

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC 06/13] drm/i915/svm: Page table mirroring support

2019-11-25 Thread Jerome Glisse
On Fri, Nov 22, 2019 at 11:33:12PM +, Jason Gunthorpe wrote:
> On Fri, Nov 22, 2019 at 12:57:27PM -0800, Niranjana Vishwanathapura wrote:

[...]

> > +static int
> > +i915_range_fault(struct i915_svm *svm, struct hmm_range *range)
> > +{
> > +   long ret;
> > +
> > +   range->default_flags = 0;
> > +   range->pfn_flags_mask = -1UL;
> > +
> > +   ret = hmm_range_register(range, >mirror);
> > +   if (ret) {
> > +   up_read(>mm->mmap_sem);
> > +   return (int)ret;
> > +   }
> 
> 
> Using a temporary range is the pattern from nouveau, is it really
> necessary in this driver?

Just to comment on this, for GPU the usage model is not application
register range of virtual address it wants to use. It is GPU can
access _any_ CPU valid address just like the CPU would (modulo mmap
of device file).

This is because the API you want in userspace is application passing
random pointer to the GPU and GPU being able to chase down any kind
of random pointer chain (assuming all valid ie pointing to valid
virtual address for the process).

This is unlike the RDMA case.


That being said, for best performance we still expect well behaving
application to provide hint to kernel so that we know if a range of
virtual address is likely to be use by the GPU or not. But this is
not, and should not be a requirement.


I posted patchset and given talks about this, but long term i believe
we want a common API to manage hint provided by userspace (see my
talk at LPC this year about new syscall to bind memory to device).
With such thing in place we could hang mmu notifier range to it. But
the driver will still need to be able to handle the case where there
is no hint provided by userspace and thus no before knowledge of what
VA might be accessed.

Cheers,
Jérôme

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

drm/edid: Add modes from CTA-861-G

2019-11-25 Thread Bhawanpreet Lakha
Everything looks good. but one concern I have is that shouldn't the 
aspect ratio be 16:9 for some of them (See below). Unless I missed 
something?


VIC 109 1280x720=*16:9*
VIC 110 1680x720=*7:3*
VIC 112 1920x1080=*16:9*
VIC 116 3840x2160=*16:9*
VIC 119 3840x2160=*16:9*
VIC 120 3840x2160=*16:9*
VIC 202-209  7680x4320=*16:9*


Bhawan

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH -next] drm/amd/powerplay: remove set but not used variable 'stretch_amount2'

2019-11-25 Thread Alex Deucher
On Mon, Nov 25, 2019 at 10:00 AM YueHaibing  wrote:
>
> drivers/gpu/drm/amd/amdgpu/../powerplay/smumgr/vegam_smumgr.c:
>  In function vegam_populate_clock_stretcher_data_table:
> drivers/gpu/drm/amd/amdgpu/../powerplay/smumgr/vegam_smumgr.c:1489:29:
>  warning: variable stretch_amount2 set but not used 
> [-Wunused-but-set-variable]
>
> It is never used, so can be removed.
>
> Signed-off-by: YueHaibing 

Applied.  thanks!

Alex

> ---
>  drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c 
> b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
> index 50896e9..b0e0d67 100644
> --- a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
> @@ -1486,7 +1486,7 @@ static int 
> vegam_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
> struct vegam_smumgr *smu_data =
> (struct vegam_smumgr *)(hwmgr->smu_backend);
>
> -   uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0;
> +   uint8_t i, stretch_amount, volt_offset = 0;
> struct phm_ppt_v1_information *table_info =
> (struct phm_ppt_v1_information *)(hwmgr->pptable);
> struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
> @@ -1525,11 +1525,9 @@ static int 
> vegam_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
> (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ?
> table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 5;
> /* Populate CKS Lookup Table */
> -   if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
> -   stretch_amount2 = 0;
> -   else if (stretch_amount == 3 || stretch_amount == 4)
> -   stretch_amount2 = 1;
> -   else {
> +   if (!(stretch_amount == 1 || stretch_amount == 2 ||
> + stretch_amount == 5 || stretch_amount == 3 ||
> + stretch_amount == 4)) {
> phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
> PHM_PlatformCaps_ClockStretcher);
> PP_ASSERT_WITH_CODE(false,
> --
> 2.7.4
>
>
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH -next] drm/amd/display: remove set but not used variable 'msg_out'

2019-11-25 Thread Alex Deucher
On Mon, Nov 25, 2019 at 10:00 AM YueHaibing  wrote:
>
> drivers/gpu/drm/amd/amdgpu/../display/modules/hdcp/hdcp_psp.c: In function 
> mod_hdcp_hdcp2_enable_encryption:
> drivers/gpu/drm/amd/amdgpu/../display/modules/hdcp/hdcp_psp.c:633:77: 
> warning: variable msg_out set but not used [-Wunused-but-set-variable]
> drivers/gpu/drm/amd/amdgpu/../display/modules/hdcp/hdcp_psp.c: In function 
> mod_hdcp_hdcp2_enable_dp_stream_encryption:
> drivers/gpu/drm/amd/amdgpu/../display/modules/hdcp/hdcp_psp.c:710:77: 
> warning: variable msg_out set but not used [-Wunused-but-set-variable]
>
> It is never used, so remove it.
>
> Reported-by: Hulk Robot 
> Signed-off-by: YueHaibing 

Applied.  Thanks!

Alex

> ---
>  drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c 
> b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
> index 2dd5fee..468f5e6 100644
> --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
> +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
> @@ -630,14 +630,12 @@ enum mod_hdcp_status 
> mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp)
> struct psp_context *psp = hdcp->config.psp.handle;
> struct ta_hdcp_shared_memory *hdcp_cmd;
> struct 
> ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
> -   struct 
> ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
> struct mod_hdcp_display *display = get_first_added_display(hdcp);
>
> hdcp_cmd = (struct ta_hdcp_shared_memory 
> *)psp->hdcp_context.hdcp_shared_buf;
> memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
>
> msg_in = 
> _cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
> -   msg_out = 
> _cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
>
> hdcp2_message_init(hdcp, msg_in);
>
> @@ -707,14 +705,12 @@ enum mod_hdcp_status 
> mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp
> struct psp_context *psp = hdcp->config.psp.handle;
> struct ta_hdcp_shared_memory *hdcp_cmd;
> struct 
> ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
> -   struct 
> ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
> uint8_t i;
>
> hdcp_cmd = (struct ta_hdcp_shared_memory 
> *)psp->hdcp_context.hdcp_shared_buf;
> memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
>
> msg_in = 
> _cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
> -   msg_out = 
> _cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
>
> hdcp2_message_init(hdcp, msg_in);
>
> --
> 2.7.4
>
>
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] Revert "drm/fbdev: Fallback to non tiled mode if all tiles not present"

2019-11-25 Thread Jani Nikula
On Sat, 23 Nov 2019, Uma Shankar  wrote:
> This reverts commit f25c7a006cd1c07254780e3406e45cee4842b933.
>
> 2p2c display configuration blows up dmesg when one connector is
> disconnected, causing issues in CI.
>
> Below are the sample errors thrown in logs:
>
> [IGT] core_getversion: executing
> [IGT] core_getversion: exiting, ret=0
> Setting dangerous option reset - tainting kernel
> drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> flip_done timed out
> drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> flip_done timed out
> drm:drm_atomic_helper_wait_for_dependencies] ERROR [PLANE:92:plane 1B] 
> flip_done timed out
> [drm:drm_atomic_helper_wait_for_flip_done] ERROR [CRTC:152:pipe B] flip_done 
> timed out
> [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> flip_done timed out
> [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> flip_done timed out
> [drm:drm_atomic_helper_wait_for_dependencies] ERROR [PLANE:92:plane 1B] 
> flip_done timed out
> [drm:drm_atomic_helper_wait_for_flip_done] ERROR [CRTC:152:pipe B] flip_done 
> timed out
> Console: switching to colour frame buffer device 480x135
> [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CRTC:152:pipe B] 
> flip_done timed out
> [drm:drm_atomic_helper_wait_for_dependencies] ERROR [CONNECTOR:299:DP-2] 
> flip_done timed out
>
> Reverting the change for now to unblock CI execution.
>
> Cc: Ville Syrjälä 
> Cc: Dave Airlie 
> Cc: Jani Nikula 
> Cc: Manasi Navare 
> Signed-off-by: Uma Shankar 

Pushed to drm-misc-next with Daniel's irc ack. Thanks for the
revert. Back to the drawing board.

I was about to add the Bugzilla: reference, but this being a gitlab
issue instead, I opted for the gitlab Closes: tag:

Closes: https://gitlab.freedesktop.org/drm/intel/issues/6

We should probably align on what we want to use going forward. And do we
want to keep using Bugzilla for bugzilla bugs?

BR,
Jani.


> ---
>  drivers/gpu/drm/drm_client_modeset.c | 70 
>  1 file changed, 70 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_client_modeset.c 
> b/drivers/gpu/drm/drm_client_modeset.c
> index f2150a0bac4c..895b73f23079 100644
> --- a/drivers/gpu/drm/drm_client_modeset.c
> +++ b/drivers/gpu/drm/drm_client_modeset.c
> @@ -114,33 +114,6 @@ drm_client_find_modeset(struct drm_client_dev *client, 
> struct drm_crtc *crtc)
>   return NULL;
>  }
>  
> -static struct drm_display_mode *
> -drm_connector_get_tiled_mode(struct drm_connector *connector)
> -{
> - struct drm_display_mode *mode;
> -
> - list_for_each_entry(mode, >modes, head) {
> - if (mode->hdisplay == connector->tile_h_size &&
> - mode->vdisplay == connector->tile_v_size)
> - return mode;
> - }
> - return NULL;
> -}
> -
> -static struct drm_display_mode *
> -drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
> -{
> - struct drm_display_mode *mode;
> -
> - list_for_each_entry(mode, >modes, head) {
> - if (mode->hdisplay == connector->tile_h_size &&
> - mode->vdisplay == connector->tile_v_size)
> - continue;
> - return mode;
> - }
> - return NULL;
> -}
> -
>  static struct drm_display_mode *
>  drm_connector_has_preferred_mode(struct drm_connector *connector, int width, 
> int height)
>  {
> @@ -375,14 +348,8 @@ static bool drm_client_target_preferred(struct 
> drm_connector **connectors,
>   struct drm_connector *connector;
>   u64 conn_configured = 0;
>   int tile_pass = 0;
> - int num_tiled_conns = 0;
>   int i;
>  
> - for (i = 0; i < connector_count; i++) {
> - if (connectors[i]->has_tile)
> - num_tiled_conns++;
> - }
> -
>  retry:
>   for (i = 0; i < connector_count; i++) {
>   connector = connectors[i];
> @@ -432,28 +399,6 @@ static bool drm_client_target_preferred(struct 
> drm_connector **connectors,
>   list_for_each_entry(modes[i], >modes, head)
>   break;
>   }
> - /*
> -  * In case of tiled mode if all tiles not present fallback to
> -  * first available non tiled mode.
> -  * After all tiles are present, try to find the tiled mode
> -  * for all and if tiled mode not present due to fbcon size
> -  * limitations, use first non tiled mode only for
> -  * tile 0,0 and set to no mode for all other tiles.
> -  */
> - if (connector->has_tile) {
> - if (num_tiled_conns <
> - connector->num_h_tile * connector->num_v_tile ||
> - (connector->tile_h_loc == 0 &&
> -  connector->tile_v_loc == 0 &&
> -  !drm_connector_get_tiled_mode(connector))) {
> -  

Re: [Intel-gfx] [PATCH 3/7] drm: Extract page_flip_{internal, atomic}()

2019-11-25 Thread Ville Syrjälä
On Mon, Nov 25, 2019 at 10:02:38AM +0100, Daniel Vetter wrote:
> On Fri, Nov 22, 2019 at 08:35:13PM +0200, Ville Syrjälä wrote:
> > On Tue, Nov 19, 2019 at 11:14:43AM +0100, Daniel Vetter wrote:
> > > On Fri, Nov 15, 2019 at 09:42:00PM +0200, Ville Syrjala wrote:
> > > > From: Ville Syrjälä 
> > > > 
> > > > Yank out the code for the plane->fb/old_fb/crtc handling from
> > > > the page flip path into page_flip_internal(), and provide a
> > > > simpler variant for atomic drivers.
> > > > 
> > > > We'll also move the fb vs. src viewport checks into the new
> > > > functions as they are slightly different between the two paths.
> > > > If the atomic .page_flip() implementations are guaranteed
> > > > to call drm_atomic_plane_check() we could even drop the check
> > > > entirely from page_flip_atomic(). For now toss in a FIXME.
> > > > 
> > > > v2: Bit more polish in page_flip_internal()
> > > > 
> > > > Signed-off-by: Ville Syrjälä 
> > > > ---
> > > >  drivers/gpu/drm/drm_plane.c | 159 +++-
> > > >  1 file changed, 102 insertions(+), 57 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> > > > index 38878da5b704..6052475a20a5 100644
> > > > --- a/drivers/gpu/drm/drm_plane.c
> > > > +++ b/drivers/gpu/drm/drm_plane.c
> > > > @@ -1031,13 +1031,109 @@ int drm_mode_cursor2_ioctl(struct drm_device 
> > > > *dev,
> > > > return drm_mode_cursor_common(dev, req, file_priv);
> > > >  }
> > > >  
> > > > +static int page_flip_check_fbs(const struct drm_framebuffer *fb,
> > > > +  const struct drm_framebuffer *old_fb)
> > > > +{
> > > > +   /* The framebuffer is currently unbound, presumably
> > > > +* due to a hotplug event, that userspace has not
> > > > +* yet discovered.
> > > > +*/
> > > > +   if (!old_fb)
> > > > +   return -EBUSY;
> > > > +
> > > > +   if (old_fb->format != fb->format) {
> > > > +   DRM_DEBUG_KMS("Page flip is not allowed to change frame 
> > > > buffer format.\n");
> > > > +   return -EINVAL;
> > > > +   }
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > > +static int page_flip_internal(struct drm_crtc *crtc,
> > > > + struct drm_framebuffer *fb,
> > > > + struct drm_pending_vblank_event *e,
> > > > + u32 flags,
> > > > + u32 target_vblank,
> > > > + struct drm_modeset_acquire_ctx *ctx)
> > > > +{
> > > > +   struct drm_plane *plane = crtc->primary;
> > > > +   int ret;
> > > > +
> > > > +   WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
> > > > +
> > > > +   ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
> > > > + >mode, fb);
> > > > +   if (ret)
> > > > +   return ret;
> > > > +
> > > > +   ret = page_flip_check_fbs(fb, plane->fb);
> > > > +   if (ret)
> > > > +   return ret;
> > > > +
> > > > +   plane->old_fb = plane->fb;
> > > > +   if (crtc->funcs->page_flip_target)
> > > > +   ret = crtc->funcs->page_flip_target(crtc, fb, e, flags,
> > > > +   target_vblank, ctx);
> > > > +   else
> > > > +   ret = crtc->funcs->page_flip(crtc, fb, e, flags, ctx);
> > > > +   if (ret) {
> > > > +   plane->old_fb = NULL;
> > > > +   return ret;
> > > > +   }
> > > > +
> > > > +   plane->fb = fb;
> > > > +   drm_framebuffer_get(plane->fb);
> > > > +
> > > > +   drm_framebuffer_put(plane->old_fb);
> > > > +   plane->old_fb = NULL;
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > > +static int page_flip_atomic(struct drm_crtc *crtc,
> > > > +   struct drm_framebuffer *fb,
> > > > +   struct drm_pending_vblank_event *e,
> > > > +   u32 flags,
> > > > +   u32 target_vblank,
> > > > +   struct drm_modeset_acquire_ctx *ctx)
> > > > +{
> > > > +   struct drm_plane *plane = crtc->primary;
> > > > +   struct drm_plane_state *plane_state = plane->state;
> > > > +   int ret;
> > > > +
> > > > +   WARN_ON(!drm_drv_uses_atomic_modeset(crtc->dev));
> > > > +
> > > > +   /*
> > > > +* FIXME: Can we assume all drivers end up calling
> > > > +* drm_atomic_plane_check() in their page flip paths?
> > > > +* If so we could remove this.
> > > > +*/
> > > 
> > > This is definitely wrong, core has to check these. Currently no driver
> > > checks this at all. I think you're thinking of
> > > drm_atomic_helper_check_plane_state().
> > 
> > No, I'm thinking of drm_atomic_plane_check(). That one already does the
> > "does the src rect fit into the fb" check. It gets called from
> > 

Re: [PATCH] drm/radeon: remove redundant assignment to variable ret

2019-11-25 Thread Alex Deucher
On Fri, Nov 22, 2019 at 6:15 PM Colin King  wrote:
>
> From: Colin Ian King 
>
> The variable ret is being initialized with a value that is never
> read and it is being updated later with a new value. The
> initialization is redundant and can be removed.
>
> Addresses-Coverity: ("Unused value")
> Signed-off-by: Colin Ian King 

Applied.  thanks!

Alex

> ---
>  drivers/gpu/drm/radeon/si_dpm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
> index 8148a7883de4..346315b3eebe 100644
> --- a/drivers/gpu/drm/radeon/si_dpm.c
> +++ b/drivers/gpu/drm/radeon/si_dpm.c
> @@ -5899,7 +5899,7 @@ static int 
> si_patch_single_dependency_table_based_on_leakage(struct radeon_devic
>
>  static int si_patch_dependency_tables_based_on_leakage(struct radeon_device 
> *rdev)
>  {
> -   int ret = 0;
> +   int ret;
>
> ret = si_patch_single_dependency_table_based_on_leakage(rdev,
> 
> >pm.dpm.dyn_state.vddc_dependency_on_sclk);
> --
> 2.24.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/amdgpu: Ensure ret is always initialized when using SOC15_WAIT_ON_RREG

2019-11-25 Thread Alex Deucher
On Mon, Nov 25, 2019 at 3:07 AM Nathan Chancellor
 wrote:
>
> Commit b0f3cd3191cd ("drm/amdgpu: remove unnecessary JPEG2.0 code from
> VCN2.0") introduced a new clang warning in the vcn_v2_0_stop function:
>
> ../drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c:1082:2: warning: variable 'r'
> is used uninitialized whenever 'while' loop exits because its condition
> is false [-Wsometimes-uninitialized]
> SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
> ^~
> ../drivers/gpu/drm/amd/amdgpu/../amdgpu/soc15_common.h:55:10: note:
> expanded from macro 'SOC15_WAIT_ON_RREG'
> while ((tmp_ & (mask)) != (expected_value)) {   \
>^~~
> ../drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c:1083:6: note: uninitialized use
> occurs here
> if (r)
> ^
> ../drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c:1082:2: note: remove the
> condition if it is always true
> SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
> ^
> ../drivers/gpu/drm/amd/amdgpu/../amdgpu/soc15_common.h:55:10: note:
> expanded from macro 'SOC15_WAIT_ON_RREG'
> while ((tmp_ & (mask)) != (expected_value)) {   \
>^
> ../drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c:1072:7: note: initialize the
> variable 'r' to silence this warning
> int r;
>  ^
>   = 0
> 1 warning generated.
>
> To prevent warnings like this from happening in the future, make the
> SOC15_WAIT_ON_RREG macro initialize its ret variable before the while
> loop that can time out. This macro's return value is always checked so
> it should set ret in both the success and fail path.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/776
> Signed-off-by: Nathan Chancellor 

Applied.  Thanks!

Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/soc15_common.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h 
> b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
> index 839f186e1182..19e870c79896 100644
> --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
> +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
> @@ -52,6 +52,7 @@
> uint32_t old_ = 0;  \
> uint32_t tmp_ = 
> RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
> uint32_t loop = adev->usec_timeout; \
> +   ret = 0;\
> while ((tmp_ & (mask)) != (expected_value)) {   \
> if (old_ != tmp_) { \
> loop = adev->usec_timeout;  \
> --
> 2.24.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/amd/powerplay: remove redundant assignment to variables HiSidd and LoSidd

2019-11-25 Thread Alex Deucher
On Fri, Nov 22, 2019 at 6:04 PM Colin King  wrote:
>
> From: Colin Ian King 
>
> The variables HiSidd and LoSidd are being initialized with values that
> are never read and are being updated a little later with a new value.
> The initialization is redundant and can be removed.
>
> Addresses-Coverity: ("Unused value")
> Signed-off-by: Colin Ian King 

Applied.  Thanks!

Alex

> ---
>  drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c 
> b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
> index 15590fd86ef4..868e2d5f6e62 100644
> --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
> +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
> @@ -653,8 +653,8 @@ static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct 
> pp_hwmgr *hwmgr)
>  static int ci_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
>  {
> struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend);
> -   uint16_t HiSidd = 
> smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd;
> -   uint16_t LoSidd = 
> smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd;
> +   uint16_t HiSidd;
> +   uint16_t LoSidd;
> struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table;
>
> HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
> --
> 2.24.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH libdrm v4] modetest: Add support for setting mode having floating vertical refresh rate

2019-11-25 Thread Ville Syrjälä
On Mon, Nov 25, 2019 at 07:34:37AM +, Devarsh Thakkar wrote:
> Ping. Just wanted to confirm if the patch is applied or anything still 
> pending from my side ?

Seems to work -> pushed.

One thing I noticed is that we still print the modes with an integer
vrefresh so it's a bit hard to know what value to pass in. Might be
nice to make it dumo the modes with %.2f vrefresh as well.

> 
> Also I tried to subscribe as per instructions at 
> https://lists.freedesktop.org/mailman/listinfo/dri-devel 
> Sometime back, but still not able to receive messages from mailing list. Is 
> there any other way to subscribe ?
> 
> Regards,
> Devarsh
> > -Original Message-
> > From: Devarsh Thakkar 
> > Sent: 15 November 2019 06:31
> > To: dri-devel@lists.freedesktop.org; ville.syrj...@linux.intel.com
> > Cc: Hyun Kwon ; vcu-team ;
> > Ranganathan Sk ; Dhaval Rajeshbhai Shah
> > ; Satish Kumar Nagireddy ;
> > Varunkumar Allagadapa ; Devarsh Thakkar
> > 
> > Subject: [PATCH libdrm v4] modetest: Add support for setting mode having
> > floating vertical refresh rate
> > 
> > For the scenario where user may require to modeset with a mode supporting
> > a fractional value for vertical refresh-rate, appropriate mode can be 
> > selected
> > by searching for mode having matching fractional vertical refresh rate using
> > below equation.
> > 
> > vrefresh = (1000 * pixel clock) / (htotal * vtotal) Hz.
> > 
> > We do this way since driver doesn't return float value of vrefresh as it 
> > use int
> > for vrefresh in struct drm_mode_info, but we can derive the actual value
> > using pixel clock, horizontal total size and vertical total size values.
> > 
> > So for e.g. if user want to select mode having 59.94 Hz as refresh rate then
> > with this patch it be can done as shown in below command, given there is an
> > appropriate mode is available :
> > 
> > modetest -M xlnx -s 39:1920x1080-59.94@BG24 -v
> > 
> > NOTE: Above command was tested on xilinx DRM driver with DP monitor
> > which was supporting mode having 59.94 Hz refresh rate.
> > 
> > V2: Update commit message
> > V3: Update with below changes as per review comments :
> >   1) Use epsilon for vrefresh comparison
> >   2) Use implicit type-casting wherever possible
> > V4: Keep patch version history on main commit message
> > 
> > Signed-off-by: Devarsh Thakkar 
> > Reviewed-by: Ville Syrjälä 
> > ---
> >  tests/modetest/modetest.c | 20 
> >  1 file changed, 12 insertions(+), 8 deletions(-)
> > 
> > diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index
> > e66be66..b4edfcb 100644
> > --- a/tests/modetest/modetest.c
> > +++ b/tests/modetest/modetest.c
> > @@ -54,6 +54,7 @@
> >  #ifdef HAVE_SYS_SELECT_H
> >  #include 
> >  #endif
> > +#include 
> > 
> >  #include "xf86drm.h"
> >  #include "xf86drmMode.h"
> > @@ -795,7 +796,7 @@ struct pipe_arg {
> > uint32_t crtc_id;
> > char mode_str[64];
> > char format_str[5];
> > -   unsigned int vrefresh;
> > +   float vrefresh;
> > unsigned int fourcc;
> > drmModeModeInfo *mode;
> > struct crtc *crtc;
> > @@ -822,11 +823,12 @@ struct plane_arg {
> > 
> >  static drmModeModeInfo *
> >  connector_find_mode(struct device *dev, uint32_t con_id, const char
> > *mode_str,
> > -const unsigned int vrefresh)
> > +   const float vrefresh)
> >  {
> > drmModeConnector *connector;
> > drmModeModeInfo *mode;
> > int i;
> > +   float mode_vrefresh;
> > 
> > connector = get_connector_by_id(dev, con_id);
> > if (!connector || !connector->count_modes) @@ -839,9 +841,11
> > @@ connector_find_mode(struct device *dev, uint32_t con_id, const char
> > *mode_str,
> >  * first mode that match with the name. Else, return
> > the mode that match
> >  * the name and the specified vertical refresh
> > frequency.
> >  */
> > +   mode_vrefresh = mode->clock * 1000.00
> > +   / (mode->htotal * mode->vtotal);
> > if (vrefresh == 0)
> > return mode;
> > -   else if (mode->vrefresh == vrefresh)
> > +   else if (fabs(mode_vrefresh - vrefresh) < 0.005)
> > return mode;
> > }
> > }
> > @@ -1393,8 +1397,8 @@ static void atomic_set_mode(struct device *dev,
> > struct pipe_arg *pipes, unsigned
> > if (pipe->mode == NULL)
> > continue;
> > 
> > -   printf("setting mode %s-%dHz on connectors ",
> > -  pipe->mode_str, pipe->mode->vrefresh);
> > +   printf("setting mode %s-%.2fHz on connectors ",
> > +  pipe->mode_str, pipe->vrefresh);
> > for (j = 0; j < pipe->num_cons; ++j) {
> > printf("%s, ", pipe->cons[j]);
> > add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe-
> > >crtc->crtc->crtc_id); @@ -1476,8 +1480,8 @@ static 

Re: [PATCH] drm/amd/display: Use NULL for pointer assignment in copy_stream_update_to_stream

2019-11-25 Thread Harry Wentland
On 2019-11-23 2:36 p.m., Nathan Chancellor wrote:
> Clang warns:
> 
> ../drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:1965:26: warning:
> expression which evaluates to zero treated as a null pointer constant of
> type 'struct dc_dsc_config *' [-Wnon-literal-null-conversion]
> update->dsc_config = false;
>  ^
> ../drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:1971:25: warning:
> expression which evaluates to zero treated as a null pointer constant of
> type 'struct dc_dsc_config *' [-Wnon-literal-null-conversion]
> update->dsc_config = false;
>  ^
> 2 warnings generated.
> 
> Fixes: f6fe4053b91f ("drm/amd/display: Use a temporary copy of the current 
> state when updating DSC config")
> Link: 
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FClangBuiltLinux%2Flinux%2Fissues%2F777data=02%7C01%7Charry.wentland%40amd.com%7Ceb5e55813307456cf7d608d7704c79c4%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C1%7C637101346080296409sdata=6HK3wWYMoILbiBisjoHkFwopV%2BuJYUh8wCDhMSvRQQ8%3Dreserved=0
> Signed-off-by: Nathan Chancellor 

Reviewed-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index c7db4f4810c6..2645d20e8c4c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -1962,13 +1962,13 @@ static void copy_stream_update_to_stream(struct dc 
> *dc,
>   if (!dc->res_pool->funcs->validate_bandwidth(dc, 
> dsc_validate_context, true)) {
>   stream->timing.dsc_cfg = old_dsc_cfg;
>   stream->timing.flags.DSC = old_dsc_enabled;
> - update->dsc_config = false;
> + update->dsc_config = NULL;
>   }
>  
>   dc_release_state(dsc_validate_context);
>   } else {
>   DC_ERROR("Failed to allocate new validate context for 
> DSC change\n");
> - update->dsc_config = false;
> + update->dsc_config = NULL;
>   }
>   }
>  }
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 1/2] drm/sched: Avoid job cleanup if sched thread is parked.

2019-11-25 Thread Andrey Grodzovsky
When the sched thread is parked we assume ring_mirror_list is
not accessed from here.

Signed-off-by: Andrey Grodzovsky 
Reviewed-by: Christian König 
---
 drivers/gpu/drm/scheduler/sched_main.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index d4cc728..6774955 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -635,9 +635,13 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
struct drm_sched_job *job;
unsigned long flags;
 
-   /* Don't destroy jobs while the timeout worker is running */
-   if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
-   !cancel_delayed_work(>work_tdr))
+   /*
+   * Don't destroy jobs while the timeout worker is running  OR thread
+   * is being parked and hence assumed to not touch ring_mirror_list
+   */
+   if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
+!cancel_delayed_work(>work_tdr)) ||
+__kthread_should_park(sched->thread))
return NULL;
 
spin_lock_irqsave(>job_list_lock, flags);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 2/2] drm/scheduler: Avoid accessing freed bad job.

2019-11-25 Thread Andrey Grodzovsky
Problem:
Due to a race between drm_sched_cleanup_jobs in sched thread and
drm_sched_job_timedout in timeout work there is a possiblity that
bad job was already freed while still being accessed from the
timeout thread.

Fix:
Instead of just peeking at the bad job in the mirror list
remove it from the list under lock and then put it back later when
we are garanteed no race with main sched thread is possible which
is after the thread is parked.

v2: Lock around processing ring_mirror_list in drm_sched_cleanup_jobs.

v3: Rebase on top of drm-misc-next. v2 is not needed anymore as
drm_sched_cleanup_jobs already has a lock there.

Signed-off-by: Andrey Grodzovsky 
Reviewed-by: Christian König 
Tested-by: Emily Deng 
---
 drivers/gpu/drm/scheduler/sched_main.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 6774955..a604dfa 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -284,10 +284,24 @@ static void drm_sched_job_timedout(struct work_struct 
*work)
unsigned long flags;
 
sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work);
+
+   /*
+* Protects against concurrent deletion in drm_sched_cleanup_jobs that
+* is already in progress.
+*/
+   spin_lock_irqsave(>job_list_lock, flags);
job = list_first_entry_or_null(>ring_mirror_list,
   struct drm_sched_job, node);
 
if (job) {
+   /*
+* Remove the bad job so it cannot be freed by already in 
progress
+* drm_sched_cleanup_jobs. It will be reinsrted back after 
sched->thread
+* is parked at which point it's safe.
+*/
+   list_del_init(>node);
+   spin_unlock_irqrestore(>job_list_lock, flags);
+
job->sched->ops->timedout_job(job);
 
/*
@@ -298,6 +312,8 @@ static void drm_sched_job_timedout(struct work_struct *work)
job->sched->ops->free_job(job);
sched->free_guilty = false;
}
+   } else {
+   spin_unlock_irqrestore(>job_list_lock, flags);
}
 
spin_lock_irqsave(>job_list_lock, flags);
@@ -370,6 +386,19 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
struct drm_sched_job *bad)
kthread_park(sched->thread);
 
/*
+* Reinsert back the bad job here - now it's safe as 
drm_sched_cleanup_jobs
+* cannot race against us and release the bad job at this point - we 
parked
+* (waited for) any in progress (earlier) cleanups and any later ones 
will
+* bail out due to sched->thread being parked.
+*/
+   if (bad && bad->sched == sched)
+   /*
+* Add at the head of the queue to reflect it was the earliest
+* job extracted.
+*/
+   list_add(>node, >ring_mirror_list);
+
+   /*
 * Iterate the job list from later to  earlier one and either deactive
 * their HW callbacks or remove them from mirror list if they already
 * signaled.
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/amd: Fix Kconfig indentation

2019-11-25 Thread Alex Deucher
Applied.  Thanks!

Alex

On Thu, Nov 21, 2019 at 11:13 AM Deucher, Alexander
 wrote:
>
> Reviewed-by: Alex Deucher 
> 
> From: Krzysztof Kozlowski 
> Sent: Thursday, November 21, 2019 8:29 AM
> To: linux-ker...@vger.kernel.org 
> Cc: Krzysztof Kozlowski ; Deucher, Alexander 
> ; Koenig, Christian ; 
> Zhou, David(ChunMing) ; David Airlie ; 
> Daniel Vetter ; amd-...@lists.freedesktop.org 
> ; dri-devel@lists.freedesktop.org 
> 
> Subject: [PATCH] drm/amd: Fix Kconfig indentation
>
> Adjust indentation from spaces to tab (+optional two spaces) as in
> coding style with command like:
> $ sed -e 's/^/\t/' -i */Kconfig
>
> Signed-off-by: Krzysztof Kozlowski 
> ---
>  drivers/gpu/drm/amd/acp/Kconfig | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/acp/Kconfig b/drivers/gpu/drm/amd/acp/Kconfig
> index d968c2471412..19bae9100da4 100644
> --- a/drivers/gpu/drm/amd/acp/Kconfig
> +++ b/drivers/gpu/drm/amd/acp/Kconfig
> @@ -2,11 +2,11 @@
>  menu "ACP (Audio CoProcessor) Configuration"
>
>  config DRM_AMD_ACP
> -   bool "Enable AMD Audio CoProcessor IP support"
> -   depends on DRM_AMDGPU
> -   select MFD_CORE
> -   select PM_GENERIC_DOMAINS if PM
> -   help
> +   bool "Enable AMD Audio CoProcessor IP support"
> +   depends on DRM_AMDGPU
> +   select MFD_CORE
> +   select PM_GENERIC_DOMAINS if PM
> +   help
>  Choose this option to enable ACP IP support for AMD SOCs.
>  This adds the ACP (Audio CoProcessor) IP driver and wires
>  it up into the amdgpu driver.  The ACP block provides the DMA
> --
> 2.17.1
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 3/4] ARM: dts: dra76-evm: add HDMI output

2019-11-25 Thread Tomi Valkeinen
Add DRA76 EVM HDMI output for the base board.

Signed-off-by: Tomi Valkeinen 
---
 arch/arm/boot/dts/dra76-evm.dts | 66 +
 1 file changed, 66 insertions(+)

diff --git a/arch/arm/boot/dts/dra76-evm.dts b/arch/arm/boot/dts/dra76-evm.dts
index 1fb6f13fb5e2..86a3e79909a8 100644
--- a/arch/arm/boot/dts/dra76-evm.dts
+++ b/arch/arm/boot/dts/dra76-evm.dts
@@ -13,6 +13,13 @@
model = "TI DRA762 EVM";
compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7";
 
+   aliases {
+   display0 = 
+
+   sound0 = 
+   sound1 = 
+   };
+
memory@0 {
device_type = "memory";
reg = <0x0 0x8000 0x0 0x8000>;
@@ -116,6 +123,48 @@
regulator-min-microvolt = <180>;
regulator-max-microvolt = <180>;
};
+
+   hdmi0: connector {
+   compatible = "hdmi-connector";
+   label = "hdmi";
+
+   type = "a";
+
+   port {
+   hdmi_connector_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+
+   tpd12s015: encoder {
+   compatible = "ti,tpd12s015";
+
+   gpios = < 30 GPIO_ACTIVE_HIGH>,   /* gpio7_30, CT CP HPD 
*/
+   < 31 GPIO_ACTIVE_HIGH>,   /* gpio7_31, LS OE */
+   < 12 GPIO_ACTIVE_HIGH>;   /* gpio7_12/sp1_cs2, 
HPD */
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   tpd12s015_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   tpd12s015_out: endpoint {
+   remote-endpoint = <_connector_in>;
+   };
+   };
+   };
+   };
 };
 
  {
@@ -411,6 +460,23 @@
phy-supply = <_reg>;
 };
 
+ {
+   status = "ok";
+   vdda_video-supply = <_reg>;
+};
+
+ {
+   status = "ok";
+
+   vdda-supply = <_reg>;
+
+   port {
+   hdmi_out: endpoint {
+   remote-endpoint = <_in>;
+   };
+   };
+};
+
  {
spi-max-frequency = <9600>;
m25p80@0 {
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/4] ARM: dts: am57xx-idk-common: add HDMI to the common dtsi

2019-11-25 Thread Tomi Valkeinen
AM571x/AM572x/AM574x IDK base boards have HDMI output. Add DT nodes to
am57xx-idk-common.dtsi to enable HDMI.

Signed-off-by: Tomi Valkeinen 
---
 arch/arm/boot/dts/am57xx-idk-common.dtsi | 59 
 1 file changed, 59 insertions(+)

diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi 
b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 423855a2a2d6..a9c8f2859aea 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -9,6 +9,7 @@
aliases {
rtc0 = _rtc;
rtc1 = 
+   display0 = 
};
 
chosen {
@@ -96,6 +97,48 @@
default-state = "off";
};
};
+
+   hdmi0: connector@0 {
+   compatible = "hdmi-connector";
+   label = "hdmi";
+
+   type = "a";
+
+   port {
+   hdmi_connector_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+
+   tpd12s015: encoder@0 {
+   compatible = "ti,tpd12s016", "ti,tpd12s015";
+
+   gpios = <0>, /* optional CT_CP_HPD */
+   <0>, /* optional LS_OE */
+   < 12 GPIO_ACTIVE_HIGH>;   /* HPD */
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   tpd12s015_in: endpoint@0 {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   tpd12s015_out: endpoint@0 {
+   remote-endpoint = <_connector_in>;
+   };
+   };
+   };
+   };
 };
 
 _pmx_core {
@@ -490,3 +533,19 @@
  {
vdd-supply = <_reg>;
 };
+
+ {
+   status = "okay";
+
+   vdda-supply = <_reg>;
+
+   port {
+   hdmi_out: endpoint {
+   remote-endpoint = <_in>;
+   };
+   };
+};
+
+ {
+   status = "okay";
+};
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/4] ARM: dts: am437x-epos-evm: add HDMI support

2019-11-25 Thread Tomi Valkeinen
From: Jyri Sarha 

Add HDMI support for AM43x EPOS EVM. The HDMI uses SiI9022 HDMI
encoder for audio and display, and it is mutually exclusive with the
LCD and analogue audio. The choice between LCD + analogue audio and
HDMI + HDMI-audio is made by booting either with am43x-epos-evm.dtb or
am43x-epos-evm-hdmi.dtb.

Signed-off-by: Jyri Sarha 
Signed-off-by: Tomi Valkeinen 
---
 arch/arm/boot/dts/Makefile|   1 +
 arch/arm/boot/dts/am43x-epos-evm-hdmi.dts | 120 ++
 2 files changed, 121 insertions(+)
 create mode 100644 arch/arm/boot/dts/am43x-epos-evm-hdmi.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 612149069180..43ba465596ad 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -777,6 +777,7 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
omap4-var-stk-om44.dtb
 dtb-$(CONFIG_SOC_AM43XX) += \
am43x-epos-evm.dtb \
+   am43x-epos-evm-hdmi.dtb \
am437x-cm-t43.dtb \
am437x-gp-evm.dtb \
am437x-gp-evm-hdmi.dtb \
diff --git a/arch/arm/boot/dts/am43x-epos-evm-hdmi.dts 
b/arch/arm/boot/dts/am43x-epos-evm-hdmi.dts
new file mode 100644
index ..314e9e8c513c
--- /dev/null
+++ b/arch/arm/boot/dts/am43x-epos-evm-hdmi.dts
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/* AM437x EPOS EVM with HDMI output */
+
+#include "am43x-epos-evm.dts"
+
+/delete-node/ 
+
+/ {
+   aliases {
+   display0 = 
+   };
+
+   hdmi: connector {
+   compatible = "hdmi-connector";
+   label = "hdmi";
+
+   type = "b";
+
+   port {
+   hdmi_connector_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+
+   sound@1 {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "HDMI";
+   simple-audio-card,format = "i2s";
+   simple-audio-card,bitclock-master = <_dailink_master>;
+   simple-audio-card,frame-master = <_dailink_master>;
+   hdmi_dailink_master: simple-audio-card,cpu {
+   sound-dai = <>;
+   system-clock-frequency = <2400>;
+   system-clock-direction-out;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <>;
+   };
+   };
+
+   sii9022_mclk: sii9022_mclk {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <1200>;
+   };
+};
+
+_bl {
+   status = "disabled";
+};
+
+ {
+   status = "disabled";
+};
+
+ {
+   status = "disabled";
+};
+
+_pinmux {
+   sii9022_pins: sii9022_pins {
+   pinctrl-single,pins = <
+   AM4372_IOPAD(0x848, PIN_INPUT | MUX_MODE7)  /* 
gpmc_a2.gpio1_18 */
+   >;
+   };
+};
+
+ {
+   sii9022: sii9022@3b {
+   #sound-dai-cells = <0>;
+   compatible = "sil,sii9022";
+   reg = <0x3b>;
+
+   interrupt-parent = <>;
+   interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
+
+   sil,i2s-data-lanes = < 0 >;
+   clocks = <_mclk>;
+   clock-names = "mclk";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   sii9022_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   sii9022_out: endpoint {
+   remote-endpoint = <_connector_in>;
+   };
+   };
+   };
+   };
+};
+
+_out {
+   remote-endpoint = <_in>;
+   data-lines = <24>;
+};
+
+/* Override SelLCDorHDMI from am437x-epos-evm.dts to select HDMI */
+ {
+   p1 {
+   output-low;
+   };
+};
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/4] ARM: dts: am437x-gp-evm: add HDMI support

2019-11-25 Thread Tomi Valkeinen
Add HDMI support for AM437x GP EVM. The HDMI uses SiI9022 HDMI encoder,
and is mutually exclusive with the LCD. The choice between LCD and HDMI
is made by booting either with am437x-gp-evm.dtb or
am437x-gp-evm-hdmi.dtb.

Signed-off-by: Tomi Valkeinen 
---
 arch/arm/boot/dts/Makefile   |   1 +
 arch/arm/boot/dts/am437x-gp-evm-hdmi.dts | 112 +++
 2 files changed, 113 insertions(+)
 create mode 100644 arch/arm/boot/dts/am437x-gp-evm-hdmi.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b21b3a64641a..612149069180 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -779,6 +779,7 @@ dtb-$(CONFIG_SOC_AM43XX) += \
am43x-epos-evm.dtb \
am437x-cm-t43.dtb \
am437x-gp-evm.dtb \
+   am437x-gp-evm-hdmi.dtb \
am437x-idk-evm.dtb \
am437x-sbc-t43.dtb \
am437x-sk-evm.dtb
diff --git a/arch/arm/boot/dts/am437x-gp-evm-hdmi.dts 
b/arch/arm/boot/dts/am437x-gp-evm-hdmi.dts
new file mode 100644
index ..580a1e3e0dcd
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-gp-evm-hdmi.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/* AM437x GP EVM with HDMI output */
+
+#include "am437x-gp-evm.dts"
+
+/delete-node/ 
+
+/ {
+   aliases {
+   display0 = 
+   };
+
+   hdmi: connector {
+   compatible = "hdmi-connector";
+   label = "hdmi";
+
+   type = "b";
+
+   port {
+   hdmi_connector_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+
+   sound@1 {
+   compatible = "simple-audio-card";
+   simple-audio-card,name = "HDMI";
+   simple-audio-card,format = "i2s";
+   simple-audio-card,bitclock-master = <_dailink_master>;
+   simple-audio-card,frame-master = <_dailink_master>;
+   hdmi_dailink_master: simple-audio-card,cpu {
+   sound-dai = <>;
+   system-clock-frequency = <2400>;
+   system-clock-direction-out;
+   };
+
+   simple-audio-card,codec {
+   sound-dai = <>;
+   };
+   };
+
+   sii9022_mclk: sii9022_mclk {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <1200>;
+   };
+};
+
+_bl {
+   status = "disabled";
+};
+
+ {
+   status = "disabled";
+};
+
+ {
+   status = "disabled";
+};
+
+ {
+   sii9022: sii9022@3b {
+   #sound-dai-cells = <0>;
+   compatible = "sil,sii9022";
+   reg = <0x3b>;
+
+   interrupt-parent = <>;
+   interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+
+   sil,i2s-data-lanes = < 0 >;
+   clocks = <_mclk>;
+   clock-names = "mclk";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   sii9022_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   sii9022_out: endpoint {
+   remote-endpoint = <_connector_in>;
+   };
+   };
+   };
+   };
+};
+
+_out {
+   remote-endpoint = <_in>;
+   data-lines = <24>;
+};
+
+/* Override SelLCDorHDMI from am437x-gp-evm.dts to select HDMI */
+ {
+   p8 {
+   output-low;
+   };
+};
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2] video: hyperv: hyperv_fb: Use physical memory for fb on HyperV Gen 1 VMs.

2019-11-25 Thread kbuild test robot
Hi Wei,

I love your patch! Yet something to improve:

[auto build test ERROR on next-20191122]
[cannot apply to linus/master v5.4-rc8 v5.4-rc7 v5.4-rc6 v5.4]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:
https://github.com/0day-ci/linux/commits/Wei-Hu/video-hyperv-hyperv_fb-Use-physical-memory-for-fb-on-HyperV-Gen-1-VMs/20191124-163533
base:b9d3d01405061bb42358fe53f824e894a1922ced
config: i386-randconfig-b003-20191125 (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 

All errors (new ones prefixed by >>):

   ld: kernel/dma/contiguous.o: in function `dma_alloc_from_contiguous':
>> kernel/dma/contiguous.c:199: undefined reference to `cma_alloc'
>> ld: kernel/dma/contiguous.c:199: undefined reference to `cma_alloc'
   ld: kernel/dma/contiguous.o: in function `dma_release_from_contiguous':
>> kernel/dma/contiguous.c:215: undefined reference to `cma_release'
>> ld: kernel/dma/contiguous.c:215: undefined reference to `cma_release'
   ld: kernel/dma/contiguous.o: in function `dma_alloc_contiguous':
   kernel/dma/contiguous.c:248: undefined reference to `cma_alloc'
   ld: kernel/dma/contiguous.o: in function `dma_free_contiguous':
   kernel/dma/contiguous.c:267: undefined reference to `cma_release'
   ld: kernel/dma/contiguous.c:267: undefined reference to `cma_release'
   ld: kernel/dma/contiguous.o: in function `dma_contiguous_reserve_area':
>> kernel/dma/contiguous.c:169: undefined reference to `cma_declare_contiguous'
>> ld: kernel/dma/contiguous.c:175: undefined reference to `cma_get_size'
>> ld: kernel/dma/contiguous.c:175: undefined reference to `cma_get_base'

vim +199 kernel/dma/contiguous.c

c64be2bb1c6eb4 drivers/base/dma-contiguous.c Marek Szyprowski 2011-12-29  145  
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  146  
/**
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  147   
* dma_contiguous_reserve_area() - reserve custom contiguous area
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  148   
* @size: Size of the reserved area (in bytes),
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  149   
* @base: Base address of the reserved area optional, use 0 for any
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  150   
* @limit: End address of the reserved memory (optional, 0 for any).
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  151   
* @res_cma: Pointer to store the created cma region.
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  152   
* @fixed: hint about where to place the reserved area
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  153   
*
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  154   
* This function reserves memory from early allocator. It should be
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  155   
* called by arch specific code once the early allocator (memblock or bootmem)
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  156   
* has been activated and all other subsystems have already allocated/reserved
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  157   
* memory. This function allows to create custom reserved areas for specific
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  158   
* devices.
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  159   
*
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  160   
* If @fixed is true, reserve contiguous area at exactly @base.  If false,
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  161   
* reserve in range from @base to @limit.
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  162   
*/
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  163  
int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  164   
   phys_addr_t limit, struct cma **res_cma,
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  165   
   bool fixed)
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  166  {
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  167   
int ret;
3162bbd7e65b9c drivers/base/dma-contiguous.c Joonsoo Kim  2014-08-06  168  
f318dd083

[Bug 110795] Unable to install on latest Ubuntu (19.04)

2019-11-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=110795

--- Comment #40 from phoenixsamp...@gmail.com ---
CRITICAL ERROR:

Loading new amdgpu-19.30-934563 DKMS files...
Building for 5.3.0-20-generic
Building for architecture x86_64
Building initial module for 5.3.0-20-generic
ERROR (dkms apport): kernel package linux-headers-5.3.0-20-generic is not
supported
Error! Bad return status for module build on kernel: 5.3.0-20-generic (x86_64)

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v1 08/29] dt-bindings: interconnect: tegra: Add initial IDs

2019-11-25 Thread Thierry Reding
On Thu, Nov 21, 2019 at 08:14:35PM +0300, Dmitry Osipenko wrote:
> 19.11.2019 19:56, Dmitry Osipenko пишет:
> > 19.11.2019 09:25, Thierry Reding пишет:
> >> On Mon, Nov 18, 2019 at 11:02:26PM +0300, Dmitry Osipenko wrote:
> >>> Define interconnect IDs for memory controller (MC), external memory
> >>> controller (EMC), external memory (EMEM) and memory clients of display
> >>> controllers (DC).
> >>>
> >>> Signed-off-by: Dmitry Osipenko 
> >>> ---
> >>>  include/dt-bindings/interconnect/tegra-icc.h | 11 +++
> >>>  1 file changed, 11 insertions(+)
> >>>  create mode 100644 include/dt-bindings/interconnect/tegra-icc.h
> > 
> > 
> > Hello Thierry,
> > 
> >> There was a bit of discussion regarding this for a recent patch that I
> >> was working on, see:
> >>
> >>http://patchwork.ozlabs.org/project/linux-tegra/list/?series=140318
> > 
> > Thank you very much for the link.
> > 
> >> I'd rather not use an additional set of definitions for this. The memory
> >> controller already has a set of native IDs for memory clients that I
> >> think we can reuse for this.
> > 
> > I missed that it's fine to have multiple ICC connections defined
> > per-path, at quick glance looks like indeed it should be fine to re-use
> > MC IDs.
> 
> Well, it is not quite correct to have multiple connections per-path.
> 
> Please take look at interconnect's binding and core.c:
> 
>   1. there should be one src->dst connection per-path
>   2. each connection should comprise of one source and one destination nodes
> 
> >> I've only added these client IDs for Tegra194 because that's where we
> >> need it to actually describe a specific hardware quirk, but I can come
> >> up with the equivalent for older chips as well.
> > 
> > Older Tegra SoCs have hardware units connected to MC through AHB bus,
> > like USB for example. These units do not have MC client IDs and there is
> > no MC ID defined for the AHB bus either, but probably it won't be a
> > problem to define IDs for them if will be necessary.
> > 
> 
> Since interconnect binding requires to define both source and
> destination nodes for the path, then MC IDs are not enough in order to
> define interconnect path because these IDs represent only the source
> nodes. Destination node should be either EMC or EMEM.

This doesn't really map well to Tegra. The source of the path is always
the device and the destination is always the memory controller. We also
can have multiple paths between a device and the memory controller. The
typical case is to have at least a read and a write path, but there are
a number of devices that have multiple read and/or multiple write paths
to the memory controller.

Or perhaps I'm looking at this the wrong way, and what we really ought
to describe is the paths with MC sitting in the middle. So it'd be
something like:

MC ID --- source ---> MC --- destination ---> EMC

for write paths and:

EMC --- source ---> MC --- destination ---> MC ID

for read paths. I have no idea what would be a good connection ID for
EMC, since I don't think MC really differentiates at that level. Perhaps
#interconnect-cells = <0> for EMC would be appropriate.

This would make the bindings look more like this, taking a random sample
from the above series:

ethernet@249 {
...
interconnects = <  TEGRA194_MEMORY_CLIENT_EQOSR>,
< TEGRA194_MEMORY_CLIENT_EQOSW >;
interconnect-names = "dma-mem", "dma-mem";
...
};

In words, the above would mean that for the ethernet device there is one
path (a read slave interface) where data flows from the EMC through the
MC to the device with memory client ID TEGRA194_MEMORY_CLIENT_EQOSR. The
second path (a write slave interface) describes data flowing from the
device (with memory client ID TEGRA194_MEMORY_CLIENT_EQOSW) through the
MC and towards the EMC.

Irrespective of the above, I think we definitely need to keep separate
IDs for read and write paths because each of them have separate controls
for arbitration and latency allowance. So each of those may need to be
separately configurable.

Does that make sense?

Thierry


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 08/15] drm/tegra: Remove dma_buf->k(un)map

2019-11-25 Thread Thierry Reding
On Mon, Nov 18, 2019 at 11:35:29AM +0100, Daniel Vetter wrote:
> No in-tree users left.
> 
> Signed-off-by: Daniel Vetter 
> Cc: Thierry Reding 
> Cc: Jonathan Hunter 
> Cc: linux-te...@vger.kernel.org
> ---
>  drivers/gpu/drm/tegra/gem.c | 12 
>  1 file changed, 12 deletions(-)

Same as before, I don't see any regressions when running some of the
grate tests, and there's obviously no longer any reason to keep these
functions around given that they are no longer used, so:

Reviewed-by: Thierry Reding 
Tested-by: Thierry Reding 


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 02/15] drm/tegra: Delete host1x_bo_ops->k(un)map

2019-11-25 Thread Thierry Reding
On Mon, Nov 18, 2019 at 11:35:23AM +0100, Daniel Vetter wrote:
> It doesn't have any callers anymore.
> 
> Aside: The ->mmap/munmap hooks have a bit a confusing name, they don't
> do userspace mmaps, but a kernel vmap. I think most places use vmap
> for this, except ttm, which uses kmap for vmap for added confusion.
> mmap seems entirely for userspace mappings set up through mmap(2)
> syscall.
> 
> Signed-off-by: Daniel Vetter 
> Cc: Thierry Reding 
> Cc: Jonathan Hunter 
> Cc: linux-te...@vger.kernel.org
> ---
>  drivers/gpu/drm/tegra/gem.c | 28 
>  include/linux/host1x.h  | 13 -
>  2 files changed, 41 deletions(-)

Tested along with the rest of the series and this is obviously right now
that the only user is gone, so:

Reviewed-by: Thierry Reding 
Tested-by: Thierry Reding 


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 01/15] drm/tegra: Map cmdbuf once for reloc processing

2019-11-25 Thread Thierry Reding
On Mon, Nov 18, 2019 at 11:35:22AM +0100, Daniel Vetter wrote:
> A few reasons to drop kmap:
> 
> - For native objects all we do is look at obj->vaddr anyway, so might
>   as well not call functions for every page.
> 
> - Reloc-processing on dma-buf is ... questionable.
> 
> - Plus most dma-buf that bother kernel cpu mmaps give you at least
>   vmap, much less kmaps. And all the ones relevant for arm-soc are
>   again doing a obj->vaddr game anyway, there's no real kmap going on
>   on arm it seems.
> 
> Plus this seems to be the only real in-tree user of dma_buf_kmap, and
> I'd like to get rid of that.
> 
> Signed-off-by: Daniel Vetter 
> Cc: Thierry Reding 
> Cc: linux-te...@vger.kernel.org
> ---
>  drivers/gpu/host1x/job.c | 21 +++--
>  1 file changed, 7 insertions(+), 14 deletions(-)

This looks correct to me, and running some of the grate project's tests
against this works just fine, so:

Reviewed-by: Thierry Reding 
Tested-by: Thierry Reding 

> diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
> index 25ca54de8fc5..60b2fedd0061 100644
> --- a/drivers/gpu/host1x/job.c
> +++ b/drivers/gpu/host1x/job.c
> @@ -244,8 +244,7 @@ static unsigned int pin_job(struct host1x *host, struct 
> host1x_job *job)
>  
>  static int do_relocs(struct host1x_job *job, struct host1x_job_gather *g)
>  {
> - u32 last_page = ~0;
> - void *cmdbuf_page_addr = NULL;
> + void *cmdbuf_addr = NULL;
>   struct host1x_bo *cmdbuf = g->bo;
>   unsigned int i;
>  
> @@ -267,28 +266,22 @@ static int do_relocs(struct host1x_job *job, struct 
> host1x_job_gather *g)
>   goto patch_reloc;
>   }
>  
> - if (last_page != reloc->cmdbuf.offset >> PAGE_SHIFT) {
> - if (cmdbuf_page_addr)
> - host1x_bo_kunmap(cmdbuf, last_page,
> -  cmdbuf_page_addr);
> + if (!cmdbuf_addr) {
> + cmdbuf_addr = host1x_bo_mmap(cmdbuf);
>  
> - cmdbuf_page_addr = host1x_bo_kmap(cmdbuf,
> - reloc->cmdbuf.offset >> PAGE_SHIFT);
> - last_page = reloc->cmdbuf.offset >> PAGE_SHIFT;
> -
> - if (unlikely(!cmdbuf_page_addr)) {
> + if (unlikely(!cmdbuf_addr)) {
>   pr_err("Could not map cmdbuf for relocation\n");
>   return -ENOMEM;
>   }
>   }
>  
> - target = cmdbuf_page_addr + (reloc->cmdbuf.offset & ~PAGE_MASK);
> + target = cmdbuf_addr + reloc->cmdbuf.offset;
>  patch_reloc:
>   *target = reloc_addr;
>   }
>  
> - if (cmdbuf_page_addr)
> - host1x_bo_kunmap(cmdbuf, last_page, cmdbuf_page_addr);
> + if (cmdbuf_addr)
> + host1x_bo_munmap(cmdbuf, cmdbuf_addr);
>  
>   return 0;
>  }
> -- 
> 2.24.0
> 


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 RESEND] drm/bridge/synopsys: dsi: driver-specific configuration of phy timings

2019-11-25 Thread Heiko Stübner
Am Montag, 25. November 2019, 11:09:39 CET schrieb Neil Armstrong:
> Hi,
> 
> On 25/11/2019 10:31, Heiko Stuebner wrote:
> > From: Heiko Stuebner 
> > 
> > The timing values for dw-dsi are often dependent on the used display and
> > according to Philippe Cornu will most likely also depend on the used phy
> > technology in the soc-specific implementation.
> > 
> > To solve this and allow specific implementations to define them as needed
> > add a new get_timing callback to phy_ops and call this from the dphy_timing
> > function to retrieve the necessary values for the specific mode.
> > 
> > Right now this handles the hs2lp + lp2hs where Rockchip SoCs need handling
> > according to the phy speed, while STM seems to be ok with static values.
> > 
> > changes in v3:
> > - check existence of phy_ops->get_timing in __dw_mipi_dsi_probe()
> > - emit actual error when get_timing() call fails
> > - add tags from Philippe and Yannick
> > 
> > changes in v2:
> > - add driver-specific handling, don't force all bridge users to use
> >   the same timings, as suggested by Philippe
> > 
> > Suggested-by: Philippe Cornu 
> > Signed-off-by: Heiko Stuebner 
> > Reviewed-by: Philippe Cornu 
> > Tested-by: Yannick Fertre 
> > ---
> > Resend because I seem to have forgotten to Cc mailing lists
> > 
> >  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 27 +--
> >  drivers/gpu/drm/rockchip/Kconfig  |  1 +
> >  .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 78 +++
> >  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 13 
> >  include/drm/bridge/dw_mipi_dsi.h  |  9 +++
> >  5 files changed, 121 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> > b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > index c214c6389918..b8b112278690 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > @@ -727,7 +727,15 @@ static void dw_mipi_dsi_vertical_timing_config(struct 
> > dw_mipi_dsi *dsi,
> >  
> >  static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
> >  {
> > +   const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
> > +   struct dw_mipi_dsi_dphy_timing timing;
> > u32 hw_version;
> > +   int ret;
> > +
> > +   ret = phy_ops->get_timing(dsi->plat_data->priv_data,
> > + dsi->lane_mbps, );
> > +   if (ret)
> > +   DRM_DEV_ERROR(dsi->dev, "Retrieving phy timings failed\n");
> >  
> > /*
> >  * TODO dw drv improvements
> > @@ -740,16 +748,20 @@ static void dw_mipi_dsi_dphy_timing_config(struct 
> > dw_mipi_dsi *dsi)
> > hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
> >  
> > if (hw_version >= HWVER_131) {
> > -   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
> > - PHY_LP2HS_TIME_V131(0x40));
> > +   dsi_write(dsi, DSI_PHY_TMR_CFG,
> > + PHY_HS2LP_TIME_V131(timing.data_hs2lp) |
> > + PHY_LP2HS_TIME_V131(timing.data_lp2hs));
> > dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(1));
> > } else {
> > -   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
> > - PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(1));
> > +   dsi_write(dsi, DSI_PHY_TMR_CFG,
> > + PHY_HS2LP_TIME(timing.data_hs2lp) |
> > + PHY_LP2HS_TIME(timing.data_lp2hs) |
> > + MAX_RD_TIME(1));
> > }
> >  
> > -   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
> > - | PHY_CLKLP2HS_TIME(0x40));
> > +   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG,
> > + PHY_CLKHS2LP_TIME(timing.clk_hs2lp) |
> > + PHY_CLKLP2HS_TIME(timing.clk_lp2hs));
> >  }
> >  
> >  static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
> > @@ -999,7 +1011,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
> > dsi->dev = dev;
> > dsi->plat_data = plat_data;
> >  
> > -   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
> > +   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
> > +   !plat_data->phy_ops->get_timing) {
> > DRM_ERROR("Phy not properly configured\n");
> > return ERR_PTR(-ENODEV);
> > }
> > diff --git a/drivers/gpu/drm/rockchip/Kconfig 
> > b/drivers/gpu/drm/rockchip/Kconfig
> > index 6f4222f8beeb..4b7a276994ce 100644
> > --- a/drivers/gpu/drm/rockchip/Kconfig
> > +++ b/drivers/gpu/drm/rockchip/Kconfig
> > @@ -46,6 +46,7 @@ config ROCKCHIP_DW_HDMI
> >  
> >  config ROCKCHIP_DW_MIPI_DSI
> > bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
> > +   select GENERIC_PHY_MIPI_DPHY
> > help
> >   This selects support for Rockchip SoC specific extensions
> >   for the Synopsys DesignWare HDMI driver. If you want to
> > diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 

[PATCH v4] drm/bridge/synopsys: dsi: driver-specific configuration of phy timings

2019-11-25 Thread Heiko Stuebner
From: Heiko Stuebner 

The timing values for dw-dsi are often dependent on the used display and
according to Philippe Cornu will most likely also depend on the used phy
technology in the soc-specific implementation.

To solve this and allow specific implementations to define them as needed
add a new get_timing callback to phy_ops and call this from the dphy_timing
function to retrieve the necessary values for the specific mode.

Right now this handles the hs2lp + lp2hs where Rockchip SoCs need handling
according to the phy speed, while STM seems to be ok with static values.

changes in v4:
- rebase to make it directly fit on top of drm-misc-next after all

changes in v3:
- check existence of phy_ops->get_timing in __dw_mipi_dsi_probe()
- emit actual error when get_timing() call fails
- add tags from Philippe and Yannick

changes in v2:
- add driver-specific handling, don't force all bridge users to use
  the same timings, as suggested by Philippe

Suggested-by: Philippe Cornu 
Signed-off-by: Heiko Stuebner 
Reviewed-by: Philippe Cornu 
Tested-by: Yannick Fertre 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 27 +--
 drivers/gpu/drm/rockchip/Kconfig  |  1 +
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 78 +++
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 13 
 include/drm/bridge/dw_mipi_dsi.h  |  9 +++
 5 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 49f5600a1dea..eb46f3e12418 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -718,7 +718,15 @@ static void dw_mipi_dsi_vertical_timing_config(struct 
dw_mipi_dsi *dsi,
 
 static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
 {
+   const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
+   struct dw_mipi_dsi_dphy_timing timing;
u32 hw_version;
+   int ret;
+
+   ret = phy_ops->get_timing(dsi->plat_data->priv_data,
+ dsi->lane_mbps, );
+   if (ret)
+   DRM_DEV_ERROR(dsi->dev, "Retrieving phy timings failed\n");
 
/*
 * TODO dw drv improvements
@@ -731,16 +739,20 @@ static void dw_mipi_dsi_dphy_timing_config(struct 
dw_mipi_dsi *dsi)
hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
 
if (hw_version >= HWVER_131) {
-   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
- PHY_LP2HS_TIME_V131(0x40));
+   dsi_write(dsi, DSI_PHY_TMR_CFG,
+ PHY_HS2LP_TIME_V131(timing.data_hs2lp) |
+ PHY_LP2HS_TIME_V131(timing.data_lp2hs));
dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(1));
} else {
-   dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
- PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(1));
+   dsi_write(dsi, DSI_PHY_TMR_CFG,
+ PHY_HS2LP_TIME(timing.data_hs2lp) |
+ PHY_LP2HS_TIME(timing.data_lp2hs) |
+ MAX_RD_TIME(1));
}
 
-   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
- | PHY_CLKLP2HS_TIME(0x40));
+   dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG,
+ PHY_CLKHS2LP_TIME(timing.clk_hs2lp) |
+ PHY_CLKLP2HS_TIME(timing.clk_lp2hs));
 }
 
 static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
@@ -990,7 +1002,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->dev = dev;
dsi->plat_data = plat_data;
 
-   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
+   if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
+   !plat_data->phy_ops->get_timing) {
DRM_ERROR("Phy not properly configured\n");
return ERR_PTR(-ENODEV);
}
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 6f4222f8beeb..4b7a276994ce 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -46,6 +46,7 @@ config ROCKCHIP_DW_HDMI
 
 config ROCKCHIP_DW_MIPI_DSI
bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
+   select GENERIC_PHY_MIPI_DPHY
help
  This selects support for Rockchip SoC specific extensions
  for the Synopsys DesignWare HDMI driver. If you want to
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index bc073ec5c183..9406effe8077 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -559,9 +559,87 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct 
drm_display_mode *mode,
return 0;
 }
 
+struct hstt {
+   unsigned int 

Re: [PATCH 01/15] drm/tegra: Map cmdbuf once for reloc processing

2019-11-25 Thread Thierry Reding
On Mon, Nov 25, 2019 at 10:58:56AM +0100, Daniel Vetter wrote:
> On Mon, Nov 18, 2019 at 11:35:22AM +0100, Daniel Vetter wrote:
> > A few reasons to drop kmap:
> > 
> > - For native objects all we do is look at obj->vaddr anyway, so might
> >   as well not call functions for every page.
> > 
> > - Reloc-processing on dma-buf is ... questionable.
> > 
> > - Plus most dma-buf that bother kernel cpu mmaps give you at least
> >   vmap, much less kmaps. And all the ones relevant for arm-soc are
> >   again doing a obj->vaddr game anyway, there's no real kmap going on
> >   on arm it seems.
> > 
> > Plus this seems to be the only real in-tree user of dma_buf_kmap, and
> > I'd like to get rid of that.
> > 
> > Signed-off-by: Daniel Vetter 
> > Cc: Thierry Reding 
> > Cc: linux-te...@vger.kernel.org
> 
> Ping for testing/review on these first 2 tegra patches. They're holding up
> the entire series, and I got acks for all the other bits surprisingly
> fast. So would like to land this rather sooner than later. I'm also
> working on a lot more dma-buf patches ...

Right, I had forgotten about this series. Let me go test it right away.

Thierry

> > ---
> >  drivers/gpu/host1x/job.c | 21 +++--
> >  1 file changed, 7 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
> > index 25ca54de8fc5..60b2fedd0061 100644
> > --- a/drivers/gpu/host1x/job.c
> > +++ b/drivers/gpu/host1x/job.c
> > @@ -244,8 +244,7 @@ static unsigned int pin_job(struct host1x *host, struct 
> > host1x_job *job)
> >  
> >  static int do_relocs(struct host1x_job *job, struct host1x_job_gather *g)
> >  {
> > -   u32 last_page = ~0;
> > -   void *cmdbuf_page_addr = NULL;
> > +   void *cmdbuf_addr = NULL;
> > struct host1x_bo *cmdbuf = g->bo;
> > unsigned int i;
> >  
> > @@ -267,28 +266,22 @@ static int do_relocs(struct host1x_job *job, struct 
> > host1x_job_gather *g)
> > goto patch_reloc;
> > }
> >  
> > -   if (last_page != reloc->cmdbuf.offset >> PAGE_SHIFT) {
> > -   if (cmdbuf_page_addr)
> > -   host1x_bo_kunmap(cmdbuf, last_page,
> > -cmdbuf_page_addr);
> > +   if (!cmdbuf_addr) {
> > +   cmdbuf_addr = host1x_bo_mmap(cmdbuf);
> >  
> > -   cmdbuf_page_addr = host1x_bo_kmap(cmdbuf,
> > -   reloc->cmdbuf.offset >> PAGE_SHIFT);
> > -   last_page = reloc->cmdbuf.offset >> PAGE_SHIFT;
> > -
> > -   if (unlikely(!cmdbuf_page_addr)) {
> > +   if (unlikely(!cmdbuf_addr)) {
> > pr_err("Could not map cmdbuf for relocation\n");
> > return -ENOMEM;
> > }
> > }
> >  
> > -   target = cmdbuf_page_addr + (reloc->cmdbuf.offset & ~PAGE_MASK);
> > +   target = cmdbuf_addr + reloc->cmdbuf.offset;
> >  patch_reloc:
> > *target = reloc_addr;
> > }
> >  
> > -   if (cmdbuf_page_addr)
> > -   host1x_bo_kunmap(cmdbuf, last_page, cmdbuf_page_addr);
> > +   if (cmdbuf_addr)
> > +   host1x_bo_munmap(cmdbuf, cmdbuf_addr);
> >  
> > return 0;
> >  }
> > -- 
> > 2.24.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/tegra: vic: Export module device table

2019-11-25 Thread Thierry Reding
On Mon, Nov 25, 2019 at 10:56:29AM +0100, Daniel Vetter wrote:
> On Fri, Nov 22, 2019 at 02:32:15PM +0100, Thierry Reding wrote:
> > From: Thierry Reding 
> > 
> > Export the module device table to ensure the VIC compatible strings are
> > listed in the module's aliases table. This in turn causes the driver to
> > be automatically loaded on boot if VIC is the only enabled subdevice of
> > the logical host1x DRM device.
> > 
> > Signed-off-by: Thierry Reding 
> 
> Reviewed-by: Daniel Vetter 
> 
> I noticed that the drm subdev driver also lacks the matches. How does that
> work? Just by getting loaded when any of the subdev drivers match?

Yeah, basically the host1x DRM driver registration causes a logical
device to be created. The driver will then finally bind to the device
after all the subdevices have been registered. Since all the subdevice
drivers are linked into a single module, all the module device tables
end up in that kernel module and that's enough to trigger the whole
process.

I ran into this issue when I was trying to run the Tegra DRM driver in
a "headless" configuration where all the display-related devices were
disabled via DT. Without exporting the VIC module device table, there
were no entries in the module's aliases list that would match the set
of devices registered to the system and the driver wouldn't load.

Thierry

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/tegra/vic.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
> > index 9444ba183990..c4d82b8b3065 100644
> > --- a/drivers/gpu/drm/tegra/vic.c
> > +++ b/drivers/gpu/drm/tegra/vic.c
> > @@ -386,13 +386,14 @@ static const struct vic_config vic_t194_config = {
> > .supports_sid = true,
> >  };
> >  
> > -static const struct of_device_id vic_match[] = {
> > +static const struct of_device_id tegra_vic_of_match[] = {
> > { .compatible = "nvidia,tegra124-vic", .data = _t124_config },
> > { .compatible = "nvidia,tegra210-vic", .data = _t210_config },
> > { .compatible = "nvidia,tegra186-vic", .data = _t186_config },
> > { .compatible = "nvidia,tegra194-vic", .data = _t194_config },
> > { },
> >  };
> > +MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
> >  
> >  static int vic_probe(struct platform_device *pdev)
> >  {
> > @@ -516,7 +517,7 @@ static const struct dev_pm_ops vic_pm_ops = {
> >  struct platform_driver tegra_vic_driver = {
> > .driver = {
> > .name = "tegra-vic",
> > -   .of_match_table = vic_match,
> > +   .of_match_table = tegra_vic_of_match,
> > .pm = _pm_ops
> > },
> > .probe = vic_probe,
> > -- 
> > 2.23.0
> > 
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v4 11/13] ARM: shmobile_defconfig: Enable support for panels from EDT

2019-11-25 Thread Geert Uytterhoeven
On Tue, Nov 19, 2019 at 1:12 AM Laurent Pinchart
 wrote:
> On Wed, Nov 13, 2019 at 03:51:30PM +, Fabrizio Castro wrote:
> > The iwg20d comes with an LCD panel from Emerging Display
> > Technologies Corporation (EDT), therefore enable what's
> > required to support it.
> >
> > Signed-off-by: Fabrizio Castro 
>
> Acked-by: Laurent Pinchart 
>
> I expect Geert to pick this up.

Thanks, queued in renesas-devel for v5.6.

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v4 10/13] ARM: dts: iwg20d-q7-common: Add LCD support

2019-11-25 Thread Geert Uytterhoeven
On Tue, Nov 19, 2019 at 1:10 AM Laurent Pinchart
 wrote:
> On Wed, Nov 13, 2019 at 03:51:29PM +, Fabrizio Castro wrote:
> > The iwg20d comes with a 7" capacitive touch screen, therefore
> > add support for it.
> >
> > Signed-off-by: Fabrizio Castro 
>
> Acked-by: Laurent Pinchart 
>
> I expect Geert to pick this up.

Thanks, queued in renesas-devel for v5.6.

Gr{oetje,eeting}s,

Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 RESEND] drm/bridge/synopsys: dsi: driver-specific configuration of phy timings

2019-11-25 Thread Neil Armstrong
Hi,

On 25/11/2019 10:31, Heiko Stuebner wrote:
> From: Heiko Stuebner 
> 
> The timing values for dw-dsi are often dependent on the used display and
> according to Philippe Cornu will most likely also depend on the used phy
> technology in the soc-specific implementation.
> 
> To solve this and allow specific implementations to define them as needed
> add a new get_timing callback to phy_ops and call this from the dphy_timing
> function to retrieve the necessary values for the specific mode.
> 
> Right now this handles the hs2lp + lp2hs where Rockchip SoCs need handling
> according to the phy speed, while STM seems to be ok with static values.
> 
> changes in v3:
> - check existence of phy_ops->get_timing in __dw_mipi_dsi_probe()
> - emit actual error when get_timing() call fails
> - add tags from Philippe and Yannick
> 
> changes in v2:
> - add driver-specific handling, don't force all bridge users to use
>   the same timings, as suggested by Philippe
> 
> Suggested-by: Philippe Cornu 
> Signed-off-by: Heiko Stuebner 
> Reviewed-by: Philippe Cornu 
> Tested-by: Yannick Fertre 
> ---
> Resend because I seem to have forgotten to Cc mailing lists
> 
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 27 +--
>  drivers/gpu/drm/rockchip/Kconfig  |  1 +
>  .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 78 +++
>  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 13 
>  include/drm/bridge/dw_mipi_dsi.h  |  9 +++
>  5 files changed, 121 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index c214c6389918..b8b112278690 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -727,7 +727,15 @@ static void dw_mipi_dsi_vertical_timing_config(struct 
> dw_mipi_dsi *dsi,
>  
>  static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
>  {
> + const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
> + struct dw_mipi_dsi_dphy_timing timing;
>   u32 hw_version;
> + int ret;
> +
> + ret = phy_ops->get_timing(dsi->plat_data->priv_data,
> +   dsi->lane_mbps, );
> + if (ret)
> + DRM_DEV_ERROR(dsi->dev, "Retrieving phy timings failed\n");
>  
>   /*
>* TODO dw drv improvements
> @@ -740,16 +748,20 @@ static void dw_mipi_dsi_dphy_timing_config(struct 
> dw_mipi_dsi *dsi)
>   hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
>  
>   if (hw_version >= HWVER_131) {
> - dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
> -   PHY_LP2HS_TIME_V131(0x40));
> + dsi_write(dsi, DSI_PHY_TMR_CFG,
> +   PHY_HS2LP_TIME_V131(timing.data_hs2lp) |
> +   PHY_LP2HS_TIME_V131(timing.data_lp2hs));
>   dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(1));
>   } else {
> - dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
> -   PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(1));
> + dsi_write(dsi, DSI_PHY_TMR_CFG,
> +   PHY_HS2LP_TIME(timing.data_hs2lp) |
> +   PHY_LP2HS_TIME(timing.data_lp2hs) |
> +   MAX_RD_TIME(1));
>   }
>  
> - dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
> -   | PHY_CLKLP2HS_TIME(0x40));
> + dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG,
> +   PHY_CLKHS2LP_TIME(timing.clk_hs2lp) |
> +   PHY_CLKLP2HS_TIME(timing.clk_lp2hs));
>  }
>  
>  static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
> @@ -999,7 +1011,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
>   dsi->dev = dev;
>   dsi->plat_data = plat_data;
>  
> - if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
> + if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
> + !plat_data->phy_ops->get_timing) {
>   DRM_ERROR("Phy not properly configured\n");
>   return ERR_PTR(-ENODEV);
>   }
> diff --git a/drivers/gpu/drm/rockchip/Kconfig 
> b/drivers/gpu/drm/rockchip/Kconfig
> index 6f4222f8beeb..4b7a276994ce 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -46,6 +46,7 @@ config ROCKCHIP_DW_HDMI
>  
>  config ROCKCHIP_DW_MIPI_DSI
>   bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
> + select GENERIC_PHY_MIPI_DPHY
>   help
> This selects support for Rockchip SoC specific extensions
> for the Synopsys DesignWare HDMI driver. If you want to
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
> b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index 13858f377a0c..f04b5064974d 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c

Re: [Intel-gfx] [RFC 03/13] drm/i915/svm: Runtime (RT) allocator support

2019-11-25 Thread Chris Wilson
Quoting Niranjana Vishwanathapura (2019-11-22 20:57:24)
> Shared Virtual Memory (SVM) runtime allocator support allows
> binding a shared virtual address to a buffer object (BO) in the
> device page table through an ioctl call.

The ioctl though is not svm specific, it is to do with "bulk residency"
and can be used to reduce execbuf traffic to provide virtual address
layout controls to e.g. Vulkan clients.

I915_VM_BIND {
uint32_t vm_id;
int32_t fd; /* or -1 for anon, or buf depending on flags */
uint64_t flags;
uint64_t offset; /* offset info fd [page aligned] */
uint64_t length; /* page aligned */
uint64_t iova; /* page aligned */
uint64_t extensions;
}; /* where page aligned is actually more I915_GTT_PAGE_ALIGNMENT */

as I recall. I also recall it being part of a future command stream
interface to reduce ioctls, but that is another story.
-Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 01/15] drm/tegra: Map cmdbuf once for reloc processing

2019-11-25 Thread Daniel Vetter
On Mon, Nov 18, 2019 at 11:35:22AM +0100, Daniel Vetter wrote:
> A few reasons to drop kmap:
> 
> - For native objects all we do is look at obj->vaddr anyway, so might
>   as well not call functions for every page.
> 
> - Reloc-processing on dma-buf is ... questionable.
> 
> - Plus most dma-buf that bother kernel cpu mmaps give you at least
>   vmap, much less kmaps. And all the ones relevant for arm-soc are
>   again doing a obj->vaddr game anyway, there's no real kmap going on
>   on arm it seems.
> 
> Plus this seems to be the only real in-tree user of dma_buf_kmap, and
> I'd like to get rid of that.
> 
> Signed-off-by: Daniel Vetter 
> Cc: Thierry Reding 
> Cc: linux-te...@vger.kernel.org

Ping for testing/review on these first 2 tegra patches. They're holding up
the entire series, and I got acks for all the other bits surprisingly
fast. So would like to land this rather sooner than later. I'm also
working on a lot more dma-buf patches ...

Thanks, Daniel

> ---
>  drivers/gpu/host1x/job.c | 21 +++--
>  1 file changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
> index 25ca54de8fc5..60b2fedd0061 100644
> --- a/drivers/gpu/host1x/job.c
> +++ b/drivers/gpu/host1x/job.c
> @@ -244,8 +244,7 @@ static unsigned int pin_job(struct host1x *host, struct 
> host1x_job *job)
>  
>  static int do_relocs(struct host1x_job *job, struct host1x_job_gather *g)
>  {
> - u32 last_page = ~0;
> - void *cmdbuf_page_addr = NULL;
> + void *cmdbuf_addr = NULL;
>   struct host1x_bo *cmdbuf = g->bo;
>   unsigned int i;
>  
> @@ -267,28 +266,22 @@ static int do_relocs(struct host1x_job *job, struct 
> host1x_job_gather *g)
>   goto patch_reloc;
>   }
>  
> - if (last_page != reloc->cmdbuf.offset >> PAGE_SHIFT) {
> - if (cmdbuf_page_addr)
> - host1x_bo_kunmap(cmdbuf, last_page,
> -  cmdbuf_page_addr);
> + if (!cmdbuf_addr) {
> + cmdbuf_addr = host1x_bo_mmap(cmdbuf);
>  
> - cmdbuf_page_addr = host1x_bo_kmap(cmdbuf,
> - reloc->cmdbuf.offset >> PAGE_SHIFT);
> - last_page = reloc->cmdbuf.offset >> PAGE_SHIFT;
> -
> - if (unlikely(!cmdbuf_page_addr)) {
> + if (unlikely(!cmdbuf_addr)) {
>   pr_err("Could not map cmdbuf for relocation\n");
>   return -ENOMEM;
>   }
>   }
>  
> - target = cmdbuf_page_addr + (reloc->cmdbuf.offset & ~PAGE_MASK);
> + target = cmdbuf_addr + reloc->cmdbuf.offset;
>  patch_reloc:
>   *target = reloc_addr;
>   }
>  
> - if (cmdbuf_page_addr)
> - host1x_bo_kunmap(cmdbuf, last_page, cmdbuf_page_addr);
> + if (cmdbuf_addr)
> + host1x_bo_munmap(cmdbuf, cmdbuf_addr);
>  
>   return 0;
>  }
> -- 
> 2.24.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/tegra: vic: Export module device table

2019-11-25 Thread Daniel Vetter
On Fri, Nov 22, 2019 at 02:32:15PM +0100, Thierry Reding wrote:
> From: Thierry Reding 
> 
> Export the module device table to ensure the VIC compatible strings are
> listed in the module's aliases table. This in turn causes the driver to
> be automatically loaded on boot if VIC is the only enabled subdevice of
> the logical host1x DRM device.
> 
> Signed-off-by: Thierry Reding 

Reviewed-by: Daniel Vetter 

I noticed that the drm subdev driver also lacks the matches. How does that
work? Just by getting loaded when any of the subdev drivers match?
-Daniel

> ---
>  drivers/gpu/drm/tegra/vic.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
> index 9444ba183990..c4d82b8b3065 100644
> --- a/drivers/gpu/drm/tegra/vic.c
> +++ b/drivers/gpu/drm/tegra/vic.c
> @@ -386,13 +386,14 @@ static const struct vic_config vic_t194_config = {
>   .supports_sid = true,
>  };
>  
> -static const struct of_device_id vic_match[] = {
> +static const struct of_device_id tegra_vic_of_match[] = {
>   { .compatible = "nvidia,tegra124-vic", .data = _t124_config },
>   { .compatible = "nvidia,tegra210-vic", .data = _t210_config },
>   { .compatible = "nvidia,tegra186-vic", .data = _t186_config },
>   { .compatible = "nvidia,tegra194-vic", .data = _t194_config },
>   { },
>  };
> +MODULE_DEVICE_TABLE(of, tegra_vic_of_match);
>  
>  static int vic_probe(struct platform_device *pdev)
>  {
> @@ -516,7 +517,7 @@ static const struct dev_pm_ops vic_pm_ops = {
>  struct platform_driver tegra_vic_driver = {
>   .driver = {
>   .name = "tegra-vic",
> - .of_match_table = vic_match,
> + .of_match_table = tegra_vic_of_match,
>   .pm = _pm_ops
>   },
>   .probe = vic_probe,
> -- 
> 2.23.0
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 108514] heavy screen flickering with Mobility Radeon X1600 and kernel version 3.15rc2 onward

2019-11-25 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=108514

Michel Dänzer  changed:

   What|Removed |Added

URL|https://statuslife.in/  |

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/4] drm/vc4: Use dma_resv locking wrappers

2019-11-25 Thread Daniel Vetter
I'll add more fancy logic to them soon, so everyone really has to use
them. Plus they already provide some nice additional debug
infrastructure on top of direct ww_mutex usage for the fences tracked
by dma_resv.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vc4/vc4_gem.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 7a06cb6e31c5..e1cfc3ccd05a 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -568,7 +568,7 @@ vc4_unlock_bo_reservations(struct drm_device *dev,
for (i = 0; i < exec->bo_count; i++) {
struct drm_gem_object *bo = >bo[i]->base;
 
-   ww_mutex_unlock(>resv->lock);
+   dma_resv_unlock(bo->resv);
}
 
ww_acquire_fini(acquire_ctx);
@@ -595,8 +595,7 @@ vc4_lock_bo_reservations(struct drm_device *dev,
 retry:
if (contended_lock != -1) {
bo = >bo[contended_lock]->base;
-   ret = ww_mutex_lock_slow_interruptible(>resv->lock,
-  acquire_ctx);
+   ret = dma_resv_lock_slow_interruptible(bo->resv, acquire_ctx);
if (ret) {
ww_acquire_done(acquire_ctx);
return ret;
@@ -609,19 +608,19 @@ vc4_lock_bo_reservations(struct drm_device *dev,
 
bo = >bo[i]->base;
 
-   ret = ww_mutex_lock_interruptible(>resv->lock, acquire_ctx);
+   ret = dma_resv_lock_interruptible(bo->resv, acquire_ctx);
if (ret) {
int j;
 
for (j = 0; j < i; j++) {
bo = >bo[j]->base;
-   ww_mutex_unlock(>resv->lock);
+   dma_resv_unlock(bo->resv);
}
 
if (contended_lock != -1 && contended_lock >= i) {
bo = >bo[contended_lock]->base;
 
-   ww_mutex_unlock(>resv->lock);
+   dma_resv_unlock(bo->resv);
}
 
if (ret == -EDEADLK) {
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 0/4] consistently use dma_resv locking wrappers

2019-11-25 Thread Daniel Vetter
Hi all,

This is prep work for some dma_resv series I'm tinkering with, but I
figured good to split this out since good idea to land this no matter what
exactly I'll end up creating in dma_resv. With these everything in
drivers/gpu nicely goes through either the dma_resv or drm_modeset_lock
wrappers, and doesn't call ww_mutex directly.

Review, comments, acks all very much welcome, as usual.

Cheers, Daniel

Daniel Vetter (4):
  drm/etnaviv: Use dma_resv locking wrappers
  drm/i915: Use dma_resv locking wrappers
  drm/msm: Use dma_resv locking wrappers
  drm/vc4: Use dma_resv locking wrappers

 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c   |  8 +++-
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c |  6 +++---
 drivers/gpu/drm/msm/msm_gem_submit.c   | 10 +-
 drivers/gpu/drm/vc4/vc4_gem.c  | 11 +--
 4 files changed, 16 insertions(+), 19 deletions(-)

-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/4] drm/i915: Use dma_resv locking wrappers

2019-11-25 Thread Daniel Vetter
I'll add more fancy logic to them soon, so everyone really has to use
them. Plus they already provide some nice additional debug
infrastructure on top of direct ww_mutex usage for the fences tracked
by dma_resv.

Aside: We might want to create wrappers for i915_vma locking of the
->resv like we have for the i915_gem_bo itself already.

Signed-off-by: Daniel Vetter 
Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Jani Nikula 
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 7a87e8270460..7b8f4ebd9986 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1848,7 +1848,7 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
for (i = 0; i < count; i++) {
struct i915_vma *vma = eb->vma[i];
 
-   err = ww_mutex_lock_interruptible(>resv->lock, );
+   err = dma_resv_lock_interruptible(vma->resv, );
if (!err)
continue;
 
@@ -1859,7 +1859,7 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
do {
int j = i - 1;
 
-   ww_mutex_unlock(>vma[j]->resv->lock);
+   dma_resv_unlock(eb->vma[j]->resv);
 
swap(eb->flags[i], eb->flags[j]);
swap(eb->vma[i],  eb->vma[j]);
@@ -1868,7 +1868,7 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
GEM_BUG_ON(vma != eb->vma[0]);
vma->exec_flags = >flags[0];
 
-   err = ww_mutex_lock_slow_interruptible(>resv->lock,
+   err = dma_resv_lock_slow_interruptible(vma->resv,
   );
}
if (err)
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/4] drm/etnaviv: Use dma_resv locking wrappers

2019-11-25 Thread Daniel Vetter
I'll add more fancy logic to them soon, so everyone really has to use
them. Plus they already provide some nice additional debug
infrastructure on top of direct ww_mutex usage for the fences tracked
by dma_resv.

Signed-off-by: Daniel Vetter 
Cc: Lucas Stach 
Cc: Russell King 
Cc: Christian Gmeiner 
Cc: etna...@lists.freedesktop.org
---
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index aa3e4c3b063a..947b21868e72 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -113,7 +113,7 @@ static void submit_unlock_object(struct etnaviv_gem_submit 
*submit, int i)
if (submit->bos[i].flags & BO_LOCKED) {
struct drm_gem_object *obj = >bos[i].obj->base;
 
-   ww_mutex_unlock(>resv->lock);
+   dma_resv_unlock(obj->resv);
submit->bos[i].flags &= ~BO_LOCKED;
}
 }
@@ -133,8 +133,7 @@ static int submit_lock_objects(struct etnaviv_gem_submit 
*submit,
contended = i;
 
if (!(submit->bos[i].flags & BO_LOCKED)) {
-   ret = ww_mutex_lock_interruptible(>resv->lock,
- ticket);
+   ret = dma_resv_lock(obj->resv, ticket);
if (ret == -EALREADY)
DRM_ERROR("BO at index %u already on submit 
list\n",
  i);
@@ -161,8 +160,7 @@ static int submit_lock_objects(struct etnaviv_gem_submit 
*submit,
obj = >bos[contended].obj->base;
 
/* we lost out in a seqno race, lock and retry.. */
-   ret = ww_mutex_lock_slow_interruptible(>resv->lock,
-  ticket);
+   ret = dma_resv_lock_slow_interruptible(obj->resv, ticket);
if (!ret) {
submit->bos[contended].flags |= BO_LOCKED;
slow_locked = contended;
-- 
2.24.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  1   2   >