[Bug 109234] amdgpu random hangs with 5.0-rc1/4.21+

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109234

--- Comment #14 from bmil...@gmail.com ---
Created attachment 143066
  --> https://bugs.freedesktop.org/attachment.cgi?id=143066&action=edit
dmesg kfd and amdgpu hangs

attachment for last comment

-- 
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


[Bug 109234] amdgpu random hangs with 5.0-rc1/4.21+

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109234

--- Comment #13 from bmil...@gmail.com ---
There are a few new dma fixes on torvalds tree, but I'm still triggering the
bug. I got something similar now but slightly different while watching a
real-time 60fps interpolated video that uses opencl acceleration via rocm.
Attached the log, the first error is from kfd driver and the second looks like
the one reported in OP.

-- 
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


nouveau-fixes 5.0

2019-01-10 Thread Ben Skeggs
The following changes since commit 8ff01abcccbb563fbf50b84a476bd9b22c42c0a3:

  drm/nouveau/ce/tu106: initial support (2018-12-11 15:38:01 +1000)

are available in the Git repository at:

  git://github.com/skeggsb/linux linux-4.21

for you to fetch changes up to a5176a4cb85bb6213daadf691097cf411da35df2:

  drm/nouveau/falcon: avoid touching registers if engine is off
(2019-01-11 16:25:54 +1000)


Ben Skeggs (1):
  drm/nouveau: register backlight on pascal and newer

Ilia Mirkin (1):
  drm/nouveau/falcon: avoid touching registers if engine is off

Takashi Iwai (1):
  drm/nouveau: Don't disable polling in fallback mode

 drivers/gpu/drm/nouveau/nouveau_backlight.c  | 3 +++
 drivers/gpu/drm/nouveau/nvkm/engine/falcon.c | 7 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 7 ---
 3 files changed, 12 insertions(+), 5 deletions(-)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 0/6] drm: byteorder fixes

2019-01-10 Thread Ilia Mirkin
Hi Gerd,

What happened with this series (and the next one)?

Semi-relatedly, I wonder if it wouldn't be better to just dump the
BIG_ENDIAN flag and just define the "host" format to be the right one
for a consistent little-endian interpretation.

Cheers,

  -ilia


On Wed, Sep 5, 2018 at 2:04 AM Gerd Hoffmann  wrote:
>
> Patch series adds some convinience #defines for host byteoder drm
> formats.  It fixes drm_mode_addfb() behavior on bigendian machines.  For
> bug compatibility reasons a mode_config quirk activates the fix.
> bochs and virtio-gpu drivers are updated to use the new #defines, set
> the new driver feature flag and fix some issues.
>
> Gerd Hoffmann (6):
>   drm: replace DRIVER_PREFER_XBGR_30BPP driver flag with mode_config
> quirk
>   drm: byteorder: add DRM_FORMAT_HOST_*
>   drm: do not mask out DRM_FORMAT_BIG_ENDIAN
>   drm: fix drm_mode_addfb() on big endian machines.
>   drm/bochs: fix DRM_FORMAT_* handling for big endian machines.
>   drm/virtio: fix DRM_FORMAT_* handling
>
>  include/drm/drm_drv.h|  1 -
>  include/drm/drm_fourcc.h | 22 +
>  include/drm/drm_mode_config.h| 15 +
>  drivers/gpu/drm/bochs/bochs_fbdev.c  |  5 ++-
>  drivers/gpu/drm/bochs/bochs_kms.c| 34 +++-
>  drivers/gpu/drm/bochs/bochs_mm.c |  2 +-
>  drivers/gpu/drm/drm_framebuffer.c| 17 --
>  drivers/gpu/drm/nouveau/dispnv50/disp.c  |  2 +-
>  drivers/gpu/drm/virtio/virtgpu_display.c |  5 +++
>  drivers/gpu/drm/virtio/virtgpu_fb.c  |  2 +-
>  drivers/gpu/drm/virtio/virtgpu_gem.c |  7 +++--
>  drivers/gpu/drm/virtio/virtgpu_plane.c   | 54 
> ++--
>  12 files changed, 101 insertions(+), 65 deletions(-)
>
> --
> 2.9.3
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 10/16] drm/bochs: remove old bochs_crtc_* functions

2019-01-10 Thread Gerd Hoffmann
Remove the old, now unused crtc callbacks.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 81 ---
 1 file changed, 81 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 67c3674609..5b7e1a7c6b 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -20,74 +20,6 @@ MODULE_PARM_DESC(defy, "default y resolution");
 
 /* -- */
 
-static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-   switch (mode) {
-   case DRM_MODE_DPMS_ON:
-   case DRM_MODE_DPMS_STANDBY:
-   case DRM_MODE_DPMS_SUSPEND:
-   case DRM_MODE_DPMS_OFF:
-   default:
-   return;
-   }
-}
-
-static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-   struct drm_framebuffer *old_fb)
-{
-   struct bochs_device *bochs =
-   container_of(crtc, struct bochs_device, crtc);
-   struct bochs_bo *bo;
-   u64 gpu_addr = 0;
-   int ret;
-
-   if (old_fb) {
-   bo = gem_to_bochs_bo(old_fb->obj[0]);
-   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-   if (ret) {
-   DRM_ERROR("failed to reserve old_fb bo\n");
-   } else {
-   bochs_bo_unpin(bo);
-   ttm_bo_unreserve(&bo->bo);
-   }
-   }
-
-   if (WARN_ON(crtc->primary->fb == NULL))
-   return -EINVAL;
-
-   bo = gem_to_bochs_bo(crtc->primary->fb->obj[0]);
-   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-   if (ret)
-   return ret;
-
-   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-   if (ret) {
-   ttm_bo_unreserve(&bo->bo);
-   return ret;
-   }
-
-   ttm_bo_unreserve(&bo->bo);
-   bochs_hw_setbase(bochs, x, y, gpu_addr);
-   return 0;
-}
-
-static int bochs_crtc_mode_set(struct drm_crtc *crtc,
-  struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode,
-  int x, int y, struct drm_framebuffer *old_fb)
-{
-   struct bochs_device *bochs =
-   container_of(crtc, struct bochs_device, crtc);
-
-   if (WARN_ON(crtc->primary->fb == NULL))
-   return -EINVAL;
-
-   bochs_hw_setmode(bochs, mode);
-   bochs_hw_setformat(bochs, crtc->primary->fb->format);
-   bochs_crtc_mode_set_base(crtc, x, y, old_fb);
-   return 0;
-}
-
 static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct bochs_device *bochs =
@@ -96,14 +28,6 @@ static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc)
bochs_hw_setmode(bochs, &crtc->mode);
 }
 
-static void bochs_crtc_prepare(struct drm_crtc *crtc)
-{
-}
-
-static void bochs_crtc_commit(struct drm_crtc *crtc)
-{
-}
-
 static void bochs_crtc_atomic_enable(struct drm_crtc *crtc,
 struct drm_crtc_state *old_crtc_state)
 {
@@ -138,12 +62,7 @@ static const struct drm_crtc_funcs bochs_crtc_funcs = {
 };
 
 static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
-   .dpms = bochs_crtc_dpms,
-   .mode_set = bochs_crtc_mode_set,
-   .mode_set_base = bochs_crtc_mode_set_base,
.mode_set_nofb = bochs_crtc_mode_set_nofb,
-   .prepare = bochs_crtc_prepare,
-   .commit = bochs_crtc_commit,
.atomic_enable = bochs_crtc_atomic_enable,
.atomic_flush = bochs_crtc_atomic_flush,
 };
-- 
2.9.3

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


[PATCH v4 15/16] drm/bochs: drop old fbdev emulation code

2019-01-10 Thread Gerd Hoffmann
Not needed any more, bochs uses the generic emulation now.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs.h   |   9 ---
 drivers/gpu/drm/bochs/bochs_fbdev.c | 129 
 2 files changed, 138 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index ede22beb85..03711394f1 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -80,12 +80,6 @@ struct bochs_device {
struct ttm_bo_device bdev;
bool initialized;
} ttm;
-
-   /* fbdev */
-   struct {
-   struct drm_framebuffer *fb;
-   struct drm_fb_helper helper;
-   } fb;
 };
 
 struct bochs_bo {
@@ -157,7 +151,4 @@ int bochs_kms_init(struct bochs_device *bochs);
 void bochs_kms_fini(struct bochs_device *bochs);
 
 /* bochs_fbdev.c */
-int bochs_fbdev_init(struct bochs_device *bochs);
-void bochs_fbdev_fini(struct bochs_device *bochs);
-
 extern const struct drm_mode_config_funcs bochs_mode_funcs;
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c 
b/drivers/gpu/drm/bochs/bochs_fbdev.c
index ccf783b038..7cac3f5253 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -11,124 +11,6 @@
 
 /* -- */
 
-static int bochsfb_mmap(struct fb_info *info,
-   struct vm_area_struct *vma)
-{
-   struct drm_fb_helper *fb_helper = info->par;
-   struct bochs_bo *bo = gem_to_bochs_bo(fb_helper->fb->obj[0]);
-
-   return ttm_fbdev_mmap(vma, &bo->bo);
-}
-
-static struct fb_ops bochsfb_ops = {
-   .owner = THIS_MODULE,
-   DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
-   .fb_mmap = bochsfb_mmap,
-};
-
-static int bochsfb_create_object(struct bochs_device *bochs,
-const struct drm_mode_fb_cmd2 *mode_cmd,
-struct drm_gem_object **gobj_p)
-{
-   struct drm_device *dev = bochs->dev;
-   struct drm_gem_object *gobj;
-   u32 size;
-   int ret = 0;
-
-   size = mode_cmd->pitches[0] * mode_cmd->height;
-   ret = bochs_gem_create(dev, size, true, &gobj);
-   if (ret)
-   return ret;
-
-   *gobj_p = gobj;
-   return ret;
-}
-
-static int bochsfb_create(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
-{
-   struct bochs_device *bochs =
-   container_of(helper, struct bochs_device, fb.helper);
-   struct fb_info *info;
-   struct drm_framebuffer *fb;
-   struct drm_mode_fb_cmd2 mode_cmd;
-   struct drm_gem_object *gobj = NULL;
-   struct bochs_bo *bo = NULL;
-   int size, ret;
-
-   if (sizes->surface_bpp != 32)
-   return -EINVAL;
-
-   mode_cmd.width = sizes->surface_width;
-   mode_cmd.height = sizes->surface_height;
-   mode_cmd.pitches[0] = sizes->surface_width * 4;
-   mode_cmd.pixel_format = DRM_FORMAT_HOST_XRGB;
-   size = mode_cmd.pitches[0] * mode_cmd.height;
-
-   /* alloc, pin & map bo */
-   ret = bochsfb_create_object(bochs, &mode_cmd, &gobj);
-   if (ret) {
-   DRM_ERROR("failed to create fbcon backing object %d\n", ret);
-   return ret;
-   }
-
-   bo = gem_to_bochs_bo(gobj);
-
-   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
-   if (ret) {
-   DRM_ERROR("failed to pin fbcon\n");
-   return ret;
-   }
-
-   ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
- &bo->kmap);
-   if (ret) {
-   DRM_ERROR("failed to kmap fbcon\n");
-   return ret;
-   }
-
-   /* init fb device */
-   info = drm_fb_helper_alloc_fbi(helper);
-   if (IS_ERR(info)) {
-   DRM_ERROR("Failed to allocate fbi: %ld\n", PTR_ERR(info));
-   return PTR_ERR(info);
-   }
-
-   info->par = &bochs->fb.helper;
-
-   fb = drm_gem_fbdev_fb_create(bochs->dev, sizes, 0, gobj, NULL);
-   if (IS_ERR(fb)) {
-   DRM_ERROR("Failed to create framebuffer: %ld\n", PTR_ERR(fb));
-   return PTR_ERR(fb);
-   }
-
-   /* setup helper */
-   bochs->fb.helper.fb = fb;
-
-   strcpy(info->fix.id, "bochsdrmfb");
-
-   info->fbops = &bochsfb_ops;
-
-   drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
-   drm_fb_helper_fill_var(info, &bochs->fb.helper, sizes->fb_width,
-  sizes->fb_height);
-
-   info->screen_base = bo->kmap.virtual;
-   info->screen_size = size;
-
-   drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node);
-   info->fix.smem_start = 0;
-   info-

[PATCH v4 02/16] drm/bochs: split bochs_hw_setmode

2019-01-10 Thread Gerd Hoffmann
Create a separate bochs_hw_setformat function to configure
the framebuffer format (actually just the byteorder).

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs.h |  5 +++--
 drivers/gpu/drm/bochs/bochs_hw.c  | 19 ---
 drivers/gpu/drm/bochs/bochs_kms.c |  3 ++-
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index fb38c8b857..4dc1b6384e 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -121,8 +121,9 @@ int bochs_hw_init(struct drm_device *dev);
 void bochs_hw_fini(struct drm_device *dev);
 
 void bochs_hw_setmode(struct bochs_device *bochs,
- struct drm_display_mode *mode,
- const struct drm_format_info *format);
+ struct drm_display_mode *mode);
+void bochs_hw_setformat(struct bochs_device *bochs,
+   const struct drm_format_info *format);
 void bochs_hw_setbase(struct bochs_device *bochs,
  int x, int y, u64 addr);
 int bochs_hw_load_edid(struct bochs_device *bochs);
diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c
index d0b4e1cee8..3e04b2f0ec 100644
--- a/drivers/gpu/drm/bochs/bochs_hw.c
+++ b/drivers/gpu/drm/bochs/bochs_hw.c
@@ -204,8 +204,7 @@ void bochs_hw_fini(struct drm_device *dev)
 }
 
 void bochs_hw_setmode(struct bochs_device *bochs,
- struct drm_display_mode *mode,
- const struct drm_format_info *format)
+ struct drm_display_mode *mode)
 {
bochs->xres = mode->hdisplay;
bochs->yres = mode->vdisplay;
@@ -213,12 +212,8 @@ void bochs_hw_setmode(struct bochs_device *bochs,
bochs->stride = mode->hdisplay * (bochs->bpp / 8);
bochs->yres_virtual = bochs->fb_size / bochs->stride;
 
-   DRM_DEBUG_DRIVER("%dx%d @ %d bpp, format %c%c%c%c, vy %d\n",
+   DRM_DEBUG_DRIVER("%dx%d @ %d bpp, vy %d\n",
 bochs->xres, bochs->yres, bochs->bpp,
-(format->format >>  0) & 0xff,
-(format->format >>  8) & 0xff,
-(format->format >> 16) & 0xff,
-(format->format >> 24) & 0xff,
 bochs->yres_virtual);
 
bochs_vga_writeb(bochs, 0x3c0, 0x20); /* unblank */
@@ -236,6 +231,16 @@ void bochs_hw_setmode(struct bochs_device *bochs,
 
bochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE,
  VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+}
+
+void bochs_hw_setformat(struct bochs_device *bochs,
+   const struct drm_format_info *format)
+{
+   DRM_DEBUG_DRIVER("format %c%c%c%c\n",
+(format->format >>  0) & 0xff,
+(format->format >>  8) & 0xff,
+(format->format >> 16) & 0xff,
+(format->format >> 24) & 0xff);
 
switch (format->format) {
case DRM_FORMAT_XRGB:
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index c8ce54498d..f7e6d1a9b3 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -80,7 +80,8 @@ static int bochs_crtc_mode_set(struct drm_crtc *crtc,
if (WARN_ON(crtc->primary->fb == NULL))
return -EINVAL;
 
-   bochs_hw_setmode(bochs, mode, crtc->primary->fb->format);
+   bochs_hw_setmode(bochs, mode);
+   bochs_hw_setformat(bochs, crtc->primary->fb->format);
bochs_crtc_mode_set_base(crtc, x, y, old_fb);
return 0;
 }
-- 
2.9.3

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


[PATCH v4 16/16] drm/bochs: move remaining fb bits to kms

2019-01-10 Thread Gerd Hoffmann
bochs_fbdev.c is almost empty now.  Move the remaining framebuffer bits
over to bochs_kms.c.  Pure code motion. No functional change.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_fbdev.c | 29 -
 drivers/gpu/drm/bochs/bochs_kms.c   | 17 +
 drivers/gpu/drm/bochs/Makefile  |  2 +-
 3 files changed, 18 insertions(+), 30 deletions(-)
 delete mode 100644 drivers/gpu/drm/bochs/bochs_fbdev.c

diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c 
b/drivers/gpu/drm/bochs/bochs_fbdev.c
deleted file mode 100644
index 7cac3f5253..00
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "bochs.h"
-#include 
-#include 
-
-/* -- */
-
-static struct drm_framebuffer *
-bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   if (mode_cmd->pixel_format != DRM_FORMAT_XRGB &&
-   mode_cmd->pixel_format != DRM_FORMAT_BGRX)
-   return ERR_PTR(-EINVAL);
-
-   return drm_gem_fb_create(dev, file, mode_cmd);
-}
-
-const struct drm_mode_config_funcs bochs_mode_funcs = {
-   .fb_create = bochs_gem_fb_create,
-   .atomic_check = drm_atomic_helper_check,
-   .atomic_commit = drm_atomic_helper_commit,
-};
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index fc856a02a2..e9d5dbc346 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static int defx = 1024;
 static int defy = 768;
@@ -256,6 +257,22 @@ static void bochs_connector_init(struct drm_device *dev)
}
 }
 
+static struct drm_framebuffer *
+bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
+   const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   if (mode_cmd->pixel_format != DRM_FORMAT_XRGB &&
+   mode_cmd->pixel_format != DRM_FORMAT_BGRX)
+   return ERR_PTR(-EINVAL);
+
+   return drm_gem_fb_create(dev, file, mode_cmd);
+}
+
+const struct drm_mode_config_funcs bochs_mode_funcs = {
+   .fb_create = bochs_gem_fb_create,
+   .atomic_check = drm_atomic_helper_check,
+   .atomic_commit = drm_atomic_helper_commit,
+};
 
 int bochs_kms_init(struct bochs_device *bochs)
 {
diff --git a/drivers/gpu/drm/bochs/Makefile b/drivers/gpu/drm/bochs/Makefile
index 98ef60a19e..e9e0f8f5eb 100644
--- a/drivers/gpu/drm/bochs/Makefile
+++ b/drivers/gpu/drm/bochs/Makefile
@@ -1,3 +1,3 @@
-bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_fbdev.o bochs_hw.o
+bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_hw.o
 
 obj-$(CONFIG_DRM_BOCHS)+= bochs-drm.o
-- 
2.9.3

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


[PATCH v4 00/16] drm/bochs: cleanups, atomic modesetting, generic fbdev.

2019-01-10 Thread Gerd Hoffmann
This series adds support for atomic modesetting to the bochs driver.
It also switches over to the generic fbdev implementation and does
some cleanups.

v4:
 - fix suspend/resume by using atomic helpers (Noralf).

v3:
 - adjust pin/unpin fix & reorder patches a bit,
   to keep the series bisectable (Daniel).
 - drop dmabuf import/export callbacks.

v2:
 - some updates according to Oleksandr's review.
 - fix ttm bo pin/unpin  (new patch #15).

Gerd Hoffmann (16):
  drm/bochs: encoder cleanup
  drm/bochs: split bochs_hw_setmode
  drm/bochs: atomic: add atomic_flush+atomic_enable callbacks.
  drm/bochs: atomic: add mode_set_nofb callback.
  drm/bochs: atomic: switch planes to atomic, wire up helpers.
  drm/bochs: atomic: use atomic set_config helper
  drm/bochs: atomic: use atomic page_flip helper
  drm/bochs: atomic: use suspend/resume helpers
  drm/bochs: atomic: set DRIVER_ATOMIC
  drm/bochs: remove old bochs_crtc_* functions
  drm/bochs: drop unused gpu_addr arg from bochs_bo_pin()
  drm/bochs: move ttm_bo_(un)reserve calls into bochs_bo_{pin,unpin}
  drm/bochs: add basic prime support
  drm/bochs: switch to generic drm fbdev emulation
  drm/bochs: drop old fbdev emulation code
  drm/bochs: move remaining fb bits to kms

 drivers/gpu/drm/bochs/bochs.h   |  23 ++--
 drivers/gpu/drm/bochs/bochs_drv.c   |  35 +++---
 drivers/gpu/drm/bochs/bochs_fbdev.c | 163 ---
 drivers/gpu/drm/bochs/bochs_hw.c|  19 ++--
 drivers/gpu/drm/bochs/bochs_kms.c   | 218 +---
 drivers/gpu/drm/bochs/bochs_mm.c|  68 +--
 drivers/gpu/drm/bochs/Makefile  |   2 +-
 7 files changed, 198 insertions(+), 330 deletions(-)
 delete mode 100644 drivers/gpu/drm/bochs/bochs_fbdev.c

-- 
2.9.3

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


[PATCH v4 03/16] drm/bochs: atomic: add atomic_flush+atomic_enable callbacks.

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, step one.
Add atomic crtc helper callbacks.

Signed-off-by: Gerd Hoffmann 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index f7e6d1a9b3..2cbd406b1f 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -115,6 +115,29 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc,
return 0;
 }
 
+static void bochs_crtc_atomic_enable(struct drm_crtc *crtc,
+struct drm_crtc_state *old_crtc_state)
+{
+}
+
+static void bochs_crtc_atomic_flush(struct drm_crtc *crtc,
+   struct drm_crtc_state *old_crtc_state)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_pending_vblank_event *event;
+
+   if (crtc->state && crtc->state->event) {
+   unsigned long irqflags;
+
+   spin_lock_irqsave(&dev->event_lock, irqflags);
+   event = crtc->state->event;
+   crtc->state->event = NULL;
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irqrestore(&dev->event_lock, irqflags);
+   }
+}
+
+
 /* These provide the minimum set of functions required to handle a CRTC */
 static const struct drm_crtc_funcs bochs_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
@@ -128,6 +151,8 @@ static const struct drm_crtc_helper_funcs 
bochs_helper_funcs = {
.mode_set_base = bochs_crtc_mode_set_base,
.prepare = bochs_crtc_prepare,
.commit = bochs_crtc_commit,
+   .atomic_enable = bochs_crtc_atomic_enable,
+   .atomic_flush = bochs_crtc_atomic_flush,
 };
 
 static const uint32_t bochs_formats[] = {
-- 
2.9.3

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


[PATCH v4 13/16] drm/bochs: add basic prime support

2019-01-10 Thread Gerd Hoffmann
Just enough to make the generic framebuffer emulation happy.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs.h |  7 ++
 drivers/gpu/drm/bochs/bochs_drv.c | 11 -
 drivers/gpu/drm/bochs/bochs_mm.c  | 49 +++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index d0d474e06f..ede22beb85 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -145,6 +145,13 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct 
drm_device *dev,
 int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag);
 int bochs_bo_unpin(struct bochs_bo *bo);
 
+int bochs_gem_prime_pin(struct drm_gem_object *obj);
+void bochs_gem_prime_unpin(struct drm_gem_object *obj);
+void *bochs_gem_prime_vmap(struct drm_gem_object *obj);
+void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+int bochs_gem_prime_mmap(struct drm_gem_object *obj,
+struct vm_area_struct *vma);
+
 /* bochs_kms.c */
 int bochs_kms_init(struct bochs_device *bochs);
 void bochs_kms_fini(struct bochs_device *bochs);
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c 
b/drivers/gpu/drm/bochs/bochs_drv.c
index a8cb22cffe..a3f4e21078 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -81,7 +81,8 @@ static const struct file_operations bochs_fops = {
 };
 
 static struct drm_driver bochs_driver = {
-   .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+   .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
+ DRIVER_PRIME,
.fops   = &bochs_fops,
.name   = "bochs-drm",
.desc   = "bochs dispi vga interface (qemu stdvga)",
@@ -91,6 +92,14 @@ static struct drm_driver bochs_driver = {
.gem_free_object_unlocked = bochs_gem_free_object,
.dumb_create= bochs_dumb_create,
.dumb_map_offset= bochs_dumb_mmap_offset,
+
+   .gem_prime_export = drm_gem_prime_export,
+   .gem_prime_import = drm_gem_prime_import,
+   .gem_prime_pin = bochs_gem_prime_pin,
+   .gem_prime_unpin = bochs_gem_prime_unpin,
+   .gem_prime_vmap = bochs_gem_prime_vmap,
+   .gem_prime_vunmap = bochs_gem_prime_vunmap,
+   .gem_prime_mmap = bochs_gem_prime_mmap,
 };
 
 /* -- */
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index fcbf35456d..641a33f134 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -395,3 +395,52 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct 
drm_device *dev,
drm_gem_object_put_unlocked(obj);
return 0;
 }
+
+/* -- */
+
+int bochs_gem_prime_pin(struct drm_gem_object *obj)
+{
+   struct bochs_bo *bo = gem_to_bochs_bo(obj);
+
+   return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
+}
+
+void bochs_gem_prime_unpin(struct drm_gem_object *obj)
+{
+   struct bochs_bo *bo = gem_to_bochs_bo(obj);
+
+   bochs_bo_unpin(bo);
+}
+
+void *bochs_gem_prime_vmap(struct drm_gem_object *obj)
+{
+   struct bochs_bo *bo = gem_to_bochs_bo(obj);
+   bool is_iomem;
+   int ret;
+
+   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
+   if (ret)
+   return NULL;
+   ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+   if (ret) {
+   bochs_bo_unpin(bo);
+   return NULL;
+   }
+   return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+}
+
+void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+   struct bochs_bo *bo = gem_to_bochs_bo(obj);
+
+   ttm_bo_kunmap(&bo->kmap);
+   bochs_bo_unpin(bo);
+}
+
+int bochs_gem_prime_mmap(struct drm_gem_object *obj,
+struct vm_area_struct *vma)
+{
+   struct bochs_bo *bo = gem_to_bochs_bo(obj);
+
+   return ttm_fbdev_mmap(vma, &bo->bo);
+}
-- 
2.9.3

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


[PATCH v4 01/16] drm/bochs: encoder cleanup

2019-01-10 Thread Gerd Hoffmann
Most unused callbacks can be NULL pointers these days.
Drop a bunch of empty encoder callbacks.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 26 --
 1 file changed, 26 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index f87c284dd9..c8ce54498d 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -170,31 +170,6 @@ static void bochs_crtc_init(struct drm_device *dev)
drm_crtc_helper_add(crtc, &bochs_helper_funcs);
 }
 
-static void bochs_encoder_mode_set(struct drm_encoder *encoder,
-  struct drm_display_mode *mode,
-  struct drm_display_mode *adjusted_mode)
-{
-}
-
-static void bochs_encoder_dpms(struct drm_encoder *encoder, int state)
-{
-}
-
-static void bochs_encoder_prepare(struct drm_encoder *encoder)
-{
-}
-
-static void bochs_encoder_commit(struct drm_encoder *encoder)
-{
-}
-
-static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = {
-   .dpms = bochs_encoder_dpms,
-   .mode_set = bochs_encoder_mode_set,
-   .prepare = bochs_encoder_prepare,
-   .commit = bochs_encoder_commit,
-};
-
 static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = {
.destroy = drm_encoder_cleanup,
 };
@@ -207,7 +182,6 @@ static void bochs_encoder_init(struct drm_device *dev)
encoder->possible_crtcs = 0x1;
drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs,
 DRM_MODE_ENCODER_DAC, NULL);
-   drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs);
 }
 
 
-- 
2.9.3

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


[PATCH v4 07/16] drm/bochs: atomic: use atomic page_flip helper

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, step five.
Use atomic page_flip helper for crtc.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 23 +--
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 646f897cb2..67c3674609 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -104,27 +104,6 @@ static void bochs_crtc_commit(struct drm_crtc *crtc)
 {
 }
 
-static int bochs_crtc_page_flip(struct drm_crtc *crtc,
-   struct drm_framebuffer *fb,
-   struct drm_pending_vblank_event *event,
-   uint32_t page_flip_flags,
-   struct drm_modeset_acquire_ctx *ctx)
-{
-   struct bochs_device *bochs =
-   container_of(crtc, struct bochs_device, crtc);
-   struct drm_framebuffer *old_fb = crtc->primary->fb;
-   unsigned long irqflags;
-
-   drm_atomic_set_fb_for_plane(crtc->primary->state, fb);
-   bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
-   if (event) {
-   spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
-   drm_crtc_send_vblank_event(crtc, event);
-   spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags);
-   }
-   return 0;
-}
-
 static void bochs_crtc_atomic_enable(struct drm_crtc *crtc,
 struct drm_crtc_state *old_crtc_state)
 {
@@ -152,7 +131,7 @@ static void bochs_crtc_atomic_flush(struct drm_crtc *crtc,
 static const struct drm_crtc_funcs bochs_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = drm_crtc_cleanup,
-   .page_flip = bochs_crtc_page_flip,
+   .page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
-- 
2.9.3

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


[PATCH v4 04/16] drm/bochs: atomic: add mode_set_nofb callback.

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, step two.
Add mode_set_nofb crtc helper callback.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 2cbd406b1f..56fd7be933 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -86,6 +86,14 @@ static int bochs_crtc_mode_set(struct drm_crtc *crtc,
return 0;
 }
 
+static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+   struct bochs_device *bochs =
+   container_of(crtc, struct bochs_device, crtc);
+
+   bochs_hw_setmode(bochs, &crtc->mode);
+}
+
 static void bochs_crtc_prepare(struct drm_crtc *crtc)
 {
 }
@@ -149,6 +157,7 @@ static const struct drm_crtc_helper_funcs 
bochs_helper_funcs = {
.dpms = bochs_crtc_dpms,
.mode_set = bochs_crtc_mode_set,
.mode_set_base = bochs_crtc_mode_set_base,
+   .mode_set_nofb = bochs_crtc_mode_set_nofb,
.prepare = bochs_crtc_prepare,
.commit = bochs_crtc_commit,
.atomic_enable = bochs_crtc_atomic_enable,
-- 
2.9.3

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


[PATCH v4 14/16] drm/bochs: switch to generic drm fbdev emulation

2019-01-10 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_drv.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_drv.c 
b/drivers/gpu/drm/bochs/bochs_drv.c
index a3f4e21078..cea42ac64d 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -16,10 +16,6 @@ static int bochs_modeset = -1;
 module_param_named(modeset, bochs_modeset, int, 0444);
 MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
 
-static bool enable_fbdev = true;
-module_param_named(fbdev, enable_fbdev, bool, 0444);
-MODULE_PARM_DESC(fbdev, "register fbdev device");
-
 /* -- */
 /* drm interface  */
 
@@ -27,7 +23,6 @@ static void bochs_unload(struct drm_device *dev)
 {
struct bochs_device *bochs = dev->dev_private;
 
-   bochs_fbdev_fini(bochs);
bochs_kms_fini(bochs);
bochs_mm_fini(bochs);
bochs_hw_fini(dev);
@@ -58,9 +53,6 @@ static int bochs_load(struct drm_device *dev)
if (ret)
goto err;
 
-   if (enable_fbdev)
-   bochs_fbdev_init(bochs);
-
return 0;
 
 err:
@@ -110,9 +102,7 @@ static int bochs_pm_suspend(struct device *dev)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
-   struct bochs_device *bochs = drm_dev->dev_private;
 
-   drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 1);
return drm_mode_config_helper_suspend(drm_dev);
 }
 
@@ -120,9 +110,7 @@ static int bochs_pm_resume(struct device *dev)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
-   struct bochs_device *bochs = drm_dev->dev_private;
 
-   drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 0);
return drm_mode_config_helper_resume(drm_dev);
 }
 #endif
@@ -167,6 +155,7 @@ static int bochs_pci_probe(struct pci_dev *pdev,
if (ret)
goto err_unload;
 
+   drm_fbdev_generic_setup(dev, 32);
return ret;
 
 err_unload:
-- 
2.9.3

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


[PATCH v4 05/16] drm/bochs: atomic: switch planes to atomic, wire up helpers.

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, step three.
Wire up atomic helpers.  Switch planes to atomic.

We are late to the party, the transitional helpers are gone,
so this can't be splitted into smaller steps any more.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_fbdev.c |  3 ++
 drivers/gpu/drm/bochs/bochs_kms.c   | 82 +++--
 2 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c 
b/drivers/gpu/drm/bochs/bochs_fbdev.c
index dd3c7df267..d9f3d42999 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -6,6 +6,7 @@
  */
 
 #include "bochs.h"
+#include 
 #include 
 
 /* -- */
@@ -149,6 +150,8 @@ bochs_gem_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
 const struct drm_mode_config_funcs bochs_mode_funcs = {
.fb_create = bochs_gem_fb_create,
+   .atomic_check = drm_atomic_helper_check,
+   .atomic_commit = drm_atomic_helper_commit,
 };
 
 int bochs_fbdev_init(struct bochs_device *bochs)
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 56fd7be933..c6993c2d59 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -6,7 +6,9 @@
  */
 
 #include "bochs.h"
+#include 
 #include 
+#include 
 
 static int defx = 1024;
 static int defy = 768;
@@ -113,7 +115,7 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->primary->fb;
unsigned long irqflags;
 
-   crtc->primary->fb = fb;
+   drm_atomic_set_fb_for_plane(crtc->primary->state, fb);
bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
if (event) {
spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
@@ -151,6 +153,9 @@ static const struct drm_crtc_funcs bochs_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = drm_crtc_cleanup,
.page_flip = bochs_crtc_page_flip,
+   .reset = drm_atomic_helper_crtc_reset,
+   .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
 static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
@@ -169,6 +174,71 @@ static const uint32_t bochs_formats[] = {
DRM_FORMAT_BGRX,
 };
 
+static void bochs_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+   struct bochs_device *bochs = plane->dev->dev_private;
+   struct bochs_bo *bo;
+
+   if (!plane->state->fb)
+   return;
+   bo = gem_to_bochs_bo(plane->state->fb->obj[0]);
+   bochs_hw_setbase(bochs,
+plane->state->crtc_x,
+plane->state->crtc_y,
+bo->bo.offset);
+   bochs_hw_setformat(bochs, plane->state->fb->format);
+}
+
+static int bochs_plane_prepare_fb(struct drm_plane *plane,
+   struct drm_plane_state *new_state)
+{
+   struct bochs_bo *bo;
+   int ret;
+
+   if (!new_state->fb)
+   return 0;
+   bo = gem_to_bochs_bo(new_state->fb->obj[0]);
+
+   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+   if (ret)
+   return ret;
+   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+   ttm_bo_unreserve(&bo->bo);
+   return ret;
+}
+
+static void bochs_plane_cleanup_fb(struct drm_plane *plane,
+  struct drm_plane_state *old_state)
+{
+   struct bochs_bo *bo;
+   int ret;
+
+   if (!old_state->fb)
+   return;
+   bo = gem_to_bochs_bo(old_state->fb->obj[0]);
+   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+   if (ret)
+   return;
+   bochs_bo_unpin(bo);
+   ttm_bo_unreserve(&bo->bo);
+}
+
+static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = {
+   .atomic_update = bochs_plane_atomic_update,
+   .prepare_fb = bochs_plane_prepare_fb,
+   .cleanup_fb = bochs_plane_cleanup_fb,
+};
+
+static const struct drm_plane_funcs bochs_plane_funcs = {
+   .update_plane   = drm_atomic_helper_update_plane,
+   .disable_plane  = drm_atomic_helper_disable_plane,
+   .destroy= drm_primary_helper_destroy,
+   .reset  = drm_atomic_helper_plane_reset,
+   .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
 static struct drm_plane *bochs_primary_plane(struct drm_device *dev)
 {
struct drm_plane *primary;
@@ -181,16 +251,17 @@ static struct drm_plane *bochs_primary_plane(struct 
drm_device *dev)
}
 
ret = drm_universal_plane_init(dev, primary, 0,
-  &drm

[PATCH v4 08/16] drm/bochs: atomic: use suspend/resume helpers

2019-01-10 Thread Gerd Hoffmann
Switch to atomic helpers: drm_mode_config_helper_suspend/resume().

Signed-off-by: Gerd Hoffmann 
---
 drivers/gpu/drm/bochs/bochs_drv.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_drv.c 
b/drivers/gpu/drm/bochs/bochs_drv.c
index f3dd66ae99..08ba6029d2 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -103,11 +103,8 @@ static int bochs_pm_suspend(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct bochs_device *bochs = drm_dev->dev_private;
 
-   drm_kms_helper_poll_disable(drm_dev);
-
drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 1);
-
-   return 0;
+   return drm_mode_config_helper_suspend(drm_dev);
 }
 
 static int bochs_pm_resume(struct device *dev)
@@ -116,12 +113,8 @@ static int bochs_pm_resume(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct bochs_device *bochs = drm_dev->dev_private;
 
-   drm_helper_resume_force_mode(drm_dev);
-
drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 0);
-
-   drm_kms_helper_poll_enable(drm_dev);
-   return 0;
+   return drm_mode_config_helper_resume(drm_dev);
 }
 #endif
 
-- 
2.9.3

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


[PATCH v4 11/16] drm/bochs: drop unused gpu_addr arg from bochs_bo_pin()

2019-01-10 Thread Gerd Hoffmann
It's always NULL, so just remove it.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs.h   |  2 +-
 drivers/gpu/drm/bochs/bochs_fbdev.c |  2 +-
 drivers/gpu/drm/bochs/bochs_kms.c   |  2 +-
 drivers/gpu/drm/bochs/bochs_mm.c| 11 +--
 4 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 4dc1b6384e..d0d474e06f 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -142,7 +142,7 @@ int bochs_dumb_create(struct drm_file *file, struct 
drm_device *dev,
 int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
   uint32_t handle, uint64_t *offset);
 
-int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr);
+int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag);
 int bochs_bo_unpin(struct bochs_bo *bo);
 
 /* bochs_kms.c */
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c 
b/drivers/gpu/drm/bochs/bochs_fbdev.c
index d9f3d42999..92feb817ff 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -81,7 +81,7 @@ static int bochsfb_create(struct drm_fb_helper *helper,
if (ret)
return ret;
 
-   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
if (ret) {
DRM_ERROR("failed to pin fbcon\n");
ttm_bo_unreserve(&bo->bo);
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 5b7e1a7c6b..f663c54185 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -101,7 +101,7 @@ static int bochs_plane_prepare_fb(struct drm_plane *plane,
ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
if (ret)
return ret;
-   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
ttm_bo_unreserve(&bo->bo);
return ret;
 }
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 0980411e41..5a0e092847 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -210,20 +210,13 @@ static void bochs_ttm_placement(struct bochs_bo *bo, int 
domain)
bo->placement.num_busy_placement = c;
 }
 
-static inline u64 bochs_bo_gpu_offset(struct bochs_bo *bo)
-{
-   return bo->bo.offset;
-}
-
-int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr)
+int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag)
 {
struct ttm_operation_ctx ctx = { false, false };
int i, ret;
 
if (bo->pin_count) {
bo->pin_count++;
-   if (gpu_addr)
-   *gpu_addr = bochs_bo_gpu_offset(bo);
return 0;
}
 
@@ -235,8 +228,6 @@ int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 
*gpu_addr)
return ret;
 
bo->pin_count = 1;
-   if (gpu_addr)
-   *gpu_addr = bochs_bo_gpu_offset(bo);
return 0;
 }
 
-- 
2.9.3

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


[PATCH v4 09/16] drm/bochs: atomic: set DRIVER_ATOMIC

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, final step.
Set the DRIVER_ATOMIC flag.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bochs/bochs_drv.c 
b/drivers/gpu/drm/bochs/bochs_drv.c
index 08ba6029d2..a8cb22cffe 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -81,7 +81,7 @@ static const struct file_operations bochs_fops = {
 };
 
 static struct drm_driver bochs_driver = {
-   .driver_features= DRIVER_GEM | DRIVER_MODESET,
+   .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
.fops   = &bochs_fops,
.name   = "bochs-drm",
.desc   = "bochs dispi vga interface (qemu stdvga)",
-- 
2.9.3

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


[PATCH v4 12/16] drm/bochs: move ttm_bo_(un)reserve calls into bochs_bo_{pin, unpin}

2019-01-10 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_fbdev.c |  8 
 drivers/gpu/drm/bochs/bochs_kms.c   | 14 +-
 drivers/gpu/drm/bochs/bochs_mm.c|  8 
 3 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c 
b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 92feb817ff..ccf783b038 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -77,14 +77,9 @@ static int bochsfb_create(struct drm_fb_helper *helper,
 
bo = gem_to_bochs_bo(gobj);
 
-   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-   if (ret)
-   return ret;
-
ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
if (ret) {
DRM_ERROR("failed to pin fbcon\n");
-   ttm_bo_unreserve(&bo->bo);
return ret;
}
 
@@ -92,12 +87,9 @@ static int bochsfb_create(struct drm_fb_helper *helper,
  &bo->kmap);
if (ret) {
DRM_ERROR("failed to kmap fbcon\n");
-   ttm_bo_unreserve(&bo->bo);
return ret;
}
 
-   ttm_bo_unreserve(&bo->bo);
-
/* init fb device */
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index f663c54185..fc856a02a2 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -92,34 +92,22 @@ static int bochs_plane_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *new_state)
 {
struct bochs_bo *bo;
-   int ret;
 
if (!new_state->fb)
return 0;
bo = gem_to_bochs_bo(new_state->fb->obj[0]);
-
-   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-   if (ret)
-   return ret;
-   ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
-   ttm_bo_unreserve(&bo->bo);
-   return ret;
+   return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
 }
 
 static void bochs_plane_cleanup_fb(struct drm_plane *plane,
   struct drm_plane_state *old_state)
 {
struct bochs_bo *bo;
-   int ret;
 
if (!old_state->fb)
return;
bo = gem_to_bochs_bo(old_state->fb->obj[0]);
-   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-   if (ret)
-   return;
bochs_bo_unpin(bo);
-   ttm_bo_unreserve(&bo->bo);
 }
 
 static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = {
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 5a0e092847..fcbf35456d 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -223,7 +223,11 @@ int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag)
bochs_ttm_placement(bo, pl_flag);
for (i = 0; i < bo->placement.num_placement; i++)
bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+   if (ret)
+   return ret;
ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
+   ttm_bo_unreserve(&bo->bo);
if (ret)
return ret;
 
@@ -247,7 +251,11 @@ int bochs_bo_unpin(struct bochs_bo *bo)
 
for (i = 0; i < bo->placement.num_placement; i++)
bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
+   ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+   if (ret)
+   return ret;
ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
+   ttm_bo_unreserve(&bo->bo);
if (ret)
return ret;
 
-- 
2.9.3

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


[PATCH v4 06/16] drm/bochs: atomic: use atomic set_config helper

2019-01-10 Thread Gerd Hoffmann
Conversion to atomic modesetting, step four.
Use atomic set_config helper for crtc.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Oleksandr Andrushchenko 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/bochs/bochs_kms.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index c6993c2d59..646f897cb2 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -150,7 +150,7 @@ static void bochs_crtc_atomic_flush(struct drm_crtc *crtc,
 
 /* These provide the minimum set of functions required to handle a CRTC */
 static const struct drm_crtc_funcs bochs_crtc_funcs = {
-   .set_config = drm_crtc_helper_set_config,
+   .set_config = drm_atomic_helper_set_config,
.destroy = drm_crtc_cleanup,
.page_flip = bochs_crtc_page_flip,
.reset = drm_atomic_helper_crtc_reset,
-- 
2.9.3

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


[PATCH 3/3] drm/i915/icl: Enabling Y2xx and Y4xx (xx:10/12/16) formats for universal planes

2019-01-10 Thread swati2 . sharma
From: Swati Sharma 

Signed-off-by: Swati Sharma 
---
 drivers/gpu/drm/i915/intel_display.c | 30 ++
 drivers/gpu/drm/i915/intel_sprite.c  | 61 ++--
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 1cc441f..e7a86c6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2633,6 +2633,18 @@ int skl_format_to_fourcc(int format, bool rgb_order, 
bool alpha)
return DRM_FORMAT_RGB565;
case PLANE_CTL_FORMAT_NV12:
return DRM_FORMAT_NV12;
+   case PLANE_CTL_FORMAT_Y210:
+   return DRM_FORMAT_Y210;
+   case PLANE_CTL_FORMAT_Y212:
+   return DRM_FORMAT_Y212;
+   case PLANE_CTL_FORMAT_Y216:
+   return DRM_FORMAT_Y216;
+   case PLANE_CTL_FORMAT_Y410:
+   return DRM_FORMAT_Y410;
+   case PLANE_CTL_FORMAT_Y412:
+   return DRM_FORMAT_Y412;
+   case PLANE_CTL_FORMAT_Y416:
+   return DRM_FORMAT_Y416;
default:
case PLANE_CTL_FORMAT_XRGB_:
if (rgb_order) {
@@ -3529,6 +3541,18 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format)
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
case DRM_FORMAT_NV12:
return PLANE_CTL_FORMAT_NV12;
+   case DRM_FORMAT_Y210:
+   return PLANE_CTL_FORMAT_Y210;
+   case DRM_FORMAT_Y212:
+   return PLANE_CTL_FORMAT_Y212;
+   case DRM_FORMAT_Y216:
+   return PLANE_CTL_FORMAT_Y216;
+   case DRM_FORMAT_Y410:
+   return PLANE_CTL_FORMAT_Y410;
+   case DRM_FORMAT_Y412:
+   return PLANE_CTL_FORMAT_Y412;
+   case DRM_FORMAT_Y416:
+   return PLANE_CTL_FORMAT_Y416;
default:
MISSING_CASE(pixel_format);
}
@@ -5022,6 +5046,12 @@ static int skl_update_scaler_plane(struct 
intel_crtc_state *crtc_state,
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_NV12:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
+   case DRM_FORMAT_Y410:
+   case DRM_FORMAT_Y412:
+   case DRM_FORMAT_Y416:
break;
default:
DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 
0x%x\n",
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 8f3982c..f1bc46d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1750,6 +1750,27 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device 
*dev, void *data,
DRM_FORMAT_VYUY,
 };
 
+static const uint32_t icl_plane_formats[] = {
+   DRM_FORMAT_C8,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_Y210,
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_Y216,
+   DRM_FORMAT_Y410,
+   DRM_FORMAT_Y412,
+   DRM_FORMAT_Y416,
+};
+
 static const uint32_t skl_planar_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
@@ -1766,6 +1787,28 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device 
*dev, void *data,
DRM_FORMAT_NV12,
 };
 
+static const uint32_t icl_planar_formats[] = {
+   DRM_FORMAT_C8,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_NV12,
+   DRM_FORMAT_Y210,
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_Y216,
+   DRM_FORMAT_Y410,
+   DRM_FORMAT_Y412,
+   DRM_FORMAT_Y416,
+};
+
 static const uint64_t skl_plane_format_modifiers_noccs[] = {
I915_FORMAT_MOD_Yf_TILED,
I915_FORMAT_MOD_Y_TILED,
@@ -1904,6 +1947,12 @@ static bool skl_plane_format_mod_supported(struct 
drm_plane *_plane,
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
+   case DRM_FORMAT_Y410:
+   case DRM_FORMAT_Y412:
+   case DRM_FORMAT_Y416:
case DRM_FORMAT_NV12:
if (modifier == I915_FORMAT_MOD_Yf_TILED)
return true;
@@ -2045,8 +2094,16 @@ struct intel_plane *
plane->update_slave = icl_update_slave;
 
if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
-   formats = skl_planar_formats;
-   num_formats = ARRAY_SIZE(skl_planar_formats);
+

[PATCH 2/3] drm/i915/icl: Add Y2xx and Y4xx (xx:10/12/16) plane control definitions

2019-01-10 Thread swati2 . sharma
From: Swati Sharma 

Added needed plane control flag definitions for Y2xx and Y4xx (10, 12 and
16 bits)

Signed-off-by: Swati Sharma 
---
 drivers/gpu/drm/i915/i915_reg.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 44958d9..7150bc5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6546,6 +6546,12 @@ enum {
 #define   PLANE_CTL_FORMAT_RGB_565 (14 << 24)
 #define   ICL_PLANE_CTL_FORMAT_MASK(0x1f << 23)
 #define   PLANE_CTL_PIPE_CSC_ENABLE(1 << 23) /* Pre-GLK */
+#define   PLANE_CTL_FORMAT_Y210 (1 << 23)
+#define   PLANE_CTL_FORMAT_Y212 (3 << 23)
+#define   PLANE_CTL_FORMAT_Y216 (5 << 23)
+#define   PLANE_CTL_FORMAT_Y410 (7 << 23)
+#define   PLANE_CTL_FORMAT_Y412 (9 << 23)
+#define   PLANE_CTL_FORMAT_Y416 (0xb << 23)
 #define   PLANE_CTL_KEY_ENABLE_MASK(0x3 << 21)
 #define   PLANE_CTL_KEY_ENABLE_SOURCE  (1 << 21)
 #define   PLANE_CTL_KEY_ENABLE_DESTINATION (2 << 21)
-- 
1.9.1

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


[PATCH 1/3] drm: Add Y2xx and Y4xx (xx:10/12/16) format definitions and fourcc

2019-01-10 Thread swati2 . sharma
From: Swati Sharma 

The following pixel formats are packed format that follows 4:2:2
chroma sampling. For memory represenation each component is
allocated 16 bits each. Thus each pixel occupies 32bit.

Y210:   For each component, valid data occupies MSB 10 bits.
LSB 6 bits are filled with zeroes.
Y212:   For each component, valid data occupies MSB 12 bits.
LSB 4 bits are filled with zeroes.
Y216:   For each component valid data occupies 16 bits,
doesn't require any padding bits.

First 16 bits stores the Y value and the next 16 bits stores one
of the chroma samples alternatively. The first luma sample will
be accompanied by first U sample and second luma sample is
accompanied by the first V sample.

The following pixel formats are packed format that follows 4:4:4
chroma sampling. Channels are arranged in the order UYVA in
increasing memory order.

Y410:   Each color component occupies 10 bits and X component
takes 2 bits, thus each pixel occupies 32 bits.
Y412:   Each color component is 16 bits where valid data
occupies MSB 12 bits. LSB 4 bits are filled with zeroes.
Thus, each pixel occupies 64 bits.
Y416:   Each color component occupies 16 bits for valid data,
doesn't require any padding bits. Thus, each pixel
occupies 64 bits.

Signed-off-by: Swati Sharma 
---
 drivers/gpu/drm/drm_fourcc.c  |  6 ++
 include/uapi/drm/drm_fourcc.h | 18 +-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index d90ee03..639ab93 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -226,6 +226,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_VYUY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_XYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_AYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_Y210,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y212,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y216,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y410,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y412,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y416,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_Y0L0,.depth = 0,  
.num_planes = 1,
  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0 },
  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 0b44260..97249a5 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -151,7 +151,23 @@
 #define DRM_FORMAT_VYUYfourcc_code('V', 'Y', 'U', 'Y') /* 
[31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
 
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
-#define DRM_FORMAT_XYUVfourcc_code('X', 'Y', 'U', 'V') /* 
[31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XYUVfourcc_code('X', 'Y', 'U', 'V') /* [31:0] 
X:Y:Cb:Cr 8:8:8:8 little endian */
+
+/*
+ * packed Y2xx indicate for each component, xx valid data occupy msb
+ * 16-xx padding occupy lsb
+ */
+#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') /* [63:0] 
Y0:x:Cb0:x:Y1:x:Cr1:x 10:6:10:6:10:6:10:6 little endian */
+#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') /* [63:0] 
Y0:x:Cb0:x:Y1:x:Cr1:x 12:4:12:4:12:4:12:4 little endian */
+#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6') /* [63:0] 
Y0:Cb0:Y1:Cr1 16:16:16:16 little endian */
+
+/*
+ * packed Y4xx indicate for each component, xx valid data occupy msb
+ * 16-xx padding occupy lsb except Y410
+ */
+#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0') /* [31:0] 
X:V:Y:U 2:10:10:10 little endian */
+#define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2') /* [64:0] 
X:x:V:x:Y:x:U:x 12:4:12:4:12:4:12:4 little endian */
+#define DRM_FORMAT_Y416 fourcc_code('Y', '4', '1', '6') /* [64:0] 
X:V:Y:U 16:16:16:16 little endian */

[PATCH 0/3] Enable Y2xx and Y4xx (xx:10/12/16 bits) packed formats for ICL

2019-01-10 Thread swati2 . sharma
From: Swati Sharma 

These patches enable packed format YUV422-Y210, Y212 and Y216
and YUV444-Y410, Y412, Y416 for 10, 12 and 16 bits for ICL+.

IGT needs libraries for Pixman and Cairo to support more than 8bpc.
Work going on from Maarten Lankhorst.

Initial review for Y2xx done https://patchwork.freedesktop.org/series/48729/
However, submitting new patch series consolidating Y2xx and Y4xx.

Swati Sharma (3):
  drm: Add Y2xx and Y4xx (xx:10/12/16) format definitions and fourcc
  drm/i915/icl: Add Y2xx and Y4xx (xx:10/12/16) plane control
definitions
  drm/i915/icl: Enabling Y2xx and Y4xx (xx:10/12/16) formats for
universal planes

 drivers/gpu/drm/drm_fourcc.c |  6 
 drivers/gpu/drm/i915/i915_reg.h  |  6 
 drivers/gpu/drm/i915/intel_display.c | 30 ++
 drivers/gpu/drm/i915/intel_sprite.c  | 61 ++--
 include/uapi/drm/drm_fourcc.h| 18 ++-
 5 files changed, 118 insertions(+), 3 deletions(-)

-- 
1.9.1

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


[Bug 109229] glLinkProgram locks up for ~30 seconds

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109229

--- Comment #6 from Fabian  ---
Hi Tim, sorry about the slow reply.

I've added instructions on how to reproduce the problem here:
https://github.com/godotengine/godot/issues/24783#issuecomment-453380560

Download build.zip and it has everything you need in there.


How would I go about bisecting the changes between 18.2 and 18.3 where things
went awry?

-- 
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 v2 26/49] drm/omap: Move DISPC timing checks to CRTC .mode_valid() operation

2019-01-10 Thread Laurent Pinchart
The DISPC timings checks relate to the CRTC, but they're performed in
the encoder and connector .atomic_check() and .mode_valid() operations.
Move them to the CRTC .mode_valid() operation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 6 --
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 9 +
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 6 --
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 8db1f2fbcf43..dd1e0f2e8ffc 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -245,8 +245,6 @@ static int omap_connector_mode_valid(struct drm_connector 
*connector,
 struct drm_display_mode *mode)
 {
struct omap_connector *omap_connector = to_omap_connector(connector);
-   enum omap_channel channel = omap_connector->output->dispc_channel;
-   struct omap_drm_private *priv = connector->dev->dev_private;
struct omap_dss_device *dssdev;
struct videomode vm = {0};
struct drm_device *dev = connector->dev;
@@ -256,10 +254,6 @@ static int omap_connector_mode_valid(struct drm_connector 
*connector,
drm_display_mode_to_videomode(mode, &vm);
mode->vrefresh = drm_mode_vrefresh(mode);
 
-   r = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
-   if (r)
-   goto done;
-
for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings)
continue;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index caffc547ef97..51036e6fca1c 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -391,6 +391,15 @@ static enum drm_mode_status omap_crtc_mode_valid(struct 
drm_crtc *crtc,
const struct drm_display_mode *mode)
 {
struct omap_drm_private *priv = crtc->dev->dev_private;
+   struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct videomode vm = {0};
+   int r;
+
+   drm_display_mode_to_videomode(mode, &vm);
+   r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel,
+  &vm);
+   if (r)
+   return r;
 
/* Check for bandwidth limit */
if (priv->max_bandwidth) {
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 02b2e24ad333..0f8da7b81829 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -206,19 +206,13 @@ static int omap_encoder_atomic_check(struct drm_encoder 
*encoder,
 struct drm_connector_state *conn_state)
 {
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   enum omap_channel channel = omap_encoder->output->dispc_channel;
struct drm_device *dev = encoder->dev;
-   struct omap_drm_private *priv = dev->dev_private;
struct omap_dss_device *dssdev;
struct videomode vm = { 0 };
int ret;
 
drm_display_mode_to_videomode(&crtc_state->mode, &vm);
 
-   ret = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
-   if (ret)
-   goto done;
-
for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings)
continue;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 40/49] drm/bridge: ti-tfp410: Add support for the powerdown GPIO

2019-01-10 Thread Laurent Pinchart
The TFP410 has a powerdown pin that can be connected to a GPIO to
control power saving. The DT bindings define a corresponding property,
but the driver doesn't implement support for it. Fix that.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Jyri Sarha 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index e4280f5af9f5..d25d23cfe3f5 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -32,6 +32,7 @@ struct tfp410 {
struct i2c_adapter  *ddc;
struct gpio_desc*hpd;
struct delayed_work hpd_work;
+   struct gpio_desc*powerdown;
 
struct device *dev;
 };
@@ -139,8 +140,24 @@ static int tfp410_attach(struct drm_bridge *bridge)
return 0;
 }
 
+static void tfp410_enable(struct drm_bridge *bridge)
+{
+   struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
+
+   gpiod_set_value_cansleep(dvi->powerdown, 0);
+}
+
+static void tfp410_disable(struct drm_bridge *bridge)
+{
+   struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
+
+   gpiod_set_value_cansleep(dvi->powerdown, 1);
+}
+
 static const struct drm_bridge_funcs tfp410_bridge_funcs = {
.attach = tfp410_attach,
+   .enable = tfp410_enable,
+   .disable= tfp410_disable,
 };
 
 static void tfp410_hpd_work_func(struct work_struct *work)
@@ -229,6 +246,13 @@ static int tfp410_init(struct device *dev)
if (ret)
goto fail;
 
+   dvi->powerdown = devm_gpiod_get_optional(dev, "powerdown",
+GPIOD_OUT_HIGH);
+   if (IS_ERR(dvi->powerdown)) {
+   dev_err(dev, "failed to parse powerdown gpio\n");
+   return PTR_ERR(dvi->powerdown);
+   }
+
if (dvi->hpd) {
INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 29/49] drm/omap: Pass drm_display_mode to .check_timings() and .set_timings()

2019-01-10 Thread Laurent Pinchart
The omap_dss_device .check_timings() and .set_timings() operations
operate on struct videomode, while the DRM API operates on struct
drm_display_mode. This forces conversion from to videomode in the
callers. While that's not a problem per se, it creates a difference with
the drm_bridge API.

Replace the videomode parameter to the .check_timings() and
.set_timings() operations with a drm_display_mode. This pushed the
conversion to videomode down to the DSS devices in some cases. If needed
they will be converted to operate on drm_display_mode natively.

Signed-off-by: Laurent Pinchart 
Tested-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   |  8 +++---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 16 +--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |  6 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |  6 ++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  4 +--
 drivers/gpu/drm/omapdrm/dss/sdi.c | 17 +--
 drivers/gpu/drm/omapdrm/dss/venc.c| 28 +--
 drivers/gpu/drm/omapdrm/omap_connector.c  |  7 ++---
 drivers/gpu/drm/omapdrm/omap_encoder.c|  2 +-
 9 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index ce812094177c..d9f10f41ddfb 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -1127,20 +1127,20 @@ static int dsicm_get_modes(struct omap_dss_device 
*dssdev,
 }
 
 static int dsicm_check_timings(struct omap_dss_device *dssdev,
-  struct videomode *vm)
+  struct drm_display_mode *mode)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
int ret = 0;
 
-   if (vm->hactive != ddata->vm.hactive)
+   if (mode->hdisplay != ddata->vm.hactive)
ret = -EINVAL;
 
-   if (vm->vactive != ddata->vm.vactive)
+   if (mode->vdisplay != ddata->vm.vactive)
ret = -EINVAL;
 
if (ret) {
dev_warn(dssdev->dev, "wrong resolution: %d x %d",
-vm->hactive, vm->vactive);
+mode->hdisplay, mode->vdisplay);
dev_warn(dssdev->dev, "panel resolution: %d x %d",
 ddata->vm.hactive, ddata->vm.vactive);
}
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 0db01cadf09f..0cb3cb72f15f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -459,7 +459,7 @@ static void dpi_display_disable(struct omap_dss_device 
*dssdev)
 }
 
 static void dpi_set_timings(struct omap_dss_device *dssdev,
-   const struct videomode *vm)
+   const struct drm_display_mode *mode)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
@@ -467,13 +467,13 @@ static void dpi_set_timings(struct omap_dss_device 
*dssdev,
 
mutex_lock(&dpi->lock);
 
-   dpi->vm = *vm;
+   drm_display_mode_to_videomode(mode, &dpi->vm);
 
mutex_unlock(&dpi->lock);
 }
 
 static int dpi_check_timings(struct omap_dss_device *dssdev,
-struct videomode *vm)
+struct drm_display_mode *mode)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
int lck_div, pck_div;
@@ -482,20 +482,20 @@ static int dpi_check_timings(struct omap_dss_device 
*dssdev,
struct dpi_clk_calc_ctx ctx;
bool ok;
 
-   if (vm->hactive % 8 != 0)
+   if (mode->hdisplay % 8 != 0)
return -EINVAL;
 
-   if (vm->pixelclock == 0)
+   if (mode->clock == 0)
return -EINVAL;
 
if (dpi->pll) {
-   ok = dpi_pll_clk_calc(dpi, vm->pixelclock, &ctx);
+   ok = dpi_pll_clk_calc(dpi, mode->clock * 1000, &ctx);
if (!ok)
return -EINVAL;
 
fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
} else {
-   ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx);
+   ok = dpi_dss_clk_calc(dpi, mode->clock * 1000, &ctx);
if (!ok)
return -EINVAL;
 
@@ -507,7 +507,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 
pck = fck / lck_div / pck_div;
 
-   vm->pixelclock = pck;
+   mode->clock = pck / 1000;
 
return 0;
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 60792981a33f..4337380b1bf7 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -249,15 +249,15 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
 }
 
 static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
-const struct videomode *vm)
+

[PATCH v2 38/49] dt-bindings: display: tfp410: Add bus parameters properties

2019-01-10 Thread Laurent Pinchart
The TFP410 supports configuration of several input bus parameters
through either the I2C port or chip pins. In the latter case, we need to
specify those parameters in DT.

Two new properties are added, ti,deskew to specify the data de-skew
configuration (as set through the DK[3:1] pins), and pclk-sample to
specify the pixel clock sampling edge (as set through the EDGE pin).

Signed-off-by: Laurent Pinchart 
Reviewed-by: Tomi Valkeinen 
---
 .../bindings/display/bridge/ti,tfp410.txt | 24 ++-
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt 
b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
index 54d7e31525ec..3f903af93949 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
+++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
@@ -6,15 +6,25 @@ Required properties:
 
 Optional properties:
 - powerdown-gpios: power-down gpio
-- reg: I2C address. If and only if present the device node
-   should be placed into the i2c controller node where the
-   tfp410 i2c is connected to.
+- reg: I2C address. If and only if present the device node should be placed
+  into the I2C controller node where the TFP410 I2C is connected to.
+- ti,deskew: data de-skew in 350ps increments, from -4 to +3, as configured
+  through th DK[3:1] pins. This property shall be present only if the TFP410
+  is not connected through I2C.
 
 Required nodes:
-- Video port 0 for DPI input [1].
-- Video port 1 for DVI output [1].
 
-[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+This device has two video ports. Their connections are modeled using the OF
+graph bindings specified in [1]. Each port node shall have a single endpoint.
+
+- Port 0 is the DPI input port. Its endpoint subnode shall contain a
+  pclk-sample property and a remote-endpoint property as specified in [1].
+
+- Port 1 is the DVI output port. Its endpoint subnode shall contain a
+  remote-endpoint property is specified in [1].
+
+[1] Documentation/devicetree/bindings/media/video-interfaces.txt
+
 
 Example
 ---
@@ -22,6 +32,7 @@ Example
 tfp410: encoder@0 {
compatible = "ti,tfp410";
powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
+   ti,deskew = <4>;
 
ports {
#address-cells = <1>;
@@ -31,6 +42,7 @@ tfp410: encoder@0 {
reg = <0>;
 
tfp410_in: endpoint@0 {
+   pclk-sample = <1>;
remote-endpoint = <&dpi_out>;
};
};
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 43/49] dt-bindings: display: Add OSD Displays OSD070T1718-19TS panel binding

2019-01-10 Thread Laurent Pinchart
The OSD Displays OSD070T1718-19TS is a 7" WVGA (800x480) 24bit RGB panel
and is compatible with the simple-panel bindings.

Signed-off-by: Laurent Pinchart 
---
 .../display/panel/osddisplays,osd070t1718-19ts.txt | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/osddisplays,osd070t1718-19ts.txt

diff --git 
a/Documentation/devicetree/bindings/display/panel/osddisplays,osd070t1718-19ts.txt
 
b/Documentation/devicetree/bindings/display/panel/osddisplays,osd070t1718-19ts.txt
new file mode 100644
index ..ae7011820231
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/panel/osddisplays,osd070t1718-19ts.txt
@@ -0,0 +1,7 @@
+OSD Displays OSD070T1718-19TS 7" WVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "osddisplays,osd070t1718-19ts"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 23/49] drm/omap: panel-dsi-cm: Store source pointer internally

2019-01-10 Thread Laurent Pinchart
The source pointer will be removed to the omap_dss_device structure.
Store it internally in the DSI panel driver data.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 55 ++-
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index fe9d9f847d2e..ce812094177c 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -43,6 +43,7 @@
 
 struct panel_drv_data {
struct omap_dss_device dssdev;
+   struct omap_dss_device *src;
 
struct videomode vm;
 
@@ -143,7 +144,7 @@ static void hw_guard_wait(struct panel_drv_data *ddata)
 
 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
int r;
u8 buf[1];
 
@@ -159,14 +160,14 @@ static int dsicm_dcs_read_1(struct panel_drv_data *ddata, 
u8 dcs_cmd, u8 *data)
 
 static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
 
return src->ops->dsi.dcs_write(src, ddata->channel, &dcs_cmd, 1);
 }
 
 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 
param)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
u8 buf[2] = { dcs_cmd, param };
 
return src->ops->dsi.dcs_write(src, ddata->channel, buf, 2);
@@ -175,7 +176,7 @@ static int dsicm_dcs_write_1(struct panel_drv_data *ddata, 
u8 dcs_cmd, u8 param)
 static int dsicm_sleep_in(struct panel_drv_data *ddata)
 
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
u8 cmd;
int r;
 
@@ -230,7 +231,7 @@ static int dsicm_get_id(struct panel_drv_data *ddata, u8 
*id1, u8 *id2, u8 *id3)
 static int dsicm_set_update_window(struct panel_drv_data *ddata,
u16 x, u16 y, u16 w, u16 h)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
int r;
u16 x1 = x;
u16 x2 = x + w - 1;
@@ -277,7 +278,7 @@ static void dsicm_cancel_ulps_work(struct panel_drv_data 
*ddata)
 
 static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
int r;
 
if (ddata->ulps_enabled)
@@ -311,7 +312,7 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 
 static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 {
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
int r;
 
if (!ddata->ulps_enabled)
@@ -363,7 +364,7 @@ static int dsicm_wake_up(struct panel_drv_data *ddata)
 static int dsicm_bl_update_status(struct backlight_device *dev)
 {
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
int r = 0;
int level;
 
@@ -411,7 +412,7 @@ static ssize_t dsicm_num_errors_show(struct device *dev,
 {
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
u8 errors = 0;
int r;
 
@@ -443,7 +444,7 @@ static ssize_t dsicm_hw_revision_show(struct device *dev,
 {
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
u8 id1, id2, id3;
int r;
 
@@ -475,7 +476,7 @@ static ssize_t dsicm_store_ulps(struct device *dev,
 {
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
unsigned long t;
int r;
 
@@ -525,7 +526,7 @@ static ssize_t dsicm_store_ulps_timeout(struct device *dev,
 {
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct omap_dss_device *src = ddata->dssdev.src;
+   struct omap_dss_device *src = ddata->src;
unsigned long t;
int r;
 
@@ -600,7 +601,7 @@ static void dsicm_hw_reset(struct panel_drv_data *ddata)
 
 static int dsicm_power_on(struct panel_drv_data *ddata)
 {
-   struct omap_dss_device *src 

[PATCH v2 24/49] drm/omap: Notify all devices in the pipeline of output disconnection

2019-01-10 Thread Laurent Pinchart
For HDMI pipelines, when the output gets disconnected the device
handling CEC needs to be notified. Instead of guessing which device that
would be (and sometimes getting it wrong), notify all devices in the
pipeline.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 28 ++--
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 31b6d6d1def3..8db1f2fbcf43 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -35,18 +35,22 @@ struct omap_connector {
 };
 
 static void omap_connector_hpd_notify(struct drm_connector *connector,
- struct omap_dss_device *src,
  enum drm_connector_status status)
 {
-   if (status == connector_status_disconnected) {
-   /*
-* If the source is an HDMI encoder, notify it of disconnection.
-* This is required to let the HDMI encoder reset any internal
-* state related to connection status, such as the CEC address.
-*/
-   if (src && src->type == OMAP_DISPLAY_TYPE_HDMI &&
-   src->ops->hdmi.lost_hotplug)
-   src->ops->hdmi.lost_hotplug(src);
+   struct omap_connector *omap_connector = to_omap_connector(connector);
+   struct omap_dss_device *dssdev;
+
+   if (status != connector_status_disconnected)
+   return;
+
+   /*
+* Notify all devics in the pipeline of disconnection. This is required
+* to let the HDMI encoders reset their internal state related to
+* connection status, such as the CEC address.
+*/
+   for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) {
+   if (dssdev->ops && dssdev->ops->hdmi.lost_hotplug)
+   dssdev->ops->hdmi.lost_hotplug(dssdev);
}
 }
 
@@ -66,7 +70,7 @@ static void omap_connector_hpd_cb(void *cb_data,
if (old_status == status)
return;
 
-   omap_connector_hpd_notify(connector, omap_connector->hpd, status);
+   omap_connector_hpd_notify(connector, status);
 
drm_kms_helper_hotplug_event(dev);
 }
@@ -127,7 +131,7 @@ static enum drm_connector_status omap_connector_detect(
   ? connector_status_connected
   : connector_status_disconnected;
 
-   omap_connector_hpd_notify(connector, dssdev->src, status);
+   omap_connector_hpd_notify(connector, status);
} else {
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DPI:
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 18/49] drm/omap: Add a dss device operation flag for .get_modes()

2019-01-10 Thread Laurent Pinchart
Instead of manually iterating over the dss devices in the pipeline to
find the first one that implements the .get_modes() operation, add a new
operation flag for .get_modes() and use the omap_connector_find_device()
helper function to locate the right dss device.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  | 1 +
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 1 +
 .../gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c   | 1 +
 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c   | 1 +
 .../gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c| 1 +
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c   | 1 +
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c   | 1 +
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c   | 1 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 4 +++-
 drivers/gpu/drm/omapdrm/dss/venc.c| 1 +
 drivers/gpu/drm/omapdrm/omap_connector.c  | 8 
 11 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index d6a584292e91..897b8820e000 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -152,6 +152,7 @@ static int panel_dpi_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DPI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
drm_bus_flags_from_videomode(&ddata->vm, &dssdev->bus_flags);
 
omapdss_display_init(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index c5f570106a17..fe9d9f847d2e 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -1271,6 +1271,7 @@ static int dsicm_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DSI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
 
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c 
b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index e05b7f80416e..f37931bf1c5f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -199,6 +199,7 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
dssdev->type = OMAP_DISPLAY_TYPE_DPI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
 
/*
 * Note: According to the panel documentation:
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c 
b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index cf2127837e67..8f2fb3d0492f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -194,6 +194,7 @@ static int nec_8048_probe(struct spi_device *spi)
dssdev->type = OMAP_DISPLAY_TYPE_DPI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
  | DRM_BUS_FLAG_PIXDATA_POSEDGE;
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c 
b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index 30320cee1e56..8d5d7f775b55 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -209,6 +209,7 @@ static int sharp_ls_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DPI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
 
/*
 * Note: According to the panel documentation:
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 8debe77f92ff..b8360cef3754 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -708,6 +708,7 @@ static int acx565akm_probe(struct spi_device *spi)
dssdev->type = OMAP_DISPLAY_TYPE_SDI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_NEGEDGE
  | DRM_BUS_FLAG_PIXDATA_POSEDGE;
 
diff --git a/drivers/gpu/drm/omapdrm/displ

[PATCH v2 42/49] dt-bindings: Add vendor prefix for OSD Displays

2019-01-10 Thread Laurent Pinchart
OSD Displays is a panel manufacturer. It has been acquired by New Vision
Displays in 2015 but continues to operate under its own brand name.

Signed-off-by: Laurent Pinchart 
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 389508584f48..8b10a323a334 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -293,6 +293,7 @@ oranth  Shenzhen Oranth Technology Co., Ltd.
 ORCL   Oracle Corporation
 orisetech  Orise Technology
 ortustech  Ortus Technology Co., Ltd.
+osddisplaysOSD Displays
 ovti   OmniVision Technologies
 oxsemi Oxford Semiconductor, Ltd.
 panasonic  Panasonic Corporation
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 32/49] drm/omap: Simplify OF lookup of DSS devices

2019-01-10 Thread Laurent Pinchart
Now that the direction of OF graph walk has been reversed, there's no
need to lookup devices by port as we have no sink device connected
through multiple sink ports. Simplify OF lookup of the DSS devices to
look them up by node only.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c|  5 +--
 drivers/gpu/drm/omapdrm/dss/dss-of.c  | 60 ---
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 +-
 3 files changed, 10 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 62ccbeb99a84..d14abde3c5f0 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -112,13 +112,12 @@ void omapdss_device_put(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_device_put);
 
-struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
-   unsigned int port)
+struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node)
 {
struct omap_dss_device *dssdev;
 
list_for_each_entry(dssdev, &omapdss_devices_list, list) {
-   if (dssdev->dev->of_node == src && dssdev->of_ports & BIT(port))
+   if (dssdev->dev->of_node == node)
return omapdss_device_get(dssdev);
}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c 
b/drivers/gpu/drm/omapdrm/dss/dss-of.c
index 0422597ac6b0..b2094055c5fc 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss-of.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c
@@ -12,71 +12,25 @@
  * more details.
  */
 
-#include 
 #include 
-#include 
 #include 
 #include 
-#include 
 
 #include "omapdss.h"
 
-static struct device_node *
-dss_of_port_get_parent_device(struct device_node *port)
-{
-   struct device_node *np;
-   int i;
-
-   if (!port)
-   return NULL;
-
-   np = of_get_parent(port);
-
-   for (i = 0; i < 2 && np; ++i) {
-   struct property *prop;
-
-   prop = of_find_property(np, "compatible", NULL);
-
-   if (prop)
-   return np;
-
-   np = of_get_next_parent(np);
-   }
-
-   return NULL;
-}
-
 struct omap_dss_device *
 omapdss_of_find_connected_device(struct device_node *node, unsigned int port)
 {
-   struct device_node *src_node;
-   struct device_node *src_port;
-   struct device_node *ep;
-   struct omap_dss_device *src;
-   u32 port_number = 0;
+   struct device_node *remote_node;
+   struct omap_dss_device *dssdev;
 
-   /* Get the endpoint... */
-   ep = of_graph_get_endpoint_by_regs(node, port, 0);
-   if (!ep)
+   remote_node = of_graph_get_remote_node(node, port, 0);
+   if (!remote_node)
return NULL;
 
-   /* ... and its remote port... */
-   src_port = of_graph_get_remote_port(ep);
-   of_node_put(ep);
-   if (!src_port)
-   return NULL;
-
-   /* ... and the remote port's number and parent... */
-   of_property_read_u32(src_port, "reg", &port_number);
-   src_node = dss_of_port_get_parent_device(src_port);
-   of_node_put(src_port);
-   if (!src_node)
-   return ERR_PTR(-EINVAL);
-
-   /* ... and finally the connected device. */
-   src = omapdss_find_device_by_port(src_node, port_number);
-   of_node_put(src_node);
+   dssdev = omapdss_find_device_by_node(remote_node);
+   of_node_put(remote_node);
 
-   return src ? src : ERR_PTR(-EPROBE_DEFER);
+   return dssdev ? dssdev : ERR_PTR(-EPROBE_DEFER);
 }
 EXPORT_SYMBOL_GPL(omapdss_of_find_connected_device);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index a63b1d4b7a8a..d13a6b5774e8 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -474,8 +474,7 @@ void omapdss_device_register(struct omap_dss_device 
*dssdev);
 void omapdss_device_unregister(struct omap_dss_device *dssdev);
 struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
 void omapdss_device_put(struct omap_dss_device *dssdev);
-struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
-   unsigned int port);
+struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node);
 int omapdss_device_connect(struct dss_device *dss,
   struct omap_dss_device *src,
   struct omap_dss_device *dst);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 45/49] drm/omap: Add support for drm_bridge

2019-01-10 Thread Laurent Pinchart
Hook up drm_bridge support in the omapdrm driver. Despite the recent
extensive preparation work, this is a rather intrusive change, as the
management of outputs needs to be adapted through the driver to handle
both omap_dss_device and drm_bridge.

Connector creation is skipped when using a drm_bridge, as the bridge
creates the connector internally. This creates issues with systems that
split connector operations (such as modes retrieval and hot-plug
detection) across different bridges. These systems can't be supported
using drm_bridge for now (their support through the omap_dss_device
infrastructure is not affected), this will be fixed in subsequent
changes.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
Changes since v1:

- Fix typo in function name (updata -> update)
---
 drivers/gpu/drm/omapdrm/dss/base.c   | 27 --
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  1 +
 drivers/gpu/drm/omapdrm/dss/output.c | 21 +---
 drivers/gpu/drm/omapdrm/omap_connector.c | 16 --
 drivers/gpu/drm/omapdrm/omap_connector.h |  1 -
 drivers/gpu/drm/omapdrm/omap_crtc.c  |  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c   | 69 +---
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 69 ++--
 8 files changed, 145 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 81ea0f55cd75..09c9f2971aa2 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dss.h"
 #include "omapdss.h"
@@ -156,7 +157,7 @@ struct omap_dss_device *omapdss_device_next_output(struct 
omap_dss_device *from)
goto done;
}
 
-   if (dssdev->id && dssdev->next)
+   if (dssdev->id && (dssdev->next || dssdev->bridge))
goto done;
}
 
@@ -184,7 +185,18 @@ int omapdss_device_connect(struct dss_device *dss,
 {
int ret;
 
-   dev_dbg(dst->dev, "connect\n");
+   dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n",
+   src ? dev_name(src->dev) : "NULL",
+   dst ? dev_name(dst->dev) : "NULL");
+
+   if (!dst) {
+   /*
+* The destination is NULL when the source is connected to a
+* bridge instead of a DSS device. Stop here, we will attach the
+* bridge later when we will have a DRM encoder.
+*/
+   return src && src->bridge ? 0 : -EINVAL;
+   }
 
if (omapdss_device_is_connected(dst))
return -EBUSY;
@@ -204,7 +216,16 @@ EXPORT_SYMBOL_GPL(omapdss_device_connect);
 void omapdss_device_disconnect(struct omap_dss_device *src,
   struct omap_dss_device *dst)
 {
-   dev_dbg(dst->dev, "disconnect\n");
+   struct dss_device *dss = src ? src->dss : dst->dss;
+
+   dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n",
+   src ? dev_name(src->dev) : "NULL",
+   dst ? dev_name(dst->dev) : "NULL");
+
+   if (!dst) {
+   WARN_ON(!src->bridge);
+   return;
+   }
 
if (!dst->id && !omapdss_device_is_connected(dst)) {
WARN_ON(!dst->display);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index ab5467a1e92c..f47e9b94288f 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -410,6 +410,7 @@ struct omap_dss_device {
 
struct dss_device *dss;
struct omap_dss_device *next;
+   struct drm_bridge *bridge;
 
struct list_head list;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c 
b/drivers/gpu/drm/omapdrm/dss/output.c
index f25ecfd26534..2a53025c2fde 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -20,25 +20,34 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dss.h"
 #include "omapdss.h"
 
 int omapdss_device_init_output(struct omap_dss_device *out)
 {
-   out->next = omapdss_of_find_connected_device(out->dev->of_node, 0);
-   if (IS_ERR(out->next)) {
-   if (PTR_ERR(out->next) != -EPROBE_DEFER)
-   dev_err(out->dev, "failed to find video sink\n");
-   return PTR_ERR(out->next);
+   struct device_node *remote_node;
+
+   remote_node = of_graph_get_remote_node(out->dev->of_node, 0, 0);
+   if (!remote_node) {
+   dev_dbg(out->dev, "failed to find video sink\n");
+   return 0;
}
 
+   out->next = omapdss_find_device_by_node(remote_node);
+   out->bridge = of_drm_find_bridge(remote_node);
+
+   of_node_put(remote_node);
+
if (out->next && out->type != out->next->type) {
dev_err(out->dev, "output type and display type don't match\n");
+   omapdss_device_put(out->next);
+   

[PATCH v2 35/49] drm: Clarify definition of the DRM_BUS_FLAG_(PIXDATA|SYNC)_* macros

2019-01-10 Thread Laurent Pinchart
From: Laurent Pinchart 

The DRM_BUS_FLAG_PIXDATA_POSEDGE and DRM_BUS_FLAG_PIXDATA_NEGEDGE macros
and their DRM_BUS_FLAG_SYNC_* counterparts define on which pixel clock
edge data and sync signals are driven. They are however used in some
drivers to define on which pixel clock edge data and sync signals are
sampled, which should usually (but not always) be the opposite edge of
the driving edge. This creates confusion.

Create four new macros for both PIXDATA and SYNC that explicitly state
the driving and sampling edge in their name to remove the confusion. The
driving macros are defined as the opposite of the sampling macros to
made code simpler based on the assumption that the driving and sampling
edges are opposite.

Signed-off-by: Laurent Pinchart 
Acked-by: Linus Walleij 
---
Changes since v1:

- Address the DRM_BUS_FLAG_SYNC_* flags
- Rebase on top of drm-next
---
 include/drm/drm_connector.h | 36 
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 9be2181b3ed7..00bb7a74962b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -330,19 +330,47 @@ struct drm_display_info {
 
 #define DRM_BUS_FLAG_DE_LOW(1<<0)
 #define DRM_BUS_FLAG_DE_HIGH   (1<<1)
-/* drive data on pos. edge */
+
+/*
+ * Don't use those two flags directly, use the DRM_BUS_FLAG_PIXDATA_DRIVE_*
+ * and DRM_BUS_FLAG_PIXDATA_SAMPLE_* variants to qualify the flags explicitly.
+ * The DRM_BUS_FLAG_PIXDATA_SAMPLE_* flags are defined as the opposite of the
+ * DRM_BUS_FLAG_PIXDATA_DRIVE_* flags to make code simpler, as signals are
+ * usually to be sampled on the opposite edge of the driving edge.
+ */
 #define DRM_BUS_FLAG_PIXDATA_POSEDGE   (1<<2)
-/* drive data on neg. edge */
 #define DRM_BUS_FLAG_PIXDATA_NEGEDGE   (1<<3)
+
+/* Drive data on rising edge */
+#define DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE DRM_BUS_FLAG_PIXDATA_POSEDGE
+/* Drive data on falling edge */
+#define DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE DRM_BUS_FLAG_PIXDATA_NEGEDGE
+/* Sample data on rising edge */
+#define DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGEDRM_BUS_FLAG_PIXDATA_NEGEDGE
+/* Sample data on falling edge */
+#define DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGEDRM_BUS_FLAG_PIXDATA_POSEDGE
+
 /* data is transmitted MSB to LSB on the bus */
 #define DRM_BUS_FLAG_DATA_MSB_TO_LSB   (1<<4)
 /* data is transmitted LSB to MSB on the bus */
 #define DRM_BUS_FLAG_DATA_LSB_TO_MSB   (1<<5)
-/* drive sync on pos. edge */
+
+/*
+ * Similarly to the DRM_BUS_FLAG_PIXDATA_* flags, don't use these two flags
+ * directly, use one of the DRM_BUS_FLAG_SYNC_(DRIVE|SAMPLE)_* instead.
+ */
 #define DRM_BUS_FLAG_SYNC_POSEDGE  (1<<6)
-/* drive sync on neg. edge */
 #define DRM_BUS_FLAG_SYNC_NEGEDGE  (1<<7)
 
+/* Drive sync on rising edge */
+#define DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE
DRM_BUS_FLAG_SYNC_POSEDGE
+/* Drive sync on falling edge */
+#define DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE
DRM_BUS_FLAG_SYNC_NEGEDGE
+/* Sample sync on rising edge */
+#define DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE   DRM_BUS_FLAG_SYNC_NEGEDGE
+/* Sample sync on falling edge */
+#define DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE   DRM_BUS_FLAG_SYNC_POSEDGE
+
/**
 * @bus_flags: Additional information (like pixel signal polarity) for
 * the pixel data on the bus, using DRM_BUS_FLAGS\_ defines.
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 44/49] drm/panel: simple: Add OSD070T1718-19TS panel support

2019-01-10 Thread Laurent Pinchart
Add support for the OSD070T1718-19TS 7" 800x480 panel from One Stop
Displays to the panel-simple driver.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/panel/panel-simple.c | 29 
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 2657adf21a7f..9e6a4863e3c5 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2008,6 +2008,32 @@ static const struct panel_desc ortustech_com43h4m85ulc = 
{
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 };
 
+static const struct drm_display_mode osddisplays_osd070t1718_19ts_mode  = {
+   .clock = 33000,
+   .hdisplay = 800,
+   .hsync_start = 800 + 210,
+   .hsync_end = 800 + 210 + 30,
+   .htotal = 800 + 210 + 30 + 16,
+   .vdisplay = 480,
+   .vsync_start = 480 + 22,
+   .vsync_end = 480 + 22 + 13,
+   .vtotal = 480 + 22 + 13 + 10,
+   .vrefresh = 60,
+   .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc osddisplays_osd070t1718_19ts = {
+   .modes = &osddisplays_osd070t1718_19ts_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 152,
+   .height = 91,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
+};
+
 static const struct drm_display_mode qd43003c0_40_mode = {
.clock = 9000,
.hdisplay = 480,
@@ -2685,6 +2711,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "ortustech,com43h4m85ulc",
.data = &ortustech_com43h4m85ulc,
+   }, {
+   .compatible = "osddisplays,osd070t1718-19ts",
+   .data = &osddisplays_osd070t1718_19ts,
}, {
.compatible = "qiaodian,qd43003c0-40",
.data = &qd43003c0_40,
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 33/49] drm/omap: Refactor initialization sequence

2019-01-10 Thread Laurent Pinchart
The omapdrm driver initialization procedure starts by connecting all
available pipelines, gathering related information (such as output and
display DSS devices, and DT aliases), sorting them by alias, and finally
creates all the DRM/KMS objects.

When using DRM bridges instead of DSS devices, we will need to attach to
the bridges before getting the aliases. As attaching to bridges requires
an encoder object, we have to reorganize the initialization sequence to
create encoders before getting aliases and sorting the pipelines.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 123 +
 1 file changed, 56 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index afa736233076..6b91f44e5a60 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -150,48 +150,27 @@ static void omap_disconnect_pipelines(struct drm_device 
*ddev)
priv->num_pipes = 0;
 }
 
-static int omap_compare_pipes(const void *a, const void *b)
-{
-   const struct omap_drm_pipeline *pipe1 = a;
-   const struct omap_drm_pipeline *pipe2 = b;
-
-   if (pipe1->alias_id > pipe2->alias_id)
-   return 1;
-   else if (pipe1->alias_id < pipe2->alias_id)
-   return -1;
-   return 0;
-}
-
 static int omap_connect_pipelines(struct drm_device *ddev)
 {
struct omap_drm_private *priv = ddev->dev_private;
struct omap_dss_device *output = NULL;
-   unsigned int i;
int r;
 
-   if (!omapdss_stack_is_ready())
-   return -EPROBE_DEFER;
-
for_each_dss_output(output) {
r = omapdss_device_connect(priv->dss, NULL, output);
if (r == -EPROBE_DEFER) {
omapdss_device_put(output);
-   goto cleanup;
+   return r;
} else if (r) {
dev_warn(output->dev, "could not connect output %s\n",
 output->name);
} else {
struct omap_drm_pipeline *pipe;
-   int id;
 
pipe = &priv->pipes[priv->num_pipes++];
pipe->output = omapdss_device_get(output);
pipe->display = omapdss_display_get(output);
 
-   id = of_alias_get_id(pipe->display->dev->of_node,
-"display");
-   pipe->alias_id = id >= 0 ? id : priv->num_pipes - 1;
-
if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
/* To balance the 'for_each_dss_output' loop */
omapdss_device_put(output);
@@ -200,36 +179,19 @@ static int omap_connect_pipelines(struct drm_device *ddev)
}
}
 
-   /* Sort the list by DT aliases */
-   sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]),
-omap_compare_pipes, NULL);
-
-   /*
-* Populate the pipeline lookup table by DISPC channel. Only one display
-* is allowed per channel.
-*/
-   for (i = 0; i < priv->num_pipes; ++i) {
-   struct omap_drm_pipeline *pipe = &priv->pipes[i];
-   enum omap_channel channel = pipe->output->dispc_channel;
-
-   if (WARN_ON(priv->channels[channel] != NULL)) {
-   r = -EINVAL;
-   goto cleanup;
-   }
-
-   priv->channels[channel] = pipe;
-   }
-
return 0;
+}
 
-cleanup:
-   /*
-* if we are deferring probe, we disconnect the devices we previously
-* connected
-*/
-   omap_disconnect_pipelines(ddev);
+static int omap_compare_pipelines(const void *a, const void *b)
+{
+   const struct omap_drm_pipeline *pipe1 = a;
+   const struct omap_drm_pipeline *pipe2 = b;
 
-   return r;
+   if (pipe1->alias_id > pipe2->alias_id)
+   return 1;
+   else if (pipe1->alias_id < pipe2->alias_id)
+   return -1;
+   return 0;
 }
 
 static int omap_modeset_init_properties(struct drm_device *dev)
@@ -254,6 +216,9 @@ static int omap_modeset_init(struct drm_device *dev)
int ret;
u32 plane_crtc_mask;
 
+   if (!omapdss_stack_is_ready())
+   return -EPROBE_DEFER;
+
drm_mode_config_init(dev);
 
ret = omap_modeset_init_properties(dev);
@@ -268,6 +233,10 @@ static int omap_modeset_init(struct drm_device *dev)
 * configuration does not match the expectations or exceeds
 * the available resources, the configuration is rejected.
 */
+   ret = omap_connect_pipelines(dev);
+   if (ret < 0)
+   return ret;
+
if (priv->num_pipes > num_mgrs || priv->num_pipes > num_ovls) {
   

[PATCH v2 12/49] drm/omap: Remove enable checks from display .enable() and .remove()

2019-01-10 Thread Laurent Pinchart
The displays (connectors, panels and encoders) bail out from their
.enable() and .disable() handlers if the dss device is already enabled
or disabled. Those safety checks are not needed when the functions are
called through the omapdss_device_ops, as the .enable() and .disable()
handlers are called from the DRM atomic helpers that already guarantee
that no double enabling or disabling can occur.

However, the handlers are also called directly from the .remove()
handler. While this shouldn't be needed either as the modules can't be
removed as long as the device is in use, it's still a good practice to
disable the device explicitly. There is currently a safety check in
.remove() in some drivers but not all of them.

Remove the safety checks from the .enable() and .disable() handlers, and
add missing ones in the .remove() handler.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c|  6 ++
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c  |  6 ++
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c |  6 ++
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c |  6 --
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c |  6 --
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  |  6 ++
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 11 +--
 .../drm/omapdrm/displays/panel-lgphilips-lb035q02.c   |  6 ++
 .../gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c   |  6 ++
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c|  6 ++
 .../gpu/drm/omapdrm/displays/panel-sony-acx565akm.c   |  6 ++
 .../gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c   |  6 ++
 .../gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c   |  6 ++
 drivers/gpu/drm/omapdrm/omap_encoder.c|  6 --
 14 files changed, 25 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 910a5b9c036a..2b5b77627cfb 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -46,9 +46,6 @@ static void tvc_disable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *src = dssdev->src;
 
-   if (!omapdss_device_is_enabled(dssdev))
-   return;
-
src->ops->disable(src);
 }
 
@@ -92,7 +89,8 @@ static int __exit tvc_remove(struct platform_device *pdev)
 
omapdss_device_unregister(&ddata->dssdev);
 
-   tvc_disable(dssdev);
+   if (omapdss_device_is_enabled(dssdev))
+   tvc_disable(dssdev);
 
return 0;
 }
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 1e0925791c3d..a1784e263835 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -57,9 +57,6 @@ static void dvic_disable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *src = dssdev->src;
 
-   if (!omapdss_device_is_enabled(dssdev))
-   return;
-
src->ops->disable(src);
 }
 
@@ -282,7 +279,8 @@ static int __exit dvic_remove(struct platform_device *pdev)
 
omapdss_device_unregister(&ddata->dssdev);
 
-   dvic_disable(dssdev);
+   if (omapdss_device_is_enabled(dssdev))
+   dvic_disable(dssdev);
 
i2c_put_adapter(ddata->i2c_adapter);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 649364e04edd..05cd503c4d29 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -52,9 +52,6 @@ static void hdmic_disable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *src = dssdev->src;
 
-   if (!omapdss_device_is_enabled(dssdev))
-   return;
-
src->ops->disable(src);
 }
 
@@ -179,7 +176,8 @@ static int __exit hdmic_remove(struct platform_device *pdev)
 
omapdss_device_unregister(&ddata->dssdev);
 
-   hdmic_disable(dssdev);
+   if (omapdss_device_is_enabled(dssdev))
+   hdmic_disable(dssdev);
 
return 0;
 }
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 0b1032625e42..ce116c28479f 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -49,9 +49,6 @@ static int opa362_enable(struct omap_dss_device *dssdev)
 
dev_dbg(dssdev->dev, "enable\n");
 
-   if (omapdss_device_is_enabled(dssdev))
-   return 0;
-
r = src->ops->enable(src);
if (r)
return r;
@@ -71,9 +68,6 @@ static void opa362_disable(struct omap_dss_device *dssdev)
 
dev_dbg(dssdev->dev, "disable\n");
 
-   i

[PATCH v2 30/49] drm/omap: venc: Use drm_display_mode natively

2019-01-10 Thread Laurent Pinchart
Replace internal usage of struct videomode with struct drm_display_mode
in order to avoid converting needlessly between the data structures.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
Changes since v1:

- Set mode.crtc_* fields and mode name in venc_check_timings()
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 90 +++---
 1 file changed, 44 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 7bce5898654a..f2cbecfd05b5 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -267,38 +267,34 @@ enum venc_videomode {
VENC_MODE_NTSC,
 };
 
-static const struct videomode omap_dss_pal_vm = {
-   .hactive= 720,
-   .vactive= 574,
-   .pixelclock = 1350,
-   .hsync_len  = 64,
-   .hfront_porch   = 12,
-   .hback_porch= 68,
-   .vsync_len  = 5,
-   .vfront_porch   = 5,
-   .vback_porch= 41,
-
-   .flags  = DISPLAY_FLAGS_INTERLACED | DISPLAY_FLAGS_HSYNC_LOW |
- DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_DE_HIGH |
- DISPLAY_FLAGS_PIXDATA_POSEDGE |
- DISPLAY_FLAGS_SYNC_NEGEDGE,
+static const struct drm_display_mode omap_dss_pal_mode = {
+   .hdisplay   = 720,
+   .hsync_start= 732,
+   .hsync_end  = 796,
+   .htotal = 864,
+   .vdisplay   = 574,
+   .vsync_start= 579,
+   .vsync_end  = 584,
+   .vtotal = 625,
+   .clock  = 13500,
+
+   .flags  = DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_NHSYNC |
+ DRM_MODE_FLAG_NVSYNC,
 };
 
-static const struct videomode omap_dss_ntsc_vm = {
-   .hactive= 720,
-   .vactive= 482,
-   .pixelclock = 1350,
-   .hsync_len  = 64,
-   .hfront_porch   = 16,
-   .hback_porch= 58,
-   .vsync_len  = 6,
-   .vfront_porch   = 6,
-   .vback_porch= 31,
-
-   .flags  = DISPLAY_FLAGS_INTERLACED | DISPLAY_FLAGS_HSYNC_LOW |
- DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_DE_HIGH |
- DISPLAY_FLAGS_PIXDATA_POSEDGE |
- DISPLAY_FLAGS_SYNC_NEGEDGE,
+static const struct drm_display_mode omap_dss_ntsc_mode = {
+   .hdisplay   = 720,
+   .hsync_start= 736,
+   .hsync_end  = 800,
+   .htotal = 858,
+   .vdisplay   = 482,
+   .vsync_start= 488,
+   .vsync_end  = 494,
+   .vtotal = 525,
+   .clock  = 13500,
+
+   .flags  = DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_NHSYNC |
+ DRM_MODE_FLAG_NVSYNC,
 };
 
 struct venc_device {
@@ -521,21 +517,19 @@ static void venc_display_disable(struct omap_dss_device 
*dssdev)
 static int venc_get_modes(struct omap_dss_device *dssdev,
  struct drm_connector *connector)
 {
-   static const struct videomode *modes[] = {
-   &omap_dss_pal_vm,
-   &omap_dss_ntsc_vm,
+   static const struct drm_display_mode *modes[] = {
+   &omap_dss_pal_mode,
+   &omap_dss_ntsc_mode,
};
unsigned int i;
 
for (i = 0; i < ARRAY_SIZE(modes); ++i) {
struct drm_display_mode *mode;
 
-   mode = drm_mode_create(connector->dev);
+   mode = drm_mode_duplicate(connector->dev, modes[i]);
if (!mode)
return i;
 
-   drm_display_mode_from_videomode(modes[i], mode);
-
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
@@ -549,14 +543,14 @@ static enum venc_videomode venc_get_videomode(const 
struct drm_display_mode *mod
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
return VENC_MODE_UNKNOWN;
 
-   if (mode->clock == omap_dss_pal_vm.pixelclock / 1000 &&
-   mode->hdisplay == omap_dss_pal_vm.hactive &&
-   mode->vdisplay == omap_dss_pal_vm.vactive)
+   if (mode->clock == omap_dss_pal_mode.clock &&
+   mode->hdisplay == omap_dss_pal_mode.hdisplay &&
+   mode->vdisplay == omap_dss_pal_mode.vdisplay)
return VENC_MODE_PAL;
 
-   if (mode->clock == omap_dss_ntsc_vm.pixelclock / 1000 &&
-   mode->hdisplay == omap_dss_ntsc_vm.hactive &&
-   mode->vdisplay == omap_dss_ntsc_vm.vactive)
+   if (mode->clock == omap_dss_ntsc_mode.clock &&
+   mode->hdisplay == omap_dss_ntsc_mode.hdisplay &&
+   mode->vdisplay == omap_dss_ntsc_mode.vdisplay)
return VENC_MODE_NTSC;
 
return VENC_MODE_UNKNOWN;
@@ -597,16 +591,20 @@ static int venc_check_timings(struct omap_

[PATCH v2 27/49] drm/omap: venc: Simplify mode setting by caching configuration

2019-01-10 Thread Laurent Pinchart
The mode setting handler of the VENC stores the video mode internally,
to then convert it to a configuration when programming the hardware. The
stored mode is otherwise unused. Cache the configuration directly
instead.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 68 +++---
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 638cfd69ccf6..6cb708e1944e 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -301,24 +301,6 @@ static const struct videomode omap_dss_ntsc_vm = {
  DISPLAY_FLAGS_SYNC_NEGEDGE,
 };
 
-static enum venc_videomode venc_get_videomode(const struct videomode *vm)
-{
-   if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
-   return VENC_MODE_UNKNOWN;
-
-   if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
-   vm->hactive == omap_dss_pal_vm.hactive &&
-   vm->vactive == omap_dss_pal_vm.vactive)
-   return VENC_MODE_PAL;
-
-   if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
-   vm->hactive == omap_dss_ntsc_vm.hactive &&
-   vm->vactive == omap_dss_ntsc_vm.vactive)
-   return VENC_MODE_NTSC;
-
-   return VENC_MODE_UNKNOWN;
-}
-
 struct venc_device {
struct platform_device *pdev;
void __iomem *base;
@@ -330,7 +312,7 @@ struct venc_device {
 
struct clk  *tv_dac_clk;
 
-   struct videomode vm;
+   const struct venc_config *config;
enum omap_dss_venc_type type;
bool invert_polarity;
bool requires_tv_dac_clk;
@@ -450,18 +432,6 @@ static void venc_runtime_put(struct venc_device *venc)
WARN_ON(r < 0 && r != -ENOSYS);
 }
 
-static const struct venc_config *venc_timings_to_config(const struct videomode 
*vm)
-{
-   switch (venc_get_videomode(vm)) {
-   default:
-   WARN_ON_ONCE(1);
-   case VENC_MODE_PAL:
-   return &venc_config_pal_trm;
-   case VENC_MODE_NTSC:
-   return &venc_config_ntsc_trm;
-   }
-}
-
 static int venc_power_on(struct venc_device *venc)
 {
u32 l;
@@ -472,7 +442,7 @@ static int venc_power_on(struct venc_device *venc)
goto err0;
 
venc_reset(venc);
-   venc_write_config(venc, venc_timings_to_config(&venc->vm));
+   venc_write_config(venc, venc->config);
 
dss_set_venc_output(venc->dss, venc->type);
dss_set_dac_pwrdn_bgz(venc->dss, 1);
@@ -574,16 +544,46 @@ static int venc_get_modes(struct omap_dss_device *dssdev,
return ARRAY_SIZE(modes);
 }
 
+static enum venc_videomode venc_get_videomode(const struct videomode *vm)
+{
+   if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
+   return VENC_MODE_UNKNOWN;
+
+   if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
+   vm->hactive == omap_dss_pal_vm.hactive &&
+   vm->vactive == omap_dss_pal_vm.vactive)
+   return VENC_MODE_PAL;
+
+   if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
+   vm->hactive == omap_dss_ntsc_vm.hactive &&
+   vm->vactive == omap_dss_ntsc_vm.vactive)
+   return VENC_MODE_NTSC;
+
+   return VENC_MODE_UNKNOWN;
+}
+
 static void venc_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
struct venc_device *venc = dssdev_to_venc(dssdev);
+   enum venc_videomode venc_mode = venc_get_videomode(vm);
 
DSSDBG("venc_set_timings\n");
 
mutex_lock(&venc->venc_lock);
 
-   venc->vm = *vm;
+   switch (venc_mode) {
+   default:
+   WARN_ON_ONCE(1);
+   /* Fall-through */
+   case VENC_MODE_PAL:
+   venc->config = &venc_config_pal_trm;
+   break;
+
+   case VENC_MODE_NTSC:
+   venc->config = &venc_config_ntsc_trm;
+   break;
+   }
 
dispc_set_tv_pclk(venc->dss->dispc, 1350);
 
@@ -854,7 +854,7 @@ static int venc_probe(struct platform_device *pdev)
 
mutex_init(&venc->venc_lock);
 
-   venc->vm = omap_dss_pal_vm;
+   venc->config = &venc_config_pal_trm;
 
venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0);
venc->base = devm_ioremap_resource(&pdev->dev, venc_mem);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 49/49] drm/omap: Remove panel-dpi driver

2019-01-10 Thread Laurent Pinchart
Panels are now supported through the drm_panel infrastructure, remove
the omapdrm-specific driver.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/Kconfig  |   6 -
 drivers/gpu/drm/omapdrm/displays/Makefile |   1 -
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  | 199 --
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   1 -
 4 files changed, 207 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-dpi.c

diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig 
b/drivers/gpu/drm/omapdrm/displays/Kconfig
index 38d066ac966e..7b0bcb494b5c 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -22,12 +22,6 @@ config DRM_OMAP_CONNECTOR_ANALOG_TV
help
  Driver for a generic analog TV connector.
 
-config DRM_OMAP_PANEL_DPI
-   tristate "Generic DPI panel"
-   depends on BACKLIGHT_CLASS_DEVICE
-   help
- Driver for generic DPI panels.
-
 config DRM_OMAP_PANEL_DSI_CM
tristate "Generic DSI Command Mode Panel"
depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile 
b/drivers/gpu/drm/omapdrm/displays/Makefile
index da1d5321ef50..1db34d4fed64 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_DRM_OMAP_ENCODER_OPA362) += encoder-opa362.o
 obj-$(CONFIG_DRM_OMAP_ENCODER_TPD12S015) += encoder-tpd12s015.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_HDMI) += connector-hdmi.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
-obj-$(CONFIG_DRM_OMAP_PANEL_DPI) += panel-dpi.o
 obj-$(CONFIG_DRM_OMAP_PANEL_DSI_CM) += panel-dsi-cm.o
 obj-$(CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
deleted file mode 100644
index 389ae2821222..
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Generic MIPI DPI Panel Driver
- *
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Tomi Valkeinen 
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-#include "../dss/omapdss.h"
-
-struct panel_drv_data {
-   struct omap_dss_device dssdev;
-
-   struct videomode vm;
-
-   struct backlight_device *backlight;
-
-   struct gpio_desc *enable_gpio;
-   struct regulator *vcc_supply;
-};
-
-#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
-
-static int panel_dpi_connect(struct omap_dss_device *src,
-struct omap_dss_device *dst)
-{
-   return 0;
-}
-
-static void panel_dpi_disconnect(struct omap_dss_device *src,
-struct omap_dss_device *dst)
-{
-}
-
-static void panel_dpi_enable(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-   int r;
-
-   r = regulator_enable(ddata->vcc_supply);
-   if (r)
-   return;
-
-   gpiod_set_value_cansleep(ddata->enable_gpio, 1);
-   backlight_enable(ddata->backlight);
-}
-
-static void panel_dpi_disable(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   backlight_disable(ddata->backlight);
-
-   gpiod_set_value_cansleep(ddata->enable_gpio, 0);
-   regulator_disable(ddata->vcc_supply);
-}
-
-static int panel_dpi_get_modes(struct omap_dss_device *dssdev,
-  struct drm_connector *connector)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   return omapdss_display_get_modes(connector, &ddata->vm);
-}
-
-static const struct omap_dss_device_ops panel_dpi_ops = {
-   .connect= panel_dpi_connect,
-   .disconnect = panel_dpi_disconnect,
-
-   .enable = panel_dpi_enable,
-   .disable= panel_dpi_disable,
-
-   .get_modes  = panel_dpi_get_modes,
-};
-
-static int panel_dpi_probe_of(struct platform_device *pdev)
-{
-   struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct device_node *node = pdev->dev.of_node;
-   int r;
-   struct display_timing timing;
-   struct gpio_desc *gpio;
-
-   gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW);
-   if (IS_ERR(gpio))
-   return PTR_ERR(gpio);
-
-   ddata->enable_gpio = gpio;
-
-   /*
-* Many different panels are supported by this driver and there are
-* probably very different needs for their reset pins in regards to
-

[PATCH v2 31/49] drm/omap: Store pixel clock instead of full mode in DPI and SDI encoders

2019-01-10 Thread Laurent Pinchart
The DPI and SDI encoders store the full videomode upon mode set, to only
use the value of the pixel clock when enabling the encoder. This wastes
memory. Store the pixel clock value only.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 9 -
 drivers/gpu/drm/omapdrm/dss/sdi.c | 6 +++---
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 0cb3cb72f15f..295bc3eeea80 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -47,8 +47,8 @@ struct dpi_data {
 
struct mutex lock;
 
-   struct videomode vm;
struct dss_lcd_mgr_config mgr_config;
+   unsigned long pixelclock;
int data_lines;
 
struct omap_dss_device output;
@@ -347,16 +347,15 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, 
unsigned long pck_req,
 
 static int dpi_set_mode(struct dpi_data *dpi)
 {
-   const struct videomode *vm = &dpi->vm;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
int r = 0;
 
if (dpi->pll)
r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
-   vm->pixelclock, &fck, &lck_div, &pck_div);
+   dpi->pixelclock, &fck, &lck_div, &pck_div);
else
-   r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck,
+   r = dpi_set_dispc_clk(dpi, dpi->pixelclock, &fck,
&lck_div, &pck_div);
if (r)
return r;
@@ -467,7 +466,7 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
 
mutex_lock(&dpi->lock);
 
-   drm_display_mode_to_videomode(mode, &dpi->vm);
+   dpi->pixelclock = mode->clock * 1000;
 
mutex_unlock(&dpi->lock);
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index f096a7f77e5f..38b0bf19538d 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -37,7 +37,7 @@ struct sdi_device {
struct regulator *vdds_sdi_reg;
 
struct dss_lcd_mgr_config mgr_config;
-   struct videomode vm;
+   unsigned long pixelclock;
int datapairs;
 
struct omap_dss_device output;
@@ -144,7 +144,7 @@ static void sdi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = sdi_calc_clock_div(sdi, sdi->vm.pixelclock, &fck, &dispc_cinfo);
+   r = sdi_calc_clock_div(sdi, sdi->pixelclock, &fck, &dispc_cinfo);
if (r)
goto err_calc_clock_div;
 
@@ -210,7 +210,7 @@ static void sdi_set_timings(struct omap_dss_device *dssdev,
 {
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
 
-   drm_display_mode_to_videomode(mode, &sdi->vm);
+   sdi->pixelclock = mode->clock * 1000;
 }
 
 static int sdi_check_timings(struct omap_dss_device *dssdev,
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 16/49] drm/omap: Expose DRM modes instead of timings in display devices

2019-01-10 Thread Laurent Pinchart
omap_dss_device operations expose fixed video timings through a
.get_timings() operation that return a single timing for the device. To
prepare for the move to drm_bridge, modify the API to instead add DRM
modes directly to the connector.

As this puts more burden on display devices, we also create a helper
function for panels to add a single DRM mode from the panel video
timings.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  |  8 ++---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 10 +++---
 .../displays/panel-lgphilips-lb035q02.c   |  8 ++---
 .../omapdrm/displays/panel-nec-nl8048hl11.c   |  8 ++---
 .../displays/panel-sharp-ls037v7dw01.c|  8 ++---
 .../omapdrm/displays/panel-sony-acx565akm.c   |  8 ++---
 .../omapdrm/displays/panel-tpo-td028ttec1.c   |  8 ++---
 .../omapdrm/displays/panel-tpo-td043mtea1.c   |  8 ++---
 drivers/gpu/drm/omapdrm/dss/display.c | 22 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  8 +++--
 drivers/gpu/drm/omapdrm/dss/venc.c| 12 ---
 drivers/gpu/drm/omapdrm/omap_connector.c  | 33 ++-
 12 files changed, 80 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index eee44d9ea0c3..d6a584292e91 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -68,12 +68,12 @@ static void panel_dpi_disable(struct omap_dss_device 
*dssdev)
regulator_disable(ddata->vcc_supply);
 }
 
-static void panel_dpi_get_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
+static int panel_dpi_get_modes(struct omap_dss_device *dssdev,
+  struct drm_connector *connector)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   *vm = ddata->vm;
+   return omapdss_display_get_modes(connector, &ddata->vm);
 }
 
 static const struct omap_dss_device_ops panel_dpi_ops = {
@@ -83,7 +83,7 @@ static const struct omap_dss_device_ops panel_dpi_ops = {
.enable = panel_dpi_enable,
.disable= panel_dpi_disable,
 
-   .get_timings= panel_dpi_get_timings,
+   .get_modes  = panel_dpi_get_modes,
 };
 
 static int panel_dpi_probe_of(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index ffbf20e6ebe9..9cd9ab487a24 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 
+#include 
+
 #include 
 #include 
 
@@ -1110,12 +1112,12 @@ static void dsicm_ulps_work(struct work_struct *work)
mutex_unlock(&ddata->lock);
 }
 
-static void dsicm_get_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
+static int dsicm_get_modes(struct omap_dss_device *dssdev,
+  struct drm_connector *connector)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   *vm = ddata->vm;
+   return omapdss_display_get_modes(connector, &ddata->vm);
 }
 
 static int dsicm_check_timings(struct omap_dss_device *dssdev,
@@ -1156,7 +1158,7 @@ static const struct omap_dss_device_ops dsicm_ops = {
.enable = dsicm_enable,
.disable= dsicm_disable,
 
-   .get_timings= dsicm_get_timings,
+   .get_modes  = dsicm_get_modes,
.check_timings  = dsicm_check_timings,
 };
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c 
b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index e043cab0a0c9..e05b7f80416e 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -139,12 +139,12 @@ static void lb035q02_disable(struct omap_dss_device 
*dssdev)
gpiod_set_value_cansleep(ddata->enable_gpio, 0);
 }
 
-static void lb035q02_get_timings(struct omap_dss_device *dssdev,
-struct videomode *vm)
+static int lb035q02_get_modes(struct omap_dss_device *dssdev,
+ struct drm_connector *connector)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   *vm = ddata->vm;
+   return omapdss_display_get_modes(connector, &ddata->vm);
 }
 
 static const struct omap_dss_device_ops lb035q02_ops = {
@@ -154,7 +154,7 @@ static const struct omap_dss_device_ops lb035q02_ops = {
.enable = lb035q02_enable,
.disable= lb035q02_disable,
 
-   .get_timings= lb035q02_get_timings,
+   .get_modes  = lb035q02_get_modes,
 };
 
 static int lb035q02_probe_of(struct spi_device *spi)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c 
b/drivers/gpu/drm/

[PATCH v2 47/49] drm/omap: Whitelist DT nodes to fixup with omapdss, prefix

2019-01-10 Thread Laurent Pinchart
The omapdss driver patches DT at runtime to prepend an "omapdss," prefix
to the compatible string of all encoders, panels and connectors. This
mechanism ensures they get bound to the omapdss-specific drivers instead
of generic drivers.

Now that we have drm_bridge support in omapdrm, we need to selectively
disable this mechanism. Add a whitelist of compatible strings to patch,
and fill it with all the devices we support. They will be removed one by
one once corresponding drm_bridge drivers become available and get
successfully tested with omapdrm.

The omapdss components load check code is updated accordingly to ignore
devices managed by external bridge drivers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 20 +++---
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   | 21 ++-
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 3c088cd2ceab..f8dad99013e8 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -303,6 +303,7 @@ struct omapdss_comp_node {
struct list_head list;
struct device_node *node;
bool dss_core_component;
+   const char *compat;
 };
 
 static bool omapdss_list_contains(const struct device_node *node)
@@ -320,13 +321,20 @@ static bool omapdss_list_contains(const struct 
device_node *node)
 static void omapdss_walk_device(struct device *dev, struct device_node *node,
bool dss_core)
 {
+   struct omapdss_comp_node *comp;
struct device_node *n;
-   struct omapdss_comp_node *comp = devm_kzalloc(dev, sizeof(*comp),
- GFP_KERNEL);
+   const char *compat;
+   int ret;
+
+   ret = of_property_read_string(node, "compatible", &compat);
+   if (ret < 0)
+   return;
 
+   comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
if (comp) {
comp->node = node;
comp->dss_core_component = dss_core;
+   comp->compat = compat;
list_add(&comp->list, &omapdss_comp_list);
}
 
@@ -366,12 +374,8 @@ void omapdss_gather_components(struct device *dev)
 
omapdss_walk_device(dev, dev->of_node, true);
 
-   for_each_available_child_of_node(dev->of_node, child) {
-   if (!of_find_property(child, "compatible", NULL))
-   continue;
-
+   for_each_available_child_of_node(dev->of_node, child)
omapdss_walk_device(dev, child, true);
-   }
 }
 EXPORT_SYMBOL(omapdss_gather_components);
 
@@ -379,6 +383,8 @@ static bool omapdss_component_is_loaded(struct 
omapdss_comp_node *comp)
 {
if (comp->dss_core_component)
return true;
+   if (!strstarts(comp->compat, "omapdss,"))
+   return true;
if (omapdss_device_is_registered(comp->node))
return true;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c 
b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
index 3bfb95d230e0..309b7b453e98 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
@@ -184,6 +184,25 @@ static const struct of_device_id omapdss_of_match[] 
__initconst = {
{},
 };
 
+static const struct of_device_id omapdss_of_fixups_whitelist[] __initconst = {
+   { .compatible = "composite-video-connector" },
+   { .compatible = "dvi-connector" },
+   { .compatible = "hdmi-connector" },
+   { .compatible = "lgphilips,lb035q02" },
+   { .compatible = "nec,nl8048hl11" },
+   { .compatible = "panel-dpi" },
+   { .compatible = "panel-dsi-cm" },
+   { .compatible = "sharp,ls037v7dw01" },
+   { .compatible = "sony,acx565akm" },
+   { .compatible = "svideo-connector" },
+   { .compatible = "ti,opa362" },
+   { .compatible = "ti,tfp410" },
+   { .compatible = "ti,tpd12s015" },
+   { .compatible = "toppoly,td028ttec1" },
+   { .compatible = "tpo,td028ttec1" },
+   { .compatible = "tpo,td043mtea1" },
+};
+
 static int __init omapdss_boot_init(void)
 {
struct device_node *dss, *child;
@@ -210,7 +229,7 @@ static int __init omapdss_boot_init(void)
n = list_first_entry(&dss_conv_list, struct dss_conv_node,
list);
 
-   if (!n->root)
+   if (of_match_node(omapdss_of_fixups_whitelist, n->node))
omapdss_omapify_node(n->node);
 
list_del(&n->list);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 46/49] drm/omap: Add support for drm_panel

2019-01-10 Thread Laurent Pinchart
Hook up drm_panel support in the omapdrm driver. The change is
relatively simply as the way has been paved by drm_bridge support
already. In addition to looking up, attaching to and detaching from the
panel, we only need to add panel support in the connector .get_modes()
handler, take connector bus flags (set by the panel) into account, and
enable/disable the panel in the encoder enable/disable operations
handlers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c   | 12 ---
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  1 +
 drivers/gpu/drm/omapdrm/dss/output.c |  7 +++-
 drivers/gpu/drm/omapdrm/omap_connector.c |  9 ++
 drivers/gpu/drm/omapdrm/omap_drv.c   | 15 -
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 41 
 6 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 09c9f2971aa2..3c088cd2ceab 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -157,7 +157,8 @@ struct omap_dss_device *omapdss_device_next_output(struct 
omap_dss_device *from)
goto done;
}
 
-   if (dssdev->id && (dssdev->next || dssdev->bridge))
+   if (dssdev->id &&
+   (dssdev->next || dssdev->bridge || dssdev->panel))
goto done;
}
 
@@ -192,10 +193,11 @@ int omapdss_device_connect(struct dss_device *dss,
if (!dst) {
/*
 * The destination is NULL when the source is connected to a
-* bridge instead of a DSS device. Stop here, we will attach the
-* bridge later when we will have a DRM encoder.
+* bridge or panel instead of a DSS device. Stop here, we will
+* attach the bridge or panel later when we will have a DRM
+* encoder.
 */
-   return src && src->bridge ? 0 : -EINVAL;
+   return src && (src->bridge || src->panel) ? 0 : -EINVAL;
}
 
if (omapdss_device_is_connected(dst))
@@ -223,7 +225,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
dst ? dev_name(dst->dev) : "NULL");
 
if (!dst) {
-   WARN_ON(!src->bridge);
+   WARN_ON(!src->bridge && !src->panel);
return;
}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index f47e9b94288f..0c734d1f89e1 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -411,6 +411,7 @@ struct omap_dss_device {
struct dss_device *dss;
struct omap_dss_device *next;
struct drm_bridge *bridge;
+   struct drm_panel *panel;
 
struct list_head list;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c 
b/drivers/gpu/drm/omapdrm/dss/output.c
index 2a53025c2fde..10a9ee5cdc61 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -22,6 +22,8 @@
 #include 
 #include 
 
+#include 
+
 #include "dss.h"
 #include "omapdss.h"
 
@@ -37,6 +39,9 @@ int omapdss_device_init_output(struct omap_dss_device *out)
 
out->next = omapdss_find_device_by_node(remote_node);
out->bridge = of_drm_find_bridge(remote_node);
+   out->panel = of_drm_find_panel(remote_node);
+   if (IS_ERR(out->panel))
+   out->panel = NULL;
 
of_node_put(remote_node);
 
@@ -47,7 +52,7 @@ int omapdss_device_init_output(struct omap_dss_device *out)
return -EINVAL;
}
 
-   return out->next || out->bridge ? 0 : -EPROBE_DEFER;
+   return out->next || out->bridge || out->panel ? 0 : -EPROBE_DEFER;
 }
 EXPORT_SYMBOL(omapdss_device_init_output);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index f528baa80114..2da16f00cfae 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "omap_drv.h"
 
@@ -211,6 +212,7 @@ static int omap_connector_get_modes_edid(struct 
drm_connector *connector,
 
 static int omap_connector_get_modes(struct drm_connector *connector)
 {
+   struct omap_connector *omap_connector = to_omap_connector(connector);
struct omap_dss_device *dssdev;
 
DBG("%s", connector->name);
@@ -233,6 +235,13 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
if (dssdev)
return dssdev->ops->get_modes(dssdev, connector);
 
+   /*
+* Otherwise if the display pipeline uses a drm_panel, we delegate the
+* operation to the panel API.
+*/
+   if (omap_connector->output->panel)
+   return drm_panel_get_modes(omap_connector->output->panel);
+
/*
 * We

[PATCH v2 34/49] drm/omap: Merge omap_dss_device type and output_type fields

2019-01-10 Thread Laurent Pinchart
The omap_dss_device type and output_type fields differ mostly for
historical reasons. The output_type field is required for all devices
but the display at the end of the pipeline, and must be set to
OMAP_DISPLAY_TYPE_NONE for the latter. The type field is required for
all devices but the internal encoder, for which it is ignored.

The only reason why the output_type field must be set to
OMAP_DISPLAY_TYPE_NONE for the display at the end of the pipeline is to
identify omap_dss_device instances corresponding to displays. This is
not documented and confusing.

Clean the code by adding a new display field to the omap_dss_device
structure to identify displays, and merge the type and output_type
fields.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |  1 +
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  1 +
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  1 +
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c  |  1 -
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c  |  1 -
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  1 -
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c   |  1 +
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c|  1 +
 .../omapdrm/displays/panel-lgphilips-lb035q02.c|  1 +
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|  1 +
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c |  1 +
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|  1 +
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c|  1 +
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c|  1 +
 drivers/gpu/drm/omapdrm/dss/base.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/dpi.c  |  2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c  |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c|  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c|  2 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h  | 14 +-
 drivers/gpu/drm/omapdrm/dss/output.c   |  2 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c  |  2 +-
 drivers/gpu/drm/omapdrm/dss/venc.c |  2 +-
 drivers/gpu/drm/omapdrm/omap_crtc.c|  2 +-
 drivers/gpu/drm/omapdrm/omap_encoder.c |  6 +++---
 25 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 1503563117f3..6c0561101874 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -56,6 +56,7 @@ static int tvc_probe(struct platform_device *pdev)
dssdev->ops = &tvc_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_VENC;
+   dssdev->display = true;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index bf5ee50ce5fe..fa3a69bf8a04 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -239,6 +239,7 @@ static int dvic_probe(struct platform_device *pdev)
dssdev->ops = &dvic_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_DVI;
+   dssdev->display = true;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 797da4a3f22e..68d6f6e44b03 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -140,6 +140,7 @@ static int hdmic_probe(struct platform_device *pdev)
dssdev->ops = &hdmic_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
+   dssdev->display = true;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
dssdev->ops_flags = ddata->hpd_gpio
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index fc5e0c47054d..29a5a130ebd1 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -88,7 +88,6 @@ static int opa362_probe(struct platform_device *pdev)
dssdev->ops = &opa362_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_VENC;
-   dssdev->output_type = OMAP_DISPLAY_TYPE_VENC;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(1) | BIT(0);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 82035078377a..fb88537de1cc 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -84,7 +84,6 @@ static int tfp410_probe

[PATCH v2 28/49] drm/omap: Factor out common mode validation code

2019-01-10 Thread Laurent Pinchart
The encoder .atomic_check() and connector .mode_valid() operations both
walk through the dss devices in the pipeline to validate the mode.
Factor out the common code in a new omap_drm_connector_mode_fixup()
function.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
Changes since v1:

- Remove unneeded NULL check for adjusted_mode in
  omap_connector_mode_fixup()
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 54 +---
 drivers/gpu/drm/omapdrm/omap_connector.h |  5 +++
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 30 -
 3 files changed, 44 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index dd1e0f2e8ffc..b6433c55419e 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -241,50 +241,56 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
return 0;
 }
 
-static int omap_connector_mode_valid(struct drm_connector *connector,
-struct drm_display_mode *mode)
+enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev,
+   const struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode)
 {
-   struct omap_connector *omap_connector = to_omap_connector(connector);
-   struct omap_dss_device *dssdev;
-   struct videomode vm = {0};
-   struct drm_device *dev = connector->dev;
-   struct drm_display_mode *new_mode;
-   int r, ret = MODE_BAD;
+   struct videomode vm = { 0 };
+   int ret;
 
drm_display_mode_to_videomode(mode, &vm);
-   mode->vrefresh = drm_mode_vrefresh(mode);
 
-   for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) {
+   for (; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings)
continue;
 
-   r = dssdev->ops->check_timings(dssdev, &vm);
-   if (r)
-   goto done;
+   ret = dssdev->ops->check_timings(dssdev, &vm);
+   if (ret)
+   return MODE_BAD;
}
 
-   /* check if vrefresh is still valid */
-   new_mode = drm_mode_duplicate(dev, mode);
-   if (!new_mode)
-   return MODE_BAD;
+   drm_display_mode_from_videomode(&vm, adjusted_mode);
 
-   new_mode->clock = vm.pixelclock / 1000;
-   new_mode->vrefresh = 0;
-   if (mode->vrefresh == drm_mode_vrefresh(new_mode))
-   ret = MODE_OK;
-   drm_mode_destroy(dev, new_mode);
+   return MODE_OK;
+}
+
+static enum drm_mode_status omap_connector_mode_valid(struct drm_connector 
*connector,
+struct drm_display_mode *mode)
+{
+   struct omap_connector *omap_connector = to_omap_connector(connector);
+   struct drm_display_mode new_mode = { { 0 } };
+   enum drm_mode_status status;
+
+   status = omap_connector_mode_fixup(omap_connector->output, mode,
+  &new_mode);
+   if (status != MODE_OK)
+   goto done;
+
+   /* Check if vrefresh is still valid. */
+   if (drm_mode_vrefresh(mode) != drm_mode_vrefresh(&new_mode))
+   status = MODE_NOCLOCK;
 
 done:
DBG("connector: mode %s: "
"%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
-   (ret == MODE_OK) ? "valid" : "invalid",
+   (status == MODE_OK) ? "valid" : "invalid",
mode->base.id, mode->name, mode->vrefresh, mode->clock,
mode->hdisplay, mode->hsync_start,
mode->hsync_end, mode->htotal,
mode->vdisplay, mode->vsync_start,
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
 
-   return ret;
+   return status;
 }
 
 static const struct drm_connector_funcs omap_connector_funcs = {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h 
b/drivers/gpu/drm/omapdrm/omap_connector.h
index 4a1dcd0f031b..6b7d4d95e32b 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.h
+++ b/drivers/gpu/drm/omapdrm/omap_connector.h
@@ -22,6 +22,8 @@
 
 #include 
 
+enum drm_mode_status;
+
 struct drm_connector;
 struct drm_device;
 struct drm_encoder;
@@ -34,5 +36,8 @@ struct drm_connector *omap_connector_init(struct drm_device 
*dev,
 bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
 void omap_connector_enable_hpd(struct drm_connector *connector);
 void omap_connector_disable_hpd(struct drm_connector *connector);
+enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev,
+   const struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode);
 
 #en

[PATCH v2 09/49] drm/omap: Move common display enable/disable code to encoder

2019-01-10 Thread Laurent Pinchart
All .enable() and .disable() handlers for panels and connectors share
common code that validates and updates the device's state. Move it to
common locations in the omap_encoder_enable() and omap_encoder_disable()
handlers.

The enabled check in the .disable() handler is left untouched, it will
be addressed separately.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 .../omapdrm/displays/connector-analog-tv.c| 23 +-
 .../gpu/drm/omapdrm/displays/connector-dvi.c  | 17 +--
 .../gpu/drm/omapdrm/displays/connector-hdmi.c | 23 +-
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  | 10 ---
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 18 ---
 .../displays/panel-lgphilips-lb035q02.c   | 10 ---
 .../omapdrm/displays/panel-nec-nl8048hl11.c   | 10 ---
 .../displays/panel-sharp-ls037v7dw01.c| 10 ---
 .../omapdrm/displays/panel-sony-acx565akm.c   | 18 +--
 .../omapdrm/displays/panel-tpo-td028ttec1.c   | 14 +
 .../omapdrm/displays/panel-tpo-td043mtea1.c   | 10 ---
 drivers/gpu/drm/omapdrm/omap_encoder.c| 30 +--
 12 files changed, 32 insertions(+), 161 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 28a3ce8f88d2..910a5b9c036a 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -37,40 +37,19 @@ static void tvc_disconnect(struct omap_dss_device *src,
 
 static int tvc_enable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
-   int r;
 
-   dev_dbg(ddata->dev, "enable\n");
-
-   if (!omapdss_device_is_connected(dssdev))
-   return -ENODEV;
-
-   if (omapdss_device_is_enabled(dssdev))
-   return 0;
-
-   r = src->ops->enable(src);
-   if (r)
-   return r;
-
-   dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-   return r;
+   return src->ops->enable(src);
 }
 
 static void tvc_disable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   dev_dbg(ddata->dev, "disable\n");
-
if (!omapdss_device_is_enabled(dssdev))
return;
 
src->ops->disable(src);
-
-   dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static const struct omap_dss_device_ops tvc_ops = {
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 24b14f44248e..1e0925791c3d 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -49,21 +49,8 @@ static void dvic_disconnect(struct omap_dss_device *src,
 static int dvic_enable(struct omap_dss_device *dssdev)
 {
struct omap_dss_device *src = dssdev->src;
-   int r;
-
-   if (!omapdss_device_is_connected(dssdev))
-   return -ENODEV;
-
-   if (omapdss_device_is_enabled(dssdev))
-   return 0;
 
-   r = src->ops->enable(src);
-   if (r)
-   return r;
-
-   dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-   return 0;
+   return src->ops->enable(src);
 }
 
 static void dvic_disable(struct omap_dss_device *dssdev)
@@ -74,8 +61,6 @@ static void dvic_disable(struct omap_dss_device *dssdev)
return;
 
src->ops->disable(src);
-
-   dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static int dvic_ddc_read(struct i2c_adapter *adapter,
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index e602fa4a50a4..649364e04edd 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -43,40 +43,19 @@ static void hdmic_disconnect(struct omap_dss_device *src,
 
 static int hdmic_enable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
-   int r;
-
-   dev_dbg(ddata->dev, "enable\n");
-
-   if (!omapdss_device_is_connected(dssdev))
-   return -ENODEV;
-
-   if (omapdss_device_is_enabled(dssdev))
-   return 0;
 
-   r = src->ops->enable(src);
-   if (r)
-   return r;
-
-   dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-   return r;
+   return src->ops->enable(src);
 }
 
 static void hdmic_disable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   dev_dbg(ddata->dev, "disable\n");
-
if (!omapdss_device_is_enabled(dssdev))
return;
 
src->ops->disable(src);
-
-  

[PATCH v2 37/49] drm/bridge: use bus flags in bridge timings

2019-01-10 Thread Laurent Pinchart
From: Stefan Agner 

The DRM bus flags convey additional information on pixel data on
the bus. All current available bus flags might be of interest for
a bridge. Remove the sampling_edge field and use bus_flags.

In the case at hand a dumb VGA bridge needs a specific data enable
polarity (DRM_BUS_FLAG_DE_LOW).

Signed-off-by: Stefan Agner 
Signed-off-by: Laurent Pinchart 
Reviewed-by: Tomi Valkeinen 
---
Changes since v1:

- Renamed bus_flags to input_bus_flags
---
 drivers/gpu/drm/bridge/dumb-vga-dac.c |  6 +++---
 include/drm/drm_bridge.h  | 12 +---
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c 
b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 7dc14c22f7db..191a4a6e624f 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -234,7 +234,7 @@ static int dumb_vga_remove(struct platform_device *pdev)
  */
 static const struct drm_bridge_timings default_dac_timings = {
/* Timing specifications, datasheet page 7 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
+   .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
.setup_time_ps = 500,
.hold_time_ps = 1500,
 };
@@ -245,7 +245,7 @@ static const struct drm_bridge_timings default_dac_timings 
= {
  */
 static const struct drm_bridge_timings ti_ths8134_dac_timings = {
/* From timing diagram, datasheet page 9 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
+   .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 12 */
.setup_time_ps = 3000,
/* I guess this means latched input */
@@ -258,7 +258,7 @@ static const struct drm_bridge_timings 
ti_ths8134_dac_timings = {
  */
 static const struct drm_bridge_timings ti_ths8135_dac_timings = {
/* From timing diagram, datasheet page 14 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
+   .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 16 */
.setup_time_ps = 2000,
.hold_time_ps = 500,
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index bf81fb573a5e..27c17706626c 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -244,15 +244,13 @@ struct drm_bridge_funcs {
  */
 struct drm_bridge_timings {
/**
-* @sampling_edge:
+* @input_bus_flags:
 *
-* Tells whether the bridge samples the digital input signals from the
-* display engine on the positive or negative edge of the clock. This
-* should use the DRM_BUS_FLAG_PIXDATA_SAMPLE_[POS|NEG]EDGE and
-* DRM_BUS_FLAG_SYNC_SAMPLE_[POS|NEG]EDGE bitwise flags from the DRM
-* connector (bit 2, 3, 6 and 7 valid).
+* Tells what additional settings for the pixel data on the bus
+* this bridge requires (like pixel signal polarity). See also
+* &drm_display_info->bus_flags.
 */
-   u32 sampling_edge;
+   u32 input_bus_flags;
/**
 * @setup_time_ps:
 *
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 25/49] drm/omap: Remove src field from omap_dss_device structure

2019-01-10 Thread Laurent Pinchart
The field is only used to check whether the device is connected, and we
can do so by checking the dss field instead. Remove the src field.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 14 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  1 -
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 76470ba45660..62ccbeb99a84 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -176,7 +176,7 @@ EXPORT_SYMBOL(omapdss_device_next_output);
 
 static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
 {
-   return dssdev->src;
+   return dssdev->dss;
 }
 
 int omapdss_device_connect(struct dss_device *dss,
@@ -198,11 +198,6 @@ int omapdss_device_connect(struct dss_device *dss,
return ret;
}
 
-   if (src) {
-   WARN_ON(dst->src);
-   dst->src = src;
-   }
-
return 0;
 }
 EXPORT_SYMBOL_GPL(omapdss_device_connect);
@@ -217,13 +212,6 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
return;
}
 
-   if (src) {
-   if (WARN_ON(dst->src != src))
-   return;
-
-   dst->src = NULL;
-   }
-
WARN_ON(dst->state != OMAP_DSS_DISPLAY_DISABLED);
 
dst->ops->disconnect(src, dst);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index dd93c2121a35..015b2dd9fb99 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -409,7 +409,6 @@ struct omap_dss_device {
struct module *owner;
 
struct dss_device *dss;
-   struct omap_dss_device *src;
struct omap_dss_device *next;
 
struct list_head list;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 39/49] drm/bridge: ti-tfp410: Set connector type based on DT connector node

2019-01-10 Thread Laurent Pinchart
The TI TFP410 is a DVI encoder, not a full HDMI encoder. Its output can
be routed to a DVI-D connector, even if in many cases embedded systems
will use an HDMI connector to carry the DVI signals.

Instead of hardcoding the connector type to HDMI, retrieve the connector
type from its DT node.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Jyri Sarha 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index c3e32138c6bb..e4280f5af9f5 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -27,6 +27,7 @@
 struct tfp410 {
struct drm_bridge   bridge;
struct drm_connectorconnector;
+   unsigned intconnector_type;
 
struct i2c_adapter  *ddc;
struct gpio_desc*hpd;
@@ -126,7 +127,7 @@ static int tfp410_attach(struct drm_bridge *bridge)
drm_connector_helper_add(&dvi->connector,
 &tfp410_con_helper_funcs);
ret = drm_connector_init(bridge->dev, &dvi->connector,
-&tfp410_con_funcs, DRM_MODE_CONNECTOR_HDMIA);
+&tfp410_con_funcs, dvi->connector_type);
if (ret) {
dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
return ret;
@@ -172,6 +173,11 @@ static int tfp410_get_connector_properties(struct tfp410 
*dvi)
if (!connector_node)
return -ENODEV;
 
+   if (of_device_is_compatible(connector_node, "hdmi-connector"))
+   dvi->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+   else
+   dvi->connector_type = DRM_MODE_CONNECTOR_DVID;
+
dvi->hpd = fwnode_get_named_gpiod(&connector_node->fwnode,
"hpd-gpios", 0, GPIOD_IN, "hpd");
if (IS_ERR(dvi->hpd)) {
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 36/49] drm: Use new DRM_BUS_FLAG_*_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags

2019-01-10 Thread Laurent Pinchart
From: Laurent Pinchart 

The DRM_BUS_FLAG_PIXDATA_(POS|NEG)EDGE and
DRM_BUS_FLAG_SYNC_(POS|NEG)EDGE flags are deprecated in favour of the
new DRM_BUS_FLAG_PIXDATA_(DRIVE|SAMPLE)_(POS|NEG)EDGE and
new DRM_BUS_FLAG_SYNC_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags. Replace them
through the code.

This effectively changes the value of the .sampling_edge bridge timings
field in the dumb-vga-dac driver. This is safe to do as no driver
consumes these values yet.

Signed-off-by: Laurent Pinchart 
Acked-by: Linus Walleij 
---
Changes since v1:

- Clarify commit message
- Address the DRM_BUS_FLAG_SYNC_* flags
- Rebase on top of drm-next
---
 drivers/gpu/drm/bridge/dumb-vga-dac.c |  6 ++---
 drivers/gpu/drm/drm_modes.c   | 12 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c|  2 +-
 drivers/gpu/drm/imx/ipuv3-crtc.c  |  2 +-
 drivers/gpu/drm/mxsfb/mxsfb_crtc.c|  6 ++---
 .../gpu/drm/omapdrm/displays/encoder-tfp410.c |  5 ++--
 .../displays/panel-lgphilips-lb035q02.c   |  5 ++--
 .../omapdrm/displays/panel-nec-nl8048hl11.c   |  5 ++--
 .../displays/panel-sharp-ls037v7dw01.c|  5 ++--
 .../omapdrm/displays/panel-sony-acx565akm.c   |  5 ++--
 .../omapdrm/displays/panel-tpo-td028ttec1.c   |  5 ++--
 .../omapdrm/displays/panel-tpo-td043mtea1.c   |  5 ++--
 drivers/gpu/drm/omapdrm/dss/dsi.c |  4 ++--
 drivers/gpu/drm/omapdrm/dss/sdi.c |  4 ++--
 drivers/gpu/drm/omapdrm/omap_encoder.c|  8 +++
 drivers/gpu/drm/panel/panel-arm-versatile.c   |  4 ++--
 drivers/gpu/drm/panel/panel-ilitek-ili9322.c  |  4 ++--
 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c   |  2 +-
 drivers/gpu/drm/panel/panel-simple.c  | 24 +--
 drivers/gpu/drm/pl111/pl111_display.c |  2 +-
 drivers/gpu/drm/sun4i/sun4i_tcon.c|  4 ++--
 drivers/gpu/drm/tve200/tve200_display.c   |  3 ++-
 include/drm/drm_bridge.h  |  9 +++
 23 files changed, 70 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c 
b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 9b706789a341..7dc14c22f7db 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -234,7 +234,7 @@ static int dumb_vga_remove(struct platform_device *pdev)
  */
 static const struct drm_bridge_timings default_dac_timings = {
/* Timing specifications, datasheet page 7 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
.setup_time_ps = 500,
.hold_time_ps = 1500,
 };
@@ -245,7 +245,7 @@ static const struct drm_bridge_timings default_dac_timings 
= {
  */
 static const struct drm_bridge_timings ti_ths8134_dac_timings = {
/* From timing diagram, datasheet page 9 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 12 */
.setup_time_ps = 3000,
/* I guess this means latched input */
@@ -258,7 +258,7 @@ static const struct drm_bridge_timings 
ti_ths8134_dac_timings = {
  */
 static const struct drm_bridge_timings ti_ths8135_dac_timings = {
/* From timing diagram, datasheet page 14 */
-   .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+   .sampling_edge = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
/* From datasheet, page 16 */
.setup_time_ps = 2000,
.hold_time_ps = 500,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 24a750436559..bf49ee1a09e1 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -662,22 +662,22 @@ EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
  * @bus_flags: information about pixelclk, sync and DE polarity will be stored
  * here
  *
- * Sets DRM_BUS_FLAG_DE_(LOW|HIGH),  DRM_BUS_FLAG_PIXDATA_(POS|NEG)EDGE and
- * DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS
+ * Sets DRM_BUS_FLAG_DE_(LOW|HIGH),  DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE
+ * and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to 
DISPLAY_FLAGS
  * found in @vm
  */
 void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
 {
*bus_flags = 0;
if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
-   *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
+   *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
-   *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
+   *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
 
if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE)
-   *bus_flags |= DRM_BUS_FLAG_SYNC_POSEDGE;
+   *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE;
if (vm->flags & DISPLAY_FLAGS_SYNC_NEGEDGE)
-   *bus_flags |= DRM_BUS_FLAG_SYNC_NEGEDGE;
+   *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
 
if (vm->

[PATCH v2 22/49] drm/omap: Don't store display pointer in omap_connector structure

2019-01-10 Thread Laurent Pinchart
Display pipelines based on drm_bridge are handled from the bridge
closest to the CRTC. To move to that model we thus need to transition
away from walking pipelines in the other direction, and from accessing
the device at the end of the pipeline when possible.

Remove most accesses to the display device from the omap_connector
implementation, and don't store it in the omap_connector structure.

- For debug messages we can simply use the connector name instead.
- For type checks we can use the drm_connector type.
- For operation lookup we can start at the other end of the pipeline and
  locate the last matching device.

The display device is still passed to the connector init function in
order to find its type, which requires access to the end of the
pipeline.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 31 ++--
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 0bbbf4d0502d..31b6d6d1def3 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -30,7 +30,6 @@
 struct omap_connector {
struct drm_connector base;
struct omap_dss_device *output;
-   struct omap_dss_device *display;
struct omap_dss_device *hpd;
bool hdmi_mode;
 };
@@ -103,20 +102,20 @@ omap_connector_find_device(struct drm_connector 
*connector,
   enum omap_dss_device_ops_flag op)
 {
struct omap_connector *omap_connector = to_omap_connector(connector);
-   struct omap_dss_device *dssdev;
+   struct omap_dss_device *dssdev = NULL;
+   struct omap_dss_device *d;
 
-   for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
-   if (dssdev->ops_flags & op)
-   return dssdev;
+   for (d = omap_connector->output; d; d = d->next) {
+   if (d->ops_flags & op)
+   dssdev = d;
}
 
-   return NULL;
+   return dssdev;
 }
 
 static enum drm_connector_status omap_connector_detect(
struct drm_connector *connector, bool force)
 {
-   struct omap_connector *omap_connector = to_omap_connector(connector);
struct omap_dss_device *dssdev;
enum drm_connector_status status;
 
@@ -130,11 +129,10 @@ static enum drm_connector_status omap_connector_detect(
 
omap_connector_hpd_notify(connector, dssdev->src, status);
} else {
-   switch (omap_connector->display->type) {
-   case OMAP_DISPLAY_TYPE_DPI:
-   case OMAP_DISPLAY_TYPE_DBI:
-   case OMAP_DISPLAY_TYPE_SDI:
-   case OMAP_DISPLAY_TYPE_DSI:
+   switch (connector->connector_type) {
+   case DRM_MODE_CONNECTOR_DPI:
+   case DRM_MODE_CONNECTOR_LVDS:
+   case DRM_MODE_CONNECTOR_DSI:
status = connector_status_connected;
break;
default:
@@ -143,7 +141,7 @@ static enum drm_connector_status omap_connector_detect(
}
}
 
-   VERB("%s: %d (force=%d)", omap_connector->display->name, status, force);
+   VERB("%s: %d (force=%d)", connector->name, status, force);
 
return status;
 }
@@ -152,7 +150,7 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
 {
struct omap_connector *omap_connector = to_omap_connector(connector);
 
-   DBG("%s", omap_connector->display->name);
+   DBG("%s", connector->name);
 
if (omap_connector->hpd) {
struct omap_dss_device *hpd = omap_connector->hpd;
@@ -166,7 +164,6 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
drm_connector_cleanup(connector);
 
omapdss_device_put(omap_connector->output);
-   omapdss_device_put(omap_connector->display);
 
kfree(omap_connector);
 }
@@ -210,10 +207,9 @@ static int omap_connector_get_modes_edid(struct 
drm_connector *connector,
 
 static int omap_connector_get_modes(struct drm_connector *connector)
 {
-   struct omap_connector *omap_connector = to_omap_connector(connector);
struct omap_dss_device *dssdev;
 
-   DBG("%s", omap_connector->display->name);
+   DBG("%s", connector->name);
 
/*
 * If display exposes EDID, then we parse that in the normal way to
@@ -346,7 +342,6 @@ struct drm_connector *omap_connector_init(struct drm_device 
*dev,
goto fail;
 
omap_connector->output = omapdss_device_get(output);
-   omap_connector->display = omapdss_device_get(display);
 
connector = &omap_connector->base;
connector->interlace_allowed = 1;
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http

[PATCH v2 11/49] drm/omap: Remove connection checks from display .enable() and .remove()

2019-01-10 Thread Laurent Pinchart
The displays (connectors, panels and encoders) return an error from
their .enable() handler when the dss device is not connected. They also
disconnect the dss device explicitly from their .remove() handler if it
is still connected.

Those safety checks are not needed:

- The .enable() handler is called from code paths that access the dss
  devices chain from the display device, which is set to NULL when the
  device isn't connected.

- The .remove() handler can only be called when unloading the module as
  the driver has the suppress_bind_attrs attribute set, and a reference
  to the module is taken when constructing the dss devices chain, so the
  module can only be unloaded when the dss device is disconnected.

Remove the safety checks.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/encoder-opa362.c   |  7 ---
 .../gpu/drm/omapdrm/displays/encoder-tfp410.c   |  7 ---
 .../drm/omapdrm/displays/encoder-tpd12s015.c|  4 
 drivers/gpu/drm/omapdrm/dss/base.c  |  5 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h   |  5 -
 drivers/gpu/drm/omapdrm/omap_encoder.c  | 17 +
 6 files changed, 10 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 4fefd80f53bb..0b1032625e42 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -49,9 +49,6 @@ static int opa362_enable(struct omap_dss_device *dssdev)
 
dev_dbg(dssdev->dev, "enable\n");
 
-   if (!omapdss_device_is_connected(dssdev))
-   return -ENODEV;
-
if (omapdss_device_is_enabled(dssdev))
return 0;
 
@@ -145,10 +142,6 @@ static int __exit opa362_remove(struct platform_device 
*pdev)
if (omapdss_device_is_enabled(dssdev))
opa362_disable(dssdev);
 
-   WARN_ON(omapdss_device_is_connected(dssdev));
-   if (omapdss_device_is_connected(dssdev))
-   omapdss_device_disconnect(NULL, dssdev);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index f1a748353279..fcc2dc5188a2 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -42,9 +42,6 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
struct omap_dss_device *src = dssdev->src;
int r;
 
-   if (!omapdss_device_is_connected(dssdev))
-   return -ENODEV;
-
if (omapdss_device_is_enabled(dssdev))
return 0;
 
@@ -139,10 +136,6 @@ static int __exit tfp410_remove(struct platform_device 
*pdev)
if (omapdss_device_is_enabled(dssdev))
tfp410_disable(dssdev);
 
-   WARN_ON(omapdss_device_is_connected(dssdev));
-   if (omapdss_device_is_connected(dssdev))
-   omapdss_device_disconnect(NULL, dssdev);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 94de55fd8884..1a2bc59bf104 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -229,10 +229,6 @@ static int __exit tpd_remove(struct platform_device *pdev)
if (omapdss_device_is_enabled(dssdev))
tpd_disable(dssdev);
 
-   WARN_ON(omapdss_device_is_connected(dssdev));
-   if (omapdss_device_is_connected(dssdev))
-   omapdss_device_disconnect(NULL, dssdev);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 472f56e3de70..787157b00694 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -185,6 +185,11 @@ struct omap_dss_device *omapdss_device_get_next(struct 
omap_dss_device *from,
 }
 EXPORT_SYMBOL(omapdss_device_get_next);
 
+static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
+{
+   return dssdev->src;
+}
+
 int omapdss_device_connect(struct dss_device *dss,
   struct omap_dss_device *src,
   struct omap_dss_device *dst)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index de0520a8eb4e..698155dd7941 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -505,11 +505,6 @@ int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void 
*arg, u32 mask);
 int omapdss_compat_init(void);
 void omapdss_compat_uninit(void);
 
-static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
-{
-   return dssdev->src;
-}
-
 static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
 {
return dssdev->state == OMAP_DSS_DISPLAY

[PATCH v2 48/49] drm/omap: Remove TFP410 and DVI connector drivers

2019-01-10 Thread Laurent Pinchart
Those components are supported by the drm_bridge infrastructure, remove
the omapdrm-specific driver.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/Kconfig  |  11 -
 drivers/gpu/drm/omapdrm/displays/Makefile |   2 -
 .../gpu/drm/omapdrm/displays/connector-dvi.c  | 293 --
 .../gpu/drm/omapdrm/displays/encoder-tfp410.c | 140 -
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   2 -
 5 files changed, 448 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/connector-dvi.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c

diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig 
b/drivers/gpu/drm/omapdrm/displays/Kconfig
index a349cb61961e..38d066ac966e 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -6,23 +6,12 @@ config DRM_OMAP_ENCODER_OPA362
  Driver for OPA362 external analog TV amplifier controlled
  through a GPIO.
 
-config DRM_OMAP_ENCODER_TFP410
-tristate "TFP410 DPI to DVI Encoder"
-   help
- Driver for TFP410 DPI to DVI encoder.
-
 config DRM_OMAP_ENCODER_TPD12S015
 tristate "TPD12S015 HDMI ESD protection and level shifter"
help
  Driver for TPD12S015, which offers HDMI ESD protection and level
  shifting.
 
-config DRM_OMAP_CONNECTOR_DVI
-tristate "DVI Connector"
-   depends on I2C
-   help
- Driver for a generic DVI connector.
-
 config DRM_OMAP_CONNECTOR_HDMI
 tristate "HDMI Connector"
help
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile 
b/drivers/gpu/drm/omapdrm/displays/Makefile
index d99659e1381b..da1d5321ef50 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_OMAP_ENCODER_OPA362) += encoder-opa362.o
-obj-$(CONFIG_DRM_OMAP_ENCODER_TFP410) += encoder-tfp410.o
 obj-$(CONFIG_DRM_OMAP_ENCODER_TPD12S015) += encoder-tpd12s015.o
-obj-$(CONFIG_DRM_OMAP_CONNECTOR_DVI) += connector-dvi.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_HDMI) += connector-hdmi.o
 obj-$(CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
 obj-$(CONFIG_DRM_OMAP_PANEL_DPI) += panel-dpi.o
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
deleted file mode 100644
index fa3a69bf8a04..
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Generic DVI Connector driver
- *
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Tomi Valkeinen 
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-
-#include "../dss/omapdss.h"
-
-struct panel_drv_data {
-   struct omap_dss_device dssdev;
-
-   struct i2c_adapter *i2c_adapter;
-
-   struct gpio_desc *hpd_gpio;
-
-   void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
-   void *hpd_cb_data;
-   bool hpd_enabled;
-   /* mutex for hpd fields above */
-   struct mutex hpd_lock;
-};
-
-#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
-
-static int dvic_connect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   return 0;
-}
-
-static void dvic_disconnect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-}
-
-static int dvic_ddc_read(struct i2c_adapter *adapter,
-   unsigned char *buf, u16 count, u8 offset)
-{
-   int r, retries;
-
-   for (retries = 3; retries > 0; retries--) {
-   struct i2c_msg msgs[] = {
-   {
-   .addr   = DDC_ADDR,
-   .flags  = 0,
-   .len= 1,
-   .buf= &offset,
-   }, {
-   .addr   = DDC_ADDR,
-   .flags  = I2C_M_RD,
-   .len= count,
-   .buf= buf,
-   }
-   };
-
-   r = i2c_transfer(adapter, msgs, 2);
-   if (r == 2)
-   return 0;
-
-   if (r != -EAGAIN)
-   break;
-   }
-
-   return r < 0 ? r : -EIO;
-}
-
-static int dvic_read_edid(struct omap_dss_device *dssdev,
-   u8 *edid, int len)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-   int r, l, bytes_read;
-
-   l = min(EDID_LENGTH, len);
-   r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0);
-   if (r)
-   return r;
-
-   byt

[PATCH v2 41/49] drm/bridge: ti-tfp410: Report input bus config through bridge timings

2019-01-10 Thread Laurent Pinchart
The TFP410 supports configurable pixel clock sampling edge and data
de-skew adjustments. The configuration can be set through I2C or
dedicated chip pins.

Report the configuration through the drm_bridge timings. As the
ti-tftp410 driver doesn't support configuring the chip through I2C, we
simply use the default configuration in that case. When the chip is
configured through dedicated pins, we parse the configuration from DT.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Tomi Valkeinen 
Reviewed-by: Jyri Sarha 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 77 --
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index d25d23cfe3f5..48ec647a7526 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -34,6 +34,8 @@ struct tfp410 {
struct delayed_work hpd_work;
struct gpio_desc*powerdown;
 
+   struct drm_bridge_timings timings;
+
struct device *dev;
 };
 
@@ -180,6 +182,70 @@ static irqreturn_t tfp410_hpd_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
 }
 
+static const struct drm_bridge_timings tfp410_default_timings = {
+   .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
+| DRM_BUS_FLAG_DE_HIGH,
+   .setup_time_ps = 1200,
+   .hold_time_ps = 1300,
+};
+
+static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
+{
+   struct drm_bridge_timings *timings = &dvi->timings;
+   struct device_node *ep;
+   u32 pclk_sample = 0;
+   s32 deskew = 0;
+
+   /* Start with defaults. */
+   *timings = tfp410_default_timings;
+
+   if (i2c)
+   /*
+* In I2C mode timings are configured through the I2C interface.
+* As the driver doesn't support I2C configuration yet, we just
+* go with the defaults (BSEL=1, DSEL=1, DKEN=0, EDGE=1).
+*/
+   return 0;
+
+   /*
+* In non-I2C mode, timings are configured through the BSEL, DSEL, DKEN
+* and EDGE pins. They are specified in DT through endpoint properties
+* and vendor-specific properties.
+*/
+   ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
+   if (!ep)
+   return -EINVAL;
+
+   /* Get the sampling edge from the endpoint. */
+   of_property_read_u32(ep, "pclk-sample", &pclk_sample);
+   of_node_put(ep);
+
+   timings->input_bus_flags = DRM_BUS_FLAG_DE_HIGH;
+
+   switch (pclk_sample) {
+   case 0:
+   timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
+|  DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
+   break;
+   case 1:
+   timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
+|  DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   /* Get the setup and hold time from vendor-specific properties. */
+   of_property_read_u32(dvi->dev->of_node, "ti,deskew", (u32 *)&deskew);
+   if (deskew < -4 || deskew > 3)
+   return -EINVAL;
+
+   timings->setup_time_ps = min(0, 1200 - 350 * deskew);
+   timings->hold_time_ps = min(0, 1300 + 350 * deskew);
+
+   return 0;
+}
+
 static int tfp410_get_connector_properties(struct tfp410 *dvi)
 {
struct device_node *connector_node, *ddc_phandle;
@@ -223,7 +289,7 @@ static int tfp410_get_connector_properties(struct tfp410 
*dvi)
return ret;
 }
 
-static int tfp410_init(struct device *dev)
+static int tfp410_init(struct device *dev, bool i2c)
 {
struct tfp410 *dvi;
int ret;
@@ -240,8 +306,13 @@ static int tfp410_init(struct device *dev)
 
dvi->bridge.funcs = &tfp410_bridge_funcs;
dvi->bridge.of_node = dev->of_node;
+   dvi->bridge.timings = &dvi->timings;
dvi->dev = dev;
 
+   ret = tfp410_parse_timings(dvi, i2c);
+   if (ret)
+   goto fail;
+
ret = tfp410_get_connector_properties(dvi);
if (ret)
goto fail;
@@ -294,7 +365,7 @@ static int tfp410_fini(struct device *dev)
 
 static int tfp410_probe(struct platform_device *pdev)
 {
-   return tfp410_init(&pdev->dev);
+   return tfp410_init(&pdev->dev, false);
 }
 
 static int tfp410_remove(struct platform_device *pdev)
@@ -331,7 +402,7 @@ static int tfp410_i2c_probe(struct i2c_client *client,
return -ENXIO;
}
 
-   return tfp410_init(&client->dev);
+   return tfp410_init(&client->dev, true);
 }
 
 static int tfp410_i2c_remove(struct i2c_client *client)
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 17/49] drm/omap: Merge display .get_modes() and .get_size() operations

2019-01-10 Thread Laurent Pinchart
Now that the .get_modes() operations takes a drm_connector and fills it
with modes, it becomes easy to fill display information in the same
operation without requiring a separate .get_size() opearation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 14 +++---
 drivers/gpu/drm/omapdrm/dss/omapdss.h   |  3 ---
 drivers/gpu/drm/omapdrm/omap_connector.c| 15 ++-
 3 files changed, 5 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 9cd9ab487a24..c5f570106a17 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -1117,6 +1117,9 @@ static int dsicm_get_modes(struct omap_dss_device *dssdev,
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
+   connector->display_info.width_mm = ddata->width_mm;
+   connector->display_info.height_mm = ddata->height_mm;
+
return omapdss_display_get_modes(connector, &ddata->vm);
 }
 
@@ -1142,15 +1145,6 @@ static int dsicm_check_timings(struct omap_dss_device 
*dssdev,
return ret;
 }
 
-static void dsicm_get_size(struct omap_dss_device *dssdev,
- unsigned int *width, unsigned int *height)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   *width = ddata->width_mm;
-   *height = ddata->height_mm;
-}
-
 static const struct omap_dss_device_ops dsicm_ops = {
.connect= dsicm_connect,
.disconnect = dsicm_disconnect,
@@ -1166,8 +1160,6 @@ static const struct omap_dss_driver dsicm_dss_driver = {
.update = dsicm_update,
.sync   = dsicm_sync,
 
-   .get_size   = dsicm_get_size,
-
.enable_te  = dsicm_enable_te,
.get_te = dsicm_get_te,
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 88fa61ddc959..7637fc041b71 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -457,9 +457,6 @@ struct omap_dss_driver {
int (*memory_read)(struct omap_dss_device *dssdev,
void *buf, size_t size,
u16 x, u16 y, u16 w, u16 h);
-
-   void (*get_size)(struct omap_dss_device *dssdev,
-unsigned int *width, unsigned int *height);
 };
 
 struct dss_device *omapdss_get_dss(void);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 93b31bf07d05..c21a2016d03f 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -225,19 +225,8 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
return omap_connector_get_modes_edid(connector, dssdev);
 
/*
-* Otherwise we have either a fixed resolution panel or an output that
-* doesn't support modes discovery (e.g. DVI or VGA with the DDC bus
-* unconnected, or analog TV). Start by querying the size.
-*/
-   dssdev = omap_connector->display;
-   if (dssdev->driver && dssdev->driver->get_size)
-   dssdev->driver->get_size(dssdev,
-&connector->display_info.width_mm,
-&connector->display_info.height_mm);
-
-   /*
-* If the display pipeline reports modes (e.g. with a fixed resolution
-* panel or an analog TV output), query it.
+* Otherwise if the display pipeline reports modes (e.g. with a fixed
+* resolution panel or an analog TV output), query it.
 */
for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
if (dssdev->ops->get_modes)
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 04/49] drm/omap: dsi: Hack-fix DSI bus flags

2019-01-10 Thread Laurent Pinchart
From: Tomi Valkeinen 

Since commit b4935e3a3cfa ("drm/omap: Store bus flags in the
omap_dss_device structure") video mode flags are managed by the omapdss
(and later omapdrm) core based on bus flags stored in omap_dss_device.
This works fine for all devices whose video modes are set by the omapdss
and omapdrm core, but breaks DSI operation as the DSI still uses legacy
code paths and sets the DISPC timings manually.

To fix the problem properly we should move the DSI encoder to the new
encoder model. This will however require a considerable amount of work.
Restore DSI operation by adding back video mode flags handling in the
DSI encoder driver as a hack in the meantime.

Fixes: b4935e3a3cfa ("drm/omap: Store bus flags in the omap_dss_device 
structure")
Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index b5685018d830..64fb788b6647 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4751,6 +4751,17 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH;
dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
+   /*
+* HACK: These flags should be handled through the omap_dss_device bus
+* flags, but this will only be possible when the DSI encoder will be
+* converted to the omapdrm-managed encoder model.
+*/
+   dsi->vm.flags &= ~DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+   dsi->vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
+   dsi->vm.flags &= ~DISPLAY_FLAGS_DE_LOW;
+   dsi->vm.flags |= DISPLAY_FLAGS_DE_HIGH;
+   dsi->vm.flags &= ~DISPLAY_FLAGS_SYNC_POSEDGE;
+   dsi->vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
 
dss_mgr_set_timings(&dsi->output, &dsi->vm);
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 01/49] drm/atomic: Constify mode argument to mode_valid_path()

2019-01-10 Thread Laurent Pinchart
The mode_valid_path() function validates the mode it receives without
ever modifying it. Constify the mode pointer argument to make that
explicit.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_atomic_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 54e2ae614dcc..d4ebec2c9f15 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -489,7 +489,7 @@ mode_fixup(struct drm_atomic_state *state)
 static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
struct drm_encoder *encoder,
struct drm_crtc *crtc,
-   struct drm_display_mode *mode)
+   const struct drm_display_mode *mode)
 {
enum drm_mode_status ret;
 
@@ -528,7 +528,7 @@ mode_valid(struct drm_atomic_state *state)
struct drm_crtc *crtc = conn_state->crtc;
struct drm_crtc_state *crtc_state;
enum drm_mode_status mode_status;
-   struct drm_display_mode *mode;
+   const struct drm_display_mode *mode;
 
if (!crtc || !encoder)
continue;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 10/49] drm/omap: Remove connection checks from internal encoders .enable()

2019-01-10 Thread Laurent Pinchart
The internal encoders return an error from their .enable() handler when
their are not connected to a dss manager. As the flag used is set and
cleared in the connect and disconnect handlers, this effectively checks
whether the omap_dss_device is connected.

The .enable() handler is called from code paths that access the dss
devices chain from the display device, which is set to NULL when the
device isn't connected, making it impossible to access the device in
that case.

The safety check is thus not needed, remove it.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 17 +
 drivers/gpu/drm/omapdrm/dss/dsi.c | 20 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   | 17 +
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   | 17 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  1 -
 drivers/gpu/drm/omapdrm/dss/sdi.c | 16 +---
 drivers/gpu/drm/omapdrm/dss/venc.c| 17 +
 7 files changed, 7 insertions(+), 98 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index ca4f3c4c6318..0cf3b220e35f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -386,12 +386,6 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
 
mutex_lock(&dpi->lock);
 
-   if (!out->dispc_channel_connected) {
-   DSSERR("failed to enable display: no output/manager\n");
-   r = -ENODEV;
-   goto err_no_out_mgr;
-   }
-
if (dpi->vdds_dsi_reg) {
r = regulator_enable(dpi->vdds_dsi_reg);
if (r)
@@ -439,7 +433,6 @@ static int dpi_display_enable(struct omap_dss_device 
*dssdev)
if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
 err_reg_enable:
-err_no_out_mgr:
mutex_unlock(&dpi->lock);
return r;
 }
@@ -596,23 +589,15 @@ static int dpi_connect(struct omap_dss_device *src,
   struct omap_dss_device *dst)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
-   int r;
 
dpi_init_pll(dpi);
 
-   r = omapdss_device_connect(dst->dss, dst, dst->next);
-   if (r)
-   return r;
-
-   dst->dispc_channel_connected = true;
-   return 0;
+   return omapdss_device_connect(dst->dss, dst, dst->next);
 }
 
 static void dpi_disconnect(struct omap_dss_device *src,
   struct omap_dss_device *dst)
 {
-   dst->dispc_channel_connected = false;
-
omapdss_device_disconnect(dst, dst->next);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 64fb788b6647..c14f8fb2a99b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3753,19 +3753,13 @@ static int dsi_enable_video_output(struct 
omap_dss_device *dssdev, int channel)
 {
struct dsi_data *dsi = to_dsi_data(dssdev);
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
-   struct omap_dss_device *out = &dsi->output;
u8 data_type;
u16 word_count;
int r;
 
-   if (!out->dispc_channel_connected) {
-   DSSERR("failed to enable display: no output/manager\n");
-   return -ENODEV;
-   }
-
r = dsi_display_init_dispc(dsi);
if (r)
-   goto err_init_dispc;
+   return r;
 
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
switch (dsi->pix_fmt) {
@@ -3814,7 +3808,6 @@ static int dsi_enable_video_output(struct omap_dss_device 
*dssdev, int channel)
}
 err_pix_fmt:
dsi_display_uninit_dispc(dsi);
-err_init_dispc:
return r;
 }
 
@@ -4888,21 +4881,12 @@ static int dsi_get_clocks(struct dsi_data *dsi)
 static int dsi_connect(struct omap_dss_device *src,
   struct omap_dss_device *dst)
 {
-   int r;
-
-   r = omapdss_device_connect(dst->dss, dst, dst->next);
-   if (r)
-   return r;
-
-   dst->dispc_channel_connected = true;
-   return 0;
+   return omapdss_device_connect(dst->dss, dst, dst->next);
 }
 
 static void dsi_disconnect(struct omap_dss_device *src,
   struct omap_dss_device *dst)
 {
-   dst->dispc_channel_connected = false;
-
omapdss_device_disconnect(dst, dst->next);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index aabdda394c9c..b6b44f07c74e 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -322,12 +322,6 @@ static int hdmi_display_enable(struct omap_dss_device 
*dssdev)
 
mutex_lock(&hdmi->lock);
 
-   if (!dssdev->dispc_channel_connected) {
-   DSSERR("failed to enable display: no output/manager\n");
-   r = -ENODEV;
-   goto err0;
-   }
-
r = hdmi_power_on_ful

[PATCH v2 07/49] drm/omap: venc: Remove wss_data field from venc_device structure

2019-01-10 Thread Laurent Pinchart
The venc_device structure wss_data field is set to 0 and never otherwise
modified, remove it.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index b5f52727f8b1..fbe9d42dbdb6 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -323,7 +323,6 @@ struct venc_device {
struct platform_device *pdev;
void __iomem *base;
struct mutex venc_lock;
-   u32 wss_data;
struct regulator *vdda_dac_reg;
struct dss_device *dss;
 
@@ -367,8 +366,7 @@ static void venc_write_config(struct venc_device *venc,
venc_write_reg(venc, VENC_BLACK_LEVEL, config->black_level);
venc_write_reg(venc, VENC_BLANK_LEVEL, config->blank_level);
venc_write_reg(venc, VENC_M_CONTROL, config->m_control);
-   venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
-  venc->wss_data);
+   venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data);
venc_write_reg(venc, VENC_S_CARR, config->s_carr);
venc_write_reg(venc, VENC_L21__WC_CTL, config->l21__wc_ctl);
venc_write_reg(venc, VENC_SAVID__EAVID, config->savid__eavid);
@@ -543,8 +541,6 @@ static int venc_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err0;
 
-   venc->wss_data = 0;
-
mutex_unlock(&venc->venc_lock);
 
return 0;
@@ -585,10 +581,6 @@ static void venc_set_timings(struct omap_dss_device 
*dssdev,
 
mutex_lock(&venc->venc_lock);
 
-   /* Reset WSS data when the TV standard changes. */
-   if (memcmp(&venc->vm, vm, sizeof(*vm)))
-   venc->wss_data = 0;
-
venc->vm = *vm;
 
dispc_set_tv_pclk(venc->dss->dispc, 1350);
@@ -878,7 +870,6 @@ static int venc_probe(struct platform_device *pdev)
 
mutex_init(&venc->venc_lock);
 
-   venc->wss_data = 0;
venc->vm = omap_dss_pal_vm;
 
venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 00/49] omapdrm: drm_bridge and drm_panel support

2019-01-10 Thread Laurent Pinchart
Hello,

This patch series consolidates the three pending series for the omapdrm and
tfp410 drivers that all together implement drm_bridge and drm_panel support
for omapdrm.

The series starts with four patches not posted before as part of this work.
The first patch (01/49) has been sitting in my tree as a base for the omapdrm
rework for such a long time that I have included it here. The next three
patches (02/49 to 04/49) have been written by Tomi to fix DSI regression
introduced by previous omapdrm rework, and are included here to start with a
cleaner base.

The following 30 patches (05/49 to 34/49) have previously been posted as part
of "[PATCH 00/29] omapdrm: Last large refactoring for drm_bridge transition"
[1]. They complete the extensive rework of the omapdrm and omapdss drivers to
prepare for the transition to drm_bridge.

The next 7 patches (35/49 to 41/49) have been previously posted as part of
"[PATCH v2 0/2] Clarify display info PIXDATA bus flags" [2] and
"[PATCH 0/5] drm: ti-tfp410 improvements" [3]. They improve the ti-tfp410
driver with new features required by omapdrm and currently implemented in the
omapdrm custom tfp410 driver.

The next 2 patches (42/49 and 43/49) are new and add missing DT bindings for
the panel used by the TI AM57xx EVM.

The last 6 patches (44/49 to 49/49) have previously been posted as part of
"[PATCH 0/6] omapdrm: drm_bridge and drm_panel support" [4]. They hook up
support for drm_bridge and drm_panel in the omapdrm driver, and remove the
omapdrm-specific tfp410 and panel-dpi drivers.

All patches have been rebased on top of v5.0-rc1 and review comments have been
incorporated. Please see individual patches for changelogs. The whole series
is available from

git://linuxtv.org/pinchartl/media.git omapdrm/bridge/next

[1] https://www.spinics.net/lists/dri-devel/msg198993.html
[2] https://lists.freedesktop.org/archives/dri-devel/2018-December/199204.html
[3] https://www.spinics.net/lists/dri-devel/msg199245.html
[4] https://www.spinics.net/lists/dri-devel/msg199524.html

Laurent Pinchart (45):
  drm/atomic: Constify mode argument to mode_valid_path()
  drm/omap: Remove declaration of nonexisting function
  drm/omap: Remove unused kobj field from struct omap_dss_device
  drm/omap: venc: Remove wss_data field from venc_device structure
  drm/omap: Use atomic suspend/resume helpers
  drm/omap: Move common display enable/disable code to encoder
  drm/omap: Remove connection checks from internal encoders .enable()
  drm/omap: Remove connection checks from display .enable() and
.remove()
  drm/omap: Remove enable checks from display .enable() and .remove()
  drm/omap: Reverse direction of the DSS device enable/disable
operations
  drm/omap: Remove omap_dss_device dst field
  drm/omap: Factor out common init/cleanup code for output devices
  drm/omap: Expose DRM modes instead of timings in display devices
  drm/omap: Merge display .get_modes() and .get_size() operations
  drm/omap: Add a dss device operation flag for .get_modes()
  drm/omap: venc: List both PAL and NTSC modes
  drm/omap: Don't pass display pointer to encoder init function
  drm/omap: Move display alias ID to omap_drm_pipeline
  drm/omap: Don't store display pointer in omap_connector structure
  drm/omap: panel-dsi-cm: Store source pointer internally
  drm/omap: Notify all devices in the pipeline of output disconnection
  drm/omap: Remove src field from omap_dss_device structure
  drm/omap: Move DISPC timing checks to CRTC .mode_valid() operation
  drm/omap: venc: Simplify mode setting by caching configuration
  drm/omap: Factor out common mode validation code
  drm/omap: Pass drm_display_mode to .check_timings() and .set_timings()
  drm/omap: venc: Use drm_display_mode natively
  drm/omap: Store pixel clock instead of full mode in DPI and SDI
encoders
  drm/omap: Simplify OF lookup of DSS devices
  drm/omap: Refactor initialization sequence
  drm/omap: Merge omap_dss_device type and output_type fields
  drm: Clarify definition of the DRM_BUS_FLAG_(PIXDATA|SYNC)_* macros
  drm: Use new DRM_BUS_FLAG_*_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags
  dt-bindings: display: tfp410: Add bus parameters properties
  drm/bridge: ti-tfp410: Set connector type based on DT connector node
  drm/bridge: ti-tfp410: Add support for the powerdown GPIO
  drm/bridge: ti-tfp410: Report input bus config through bridge timings
  dt-bindings: Add vendor prefix for OSD Displays
  dt-bindings: display: Add OSD Displays OSD070T1718-19TS panel binding
  drm/panel: simple: Add OSD070T1718-19TS panel support
  drm/omap: Add support for drm_bridge
  drm/omap: Add support for drm_panel
  drm/omap: Whitelist DT nodes to fixup with omapdss, prefix
  drm/omap: Remove TFP410 and DVI connector drivers
  drm/omap: Remove panel-dpi driver

Stefan Agner (1):
  drm/bridge: use bus flags in bridge timings

Tomi Valkeinen (3):
  drm/omap: dsi: Fix crash in DSI debug dumps
  drm/omap: dsi: Fix OF platform depopulate
  drm/omap: dsi: Hack-fix DSI

[PATCH v2 20/49] drm/omap: Don't pass display pointer to encoder init function

2019-01-10 Thread Laurent Pinchart
The display isn't used by the encoder implementation, don't pass it to
the initialization function and store it internally needlessly.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 2 +-
 drivers/gpu/drm/omapdrm/omap_encoder.c | 5 +
 drivers/gpu/drm/omapdrm/omap_encoder.h | 3 +--
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 8a4dd737d88c..d1f6f4e47520 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -296,7 +296,7 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_encoder *encoder;
struct drm_crtc *crtc;
 
-   encoder = omap_encoder_init(dev, pipe->output, display);
+   encoder = omap_encoder_init(dev, pipe->output);
if (!encoder)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 3448b07546a9..02b2e24ad333 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -37,7 +37,6 @@
 struct omap_encoder {
struct drm_encoder base;
struct omap_dss_device *output;
-   struct omap_dss_device *display;
 };
 
 static void omap_encoder_destroy(struct drm_encoder *encoder)
@@ -247,8 +246,7 @@ static const struct drm_encoder_helper_funcs 
omap_encoder_helper_funcs = {
 
 /* initialize encoder */
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
- struct omap_dss_device *output,
- struct omap_dss_device *display)
+ struct omap_dss_device *output)
 {
struct drm_encoder *encoder = NULL;
struct omap_encoder *omap_encoder;
@@ -258,7 +256,6 @@ struct drm_encoder *omap_encoder_init(struct drm_device 
*dev,
goto fail;
 
omap_encoder->output = output;
-   omap_encoder->display = display;
 
encoder = &omap_encoder->base;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h 
b/drivers/gpu/drm/omapdrm/omap_encoder.h
index a7b5dde63ecb..4aefb3142886 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.h
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.h
@@ -25,7 +25,6 @@ struct drm_encoder;
 struct omap_dss_device;
 
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
- struct omap_dss_device *output,
- struct omap_dss_device *display);
+ struct omap_dss_device *output);
 
 #endif /* __OMAPDRM_ENCODER_H__ */
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 03/49] drm/omap: dsi: Fix OF platform depopulate

2019-01-10 Thread Laurent Pinchart
From: Tomi Valkeinen 

Commit edb715dffdee ("drm/omap: dss: dsi: Move initialization code from
bind to probe") moved the of_platform_populate() call from dsi_bind() to
dsi_probe(), but failed to move the corresponding
of_platform_depopulate() from dsi_unbind() to dsi_remove(). This results
in OF child devices being potentially removed multiple times. Fix it by
placing the of_platform_depopulate() call where it belongs.

Fixes: edb715dffdee ("drm/omap: dss: dsi: Move initialization code from bind to 
probe")
Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 277f9dd2ec8c..b5685018d830 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5104,8 +5104,6 @@ static void dsi_unbind(struct device *dev, struct device 
*master, void *data)
dss_debugfs_remove_file(dsi->debugfs.irqs);
dss_debugfs_remove_file(dsi->debugfs.regs);
 
-   of_platform_depopulate(dev);
-
WARN_ON(dsi->scp_clk_refcount > 0);
 
dss_pll_unregister(&dsi->pll);
@@ -5457,6 +5455,8 @@ static int dsi_remove(struct platform_device *pdev)
 
dsi_uninit_output(dsi);
 
+   of_platform_depopulate(&pdev->dev);
+
pm_runtime_disable(&pdev->dev);
 
if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) {
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 06/49] drm/omap: Remove unused kobj field from struct omap_dss_device

2019-01-10 Thread Laurent Pinchart
The kobj field from struct omap_dss_device is not used. Remove it.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 33e15cb77efa..3b4bf5c47173 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -19,7 +19,6 @@
 #define __OMAP_DRM_DSS_H
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -404,7 +403,6 @@ enum omap_dss_device_type {
 };
 
 struct omap_dss_device {
-   struct kobject kobj;
struct device *dev;
 
struct module *owner;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 21/49] drm/omap: Move display alias ID to omap_drm_pipeline

2019-01-10 Thread Laurent Pinchart
The DT bindings for the OMAP DSS allow assigning numerical IDs to
display outputs through display entries in the alias node. The driver
uses this information to sort pipelines according to the order specified
in DT, making it possible for a system to give a priority order to
outputs.

Retrieval of the alias ID is done when initializing display dss devices.
That code will be removed when moving to drm_bridge and drm_panel. Move
retrieval of the alias ID to display pipeline connection time and store
it in the pipeline structure instead to keep the feature.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/display.c | 2 --
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 --
 drivers/gpu/drm/omapdrm/omap_drv.c| 9 +++--
 drivers/gpu/drm/omapdrm/omap_drv.h| 1 +
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/display.c 
b/drivers/gpu/drm/omapdrm/dss/display.c
index 398964358386..e93f61a567a8 100644
--- a/drivers/gpu/drm/omapdrm/dss/display.c
+++ b/drivers/gpu/drm/omapdrm/dss/display.c
@@ -42,8 +42,6 @@ void omapdss_display_init(struct omap_dss_device *dssdev)
if (id < 0)
id = disp_num_counter++;
 
-   dssdev->alias_id = id;
-
/* Use 'label' property for name, if it exists */
of_property_read_string(dssdev->dev->of_node, "label", &dssdev->name);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 01da7e94b974..dd93c2121a35 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -414,8 +414,6 @@ struct omap_dss_device {
 
struct list_head list;
 
-   unsigned int alias_id;
-
enum omap_display_type type;
/*
 * DSS output type that this device generates (for DSS internal devices)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index d1f6f4e47520..afa736233076 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -155,9 +155,9 @@ static int omap_compare_pipes(const void *a, const void *b)
const struct omap_drm_pipeline *pipe1 = a;
const struct omap_drm_pipeline *pipe2 = b;
 
-   if (pipe1->display->alias_id > pipe2->display->alias_id)
+   if (pipe1->alias_id > pipe2->alias_id)
return 1;
-   else if (pipe1->display->alias_id < pipe2->display->alias_id)
+   else if (pipe1->alias_id < pipe2->alias_id)
return -1;
return 0;
 }
@@ -182,11 +182,16 @@ static int omap_connect_pipelines(struct drm_device *ddev)
 output->name);
} else {
struct omap_drm_pipeline *pipe;
+   int id;
 
pipe = &priv->pipes[priv->num_pipes++];
pipe->output = omapdss_device_get(output);
pipe->display = omapdss_display_get(output);
 
+   id = of_alias_get_id(pipe->display->dev->of_node,
+"display");
+   pipe->alias_id = id >= 0 ? id : priv->num_pipes - 1;
+
if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
/* To balance the 'for_each_dss_output' loop */
omapdss_device_put(output);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index bd7f2c227a25..b4780a07b702 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -51,6 +51,7 @@ struct omap_drm_pipeline {
struct drm_connector *connector;
struct omap_dss_device *output;
struct omap_dss_device *display;
+   unsigned int alias_id;
 };
 
 struct omap_drm_private {
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 08/49] drm/omap: Use atomic suspend/resume helpers

2019-01-10 Thread Laurent Pinchart
Instead of rolling out custom suspend/resume implementations based on
state information stored in the driver's data structures, use the atomic
suspend/resume helpers that rely on a DRM atomic state object.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
Changes since v1:

- Use drm_mode_config_helper_suspend()
---
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 --
 drivers/gpu/drm/omapdrm/omap_drv.c| 50 ++-
 2 files changed, 2 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 3b4bf5c47173..7b2f2c8bf893 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -432,9 +432,6 @@ struct omap_dss_device {
unsigned long ops_flags;
u32 bus_flags;
 
-   /* helper variable for driver suspend/resume */
-   bool activate_after_resume;
-
enum omap_display_caps caps;
 
enum omap_dss_display_state state;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 5e67d58cbc28..8a4dd737d88c 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -685,54 +685,12 @@ static int pdev_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int omap_drm_suspend_all_displays(struct drm_device *ddev)
-{
-   struct omap_drm_private *priv = ddev->dev_private;
-   int i;
-
-   for (i = 0; i < priv->num_pipes; i++) {
-   struct omap_dss_device *display = priv->pipes[i].display;
-
-   if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
-   display->ops->disable(display);
-   display->activate_after_resume = true;
-   } else {
-   display->activate_after_resume = false;
-   }
-   }
-
-   return 0;
-}
-
-static int omap_drm_resume_all_displays(struct drm_device *ddev)
-{
-   struct omap_drm_private *priv = ddev->dev_private;
-   int i;
-
-   for (i = 0; i < priv->num_pipes; i++) {
-   struct omap_dss_device *display = priv->pipes[i].display;
-
-   if (display->activate_after_resume) {
-   display->ops->enable(display);
-   display->activate_after_resume = false;
-   }
-   }
-
-   return 0;
-}
-
 static int omap_drm_suspend(struct device *dev)
 {
struct omap_drm_private *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = priv->ddev;
 
-   drm_kms_helper_poll_disable(drm_dev);
-
-   drm_modeset_lock_all(drm_dev);
-   omap_drm_suspend_all_displays(drm_dev);
-   drm_modeset_unlock_all(drm_dev);
-
-   return 0;
+   return drm_mode_config_helper_suspend(drm_dev);
 }
 
 static int omap_drm_resume(struct device *dev)
@@ -740,11 +698,7 @@ static int omap_drm_resume(struct device *dev)
struct omap_drm_private *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = priv->ddev;
 
-   drm_modeset_lock_all(drm_dev);
-   omap_drm_resume_all_displays(drm_dev);
-   drm_modeset_unlock_all(drm_dev);
-
-   drm_kms_helper_poll_enable(drm_dev);
+   drm_mode_config_helper_resume(drm_dev);
 
return omap_gem_resume(drm_dev);
 }
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 02/49] drm/omap: dsi: Fix crash in DSI debug dumps

2019-01-10 Thread Laurent Pinchart
From: Tomi Valkeinen 

Reading any of the DSI debugfs files results in a crash, as wrong
pointer is passed to the dump functions, and the dump functions use a
wrong pointer. This patch fixes DSI debug dumps.

Fixes: f3ed97f9ae7d ("drm/omap: dsi: Simplify debugfs implementation")
Signed-off-by: Tomi Valkeinen 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 00a9c2ab9e6c..277f9dd2ec8c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -1406,7 +1406,7 @@ static void dsi_pll_disable(struct dss_pll *pll)
 
 static int dsi_dump_dsi_clocks(struct seq_file *s, void *p)
 {
-   struct dsi_data *dsi = p;
+   struct dsi_data *dsi = s->private;
struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
enum dss_clk_source dispc_clk_src, dsi_clk_src;
int dsi_module = dsi->module_id;
@@ -1467,7 +1467,7 @@ static int dsi_dump_dsi_clocks(struct seq_file *s, void 
*p)
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
 {
-   struct dsi_data *dsi = p;
+   struct dsi_data *dsi = s->private;
unsigned long flags;
struct dsi_irq_stats stats;
 
@@ -1558,7 +1558,7 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p)
 
 static int dsi_dump_dsi_regs(struct seq_file *s, void *p)
 {
-   struct dsi_data *dsi = p;
+   struct dsi_data *dsi = s->private;
 
if (dsi_runtime_get(dsi))
return 0;
@@ -5083,15 +5083,15 @@ static int dsi_bind(struct device *dev, struct device 
*master, void *data)
 
snprintf(name, sizeof(name), "dsi%u_regs", dsi->module_id + 1);
dsi->debugfs.regs = dss_debugfs_create_file(dss, name,
-   dsi_dump_dsi_regs, &dsi);
+   dsi_dump_dsi_regs, dsi);
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
snprintf(name, sizeof(name), "dsi%u_irqs", dsi->module_id + 1);
dsi->debugfs.irqs = dss_debugfs_create_file(dss, name,
-   dsi_dump_dsi_irqs, &dsi);
+   dsi_dump_dsi_irqs, dsi);
 #endif
snprintf(name, sizeof(name), "dsi%u_clks", dsi->module_id + 1);
dsi->debugfs.clks = dss_debugfs_create_file(dss, name,
-   dsi_dump_dsi_clocks, &dsi);
+   dsi_dump_dsi_clocks, dsi);
 
return 0;
 }
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 13/49] drm/omap: Reverse direction of the DSS device enable/disable operations

2019-01-10 Thread Laurent Pinchart
The omapdrm and omapdss drivers are architectured based on display
pipelines made of multiple components handled from sink (display) to
source (DSS output). This is incompatible with the DRM bridge and panel
APIs that handle components from source to sink.

Reconcile the omapdrm and omapdss drivers with the DRM bridge and panel
model by reversing the direction of the DSS device .enable() and
.disable() operations. This completes the move to the DRM bridge model,
with the notable exception of the DSI pipelines that will require more
work.

We also adapt the omapdss shutdown handler dss_shutdown() to shut down
all active pipelines starting from the pipeline output device instead of
the display device.

As a consequence the for_each_dss_display() macro isn't used and can be
removed, and the omapdss_device_get_next() function underlying the macro
can be simplified to search for output devices only.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
Changes since v1:

- Shutdown pipelines starting at the output device
---
 .../omapdrm/displays/connector-analog-tv.c| 21 --
 .../gpu/drm/omapdrm/displays/connector-dvi.c  | 21 --
 .../gpu/drm/omapdrm/displays/connector-hdmi.c | 21 --
 .../gpu/drm/omapdrm/displays/encoder-opa362.c | 25 +--
 .../gpu/drm/omapdrm/displays/encoder-tfp410.c | 21 +-
 .../drm/omapdrm/displays/encoder-tpd12s015.c  | 35 -
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c  | 18 +
 .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 22 ++
 .../displays/panel-lgphilips-lb035q02.c   | 16 +---
 .../omapdrm/displays/panel-nec-nl8048hl11.c   | 16 +---
 .../displays/panel-sharp-ls037v7dw01.c| 32 
 .../omapdrm/displays/panel-sony-acx565akm.c   | 18 +
 .../omapdrm/displays/panel-tpo-td028ttec1.c   | 25 ++-
 .../omapdrm/displays/panel-tpo-td043mtea1.c   | 17 +
 drivers/gpu/drm/omapdrm/dss/base.c| 73 +++
 drivers/gpu/drm/omapdrm/dss/dpi.c |  5 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c |  7 +-
 drivers/gpu/drm/omapdrm/dss/dss.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   | 12 +--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   | 12 +--
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 20 +++--
 drivers/gpu/drm/omapdrm/dss/sdi.c |  8 +-
 drivers/gpu/drm/omapdrm/dss/venc.c| 12 +--
 drivers/gpu/drm/omapdrm/omap_encoder.c| 49 ++---
 24 files changed, 171 insertions(+), 337 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 2b5b77627cfb..1503563117f3 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -35,26 +35,9 @@ static void tvc_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int tvc_enable(struct omap_dss_device *dssdev)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->enable(src);
-}
-
-static void tvc_disable(struct omap_dss_device *dssdev)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   src->ops->disable(src);
-}
-
 static const struct omap_dss_device_ops tvc_ops = {
.connect= tvc_connect,
.disconnect = tvc_disconnect,
-
-   .enable = tvc_enable,
-   .disable= tvc_disable,
 };
 
 static int tvc_probe(struct platform_device *pdev)
@@ -85,13 +68,9 @@ static int tvc_probe(struct platform_device *pdev)
 static int __exit tvc_remove(struct platform_device *pdev)
 {
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct omap_dss_device *dssdev = &ddata->dssdev;
 
omapdss_device_unregister(&ddata->dssdev);
 
-   if (omapdss_device_is_enabled(dssdev))
-   tvc_disable(dssdev);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index a1784e263835..bf5ee50ce5fe 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -46,20 +46,6 @@ static void dvic_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int dvic_enable(struct omap_dss_device *dssdev)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->enable(src);
-}
-
-static void dvic_disable(struct omap_dss_device *dssdev)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   src->ops->disable(src);
-}
-
 static int dvic_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
 {
@@ -163,9 +149,6 @@ static const struct omap_dss_device_ops dvic_ops = {
.connect= dvic_connect,
.disconnect = dvic_disconnect,
 
-   .enable = dvic_enable,
-   .disable= dvic_disable,
-
.read_edid  = dvic_read_edid,
 

[PATCH v2 14/49] drm/omap: Remove omap_dss_device dst field

2019-01-10 Thread Laurent Pinchart
The field is only used in a safety check during device
connection/disconnection, where the src field can be easily used
instead. Remove it and use src.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 6 ++
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 -
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 916225d62cc2..76470ba45660 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -199,9 +199,8 @@ int omapdss_device_connect(struct dss_device *dss,
}
 
if (src) {
-   WARN_ON(src->dst);
+   WARN_ON(dst->src);
dst->src = src;
-   src->dst = dst;
}
 
return 0;
@@ -219,11 +218,10 @@ void omapdss_device_disconnect(struct omap_dss_device 
*src,
}
 
if (src) {
-   if (WARN_ON(dst != src->dst))
+   if (WARN_ON(dst->src != src))
return;
 
dst->src = NULL;
-   src->dst = NULL;
}
 
WARN_ON(dst->state != OMAP_DSS_DISPLAY_DISABLED);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 4cd3874228a5..fc82b8f545ae 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -406,7 +406,6 @@ struct omap_dss_device {
 
struct dss_device *dss;
struct omap_dss_device *src;
-   struct omap_dss_device *dst;
struct omap_dss_device *next;
 
struct list_head list;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 15/49] drm/omap: Factor out common init/cleanup code for output devices

2019-01-10 Thread Laurent Pinchart
All the internal encoders share common init and cleanup code. Factor it
out to separate functions.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 17 +++--
 drivers/gpu/drm/omapdrm/dss/dsi.c | 17 +++--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   | 17 +++--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   | 17 +++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 ++-
 drivers/gpu/drm/omapdrm/dss/output.c  | 18 --
 drivers/gpu/drm/omapdrm/dss/sdi.c | 17 +++--
 drivers/gpu/drm/omapdrm/dss/venc.c| 17 +++--
 8 files changed, 36 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 74e841a2b4eb..0db01cadf09f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -641,19 +641,9 @@ static int dpi_init_output_port(struct dpi_data *dpi, 
struct device_node *port)
out->ops = &dpi_ops;
out->owner = THIS_MODULE;
 
-   out->next = omapdss_of_find_connected_device(out->dev->of_node, 0);
-   if (IS_ERR(out->next)) {
-   if (PTR_ERR(out->next) != -EPROBE_DEFER)
-   dev_err(out->dev, "failed to find video sink\n");
-   return PTR_ERR(out->next);
-   }
-
-   r = omapdss_output_validate(out);
-   if (r) {
-   omapdss_device_put(out->next);
-   out->next = NULL;
+   r = omapdss_device_init_output(out);
+   if (r < 0)
return r;
-   }
 
omapdss_device_register(out);
 
@@ -665,9 +655,8 @@ static void dpi_uninit_output_port(struct device_node *port)
struct dpi_data *dpi = port->data;
struct omap_dss_device *out = &dpi->output;
 
-   if (out->next)
-   omapdss_device_put(out->next);
omapdss_device_unregister(out);
+   omapdss_device_cleanup_output(out);
 }
 
 static const struct soc_device_attribute dpi_soc_devices[] = {
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 4dad2bf6b551..4ac325e664b5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5131,19 +5131,9 @@ static int dsi_init_output(struct dsi_data *dsi)
   | DRM_BUS_FLAG_DE_HIGH
   | DRM_BUS_FLAG_SYNC_NEGEDGE;
 
-   out->next = omapdss_of_find_connected_device(out->dev->of_node, 0);
-   if (IS_ERR(out->next)) {
-   if (PTR_ERR(out->next) != -EPROBE_DEFER)
-   dev_err(out->dev, "failed to find video sink\n");
-   return PTR_ERR(out->next);
-   }
-
-   r = omapdss_output_validate(out);
-   if (r) {
-   omapdss_device_put(out->next);
-   out->next = NULL;
+   r = omapdss_device_init_output(out);
+   if (r < 0)
return r;
-   }
 
omapdss_device_register(out);
 
@@ -5154,9 +5144,8 @@ static void dsi_uninit_output(struct dsi_data *dsi)
 {
struct omap_dss_device *out = &dsi->output;
 
-   if (out->next)
-   omapdss_device_put(out->next);
omapdss_device_unregister(out);
+   omapdss_device_cleanup_output(out);
 }
 
 static int dsi_probe_of(struct dsi_data *dsi)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 6f88fb4d6344..60792981a33f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -687,19 +687,9 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi)
out->of_ports = BIT(0);
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 
-   out->next = omapdss_of_find_connected_device(out->dev->of_node, 0);
-   if (IS_ERR(out->next)) {
-   if (PTR_ERR(out->next) != -EPROBE_DEFER)
-   dev_err(out->dev, "failed to find video sink\n");
-   return PTR_ERR(out->next);
-   }
-
-   r = omapdss_output_validate(out);
-   if (r) {
-   omapdss_device_put(out->next);
-   out->next = NULL;
+   r = omapdss_device_init_output(out);
+   if (r < 0)
return r;
-   }
 
omapdss_device_register(out);
 
@@ -710,9 +700,8 @@ static void hdmi4_uninit_output(struct omap_hdmi *hdmi)
 {
struct omap_dss_device *out = &hdmi->output;
 
-   if (out->next)
-   omapdss_device_put(out->next);
omapdss_device_unregister(out);
+   omapdss_device_cleanup_output(out);
 }
 
 static int hdmi4_probe_of(struct omap_hdmi *hdmi)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 28cf1c32b158..d7d33b4d2bed 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -671,19 +671,9 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
out->of_ports = BIT(0);
out->ops

[PATCH v2 05/49] drm/omap: Remove declaration of nonexisting function

2019-01-10 Thread Laurent Pinchart
The omap_connector_attached_encoder() doesn't exist anymore, remove its
declaration from omap_connector.h.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h 
b/drivers/gpu/drm/omapdrm/omap_connector.h
index 854099801649..4a1dcd0f031b 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.h
+++ b/drivers/gpu/drm/omapdrm/omap_connector.h
@@ -31,8 +31,6 @@ struct drm_connector *omap_connector_init(struct drm_device 
*dev,
  struct omap_dss_device *output,
  struct omap_dss_device *display,
  struct drm_encoder *encoder);
-struct drm_encoder *omap_connector_attached_encoder(
-   struct drm_connector *connector);
 bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
 void omap_connector_enable_hpd(struct drm_connector *connector);
 void omap_connector_disable_hpd(struct drm_connector *connector);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 19/49] drm/omap: venc: List both PAL and NTSC modes

2019-01-10 Thread Laurent Pinchart
The TV encoder supports both PAL and NTSC modes, but when queried for
the list of modes it supports, only the currently selected mode is
reported. Fix it and report the two modes unconditionally.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
Tested-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index f1abb4195a76..638cfd69ccf6 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -551,14 +551,27 @@ static void venc_display_disable(struct omap_dss_device 
*dssdev)
 static int venc_get_modes(struct omap_dss_device *dssdev,
  struct drm_connector *connector)
 {
-   struct venc_device *venc = dssdev_to_venc(dssdev);
-   int r;
+   static const struct videomode *modes[] = {
+   &omap_dss_pal_vm,
+   &omap_dss_ntsc_vm,
+   };
+   unsigned int i;
 
-   mutex_lock(&venc->venc_lock);
-   r = omapdss_display_get_modes(connector, &venc->vm);
-   mutex_unlock(&venc->venc_lock);
+   for (i = 0; i < ARRAY_SIZE(modes); ++i) {
+   struct drm_display_mode *mode;
 
-   return r;
+   mode = drm_mode_create(connector->dev);
+   if (!mode)
+   return i;
+
+   drm_display_mode_from_videomode(modes[i], mode);
+
+   mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+   drm_mode_set_name(mode);
+   drm_mode_probed_add(connector, mode);
+   }
+
+   return ARRAY_SIZE(modes);
 }
 
 static void venc_set_timings(struct omap_dss_device *dssdev,
-- 
Regards,

Laurent Pinchart

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


Re: Re: [PATCH] drm/mediatek: Add MTK Framebuffer-Device (mt7623)

2019-01-10 Thread CK Hu
Hi, Daniel:

On Thu, 2019-01-10 at 21:02 +0100, Daniel Vetter wrote:
> On Thu, Jan 10, 2019 at 08:01:37PM +0100, Frank Wunderlich wrote:
> > Hi Daniel,
> > 
> > > > Would be good to use the new generic fbdev emulation code here, for even
> > > > less code. Or at least know why this isn't possible to use for mtk (and
> > > > maybe address that in the core code). Hand-rolling fbdev code shouldn't 
> > > > be
> > > > needed anymore.
> > > 
> > > Back on the mailing list, no private replies please:
> > 
> > i don't wanted to spam all people with dumb questions ;)
> 
> There's no dumb questions, only insufficient documentation :-)
> 
> > > For examples please grep for drm_fbdev_generic_setup(). There's also a
> > > still in-flight series from Gerd Hoffmann to convert over bochs. That,
> > > plus all the kerneldoc linked from there should get you started.
> > > -Daniel
> > 
> > this is one of google best founds if i search for drm_fbdev_generic_setup:
> > 
> > https://lkml.org/lkml/2018/12/19/305
> > 
> > not very helpful...
> > 
> > so i tried kernel-doc
> > 
> > https://www.kernel.org/doc/html/latest/gpu/drm-kms-helpers.html?highlight=drm_fbdev_generic_setup#c.drm_fbdev_generic_setup
> > 
> > which is nice function-reference but i've found no generic workflow
> > 
> > as the posted driver is "only" a driver ported from kernel 4.4 by 
> > Alexander, i don't know if this new framework can be used and which parts 
> > need to be changed. I only try to bring his code Mainline
> > Maybe CK Hu can help here because driver is originally from him and he 
> > knows internals. Or maybe you can help here?
> > 
> > i personally make my first steps as spare-time kernel-developer :)
> 
> There's a ton of in-kernel users of that function already, I meant you can
> use those to serve as examples ... If those + the kerneldoc aren't
> good enough, then we need to improve them.
> -Daniel

I've tried with drm_fbdev_generic_setup() and it works fine with simple
modification. The patch is

--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -379,6 +380,7 @@ static void mtk_drm_kms_deinit(struct drm_device
*drm)
.gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
+   .gem_prime_vmap = mtk_drm_gem_prime_vmap,
.ioctls = mtk_ioctls,
.num_ioctls = ARRAY_SIZE(mtk_ioctls),
.fops = &mtk_drm_fops,
@@ -416,6 +418,8 @@ static int mtk_drm_bind(struct device *dev)
if (ret < 0)
goto err_deinit;

+   drm_fbdev_generic_setup(drm, 32);
+
return 0;


But I implement .gem_prime_vmap with a workaround,


--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -280,3 +280,8 @@ int mtk_gem_create_ioctl(struct drm_device *dev,
void *data,
mtk_drm_gem_free_object(&mtk_gem->base);
return ret;
 }
+
+void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj)
+{
+   return (void *)1;
+}

Current drm_fb_helper depends on drm_client to create fbdev. When
drm_client create drm_client_buffer, it need to vmap to get kernel
vaddr. But I think for fbdev, the vaddr is useless. Do you agree that I
temporarily implement .gem_prime_vmap in such way?

Regards,
CK


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


[Bug 109298] AMDGPU leaving DRI2 enabled causes white artifacting

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109298

Bug ID: 109298
   Summary: AMDGPU leaving DRI2 enabled causes white artifacting
   Product: DRI
   Version: XOrg git
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: DRM/AMDgpu
  Assignee: dri-devel@lists.freedesktop.org
  Reporter: tkdestroyer2+bugs-freedesk...@gmail.com

I am running:
Solus OS
Linux kernel 4.18.5
xorg-driver-video-amdgpu 18.1.0
xinit 1.4.0
xorg-server 1.20.3
VG248QE DisplayPort 1080@144

$ cat /sys/class/drm/card1/device/vbios_version
MS-V30823-F5

I have an MSI R9 390, one of the bugged ones. I can boot successfully using
cik_support=1 dpm=1 and dc=1.

The bug I am encountering is the following:

- Use default Xorg configuration
- Encounter white rectangles where there should be rendered content
  ex: Desktop background is between 6 and 9 tenths white starting from the top
going down. Only the rest of the bottom strip is showing.
  ex: Firefox shows white rectangles of white pixels where there should be
content. They vary in size and position and tend to show up after recent
renderings. Can be 'wiped' away using the mouse-highlight.

I have managed to reduce the impact of this bug by switching off DRI2 by
setting xorg configuration option AccelMethod to none. No other configuration
of options (as they appear in the manpages for amdgpu) will work in removing
these issues. This lets me utilize accelerated 3D graphics until I can get DRI2
up and running again.

It may be important to note that some applications will work, particularly when
they are small windows, like when first opening a PDF. Scrolling and everything
works normally, but when one maximizes the window to 1080p, the artifacts
appear. One application that worked is MineTest, which appears to be using 2D
rendering (poor performance with DRI2 off).

-- 
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


[git pull] drm fixes for 5.0-rc2

2019-01-10 Thread Dave Airlie
Hi Linus,

Not a huge amount for rc2, assume the usual quiet period, and rc3 will
be most of it.

amdgpu:
- Powerplay fixes
- Virtual display pinning fixes
- Golden register updates for Vega
- Pitch and gem size validation fixes
- SR-IOV init error fix
- Pagetables in system RAM disable for some Raven system
- DP-MST resume fixes

tc358767 bridge:
- fix to work with displayport connector.

Dave.

drm-fixes-2019-01-11:
drm: amdgpu + tc358767 bridge + amd mst s/r fix
The following changes since commit bfeffd155283772bbe78c6a05dec7c0128ee500c:

  Linux 5.0-rc1 (2019-01-06 17:08:20 -0800)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2019-01-11

for you to fetch changes up to f34c48e06ddcc197f2cf7cbc006ceb74e28e1ccf:

  Merge branch 'drm-fixes-5.0' of
git://people.freedesktop.org/~agd5f/linux into drm-fixes (2019-01-11
07:38:56 +1000)


drm: amdgpu + tc358767 bridge + amd mst s/r fix


Christian König (1):
  drm/amdgpu: disable system memory page tables for now

Dave Airlie (2):
  Merge tag 'drm-misc-fixes-2019-01-10' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
  Merge branch 'drm-fixes-5.0' of
git://people.freedesktop.org/~agd5f/linux into drm-fixes

Emily Deng (3):
  drm/amdgpu/virtual_dce: No need to pin the fb's bo
  drm/amdgpu/virtual_dce: No need to pin the cursor bo
  drm/amdgpu/sriov:Correct pfvf exchange logic

Evan Quan (5):
  drm/amd/powerplay: support BOOTUP_DEFAULT power profile mode
  drm/amd/powerplay: update OD support flag for SKU with no OD capabilities
  drm/amd/powerplay: create pp_od_clk_voltage device file under OD support
  drm/amd/powerplay: avoid possible buffer overflow
  drm/amd/powerplay: drop the unnecessary uclk hard min setting

Jim Qu (1):
  drm/amdgpu: set WRITE_BURST_LENGTH to 64B to workaround SDMA1 hang

Kent Russell (1):
  drm/amdgpu: Cleanup 2 compiler warnings

Likun Gao (1):
  drm/amdgpu: make gfx9 enter into rlc safe mode when set MGCG

Lyude Paul (3):
  drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume()
  drm/amdgpu: Don't fail resume process if resuming atomic state fails
  drm/dp_mst: Add __must_check to drm_dp_mst_topology_mgr_resume()

Tao Zhou (1):
  drm/amdgpu: fix CPDMA hang in PRT mode for VEGA20

Tiecheng Zhou (1):
  drm/amdgpu/gfx_v8_0: Reorder the gfx, kiq and kcq rings test sequence

Tomi Valkeinen (7):
  drm/bridge: tc358767: add bus flags
  drm/bridge: tc358767: add defines for DP1_SRCCTRL & PHY_2LANE
  drm/bridge: tc358767: fix single lane configuration
  drm/bridge: tc358767: fix initial DP0/1_SRCCTRL value
  drm/bridge: tc358767: reject modes which require too much BW
  drm/bridge: tc358767: fix output H/V syncs
  drm/bridge: tc358767: use DP connector if no panel set

Yu Zhao (2):
  drm/amdgpu: validate user pitch alignment
  drm/amdgpu: validate user GEM object size

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c| 38 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 22 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c |  3 --
 drivers/gpu/drm/amd/amdgpu/dce_virtual.c   | 17 ++--
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c  | 48 +++---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c  | 14 ---
 drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c |  3 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 37 +++--
 drivers/gpu/drm/amd/include/kgd_pp_interface.h | 13 +++---
 drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c| 24 ++-
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c   |  8 ++--
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 12 +++---
 drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 34 ++-
 drivers/gpu/drm/amd/powerplay/inc/hwmgr.h  |  2 +-
 drivers/gpu/drm/bridge/tc358767.c  | 48 +-
 include/drm/drm_dp_mst_helper.h|  3 +-
 18 files changed, 221 insertions(+), 119 deletions(-)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 0/6] omapdrm: drm_bridge and drm_panel support

2019-01-10 Thread Laurent Pinchart
Hi Sebastian,

On Thursday, 20 December 2018 14:17:27 EET Sebastian Reichel wrote:
> Hi,
> 
> On Mon, Dec 10, 2018 at 03:06:17AM +0200, Laurent Pinchart wrote:
> > This patch series hooks up support for drm_bridge and drm_panel in the
> > omapdrm driver.
> > 
> > [...]
> 
> The series is
> 
> Reviewed-by: Sebastian Reichel 
> 
> At the same time it is tested to break display on Droid 4. I don't
> know the exact reason yet. Debugging this is annoyingly hard, since
> the patches for manual display update still have not been merged
> making the testing process cumbersome.

Is it this series that breaks display on Droid 4, or was it broken already ? 
I've pushed all pending omapdrm patches to

git://linuxtv.org/pinchartl/media.git omapdrm/bridge/next

with the three fixes from Tomi at the bottom of the branch, and this series at 
the top.

I think the omapdrm/dss drivers are now in a shape that can let us consider 
upstreaming DSI support. The real challenge will be to do so in a way 
compatible with drm_bridge and drm_panel.

-- 
Regards,

Laurent Pinchart



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


Re: Aw: Re: [PATCH] drm/mediatek: Add MTK Framebuffer-Device (mt7623)

2019-01-10 Thread CK Hu
Hi, Frank:

On Thu, 2019-01-10 at 20:01 +0100, Frank Wunderlich wrote:
> Hi Daniel,
> 
> > > Would be good to use the new generic fbdev emulation code here, for even
> > > less code. Or at least know why this isn't possible to use for mtk (and
> > > maybe address that in the core code). Hand-rolling fbdev code shouldn't be
> > > needed anymore.
> > 
> > Back on the mailing list, no private replies please:
> 
> i don't wanted to spam all people with dumb questions ;)
> 
> > For examples please grep for drm_fbdev_generic_setup(). There's also a
> > still in-flight series from Gerd Hoffmann to convert over bochs. That,
> > plus all the kerneldoc linked from there should get you started.
> > -Daniel
> 
> this is one of google best founds if i search for drm_fbdev_generic_setup:
> 
> https://lkml.org/lkml/2018/12/19/305
> 
> not very helpful...
> 
> so i tried kernel-doc
> 
> https://www.kernel.org/doc/html/latest/gpu/drm-kms-helpers.html?highlight=drm_fbdev_generic_setup#c.drm_fbdev_generic_setup
> 
> which is nice function-reference but i've found no generic workflow
> 
> as the posted driver is "only" a driver ported from kernel 4.4 by Alexander, 
> i don't know if this new framework can be used and which parts need to be 
> changed. I only try to bring his code Mainline
> Maybe CK Hu can help here because driver is originally from him and he knows 
> internals. Or maybe you can help here?

I could help on this but I'm a little busy now, so I'm not sure how long
this process takes.

Regards,
CK

> 
> i personally make my first steps as spare-time kernel-developer :)
> 
> regards Frank
> 
> ___
> Linux-mediatek mailing list
> linux-media...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


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


[Bug 109135] R9 390 hangs at boot with DPM/DC enabled for kernels 4.19.x and above, says KMS not supported

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109135

--- Comment #8 from rmuncr...@humanavance.com ---
(In reply to Alex Deucher from comment #7)
> Can you bisect to figure out what commit broke things for you?

Actually I remember doing that many years ago when I was a maintainer for Steam
under wine. I'll look and see if I can find a current bisect tutorial and give
it a try. Any links or tips you can give to help give me a quick start would be
appreciated. I do remember it can take many days, which I'm willing to invest
as I said. However the fewer days the better! :)

-- 
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


[Bug 109135] R9 390 hangs at boot with DPM/DC enabled for kernels 4.19.x and above, says KMS not supported

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109135

--- Comment #7 from Alex Deucher  ---
Can you bisect to figure out what commit broke things for you?

-- 
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 4/4] drm/tinydrm: Use damage helper for dirtyfb

2019-01-10 Thread David Lechner

On 1/9/19 11:49 AM, Noralf Trønnes wrote:

This switches to drm_atomic_helper_dirtyfb() as the framebuffer dirty
handler. All flushing will now happen in the pipe functions.

Also enable the damage plane property for all except repaper which can
only do full updates.

ili9225:
This change made ili9225_init() equal to mipi_dbi_init() so use it.

Cc: David Lechner 
Cc: Eric Anholt 
Signed-off-by: Noralf Trønnes 
---


...


+static void ili9225_pipe_update(struct drm_simple_display_pipe *pipe,
+   struct drm_plane_state *old_state)
+{
+   struct drm_plane_state *state = pipe->plane.state;
+   struct drm_crtc *crtc = &pipe->crtc;
+   struct drm_rect rect;
+
+   if (drm_atomic_helper_damage_merged(old_state, state, &rect))
+   ili9225_fb_dirty(state->fb, &rect);
+
+   if (crtc->state->event) {
+   spin_lock_irq(&crtc->dev->event_lock);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   spin_unlock_irq(&crtc->dev->event_lock);
+   crtc->state->event = NULL;
+   }
+}


It looks like this function body is repeated 4 times with the only
difference being the dirty function. Perhaps a helper function is
called for?

Also, I was going to test out this series the displays that I have,
but I guess I will wait until it is easier to apply the patches.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 18/20] drm/dp_mst: Start tracking per-port VCPI allocations

2019-01-10 Thread Lyude Paul
There has been a TODO waiting for quite a long time in
drm_dp_mst_topology.c:

/* We cannot rely on port->vcpi.num_slots to update
 * topology_state->avail_slots as the port may not exist if the parent
 * branch device was unplugged. This should be fixed by tracking
 * per-port slot allocation in drm_dp_mst_topology_state instead of
 * depending on the caller to tell us how many slots to release.
 */

That's not the only reason we should fix this: forcing the driver to
track the VCPI allocations throughout a state's atomic check is
error prone, because it means that extra care has to be taken with the
order that drm_dp_atomic_find_vcpi_slots() and
drm_dp_atomic_release_vcpi_slots() are called in in order to ensure
idempotency. Currently the only driver actually using these helpers,
i915, doesn't even do this correctly: multiple ->best_encoder() checks
with i915's current implementation would not be idempotent and would
over-allocate VCPI slots, something I learned trying to implement
fallback retraining in MST.

So: simplify this whole mess, and teach drm_dp_atomic_find_vcpi_slots()
and drm_dp_atomic_release_vcpi_slots() to track the VCPI allocations for
each port. This allows us to ensure idempotency without having to rely
on the driver as much. Additionally: the driver doesn't need to do any
kind of VCPI slot tracking anymore if it doesn't need it for it's own
internal state.

Additionally; this adds a new drm_dp_mst_atomic_check() helper which
must be used by atomic drivers to perform validity checks for the new
VCPI allocations incurred by a state.

Also: update the documentation and make it more obvious that these
/must/ be called by /all/ atomic drivers supporting MST.

Changes since v9:
* Add some missing changes that were requested by danvet that I forgot
  about after I redid all of the kref stuff:
  * Remove unnecessary state changes in intel_dp_mst_atomic_check
  * Cleanup atomic check logic for VCPI allocations - all we need to check in
compute_config is whether or not this state disables a CRTC, then free
VCPI based off that

Changes since v8:
 * Fix compile errors, whoops!

Changes since v7:
 - Don't check for mixed stale/valid VCPI allocations, just rely on
 connector registration to stop such erroneous modesets

Changes since v6:
 - Keep a kref to all of the ports we have allocations on. This required
   a good bit of changing to when we call drm_dp_find_vcpi_slots(),
   mainly that we need to ensure that we only redo VCPI allocations on
   actual mode or CRTC changes, not crtc_state->active changes.
   Additionally, we no longer take the registration of the DRM connector
   for each port into account because so long as we have a kref to the
   port in the new or previous atomic state, the connector will stay
   registered.
 - Use the small changes to drm_dp_put_port() to add even more error
   checking to make misusage of the helpers more obvious. I added this
   after having to chase down various use-after-free conditions that
   started popping up from the new helpers so no one else has to
   troubleshoot that.
 - Move some accidental DRM_DEBUG_KMS() calls to DRM_DEBUG_ATOMIC()
 - Update documentation again, note that find/release() should both not be
   called on the same port in a single atomic check phase (but multiple
   calls to one or the other is OK)

Changes since v4:
 - Don't skip the atomic checks for VCPI allocations if no new VCPI
   allocations happen in a state. This makes the next change I'm about
   to list here a lot easier to implement.
 - Don't ignore VCPI allocations on destroyed ports, instead ensure that
   when ports are destroyed and still have VCPI allocations in the
   topology state, the only state changes allowed are releasing said
   ports' VCPI. This prevents a state with a mix of VCPI allocations
   from destroyed ports, and allocations from valid ports.

Changes since v3:
 - Don't release VCPI allocations in the topology state immediately in
   drm_dp_atomic_release_vcpi_slots(), instead mark them as 0 and skip
   over them in drm_dp_mst_duplicate_state(). This makes it so
   drm_dp_atomic_release_vcpi_slots() is still idempotent while also
   throwing warnings if the driver messes up it's book keeping and tries
   to release VCPI slots on a port that doesn't have any pre-existing
   VCPI allocation - danvet
 - Change mst_state/state in some debugging messages to "mst state"

Changes since v2:
 - Use kmemdup() for duplicating MST state - danvet
 - Move port validation out of duplicate state callback - danvet
 - Handle looping through MST topology states in
   drm_dp_mst_atomic_check() so the driver doesn't have to do it
 - Fix documentation in drm_dp_atomic_find_vcpi_slots()
 - Move the atomic check for each individual topology state into it's
   own function, reduces indenting
 - Don't consider "stale" MST ports when calculating the bandwidth
   requirements. This is needed because originally we reli

[PATCH v7 17/20] drm/dp_mst: Add some atomic state iterator macros

2019-01-10 Thread Lyude Paul
Changes since v6:
 - Move EXPORT_SYMBOL() for drm_dp_mst_topology_state_funcs to this
   commit
 - Document __drm_dp_mst_state_iter_get() and note that it shouldn't be
   called directly

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c |  5 +-
 include/drm/drm_dp_mst_helper.h   | 96 +++
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index b5976f8c318c..e3497bc49494 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3521,10 +3521,11 @@ static void drm_dp_mst_destroy_state(struct 
drm_private_obj *obj,
kfree(mst_state);
 }
 
-static const struct drm_private_state_funcs mst_state_funcs = {
+const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {
.atomic_duplicate_state = drm_dp_mst_duplicate_state,
.atomic_destroy_state = drm_dp_mst_destroy_state,
 };
+EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs);
 
 /**
  * drm_atomic_get_mst_topology_state: get MST topology state
@@ -3608,7 +3609,7 @@ int drm_dp_mst_topology_mgr_init(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_atomic_private_obj_init(dev, &mgr->base,
&mst_state->base,
-   &mst_state_funcs);
+   &drm_dp_mst_topology_state_funcs);
 
return 0;
 }
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 70ec452f2a47..fa533571b16c 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -651,4 +651,100 @@ int drm_dp_send_power_updown_phy(struct 
drm_dp_mst_topology_mgr *mgr,
 void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
 void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);
 
+extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs;
+
+/**
+ * __drm_dp_mst_state_iter_get - private atomic state iterator function for
+ * macro-internal use
+ * @state: &struct drm_atomic_state pointer
+ * @mgr: pointer to the &struct drm_dp_mst_topology_mgr iteration cursor
+ * @old_state: optional pointer to the old &struct drm_dp_mst_topology_state
+ * iteration cursor
+ * @new_state: optional pointer to the new &struct drm_dp_mst_topology_state
+ * iteration cursor
+ * @i: int iteration cursor, for macro-internal use
+ *
+ * Used by for_each_oldnew_mst_mgr_in_state(),
+ * for_each_old_mst_mgr_in_state(), and for_each_new_mst_mgr_in_state(). Don't
+ * call this directly.
+ *
+ * Returns:
+ * True if the current &struct drm_private_obj is a &struct
+ * drm_dp_mst_topology_mgr, false otherwise.
+ */
+static inline bool
+__drm_dp_mst_state_iter_get(struct drm_atomic_state *state,
+   struct drm_dp_mst_topology_mgr **mgr,
+   struct drm_dp_mst_topology_state **old_state,
+   struct drm_dp_mst_topology_state **new_state,
+   int i)
+{
+   struct __drm_private_objs_state *objs_state = &state->private_objs[i];
+
+   if (objs_state->ptr->funcs != &drm_dp_mst_topology_state_funcs)
+   return false;
+
+   *mgr = to_dp_mst_topology_mgr(objs_state->ptr);
+   if (old_state)
+   *old_state = to_dp_mst_topology_state(objs_state->old_state);
+   if (new_state)
+   *new_state = to_dp_mst_topology_state(objs_state->new_state);
+
+   return true;
+}
+
+/**
+ * for_each_oldnew_mst_mgr_in_state - iterate over all DP MST topology
+ * managers in an atomic update
+ * @__state: &struct drm_atomic_state pointer
+ * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor
+ * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old
+ * state
+ * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new
+ * state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all DRM DP MST topology managers in an atomic update,
+ * tracking both old and new state. This is useful in places where the state
+ * delta needs to be considered, for example in atomic check functions.
+ */
+#define for_each_oldnew_mst_mgr_in_state(__state, mgr, old_state, new_state, 
__i) \
+   for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
+   for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), 
&(old_state), &(new_state), (__i)))
+
+/**
+ * for_each_old_mst_mgr_in_state - iterate over all DP MST topology managers
+ * in an atomic update
+ * @__state: &struct drm_atomic_state pointer
+ * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor
+ * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old
+ * state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all DRM DP MST topology managers in

[PATCH v7 14/20] drm/nouveau: Keep malloc references to MST ports

2019-01-10 Thread Lyude Paul
Now that we finally have a sane way to keep port allocations around, use
it to fix the potential unchecked ->port accesses that nouveau makes by
making sure we keep the mst port allocated for as long as it's
drm_connector is accessible.

Additionally, now that we've guaranteed that mstc->port is allocated for
as long as we keep mstc around we can remove the connector registration
checks for codepaths which release payloads, allowing us to release
payloads on active topologies properly. These registration checks were
only required before in order to avoid situations where mstc->port could
technically be pointing at freed memory.

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 28538ef19b71..15f378902fcb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -963,7 +963,11 @@ static void
 nv50_mstc_destroy(struct drm_connector *connector)
 {
struct nv50_mstc *mstc = nv50_mstc(connector);
+
drm_connector_cleanup(&mstc->connector);
+   if (mstc->port)
+   drm_dp_mst_put_port_malloc(mstc->port);
+
kfree(mstc);
 }
 
@@ -1011,6 +1015,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct 
drm_dp_mst_port *port,
drm_object_attach_property(&mstc->connector.base, 
dev->mode_config.path_property, 0);
drm_object_attach_property(&mstc->connector.base, 
dev->mode_config.tile_property, 0);
drm_connector_set_path_property(&mstc->connector, path);
+   drm_dp_mst_get_port_malloc(port);
return 0;
 }
 
@@ -1076,6 +1081,7 @@ nv50_mstm_destroy_connector(struct 
drm_dp_mst_topology_mgr *mgr,
drm_fb_helper_remove_one_connector(&drm->fbcon->helper, 
&mstc->connector);
 
drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL);
+   drm_dp_mst_put_port_malloc(mstc->port);
mstc->port = NULL;
drm_modeset_unlock(&drm->dev->mode_config.connection_mutex);
 
-- 
2.20.1

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


[PATCH v7 12/20] drm/nouveau: Remove bogus cleanup in nv50_mstm_add_connector()

2019-01-10 Thread Lyude Paul
Trying to destroy the connector using mstc->connector.funcs->destroy()
if connector initialization fails is wrong: there is no possible
codepath in nv50_mstc_new where nv50_mstm_add_connector() would return
<0 and mstc would be non-NULL.

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index bc06aa79363f..800213be76ea 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1098,11 +1098,8 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr 
*mgr,
int ret;
 
ret = nv50_mstc_new(mstm, port, path, &mstc);
-   if (ret) {
-   if (mstc)
-   mstc->connector.funcs->destroy(&mstc->connector);
+   if (ret)
return NULL;
-   }
 
return &mstc->connector;
 }
-- 
2.20.1

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


[PATCH v7 15/20] drm/nouveau: Stop unsetting mstc->port, use malloc refs

2019-01-10 Thread Lyude Paul
Same as we did for i915, but for nouveau this time. Additionally, we
grab a malloc reference to the port that lasts for the entire lifetime
of nv50_mstc, which gives us the guarantee that mstc->port will always
point to valid memory for as long as the mstc stays around.

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 15f378902fcb..6f8a54e81727 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -708,8 +708,7 @@ nv50_msto_cleanup(struct nv50_msto *msto)
 
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
-   if (mstc->port)
-   drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
+   drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
 
msto->mstc = NULL;
msto->head = NULL;
@@ -734,7 +733,7 @@ nv50_msto_prepare(struct nv50_msto *msto)
};
 
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
-   if (mstc->port && mstc->port->vcpi.vcpi > 0) {
+   if (mstc->port->vcpi.vcpi > 0) {
struct drm_dp_payload *payload = nv50_msto_payload(msto);
if (payload) {
args.vcpi.start_slot = payload->start_slot;
@@ -831,8 +830,7 @@ nv50_msto_disable(struct drm_encoder *encoder)
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
-   if (mstc->port)
-   drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
+   drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
 
mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0);
mstm->modified = true;
@@ -944,7 +942,7 @@ nv50_mstc_detect(struct drm_connector *connector, bool 
force)
enum drm_connector_status conn_status;
int ret;
 
-   if (!mstc->port)
+   if (drm_connector_is_unregistered(connector))
return connector_status_disconnected;
 
ret = pm_runtime_get_sync(connector->dev->dev);
@@ -965,8 +963,7 @@ nv50_mstc_destroy(struct drm_connector *connector)
struct nv50_mstc *mstc = nv50_mstc(connector);
 
drm_connector_cleanup(&mstc->connector);
-   if (mstc->port)
-   drm_dp_mst_put_port_malloc(mstc->port);
+   drm_dp_mst_put_port_malloc(mstc->port);
 
kfree(mstc);
 }
@@ -1080,11 +1077,6 @@ nv50_mstm_destroy_connector(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_fb_helper_remove_one_connector(&drm->fbcon->helper, 
&mstc->connector);
 
-   drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL);
-   drm_dp_mst_put_port_malloc(mstc->port);
-   mstc->port = NULL;
-   drm_modeset_unlock(&drm->dev->mode_config.connection_mutex);
-
drm_connector_put(&mstc->connector);
 }
 
-- 
2.20.1

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


[Bug 109135] R9 390 hangs at boot with DPM/DC enabled for kernels 4.19.x and above, says KMS not supported

2019-01-10 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109135

--- Comment #6 from rmuncr...@humanavance.com ---
(In reply to iive from comment #5)
> (In reply to rmuncrief from comment #2)
> [...]
> > Here's the grub line I use for all testing:
> > GRUB_CMDLINE_LINUX_DEFAULT="quiet
> > resume=UUID=b4f71480-8fe3-43c2-99c9-fc3f5687545b libata.atapi_passthru16=0
> > rd.modules-load=vfio-pci amd_iommu=on iommu=pt amdgpu.modeset=1
> [...]
> 
> Would you try with "iommu=soft", aka disable the hardware one?
> Maybe try tuning it off entirely.

Thank you for looking into this bug. I tried all combinations of
amd_iommu/iommu "soft" and "off", on kernels 4.19.13, 4.20.0, and
linux-mainline from last night. And I tried them all with the BIOS iommu
enabled and disabled, and also leaving and removing iommu=pt.

In all cases the boot failed in the same way, with a black screen and complete
lockup so that even ssh from another terminal would not work. And unfortunately
none of them generated any type of boot log that I could find. In fact if you
delete all the /var/log/Xorg.* log files, and then try booting with the bad
kernels, not even an empty Xorg.*.old log file is generated. The only log that
appears after I finally change back to 4.18.20 is the single Xorg.0.log from
its boot. And of course there's nothing at all in journalctl.

In any case I'm an embedded systems designer, but only have a cursory knowledge
of low level Linux kernel development. However I'm willing to invest whatever
time is necessary to help find this bug. I bought an expensive R9 390 three
years ago and have only been able to fully utilize it for about six months off
and on.

By the way, I'd have no problem sticking with the 4.18 kernel as everything
works great with it, and I've heard that same sentiment from others. It really
seems that for whatever reasons there were systemic errors introduced after it,
and they will take a substantial amount of time to fix. Our only concern is
that 4.18 will soon lose support. So given the unprecedented number of problems
with all later kernels it may be wise to move it to LTS, and give developers
more time to work on the plethora of problems they're dealing with now.

-- 
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 v7 11/20] drm/amdgpu/display: Keep malloc ref to MST port

2019-01-10 Thread Lyude Paul
Just like i915 and nouveau, it's a good idea for us to hold a malloc
reference to the port here so that we never pass a freed pointer to any
of the DP MST helper functions.

Also, we stop unsetting aconnector->port in
dm_dp_destroy_mst_connector(). There's literally no point to that
assignment that I can see anyway.

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e7ca1f3a8d1..24632727e127 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -191,6 +191,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
drm_encoder_cleanup(&amdgpu_encoder->base);
kfree(amdgpu_encoder);
drm_connector_cleanup(connector);
+   drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
kfree(amdgpu_dm_connector);
 }
 
@@ -363,7 +364,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
amdgpu_dm_connector_funcs_reset(connector);
 
DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
+
+   drm_dp_mst_get_port_malloc(port);
 
DRM_DEBUG_KMS(":%d\n", connector->base.id);
 
@@ -379,12 +382,12 @@ static void dm_dp_destroy_mst_connector(struct 
drm_dp_mst_topology_mgr *mgr,
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
 
DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
-   aconnector, connector->base.id, 
aconnector->mst_port);
+aconnector, connector->base.id, aconnector->mst_port);
 
-   aconnector->port = NULL;
if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps(connector, NULL);
-   dc_link_remove_remote_sink(aconnector->dc_link, 
aconnector->dc_sink);
+   dc_link_remove_remote_sink(aconnector->dc_link,
+  aconnector->dc_sink);
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
}
-- 
2.20.1

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


[PATCH v7 16/20] drm/nouveau: Grab payload lock in nv50_msto_payload()

2019-01-10 Thread Lyude Paul
Going through the currently programmed payloads isn't safe without
holding mgr->payload_lock, so actually do that and warn if anyone tries
calling nv50_msto_payload() in the future without grabbing the right
locks.

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 6f8a54e81727..8044ebba56a4 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -679,6 +679,8 @@ nv50_msto_payload(struct nv50_msto *msto)
struct nv50_mstm *mstm = mstc->mstm;
int vcpi = mstc->port->vcpi.vcpi, i;
 
+   WARN_ON(!mutex_is_locked(&mstm->mgr.payload_lock));
+
NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi);
for (i = 0; i < mstm->mgr.max_payloads; i++) {
struct drm_dp_payload *payload = &mstm->mgr.payloads[i];
@@ -732,6 +734,8 @@ nv50_msto_prepare(struct nv50_msto *msto)
   (0x0100 << msto->head->base.index),
};
 
+   mutex_lock(&mstm->mgr.payload_lock);
+
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
if (mstc->port->vcpi.vcpi > 0) {
struct drm_dp_payload *payload = nv50_msto_payload(msto);
@@ -747,7 +751,9 @@ nv50_msto_prepare(struct nv50_msto *msto)
  msto->encoder.name, msto->head->base.base.name,
  args.vcpi.start_slot, args.vcpi.num_slots,
  args.vcpi.pbn, args.vcpi.aligned_pbn);
+
nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args));
+   mutex_unlock(&mstm->mgr.payload_lock);
 }
 
 static int
-- 
2.20.1

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


[PATCH v7 20/20] drm/nouveau: Use atomic VCPI helpers for MST

2019-01-10 Thread Lyude Paul
Currently, nouveau uses the yolo method of setting up MST displays: it
uses the old VCPI helpers (drm_dp_find_vcpi_slots()) for computing the
display configuration. These helpers don't take care to make sure they
take a reference to the mstb port that they're checking, and
additionally don't actually check whether or not the topology still has
enough bandwidth to provide the VCPI tokens required.

So, drop usage of the old helpers and move entirely over to the atomic
helpers.

Changes since v6:
* Cleanup atomic check logic and remove a bunch of unneeded checks -
  danvet
Changes since v5:
* Update nv50_msto_atomic_check() and nv50_mstc_atomic_check() to the
  new requirements for drm_dp_atomic_find_vcpi_slots() and
  drm_dp_atomic_release_vcpi_slots()

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 54 ++---
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 8044ebba56a4..67107f0b1299 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -761,16 +761,23 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_state,
   struct drm_connector_state *conn_state)
 {
-   struct nv50_mstc *mstc = nv50_mstc(conn_state->connector);
+   struct drm_atomic_state *state = crtc_state->state;
+   struct drm_connector *connector = conn_state->connector;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
struct nv50_mstm *mstm = mstc->mstm;
-   int bpp = conn_state->connector->display_info.bpc * 3;
+   int bpp = connector->display_info.bpc * 3;
int slots;
 
-   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp);
+   mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
+bpp);
 
-   slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn);
-   if (slots < 0)
-   return slots;
+   if (drm_atomic_crtc_needs_modeset(crtc_state) &&
+   !drm_connector_is_unregistered(connector)) {
+   slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
+ mstc->port, mstc->pbn);
+   if (slots < 0)
+   return slots;
+   }
 
return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
   mstc->native);
@@ -933,12 +940,43 @@ nv50_mstc_get_modes(struct drm_connector *connector)
return ret;
 }
 
+static int
+nv50_mstc_atomic_check(struct drm_connector *connector,
+  struct drm_connector_state *new_conn_state)
+{
+   struct drm_atomic_state *state = new_conn_state->state;
+   struct nv50_mstc *mstc = nv50_mstc(connector);
+   struct drm_dp_mst_topology_mgr *mgr = &mstc->mstm->mgr;
+   struct drm_connector_state *old_conn_state =
+   drm_atomic_get_old_connector_state(state, connector);
+   struct drm_crtc_state *crtc_state;
+   struct drm_crtc *new_crtc = new_conn_state->crtc;
+
+   if (!old_conn_state->crtc)
+   return 0;
+
+   /* We only want to free VCPI if this state disables the CRTC on this
+* connector
+*/
+   if (new_crtc) {
+   crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
+
+   if (!crtc_state ||
+   !drm_atomic_crtc_needs_modeset(crtc_state) ||
+   crtc_state->enable)
+   return 0;
+   }
+
+   return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port);
+}
+
 static const struct drm_connector_helper_funcs
 nv50_mstc_help = {
.get_modes = nv50_mstc_get_modes,
.mode_valid = nv50_mstc_mode_valid,
.best_encoder = nv50_mstc_best_encoder,
.atomic_best_encoder = nv50_mstc_atomic_best_encoder,
+   .atomic_check = nv50_mstc_atomic_check,
 };
 
 static enum drm_connector_status
@@ -2120,6 +2158,10 @@ nv50_disp_atomic_check(struct drm_device *dev, struct 
drm_atomic_state *state)
return ret;
}
 
+   ret = drm_dp_mst_atomic_check(state);
+   if (ret)
+   return ret;
+
return 0;
 }
 
-- 
2.20.1

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


[PATCH v7 19/20] drm/dp_mst: Check payload count in drm_dp_mst_atomic_check()

2019-01-10 Thread Lyude Paul
It occurred to me that we never actually check this! So let's start
doing that.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 88db6d7e1a36..196ebba8af5f 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3641,7 +3641,7 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
   struct drm_dp_mst_topology_state 
*mst_state)
 {
struct drm_dp_vcpi_allocation *vcpi;
-   int avail_slots = 63;
+   int avail_slots = 63, payload_count = 0;
 
list_for_each_entry(vcpi, &mst_state->vcpis, next) {
/* Releasing VCPI is always OK-even if the port is gone */
@@ -3661,6 +3661,12 @@ drm_dp_mst_atomic_check_topology_state(struct 
drm_dp_mst_topology_mgr *mgr,
 avail_slots + vcpi->vcpi);
return -ENOSPC;
}
+
+   if (++payload_count > mgr->max_payloads) {
+   DRM_DEBUG_ATOMIC("[MST MGR:%p] state %p has too many 
payloads (max=%d)\n",
+mgr, mst_state, mgr->max_payloads);
+   return -EINVAL;
+   }
}
DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
 mgr, mst_state, avail_slots,
-- 
2.20.1

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


[PATCH v7 06/20] drm/dp_mst: Introduce new refcounting scheme for mstbs and ports

2019-01-10 Thread Lyude Paul
The current way of handling refcounting in the DP MST helpers is really
confusing and probably just plain wrong because it's been hacked up many
times over the years without anyone actually going over the code and
seeing if things could be simplified.

To the best of my understanding, the current scheme works like this:
drm_dp_mst_port and drm_dp_mst_branch both have a single refcount. When
this refcount hits 0 for either of the two, they're removed from the
topology state, but not immediately freed. Both ports and branch devices
will reinitialize their kref once it's hit 0 before actually destroying
themselves. The intended purpose behind this is so that we can avoid
problems like not being able to free a remote payload that might still
be active, due to us having removed all of the port/branch device
structures in memory, as per:

commit 91a25e463130 ("drm/dp/mst: deallocate payload on port destruction")

Which may have worked, but then it caused use-after-free errors. Being
new to MST at the time, I tried fixing it;

commit 263efde31f97 ("drm/dp/mst: Get validated port ref in 
drm_dp_update_payload_part1()")

But, that was broken: both drm_dp_mst_port and drm_dp_mst_branch structs
are validated in almost every DP MST helper function. Simply put, this
means we go through the topology and try to see if the given
drm_dp_mst_branch or drm_dp_mst_port is still attached to something
before trying to use it in order to avoid dereferencing freed memory
(something that has happened a LOT in the past with this library).
Because of this it doesn't actually matter whether or not we keep keep
the ports and branches around in memory as that's not enough, because
any function that validates the branches and ports passed to it will
still reject them anyway since they're no longer in the topology
structure. So, use-after-free errors were fixed but payload deallocation
was completely broken.

Two years later, AMD informed me about this issue and I attempted to
come up with a temporary fix, pending a long-overdue cleanup of this
library:

commit c54c7374ff44 ("drm/dp_mst: Skip validating ports during destruction, 
just ref")

But then that introduced use-after-free errors, so I quickly reverted
it:

commit 9765635b3075 ("Revert "drm/dp_mst: Skip validating ports during 
destruction, just ref"")

And in the process, learned that there is just no simple fix for this:
the design is just broken. Unfortunately, the usage of these helpers are
quite broken as well. Some drivers like i915 have been smart enough to
avoid accessing any kind of information from MST port structures, but
others like nouveau have assumed, understandably so, that
drm_dp_mst_port structures are normal and can just be accessed at any
time without worrying about use-after-free errors.

After a lot of discussion, me and Daniel Vetter came up with a better
idea to replace all of this.

To summarize, since this is documented far more indepth in the
documentation this patch introduces, we make it so that drm_dp_mst_port
and drm_dp_mst_branch structures have two different classes of
refcounts: topology_kref, and malloc_kref. topology_kref corresponds to
the lifetime of the given drm_dp_mst_port or drm_dp_mst_branch in it's
given topology. Once it hits zero, any associated connectors are removed
and the branch or port can no longer be validated. malloc_kref
corresponds to the lifetime of the memory allocation for the actual
structure, and will always be non-zero so long as the topology_kref is
non-zero. This gives us a way to allow callers to hold onto port and
branch device structures past their topology lifetime, and dramatically
simplifies the lifetimes of both structures. This also finally fixes the
port deallocation problem, properly.

Additionally: since this now means that we can keep ports and branch
devices allocated in memory for however long we need, we no longer need
a significant amount of the port validation that we currently do.

Additionally, there is one last scenario that this fixes, which couldn't
have been fixed properly beforehand:

- CPU1 unrefs port from topology (refcount 1->0)
- CPU2 refs port in topology(refcount 0->1)

Since we now can guarantee memory safety for ports and branches
as-needed, we also can make our main reference counting functions fix
this problem by using kref_get_unless_zero() internally so that topology
refcounts can only ever reach 0 once.

Changes since v4:
* Change the kernel-figure summary for dp-mst/topology-figure-1.dot a
  bit - danvet
* Remove figure numbers - danvet

Changes since v3:
* Remove rebase detritus - danvet
* Split out purely style changes into separate patches - hwentlan

Changes since v2:
* Fix commit message - checkpatch
* s/)-1/) - 1/g - checkpatch

Changes since v1:
* Remove forward declarations - danvet
* Move "Branch device and port refcounting" section from documentation
  into kernel-doc comments - danvet
* Export internal topology lifetime functions into their own section in
  the kernel

[PATCH v7 09/20] drm/dp_mst: Fix payload deallocation on hotplugs using malloc refs

2019-01-10 Thread Lyude Paul
Up until now, freeing payloads on remote MST hubs that just had ports
removed has almost never worked because we've been relying on port
validation in order to stop us from accessing ports that have already
been freed from memory, but ports which need their payloads released due
to being removed will never be a valid part of the topology after
they've been removed.

Since we've introduced malloc refs, we can replace all of the validation
logic in payload helpers which are used for deallocation with some
well-placed malloc krefs. This ensures that regardless of whether or not
the ports are still valid and in the topology, any port which has an
allocated payload will remain allocated in memory until it's payloads
have been removed - finally allowing us to actually release said
payloads correctly.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Reviewed-by: Harry Wentland 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 54 +++
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index bb9107852fed..b5976f8c318c 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2095,10 +2095,6 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
u8 sinks[DRM_DP_MAX_SDP_STREAMS];
int i;
 
-   port = drm_dp_mst_topology_get_port_validated(mgr, port);
-   if (!port)
-   return -EINVAL;
-
port_num = port->port_num;
mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
if (!mstb) {
@@ -2106,10 +2102,8 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
   port->parent,
   &port_num);
 
-   if (!mstb) {
-   drm_dp_mst_topology_put_port(port);
+   if (!mstb)
return -EINVAL;
-   }
}
 
txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
@@ -2146,7 +2140,6 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
kfree(txmsg);
 fail_put:
drm_dp_mst_topology_put_mstb(mstb);
-   drm_dp_mst_topology_put_port(port);
return ret;
 }
 
@@ -2251,15 +2244,16 @@ static int drm_dp_destroy_payload_step2(struct 
drm_dp_mst_topology_mgr *mgr,
  */
 int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
 {
-   int i, j;
-   int cur_slots = 1;
struct drm_dp_payload req_payload;
struct drm_dp_mst_port *port;
+   int i, j;
+   int cur_slots = 1;
 
mutex_lock(&mgr->payload_lock);
for (i = 0; i < mgr->max_payloads; i++) {
struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
struct drm_dp_payload *payload = &mgr->payloads[i];
+   bool put_port = false;
 
/* solve the current payloads - compare to the hw ones
   - update the hw view */
@@ -2267,12 +2261,20 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
if (vcpi) {
port = container_of(vcpi, struct drm_dp_mst_port,
vcpi);
-   port = drm_dp_mst_topology_get_port_validated(mgr,
- port);
-   if (!port) {
-   mutex_unlock(&mgr->payload_lock);
-   return -EINVAL;
+
+   /* Validated ports don't matter if we're releasing
+* VCPI
+*/
+   if (vcpi->num_slots) {
+   port = drm_dp_mst_topology_get_port_validated(
+   mgr, port);
+   if (!port) {
+   mutex_unlock(&mgr->payload_lock);
+   return -EINVAL;
+   }
+   put_port = true;
}
+
req_payload.num_slots = vcpi->num_slots;
req_payload.vcpi = vcpi->vcpi;
} else {
@@ -2304,7 +2306,7 @@ int drm_dp_update_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr)
}
cur_slots += req_payload.num_slots;
 
-   if (port)
+   if (put_port)
drm_dp_mst_topology_put_port(port);
}
 
@@ -3120,6 +3122,8 @@ bool drm_dp_mst_allocate_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
  pbn, port->vcpi.num_slots);
 
+   /* Keep port allocated until it's payload has been 

[PATCH v7 13/20] drm/nouveau: Remove unnecessary VCPI checks in nv50_msto_cleanup()

2019-01-10 Thread Lyude Paul
There is no need to look at the port's VCPI allocation before calling
drm_dp_mst_deallocate_vcpi(), as we already have msto->disabled to let
us avoid cleaning up an msto more then once. The DP MST core will never
call drm_dp_mst_deallocate_vcpi() on it's own, which is presumably what
these checks are meant to protect against.

More importantly though, we're about to stop clearing mstc->port in the
next commit, which means if we could potentially hit a use-after-free
error if we tried to check mstc->port->vcpi here. So to make life easier
for anyone who bisects this code in the future, use msto->disabled
instead to check whether or not we need to deallocate VCPI instead.

Signed-off-by: Lyude Paul 
Reviewed-By: Ben Skeggs 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 800213be76ea..28538ef19b71 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -703,14 +703,17 @@ nv50_msto_cleanup(struct nv50_msto *msto)
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
+   if (!msto->disabled)
+   return;
+
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
-   if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto))
+
+   if (mstc->port)
drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
-   if (msto->disabled) {
-   msto->mstc = NULL;
-   msto->head = NULL;
-   msto->disabled = false;
-   }
+
+   msto->mstc = NULL;
+   msto->head = NULL;
+   msto->disabled = false;
 }
 
 static void
-- 
2.20.1

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


[PATCH v7 10/20] drm/i915: Keep malloc references to MST ports

2019-01-10 Thread Lyude Paul
So that the ports stay around until we've destroyed the connectors, in
order to ensure that we don't pass an invalid pointer to any MST helpers
once we introduce the new MST VCPI helpers.

Changes since v1:
* Move drm_dp_mst_get_port_malloc() to where we assign
  intel_connector->port - danvet

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Harry Wentland 
Cc: Juston Li 
---
 drivers/gpu/drm/i915/intel_connector.c | 4 
 drivers/gpu/drm/i915/intel_dp_mst.c| 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_connector.c 
b/drivers/gpu/drm/i915/intel_connector.c
index 4f4ffd1c8fd3..ee16758747c5 100644
--- a/drivers/gpu/drm/i915/intel_connector.c
+++ b/drivers/gpu/drm/i915/intel_connector.c
@@ -94,6 +94,10 @@ void intel_connector_destroy(struct drm_connector *connector)
intel_panel_fini(&intel_connector->panel);
 
drm_connector_cleanup(connector);
+
+   if (intel_connector->port)
+   drm_dp_mst_put_port_malloc(intel_connector->port);
+
kfree(connector);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index 4eae81671b0e..cdce0c519f9a 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -456,6 +456,7 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
intel_connector->mst_port = intel_dp;
intel_connector->port = port;
+   drm_dp_mst_get_port_malloc(port);
 
connector = &intel_connector->base;
ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
-- 
2.20.1

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


[PATCH v7 05/20] drm/dp_mst: Rename drm_dp_mst_get_validated_(port|mstb)_ref and friends

2019-01-10 Thread Lyude Paul
s/drm_dp_get_validated_port_ref/drm_dp_mst_topology_get_port_validated/
s/drm_dp_put_port/drm_dp_mst_topology_put_port/
s/drm_dp_get_validated_mstb_ref/drm_dp_mst_topology_get_mstb_validated/
s/drm_dp_put_mst_branch_device/drm_dp_mst_topology_put_mstb/

This is a much more consistent naming scheme, and will make even more
sense once we redesign how the current refcounting scheme here works.

Signed-off-by: Lyude Paul 
Reviewed-by: Daniel Vetter 
Reviewed-by: Harry Wentland 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 114 ++
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 75cca6a843fb..074e985093ca 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -46,7 +46,7 @@ static bool dump_dp_payload_table(struct 
drm_dp_mst_topology_mgr *mgr,
  char *buf);
 static int test_calc_pbn_mode(void);
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port);
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);
 
 static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
 int id,
@@ -888,7 +888,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
 */
list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
list_del(&port->next);
-   drm_dp_put_port(port);
+   drm_dp_mst_topology_put_port(port);
}
 
/* drop any tx slots msg */
@@ -911,7 +911,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref 
*kref)
kref_put(kref, drm_dp_free_mst_branch_device);
 }
 
-static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
+static void drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)
 {
kref_put(&mstb->kref, drm_dp_destroy_mst_branch_device);
 }
@@ -930,7 +930,7 @@ static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port 
*port, int old_pdt)
case DP_PEER_DEVICE_MST_BRANCHING:
mstb = port->mstb;
port->mstb = NULL;
-   drm_dp_put_mst_branch_device(mstb);
+   drm_dp_mst_topology_put_mstb(mstb);
break;
}
 }
@@ -970,12 +970,14 @@ static void drm_dp_destroy_port(struct kref *kref)
kfree(port);
 }
 
-static void drm_dp_put_port(struct drm_dp_mst_port *port)
+static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)
 {
kref_put(&port->kref, drm_dp_destroy_port);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, 
struct drm_dp_mst_branch *to_find)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_branch *to_find)
 {
struct drm_dp_mst_port *port;
struct drm_dp_mst_branch *rmstb;
@@ -985,7 +987,8 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
}
list_for_each_entry(port, &mstb->ports, next) {
if (port->mstb) {
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   port->mstb, to_find);
if (rmstb)
return rmstb;
}
@@ -993,12 +996,15 @@ static struct drm_dp_mst_branch 
*drm_dp_mst_get_validated_mstb_ref_locked(struct
return NULL;
 }
 
-static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb)
+static struct drm_dp_mst_branch *
+drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_branch *mstb)
 {
struct drm_dp_mst_branch *rmstb = NULL;
mutex_lock(&mgr->lock);
if (mgr->mst_primary)
-   rmstb = 
drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb);
+   rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
+   mgr->mst_primary, mstb);
mutex_unlock(&mgr->lock);
return rmstb;
 }
@@ -1021,7 +1027,9 @@ static struct drm_dp_mst_port 
*drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_
return NULL;
 }
 
-static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct 
drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+static struct drm_dp_mst_port *
+drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,
+  struct drm_dp_mst_port *port)
 {
struct drm_dp_mst_port *rport = NULL;
mutex_lock(&mgr->lock);
@@ -1215,7 +1223,7 @@ static void drm_dp_add_port(s

[PATCH v7 07/20] drm/dp_mst: Restart last_connected_port_and_mstb() if topology ref fails

2019-01-10 Thread Lyude Paul
While this isn't a complete fix, this will improve the reliability of
drm_dp_get_last_connected_port_and_mstb() pretty significantly during
hotplug events, since there's a chance that the in-memory topology tree
may not be fully updated when drm_dp_get_last_connected_port_and_mstb()
is called and thus might end up causing our search to fail on an mstb
whose topology refcount has reached 0, but has not yet been removed from
it's parent.

Ideally, we should further fix this problem by ensuring that we deal
with the potential for racing with a hotplug event, which would look
like this:

* drm_dp_payload_send_msg() retrieves the last living relative of mstb
  with drm_dp_get_last_connected_port_and_mstb()
* drm_dp_payload_send_msg() starts building payload message
  At the same time, mstb gets unplugged from the topology and is no
  longer the actual last living relative of the original mstb
* drm_dp_payload_send_msg() tries sending the payload message, hub times
  out
* Hub timed out, we give up and run away-resulting in the payload being
  leaked

This could be fixed by restarting the
drm_dp_get_last_connected_port_and_mstb() search whenever we get a
timeout, sending the payload to the new mstb, then repeating until
either the entire topology is removed from the system or
drm_dp_get_last_connected_port_and_mstb() fails. But since the above
race condition is not terribly likely, we'll address that in a later
patch series once we've improved the recovery handling for VCPI
allocations in the rest of the DP MST helpers.

Changes since v1:
* Convert kerneldoc for drm_dp_get_last_connected_port_and_mstb to
  normal comment - danvet

Signed-off-by: Lyude Paul 
Reviewed-by: Harry Wentland 
Reviewed-by: Daniel Vetter 
Cc: David Airlie 
Cc: Jerry Zuo 
Cc: Juston Li 
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 44 +--
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 796985609933..7a251905b3c4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2048,24 +2048,40 @@ static struct drm_dp_mst_port 
*drm_dp_get_last_connected_port_to_mstb(struct drm
return 
drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
 }
 
-static struct drm_dp_mst_branch 
*drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
-struct 
drm_dp_mst_branch *mstb,
-int 
*port_num)
+/*
+ * Searches upwards in the topology starting from mstb to try to find the
+ * closest available parent of mstb that's still connected to the rest of the
+ * topology. This can be used in order to perform operations like releasing
+ * payloads, where the branch device which owned the payload may no longer be
+ * around and thus would require that the payload on the last living relative
+ * be freed instead.
+ */
+static struct drm_dp_mst_branch *
+drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
+   struct drm_dp_mst_branch *mstb,
+   int *port_num)
 {
struct drm_dp_mst_branch *rmstb = NULL;
struct drm_dp_mst_port *found_port;
+
mutex_lock(&mgr->lock);
-   if (mgr->mst_primary) {
+   if (!mgr->mst_primary)
+   goto out;
+
+   do {
found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
+   if (!found_port)
+   break;
 
-   if (found_port) {
+   if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
rmstb = found_port->parent;
-   if (drm_dp_mst_topology_try_get_mstb(rmstb))
-   *port_num = found_port->port_num;
-   else
-   rmstb = NULL;
+   *port_num = found_port->port_num;
+   } else {
+   /* Search again, starting from this parent */
+   mstb = found_port->parent;
}
-   }
+   } while (!rmstb);
+out:
mutex_unlock(&mgr->lock);
return rmstb;
 }
@@ -2114,6 +2130,14 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
 
drm_dp_queue_down_tx(mgr, txmsg);
 
+   /*
+* FIXME: there is a small chance that between getting the last
+* connected mstb and sending the payload message, the last connected
+* mstb could also be removed from the topology. In the future, this
+* needs to be fixed by restarting the
+* drm_dp_get_last_connected_port_and_mstb() search in the event of a
+* timeout if the topology is still connected to the system.
+*/
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg

  1   2   3   >